diff --git a/.gitignore b/.gitignore index 0501d83e5b..1319d287ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,32 +1,23 @@ -/download -/eclipseBin +# eclipse +bin +*.launch +.settings +.metadata +.classpath +.project -## gradle -/.gradle -/build -/gradle -/gradlew -/gradlew.bat -/libs +# idea +out +*.ipr +*.iws +*.iml +.idea -## ForgeGradle -/run +# gradle +build +.gradle -## eclipse -/eclipse -/.settings -/.metadata -/.classpath -/.project -/bin - -## intellij -/out -/.idea -/*.iml -/*.ipr -/*.iws -/atlassian-ide-plugin.xml - -# Mac OS X -.DS_Store +# other +eclipse +run +classes \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..bbd2e200c8 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,11 @@ +Contributing +============ + +* Use appropriate formatting +* Name all variables correctly +* Prefer deferring to vanilla methods as much as possible instead of copying + * When copying, copy EXACTLY as is and make small comments to note tweaks made + * Comment the class somewhere with [VanillaCopy] to signal that that region needs to be looked at whenever updates happen +* Remove dead code. Git exists for a reason +* Commented code is dead code! +* For the love of god use @Override. \ No newline at end of file diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..03351f8e47 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ + +Forge version: +Twilight Forest version: (this is the build number) +Link to crash log: (please use a paste site such as [gist](https://gist.github.com/), do not attach the .txt or paste the log inline) + +Steps to reproduce: +1. + +What I expected to happen: + +What happened instead: diff --git a/README.md b/README.md index 9f9f2666c7..f7b6d29488 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,22 @@ -twilightforest +Twilight Forest [![Discord](https://img.shields.io/discord/313006291012288521.svg?colorB=7289DA&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAABWAgMAAABnZYq0AAAACVBMVEUAAB38%2FPz%2F%2F%2F%2Bm8P%2F9AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfhBxwQJhxy2iqrAAABoElEQVRIx7WWzdGEIAyGgcMeKMESrMJ6rILZCiiBg4eYKr%2Fd1ZAfgXFm98sJfAyGNwno3G9sLucgYGpQ4OGVRxQTREMDZjF7ILSWjoiHo1n%2BE03Aw8p7CNY5IhkYd%2F%2F6MtO3f8BNhR1QWnarCH4tr6myl0cWgUVNcfMcXACP1hKrGMt8wcAyxide7Ymcgqale7hN6846uJCkQxw6GG7h2MH4Czz3cLqD1zHu0VOXMfZjHLoYvsdd0Q7ZvsOkafJ1P4QXxrWFd14wMc60h8JKCbyQvImzlFjyGoZTKzohwWR2UzSONHhYXBQOaKKsySsahwGGDnb%2FiYPJw22sCqzirSULYy1qtHhXGbtgrM0oagBV4XiTJok3GoLoDNH8ooTmBm7ZMsbpFzi2bgPGoXWXME6XT%2BRJ4GLddxJ4PpQy7tmfoU2HPN6cKg%2BledKHBKlF8oNSt5w5g5o8eXhu1IOlpl5kGerDxIVT%2BztzKepulD8utXqpChamkzzuo7xYGk%2FkpSYuviLXun5bzdRf0Krejzqyz7Z3p0I1v2d6HmA07dofmS48njAiuMgAAAAASUVORK5CYII%3D)](https://discord.gg/6v3z26B) [![Curseforge](http://cf.way2muchnoise.eu/full_the-twilight-forest_downloads.svg)](https://minecraft.curseforge.com/projects/the-twilight-forest) [![Curseforge](http://cf.way2muchnoise.eu/versions/For%20MC_the-twilight-forest_all.svg)](https://minecraft.curseforge.com/projects/the-twilight-forest) ============== -Twilight Forest repository \ No newline at end of file +This is the home of the Twilight Forest mod for Minecraft 1.12 and beyond. + +## Downloads +Releases will be available on [CurseForge](https://minecraft.curseforge.com/projects/the-twilight-forest) when ready. + +Alternatively, grab your experimental builds from our [Discord](https://discord.gg/6v3z26B). See the #faq channel for more details. + +## Community +We have a [Discord channel](https://discord.gg/6v3z26B)! + +## YourKit +![](https://www.yourkit.com/images/yklogo.png) + +We appreciate YourKit, LLC for providing the project developers licenses of its profiler to help us improve performance! + +YourKit supports open source projects with its full-featured Java Profiler. +YourKit, LLC is the creator of [YourKit Java Profiler](https://www.yourkit.com/java/profiler/) +and [YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/), +innovative and intelligent tools for profiling Java and .NET applications. diff --git a/build.gradle b/build.gradle index 671ea9cea4..68e9ffaf94 100644 --- a/build.gradle +++ b/build.gradle @@ -1,65 +1,172 @@ +// define the properties file +ext.configFile = file "gradle.properties" +configFile.withReader { + // read config. it shall from now on be referenced as simply config or as project.config + def prop = new Properties() + prop.load(it) + project.ext.config = new ConfigSlurper().parse prop +} + +// For those who want the bleeding edge buildscript { repositories { - mavenCentral() + jcenter() maven { name = "forge" url = "http://files.minecraftforge.net/maven" } - maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" - } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' } } +apply plugin: 'java' +apply plugin: 'idea' +apply plugin: 'net.minecraftforge.gradle.forge' +apply plugin: 'maven' -apply plugin: 'forge' +/////////////////////////////////////////////////// +// IDE Settings +/////////////////////////////////////////////////// +idea { + project { + languageLevel = '1.8' + } +} -version = "2.3.8dev" -group= "twilightforest" // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = "twilightforest-1.7.10" +/////////////////////////////////////////////////// +// ForgeGradle +/////////////////////////////////////////////////// +version = (hasProperty("CIRevision") ? CIRevision : config.mod_version) +group = config.group_name +archivesBaseName = "${config.mod_id}-${config.minecraft_version}" +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 minecraft { - version = "1.7.10-10.13.4.1558-1.7.10" - runDir = "eclipse" -} + version = config.minecraft_version + "-" + config.forge_version // grab latest forge + runDir = "run" -dependencies { - // you may put jars on which you depend on in ./libs - // or you may define them like so.. - //compile "some.group:artifact:version:classifier" - //compile "some.group:artifact:version" - - // real examples - //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env - //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env - - // for more info... - // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html - // http://www.gradle.org/docs/current/userguide/dependency_management.html - - compile files('libs/Thaumcraft-deobf-1.7.10-4.2.3.5.jar') - + mappings = config.mcp_mappings + makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. + + replace '@mod_version@', version + replace '@mod_id@', config.mod_id + replace '@ci_build@', hasProperty("CIRevision") ? 'true' : 'false' + + replaceIn 'TwilightForestMod.java' + replace '@VERSION@', project.version } -processResources -{ +processResources { + //replaceIn 'assets/twilightforest/patchouli_books/guide/book.json' + //replace '@EDITION@', project.version + // this will ensure that this task is redone when the versions change. inputs.property "version", project.version inputs.property "mcversion", project.minecraft.version // replace stuff in mcmod.info, nothing else from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - + include '**/*.info' + //include '**/*.properties' + include 'assets/twilightforest/patchouli_books/guide/book.json' + // replace version and mcversion - expand 'version':project.version, 'mcversion':project.minecraft.version + expand ([ + 'version':project.version, + 'mcversion':project.minecraft.version, + 'forge_version': config.forge_version, + 'mod_version': config.mod_version, + 'minecraft_version': config.minecraft_version, + 'edition': (project.version - (config.mod_version + '.')), + 's': '$' + ]) } - + // copy everything else, thats not the mcmod.info from(sourceSets.main.resources.srcDirs) { exclude 'mcmod.info' + exclude 'assets/twilightforest/patchouli_books/guide/book.json' + } +} + +compileJava { + options.encoding = 'UTF-8' +} + +jar { + classifier = 'universal' + manifest { + attributes 'FMLAT': 'tf_at.cfg' + } +} + +repositories { + maven { + name 'progwm\'s Maven' // JEI + Mantle + TCon + url 'https://dvs1.progwml6.com/files/maven' + } + maven { + name 'tterrag\'s Maven' // CTM + url 'https://maven.tterrag.com/' + } + maven { + name 'Jared\'s Maven' // Immersive Engineering + Patchouli + url 'https://blamejared.com/maven' + } + maven { + name 'player\'s Maven' // Forestry + url 'http://maven.ic2.player.to/' + } + maven { + name 'Curseforge Maven' // Baubles + Thaumcraft + url 'https://minecraft.curseforge.com/api/maven/' } } + +dependencies { + // progwml6 + deobfCompile "mezz.jei:jei_${minecraft_version}:${jei_version}" + + deobfCompile "slimeknights.mantle:Mantle:${minecraft_sub_version}-${mantle_version}" + deobfCompile "slimeknights:TConstruct:${minecraft_version}-${tcon_version}" + + // tterrag + deobfCompile "team.chisel.ctm:CTM:MC${minecraft_version}-${ctm_version}" + //deobfCompile "team.chisel:Chisel:MC${minecraft_version}-${chisel_version}" + + // blamejared + deobfCompile "blusunrize:ImmersiveEngineering:${immersive_engineering_version}" + deobfCompile "vazkii.patchouli:Patchouli:${patchouli_version}" + + // player + deobfCompile "net.sengir.forestry:forestry_${minecraft_version}:${forestry_version}" + + // curseforge + deobfCompile "baubles:Baubles:${minecraft_sub_version}:${baubles_version}" + deobfCompile "thaumcraft:Thaumcraft:${minecraft_version}:${thaumcraft_version}" +} + +task createPom { + doLast { + pom { + project { + groupId project.group + artifactId project.archivesBaseName + version project.version + + inceptionYear '2012' + licenses { + license { + name 'LGPL 2.1' + url 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html' + distribution 'repo' + } + } + } + }.writeTo(libsDir.path + "/" + project.archivesBaseName + "-" + project.version + ".pom") + } +} + +build.dependsOn createPom diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000..aa536ea6e5 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,33 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx4G + +# suppress inspection "UnusedProperty" for whole file +# Mod Properties +mod_version=3.11 +mod_id=twilightforest +group_name=com.github.teamtwilight.twilightforest + +#Versions +minecraft_version=1.12.2 +minecraft_sub_version=1.12 + +mcp_mappings=stable_39 +forge_version=14.23.5.2847 + +jei_version=4.15.+ + +ctm_version=0.3.2.21 +chisel_version=+ + +mantle_version=+ +tcon_version=+ + +immersive_engineering_version=+ + +patchouli_version=1.0-+ + +forestry_version=5.8.2.354 + +baubles_version=1.5.2 +thaumcraft_version=6.1.BETA26 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..7c9931af6a Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..bb4bf5cf76 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun Aug 05 16:14:35 BST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..cccdd3d517 --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..f9553162f1 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/twilightforest/CommandTF.java b/src/main/java/twilightforest/CommandTF.java new file mode 100644 index 0000000000..49efdedf4d --- /dev/null +++ b/src/main/java/twilightforest/CommandTF.java @@ -0,0 +1,272 @@ +package twilightforest; + +import com.google.common.collect.ImmutableList; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.TextComponentTranslation; +import twilightforest.capabilities.CapabilityList; +import twilightforest.capabilities.shield.IShieldCapability; +import twilightforest.world.ChunkGeneratorTFBase; +import twilightforest.world.TFWorld; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +public class CommandTF extends CommandBase { + + private static final List aliases = ImmutableList.of("tffeature", "twilightforest", "tf"); + + @Override + public List getAliases() { + return aliases; + } + + @Override + public String getName() { + return "tffeature"; // This has become more of a general-purpose command now, but keeping this for legacy + } + + @Override + public String getUsage(ICommandSender sender) { + return "commands.tffeature.usage"; + } + + @Override + public int getRequiredPermissionLevel() { + return 2; + } + + @Override + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { + if (args.length == 1) + return getListOfStringsMatchingLastWord(args, EnumActions.ACTION_LIST); + + if (args.length > 1) { + try { + String[] argsMoved = Arrays.copyOfRange(args, 1, args.length); + + return EnumActions.valueOf(args[0].toUpperCase(Locale.ROOT)).tabCompletion(server, sender, argsMoved, targetPos); + } catch (Throwable e) { + return Collections.emptyList(); + } + } + + return Collections.emptyList(); + } + + @Override + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + if (args.length > 0) { + try { + EnumActions.valueOf(args[0].toUpperCase(Locale.ROOT)).execute(server, sender, args); + } catch (IllegalArgumentException e) { + throw new WrongUsageException("commands.tffeature.usage"); + } + } else { + throw new CommandException("commands.tffeature.usage"); + } + } + + private static void changeStructureActivity(ICommandSender sender, boolean flag) throws CommandException { + // activate current feature + EntityPlayerMP player = getCommandSenderAsPlayer(sender); + + if (!TFWorld.isTwilightForest(player.world)) { + throw new CommandException("commands.tffeature.not_in_twilight_forest"); + } + + // are you in a structure? + ChunkGeneratorTFBase chunkGenerator = TFWorld.getChunkGenerator(player.world); + + BlockPos pos = new BlockPos(player); + if (chunkGenerator != null && chunkGenerator.isBlockInStructureBB(pos)) { + sender.sendMessage(new TextComponentTranslation("commands.tffeature.structure.conquer.update", chunkGenerator.isStructureConquered(pos), flag)); + chunkGenerator.setStructureConquered(pos, flag); + } else { + throw new CommandException("commands.tffeature.structure.required"); + } + } + + @Override + public boolean isUsernameIndex(String[] args, int index) { + try { + return EnumActions.valueOf(args[0].toUpperCase(Locale.ROOT)).isUsernameIndex(args, index); + } catch (Throwable t) { + // Blah blah + } + + return false; + } + + private enum EnumActions { + CENTER { + @Override + protected void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + EntityPlayerMP player = getCommandSenderAsPlayer(sender); + + int dx = MathHelper.floor(player.posX); + //int dy = MathHelper.floor(player.posY); + int dz = MathHelper.floor(player.posZ); + + BlockPos cc = TFFeature.getNearestCenterXYZ(dx >> 4, dz >> 4, player.world); + + boolean fc = TFFeature.isInFeatureChunk(player.world, dx, dz); + sender.sendMessage(new TextComponentTranslation("commands.tffeature.center", cc)); + sender.sendMessage(new TextComponentTranslation("commands.tffeature.chunk", fc)); + } + }, + CONQUER { + @Override + protected void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + changeStructureActivity(sender, true); + } + }, + INFO { + // info on current feature + + @Override + protected void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + EntityPlayerMP player = getCommandSenderAsPlayer(sender); + + if (!TFWorld.isTwilightForest(player.world)) { + throw new CommandException("commands.tffeature.not_in_twilight_forest"); + } + + BlockPos pos = new BlockPos(player); + + // nearest feature + TFFeature nearbyFeature = TFFeature.getFeatureAt(pos.getX(), pos.getZ(), player.world); + sender.sendMessage(new TextComponentTranslation("commands.tffeature.nearest", nearbyFeature.name)); + + // are you in a structure? + ChunkGeneratorTFBase chunkGenerator = TFWorld.getChunkGenerator(player.world); + if (chunkGenerator != null && chunkGenerator.isBlockInStructureBB(pos)) { + sender.sendMessage(new TextComponentTranslation("commands.tffeature.structure.inside")); + + sender.sendMessage(new TextComponentTranslation("commands.tffeature.structure.conquer.status", chunkGenerator.isStructureConquered(pos))); + // are you in a room? + + // what is the spawn list +// List spawnList = chunkGenerator.getPossibleCreatures(EnumCreatureType.monster, dx, dy, dz); +// sender.sendMessage(new TextComponentTranslation("Spawn list for the area is:")); +// for (SpawnListEntry entry : spawnList) { +// sender.sendMessage(new TextComponentTranslation(entry.toString())); +// } + } else { + sender.sendMessage(new TextComponentTranslation("commands.tffeature.structure.outside")); + } + } + }, + LOCATE { + private final String[] STRUCTURE_LIST = { + TFFeature.SMALL_HILL.name, + TFFeature.MEDIUM_HILL.name, + TFFeature.LARGE_HILL.name, + TFFeature.HEDGE_MAZE.name, + TFFeature.NAGA_COURTYARD.name, + TFFeature.LICH_TOWER.name, + TFFeature.ICE_TOWER.name, + TFFeature.QUEST_GROVE.name, + TFFeature.HYDRA_LAIR.name, + TFFeature.LABYRINTH.name, + TFFeature.DARK_TOWER.name, + TFFeature.KNIGHT_STRONGHOLD.name, + TFFeature.YETI_CAVE.name, + TFFeature.TROLL_CAVE.name, + TFFeature.FINAL_CASTLE.name, + TFFeature.MUSHROOM_TOWER.name + }; + + @Override + protected void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + if (args.length != 2) { + throw new WrongUsageException("commands.tffeature.locate.usage"); + } + if (!TFWorld.isTwilightForest(getCommandSenderAsPlayer(sender).world)) { + throw new CommandException("commands.tffeature.not_in_twilight_forest"); + } + String s = args[1]; + BlockPos blockpos = sender.getEntityWorld().findNearestStructure(s, sender.getPosition(), false); + + if (blockpos != null) { + sender.sendMessage(new TextComponentTranslation("commands.locate.success", s, blockpos.getX(), blockpos.getZ())); + + } else { + blockpos = sender.getEntityWorld().findNearestStructure("twilightforest:" + s, sender.getPosition(), false); + if (blockpos != null) { + sender.sendMessage(new TextComponentTranslation("commands.locate.success", s, blockpos.getX(), blockpos.getZ())); + } else throw new CommandException("commands.locate.failure", s); + } + } + + @Override + protected List tabCompletion(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { + return args.length == 1 ? getListOfStringsMatchingLastWord(args, STRUCTURE_LIST) : Collections.emptyList(); + } + }, + REACTIVATE { + @Override + protected void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + changeStructureActivity(sender, false); + } + }, + SHIELD { + @Override + protected boolean isUsernameIndex(String[] args, int index) { + return index == 1; + } + + @Override + protected void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + + if (args.length < 4) return; + + EntityLivingBase entity = getEntity(server, sender, args[1], EntityLivingBase.class); + IShieldCapability cap = entity.getCapability(CapabilityList.SHIELDS, null); + + if (cap != null) { + // If no boolean param is around, then default val is true + boolean temp = args.length < 5 || Boolean.parseBoolean(args[4]); + if ("set".equals(args[2].toLowerCase(Locale.ROOT))) { + cap.setShields(Integer.parseInt(args[3]), temp); + } else if ("add".equals(args[2].toLowerCase(Locale.ROOT))) { + cap.addShields(Integer.parseInt(args[3]), temp); + } + } + } + }; + + private static final String[] ACTION_LIST; + + static { + int length = EnumActions.values().length; + + String[] list = new String[length]; + + for (EnumActions action : EnumActions.values()) + list[action.ordinal()] = action.toString().toLowerCase(Locale.ROOT); + + ACTION_LIST = list; + } + + protected abstract void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException; + + protected List tabCompletion(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { + return Collections.emptyList(); + } + + protected boolean isUsernameIndex(String[] args, int index) { + return false; + } + } +} diff --git a/src/main/java/twilightforest/CommandTFFeature.java b/src/main/java/twilightforest/CommandTFFeature.java deleted file mode 100644 index d3ffb053d8..0000000000 --- a/src/main/java/twilightforest/CommandTFFeature.java +++ /dev/null @@ -1,119 +0,0 @@ -package twilightforest; - -import net.minecraft.command.CommandBase; -import net.minecraft.command.ICommandSender; -import net.minecraft.command.WrongUsageException; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; - -public class CommandTFFeature extends CommandBase { - - @Override - public String getCommandName() { - return "tffeature"; - } - - @Override - public String getCommandUsage(ICommandSender sender) { - return "tffeature accepts the following arguments: info"; - } - - @Override - public void processCommand(ICommandSender sender, String[] args) { - if (args.length > 0) { - if (args[0].equalsIgnoreCase("info")) { - // info on current feature - - EntityPlayerMP player = getCommandSenderAsPlayer(sender); - - int dx = MathHelper.floor_double(player.posX); - int dy = MathHelper.floor_double(player.posY); - int dz = MathHelper.floor_double(player.posZ); - - if (!(player.worldObj.provider instanceof WorldProviderTwilightForest)) { - throw new WrongUsageException("commands.tffeature.not_in_twilight_forest", new Object[0]); - } else { - // nearest feature - TFFeature nearbyFeature = ((TFWorldChunkManager)player.worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, player.worldObj); - - sender.addChatMessage(new ChatComponentTranslation("The nearest feature is %s", new Object[] {nearbyFeature.name})); - - // are you in a structure? - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)player.worldObj.provider).getChunkProvider(); - - if (chunkProvider.isBlockInStructureBB(dx, dy, dz)) { - sender.addChatMessage(new ChatComponentTranslation("You are in the structure for that feature.")); - - sender.addChatMessage(new ChatComponentTranslation("Structure conquer flag = %s.", new Object[] {chunkProvider.isStructureConquered(dx, dy, dz)})); - - // are you in a room? - - // what is the spawn list -// List spawnList = chunkProvider.getPossibleCreatures(EnumCreatureType.monster, dx, dy, dz); -// sender.addChatMessage(new ChatComponentTranslation("Spawn list for the area is:")); -// for (SpawnListEntry entry : spawnList) { -// sender.addChatMessage(new ChatComponentTranslation(entry.toString())); -// } - - - } else { - sender.addChatMessage(new ChatComponentTranslation("You are not in the structure for that feature.")); - } - } - } else if (args[0].equalsIgnoreCase("reactivate")) { - changeStructureActivity(sender, false); - } else if (args[0].equalsIgnoreCase("conquer")) { - changeStructureActivity(sender, true); - } else if (args[0].equalsIgnoreCase("center")) { - EntityPlayerMP player = getCommandSenderAsPlayer(sender); - - int dx = MathHelper.floor_double(player.posX); - //int dy = MathHelper.floor_double(player.posY); - int dz = MathHelper.floor_double(player.posZ); - - ChunkCoordinates cc = TFFeature.getNearestCenterXYZ(dx >> 4, dz >> 4, player.worldObj); - - TFWorldChunkManager wcm = (TFWorldChunkManager)player.worldObj.provider.worldChunkMgr; - - boolean fc = wcm.isInFeatureChunk(player.worldObj, dx, dz); - sender.addChatMessage(new ChatComponentTranslation("Center of feature = %s.", new Object[] {cc})); - sender.addChatMessage(new ChatComponentTranslation("Are in feature chunk = %s.", new Object[] {fc})); - } else { - throw new WrongUsageException("commands.tffeature.usage", new Object[0]); - } - - } else { - throw new WrongUsageException("commands.tffeature.usage", new Object[0]); - } - } - - private void changeStructureActivity(ICommandSender sender, boolean flag) throws WrongUsageException { - // activate current feature - EntityPlayerMP player = getCommandSenderAsPlayer(sender); - - int dx = MathHelper.floor_double(player.posX); - int dy = MathHelper.floor_double(player.posY); - int dz = MathHelper.floor_double(player.posZ); - - if (!(player.worldObj.provider instanceof WorldProviderTwilightForest)) { - throw new WrongUsageException("commands.tffeature.not_in_twilight_forest", new Object[0]); - } else { - // are you in a structure? - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)player.worldObj.provider).getChunkProvider(); - - if (chunkProvider.isBlockInStructureBB(dx, dy, dz)) { - sender.addChatMessage(new ChatComponentTranslation("Structure conquer flag was %s. Changing to %s.", new Object[] {chunkProvider.isStructureConquered(dx, dy, dz), flag})); - - chunkProvider.setStructureConquered(dx, dy, dz, flag); - } else { - sender.addChatMessage(new ChatComponentTranslation("You are not in a structure.")); - } - } - } - -} diff --git a/src/main/java/twilightforest/CommandTFProgress.java b/src/main/java/twilightforest/CommandTFProgress.java deleted file mode 100644 index 49ab077cb4..0000000000 --- a/src/main/java/twilightforest/CommandTFProgress.java +++ /dev/null @@ -1,140 +0,0 @@ -package twilightforest; - -import java.util.List; - -import net.minecraft.command.CommandBase; -import net.minecraft.command.ICommand; -import net.minecraft.command.ICommandSender; -import net.minecraft.command.WrongUsageException; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ChatComponentTranslation; - -public class CommandTFProgress extends CommandBase { - - String[] bosses = new String[] {"none", "naga", "lich", "mooshroom", "hydra", "knights", "urghast", "yeti", "snowqueen", "giants", "final"}; - - @Override - public String getCommandName() { - return "tfprogress"; - } - - @Override - public String getCommandUsage(ICommandSender sender) { - return "tfprogress "; - } - - /** - * Return the required permission level for this command. - */ - public int getRequiredPermissionLevel() - { - return 2; - } - - @Override - public void processCommand(ICommandSender sender, String[] args) { - if (args.length < 2) { - throw new WrongUsageException("tfprogress ", new Object[0]); - } else { - EntityPlayerMP player = getPlayer(sender, args[0]); - int bossIndex = getBossIndex(args[1]); - - func_152373_a(sender, this, "Setting player %s progress to past boss %s.", new Object[] {player.getCommandSenderName(), bosses[bossIndex]}); - - - setProgress (player, bossIndex); - } - } - - - - private void setProgress(EntityPlayerMP player, int bossIndex) { - - // give previous achievements, if necessary - if (bossIndex > 0) { - for (int i = 0; i < bossIndex; i++) { - setProgress(player, i); - } - } - - // give achievements - switch (bossIndex) { - case 0: - default : - break; - case 1: - player.triggerAchievement(TFAchievementPage.twilightPortal); - player.triggerAchievement(TFAchievementPage.twilightArrival); - player.triggerAchievement(TFAchievementPage.twilightHunter); - player.triggerAchievement(TFAchievementPage.twilightKillNaga); - player.triggerAchievement(TFAchievementPage.twilightProgressNaga); - break; - case 2: - player.triggerAchievement(TFAchievementPage.twilightKillLich); - player.triggerAchievement(TFAchievementPage.twilightProgressLich); - break; - case 3: - player.triggerAchievement(TFAchievementPage.twilightProgressLabyrinth); - break; - case 4: - player.triggerAchievement(TFAchievementPage.twilightKillHydra); - player.triggerAchievement(TFAchievementPage.twilightProgressHydra); - break; - case 5: - player.triggerAchievement(TFAchievementPage.twilightProgressTrophyPedestal); - player.triggerAchievement(TFAchievementPage.twilightProgressKnights); - break; - case 6: - player.triggerAchievement(TFAchievementPage.twilightProgressUrghast); - break; - case 7: - player.triggerAchievement(TFAchievementPage.twilightProgressYeti); - break; - case 8: - player.triggerAchievement(TFAchievementPage.twilightProgressGlacier); - break; - case 9: - player.triggerAchievement(TFAchievementPage.twilightProgressTroll); - break; - case 10: - player.triggerAchievement(TFAchievementPage.twilightProgressThorns); - player.triggerAchievement(TFAchievementPage.twilightProgressCastle); - break; - } - - - } - - private int getBossIndex(String string) { - for (int i = 0; i < bosses.length; i++) { - if (bosses[i].equalsIgnoreCase(string)) { - return i; - } - } - - - return 0; - } - - /** - * Adds the strings available in this command to the given list of tab completion options. - */ - public List addTabCompletionOptions(ICommandSender p_71516_1_, String[] args) - { - return args.length == 1 ? getListOfStringsMatchingLastWord(args, this.getListOfPlayers()) : (args.length == 2 ? getListOfStringsMatchingLastWord(args, bosses) : null); - } - - protected String[] getListOfPlayers() - { - return MinecraftServer.getServer().getAllUsernames(); - } - - /** - * Return whether the specified command parameter index is a username parameter. - */ - public boolean isUsernameIndex(String[] p_82358_1_, int p_82358_2_) - { - return p_82358_2_ == 0; - } -} diff --git a/src/main/java/twilightforest/IMCHandler.java b/src/main/java/twilightforest/IMCHandler.java new file mode 100644 index 0000000000..ebb7a5d1f8 --- /dev/null +++ b/src/main/java/twilightforest/IMCHandler.java @@ -0,0 +1,143 @@ +package twilightforest; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTUtil; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.common.event.FMLInterModComms; +import twilightforest.world.feature.TFGenCaveStalactite; + +import java.util.function.Consumer; + +public class IMCHandler { + + private static final ImmutableSet.Builder BLACKLIST_BUILDER = ImmutableSet.builder(); + private static final ImmutableList.Builder ORE_BLOCKS_BUILDER = ImmutableList.builder(); + private static final ImmutableList.Builder LOADING_ICONS_BUILDER = ImmutableList.builder(); + private static final ImmutableMultimap.Builder CRUMBLE_BLOCKS_BUILDER = ImmutableMultimap.builder(); + private static final ImmutableMultimap.Builder STALACTITE_BUILDER = ImmutableMultimap.builder(); + + /** + IMC NBT Format: You can send all of your requests as one big NBT list rather than needing to shotgun a ton of tiny NBT messages. +
+	 root:
+		 • "Blacklist"                               - NBTTagList     : List of blockstates to blacklist from blockbreaking (antibuilders, naga, hydra, etc)
+			 • List Entry                            - NBTTagCompound : An IBlockState
+				 • "Name"                            - String         : Resource location of block. Is not allowed to be Air.
+				 • "Properties"                      - NBTTagCompound : Blockstate Properties
+					 • [String Property Key]         - String         : Key is nameable to a property key, and the string value attached to it is value to property.
+
+		 • "Ore_Blocks"                              - NBTTagList     : List of blockstates to add to Hollow Hills and Ore Magnets - May change this to a function in the future
+			 • List Entry                            - NBTTagCompound : An IBlockState
+				 • "Name"                            - String         : Resource location of block. Is not allowed to be Air.
+				 • "Properties"                      - NBTTagCompound : Blockstate Properties
+					 • [String Property Key]         - String         : Key is nameable to a property key, and the string value attached to it is value to property.
+	 			 • "Stalactite_Settings"             - NBTTagCompound : Settings for stalactite generation, exclude if only used for Ore Magnets. May be empty for all default values.
+	 			 	 • "Weight"                      - Integer        : Ore weight, decides how often the ore generates. Defaults to 15.
+	 				 • "Hill_Size"                   - Integer        : Minimum hill size for the ore stalactite to generate. 1-small, 2-medium, 3-large. Defaults to 3.
+	 				 • "Size"                        - Float          : Decides the maximum length of the stalactite relative to the space between hill floor and ceiling. Defaults to 0.7.
+	 				 • "Max_Length"                  - Integer        : Maximum length of a stalactite in blocks. Defaults to 8.
+	 				 • "Min_Height"                  - Integer        : Minimum space between the hill floor and the stalactite to let it generate. Defaults to 1.
+
+		 • "Crumbling"                               - NBTTagList     : List of blockstates to add to crumble horn crumbling - May change this to a function in the future
+			 • List Entry                            - NBTTagCompound : An IBlockState
+				 • "Name"                            - String         : Resource location of block. Is not allowed to be Air.
+				 • "Properties"                      - NBTTagCompound : Blockstate Properties
+				 • "Crumbles"                        - NBTTagList     : List of different blockstates that the blockstate can crumble into
+					 • List Entry                    - NBTTagCompound : An IBlockState.
+						 • "Name"                    - String         : Resource location of block. Can be Air.
+						 • "Properties"              - NBTTagCompound : Blockstate Properties
+							 • [String Property Key] - String         : Key is nameable to a property key, and the string value attached to it is value to property.
+	 
+ */ + + static void onIMC(FMLInterModComms.IMCEvent event) { + for (FMLInterModComms.IMCMessage message : event.getMessages()) { + if (message.isNBTMessage()) { + NBTTagCompound imcCompound = message.getNBTValue(); + + readStatesFromTagList(imcCompound.getTagList("Blacklist", Constants.NBT.TAG_COMPOUND), BLACKLIST_BUILDER::add); + readFromTagList(imcCompound.getTagList("Ore_Blocks", Constants.NBT.TAG_COMPOUND), IMCHandler::handleOre); + readFromTagList(imcCompound.getTagList("Crumbling", Constants.NBT.TAG_COMPOUND), IMCHandler::handleCrumble); + } + + if (message.isItemStackMessage() && message.key.equals("Loading_Icon")) { + LOADING_ICONS_BUILDER.add(message.getItemStackValue()); + } + } + } + + private static void readFromTagList(NBTTagList list, Consumer consumer) { + for (int i = 0; i < list.tagCount(); i++) { + consumer.accept(list.getCompoundTagAt(i)); + } + } + + private static void readStatesFromTagList(NBTTagList list, Consumer consumer) { + for (int i = 0; i < list.tagCount(); i++) { + IBlockState state = NBTUtil.readBlockState(list.getCompoundTagAt(i)); + if (state.getBlock() != Blocks.AIR) { + consumer.accept(state); + } + } + } + + private static void handleCrumble(NBTTagCompound nbt) { + IBlockState key = NBTUtil.readBlockState(nbt); + if (key.getBlock() != Blocks.AIR) { + readStatesFromTagList(nbt.getTagList("Crumbling", Constants.NBT.TAG_COMPOUND), value -> CRUMBLE_BLOCKS_BUILDER.put(key, value)); + } + } + + private static void handleOre(NBTTagCompound nbt) { + IBlockState nbtState = NBTUtil.readBlockState(nbt); + + if (nbtState.getBlock() != Blocks.AIR) { + ORE_BLOCKS_BUILDER.add(nbtState); + + if (nbt.hasKey("Stalactite_Settings", Constants.NBT.TAG_COMPOUND)) { + NBTTagCompound settings = nbt.getCompoundTag("Stalactite_Settings"); + int weight = readInt(settings, "Weight", 15); + int hillSize = readInt(settings, "Hill_Size", 3); + float size = readFloat(settings, "Size", 0.7f); + int maxLength = readInt(settings, "Max_Length", 8); + int minHeight = readInt(settings, "Min_Height", 1); + STALACTITE_BUILDER.put(hillSize, new TFGenCaveStalactite.StalactiteEntry(nbtState, size, maxLength, minHeight, weight)); + } + } + } + + private static int readInt(NBTTagCompound tag, String key, int defaultValue) { + return tag.hasKey(key, Constants.NBT.TAG_ANY_NUMERIC) ? tag.getInteger(key) : defaultValue; + } + + private static float readFloat(NBTTagCompound tag, String key, float defaultValue) { + return tag.hasKey(key, Constants.NBT.TAG_ANY_NUMERIC) ? tag.getFloat(key) : defaultValue; + } + + public static ImmutableSet getBlacklistedBlocks() { + return BLACKLIST_BUILDER.build(); + } + + public static ImmutableList getOreBlocks() { + return ORE_BLOCKS_BUILDER.build(); + } + + public static ImmutableList getLoadingIconStacks() { + return LOADING_ICONS_BUILDER.build(); + } + + public static ImmutableMultimap getCrumblingBlocks() { + return CRUMBLE_BLOCKS_BUILDER.build(); + } + + public static ImmutableMultimap getStalactites() { + return STALACTITE_BUILDER.build(); + } +} diff --git a/src/main/java/twilightforest/TFAchievementPage.java b/src/main/java/twilightforest/TFAchievementPage.java deleted file mode 100644 index 3338b32966..0000000000 --- a/src/main/java/twilightforest/TFAchievementPage.java +++ /dev/null @@ -1,61 +0,0 @@ -package twilightforest; - -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; -import net.minecraft.stats.Achievement; -import twilightforest.block.TFBlocks; -import twilightforest.item.TFItems; - -public class TFAchievementPage extends net.minecraftforge.common.AchievementPage { - - - public static Achievement twilightPortal = (new Achievement(TwilightForestMod.ID + 1, "twilightPortal", -2, 1, TFBlocks.portal, (Achievement)null)).setSpecial().registerStat(); - public static Achievement twilightArrival = (new Achievement(TwilightForestMod.ID + 2, "twilightArrival", 0, 0, new ItemStack(TFBlocks.log, 1, 9), twilightPortal)).registerStat(); - public static Achievement twilightHunter = (new Achievement(TwilightForestMod.ID + 3, "twilightHunter", 2, 2, TFItems.feather, twilightArrival)).registerStat(); - public static Achievement twilightMagicMapFocus = (new Achievement(TwilightForestMod.ID + 5, "twilightMagicMapFocus", 2, 0, TFItems.magicMapFocus, twilightHunter)).registerStat(); - public static Achievement twilightHill1 = (new Achievement(TwilightForestMod.ID + 10, "twilightHill1", -2, -1, Blocks.iron_ore, twilightArrival)).registerStat(); - public static Achievement twilightHill2 = (new Achievement(TwilightForestMod.ID + 11, "twilightHill2", -3, -2, Blocks.gold_ore, twilightArrival)).registerStat(); - public static Achievement twilightHill3 = (new Achievement(TwilightForestMod.ID + 12, "twilightHill3", -1, -3, Blocks.diamond_ore, twilightArrival)).registerStat(); - public static Achievement twilightHedge = (new Achievement(TwilightForestMod.ID + 13, "twilightHedge", 2, -3, TFBlocks.hedge, twilightArrival)).registerStat(); - public static Achievement twilightMagicMap = (new Achievement(TwilightForestMod.ID + 14, "twilightMagicMap", 4, -1, TFItems.magicMap, twilightMagicMapFocus)).registerStat(); - - public static Achievement twilightKillNaga = (new Achievement(TwilightForestMod.ID + 6, "twilightKillNaga", 4, 3, new ItemStack(TFItems.trophy, 1, 1), twilightHunter)).registerStat(); - public static Achievement twilightProgressNaga = (new Achievement(TwilightForestMod.ID + 17, "twilightProgressNaga", 4, 5, TFItems.nagaScale, twilightKillNaga)).registerStat(); - public static Achievement twilightKillLich = (new Achievement(TwilightForestMod.ID + 8, "twilightKillLich", 2, 5, new ItemStack(TFItems.trophy, 1, 2), twilightProgressNaga)).registerStat(); - public static Achievement twilightProgressLich = (new Achievement(TwilightForestMod.ID + 18, "twilightProgressLich", -1, 4, TFItems.scepterLifeDrain, twilightKillLich)).registerStat(); - public static Achievement twilightProgressLabyrinth = (new Achievement(TwilightForestMod.ID + 28, "twilightProgressLabyrinth", -4, 6, TFItems.meefStroganoff, twilightProgressLich)).registerStat(); - public static Achievement twilightKillHydra = (new Achievement(TwilightForestMod.ID + 30, "twilightKillHydra", -6, 4, new ItemStack(TFItems.trophy, 1, 0), twilightProgressLabyrinth)).registerStat(); - public static Achievement twilightProgressHydra = (new Achievement(TwilightForestMod.ID + 20, "twilightProgressHydra", -8, 4, TFItems.fieryBlood, twilightKillHydra)).registerStat(); - public static Achievement twilightProgressTrophyPedestal = (new Achievement(TwilightForestMod.ID + 29, "twilightProgressTrophyPedestal", -5, 2, TFBlocks.trophyPedestal, twilightProgressHydra)).registerStat(); - public static Achievement twilightProgressKnights = (new Achievement(TwilightForestMod.ID + 21, "twilightProgressKnights", -5, -1, TFItems.phantomHelm, twilightProgressTrophyPedestal)).registerStat(); - public static Achievement twilightProgressUrghast = (new Achievement(TwilightForestMod.ID + 22, "twilightProgressUrghast", -7, -1, new ItemStack(TFItems.trophy, 1, 3), twilightProgressKnights)).registerStat(); - public static Achievement twilightProgressYeti = (new Achievement(TwilightForestMod.ID + 23, "twilightProgressYeti", -7, -3, TFItems.alphaFur, twilightProgressUrghast)).registerStat(); - public static Achievement twilightProgressGlacier = (new Achievement(TwilightForestMod.ID + 24, "twilightProgressGlacier", -5, -5, new ItemStack(TFItems.trophy, 1, 4), twilightProgressYeti)).registerStat(); - public static Achievement twilightProgressTroll = (new Achievement(TwilightForestMod.ID + 25, "twilightProgressTroll", -5, -7, TFItems.lampOfCinders, twilightProgressGlacier)).registerStat(); - public static Achievement twilightProgressThorns = (new Achievement(TwilightForestMod.ID + 26, "twilightProgressThorns", -3, -7, TFBlocks.thorns, twilightProgressTroll)).registerStat(); - public static Achievement twilightProgressCastle = (new Achievement(TwilightForestMod.ID + 27, "twilightProgressCastle", -1, -7, Blocks.stonebrick, twilightProgressThorns)).registerStat(); - - public static Achievement twilightNagaArmors = (new Achievement(TwilightForestMod.ID + 7, "twilightNagaArmors", 5, 1, TFItems.plateNaga, twilightKillNaga)).setSpecial().registerStat(); - public static Achievement twilightLichScepters = (new Achievement(TwilightForestMod.ID + 9, "twilightLichScepters", 3, 7, TFItems.scepterZombie, twilightKillLich)).setSpecial().registerStat(); - - public static Achievement twilightMazeMap = (new Achievement(TwilightForestMod.ID + 15, "twilightMazeMap", 1, 7, TFItems.mazeMap, twilightProgressLich)).registerStat(); - public static Achievement twilightOreMap = (new Achievement(TwilightForestMod.ID + 16, "twilightOreMap", 1, 9, TFItems.oreMap, twilightMazeMap)).setSpecial().registerStat(); - - public static Achievement twilightHydraChop = (new Achievement(TwilightForestMod.ID + 31, "twilightHydraChop", -6, 6, TFItems.hydraChop, twilightKillHydra)).registerStat(); - public static Achievement twilightMazebreaker = (new Achievement(TwilightForestMod.ID + 32, "twilightMazebreaker", -3, 4, TFItems.mazebreakerPick, twilightProgressLich)).setSpecial().registerStat(); - public static Achievement twilightFierySet = (new Achievement(TwilightForestMod.ID + 33, "twilightFierySet", -8, 7, TFItems.fierySword, twilightProgressHydra)).setSpecial().registerStat(); - public static Achievement twilightQuestRam = (new Achievement(TwilightForestMod.ID + 34, "twilightQuestRam", 1, -5, TFItems.crumbleHorn, twilightArrival)).setSpecial().registerStat(); - - - - public TFAchievementPage() { - super("Twilight Forest", twilightPortal, twilightArrival, twilightHunter, twilightMagicMapFocus, twilightKillNaga, twilightNagaArmors, twilightKillLich, - twilightLichScepters, twilightHill1, twilightHill2, twilightHill3, twilightHedge, twilightMagicMap, twilightMazeMap, twilightOreMap, - twilightProgressNaga, twilightProgressLich, twilightProgressLabyrinth, twilightHydraChop, twilightProgressKnights, twilightProgressUrghast, - twilightProgressYeti, twilightProgressGlacier, twilightProgressTroll, twilightProgressThorns, twilightProgressCastle, - twilightKillHydra, twilightHydraChop, twilightProgressTrophyPedestal, twilightProgressHydra, twilightMazebreaker, - twilightFierySet, twilightQuestRam); - } - -} diff --git a/src/main/java/twilightforest/TFCommonProxy.java b/src/main/java/twilightforest/TFCommonProxy.java index a45b2ea7c9..04320c2a6c 100644 --- a/src/main/java/twilightforest/TFCommonProxy.java +++ b/src/main/java/twilightforest/TFCommonProxy.java @@ -1,94 +1,36 @@ package twilightforest; +import net.minecraft.advancements.Advancement; +import net.minecraft.client.gui.inventory.GuiFurnace; import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.ContainerFurnace; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.client.GuiTFCinderFurnace; -import twilightforest.inventory.ContainerTFCinderFurnace; +import net.minecraftforge.fml.common.network.IGuiHandler; +import net.minecraftforge.fml.common.registry.GameRegistry; +import twilightforest.client.particle.TFParticleType; import twilightforest.inventory.ContainerTFUncrafting; -import cpw.mods.fml.common.network.IGuiHandler; +import twilightforest.tileentity.TileEntityTFCinderFurnace; +import twilightforest.tileentity.critters.*; public class TFCommonProxy implements IGuiHandler { - - /** - * Called during the pre-load step. Register stuff here. - * Obviously most stuff in the common category will be just registered in the mod file - */ - public void doPreLoadRegistration() { - ; - } - - /** - * Called during the load step. Register stuff here. - * Obviously most stuff in the common category will be just registered in the mod file - */ - public void doOnLoadRegistration() { - ; - } - public int getCritterBlockRenderID() { - return 0; - } + public void preInit() {} - public int getPlantBlockRenderID() { - return 0; - } + public void init() {} - public int getComplexBlockRenderID() { - return 0; - } - - public int getNagastoneBlockRenderID() { - return 0; - } - - public int getMagicLeavesBlockRenderID() { - return 0; - } - - public int getPedestalBlockRenderID() { - return 0; - } - - public int getThornsBlockRenderID() { - return 0; - } - - public int getKnightmetalBlockRenderID() { - return 0; - } - - public int getHugeLilyPadBlockRenderID() { - return 0; - } - - public int getCastleMagicBlockRenderID() { - return 0; - } - - public int registerArmorRenderID(String prefix) { - return 0; - } - - public World getClientWorld() { - return null; - } - - /** - * Spawns a particle. This is my copy of RenderGlobal.spawnParticle where I implement custom particles. - * Null op except on the client. - */ - public void spawnParticle(World world, String particleType, double x, double y, double z, double velX, double velY, double velZ) - { - ; - } + public void spawnParticle(TFParticleType particleType, double x, double y, double z, double vx, double vy, double vz) {} @Override public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { if (id == TwilightForestMod.GUI_ID_UNCRAFTING) { return new ContainerTFUncrafting(player.inventory, world, x, y, z); } else if (id == TwilightForestMod.GUI_ID_FURNACE) { - return new ContainerTFCinderFurnace(player.inventory, world, x, y, z); + return new ContainerFurnace(player.inventory, (TileEntityTFCinderFurnace) world.getTileEntity(new BlockPos(x, y, z))); } else { return null; } @@ -99,32 +41,59 @@ public Object getClientGuiElement(int id, EntityPlayer player, World world, int if (id == TwilightForestMod.GUI_ID_UNCRAFTING) { return new twilightforest.client.GuiTFGoblinCrafting(player.inventory, world, x, y, z); } else if (id == TwilightForestMod.GUI_ID_FURNACE) { - return new GuiTFCinderFurnace(player.inventory, world, x, y, z); + return new GuiFurnace(player.inventory, (TileEntityTFCinderFurnace) world.getTileEntity(new BlockPos(x, y, z))); } else { return null; } } - public ModelBiped getKnightlyArmorModel(int armorSlot) { + public ModelBiped getKnightlyArmorModel(EntityEquipmentSlot armorSlot) { return null; } - public ModelBiped getPhantomArmorModel(int armorSlot) { + public ModelBiped getPhantomArmorModel(EntityEquipmentSlot armorSlot) { return null; } - - public ModelBiped getYetiArmorModel(int armorSlot) { + + public ModelBiped getYetiArmorModel(EntityEquipmentSlot armorSlot) { return null; } - - public ModelBiped getArcticArmorModel(int armorSlot) { + + public ModelBiped getArcticArmorModel(EntityEquipmentSlot armorSlot) { return null; } - - public ModelBiped getFieryArmorModel(int armorSlot) { + + public ModelBiped getFieryArmorModel(EntityEquipmentSlot armorSlot) { return null; } - - public void doBlockAnnihilateEffect(World worldObj, int blockX, int blockY, int blockZ) { } + public boolean doesPlayerHaveAdvancement(EntityPlayer player, ResourceLocation advId) { + if (player instanceof EntityPlayerMP) { + Advancement adv = ((EntityPlayerMP) player).getServerWorld().getAdvancementManager().getAdvancement(advId); + return adv != null && ((EntityPlayerMP) player).getAdvancements().getProgress(adv).isDone(); + } + return false; + } + + public TileEntityTFCicada getNewCicadaTE() { + return new TileEntityTFCicada(); + } + + public TileEntityTFFirefly getNewFireflyTE() { + return new TileEntityTFFirefly(); + } + + public TileEntityTFMoonworm getNewMoonwormTE() { + return new TileEntityTFMoonworm(); + } + + public void registerCritterTileEntities() { + GameRegistry.registerTileEntity(TileEntityTFFirefly.class, prefix("firefly" )); + GameRegistry.registerTileEntity(TileEntityTFCicada.class, prefix("cicada" )); + GameRegistry.registerTileEntity(TileEntityTFMoonworm.class, prefix("moonworm")); + } + + protected static ResourceLocation prefix(String name) { + return new ResourceLocation(TwilightForestMod.ID, name); + } } diff --git a/src/main/java/twilightforest/TFConfig.java b/src/main/java/twilightforest/TFConfig.java new file mode 100644 index 0000000000..99951d4c93 --- /dev/null +++ b/src/main/java/twilightforest/TFConfig.java @@ -0,0 +1,500 @@ +package twilightforest; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.config.Config; +import net.minecraftforge.common.config.ConfigManager; +import net.minecraftforge.fml.client.event.ConfigChangedEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.oredict.OreDictionary; +import twilightforest.world.WorldProviderTwilightForest; +import twilightforest.world.feature.TFGenCaveStalactite; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@SuppressWarnings("WeakerAccess") +@Config(modid = TwilightForestMod.ID) +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class TFConfig { + @Config.Ignore + private static final String config = TwilightForestMod.ID + ".config."; + + @Config.LangKey(config + "dimension") + @Config.Comment("Settings that are not reversible without consequences.") + public static Dimension dimension = new Dimension(); + + public static class Dimension { + @Config.LangKey(config + "dimension_id") + @Config.RequiresMcRestart + @Config.Comment("What ID number to assign to the Twilight Forest dimension. Change if you are having conflicts with another mod.") + public int dimensionID = 7; + + @Config.LangKey(config + "dimension_seed") + @Config.RequiresWorldRestart + @Config.Comment("If set, this will override the normal world seed when generating parts of the Twilight Forest Dimension.") + public String twilightForestSeed = ""; + + @Config.LangKey(config + "spawn_in_tf") + @Config.Comment("If true, players spawning for the first time will spawn in the Twilight Forest.") + public boolean newPlayersSpawnInTF = false; + + @Config.LangKey(config + "skylight_forest") + @Config.RequiresWorldRestart + @Config.Comment("If true, Twilight Forest will generate as a void except for Major Structures") + public boolean skylightForest = false; + + @Config.LangKey(config + "skylight_oaks") + @Config.RequiresWorldRestart + @Config.Comment("If true, giant Twilight Oaks will also spawn in void worlds") + public boolean skylightOaks = true; + + @Config.LangKey(config + "world_gen_weights") + @Config.Comment("Weights for various small features") + @Config.RequiresMcRestart + public WorldGenWeights worldGenWeights = new WorldGenWeights(); + + public static class WorldGenWeights { + + @Config.LangKey(config + "stone_circle_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int stoneCircleWeight = 10; + + @Config.LangKey(config + "well_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int wellWeight = 10; + + @Config.LangKey(config + "stalagmite_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int stalagmiteWeight = 12; + + @Config.LangKey(config + "foundation_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int foundationWeight = 10; + + @Config.LangKey(config + "monolith_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int monolithWeight = 10; + + @Config.LangKey(config + "grove_ruins_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int groveRuinsWeight = 5; + + @Config.LangKey(config + "hollow_stump_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int hollowStumpWeight = 12; + + @Config.LangKey(config + "fallen_hollow_log_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int fallenHollowLogWeight = 10; + + @Config.LangKey(config + "fallen_small_log_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int fallenSmallLogWeight = 10; + + @Config.LangKey(config + "druid_hut_weight") + @Config.RequiresMcRestart + @Config.RangeInt(min = 0) + public int druidHutWeight = 10; + } + + @Config.LangKey(config + "hollow_hill_stalactites") + @Config.Comment("Defines custom stalactites generated in hollow hills." + + "\nFormat is \"modid:block<:meta> size maxLength minHeight weight\", where the properties are:" + + "\nSize - the maximum length of the stalactite relative to the space between hill floor and ceiling," + + "\nMax length - maximum length of a stalactite in blocks," + + "\nMin height - minimum space between the hill floor and the stalactite to let it generate," + + "\nWeight - how often it generates." + + "\n\nFor example: \"minecraft:iron_ore 0.7 8 1 24\" would add a stalactite equal to the default iron ore stalactite.") + @Config.RequiresMcRestart + public HollowHillStalactites hollowHillStalactites = new HollowHillStalactites(); + + public static class HollowHillStalactites { + @Config.LangKey(config + "large_hill") + @Config.RequiresMcRestart + @Config.Comment("Blocks generating as stalactites in large hills only") + public String[] largeHill = {}; + + @Config.LangKey(config + "medium_hill") + @Config.RequiresMcRestart + @Config.Comment("Blocks generating as stalactites in medium and large hills") + public String[] mediumHill = {}; + + @Config.LangKey(config + "small_hill") + @Config.RequiresMcRestart + @Config.Comment("Blocks generating as stalactites in all hills") + public String[] smallHill = {}; + + @Config.LangKey(config + "stalactite_config_only") + @Config.RequiresMcRestart + @Config.Comment("If true, default stalactites and stalactites defined by other mods will not be used.") + public boolean useConfigOnly = false; + + public void load() { + registerHill(smallHill, 1); + registerHill(mediumHill, 2); + registerHill(largeHill, 3); + } + + private void registerHill(String[] definitions, int tier) { + for (String definition : definitions) { + if (!parseStalactite(definition, tier)) { + TwilightForestMod.LOGGER.warn("Invalid hollow hill stalactite definition: {}", definition); + } + } + } + + private boolean parseStalactite(String definition, int tier) { + String[] split = definition.split(" "); + if (split.length != 5) return false; + + Optional state = parseBlockState(split[0]); + if (!state.isPresent()) return false; + + try { + TFGenCaveStalactite.addStalactite(tier, state.get(), + Float.parseFloat(split[1]), + Integer.parseInt(split[2]), + Integer.parseInt(split[3]), + Integer.parseInt(split[4]) + ); + } catch (NumberFormatException e) { + return false; + } + return true; + } + } + } + + @Config.RequiresMcRestart + @Config.LangKey(config + "compat") + @Config.Comment("Should TF Compatibility load? Turn off if TF's Compatibility is causing crashes or if not desired.") + public static boolean doCompat = true; + + @Config.LangKey(config + "performance") + @Config.Comment("Lets you sacrifice various things to improve world performance.") + public static Performance performance = new Performance(); + + public static class Performance { + @Config.LangKey(config + "canopy_coverage") + @Config.RangeDouble(min = 0) + @Config.Comment("Amount of canopy coverage. Lower numbers improve chunk generation speed at the cost of a thinner forest.") + public float canopyCoverage = 1.7F; + + @Config.LangKey(config + "twilight_oaks") + @Config.RangeInt(min = 1) + @Config.Comment("Chance that a chunk in the Twilight Forest will contain a twilight oak tree. Higher numbers reduce the number of trees, increasing performance.") + public int twilightOakChance = 48; + + @Config.LangKey(config + "leaves_light_opacity") + @Config.RangeInt(min = 0, max = 255) + @Config.Comment("This controls the opacity of leaves, changing the amount of light blocked. Can be used to decrease complexity in some lighting checks.") + public int leavesLightOpacity = 1; + + @Config.LangKey(config + "glacier_packed_ice") + @Config.Comment("Setting this true will make Twilight Glaciers generate with Packed Ice instead of regular translucent Ice, decreasing amount of light checking calculations.") + public boolean glacierPackedIce = false; + + @Config.LangKey(config + "enable_skylight") + @Config.Comment("If the dimension has per-block skylight values. Disabling this will significantly improve world generation performance, at the cost of flat lighting everywhere." + + "\nWARNING: Once chunks are loaded without skylight, that data is lost and cannot easily be regenerated. Be careful!") + @Config.RequiresWorldRestart + public boolean enableSkylight = true; + + @Config.Ignore + public boolean shadersSupported = true; + } + + @Config.LangKey(config + "silent_cicadas") + @Config.Comment("Make cicadas silent for those having sound library problems, or otherwise finding them annoying.") + public static boolean silentCicadas = false; + + @Config.LangKey(config + "first_person_effects") + @Config.Comment("Controls whether various effects from the mod are rendered while in first-person view. Turn this off if you find them distracting.") + public static boolean firstPersonEffects = true; + + @Config.LangKey(config + "origin_dimension") + @Config.Comment("The dimension you can always travel to the Twilight Forest from, as well as the dimension you will return to. Defaults to the overworld.") + public static int originDimension = 0; + + @Config.LangKey(config + "portals_in_other_dimensions") + @Config.Comment("Allow portals to the Twilight Forest to be made outside of the 'origin' dimension. May be considered an exploit.") + public static boolean allowPortalsInOtherDimensions = false; + + @Config.LangKey(config + "admin_portals") + @Config.Comment("Allow portals only for admins (Operators). This severely reduces the range in which the mod usually scans for valid portal conditions, and it scans near ops only.") + public static boolean adminOnlyPortals = false; + + @Config.LangKey(config + "portals") + @Config.Comment("Disable Twilight Forest portal creation entirely. Provided for server operators looking to restrict action to the dimension.") + public static boolean disablePortalCreation = false; + + @Config.LangKey(config + "portal_creator") + @Config.Comment("Registry String IDs of items used to create the Twilight Forest Portal. (domain:regname:meta) meta is optional.") + public static String[] portalCreationItems = {"minecraft:diamond"}; + + @Config.LangKey(config + "check_portal_destination") + @Config.Comment("Determines if new portals should be pre-checked for safety. If enabled, portals will fail to form rather than redirect to a safe alternate destination." + + "\nNote that enabling this also reduces the rate at which portal formation checks are performed.") + public static boolean checkPortalDestination = false; + + @Config.LangKey(config + "portal_lighting") + @Config.Comment("Set this true if you want the lightning that zaps the portal to not set things on fire. For those who don't like fun.") + public static boolean portalLightning = false; + + @Config.LangKey(config + "portal_return") + @Config.Comment("If false, the return portal will require the activation item.") + public static boolean shouldReturnPortalBeUsable = true; + + @Config.LangKey(config + "progression_default") + @Config.Comment("Sets the default value of the game rule controlling enforced progression.") + public static boolean progressionRuleDefault = true; + + @Config.RequiresMcRestart + @Config.LangKey(config + "uncrafting") + @Config.Comment("Disable the uncrafting function of the uncrafting table. Provided as an option when interaction with other mods produces exploitable recipes.") + public static boolean disableUncrafting = false; + + @Config.LangKey(config + "antibuilder_blacklist") + @Config.Comment("Anti-Builder blacklist. (domain:block:meta) meta is optional.") + public static String[] antibuilderBlacklist = {"minecraft:bedrock", "tombmanygraves:grave_block"}; + + @Config.LangKey(config + "animate_trophyitem") + @Config.Comment("Rotate trophy heads on item model. Has no performance impact at all. For those who don't like fun.") + public static boolean rotateTrophyHeadsGui = true; + + @Config.LangKey(config + "shield_parry") + @Config.Comment("We recommend downloading the Shield Parry mod for parrying, but these controls remain for without.") + public static ShieldInteractions shieldInteractions = new ShieldInteractions(); + + public static class ShieldInteractions { + @Config.LangKey(config + "parry_non_twilight") + @Config.Comment("Set to true to parry non-Twilight projectiles.") + public boolean parryNonTwilightAttacks = false; + + @Config.LangKey(config + "parry_window_arrow") + @Config.RangeInt(min = 0) + @Config.Comment("The amount of ticks after raising a shield that makes it OK to parry an arrow.") + public int shieldParryTicksArrow = 40; + + @Config.LangKey(config + "parry_window_fireball") + @Config.RangeInt(min = 0) + @Config.Comment("The amount of ticks after raising a shield that makes it OK to parry a fireball.") + public int shieldParryTicksFireball = 40; + + @Config.LangKey(config + "parry_window_throwable") + @Config.RangeInt(min = 0) + @Config.Comment("The amount of ticks after raising a shield that makes it OK to parry a thrown item.") + public int shieldParryTicksThrowable = 40; + + @Config.LangKey(config + "parry_window_beam") + @Config.RangeInt(min = 0) + public int shieldParryTicksBeam = 10; + } + + @Config.LangKey(config + "loading_screen") + @Config.Comment("Client only: Controls for the Loading screen") + public static final LoadingScreen loadingScreen = new LoadingScreen(); + + public static class LoadingScreen { + @Config.LangKey(config + "loading_icon_enable") + @Config.Comment("Wobble the Loading icon. Has no performance impact at all. For those who don't like fun.") + public boolean enable = true; + + @Config.LangKey(config + "loading_screen_swap_frequency") + @Config.RangeInt(min = 0) + @Config.Comment("How many ticks between each loading screen change. Set to 0 to not cycle at all.") + public int cycleLoadingScreenFrequency = 0; + + @Config.LangKey(config + "loading_icon_wobble_bounce_frequency") + @Config.RangeDouble(min = 0F) + @Config.Comment("Frequency of wobble and bounce.") + public float frequency = 5F; + + @Config.LangKey(config + "loading_icon_scale") + @Config.RangeDouble(min = 0F) + @Config.Comment("Scale of whole bouncy loading icon.") + public float scale = 3F; + + @Config.LangKey(config + "loading_icon_bounciness") + @Config.RangeDouble(min = 0F) + @Config.Comment("How much the loading icon bounces.") + public float scaleDeviation = 5.25F; + + @Config.LangKey(config + "loading_icon_tilting") + @Config.RangeDouble(min = 0F, max = 360F) + @Config.Comment("How far the loading icon wobbles.") + public float tiltRange = 11.25F; + + @Config.LangKey(config + "loading_icon_tilt_pushback") + @Config.RangeDouble(min = 0F, max = 360F) + @Config.Comment("Pushback value to re-center the wobble of loading icon.") + public float tiltConstant = 22.5F; + + @Config.LangKey(config + "loading_icon_stacks") + @Config.Comment("List of items to be used for the wobbling Loading Icon. (domain:item:meta) meta is optional.") + public String[] loadingIconStacks = { + "twilightforest:experiment_115", + "twilightforest:magic_map", + "twilightforest:charm_of_life_2", + "twilightforest:charm_of_keeping_3", + "twilightforest:phantom_helmet", + "twilightforest:lamp_of_cinders", + "twilightforest:carminite", + "twilightforest:block_and_chain", + "twilightforest:yeti_helmet", + "twilightforest:hydra_chop", + "twilightforest:magic_beans", + "twilightforest:ironwood_raw", + "twilightforest:naga_scale", + "twilightforest:experiment_115:2", + "twilightforest:miniature_structure", + "twilightforest:miniature_structure:6", + "twilightforest:knightmetal_block", + "twilightforest:tower_device:10", + "twilightforest:twilight_sapling:5", + "twilightforest:twilight_sapling:6", + "twilightforest:twilight_sapling:7", + "twilightforest:twilight_sapling:8", + "twilightforest:twilight_sapling:9", + "twilightforest:borer_essence" + }; + + @Config.Ignore + private ImmutableList loadingScreenIcons; + + public ImmutableList getLoadingScreenIcons() { + return loadingScreenIcons; + } + + void loadLoadingScreenIcons() { + ImmutableList.Builder iconList = ImmutableList.builder(); + + iconList.addAll(IMCHandler.getLoadingIconStacks()); + + for (String s : loadingIconStacks) { + parseItemStack(s, 0).ifPresent(iconList::add); + } + + loadingScreenIcons = iconList.build(); + } + } + + @SubscribeEvent + public static void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event) { + if (event.getModID().equals(TwilightForestMod.ID)) { + TwilightForestMod.checkOriginDimension(); + ConfigManager.sync(TwilightForestMod.ID, Config.Type.INSTANCE); + if (!event.isWorldRunning()) { + WorldProviderTwilightForest.syncFromConfig(); + } + build(); + } + } + + public static void build() { + loadAntiBuilderBlacklist(); + buildPortalIngredient(); + loadingScreen.loadLoadingScreenIcons(); + } + + private static void loadAntiBuilderBlacklist() { + ImmutableSet.Builder builder = ImmutableSet.builder(); + + builder.addAll(IMCHandler.getBlacklistedBlocks()); + + for (String s : antibuilderBlacklist) { + parseBlockState(s).ifPresent(builder::add); + } + + disallowBreakingBlockList = builder.build(); + } + + @Config.Ignore + private static ImmutableSet disallowBreakingBlockList; + + public static ImmutableSet getDisallowedBlocks() { + return disallowBreakingBlockList; + } + + @Config.Ignore + public static Ingredient portalIngredient; + + private static void buildPortalIngredient() { + + List stacks = new ArrayList<>(); + + for (String s : portalCreationItems) { + parseItemStack(s, OreDictionary.WILDCARD_VALUE).ifPresent(stacks::add); + } + + if (stacks.isEmpty()) { + stacks.add(new ItemStack(Items.DIAMOND)); + } + + portalIngredient = Ingredient.fromStacks(stacks.toArray(new ItemStack[0])); + } + + private static Optional parseItemStack(String string, int defaultMeta) { + + String[] split = string.split(":"); + if (split.length < 2) return Optional.empty(); + + Item item = Item.REGISTRY.getObject(new ResourceLocation(split[0], split[1])); + if (item == null || item == Items.AIR) return Optional.empty(); + + int meta = defaultMeta; + if (split.length > 2) { + try { + meta = Integer.parseInt(split[2]); + } catch (NumberFormatException e) { + return Optional.empty(); + } + } + if (meta < 0 || meta > Short.MAX_VALUE) return Optional.empty(); + + return Optional.of(new ItemStack(item, 1, meta)); + } + + private static Optional parseBlockState(String string) { + + String[] split = string.split(":"); + if (split.length < 2) return Optional.empty(); + + Block block = Block.REGISTRY.getObject(new ResourceLocation(split[0], split[1])); + if (block == Blocks.AIR) return Optional.empty(); + + if (split.length == 2) { + return Optional.of(block.getDefaultState()); + } + + int meta; + try { + meta = Integer.parseInt(split[2]); + } catch (NumberFormatException e) { + return Optional.empty(); + } + if (meta < 0 || meta > 15) return Optional.empty(); + + return Optional.of(block.getStateFromMeta(meta)); + } +} diff --git a/src/main/java/twilightforest/TFDataFixers.java b/src/main/java/twilightforest/TFDataFixers.java new file mode 100644 index 0000000000..60573a447b --- /dev/null +++ b/src/main/java/twilightforest/TFDataFixers.java @@ -0,0 +1,131 @@ +package twilightforest; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.datafix.FixTypes; +import net.minecraft.util.datafix.IFixableData; +import net.minecraftforge.common.util.ModFixs; +import net.minecraftforge.fml.common.FMLCommonHandler; + +import java.util.Map; + +public class TFDataFixers { + public static final int DATA_FIXER_VERSION = 1; + + public static void init() { + ModFixs fixes = FMLCommonHandler.instance().getDataFixer().init(TwilightForestMod.ID, DATA_FIXER_VERSION); + + fixes.registerFix(FixTypes.BLOCK_ENTITY, new NamespaceTEFixer()); + fixes.registerFix(FixTypes.STRUCTURE, new StructureStartIDFixer()); + } + + private static class NamespaceTEFixer implements IFixableData { + // array only needs to cover legacy tile entity ids, no need to add future tile entity ids to list. + private final Map tileEntityNames; + + { + ImmutableMap.Builder nameMap = ImmutableMap.builder(); + + nameMap + .put("minecraft:firefly" , "twilightforest:firefly" ) + .put("minecraft:cicada" , "twilightforest:cicada" ) + .put("minecraft:moonworm" , "twilightforest:moonworm" ) + .put("minecraft:naga_spawner" , "twilightforest:naga_spawner" ) + .put("minecraft:lich_spawner" , "twilightforest:lich_spawner" ) + .put("minecraft:hydra_spawner" , "twilightforest:hydra_spawner" ) + .put("minecraft:smoker" , "twilightforest:smoker" ) + .put("minecraft:popping_jet" , "twilightforest:popping_jet" ) + .put("minecraft:flame_jet" , "twilightforest:flame_jet" ) + .put("minecraft:tower_builder" , "twilightforest:tower_builder" ) + .put("minecraft:tower_reverter" , "twilightforest:tower_reverter" ) + .put("minecraft:trophy" , "twilightforest:trophy" ) + .put("minecraft:tower_boss_spawner" , "twilightforest:tower_boss_spawner" ) + .put("minecraft:ghast_trap_inactive" , "twilightforest:ghast_trap_inactive" ) + .put("minecraft:ghast_trap_active" , "twilightforest:ghast_trap_active" ) + .put("minecraft:carminite_reactor_active", "twilightforest:carminite_reactor_active") + .put("minecraft:knight_phantom_spawner" , "twilightforest:knight_phantom_spawner" ) + .put("minecraft:snow_queen_spawner" , "twilightforest:snow_queen_spawner" ) + .put("minecraft:cinder_furnace" , "twilightforest:cinder_furnace" ) + .put("minecraft:minoshroom_spawner" , "twilightforest:minoshroom_spawner" ) + .put("minecraft:alpha_yeti_spawner" , "twilightforest:alpha_yeti_spawner" ) + .put( "firefly" , "twilightforest:firefly" ) + .put( "cicada" , "twilightforest:cicada" ) + .put( "moonworm" , "twilightforest:moonworm" ) + .put( "naga_spawner" , "twilightforest:naga_spawner" ) + .put( "lich_spawner" , "twilightforest:lich_spawner" ) + .put( "hydra_spawner" , "twilightforest:hydra_spawner" ) + .put( "smoker" , "twilightforest:smoker" ) + .put( "popping_jet" , "twilightforest:popping_jet" ) + .put( "flame_jet" , "twilightforest:flame_jet" ) + .put( "tower_builder" , "twilightforest:tower_builder" ) + .put( "tower_reverter" , "twilightforest:tower_reverter" ) + .put( "trophy" , "twilightforest:trophy" ) + .put( "tower_boss_spawner" , "twilightforest:tower_boss_spawner" ) + .put( "ghast_trap_inactive" , "twilightforest:ghast_trap_inactive" ) + .put( "ghast_trap_active" , "twilightforest:ghast_trap_active" ) + .put( "carminite_reactor_active", "twilightforest:carminite_reactor_active") + .put( "knight_phantom_spawner" , "twilightforest:knight_phantom_spawner" ) + .put( "snow_queen_spawner" , "twilightforest:snow_queen_spawner" ) + .put( "cinder_furnace" , "twilightforest:cinder_furnace" ) + .put( "minoshroom_spawner" , "twilightforest:minoshroom_spawner" ) + .put( "alpha_yeti_spawner" , "twilightforest:alpha_yeti_spawner" ); + + tileEntityNames = nameMap.build(); + } + + @Override + public int getFixVersion() { + return 1; + } + + @Override + public NBTTagCompound fixTagCompound(NBTTagCompound compound) { + String tileEntityLocation = compound.getString("id"); + + compound.setString("id", tileEntityNames.getOrDefault(tileEntityLocation, tileEntityLocation)); + + return compound; + } + } + + private static class StructureStartIDFixer implements IFixableData { + private final String[] startIDs = { + "TFNothing", // Nothing + "TFHill" , // Small Hill + "TFHill" , // Medium + "TFHill" , // Large + "TFHedge" , // Hedge Maze + "TFNC" , // Courtyard + "TFLT" , // Lich Tower + "TFAP" , // Aurora Palace + "TFNothing", // (Quest Island) + "TFQuest1" , // Quest Grove + "TFNothing", // (Druid Grove) + "TFNothing", // (Floating Ruins) + "TFHydra" , // Hydra Lair + "TFLr" , // Labyrinth + "TFDT" , // Dark Tower + "TFKSt" , // Knight Stronghold + "TFNothing", // (World Tree) + "TFYeti" , // Yeti Cave + "TFTC" , // Troll cave + "TFFC" , // Final Castle + "TFMT" // Mushroom Tower + }; + + @Override + public int getFixVersion() { + return 1; + } + + // Basically we just need to shove the structure ID from the `FeatureID` key to the regular `id`. + @Override + public NBTTagCompound fixTagCompound(NBTTagCompound compound) { + int featureID = compound.getInteger("FeatureID"); + + compound.setString("id", featureID < startIDs.length ? startIDs[featureID] : "TFNothing"); + + return compound; + } + } +} diff --git a/src/main/java/twilightforest/TFEventListener.java b/src/main/java/twilightforest/TFEventListener.java index 7272edcf84..192459fb87 100644 --- a/src/main/java/twilightforest/TFEventListener.java +++ b/src/main/java/twilightforest/TFEventListener.java @@ -1,674 +1,427 @@ package twilightforest; -import java.util.ArrayList; -import java.util.HashMap; - +import com.google.common.collect.ImmutableSet; import net.minecraft.block.Block; -import net.minecraft.block.BlockSapling; -import net.minecraft.client.Minecraft; -import net.minecraft.command.CommandGameRule; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.item.EntityXPOrb; -import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.entity.projectile.EntityFireball; +import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Blocks; -import net.minecraft.init.Items; +import net.minecraft.init.MobEffects; +import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; -import net.minecraft.potion.Potion; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.network.play.INetHandlerPlayServer; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.ChatComponentText; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.GameRules; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.common.ISpecialArmor.ArmorProperties; -import net.minecraftforge.event.CommandEvent; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.event.GameRuleChangeEvent; +import net.minecraftforge.event.entity.ProjectileImpactEvent; import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingDeathEvent; +import net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; -import net.minecraftforge.event.entity.player.BonemealEvent; -import net.minecraftforge.event.entity.player.EntityItemPickupEvent; +import net.minecraftforge.event.entity.player.AdvancementEvent; +import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; import net.minecraftforge.event.world.BlockEvent.BreakEvent; import net.minecraftforge.event.world.BlockEvent.HarvestDropsEvent; import net.minecraftforge.event.world.WorldEvent; -import twilightforest.biomes.TFBiomeBase; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.Event.Result; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent.ItemCraftedEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent; +import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent; +import net.minecraftforge.fml.common.network.FMLNetworkEvent; +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.items.ItemHandlerHelper; +import twilightforest.advancements.TFAdvancements; +import twilightforest.block.BlockTFCritter; +import twilightforest.block.BlockTFGiantBlock; +import twilightforest.block.BlockTFPortal; import twilightforest.block.TFBlocks; +import twilightforest.capabilities.CapabilityList; +import twilightforest.capabilities.shield.IShieldCapability; +import twilightforest.compat.Baubles; +import twilightforest.compat.TFCompat; import twilightforest.enchantment.TFEnchantment; import twilightforest.entity.EntityTFCharmEffect; -import twilightforest.entity.EntityTFKobold; -import twilightforest.entity.EntityTFPinchBeetle; -import twilightforest.entity.EntityTFYeti; +import twilightforest.entity.IHostileMount; +import twilightforest.entity.ITFProjectile; +import twilightforest.item.ItemTFPhantomArmor; import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; +import twilightforest.network.PacketAreaProtection; +import twilightforest.network.PacketEnforceProgressionStatus; +import twilightforest.network.PacketSetSkylightEnabled; +import twilightforest.network.PacketUpdateShield; +import twilightforest.network.TFPacketHandler; +import twilightforest.potions.TFPotions; +import twilightforest.util.TFItemStackUtils; +import twilightforest.world.ChunkGeneratorTFBase; +import twilightforest.world.TFWorld; import twilightforest.world.WorldProviderTwilightForest; -import cpw.mods.fml.common.FMLLog; -import cpw.mods.fml.common.eventhandler.Event.Result; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.PlayerEvent.ItemCraftedEvent; -import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent; -import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; -import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent; -import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent; -import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; /** * So much of the mod logic in this one class */ +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) public class TFEventListener { - - protected HashMap playerKeepsMap = new HashMap(); - private boolean isBreakingWithGiantPick = false; - private boolean shouldMakeGiantCobble = false; - private int amountOfCobbleToReplace = 0; - private long lastSpawnedHintMonsterTime; - /** - * Check if the player picks up a lich scepter, and if so, check for the scepter mastery achievement - */ - @SubscribeEvent - public void pickupItem(EntityItemPickupEvent event) { - Item item = event.item.getEntityItem().getItem(); - if (item == TFItems.scepterTwilight || item == TFItems.scepterLifeDrain - || item == TFItems.scepterZombie) { - // the player has picked up a scepter. Check if they have them all in their inventory, and if so, achievement - //System.out.println("Player picked up a scepter"); - checkPlayerForScepterMastery(event.entityPlayer); - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressLich); - } - - // naga scale gives naga progress achievement - if (item == TFItems.nagaScale) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressNaga); - } - // trophy gives kill achievement - if (item == TFItems.trophy && event.item.getEntityItem().getItemDamage() == 0) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightKillHydra); - } - if (item == TFItems.trophy && event.item.getEntityItem().getItemDamage() == 1) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightKillNaga); - } - if (item == TFItems.trophy && event.item.getEntityItem().getItemDamage() == 2) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightKillLich); - } - if (item == TFItems.trophy && event.item.getEntityItem().getItemDamage() == 3) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressUrghast); - } - if (item == TFItems.trophy && event.item.getEntityItem().getItemDamage() == 4) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressGlacier); - } - // mazebreaker - if (item == TFItems.mazebreakerPick) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightMazebreaker); - } - // meef stroganoff (or axe) - if (item == TFItems.meefStroganoff || item == TFItems.minotaurAxe) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressLabyrinth); - } - // fiery blood - if (item == TFItems.fieryBlood) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressHydra); - } - // phantom helm/plate - if (item == TFItems.phantomHelm || item == TFItems.phantomPlate) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressKnights); - } - // fiery tears - if (item == TFItems.fieryTears) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressUrghast); - } - // yeti items - if (item == TFItems.alphaFur || item == TFItems.yetiBoots || item == TFItems.yetiHelm - || item == TFItems.yetiPlate || item == TFItems.yetiLegs) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressYeti); - } - // lamp of cinders - if (item == TFItems.lampOfCinders) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightProgressTroll); - } - } + private static final ImmutableSet SHIELD_DAMAGE_BLACKLIST = ImmutableSet.of( + "inWall", "cramming", "drown", "starve", "fall", "flyIntoWall", "outOfWorld", "fallingBlock" + ); - /** - * Does the player have all three scepters somewhere in the inventory? - * @param player - */ - private void checkPlayerForScepterMastery(EntityPlayer player) - { - boolean scepterTwilight = false; - boolean scepterLifeDrain = false; - boolean scepterZombie = false; - - IInventory inv = player.inventory; - - for (int i = 0; i < inv.getSizeInventory(); i++) - { - ItemStack stack = inv.getStackInSlot(i); - - if (stack != null && stack.getItem() == TFItems.scepterTwilight) - { - scepterTwilight = true; - } - if (stack != null && stack.getItem() == TFItems.scepterLifeDrain) - { - scepterLifeDrain = true; - } - if (stack != null && stack.getItem() == TFItems.scepterZombie) - { - scepterZombie = true; - } - } - - if (scepterTwilight && scepterLifeDrain && scepterZombie) - { - player.triggerAchievement(TFAchievementPage.twilightLichScepters); - } - } + private static final Map playerKeepsMap = new HashMap<>(); + private static final Map> playerKeepsMapBaubles = new HashMap<>(); + + private static boolean isBreakingWithGiantPick = false; + private static boolean shouldMakeGiantCobble = false; + private static int amountOfCobbleToReplace = 0; - /** - * Check if we've crafted something that there's an achievement for - */ @SubscribeEvent - public void onCrafting(ItemCraftedEvent event) { - - //System.out.println("Getting item crafted event"); - + public static void onCrafting(ItemCraftedEvent event) { ItemStack itemStack = event.crafting; EntityPlayer player = event.player; - - // if the item is naga armor - if ((itemStack.getItem() == TFItems.plateNaga || itemStack.getItem() == TFItems.legsNaga)) { - // check if the player has made both armors - checkPlayerForNagaArmorer(player); - } - - // trigger achievements - if (itemStack.getItem() == TFItems.magicMapFocus) { - player.triggerAchievement(TFAchievementPage.twilightMagicMapFocus); - } - if (itemStack.getItem() == TFItems.emptyMagicMap) { - player.triggerAchievement(TFAchievementPage.twilightMagicMap); - } - if (itemStack.getItem() == TFItems.emptyMazeMap) { - player.triggerAchievement(TFAchievementPage.twilightMazeMap); - } - if (itemStack.getItem() == TFItems.emptyOreMap) { - player.triggerAchievement(TFAchievementPage.twilightOreMap); - } - - // if we've crafted 64 planks from a giant log, sneak 192 more planks into the player's inventory or drop them nearby - if (itemStack.getItem() == Item.getItemFromBlock(Blocks.planks) && itemStack.stackSize == 64 && this.doesCraftMatrixHaveGiantLog(event.craftMatrix)) { - addToPlayerInventoryOrDrop(player, new ItemStack(Blocks.planks, 64)); - addToPlayerInventoryOrDrop(player, new ItemStack(Blocks.planks, 64)); - addToPlayerInventoryOrDrop(player, new ItemStack(Blocks.planks, 64)); - - } - } - - private void addToPlayerInventoryOrDrop(EntityPlayer player, ItemStack planks) { - if (!player.inventory.addItemStackToInventory(planks)) { - player.dropPlayerItemWithRandomChoice(planks, false); - } - } - - private boolean doesCraftMatrixHaveGiantLog(IInventory inv) { + + // if we've crafted 64 planks from a giant log, sneak 192 more planks into the player's inventory or drop them nearby + if (itemStack.getItem() == Item.getItemFromBlock(Blocks.PLANKS) && itemStack.getCount() == 64 && doesCraftMatrixHaveGiantLog(event.craftMatrix)) { + ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(Blocks.PLANKS, 64)); + ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(Blocks.PLANKS, 64)); + ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(Blocks.PLANKS, 64)); + } + } + + private static boolean doesCraftMatrixHaveGiantLog(IInventory inv) { + Item giantLogItem = Item.getItemFromBlock(TFBlocks.giant_log); for (int i = 0; i < inv.getSizeInventory(); i++) { - ItemStack stack = inv.getStackInSlot(i); - - if (stack != null && stack.getItem() == Item.getItemFromBlock(TFBlocks.giantLog)) { + if (inv.getStackInSlot(i).getItem() == giantLogItem) { return true; } } - - return false; } /** - * Does the player have two naga armors? - */ - private void checkPlayerForNagaArmorer(EntityPlayer player) - { - boolean nagaScale = false; - boolean legsNaga = false; - - IInventory inv = player.inventory; - - for (int i = 0; i < inv.getSizeInventory(); i++) - { - ItemStack stack = inv.getStackInSlot(i); - - if (stack != null && stack.getItem() == TFItems.nagaScale) - { - nagaScale = true; - } - if (stack != null && stack.getItem() == TFItems.legsNaga) - { - legsNaga = true; - } - } - - if (nagaScale && legsNaga) - { - player.triggerAchievement(TFAchievementPage.twilightNagaArmors); - } - } - - /** - * Check to see if a smeltable block has dropped with a fiery tool, and if so, smelt it * Also check if we need to transform 64 cobbles into a giant cobble */ @SubscribeEvent - public void harvestDrops(HarvestDropsEvent event) { - if (event.harvester != null && event.harvester.inventory.getCurrentItem() != null && event.harvester.inventory.getCurrentItem().getItem().func_150897_b(event.block)) { - if (event.harvester.inventory.getCurrentItem().getItem() == TFItems.fieryPick) { - ArrayList removeThese = new ArrayList(1); - ArrayList addThese = new ArrayList(1); - - for (ItemStack input : event.drops) - { - // does it smelt? - ItemStack result = FurnaceRecipes.smelting().getSmeltingResult(input); - if (result != null) - { - addThese.add(new ItemStack(result.getItem(), input.stackSize)); - removeThese.add(input); - - // spawn XP - spawnSpeltXP(result, event.world, event.x, event.y, event.z); - } - } - - // remove things we've decided to remove - event.drops.removeAll(removeThese); - - // add things we add - event.drops.addAll(addThese); - } - } - + public static void harvestDrops(HarvestDropsEvent event) { // this flag is set in reaction to the breakBlock event, but we need to remove the drops in this event - if (this.shouldMakeGiantCobble && event.drops.size() > 0) { + if (shouldMakeGiantCobble && event.getDrops().size() > 0) { // turn the next 64 cobblestone drops into one giant cobble - if (event.drops.get(0).getItem() == Item.getItemFromBlock(Blocks.cobblestone)) { - event.drops.remove(0); - if (this.amountOfCobbleToReplace == 64) { - event.drops.add(new ItemStack(TFBlocks.giantCobble)); + if (event.getDrops().get(0).getItem() == Item.getItemFromBlock(Blocks.COBBLESTONE)) { + event.getDrops().remove(0); + if (amountOfCobbleToReplace == 64) { + event.getDrops().add(new ItemStack(TFBlocks.giant_cobblestone)); } - - this.amountOfCobbleToReplace--; - - if (this.amountOfCobbleToReplace <= 0) { - this.shouldMakeGiantCobble = false; + + amountOfCobbleToReplace--; + + if (amountOfCobbleToReplace <= 0) { + shouldMakeGiantCobble = false; } } } } - /** - * Spawn XP for smelting the specified item at the specified location - */ - private void spawnSpeltXP(ItemStack smelted, World world, int x, int y, int z) { - float floatXP = FurnaceRecipes.smelting().func_151398_b(smelted); - int smeltXP = (int)floatXP; - // random chance of +1 XP to handle fractions - if (floatXP > smeltXP && world.rand.nextFloat() < (floatXP - smeltXP)) - { - smeltXP++; - } + @SubscribeEvent + public static void entityHurts(LivingHurtEvent event) { - while (smeltXP > 0) - { - int splitXP = EntityXPOrb.getXPSplit(smeltXP); - smeltXP -= splitXP; - world.spawnEntityInWorld(new EntityXPOrb(world, x + 0.5D, y + 0.5D, z + 0.5D, splitXP)); - } - } + EntityLivingBase living = event.getEntityLiving(); + DamageSource damageSource = event.getSource(); + String damageType = damageSource.getDamageType(); + Entity trueSource = damageSource.getTrueSource(); - /** - * We wait for a player wearing armor with the fire react enchantment to get hurt, and if that happens, we react - */ - @SubscribeEvent - public void entityHurts(LivingHurtEvent event) - { // fire aura - if (event.entityLiving instanceof EntityPlayer && event.source.damageType.equals("mob") && event.source.getEntity() != null) - { - EntityPlayer player = (EntityPlayer)event.entityLiving; - int fireLevel = TFEnchantment.getFieryAuraLevel(player.inventory, event.source); - - //System.out.println("Detecting a fire reaction event. Reaction level is " + fireLevel); - - if (fireLevel > 0 && player.getRNG().nextInt(25) < fireLevel) - { - //System.out.println("Executing fire reaction."); - event.source.getEntity().setFire(fireLevel / 2); + if (living instanceof EntityPlayer && damageType.equals("mob") && trueSource != null) { + EntityPlayer player = (EntityPlayer) living; + int fireLevel = TFEnchantment.getFieryAuraLevel(player.inventory, damageSource); + + if (fireLevel > 0 && player.getRNG().nextInt(25) < fireLevel) { + trueSource.setFire(fireLevel / 2); } } - + // chill aura - if (event.entityLiving instanceof EntityPlayer && event.source.damageType.equals("mob") - && event.source.getEntity() != null && event.source.getEntity() instanceof EntityLivingBase) { - EntityPlayer player = (EntityPlayer)event.entityLiving; - int chillLevel = TFEnchantment.getChillAuraLevel(player.inventory, event.source); - - //System.out.println("Detecting a chill aura event. Reaction level is " + chillLevel); - - if (chillLevel > 0) { - //System.out.println("Executing chill reaction."); - ((EntityLivingBase)event.source.getEntity()).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, chillLevel * 5 + 5, chillLevel)); + if (living instanceof EntityPlayer && damageType.equals("mob") && trueSource instanceof EntityLivingBase) { + EntityPlayer player = (EntityPlayer) living; + int chillLevel = TFEnchantment.getChillAuraLevel(player.inventory, damageSource); + if (chillLevel > 0) { + ((EntityLivingBase) trueSource).addPotionEffect(new PotionEffect(TFPotions.frosty, chillLevel * 5 + 5, chillLevel)); } } - + // triple bow strips hurtResistantTime - if (event.source.damageType.equals("arrow") && event.source.getEntity() != null && event.source.getEntity() instanceof EntityPlayer) { - EntityPlayer player = (EntityPlayer)event.source.getEntity(); - - if (player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() == TFItems.tripleBow) { - //System.out.println("Triplebow Arrows!"); - event.entityLiving.hurtResistantTime = 0; - } - } - - // ice bow freezes - if (event.source.damageType.equals("arrow") && event.source.getEntity() != null && event.source.getEntity() instanceof EntityPlayer) { - EntityPlayer player = (EntityPlayer)event.source.getEntity(); - - if (player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() == TFItems.iceBow) { + if (damageType.equals("arrow") && trueSource instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) trueSource; - int chillLevel = 2; - event.entityLiving.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 20 * 10, chillLevel, true)); + if (player.getHeldItemMainhand().getItem() == TFItems.triple_bow || player.getHeldItemOffhand().getItem() == TFItems.triple_bow) { + living.hurtResistantTime = 0; } } - + // enderbow teleports - if (event.source.damageType.equals("arrow") && event.source.getEntity() != null && event.source.getEntity() instanceof EntityPlayer) { - EntityPlayer player = (EntityPlayer)event.source.getEntity(); - - if (player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() == TFItems.enderBow) { - - double sourceX = player.posX; - double sourceY = player.posY; - double sourceZ = player.posZ; - float sourceYaw = player.rotationYaw; - float sourcePitch = player.rotationPitch; - + if (damageType.equals("arrow") && trueSource instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) trueSource; + + if (player.getHeldItemMainhand().getItem() == TFItems.ender_bow || player.getHeldItemOffhand().getItem() == TFItems.ender_bow) { + + double sourceX = player.posX, sourceY = player.posY, sourceZ = player.posZ; + float sourceYaw = player.rotationYaw, sourcePitch = player.rotationPitch; + // this is the only method that will move the player properly - player.rotationYaw = event.entityLiving.rotationYaw; - player.rotationPitch = event.entityLiving.rotationPitch; - player.setPositionAndUpdate(event.entityLiving.posX, event.entityLiving.posY, event.entityLiving.posZ); - player.playSound("mob.endermen.portal", 1.0F, 1.0F); + player.rotationYaw = living.rotationYaw; + player.rotationPitch = living.rotationPitch; + player.setPositionAndUpdate(living.posX, living.posY, living.posZ); + player.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0F); - // monsters are easy to move - event.entityLiving.setPositionAndRotation(sourceX, sourceY, sourceZ, sourceYaw, sourcePitch); - event.entityLiving.playSound("mob.endermen.portal", 1.0F, 1.0F); - - - //System.out.println("Enderbow Arrow!"); + living.setPositionAndRotation(sourceX, sourceY, sourceZ, sourceYaw, sourcePitch); + living.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0F); } } - - // charm of life? - if (event.entityLiving instanceof EntityPlayer && willEntityDie(event)) - { - EntityPlayer player = (EntityPlayer)event.entityLiving; - - boolean charm1 = false; - boolean charm2 = player.inventory.consumeInventoryItem(TFItems.charmOfLife2); - if (!charm2) - { - charm1 = player.inventory.consumeInventoryItem(TFItems.charmOfLife1); + + // Smashing! + ItemStack stack = living.getItemStackFromSlot(EntityEquipmentSlot.HEAD); + Block block = Block.getBlockFromItem(stack.getItem()); + if (block instanceof BlockTFCritter) { + BlockTFCritter poorBug = (BlockTFCritter) block; + living.setItemStackToSlot(EntityEquipmentSlot.HEAD, poorBug.getSquishResult()); + living.world.playSound(null, living.posX, living.posY, living.posZ, poorBug.getSoundType().getBreakSound(), living.getSoundCategory(), 1, 1); + } + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public static void charmOfLife(LivingDeathEvent event) { + EntityLivingBase living = event.getEntityLiving(); + if (living.world.isRemote || !(living instanceof EntityPlayer) || living instanceof FakePlayer) return; + + boolean charm1 = false; + boolean charm2 = TFItemStackUtils.consumeInventoryItem(living, s -> s.getItem() == TFItems.charm_of_life_2, 1); + if (!charm2) { + charm1 = TFItemStackUtils.consumeInventoryItem(living, s -> s.getItem() == TFItems.charm_of_life_1, 1); + } + + if (charm2 || charm1) { + + if (charm1) { + living.setHealth(8); + living.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, 100, 0)); } - - // do they have a charm of life? OM NOM NOM! - if (charm2 || charm1) - { - //player.addChatMessage("Charm of Life saves you!!!"); - - // cancel damage - event.setResult(Result.DENY); - event.setCanceled(true); - event.ammount = 0; - if (charm1) - { - player.setHealth(8); - player.addPotionEffect(new PotionEffect(Potion.regeneration.id, 100, 0)); - } - - if (charm2) - { - player.setHealth((float) player.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue()); - - player.addPotionEffect(new PotionEffect(Potion.regeneration.id, 600, 3)); - player.addPotionEffect(new PotionEffect(Potion.resistance.id, 600, 0)); - player.addPotionEffect(new PotionEffect(Potion.fireResistance.id, 600, 0)); - } - - // spawn effect thingers - EntityTFCharmEffect effect = new EntityTFCharmEffect(player.worldObj, player, charm1 ? TFItems.charmOfLife1 : TFItems.charmOfLife2); - player.worldObj.spawnEntityInWorld(effect); - - EntityTFCharmEffect effect2 = new EntityTFCharmEffect(player.worldObj, player, charm1 ? TFItems.charmOfLife1 : TFItems.charmOfLife2); - effect2.offset = (float) Math.PI; - player.worldObj.spawnEntityInWorld(effect2); - - // sound - player.worldObj.playSoundEffect(player.posX + 0.5D, player.posY + 0.5D, player.posZ + 0.5D, "mob.zombie.unfect", 1.5F, 1.0F); + if (charm2) { + living.setHealth((float) living.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).getBaseValue()); + living.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, 600, 3)); + living.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 600, 0)); + living.addPotionEffect(new PotionEffect(MobEffects.FIRE_RESISTANCE, 600, 0)); } + + // spawn effect thingers + EntityTFCharmEffect effect = new EntityTFCharmEffect(living.world, living, charm1 ? TFItems.charm_of_life_1 : TFItems.charm_of_life_2); + living.world.spawnEntity(effect); + + EntityTFCharmEffect effect2 = new EntityTFCharmEffect(living.world, living, charm1 ? TFItems.charm_of_life_1 : TFItems.charm_of_life_2); + effect2.offset = (float) Math.PI; + living.world.spawnEntity(effect2); + + living.world.playSound(null, living.posX, living.posY, living.posZ, SoundEvents.ITEM_TOTEM_USE, living.getSoundCategory(), 1, 1); + + event.setCanceled(true); } } - /** - * Is this damage likely to kill the target? - */ - public boolean willEntityDie(LivingHurtEvent event) - { - float amount = event.ammount; - DamageSource source = event.source; - EntityLivingBase living = event.entityLiving; - // reduce damage by armor - if (!source.isUnblockable()){ - int armor = 25 - living.getTotalArmorValue(); - //System.out.println("Initial amount = " + amount + ", armor = " + armor + " so damage after armor is " + ((amount * armor) / 25F)); - amount = (amount * armor) / 25F; - } - - // maybe also potions? - if (living.isPotionActive(Potion.resistance)) { - int resistance = 25 - (living.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5; - amount = amount * resistance / 25F; - } - //System.out.printf("I think the player is going to take %f damage and they have %f health.\n", Math.ceil(amount), living.getHealth()); - - return Math.ceil(amount) >= Math.floor(living.getHealth()); - } - - /** - * Catch bonemeal use - */ - @SubscribeEvent - public void bonemealUsed(BonemealEvent event) - { - if (event.block == TFBlocks.sapling) - { - if (!event.world.isRemote) - { - ((BlockSapling)TFBlocks.sapling).func_149878_d(event.world, event.x, event.y, event.z, event.world.rand); + @SubscribeEvent(priority = EventPriority.HIGH) + public static void charmOfKeeping(LivingDeathEvent event) { + EntityLivingBase living = event.getEntityLiving(); - event.setResult(Result.ALLOW); - } - } + if (living.world.isRemote || !(living instanceof EntityPlayer) || living instanceof FakePlayer || living.world.getGameRules().getBoolean("keepInventory")) return; + + keepItems((EntityPlayer) living); } - - - /** - * If a player dies with a charm of keeping, consume the charm and then keep track of what items we need to keep - * - * Also keep tower keys - */ - @SubscribeEvent - public void livingDies(LivingDeathEvent event) - { - if (event.entityLiving instanceof EntityPlayer && !event.entityLiving.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) - { - EntityPlayer player = (EntityPlayer)event.entityLiving; - - if (player.inventory.consumeInventoryItem(TFItems.charmOfKeeping3)) - { - FMLLog.info("[TwilightForest] Player died with charm of keeping III! Keep it all!"); - InventoryPlayer keepInventory = new InventoryPlayer(null); - - // armor and full inventory - keepAllArmor(player, keepInventory); - for (int i = 0; i < player.inventory.mainInventory.length; i++) - { - keepInventory.mainInventory[i] = ItemStack.copyItemStack(player.inventory.mainInventory[i]); - player.inventory.mainInventory[i] = null; - } - keepInventory.setItemStack(new ItemStack(TFItems.charmOfKeeping3)); - playerKeepsMap.put(player.getCommandSenderName(), keepInventory); + private static void keepItems(EntityPlayer player) { + + // drop any existing held items, just in case + dropStoredItems(player); + + // TODO also consider situations where the actual slots may be empty, and charm gets consumed anyway. Usually won't happen. + boolean tier3 = TFItemStackUtils.consumeInventoryItem(player, s -> s.getItem() == TFItems.charm_of_keeping_3, 1); + boolean tier2 = tier3 || TFItemStackUtils.consumeInventoryItem(player, s -> s.getItem() == TFItems.charm_of_keeping_2, 1); + boolean tier1 = tier2 || TFItemStackUtils.consumeInventoryItem(player, s -> s.getItem() == TFItems.charm_of_keeping_1, 1); + + InventoryPlayer keepInventory = new InventoryPlayer(null); + + UUID playerUUID = player.getUniqueID(); + + if (tier1) { + keepAllArmor(player, keepInventory); + keepOffHand(player, keepInventory); + } + + if (tier3) { + for (int i = 0; i < player.inventory.mainInventory.size(); i++) { + keepInventory.mainInventory.set(i, player.inventory.mainInventory.get(i).copy()); + player.inventory.mainInventory.set(i, ItemStack.EMPTY); } - else if (player.inventory.consumeInventoryItem(TFItems.charmOfKeeping2)) - { - FMLLog.info("[TwilightForest] Player died with charm of keeping II! Keep armor and hotbar!"); - InventoryPlayer keepInventory = new InventoryPlayer(null); - - keepAllArmor(player, keepInventory); - for (int i = 0; i < 9; i++) - { - keepInventory.mainInventory[i] = ItemStack.copyItemStack(player.inventory.mainInventory[i]); - player.inventory.mainInventory[i] = null; - } - keepInventory.setItemStack(new ItemStack(TFItems.charmOfKeeping2)); + keepInventory.setItemStack(new ItemStack(TFItems.charm_of_keeping_3)); - playerKeepsMap.put(player.getCommandSenderName(), keepInventory); + } else if (tier2) { + for (int i = 0; i < 9; i++) { + keepInventory.mainInventory.set(i, player.inventory.mainInventory.get(i).copy()); + player.inventory.mainInventory.set(i, ItemStack.EMPTY); } - else if (player.inventory.consumeInventoryItem(TFItems.charmOfKeeping1)) - { - FMLLog.info("[TwilightForest] Player died with charm of keeping I! Keep armor and current item!"); - InventoryPlayer keepInventory = new InventoryPlayer(null); - - keepAllArmor(player, keepInventory); - if (player.inventory.getCurrentItem() != null) - { - keepInventory.mainInventory[player.inventory.currentItem] = ItemStack.copyItemStack(player.inventory.mainInventory[player.inventory.currentItem]); - player.inventory.mainInventory[player.inventory.currentItem] = null; - } - keepInventory.setItemStack(new ItemStack(TFItems.charmOfKeeping1)); + keepInventory.setItemStack(new ItemStack(TFItems.charm_of_keeping_2)); - playerKeepsMap.put(player.getCommandSenderName(), keepInventory); + } else if (tier1) { + int i = player.inventory.currentItem; + if (InventoryPlayer.isHotbar(i)) { + keepInventory.mainInventory.set(i, player.inventory.mainInventory.get(i).copy()); + player.inventory.mainInventory.set(i, ItemStack.EMPTY); } - - // check for tower keys - if (player.inventory.hasItem(TFItems.towerKey)) - { - InventoryPlayer keepInventory = retrieveOrMakeKeepInventory(player); - // keep them all - for (int i = 0; i < player.inventory.mainInventory.length; i++) - { - if (player.inventory.mainInventory[i] != null && player.inventory.mainInventory[i].getItem() == TFItems.towerKey) - { - keepInventory.mainInventory[i] = ItemStack.copyItemStack(player.inventory.mainInventory[i]); - player.inventory.mainInventory[i] = null; - } - } - playerKeepsMap.put(player.getCommandSenderName(), keepInventory); + keepInventory.setItemStack(new ItemStack(TFItems.charm_of_keeping_1)); + } + + // always keep tower keys + for (int i = 0; i < player.inventory.mainInventory.size(); i++) { + ItemStack stack = player.inventory.mainInventory.get(i); + if (stack.getItem() == TFItems.tower_key) { + keepInventory.mainInventory.set(i, stack.copy()); + player.inventory.mainInventory.set(i, ItemStack.EMPTY); } } - - if (playerKeepsMap.size() > 1) - { - FMLLog.warning("[TwilightForest] Twilight Forest mod is keeping track of a lot of dead player inventories. Has there been an apocalypse?"); + + if (tier1 && TFCompat.BAUBLES.isActivated()) { + playerKeepsMapBaubles.put(playerUUID, Baubles.keepBaubles(player)); } + + for (int i = 0; i < player.inventory.armorInventory.size(); i++) { // TODO also consider Phantom tools, when those get added + ItemStack armor = player.inventory.armorInventory.get(i); + if (armor.getItem() instanceof ItemTFPhantomArmor) { + keepInventory.armorInventory.set(i, armor.copy()); + player.inventory.armorInventory.set(i, ItemStack.EMPTY); + } + } + + playerKeepsMap.put(playerUUID, keepInventory); } /** - * If we have a stored inventory already, return that, if not, make a new one. + * Move the full armor inventory to the keep pile */ - private InventoryPlayer retrieveOrMakeKeepInventory(EntityPlayer player) - { - if (playerKeepsMap.containsKey(player.getCommandSenderName())) - { - return playerKeepsMap.get(player.getCommandSenderName()); + private static void keepAllArmor(EntityPlayer player, InventoryPlayer keepInventory) { + for (int i = 0; i < player.inventory.armorInventory.size(); i++) { + keepInventory.armorInventory.set(i, player.inventory.armorInventory.get(i).copy()); + player.inventory.armorInventory.set(i, ItemStack.EMPTY); } - else - { - return new InventoryPlayer(null); + } + + private static void keepOffHand(EntityPlayer player, InventoryPlayer keepInventory) { + for (int i = 0; i < player.inventory.offHandInventory.size(); i++) { + keepInventory.offHandInventory.set(i, player.inventory.offHandInventory.get(i).copy()); + player.inventory.offHandInventory.set(i, ItemStack.EMPTY); } } - /** - * Move the full armor inventory to the keep pile - */ - private void keepAllArmor(EntityPlayer player, InventoryPlayer keepInventory) { - for (int i = 0; i < player.inventory.armorInventory.length; i++) - { - keepInventory.armorInventory[i] = ItemStack.copyItemStack(player.inventory.armorInventory[i]); - player.inventory.armorInventory[i] = null; + @SubscribeEvent + public static void onPlayerRespawn(PlayerRespawnEvent event) { + if (event.isEndConquered()) { + updateCapabilities((EntityPlayerMP) event.player, event.player); + } else { + returnStoredItems(event.player); } } + /** * Maybe we kept some stuff for the player! */ - @SubscribeEvent - public void onPlayerRespawn(PlayerRespawnEvent event) { - EntityPlayer player = event.player; - if (playerKeepsMap.containsKey(player.getCommandSenderName())) - { - FMLLog.info("[TwilightForest] Player %s respawned and recieved items held in storage", player.getCommandSenderName()); - - InventoryPlayer keepInventory = playerKeepsMap.get(player.getCommandSenderName()); - - for (int i = 0; i < player.inventory.armorInventory.length; i++) - { - if (keepInventory.armorInventory[i] != null) - { - player.inventory.armorInventory[i] = keepInventory.armorInventory[i]; + private static void returnStoredItems(EntityPlayer player) { + InventoryPlayer keepInventory = playerKeepsMap.remove(player.getUniqueID()); + if (keepInventory != null) { + TwilightForestMod.LOGGER.debug("Player {} respawned and received items held in storage", player.getName()); + + NonNullList displaced = NonNullList.create(); + + for (int i = 0; i < player.inventory.armorInventory.size(); i++) { + ItemStack kept = keepInventory.armorInventory.get(i); + if (!kept.isEmpty()) { + ItemStack existing = player.inventory.armorInventory.set(i, kept); + if (!existing.isEmpty()) { + displaced.add(existing); + } } } - for (int i = 0; i < player.inventory.mainInventory.length; i++) - { - if (keepInventory.mainInventory[i] != null) - { - player.inventory.mainInventory[i] = keepInventory.mainInventory[i]; + for (int i = 0; i < player.inventory.offHandInventory.size(); i++) { + ItemStack kept = keepInventory.offHandInventory.get(i); + if (!kept.isEmpty()) { + ItemStack existing = player.inventory.offHandInventory.set(i, kept); + if (!existing.isEmpty()) { + displaced.add(existing); + } + } + } + for (int i = 0; i < player.inventory.mainInventory.size(); i++) { + ItemStack kept = keepInventory.mainInventory.get(i); + if (!kept.isEmpty()) { + ItemStack existing = player.inventory.mainInventory.set(i, kept); + if (!existing.isEmpty()) { + displaced.add(existing); + } } } - + + // try to give player any displaced items + for (ItemStack extra : displaced) { + ItemHandlerHelper.giveItemToPlayer(player, extra); + } + // spawn effect thingers - if (keepInventory.getItemStack() != null) - { - EntityTFCharmEffect effect = new EntityTFCharmEffect(player.worldObj, player, keepInventory.getItemStack().getItem()); - player.worldObj.spawnEntityInWorld(effect); - - EntityTFCharmEffect effect2 = new EntityTFCharmEffect(player.worldObj, player, keepInventory.getItemStack().getItem()); + if (!keepInventory.getItemStack().isEmpty()) { + EntityTFCharmEffect effect = new EntityTFCharmEffect(player.world, player, keepInventory.getItemStack().getItem()); + player.world.spawnEntity(effect); + + EntityTFCharmEffect effect2 = new EntityTFCharmEffect(player.world, player, keepInventory.getItemStack().getItem()); effect2.offset = (float) Math.PI; - player.worldObj.spawnEntityInWorld(effect2); - - player.worldObj.playSoundEffect(player.posX + 0.5D, player.posY + 0.5D, player.posZ + 0.5D, "mob.zombie.unfect", 1.5F, 1.0F); + player.world.spawnEntity(effect2); + + player.world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ZOMBIE_VILLAGER_CONVERTED, player.getSoundCategory(), 1.5F, 1.0F); } + } - playerKeepsMap.remove(player.getCommandSenderName()); + if (TFCompat.BAUBLES.isActivated()) { + NonNullList baubles = playerKeepsMapBaubles.remove(player.getUniqueID()); + if (baubles != null) { + TwilightForestMod.LOGGER.debug("Player {} respawned and received baubles held in storage", player.getName()); + Baubles.returnBaubles(player, baubles); + } } } @@ -676,325 +429,404 @@ public void onPlayerRespawn(PlayerRespawnEvent event) { * Dump stored items if player logs out */ @SubscribeEvent - public void onPlayerLogout(PlayerLoggedOutEvent event) { - EntityPlayer player = event.player; - if (playerKeepsMap.containsKey(player.getCommandSenderName())) - { - FMLLog.warning("[TwilightForest] Mod was keeping inventory items in reserve for player %s but they logged out! Items are being dropped.", player.getCommandSenderName()); - InventoryPlayer keepInventory = playerKeepsMap.get(player.getCommandSenderName()); - - // set player to the player logging out + public static void onPlayerLogout(PlayerLoggedOutEvent event) { + dropStoredItems(event.player); + } + + private static void dropStoredItems(EntityPlayer player) { + InventoryPlayer keepInventory = playerKeepsMap.remove(player.getUniqueID()); + if (keepInventory != null) { + TwilightForestMod.LOGGER.warn("Dropping inventory items previously held in reserve for player {}", player.getName()); keepInventory.player = player; keepInventory.dropAllItems(); - - playerKeepsMap.remove(player.getCommandSenderName()); } - } - - /** - * Stop the game from rendering the mount health for unfriendly creatures - */ - @SubscribeEvent - @SideOnly(Side.CLIENT) - public boolean preOverlay(RenderGameOverlayEvent.Pre event) - { - if (event.type == RenderGameOverlayEvent.ElementType.HEALTHMOUNT) - { - if (isRidingUnfriendly(Minecraft.getMinecraft().thePlayer)) - { - event.setCanceled(true); - return false; - + if (TFCompat.BAUBLES.isActivated()) { + NonNullList baubles = playerKeepsMapBaubles.remove(player.getUniqueID()); + if (baubles != null) { + TwilightForestMod.LOGGER.warn("Dropping baubles previously held in reserve for player {}", player.getName()); + for (ItemStack itemStack : baubles) { + if (!itemStack.isEmpty()) { + player.dropItem(itemStack, true, false); + } + } } } - return true; } - - - /** - * Stop the player from sneaking while riding an unfriendly creature - */ + @SubscribeEvent - public boolean livingUpdate(LivingUpdateEvent event) - { - if (event.entity instanceof EntityPlayer && event.entity.isSneaking() && isRidingUnfriendly(event.entityLiving)) - { - event.entity.setSneaking(false); + public static void livingUpdate(LivingUpdateEvent event) { + EntityLivingBase living = event.getEntityLiving(); + + IShieldCapability cap = living.getCapability(CapabilityList.SHIELDS, null); + if (cap != null) cap.update(); + + // Stop the player from sneaking while riding an unfriendly creature + if (living instanceof EntityPlayer && living.isSneaking() && isRidingUnfriendly(living)) { + living.setSneaking(false); } - return true; } - /** - * Is the specified entity riding an unfriendly creature (pinch beetle?) - */ - private boolean isRidingUnfriendly(EntityLivingBase entity) { - return entity.isRiding() && (entity.ridingEntity instanceof EntityTFPinchBeetle || entity.ridingEntity instanceof EntityTFYeti); + public static boolean isRidingUnfriendly(EntityLivingBase entity) { + return entity.isRiding() && entity.getRidingEntity() instanceof IHostileMount; } - + /** * Check if the player is trying to break a block in a structure that's considered unbreakable for progression reasons * Also check for breaking blocks with the giant's pickaxe and maybe break nearby blocks */ @SubscribeEvent - public void breakBlock(BreakEvent event) { - if (!event.getPlayer().capabilities.isCreativeMode && isAreaProtected(event.world, event.getPlayer(), event.x, event.y, event.z) && isBlockProtectedFromBreaking(event.world, event.x, event.y, event.z)) { + public static void breakBlock(BreakEvent event) { + + World world = event.getWorld(); + EntityPlayer player = event.getPlayer(); + BlockPos pos = event.getPos(); + IBlockState state = event.getState(); + + if (world.isRemote) return; + + if (isBlockProtectedFromBreaking(world, pos) && isAreaProtected(world, player, pos)) { event.setCanceled(true); - } else if (!this.isBreakingWithGiantPick && event.getPlayer().getCurrentEquippedItem() != null && event.getPlayer().getCurrentEquippedItem().getItem() == TFItems.giantPick && event.getPlayer().getCurrentEquippedItem().getItem().func_150897_b(event.block)) { - //System.out.println("Breaking with giant pick!"); - - this.isBreakingWithGiantPick = true; - - + + } else if (!isBreakingWithGiantPick && canHarvestWithGiantPick(player, state)) { + + isBreakingWithGiantPick = true; + // check nearby blocks for same block or same drop - int bx = (event.x >> 2) << 2; - int by = (event.y >> 2) << 2; - int bz = (event.z >> 2) << 2; - - // pre-check for cobble! - boolean allCobble = event.block.getItemDropped(event.blockMetadata, event.world.rand, 0) == Item.getItemFromBlock(Blocks.cobblestone); - for (int dx = 0; dx < 4; dx++) { - for (int dy = 0; dy < 4; dy++) { - for (int dz = 0; dz < 4; dz++) { - Block blockThere = event.world.getBlock(bx + dx, by + dy, bz + dz); - int metaThere = event.world.getBlockMetadata(bx + dx, by + dy, bz + dz); - allCobble &= blockThere.getItemDropped(metaThere, event.world.rand, 0) == Item.getItemFromBlock(Blocks.cobblestone); - } - } - } - - if (allCobble && !event.getPlayer().capabilities.isCreativeMode) { - //System.out.println("It's all cobble!"); - this.shouldMakeGiantCobble = true; - this.amountOfCobbleToReplace = 64; - } else { - this.shouldMakeGiantCobble = false; - this.amountOfCobbleToReplace = 0; - } - - // break all nearby blocks - for (int dx = 0; dx < 4; dx++) { - for (int dy = 0; dy < 4; dy++) { - for (int dz = 0; dz < 4; dz++) { - Block blockThere = event.world.getBlock(bx + dx, by + dy, bz + dz); - int metaThere = event.world.getBlockMetadata(bx + dx, by + dy, bz + dz); - - if (!(event.x == bx + dx && event.y == by + dy && event.z == bz + dz) && blockThere == event.block && metaThere == event.blockMetadata) { - // try to break that block too! - if (event.getPlayer() instanceof EntityPlayerMP) { - EntityPlayerMP playerMP = (EntityPlayerMP)event.getPlayer(); - - playerMP.theItemInWorldManager.tryHarvestBlock(bx + dx, by + dy, bz + dz); - } - } - } - } - } - - this.isBreakingWithGiantPick = false; - - } - } - - /** - * Check if the player is trying to right block a block in a structure that's considered protected - * Also check for fiery set achievement - */ - @SubscribeEvent - public void rightClickBlock(PlayerInteractEvent event) { - if (event.action == Action.RIGHT_CLICK_BLOCK && event.entityPlayer.worldObj.provider instanceof WorldProviderTwilightForest && !event.entityPlayer.capabilities.isCreativeMode) { - World world = event.entityPlayer.worldObj; - EntityPlayer player = event.entityPlayer; - int x = event.x; - int y = event.y; - int z = event.z; + // pre-check for cobble! + Item cobbleItem = Item.getItemFromBlock(Blocks.COBBLESTONE); + boolean allCobble = state.getBlock().getItemDropped(state, world.rand, 0) == cobbleItem; + + if (allCobble) { + for (BlockPos dPos : BlockTFGiantBlock.getVolume(pos)) { + if (dPos.equals(pos)) continue; + IBlockState stateThere = world.getBlockState(dPos); + if (stateThere.getBlock().getItemDropped(stateThere, world.rand, 0) != cobbleItem) { + allCobble = false; + break; + } + } + } - if (!world.isRemote && isBlockProtectedFromInteraction(world, x, y, z) && isAreaProtected(world, player, x, y, z)) { - event.useBlock = Result.DENY; + if (allCobble && !player.capabilities.isCreativeMode) { + shouldMakeGiantCobble = true; + amountOfCobbleToReplace = 64; + } else { + shouldMakeGiantCobble = false; + amountOfCobbleToReplace = 0; } - } - - ItemStack currentItem = event.entityPlayer.inventory.getCurrentItem(); - if (currentItem != null && (currentItem.getItem() == TFItems.fierySword || currentItem.getItem() == TFItems.fieryPick)) { - // are they also wearing the armor - if (checkPlayerForFieryArmor(event.entityPlayer)) { - event.entityPlayer.triggerAchievement(TFAchievementPage.twilightFierySet); + + // break all nearby blocks + if (player instanceof EntityPlayerMP) { + EntityPlayerMP playerMP = (EntityPlayerMP) player; + for (BlockPos dPos : BlockTFGiantBlock.getVolume(pos)) { + if (!dPos.equals(pos) && state == world.getBlockState(dPos)) { + // try to break that block too! + playerMP.interactionManager.tryHarvestBlock(dPos); + } + } } + + isBreakingWithGiantPick = false; } } - /** - * Stop the player from interacting with blocks that could produce treasure or open doors in a protected area - */ - private boolean isBlockProtectedFromInteraction(World world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - - if (block == TFBlocks.towerDevice || block == Blocks.chest || block == Blocks.trapped_chest - || block == Blocks.stone_button || block == Blocks.wooden_button || block == Blocks.lever) { - return true; - } else { - return false; - } + private static boolean canHarvestWithGiantPick(EntityPlayer player, IBlockState state) { + ItemStack heldStack = player.getHeldItemMainhand(); + Item heldItem = heldStack.getItem(); + return heldItem == TFItems.giant_pickaxe && heldItem.canHarvestBlock(state, heldStack); } - /** - * Stop the player from breaking blocks. We protect all blocks except openblocks graves - */ - private boolean isBlockProtectedFromBreaking(World world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - - // graves are okay! - if (block.getUnlocalizedName().equals("tile.openblocks.grave")) { - return false; + @SubscribeEvent + public static void onPlayerRightClick(PlayerInteractEvent.RightClickBlock event) { + + EntityPlayer player = event.getEntityPlayer(); + World world = player.world; + + if (!world.isRemote && isBlockProtectedFromInteraction(world, event.getPos()) && isAreaProtected(world, player, event.getPos())) { + event.setUseBlock(Result.DENY); } - - return true; } /** - * Return true if the player is wearing at least one piece of fiery armor + * Stop the player from interacting with blocks that could produce treasure or open doors in a protected area */ - private boolean checkPlayerForFieryArmor(EntityPlayer entityPlayer) { - ItemStack[] armor = entityPlayer.inventory.armorInventory; - if (armor[0] != null && armor[0].getItem() == TFItems.fieryBoots) { - return true; - } else if (armor[1] != null && armor[1].getItem() == TFItems.fieryLegs) { - return true; - } else if (armor[2] != null && armor[2].getItem() == TFItems.fieryPlate) { - return true; - } else if (armor[3] != null && armor[3].getItem() == TFItems.fieryHelm) { - return true; - } else { - return false; - } + private static boolean isBlockProtectedFromInteraction(World world, BlockPos pos) { + Block block = world.getBlockState(pos).getBlock(); + // TODO: improve this? + return block == TFBlocks.tower_device || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST + || block == Blocks.STONE_BUTTON || block == Blocks.WOODEN_BUTTON || block == Blocks.LEVER; + } + + private static boolean isBlockProtectedFromBreaking(World world, BlockPos pos) { + // todo improve + return !world.getBlockState(pos).getBlock().getRegistryName().getPath().contains("grave"); } /** * Return if the area at the coordinates is considered protected for that player. * Currently, if we return true, we also send the area protection packet here. */ - private boolean isAreaProtected(World world, EntityPlayer player, int x, int y, int z) { - if (world.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE) && world.provider instanceof WorldProviderTwilightForest) { - - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)world.provider).getChunkProvider(); - - if (chunkProvider != null && chunkProvider.isBlockInStructureBB(x, y, z)) { - // what feature is nearby? is it one the player has not unlocked? - TFFeature nearbyFeature = ((TFWorldChunkManager)world.provider.worldChunkMgr).getFeatureAt(x, z, world); - - if (!nearbyFeature.doesPlayerHaveRequiredAchievement(player) && chunkProvider.isBlockProtected(x, y, z)) { - - // send protection packet - StructureBoundingBox sbb = chunkProvider.getSBBAt(x, y, z); - sendAreaProtectionPacket(world, x, y, z, sbb); - - // send a hint monster? - nearbyFeature.trySpawnHintMonster(world, player, x, y, z); - - return true; - } + private static boolean isAreaProtected(World world, EntityPlayer player, BlockPos pos) { + + if (player.capabilities.isCreativeMode || !TFWorld.isProgressionEnforced(world)) { + return false; + } + + ChunkGeneratorTFBase chunkGenerator = TFWorld.getChunkGenerator(world); + + if (chunkGenerator != null && chunkGenerator.isBlockInStructureBB(pos)) { + // what feature is nearby? is it one the player has not unlocked? + TFFeature nearbyFeature = TFFeature.getFeatureAt(pos.getX(), pos.getZ(), world); + + if (!nearbyFeature.doesPlayerHaveRequiredAdvancements(player) && chunkGenerator.isBlockProtected(pos)) { + + // send protection packet + sendAreaProtectionPacket(world, pos, chunkGenerator.getSBBAt(pos)); + + // send a hint monster? + nearbyFeature.trySpawnHintMonster(world, player, pos); + + return true; } } return false; } - private void sendAreaProtectionPacket(World world, int x, int y, int z, StructureBoundingBox sbb) { - // send packet - FMLProxyPacket message = TFGenericPacketHandler.makeAreaProtectionPacket(sbb, x, y, z); + private static void sendAreaProtectionPacket(World world, BlockPos pos, StructureBoundingBox sbb) { + NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 64); + TFPacketHandler.CHANNEL.sendToAllAround(new PacketAreaProtection(sbb, pos), targetPoint); + } - NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.dimensionId, x, y, z, 64); - - TwilightForestMod.genericChannel.sendToAllAround(message, targetPoint); + @SubscribeEvent + public static void livingAttack(LivingAttackEvent event) { + EntityLivingBase living = event.getEntityLiving(); + // cancel attacks in protected areas + if (!living.world.isRemote && living instanceof IMob && event.getSource().getTrueSource() instanceof EntityPlayer + && isAreaProtected(living.world, (EntityPlayer) event.getSource().getTrueSource(), new BlockPos(living))) { + + event.setCanceled(true); + return; + } + // shields + if (!living.world.isRemote && !SHIELD_DAMAGE_BLACKLIST.contains(event.getSource().damageType)) { + IShieldCapability cap = living.getCapability(CapabilityList.SHIELDS, null); + if (cap != null && cap.shieldsLeft() > 0) { + cap.breakShield(); + event.setCanceled(true); + } + } } /** - * Cancel attacks in protected areas + * When player logs in, report conflict status, set enforced_progression rule */ @SubscribeEvent - public void livingAttack(LivingAttackEvent event) { + public static void playerLogsIn(PlayerLoggedInEvent event) { + if (!event.player.world.isRemote && event.player instanceof EntityPlayerMP) { + sendEnforcedProgressionStatus((EntityPlayerMP) event.player, TFWorld.isProgressionEnforced(event.player.world)); + updateCapabilities((EntityPlayerMP) event.player, event.player); + banishNewbieToTwilightZone(event.player); + } + } - // area protection check - if (event.entityLiving instanceof IMob && event.source.getEntity() instanceof EntityPlayer && !((EntityPlayer)event.source.getEntity()).capabilities.isCreativeMode && event.entityLiving.worldObj.provider instanceof WorldProviderTwilightForest && event.entityLiving.worldObj.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { + /** + * When player changes dimensions, send the rule status if they're moving to the Twilight Forest + */ + @SubscribeEvent + public static void playerPortals(PlayerChangedDimensionEvent event) { + if (!event.player.world.isRemote && event.player instanceof EntityPlayerMP) { + if (event.toDim == TFConfig.dimension.dimensionID) { + sendEnforcedProgressionStatus((EntityPlayerMP) event.player, TFWorld.isProgressionEnforced(event.player.world)); + } + updateCapabilities((EntityPlayerMP) event.player, event.player); + } + } - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)event.entityLiving.worldObj.provider).getChunkProvider(); + @SubscribeEvent + public static void onStartTracking(PlayerEvent.StartTracking event) { + updateCapabilities((EntityPlayerMP) event.getEntityPlayer(), event.getTarget()); + } - int mx = MathHelper.floor_double(event.entityLiving.posX); - int my = MathHelper.floor_double(event.entityLiving.posY); - int mz = MathHelper.floor_double(event.entityLiving.posZ); + // send any capabilities that are needed client-side + private static void updateCapabilities(EntityPlayerMP player, Entity entity) { + IShieldCapability cap = entity.getCapability(CapabilityList.SHIELDS, null); + if (cap != null && cap.shieldsLeft() > 0) { + TFPacketHandler.CHANNEL.sendTo(new PacketUpdateShield(entity, cap), player); + } + } - if (chunkProvider != null && chunkProvider.isBlockInStructureBB(mx, my, mz) && chunkProvider.isBlockProtected(mx, my, mz)) { - // what feature is nearby? is it one the player has not unlocked? - TFFeature nearbyFeature = ((TFWorldChunkManager)event.entityLiving.worldObj.provider.worldChunkMgr).getFeatureAt(mx, mz, event.entityLiving.worldObj); + private static void sendEnforcedProgressionStatus(EntityPlayerMP player, boolean isEnforced) { + TFPacketHandler.CHANNEL.sendTo(new PacketEnforceProgressionStatus(isEnforced), player); + } - if (!nearbyFeature.doesPlayerHaveRequiredAchievement((EntityPlayer) event.source.getEntity())) { - event.setResult(Result.DENY); - event.setCanceled(true); - - - // particle effect - for (int i = 0; i < 20; i++) { - //worldObj.spawnParticle("mobSpell", blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, red, grn, blu); - TwilightForestMod.proxy.spawnParticle(event.entityLiving.worldObj, "protection", event.entityLiving.posX, event.entityLiving.posY, event.entityLiving.posZ, 0, 0, 0); + private static void sendSkylightEnabled(EntityPlayerMP player, boolean skylightEnabled) { + TFPacketHandler.CHANNEL.sendTo(new PacketSetSkylightEnabled(skylightEnabled), player); + } - } - } - } + @SubscribeEvent + public static void onClientConnect(FMLNetworkEvent.ServerConnectionFromClientEvent event) { + INetHandlerPlayServer handler = event.getHandler(); + if (handler instanceof NetHandlerPlayServer) { + EntityPlayerMP player = ((NetHandlerPlayServer) handler).player; + sendSkylightEnabled(player, WorldProviderTwilightForest.isSkylightEnabled(TFWorld.getDimensionData(player.world))); } } - - /** - * When player logs in, report conflict status, set enforced_progression rule + + @SubscribeEvent + public static void onServerDisconnect(FMLNetworkEvent.ClientDisconnectionFromServerEvent event) { + WorldProviderTwilightForest.syncFromConfig(); + } + + /** + * When world is loaded, check if the game rule is defined */ @SubscribeEvent - public void playerLogsIn(PlayerLoggedInEvent event) { - TwilightForestMod.hasBiomeIdConflicts = TFBiomeBase.areThereBiomeIdConflicts(); - if (TwilightForestMod.hasBiomeIdConflicts) { - event.player.addChatMessage(new ChatComponentText("[TwilightForest] Biome ID conflict detected. Fix by editing the config file.")); - } - - // check enforced progression - if (!event.player.worldObj.isRemote && event.player instanceof EntityPlayerMP) { - this.sendEnforcedProgressionStatus((EntityPlayerMP)event.player, event.player.worldObj.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE)); + public static void worldLoaded(WorldEvent.Load event) { + if (!event.getWorld().isRemote && !event.getWorld().getGameRules().hasRule(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { + TwilightForestMod.LOGGER.info("Loaded a world with the {} game rule not defined. Defining it.", TwilightForestMod.ENFORCED_PROGRESSION_RULE); + event.getWorld().getGameRules().addGameRule(TwilightForestMod.ENFORCED_PROGRESSION_RULE, String.valueOf(TFConfig.progressionRuleDefault), GameRules.ValueType.BOOLEAN_VALUE); } } - - /** - * When player changes dimensions, send the rule status if they're moving to the Twilight Forest + + /** + * Check if someone's changing the progression game rule */ @SubscribeEvent - public void playerPortals(PlayerChangedDimensionEvent event) { - // check enforced progression - if (!event.player.worldObj.isRemote && event.player instanceof EntityPlayerMP && event.toDim == TwilightForestMod.dimensionID) { - this.sendEnforcedProgressionStatus((EntityPlayerMP)event.player, event.player.worldObj.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE)); + public static void gameRuleChanged(GameRuleChangeEvent event) { + if (event.getRuleName().equals(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { + boolean isEnforced = event.getRules().getBoolean(TwilightForestMod.ENFORCED_PROGRESSION_RULE); + TFPacketHandler.CHANNEL.sendToAll(new PacketEnforceProgressionStatus(isEnforced)); } } - - private void sendEnforcedProgressionStatus(EntityPlayerMP player, boolean isEnforced) { - TwilightForestMod.genericChannel.sendTo(TFGenericPacketHandler.makeEnforcedProgressionStatusPacket(isEnforced), player); + + // Teleport first-time players to Twilight Forest + + private static final String NBT_TAG_TWILIGHT = "twilightforest_banished"; + + private static void banishNewbieToTwilightZone(EntityPlayer player) { + NBTTagCompound tagCompound = player.getEntityData(); + NBTTagCompound playerData = tagCompound.getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG); + + // getBoolean returns false, if false or didn't exist + boolean shouldBanishPlayer = TFConfig.dimension.newPlayersSpawnInTF && !playerData.getBoolean(NBT_TAG_TWILIGHT); + + playerData.setBoolean(NBT_TAG_TWILIGHT, true); // set true once player has spawned either way + tagCompound.setTag(EntityPlayer.PERSISTED_NBT_TAG, playerData); // commit + + if (shouldBanishPlayer) BlockTFPortal.attemptSendPlayer(player, true); // See ya hate to be ya } - /** - * When world is loaded, check if the game rule is defined - */ + // Advancement Trigger @SubscribeEvent - public void worldLoaded(WorldEvent.Load event) { - // check rule - if (!event.world.isRemote && !event.world.getGameRules().hasRule(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { - FMLLog.info("[TwilightForest] Loaded a world with the tfEnforcedProgression game rule not defined. Defining it."); - - event.world.getGameRules().addGameRule(TwilightForestMod.ENFORCED_PROGRESSION_RULE, "true"); + public static void onAdvancementGet(AdvancementEvent event) { + EntityPlayer player = event.getEntityPlayer(); + if (player instanceof EntityPlayerMP) { + TFAdvancements.ADVANCEMENT_UNLOCKED.trigger((EntityPlayerMP) player, event.getAdvancement()); } } - - /** - * When a command is used, check if someone's changing the progression game rule - */ + + @SubscribeEvent + public static void armorChanged(LivingEquipmentChangeEvent event) { + EntityLivingBase living = event.getEntityLiving(); + if (!living.world.isRemote && living instanceof EntityPlayerMP) { + TFAdvancements.ARMOR_CHANGED.trigger((EntityPlayerMP) living, event.getFrom(), event.getTo()); + } + } + + // Parrying + + private static boolean globalParry = !Loader.isModLoaded("parry"); + + @SubscribeEvent + public static void arrowParry(ProjectileImpactEvent.Arrow event) { + final EntityArrow projectile = event.getArrow(); + + if (!projectile.getEntityWorld().isRemote && globalParry && + (TFConfig.shieldInteractions.parryNonTwilightAttacks + || projectile instanceof ITFProjectile)) { + + Entity entity = event.getRayTraceResult().entityHit; + + if (event.getEntity() != null && entity instanceof EntityLivingBase) { + EntityLivingBase entityBlocking = (EntityLivingBase) entity; + + if (entityBlocking.canBlockDamageSource(new DamageSource("parry_this") { + @Override + public Vec3d getDamageLocation() { return projectile.getPositionVector(); } + }) && (entityBlocking.getActiveItemStack().getItem().getMaxItemUseDuration(entityBlocking.getActiveItemStack()) - entityBlocking.getItemInUseCount()) <= TFConfig.shieldInteractions.shieldParryTicksArrow) { + Vec3d playerVec3 = entityBlocking.getLookVec(); + + projectile.shoot(playerVec3.x, playerVec3.y, playerVec3.z, 1.1F, 0.1F); // reflect faster and more accurately + + projectile.shootingEntity = entityBlocking; + + event.setCanceled(true); + } + } + } + } + @SubscribeEvent - public void commandSent(CommandEvent event) { - if (event.command instanceof CommandGameRule && event.parameters.length > 1 && TwilightForestMod.ENFORCED_PROGRESSION_RULE.equals(event.parameters[0])) { - boolean isEnforced = Boolean.valueOf(event.parameters[1]); - TwilightForestMod.genericChannel.sendToAll(TFGenericPacketHandler.makeEnforcedProgressionStatusPacket(isEnforced)); + public static void fireballParry(ProjectileImpactEvent.Fireball event) { + final EntityFireball projectile = event.getFireball(); + + if (!projectile.getEntityWorld().isRemote && globalParry && + (TFConfig.shieldInteractions.parryNonTwilightAttacks + || projectile instanceof ITFProjectile)) { + + Entity entity = event.getRayTraceResult().entityHit; + + if (event.getEntity() != null && entity instanceof EntityLivingBase) { + EntityLivingBase entityBlocking = (EntityLivingBase) entity; + + if (entityBlocking.canBlockDamageSource(new DamageSource("parry_this") { + @Override + public Vec3d getDamageLocation() { return projectile.getPositionVector(); } + }) && (entityBlocking.getActiveItemStack().getItem().getMaxItemUseDuration(entityBlocking.getActiveItemStack()) - entityBlocking.getItemInUseCount()) <= TFConfig.shieldInteractions.shieldParryTicksFireball) { + Vec3d playerVec3 = entityBlocking.getLookVec(); + + projectile.motionX = playerVec3.x; + projectile.motionY = playerVec3.y; + projectile.motionZ = playerVec3.z; + projectile.accelerationX = projectile.motionX * 0.1D; + projectile.accelerationY = projectile.motionY * 0.1D; + projectile.accelerationZ = projectile.motionZ * 0.1D; + + projectile.shootingEntity = entityBlocking; + + event.setCanceled(true); + } + } } } + @SubscribeEvent + public static void throwableParry(ProjectileImpactEvent.Throwable event) { + final EntityThrowable projectile = event.getThrowable(); + + if (!projectile.getEntityWorld().isRemote && globalParry && + (TFConfig.shieldInteractions.parryNonTwilightAttacks + || projectile instanceof ITFProjectile)) { + + Entity entity = event.getRayTraceResult().entityHit; + + if (event.getEntity() != null && entity instanceof EntityLivingBase) { + EntityLivingBase entityBlocking = (EntityLivingBase) entity; + + if (entityBlocking.canBlockDamageSource(new DamageSource("parry_this") { + @Override + public Vec3d getDamageLocation() { return projectile.getPositionVector(); } + }) && (entityBlocking.getActiveItemStack().getItem().getMaxItemUseDuration(entityBlocking.getActiveItemStack()) - entityBlocking.getItemInUseCount()) <= TFConfig.shieldInteractions.shieldParryTicksThrowable) { + Vec3d playerVec3 = entityBlocking.getLookVec(); + + projectile.shoot(playerVec3.x, playerVec3.y, playerVec3.z, 1.1F, 0.1F); // reflect faster and more accurately + + projectile.thrower = entityBlocking; + + event.setCanceled(true); + } + } + } + } } diff --git a/src/main/java/twilightforest/TFFeature.java b/src/main/java/twilightforest/TFFeature.java index c71cedd9f8..785edeb959 100644 --- a/src/main/java/twilightforest/TFFeature.java +++ b/src/main/java/twilightforest/TFFeature.java @@ -1,10 +1,6 @@ package twilightforest; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.monster.EntityBlaze; import net.minecraft.entity.monster.EntityCaveSpider; @@ -18,214 +14,511 @@ import net.minecraft.entity.passive.EntityBat; import net.minecraft.entity.passive.EntitySquid; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Items; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; -import net.minecraft.stats.Achievement; -import net.minecraft.stats.StatisticsFile; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.biome.BiomeGenBase.SpawnListEntry; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biome.SpawnListEntry; +import net.minecraft.world.gen.MapGenBase; +import net.minecraft.world.gen.structure.MapGenStructureIO; import twilightforest.biomes.TFBiomeBase; -import twilightforest.entity.EntityTFAdherent; -import twilightforest.entity.EntityTFArmoredGiant; -import twilightforest.entity.EntityTFBlockGoblin; -import twilightforest.entity.EntityTFDeathTome; -import twilightforest.entity.EntityTFFireBeetle; -import twilightforest.entity.EntityTFGiantMiner; -import twilightforest.entity.EntityTFGoblinKnightLower; -import twilightforest.entity.EntityTFHarbingerCube; -import twilightforest.entity.EntityTFHelmetCrab; -import twilightforest.entity.EntityTFIceExploder; -import twilightforest.entity.EntityTFIceShooter; -import twilightforest.entity.EntityTFKobold; -import twilightforest.entity.EntityTFMazeSlime; -import twilightforest.entity.EntityTFMiniGhast; -import twilightforest.entity.EntityTFMinotaur; -import twilightforest.entity.EntityTFPinchBeetle; -import twilightforest.entity.EntityTFRedcap; -import twilightforest.entity.EntityTFRedcapSapper; -import twilightforest.entity.EntityTFSlimeBeetle; -import twilightforest.entity.EntityTFSnowGuardian; -import twilightforest.entity.EntityTFSwarmSpider; -import twilightforest.entity.EntityTFTowerBroodling; -import twilightforest.entity.EntityTFTowerGhast; -import twilightforest.entity.EntityTFTowerGolem; -import twilightforest.entity.EntityTFTroll; -import twilightforest.entity.EntityTFWraith; -import twilightforest.entity.EntityTFYeti; +import twilightforest.entity.*; +import twilightforest.structures.*; +import twilightforest.structures.courtyard.NagaCourtyardPieces; +import twilightforest.structures.darktower.TFDarkTowerPieces; +import twilightforest.structures.finalcastle.TFFinalCastlePieces; +import twilightforest.structures.icetower.TFIceTowerPieces; +import twilightforest.structures.lichtower.TFLichTowerPieces; +import twilightforest.structures.minotaurmaze.TFMinotaurMazePieces; +import twilightforest.structures.mushroomtower.TFMushroomTowerPieces; +import twilightforest.structures.start.*; +import twilightforest.structures.stronghold.TFStrongholdPieces; +import twilightforest.structures.trollcave.TFTrollCavePieces; +import twilightforest.util.IntPair; +import twilightforest.util.PlayerHelper; +import twilightforest.world.MapGenTFMajorFeature; import twilightforest.world.TFWorld; -import twilightforest.world.TFWorldChunkManager; - - - -public class TFFeature { - - public static final TFFeature[] featureList = new TFFeature[256]; - - public static final TFFeature nothing = new TFFeature(0, 0, "No Feature").enableDecorations().disableStructure(); - public static final TFFeature hill1 = new TFFeature(1, 1, "Small Hollow Hill").enableDecorations().enableTerrainAlterations(); - public static final TFFeature hill2 = new TFFeature(2, 2, "Medium Hollow Hill").enableDecorations().enableTerrainAlterations(); - public static final TFFeature hill3 = new TFFeature(3, 3, "Large Hollow Hill").enableDecorations().enableTerrainAlterations(); - public static final TFFeature hedgeMaze = new TFFeature(4, 2, "Hedge Maze").enableTerrainAlterations(); - public static final TFFeature nagaCourtyard = new TFFeature(5, 3, "Naga Courtyard").enableTerrainAlterations(); - public static final TFFeature lichTower = new TFFeature(6, 1, "Lich Tower").setRequiredAchievement(TFAchievementPage.twilightKillNaga); - public static final TFFeature iceTower = new TFFeature(7, 2, "Ice Tower").setRequiredAchievement(TFAchievementPage.twilightProgressYeti); - public static final TFFeature questIsland = new TFFeature(8, 1, "Quest Island").disableStructure(); - public static final TFFeature questGrove = new TFFeature(9, 1, "Quest Grove").enableTerrainAlterations(); - public static final TFFeature druidGrove = new TFFeature(10, 1, "Druid Grove").disableStructure(); - public static final TFFeature floatRuins = new TFFeature(11, 3, "Floating Ruins").disableStructure(); - public static final TFFeature hydraLair = new TFFeature(12, 2, "Hydra Lair").setRequiredAchievement(TFAchievementPage.twilightProgressLabyrinth).enableTerrainAlterations(); - public static final TFFeature labyrinth = new TFFeature(13, 3, "Labyrinth").enableDecorations().setRequiredAchievement(TFAchievementPage.twilightKillLich); - public static final TFFeature darkTower = new TFFeature(14, 1, "Dark Tower").setRequiredAchievement(TFAchievementPage.twilightProgressKnights); - public static final TFFeature tfStronghold = new TFFeature(15, 3, "Knight Stronghold").enableDecorations().setRequiredAchievement(TFAchievementPage.twilightProgressTrophyPedestal).disableProtectionAura(); - public static final TFFeature worldTree = new TFFeature(16, 3, "World Tree").disableStructure(); - public static final TFFeature yetiCave = new TFFeature(17, 2, "Yeti Lairs").enableDecorations().enableTerrainAlterations().setRequiredAchievement(TFAchievementPage.twilightProgressUrghast); - public static final TFFeature trollCave = new TFFeature(18, 3, "Troll Lairs").enableDecorations().enableTerrainAlterations().setRequiredAchievement(TFAchievementPage.twilightProgressGlacier).disableProtectionAura(); - public static final TFFeature finalCastle = new TFFeature(19, 3, "Final Castle"); - public static final TFFeature mushroomTower = new TFFeature(20, 2, "Mushroom Tower"); - - ArrayList emptyList = new ArrayList(); - - static { - // spawn lists! - lichTower.addMonster(EntityZombie.class, 10, 4, 4); - lichTower.addMonster(EntitySkeleton.class, 10, 4, 4); - lichTower.addMonster(EntityCreeper.class, 1, 4, 4); - lichTower.addMonster(EntityEnderman.class, 1, 1, 4); - lichTower.addMonster(EntityTFDeathTome.class, 10, 4, 4); - lichTower.addMonster(EntityWitch.class, 1, 1, 1); - - hill1.addMonster(EntitySpider.class, 10, 4, 4); - hill1.addMonster(EntityZombie.class, 10, 4, 4); - hill1.addMonster(EntityTFRedcap.class, 10, 4, 4); - hill1.addMonster(EntityTFSwarmSpider.class, 10, 4, 4); - hill1.addMonster(EntityTFKobold.class, 10, 4, 8); - - hill2.addMonster(EntityTFRedcap.class, 10, 4, 4); - hill2.addMonster(EntityTFRedcapSapper.class, 1, 1, 4); - hill2.addMonster(EntityTFKobold.class, 10, 4, 8); - hill2.addMonster(EntitySkeleton.class, 10, 4, 4); - hill2.addMonster(EntityTFSwarmSpider.class, 10, 4, 4); - hill2.addMonster(EntitySpider.class, 10, 4, 4); - hill2.addMonster(EntityCreeper.class, 10, 4, 4); - hill2.addMonster(EntityTFFireBeetle.class, 5, 4, 4); - hill2.addMonster(EntityTFSlimeBeetle.class, 5, 4, 4); - hill2.addMonster(EntityWitch.class, 1, 1, 1); - - hill3.addMonster(EntityTFRedcap.class, 10, 4, 4); - hill3.addMonster(EntityTFRedcapSapper.class, 2, 1, 4); - hill3.addMonster(EntitySkeleton.class, 10, 4, 4); - hill3.addMonster(EntityCaveSpider.class, 10, 4, 4); - hill3.addMonster(EntityCreeper.class, 10, 4, 4); - hill3.addMonster(EntityEnderman.class, 1, 1, 4); - hill3.addMonster(EntityTFWraith.class, 2, 1, 4); - hill3.addMonster(EntityTFFireBeetle.class, 10, 4, 4); - hill3.addMonster(EntityTFSlimeBeetle.class, 10, 4, 4); - hill3.addMonster(EntityTFPinchBeetle.class, 10, 2, 4); - hill3.addMonster(EntityWitch.class, 1, 1, 1); - - labyrinth.addMonster(EntityTFMinotaur.class, 20, 2, 4); - labyrinth.addMonster(EntityCaveSpider.class, 10, 4, 4); - labyrinth.addMonster(EntityCreeper.class, 10, 4, 4); - labyrinth.addMonster(EntityTFMazeSlime.class, 10, 4, 4); - labyrinth.addMonster(EntityEnderman.class, 1, 1, 4); - labyrinth.addMonster(EntityTFFireBeetle.class, 10, 4, 4); - labyrinth.addMonster(EntityTFSlimeBeetle.class, 10, 4, 4); - labyrinth.addMonster(EntityTFPinchBeetle.class, 10, 2, 4); - - darkTower.addMonster(EntityTFTowerGolem.class, 10, 4, 4); - darkTower.addMonster(EntitySkeleton.class, 10, 4, 4); - darkTower.addMonster(EntityCreeper.class, 10, 4, 4); - darkTower.addMonster(EntityEnderman.class, 2, 1, 4); - darkTower.addMonster(EntityWitch.class, 1, 1, 1); - darkTower.addMonster(EntityTFMiniGhast.class, 10, 1, 4); - darkTower.addMonster(EntityTFTowerBroodling.class, 10, 8, 8); - darkTower.addMonster(EntityTFPinchBeetle.class, 10, 2, 4); - // roof ghasts - darkTower.addMonster(1, EntityTFTowerGhast.class, 10, 1, 4); - // aquarium squids (only in aquariums between y = 35 and y = 64. :/ - darkTower.addWaterCreature(EntitySquid.class, 10, 4, 4); - - tfStronghold.addMonster(EntityTFBlockGoblin.class, 10, 4, 4); - tfStronghold.addMonster(EntityTFGoblinKnightLower.class, 5, 1, 2); - tfStronghold.addMonster(EntityTFHelmetCrab.class, 10, 4, 4); - tfStronghold.addMonster(EntityTFSlimeBeetle.class, 10, 4, 4); - tfStronghold.addMonster(EntityTFRedcapSapper.class, 2, 1, 4); - tfStronghold.addMonster(EntityTFKobold.class, 10, 4, 8); - tfStronghold.addMonster(EntityCreeper.class, 10, 4, 4); - tfStronghold.addMonster(EntitySlime.class, 5, 4, 4); - - yetiCave.addMonster(EntityTFYeti.class, 10, 4, 4); - - iceTower.addMonster(EntityTFSnowGuardian.class, 10, 4, 4); - iceTower.addMonster(EntityTFIceShooter.class, 10, 4, 4); - iceTower.addMonster(EntityTFIceExploder.class, 5, 4, 4); - - trollCave.addMonster(EntityCreeper.class, 5, 4, 4); - trollCave.addMonster(EntitySkeleton.class, 10, 4, 4); - trollCave.addMonster(EntityTFTroll.class, 20, 4, 4); - trollCave.addMonster(EntityWitch.class, 5, 1, 1); - // cloud monsters - trollCave.addMonster(1, EntityTFGiantMiner.class, 10, 1, 4); - trollCave.addMonster(1, EntityTFArmoredGiant.class, 10, 1, 4); - - // plain parts of the castle, like the tower maze - finalCastle.addMonster(EntityTFKobold.class, 10, 4, 4); - finalCastle.addMonster(EntityTFAdherent.class, 10, 1, 1); - finalCastle.addMonster(EntityTFHarbingerCube.class, 10, 1, 1); - finalCastle.addMonster(EntityEnderman.class, 10, 1, 1); - - // internal castle - finalCastle.addMonster(1, EntityTFKobold.class, 10, 4, 4); - finalCastle.addMonster(1, EntityTFAdherent.class, 10, 1, 1); - finalCastle.addMonster(1, EntityTFHarbingerCube.class, 10, 1, 1); - finalCastle.addMonster(1, EntityTFArmoredGiant.class, 10, 1, 1); - - // dungeons - finalCastle.addMonster(2, EntityTFAdherent.class, 10, 1, 1); - - // forge - finalCastle.addMonster(3, EntityBlaze.class, 10, 1, 1); - - } - - public int featureID; - public int size; - public String name; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +/** + * Arbiting class that decides what feature goes where in the world, in terms of the major features in the world + */ +public enum TFFeature { + + NOTHING ( 0, "no_feature" , false) { { this.enableDecorations().disableStructure(); } }, + SMALL_HILL ( 1, "small_hollow_hill", true ) { + { + this.enableDecorations().enableTerrainAlterations(); + + MapGenStructureIO.registerStructure(StructureStartHollowHill.class, "TFHill"); + MapGenStructureIO.registerStructureComponent(ComponentTFHollowHill.class, "TFHill"); + + this.addMonster(EntitySpider.class, 10, 4, 4) + .addMonster(EntityZombie.class, 10, 4, 4) + .addMonster(EntityTFRedcap.class, 10, 4, 4) + .addMonster(EntityTFSwarmSpider.class, 10, 4, 4) + .addMonster(EntityTFKobold.class, 10, 4, 8); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartHollowHill(world, this, rand, chunkX, chunkZ); + } + }, + MEDIUM_HILL ( 2, "medium_hollow_hill", true ) { + { + this.enableDecorations().enableTerrainAlterations(); + + this.addMonster(EntityTFRedcap.class, 10, 4, 4) + .addMonster(EntityTFRedcapSapper.class, 1, 1, 4) + .addMonster(EntityTFKobold.class, 10, 4, 8) + .addMonster(EntitySkeleton.class, 10, 4, 4) + .addMonster(EntityTFSwarmSpider.class, 10, 4, 4) + .addMonster(EntitySpider.class, 10, 4, 4) + .addMonster(EntityCreeper.class, 10, 4, 4) + .addMonster(EntityTFFireBeetle.class, 5, 4, 4) + .addMonster(EntityTFSlimeBeetle.class, 5, 4, 4) + .addMonster(EntityWitch.class, 1, 1, 1); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartHollowHill(world, this, rand, chunkX, chunkZ); + } + }, + LARGE_HILL ( 3, "large_hollow_hill", true ) { + { + this.enableDecorations().enableTerrainAlterations(); + + this.addMonster(EntityTFRedcap.class, 10, 4, 4) + .addMonster(EntityTFRedcapSapper.class, 2, 1, 4) + .addMonster(EntitySkeleton.class, 10, 4, 4) + .addMonster(EntityCaveSpider.class, 10, 4, 4) + .addMonster(EntityCreeper.class, 10, 4, 4) + .addMonster(EntityEnderman.class, 1, 1, 4) + .addMonster(EntityTFWraith.class, 2, 1, 4) + .addMonster(EntityTFFireBeetle.class, 10, 4, 4) + .addMonster(EntityTFSlimeBeetle.class, 10, 4, 4) + .addMonster(EntityTFPinchBeetle.class, 10, 2, 4) + .addMonster(EntityWitch.class, 1, 1, 1); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartHollowHill(world, this, rand, chunkX, chunkZ); + } + }, + HEDGE_MAZE ( 2, "hedge_maze", true ) { + { + this.enableTerrainAlterations(); + + MapGenStructureIO.registerStructure(StructureStartHedgeMaze.class, "TFHedge"); + MapGenStructureIO.registerStructureComponent(ComponentTFHedgeMaze.class, "TFHedge"); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartHedgeMaze(world, this, rand, chunkX, chunkZ); + } + }, + NAGA_COURTYARD ( 3, "naga_courtyard", true ) { + { + this.enableTerrainAlterations(); + + //MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardMain.class, "TFNaga"); + NagaCourtyardPieces.registerPieces(); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartCourtyard(world, this, rand, chunkX, chunkZ); + } + }, + LICH_TOWER ( 1, "lich_tower", true, TwilightForestMod.prefix("progress_naga") ) { + { + TFLichTowerPieces.registerPieces(); + + this.addMonster(EntityZombie.class, 10, 4, 4) + .addMonster(EntitySkeleton.class, 10, 4, 4) + .addMonster(EntityCreeper.class, 1, 4, 4) + .addMonster(EntityEnderman.class, 1, 1, 4) + .addMonster(EntityTFDeathTome.class, 10, 4, 4) + .addMonster(EntityWitch.class, 1, 1, 1); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.lichtower", 4); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on a Pointy Tower")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartLichTower(world, this, rand, chunkX, chunkZ); + } + }, + ICE_TOWER ( 2, "ice_tower", true, TwilightForestMod.prefix("progress_yeti") ) { + { + TFIceTowerPieces.registerPieces(); + + this.addMonster(EntityTFSnowGuardian.class, 10, 4, 4) + .addMonster(EntityTFIceShooter.class, 10, 4, 4) + .addMonster(EntityTFIceExploder.class, 5, 4, 4); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.icetower", 3); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on Auroral Fortification")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartAuroraPalace(world, this, rand, chunkX, chunkZ); + } + }, + QUEST_ISLAND ( 1, "quest_island", false ) { { this.disableStructure(); } }, + QUEST_GROVE ( 1, "quest_grove" , true ) { + { + this.enableTerrainAlterations(); + + MapGenStructureIO.registerStructure(StructureStartQuestGrove.class, "TFQuest1"); + MapGenStructureIO.registerStructureComponent(ComponentTFQuestGrove.class, "TFQuest1"); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartQuestGrove(world, this, rand, chunkX, chunkZ); + } + }, + DRUID_GROVE ( 1, "druid_grove" , false ) { { this.disableStructure(); } }, + FLOATING_RUINS ( 3, "floating_ruins", false ) { { this.disableStructure(); } }, + HYDRA_LAIR ( 2, "hydra_lair" , true , TwilightForestMod.prefix("progress_labyrinth") ) { + { + this.enableTerrainAlterations(); + + MapGenStructureIO.registerStructure(StructureStartHydraLair.class, "TFHydra"); + MapGenStructureIO.registerStructureComponent(ComponentTFHydraLair.class, "TFHydra"); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.hydralair", 4); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on the Fire Swamp")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartHydraLair(world, this, rand, chunkX, chunkZ); + } + }, + LABYRINTH ( 3, "labyrinth", true, TwilightForestMod.prefix("progress_lich") ) { + { + this.enableDecorations(); + + TFMinotaurMazePieces.registerPieces(); + + this.addMonster(EntityTFMinotaur.class, 20, 2, 4) + .addMonster(EntityCaveSpider.class, 10, 4, 4) + .addMonster(EntityCreeper.class, 10, 4, 4) + .addMonster(EntityTFMazeSlime.class, 10, 4, 4) + .addMonster(EntityEnderman.class, 1, 1, 4) + .addMonster(EntityTFFireBeetle.class, 10, 4, 4) + .addMonster(EntityTFSlimeBeetle.class, 10, 4, 4) + .addMonster(EntityTFPinchBeetle.class, 10, 2, 4); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.labyrinth", 5); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on a Swampy Labyrinth")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartLabyrinth(world, this, rand, chunkX, chunkZ); + } + }, + DARK_TOWER ( 1, "dark_tower", true, TwilightForestMod.prefix("progress_knights") ) { + { + TFDarkTowerPieces.registerPieces(); + + this.addMonster(EntityTFTowerGolem.class, 10, 4, 4) + .addMonster(EntitySkeleton.class, 10, 4, 4) + .addMonster(EntityCreeper.class, 10, 4, 4) + .addMonster(EntityEnderman.class, 2, 1, 4) + .addMonster(EntityWitch.class, 1, 1, 1) + .addMonster(EntityTFMiniGhast.class, 10, 1, 4) + .addMonster(EntityTFTowerBroodling.class, 10, 8, 8) + .addMonster(EntityTFPinchBeetle.class, 10, 2, 4) + // roof ghasts + .addMonster(1, EntityTFTowerGhast.class, 10, 1, 4) + // aquarium squids (only in aquariums between y = 35 and y = 64. :/ + .addWaterCreature(EntitySquid.class, 10, 4, 4); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.darktower", 3); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on a Wooden Tower")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartDarkTower(world, this, rand, chunkX, chunkZ); + } + }, + KNIGHT_STRONGHOLD ( 3, "knight_stronghold", true, TwilightForestMod.prefix("progress_trophy_pedestal") ) { + { + this.enableDecorations().disableProtectionAura(); + + TFStrongholdPieces.registerPieces(); + + this.addMonster(EntityTFBlockGoblin.class, 10, 4, 4) + .addMonster(EntityTFGoblinKnightLower.class, 5, 1, 2) + .addMonster(EntityTFHelmetCrab.class, 10, 4, 4) + .addMonster(EntityTFSlimeBeetle.class, 10, 4, 4) + .addMonster(EntityTFRedcapSapper.class, 2, 1, 4) + .addMonster(EntityTFKobold.class, 10, 4, 8) + .addMonster(EntityCreeper.class, 10, 4, 4) + .addMonster(EntitySlime.class, 5, 4, 4); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.tfstronghold", 5); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on a Stronghold")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartKnightStronghold(world, this, rand, chunkX, chunkZ); + } + }, + WORLD_TREE ( 3, "world_tree", false ) { { this.disableStructure(); } }, + YETI_CAVE ( 2, "yeti_lairs", true , TwilightForestMod.prefix("progress_lich") ) { + { + this.enableDecorations().enableTerrainAlterations(); + + MapGenStructureIO.registerStructure(StructureStartYetiCave.class, "TFYeti"); + MapGenStructureIO.registerStructureComponent(ComponentTFYetiCave.class, "TFYeti"); + + this.addMonster(EntityTFYeti.class, 10, 4, 4); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.yeticave", 3); + + book.setTagInfo("pages" , bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title" , new NBTTagString("Notes on an Icy Cave")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartYetiCave(world, this, rand, chunkX, chunkZ); + } + }, + // TODO split cloud giants from this + TROLL_CAVE ( 4, "troll_lairs", true, TwilightForestMod.prefix("progress_merge") ) { + { + this.enableDecorations().enableTerrainAlterations().disableProtectionAura(); + + TFTrollCavePieces.registerPieces(); + + this.addMonster(EntityCreeper.class, 5, 4, 4) + .addMonster(EntitySkeleton.class, 10, 4, 4) + .addMonster(EntityTFTroll.class, 20, 4, 4) + .addMonster(EntityWitch.class, 5, 1, 1) + // cloud monsters + .addMonster(1, EntityTFGiantMiner.class, 10, 1, 4) + .addMonster(1, EntityTFArmoredGiant.class, 10, 1, 4); + } + + @Override + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.trollcave", 3); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on the Highlands")); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartTrollCave(world, this, rand, chunkX, chunkZ); + } + }, + FINAL_CASTLE ( 4, "final_castle", true, TwilightForestMod.prefix("progress_troll") ) { + { + TFFinalCastlePieces.registerFinalCastlePieces(); + + // plain parts of the castle, like the tower maze + this.addMonster(EntityTFKobold.class, 10, 4, 4) + .addMonster(EntityTFAdherent.class, 10, 1, 1) + .addMonster(EntityTFHarbingerCube.class, 10, 1, 1) + .addMonster(EntityEnderman.class, 10, 1, 1) + // internal castle + .addMonster(1, EntityTFKobold.class, 10, 4, 4) + .addMonster(1, EntityTFAdherent.class, 10, 1, 1) + .addMonster(1, EntityTFHarbingerCube.class, 10, 1, 1) + .addMonster(1, EntityTFArmoredGiant.class, 10, 1, 1) + // dungeons + .addMonster(2, EntityTFAdherent.class, 10, 1, 1) + // forge + .addMonster(3, EntityBlaze.class, 10, 1, 1); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartFinalCastle(world, this, rand, chunkX, chunkZ); + } + }, + MUSHROOM_TOWER ( 2, "mushroom_tower", true ) { + { + TFMushroomTowerPieces.registerPieces(); + } + + @Override + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartMushroomTower(world, this, rand, chunkX, chunkZ); + } + }; + + public final int size; + public final String name; + private final boolean shouldHaveFeatureGenerator; public boolean areChunkDecorationsEnabled; public boolean isStructureEnabled; public boolean isTerrainAltered; - protected List> spawnableMonsterLists; - protected List ambientCreatureList; - protected List waterCreatureList; - protected Achievement requiredAchievement = null; + private List> spawnableMonsterLists; + private List ambientCreatureList; + private List waterCreatureList; + private final ResourceLocation[] requiredAdvancements; public boolean hasProtectionAura; private long lastSpawnedHintMonsterTime; + private static final String BOOK_AUTHOR = "A Forgotten Explorer"; + private static final TFFeature[] VALUES = values(); - public TFFeature(int parID, int parSize, String parName) { - this.featureID = parID; - TFFeature.featureList[parID] = this; - this.size = parSize; - this.name = parName; + private static final int maxSize = Arrays.stream(VALUES).mapToInt(v -> v.size).max().orElse(0); + + TFFeature(int size, String name, boolean featureGenerator, ResourceLocation... requiredAdvancements) { + this.size = size; + this.name = name; this.areChunkDecorationsEnabled = false; this.isStructureEnabled = true; this.isTerrainAltered = false; - this.spawnableMonsterLists = new ArrayList>(); - this.ambientCreatureList = new ArrayList(); - this.waterCreatureList = new ArrayList(); + this.spawnableMonsterLists = new ArrayList<>(); + this.ambientCreatureList = new ArrayList<>(); + this.waterCreatureList = new ArrayList<>(); this.hasProtectionAura = true; ambientCreatureList.add(new SpawnListEntry(EntityBat.class, 10, 8, 8)); + + this.requiredAdvancements = requiredAdvancements; + + shouldHaveFeatureGenerator = featureGenerator; } - + + static void init() {} + + public static int getCount() { + return VALUES.length; + } + + public static int getMaxSize() { + return maxSize; + } + + @Nullable + public MapGenTFMajorFeature createFeatureGenerator() { + return this.shouldHaveFeatureGenerator ? new MapGenTFMajorFeature(this) : null; + } + + /** + * doesn't require modid + */ + public static TFFeature getFeatureByName(String name) { + for (TFFeature feature : VALUES) { + if (feature.name.equalsIgnoreCase(name)) { + return feature; + } + } + return NOTHING; + } + + /** + * modid sensitive + */ + public static TFFeature getFeatureByName(ResourceLocation name) { + if (name.getNamespace().equalsIgnoreCase(TwilightForestMod.ID)) { + return getFeatureByName(name.getPath()); + } + return NOTHING; + } + + public static TFFeature getFeatureByID(int id) { + return id < VALUES.length ? VALUES[id] : NOTHING; + } + + public static int getFeatureID(int mapX, int mapZ, World world) { + return getFeatureAt(mapX, mapZ, world).ordinal(); + } + + public static TFFeature getFeatureAt(int mapX, int mapZ, World world) { + return generateFeature(mapX >> 4, mapZ >> 4, world); + } + + public static boolean isInFeatureChunk(World world, int mapX, int mapZ) { + int chunkX = mapX >> 4; + int chunkZ = mapZ >> 4; + BlockPos cc = getNearestCenterXYZ(chunkX, chunkZ, world); + + return chunkX == (cc.getX() >> 4) && chunkZ == (cc.getZ() >> 4); + } + /** * Turns on biome-specific decorations like grass and trees near this feature. */ @@ -258,7 +551,7 @@ public TFFeature disableProtectionAura() { /** * Add a monster to spawn list 0 */ - public TFFeature addMonster(Class monsterClass, int weight, int minGroup, int maxGroup) { + public TFFeature addMonster(Class monsterClass, int weight, int minGroup, int maxGroup) { this.addMonster(0, monsterClass, weight, minGroup, maxGroup); return this; } @@ -266,19 +559,15 @@ public TFFeature addMonster(Class monsterClass, int /** * Add a monster to a specific spawn list */ - public TFFeature addMonster(int listIndex, Class monsterClass, int weight, int minGroup, int maxGroup) - { + public TFFeature addMonster(int listIndex, Class monsterClass, int weight, int minGroup, int maxGroup) { List monsterList; - if (this.spawnableMonsterLists.size() > listIndex) - { + if (this.spawnableMonsterLists.size() > listIndex) { monsterList = this.spawnableMonsterLists.get(listIndex); - } - else - { - monsterList = new ArrayList(); + } else { + monsterList = new ArrayList<>(); this.spawnableMonsterLists.add(listIndex, monsterList); } - + monsterList.add(new SpawnListEntry(monsterClass, weight, minGroup, maxGroup)); return this; } @@ -286,7 +575,7 @@ public TFFeature addMonster(int listIndex, Class mon /** * Add a water creature */ - public TFFeature addWaterCreature(Class monsterClass, int weight, int minGroup, int maxGroup) { + public TFFeature addWaterCreature(Class monsterClass, int weight, int minGroup, int maxGroup) { this.waterCreatureList.add(new SpawnListEntry(monsterClass, weight, minGroup, maxGroup)); return this; } @@ -295,693 +584,365 @@ public TFFeature addWaterCreature(Class monsterClass * @return The type of feature directly at the specified Chunk coordinates */ public static TFFeature getFeatureDirectlyAt(int chunkX, int chunkZ, World world) { - - if (world != null && world.getWorldChunkManager() instanceof TFWorldChunkManager) - { - TFWorldChunkManager tfManager = (TFWorldChunkManager) world.getWorldChunkManager(); - - if (tfManager.isInFeatureChunk(world, chunkX << 4, chunkZ << 4)) - { - return tfManager.getFeatureAt(chunkX << 4, chunkZ << 4, world); - } - else - { - return nothing; - } - } - else - { - return nothing; + if (isInFeatureChunk(world, chunkX << 4, chunkZ << 4)) { + return getFeatureAt(chunkX << 4, chunkZ << 4, world); } + return NOTHING; } /** * What feature would go in this chunk. Called when we know there is a feature, but there is no cache data, * either generating this chunk for the first time, or using the magic map to forecast beyond the edge of the world. */ - public static TFFeature generateFeatureForOldMapGen(int chunkX, int chunkZ, World world) - { -// if (false) -// { -// //return generateFeaturePreset5x5(chunkX, chunkZ, world); -// return generateFeaturePreset6x6(chunkX, chunkZ, world); -// } + public static TFFeature generateFeature(int chunkX, int chunkZ, World world) { + // FIXME Remove block comment start-marker to enable debug + /*if (true) { + return NAGA_COURTYARD; + }//*/ + + // set the chunkX and chunkZ to the center of the biome + chunkX = Math.round(chunkX / 16F) * 16; + chunkZ = Math.round(chunkZ / 16F) * 16; // what biome is at the center of the chunk? - BiomeGenBase biomeAt = world.getBiomeGenForCoords((chunkX << 4) + 8, (chunkZ << 4) + 8); - - // get random value - Random hillRNG = new Random(world.getSeed() + chunkX * 25117 + chunkZ * 151121); - int randnum = hillRNG.nextInt(16); - - // glaciers have ice towers - if (biomeAt == TFBiomeBase.glacier) { - return iceTower; - } - - // lakes have quest islands - if (biomeAt == TFBiomeBase.tfLake) { - return questIsland; - } - - // enchanted forests have groves - if (biomeAt == TFBiomeBase.enchantedForest) { - return questGrove; - } - - // fire swamp has hydra lair - if (biomeAt == TFBiomeBase.fireSwamp) { - return hydraLair; - } - - // temporary, clearing has maze ruins - if (biomeAt == TFBiomeBase.clearing || biomeAt == TFBiomeBase.oakSavanna) { - return labyrinth; - } - - // dark forests have their own things - if (biomeAt == TFBiomeBase.darkForest) - { - switch (randnum % 3) - { - case 0: - //return druidGrove; - break; - case 1: - return darkTower; - case 2: - return tfStronghold; - } - } - - - // highlands center has castle - if (biomeAt == TFBiomeBase.highlandsCenter) { - return finalCastle; - } - // highlands has trolls - if (biomeAt == TFBiomeBase.highlands) { - return trollCave; - } - - // deep mushrooms has mushroom tower - if (biomeAt == TFBiomeBase.deepMushrooms) { - return mushroomTower; - } - - // okay, well that takes care of most special cases - switch (randnum) - { - default: - case 0: // oops, I forgot about zero for a long time, now there are too many hill 1s - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - return hill1; - case 7: - case 8: - case 9: - return hill2; - case 10: - return hill3; - case 11: - case 12: - return hedgeMaze; - case 13: - return (biomeAt != TFBiomeBase.tfSwamp) ? nagaCourtyard : hydraLair; // hydra in the swamp, naga everywhere else - case 14: - case 15: - return lichTower; - } - } - - public static TFFeature generateFeatureFor1Point7(int chunkX, int chunkZ, World world) { - if (TwilightForestMod.oldMapGen) - { - return generateFeatureForOldMapGen(chunkX, chunkZ, world); + Biome biomeAt = world.getBiome(new BlockPos((chunkX << 4) + 8, 0, (chunkZ << 4) + 8)); + + // does the biome have a feature? + if (biomeAt instanceof TFBiomeBase) { + TFFeature biomeFeature = ((TFBiomeBase) biomeAt).containedFeature; + if (biomeFeature != NOTHING) { + return biomeFeature; + } } - - // set the chunkX and chunkZ to the center of the biome - chunkX = Math.round(chunkX / 16F) * 16; - chunkZ = Math.round(chunkZ / 16F) * 16; - - // what biome is at the center of the chunk? - BiomeGenBase biomeAt = world.getBiomeGenForCoords((chunkX << 4) + 8, (chunkZ << 4) + 8); - - // get random value - Random hillRNG = new Random(world.getSeed() + chunkX * 25117 + chunkZ * 151121); - int randnum = hillRNG.nextInt(16); - - // glaciers have ice towers - if (biomeAt == TFBiomeBase.glacier) { - return iceTower; - } - // snow has yeti lair - if (biomeAt == TFBiomeBase.tfSnow) { - return yetiCave; - } - - // lakes have quest islands - if (biomeAt == TFBiomeBase.tfLake) { - return questIsland; - } - - // enchanted forests have groves - if (biomeAt == TFBiomeBase.enchantedForest) { - return questGrove; - } - - // fire swamp has hydra lair - if (biomeAt == TFBiomeBase.fireSwamp) { - return hydraLair; - } - // swamp has labyrinth - if (biomeAt == TFBiomeBase.tfSwamp) { - return labyrinth; - } - - // dark forests have their own things - if (biomeAt == TFBiomeBase.darkForest) - { - return tfStronghold; - } - if (biomeAt == TFBiomeBase.darkForestCenter) { - return darkTower; - } - - // highlands center has castle - if (biomeAt == TFBiomeBase.highlandsCenter) { - return finalCastle; - } - // highlands has trolls - if (biomeAt == TFBiomeBase.highlands) { - return trollCave; - } - - // deep mushrooms has mushroom tower - if (biomeAt == TFBiomeBase.deepMushrooms) { - return mushroomTower; - } - - int regionOffsetX = Math.abs((chunkX + 64 >> 4) % 8); - int regionOffsetZ = Math.abs((chunkZ + 64 >> 4) % 8); - - // plant two lich towers near the center of each 2048x2048 map area + + int regionOffsetX = Math.abs((chunkX + 64 >> 4) % 8); + int regionOffsetZ = Math.abs((chunkZ + 64 >> 4) % 8); + + // plant two lich towers near the center of each 2048x2048 map area if ((regionOffsetX == 4 && regionOffsetZ == 5) || (regionOffsetX == 4 && regionOffsetZ == 3)) { - return lichTower; - } - - // also two nagas + return LICH_TOWER; + } + + // also two nagas if ((regionOffsetX == 5 && regionOffsetZ == 4) || (regionOffsetX == 3 && regionOffsetZ == 4)) { - return nagaCourtyard; - } - - // okay, well that takes care of most special cases - switch (randnum) - { - default: - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - return hill1; - case 6: - case 7: - case 8: - return hill2; - case 9: - return hill3; - case 10: - case 11: - return hedgeMaze; - case 12: - case 13: - return nagaCourtyard; - case 14: - case 15: - return lichTower; - } + return NAGA_COURTYARD; + } + + // get random value + // okay, well that takes care of most special cases + switch (new Random(world.getSeed() + chunkX * 25117 + chunkZ * 151121).nextInt(16)) { + default: + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + return SMALL_HILL; + case 6: + case 7: + case 8: + return MEDIUM_HILL; + case 9: + return LARGE_HILL; + case 10: + case 11: + return HEDGE_MAZE; + case 12: + case 13: + return NAGA_COURTYARD; + case 14: + case 15: + return LICH_TOWER; + } } /** - * What feature would go in this chunk. Called when we know there is a feature, but there is no cache data, - * either generating this chunk for the first time, or using the magic map to forecast beyond the edge of the world. + * Returns the feature nearest to the specified chunk coordinates. */ - public static TFFeature generateFeaturePreset5x5(int chunkX, int chunkZ, World world) - { - int cf = 16; - - if (chunkX % cf != 0 || chunkZ % cf != 0) - { - return TFFeature.nothing; - } - - int mx = (chunkX / cf) + 4; - int mz = (chunkZ / cf) + 4; - - - int[][] map = { - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 19, 18, 8, 15, 14, 0 }, - { 0, 0, 18, 18, 2, 3, 15, 0 }, - { 0, 0, 4, 4, 5, 16, 9, 0 }, - { 0, 0, 13, 6, 1, 2, 17, 0 }, - { 0, 0, 12, 13, 3, 17, 7, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 } }; - - if (mx >= 0 && mx < 8 && mz >= 0 && mz < 8) - { - return TFFeature.featureList[map[mz][mx]]; + public static TFFeature getNearestFeature(int cx, int cz, World world) { + return getNearestFeature(cx, cz, world, null); + } + + /** + * Returns the feature nearest to the specified chunk coordinates. + * + * If a non-null {@code center} is provided and a valid feature is found, + * it will be set to relative block coordinates indicating the center of + * that feature relative to the current chunk block coordinate system. + */ + public static TFFeature getNearestFeature(int cx, int cz, World world, @Nullable IntPair center) { + + int diam = maxSize * 2 + 1; + TFFeature[] features = new TFFeature[diam * diam]; + + for (int rad = 1; rad <= maxSize; rad++) { + for (int x = -rad; x <= rad; x++) { + for (int z = -rad; z <= rad; z++) { + + int idx = (x + maxSize) * diam + (z + maxSize); + TFFeature directlyAt = features[idx]; + if (directlyAt == null) { + features[idx] = directlyAt = getFeatureDirectlyAt(x + cx, z + cz, world); + } + + if (directlyAt.size == rad) { + if (center != null) { + center.x = (x << 4) + 8; + center.z = (z << 4) + 8; + } + return directlyAt; + } + } + } } - else - { - return TFFeature.nothing; + + return NOTHING; + } + + // [Vanilla Copy] from MapGenStructure#findNearestStructurePosBySpacing; changed 2nd param to be TFFeature instead of MapGenStructure + @Nullable + public static BlockPos findNearestFeaturePosBySpacing(World worldIn, TFFeature feature, BlockPos blockPos, int p_191069_3_, int p_191069_4_, int p_191069_5_, boolean p_191069_6_, int p_191069_7_, boolean findUnexplored) { + int i = blockPos.getX() >> 4; + int j = blockPos.getZ() >> 4; + int k = 0; + + for (Random random = new Random(); k <= p_191069_7_; ++k) { + for (int l = -k; l <= k; ++l) { + boolean flag = l == -k || l == k; + + for (int i1 = -k; i1 <= k; ++i1) { + boolean flag1 = i1 == -k || i1 == k; + + if (flag || flag1) { + int j1 = i + p_191069_3_ * l; + int k1 = j + p_191069_3_ * i1; + + if (j1 < 0) { + j1 -= p_191069_3_ - 1; + } + + if (k1 < 0) { + k1 -= p_191069_3_ - 1; + } + + int l1 = j1 / p_191069_3_; + int i2 = k1 / p_191069_3_; + Random random1 = worldIn.setRandomSeed(l1, i2, p_191069_5_); + l1 = l1 * p_191069_3_; + i2 = i2 * p_191069_3_; + + if (p_191069_6_) { + l1 = l1 + (random1.nextInt(p_191069_3_ - p_191069_4_) + random1.nextInt(p_191069_3_ - p_191069_4_)) / 2; + i2 = i2 + (random1.nextInt(p_191069_3_ - p_191069_4_) + random1.nextInt(p_191069_3_ - p_191069_4_)) / 2; + } else { + l1 = l1 + random1.nextInt(p_191069_3_ - p_191069_4_); + i2 = i2 + random1.nextInt(p_191069_3_ - p_191069_4_); + } + + MapGenBase.setupChunkSeed(worldIn.getSeed(), random, l1, i2); + random.nextInt(); + + // Check changed for TFFeature + if (getFeatureAt(l1 << 4, i2 << 4, worldIn) == feature) { + if (!findUnexplored || !worldIn.isChunkGeneratedAt(l1, i2)) { + return new BlockPos((l1 << 4) + 8, 64, (i2 << 4) + 8); + } + } else if (k == 0) { + break; + } + } + } + + if (k == 0) { + break; + } + } } - } - + + return null; + } + /** - * What feature would go in this chunk. Called when we know there is a feature, but there is no cache data, - * either generating this chunk for the first time, or using the magic map to forecast beyond the edge of the world. + * @return The feature in the chunk "region" */ - public static TFFeature generateFeaturePreset6x6(int chunkX, int chunkZ, World world) - { - int cf = 16; - - if (chunkX % cf != 0 || chunkZ % cf != 0) - { - return TFFeature.nothing; - } - - int mx = (chunkX / cf) + 3; - int mz = (chunkZ / cf) + 3; - - - int[][] map = { - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 19, 19, 18, 15, 0, 0, 0 }, - { 0, 18, 18, 18, 0, 14, 0, 0 }, - { 0, 0, 4, 1, 2, 3, 15, 0 }, - { 0, 4, 1, 5, 16, 9, 17, 0 }, - { 0, 0, 13, 2, 3, 17, 17, 0 }, - { 0, 0, 12, 13, 6, 17, 7, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 } }; - - if (mx >= 0 && mx < 8 && mz >= 0 && mz < 8) - { - return TFFeature.featureList[map[mz][mx]]; - } - else - { - return TFFeature.nothing; - } - } - - /** - * @return The feature nearest to the specified chunk coordinates - */ - public static TFFeature getNearestFeature(int cx, int cz, World world) - { - for (int rad = 1; rad <= 3; rad++) - { - for (int x = -rad; x <= rad; x++) - { - for (int z = -rad; z <= rad; z++) - { - TFFeature directlyAt = getFeatureDirectlyAt(x + cx, z + cz, world); - if (directlyAt.size == rad) - { - return directlyAt; - } - } - } - } - - return nothing; - } - - /** - * @return The feature in the chunk "region" - */ - public static TFFeature getFeatureForRegion(int chunkX, int chunkZ, World world) - { - //just round to the nearest multiple of 16 chunks? - int featureX = Math.round(chunkX / 16F) * 16; - int featureZ = Math.round(chunkZ / 16F) * 16; - - return TFFeature.generateFeatureFor1Point7(featureX, featureZ, world); - - /* old version - for (int rad = 1; rad <= 3; rad++) - { - for (int x = -rad; x <= rad; x++) - { - for (int z = -rad; z <= rad; z++) - { - TFFeature directlyAt = getFeatureDirectlyAt(x + chunkX, z + chunkZ, world); - if (directlyAt != TFFeature.nothing) - { - return directlyAt; - } - } - } - } - - return nothing; - */ - } - - /** - * If we're near a hollow hill, this returns relative block coordinates indicating the center of that hill relative to the current chunk block coordinate system. - * - * @param cx - * @param cz - * @param seed - * @return - */ - public static int[] getNearestCenter(int cx, int cz, World world) - { - for (int rad = 1; rad <= 3; rad++) - { - for (int x = -rad; x <= rad; x++) - { - for (int z = -rad; z <= rad; z++) - { - if (getFeatureDirectlyAt(x + cx, z + cz, world).size == rad) - { - int[] center = {x * 16 + 8, z * 16 + 8}; - return center; - } - } - } - } - int[] no = {0, 0}; - return no; - } - - /** - * Given some coordinates, return the center of the nearest feature. - * - * At the moment, with how features are distributed, just get the closest multiple of 256 and add +8 in both directions. - * - * Maybe in the future we'll have to actually search for a feature chunk nearby, but for now this will work. - * - */ - public static ChunkCoordinates getNearestCenterXYZ(int cx, int cz, World world) { - // legacy support - if (TwilightForestMod.oldMapGen) - { - return getNearestCenterXYZOld(cx, cz, world); - } - - int chunkX = cx; - int chunkZ = cz; - - // generate random number for the whole biome area - int regionX = (chunkX + 8) >> 4; - int regionZ = (chunkZ + 8) >> 4; - - long seed = (long)(regionX * 3129871) ^ (long)regionZ * 116129781L; - seed = seed * seed * 42317861L + seed * 7L; - - int num0 = (int) (seed >> 12 & 3L); - int num1 = (int) (seed >> 15 & 3L); - int num2 = (int) (seed >> 18 & 3L); - int num3 = (int) (seed >> 21 & 3L); - - // slightly randomize center of biome (+/- 3) - int centerX = 8 + num0 - num1; - int centerZ = 8 + num2 - num3; - - // centers are offset strangely depending on +/- - int ccz; - if (regionZ >= 0) { - ccz = (regionZ * 16 + centerZ - 8) * 16 + 8; - } else { - ccz = (regionZ * 16 + (16 - centerZ) - 8) * 16 + 9; - } - - int ccx; - if (regionX >= 0) { - ccx = (regionX * 16 + centerX - 8) * 16 + 8; - } else { - ccx = (regionX * 16 + (16 - centerX) - 8) * 16 + 9; - } - - return new ChunkCoordinates(ccx, TFWorld.SEALEVEL, ccz);// Math.abs(chunkX % 16) == centerX && Math.abs(chunkZ % 16) == centerZ; - - - - } - - private static ChunkCoordinates getNearestCenterXYZOld(int cx, int cz, World world) { - int fx = (int) (Math.round(cx / 256.0) * 256 + 8); - int fz = (int) (Math.round(cz / 256.0) * 256 + 8); - - return new ChunkCoordinates(fx, TFWorld.SEALEVEL, fz); + public static TFFeature getFeatureForRegion(int chunkX, int chunkZ, World world) { + //just round to the nearest multiple of 16 chunks? + int featureX = Math.round(chunkX / 16F) * 16; + int featureZ = Math.round(chunkZ / 16F) * 16; + return generateFeature(featureX, featureZ, world); } /** - * Returns a list of hostile monsters. Are we ever going to need passive or water creatures? - */ - public List getSpawnableList(EnumCreatureType par1EnumCreatureType) - { - if (par1EnumCreatureType == EnumCreatureType.monster) - { - return this.getSpawnableList(EnumCreatureType.monster, 0); - } - else if (par1EnumCreatureType == EnumCreatureType.ambient) - { - return this.ambientCreatureList; - } - else if (par1EnumCreatureType == EnumCreatureType.waterCreature) - { - return this.waterCreatureList; - } - else - { - return emptyList; - } - } - - /** - * Returns a list of hostile monsters in the specified indexed category - */ - public List getSpawnableList(EnumCreatureType par1EnumCreatureType, int index) - { - if (par1EnumCreatureType == EnumCreatureType.monster) - { - if (index >= 0 && index < this.spawnableMonsterLists.size()) - { - return this.spawnableMonsterLists.get(index); - } - else - { - return emptyList; - } - } - else - { - return getSpawnableList(par1EnumCreatureType); - } - } - - private TFFeature setRequiredAchievement(Achievement required) { - this.requiredAchievement = required; - - return this; + * @return The feature in the chunk "region" + */ + public static TFFeature getFeatureForRegionPos(int posX, int posZ, World world) { + return getFeatureForRegion(posX >> 4, posZ >> 4, world); } - public boolean doesPlayerHaveRequiredAchievement(EntityPlayer player) { - if (this.requiredAchievement != null) { - // can we get the player's stats here at all? - if (player instanceof EntityPlayerMP && ((EntityPlayerMP)player).func_147099_x() != null) { - StatisticsFile stats = ((EntityPlayerMP)player).func_147099_x(); - - return stats.hasAchievementUnlocked(this.requiredAchievement); - } else { - return false; // cannot get stats - } + /** + * Given some coordinates, return the center of the nearest feature. + *

+ * At the moment, with how features are distributed, just get the closest multiple of 256 and add +8 in both directions. + *

+ * Maybe in the future we'll have to actually search for a feature chunk nearby, but for now this will work. + */ + public static BlockPos getNearestCenterXYZ(int cx, int cz, World world) { + // generate random number for the whole biome area + int regionX = (cx + 8) >> 4; + int regionZ = (cz + 8) >> 4; + + long seed = (long) (regionX * 3129871) ^ (long) regionZ * 116129781L; + seed = seed * seed * 42317861L + seed * 7L; + + int num0 = (int) (seed >> 12 & 3L); + int num1 = (int) (seed >> 15 & 3L); + int num2 = (int) (seed >> 18 & 3L); + int num3 = (int) (seed >> 21 & 3L); + + // slightly randomize center of biome (+/- 3) + int centerX = 8 + num0 - num1; + int centerZ = 8 + num2 - num3; + + // centers are offset strangely depending on +/- + int ccz; + if (regionZ >= 0) { + ccz = (regionZ * 16 + centerZ - 8) * 16 + 8; + } else { + ccz = (regionZ * 16 + (16 - centerZ) - 8) * 16 + 9; + } + + int ccx; + if (regionX >= 0) { + ccx = (regionX * 16 + centerX - 8) * 16 + 8; } else { - return true; // no required achievement + ccx = (regionX * 16 + (16 - centerX) - 8) * 16 + 9; + } + + return new BlockPos(ccx, TFWorld.SEALEVEL, ccz);// Math.abs(chunkX % 16) == centerX && Math.abs(chunkZ % 16) == centerZ; + } + + /** + * Returns a list of hostile monsters. Are we ever going to need passive or water creatures? + */ + public List getSpawnableList(EnumCreatureType creatureType) { + switch (creatureType) { + case MONSTER: + return this.getSpawnableList(EnumCreatureType.MONSTER, 0); + case AMBIENT: + return this.ambientCreatureList; + case WATER_CREATURE: + return this.waterCreatureList; + default: + return new ArrayList<>(); } } - + + /** + * Returns a list of hostile monsters in the specified indexed category + */ + public List getSpawnableList(EnumCreatureType creatureType, int index) { + if (creatureType != EnumCreatureType.MONSTER) { + return getSpawnableList(creatureType); + } + if (index >= 0 && index < this.spawnableMonsterLists.size()) { + return this.spawnableMonsterLists.get(index); + } + return new ArrayList<>(); + } + + public boolean doesPlayerHaveRequiredAdvancements(EntityPlayer player) { + return PlayerHelper.doesPlayerHaveRequiredAdvancements(player, requiredAdvancements); + } /** * Try to spawn a hint monster near the specified player */ public void trySpawnHintMonster(World world, EntityPlayer player) { - this.trySpawnHintMonster(world, player, MathHelper.floor_double(player.posX), MathHelper.floor_double(player.posY), MathHelper.floor_double(player.posZ)); + this.trySpawnHintMonster(world, player, new BlockPos(player)); } /** * Try several times to spawn a hint monster */ - public void trySpawnHintMonster(World world, EntityPlayer player, int x, int y, int z) { + public void trySpawnHintMonster(World world, EntityPlayer player, BlockPos pos) { // check if the timer is valid long currentTime = world.getTotalWorldTime(); - + // if someone set the time backwards, fix the spawn timer if (currentTime < this.lastSpawnedHintMonsterTime) { this.lastSpawnedHintMonsterTime = 0; } - + if (currentTime - this.lastSpawnedHintMonsterTime > 1200) { // okay, time is good, try several times to spawn one for (int i = 0; i < 20; i++) { - if (didSpawnHintMonster(world, player, x, y, z)) { + if (didSpawnHintMonster(world, player, pos)) { this.lastSpawnedHintMonsterTime = currentTime; break; } } - } else { - //System.out.println("Can't spawn hint monster because of timer"); } - } /** * Try once to spawn a hint monster near the player. Return true if we did. - * + *

* We could change up the monster depending on what feature this is, but we currently are not doing that */ - private boolean didSpawnHintMonster(World world, EntityPlayer player, int x, int y, int z) { + private boolean didSpawnHintMonster(World world, EntityPlayer player, BlockPos pos) { // find a target point - int dx = x + world.rand.nextInt(16) - world.rand.nextInt(16); - int dy = y + world.rand.nextInt(4) - world.rand.nextInt(4); - int dz = z + world.rand.nextInt(16) - world.rand.nextInt(16); - + int dx = world.rand.nextInt(16) - world.rand.nextInt(16); + int dy = world.rand.nextInt( 4) - world.rand.nextInt( 4); + int dz = world.rand.nextInt(16) - world.rand.nextInt(16); + // make our hint monster EntityTFKobold hinty = new EntityTFKobold(world); - hinty.setPosition(dx, dy, dz); - + hinty.moveToBlockPosAndAngles(pos.add(dx, dy, dz), 0f, 0f); + // check if the bounding box is clear - boolean isClearSpawn = world.checkNoEntityCollision(hinty.boundingBox) && world.getCollidingBoundingBoxes(hinty, hinty.boundingBox).isEmpty() && !world.isAnyLiquid(hinty.boundingBox); - - if (isClearSpawn && hinty.canEntityBeSeen(player)) { - + if (hinty.isNotColliding() && hinty.getEntitySenses().canSee(player)) { + // add items and hint book ItemStack book = this.createHintBook(); - hinty.setCurrentItemOrArmor(0, book); - hinty.setEquipmentDropChance(0, 1.0F); - - world.spawnEntityInWorld(hinty); + hinty.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, book); + hinty.setDropChance(EntityEquipmentSlot.MAINHAND, 1.0F); + //hinty.setDropItemsWhenDead(true); + + world.spawnEntity(hinty); return true; - } else { - //System.out.println("Spawn point no go"); - //System.out.println("Spawn point clear? " + isClearSpawn); - //System.out.println("Spawn point can see player? " + skel.canEntityBeSeen(player)); - return false; } - } + return false; + } /** * Create a hint book for the specified feature. Only features with block protection will need this. */ public ItemStack createHintBook() { - ItemStack book = new ItemStack(Items.written_book); - - NBTTagList bookPages = new NBTTagList(); - - if (this == TFFeature.lichTower) { - - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook, gnawed on by monsters]]\u00A70\n\nI have begun examining the strange aura surrounding this tower. The bricks of the tower are protected by a curse, stronger than any I've seen before. The magic from the curse")); - bookPages.appendTag(new NBTTagString("is boiling off into the surrounding area.\n\nIn my homeland I would have many options for dealing with this magic, but here my supplies are limited. I shall have to research...")); - bookPages.appendTag(new NBTTagString("\u00A78[[Many entries later]]\u00A70\n\nA breakthrough! In my journeys I sighted a huge snake-like monster in a decorated courtyard. Nearby, I picked up a worn down, discarded green scale.\n\nThe magic in the scale seems to have the")); - bookPages.appendTag(new NBTTagString("curse-breaking properties I need, but the magic is too dim. I may need to acquire a fresher specimen, directly from the creature.")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on a Pointy Tower")); - } else if (this == TFFeature.labyrinth) { - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook, written on waterproof paper]]\u00A70\n\nThe mosquitoes in this swamp are vexing, but strange. The vast majority of them seem to have no natural source, nor do they seem to have a role in the local ecology. I have begun to")); - bookPages.appendTag(new NBTTagString("suspect that they are some kind of magical curse.\n\n\u00A78[[Next entry]]\u00A70\n\nNow that I have encountered a protection spell on the ruined labyrinth here, I consider my suspicions confirmed. Both the protection")); - bookPages.appendTag(new NBTTagString("spell and the mosquitoes are a curse. This curse seems to have a different source from the others I have encountered. I will have to research further...\n\n\u00A78[[Next entry]]\u00A70\n\nThe curse seems to")); - bookPages.appendTag(new NBTTagString("be of a type too powerful for one being alone to produce. Several wizards working in combination would be necessary.\n\nIf one of the wizards stopped contributing, the whole of the curse over the entire swamp would fall. Strangely, ")); - bookPages.appendTag(new NBTTagString("my divinations do not show signs of any nearby living wizards. I did see something interesting in one of the nearby pointy-roofed towers though...")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on a Swampy Labyrinth")); - - } else if (this == TFFeature.hydraLair) { - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook, written on fireproof paper]]\u00A70\n\nFire is a trivial obstacle for a master explorer such as myself. I have traversed seas of fire, and swam through oceans of lava. The burning air here is an interesting variation,")); - bookPages.appendTag(new NBTTagString("but ultimately no hinderance.\n\nWhat does stop me though is that I have encountered another protection spell, this time surrounding a mighty creature that must be king of this fire swamp. This is not the first protection spell I have")); - bookPages.appendTag(new NBTTagString("encountered, and I am beginning to unravel the mysteries of how they work.\n\nIf this spell is like the others, it will be sustained by a powerful creature nearby. Surrounding the fire swamp are several wet swamps, and under those")); - bookPages.appendTag(new NBTTagString("swamps are labyrinths full of minotaurs. The logical choice to bind such a spell to would be some sort of powerful minotaur, different in some way from the others that surround it...")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on the Fire Swamp")); - - } else if (this == TFFeature.tfStronghold) { - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook, written on faintly glowing paper]]\u00A70\n\nThe tendrils of darkness surrounding this area are just a manifestation of a protective spell over the entire dark forest. The spell causes blindness, which is quite vexing. I have")); - bookPages.appendTag(new NBTTagString("seen several interesting things in the area and would like to keep exploring.\n\n\u00A78[[Next entry]]\u00A70\n\nI have found ruins in the dark forest. They belong to a stronghold, of a type usually inhabited by knights. Rather than")); - bookPages.appendTag(new NBTTagString("knights though, this stronghold is full of goblins. They wear knightly armor, but their behavior is most un-knightly.\n\n\u00A78[[Next entry]]\u00A70\n\nDeep in the ruins, I have found a pedestal. The pedestal seems to be of a type that")); - bookPages.appendTag(new NBTTagString("knights would place trophies on to prove their strength.\n\nKilling a powerful creature would seem to weaken the curse on the dark forest, and placing a trophy associated with the creature on the pedestal would likely grant access into the")); - bookPages.appendTag(new NBTTagString("main part of the stronghold.\n\nThe only creature I have seen so far seen so far of sufficient power is the many-headed beast in the fire swamp. How vexing...")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on a Stronghold")); - - } else if (this == TFFeature.darkTower) { - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook that seems to have survived an explosion]]\u00A70\n\nThis tower clearly has mechanisms that are not responding to me. Their magic almost yearns to acknowledge my touch, but it cannot. It is if the devices of the tower are being")); - bookPages.appendTag(new NBTTagString("suppressed by a powerful group of beings nearby.\n\n\u00A78[[Next entry]]\u00A70\n\nThe magic seems to emanate from deep within the strongholds nearby. It can't come from the goblins, as their magic is charming, but unfocused. There")); - bookPages.appendTag(new NBTTagString("must still be some force still active in the strongholds.\n\n\u00A78[[Next entry]]\u00A70\n\nMy analysis indicates that it comes from several sources, operating as a group. I will head back to the stronghold after I resupply...")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on a Wooden Tower")); - - } else if (this == TFFeature.yetiCave) { - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook, covered in frost]]\u00A70\n\nThe blizzard surrounding these snowy lands is unceasing. This is no ordinary snowfall--this is a magical phenomenon. I will have to conduct experiments to find")); - bookPages.appendTag(new NBTTagString("what is capable of causing such an effect.\n\n\u00A78[[Next entry]]\u00A70\n\nAt the center of the dark forest, where the leaves turn red and the grass dies, there is a wooden tower. The tops of the tower are affixed with")); - bookPages.appendTag(new NBTTagString("structures acting as antennae. The antennae are not the source of the snowfall, but serve merely to boost the power of the curse causing it.\n\nA blizzard this intense must be caused by a powerful creature, most likely found")); - bookPages.appendTag(new NBTTagString("near the top of the dark forest tower. Stop the creature, and the blizzard will fade.")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on an Icy Cave")); - - } else if (this == TFFeature.iceTower) { - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook, caked in ice]]\u00A70\n\nI overcame one blizzard, only to run into this terrible ice storm atop the glacier. My explorations have shown me the splendor of an ice palace, shining with the colors of the polar aurora. It")); - bookPages.appendTag(new NBTTagString("all seems protected by some sort of curse.\n\n\u00A78[[Next entry]]\u00A70\n\nI am no novice. This curse is fed by the power of a creature nearby. The cause of the curse surrounding the fire swamp was built off the power of the leader of the ")); - bookPages.appendTag(new NBTTagString("minotaurs nearby.\n\nSurrounding this glacier, there are masses of yetis. Perhaps the yetis have some sort of leader...")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on an Auroral Fortification")); - - } else if (this == TFFeature.trollCave) { - bookPages.appendTag(new NBTTagString("\u00A78[[An explorer's notebook, damaged by acid]]\u00A70\n\nThere seems to be no way to protect myself from the toxic rainstorm surrounding this area. In my brief excursions, I have also encountered another protection spell, similar to the")); - bookPages.appendTag(new NBTTagString("others I have witnessed. The spell must be connected to the toxic storm in some way. Further research to follow...\n\n\u00A78[[Next entry]]\u00A70\n\nSuch supreme weather magic must be the result of an unequaled weather")); - bookPages.appendTag(new NBTTagString("magician. Such a person would likely hide themselves in an extreme environment, far away.\n\nBased on my logic, I would expect to find such a person somewhere on the glacier, perhaps in some sort of fortress there...")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on an the Highlands")); - - } else { - bookPages.appendTag(new NBTTagString("\u00A78[[This book shows signs of having been copied many times]]\u00A70\n\nI cannot explain the field surrounding this structure, but the magic is powerful. If this curse is like the others, than the answer to unlocking it lies elsewhere. Perhaps there is ")); - bookPages.appendTag(new NBTTagString("something I have left undone, or some monster I have yet to defeat. I will have to turn back. I will return to this place later, to see if anything has changed.")); - - book.setTagInfo("pages", bookPages); - book.setTagInfo("author", new NBTTagString("A Forgotten Explorer")); - book.setTagInfo("title", new NBTTagString("Notes on the Unexplained")); - } - - + ItemStack book = new ItemStack(Items.WRITTEN_BOOK); + this.addBookInformation(book, new NBTTagList()); return book; } + protected void addBookInformation(ItemStack book, NBTTagList bookPages) { + + addTranslatedPages(bookPages, TwilightForestMod.ID + ".book.unknown", 2); + + book.setTagInfo("pages", bookPages); + book.setTagInfo("author", new NBTTagString(BOOK_AUTHOR)); + book.setTagInfo("title", new NBTTagString("Notes on the Unexplained")); + } + + public StructureStartTFAbstract provideStructureStart(World world, Random rand, int chunkX, int chunkZ) { + return new StructureStartNothing(world, rand, chunkX, chunkZ); + } + + private static void addTranslatedPages(NBTTagList bookPages, String translationKey, int pageCount) { + for (int i = 1; i <= pageCount; i++) { + bookPages.appendTag(new NBTTagString(ITextComponent.Serializer.componentToJson(new TextComponentTranslation(translationKey + "." + i)))); + } + } } diff --git a/src/main/java/twilightforest/TFGenericPacketHandler.java b/src/main/java/twilightforest/TFGenericPacketHandler.java deleted file mode 100644 index 782af248a6..0000000000 --- a/src/main/java/twilightforest/TFGenericPacketHandler.java +++ /dev/null @@ -1,343 +0,0 @@ -package twilightforest; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import net.minecraft.client.Minecraft; -import net.minecraft.client.particle.EntityDiggingFX; -import net.minecraft.network.PacketBuffer; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.client.renderer.TFWeatherRenderer; -import twilightforest.entity.EntityTFProtectionBox; -import twilightforest.world.WorldProviderTwilightForest; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class TFGenericPacketHandler { - - public static final byte CHANGE_DIM_ID = 1; - public static final byte TRANSFORM_BIOME = 2; - public static final byte THROW_PLAYER = 3; - public static final byte AREA_PROTECTION = 4; - public static final byte STRUCTURE_PROTECTION = 5; - public static final byte STRUCTURE_PROTECTION_CLEAR = 6; - public static final byte ENFORCED_PROGRESSION_STATUS = 7; - public static final byte ANNIHILATE_BLOCK = 8; - - /** - * Packet! - */ - @SideOnly(Side.CLIENT) - @SubscribeEvent - public void incomingPacket(ClientCustomPacketEvent event) - { - ByteBuf buf = event.packet.payload(); - - // read first byte to see what kind of packet - int discriminatorByte = buf.readByte(); - - if (discriminatorByte == TRANSFORM_BIOME) { - processTransformBiomeData(buf); - } - if (discriminatorByte == THROW_PLAYER) { - processThrowPlayerData(buf); - } - if (discriminatorByte == AREA_PROTECTION) { - processAreaProtectionData(buf); - } - if (discriminatorByte == STRUCTURE_PROTECTION) { - processStructureProtectionData(buf); - } - if (discriminatorByte == STRUCTURE_PROTECTION_CLEAR) { - processStructureProtectionClearData(buf); - } - if (discriminatorByte == ENFORCED_PROGRESSION_STATUS) { - processEnforcedProgressionStatusData(buf); - } - if (discriminatorByte == ANNIHILATE_BLOCK) { - processAnnihilateBlock(buf); - } - } - - - @SideOnly(Side.CLIENT) - private void processTransformBiomeData(ByteBuf buf) { - // get coords - int x = buf.readInt(); - int z = buf.readInt(); - // biome? - byte biomeID = buf.readByte(); - - //FMLLog.info("Got tree of transformation effect packet for %d, %d, biomeid = %d", x, z, biomeID); - - - // change it! - // we're making the assumption here that we're only getting this packet if the player attached to this client is in the same world as the tree - // thus, we don't need to send a dimension or anything - World worldObj = Minecraft.getMinecraft().theWorld; - - Chunk chunkAt = worldObj.getChunkFromBlockCoords(x, z); - - chunkAt.getBiomeArray()[(z & 15) << 4 | (x & 15)] = biomeID; - - worldObj.markBlockRangeForRenderUpdate(x, 0, z, x, 255, z); - } - - @SideOnly(Side.CLIENT) - private void processThrowPlayerData(ByteBuf buf) { - // get vector - float motionX = buf.readFloat(); - float motionY = buf.readFloat(); - float motionZ = buf.readFloat(); - - // add it to the player - Minecraft.getMinecraft().thePlayer.addVelocity(motionX, motionY, motionZ); - } - - @SideOnly(Side.CLIENT) - private void processAreaProtectionData(ByteBuf buf) { - - int minX = buf.readInt(); - int minY = buf.readInt(); - int minZ = buf.readInt(); - int maxX = buf.readInt(); - int maxY = buf.readInt(); - int maxZ = buf.readInt(); - - int blockX = buf.readInt(); - int blockY = buf.readInt(); - int blockZ = buf.readInt(); - - // make a box entity - World worldObj = Minecraft.getMinecraft().theWorld; - EntityTFProtectionBox box = new EntityTFProtectionBox(worldObj, minX, minY, minZ, maxX, maxY, maxZ); - - worldObj.addWeatherEffect(box); - - // particles from the block? - for (int i = 0; i < 20; i++) { - - double d0 = worldObj.rand.nextGaussian() * 0.02D; - double d1 = worldObj.rand.nextGaussian() * 0.02D; - double d2 = worldObj.rand.nextGaussian() * 0.02D; - - float dx = blockX + 0.5F + worldObj.rand.nextFloat() - worldObj.rand.nextFloat(); - float dy = blockY + 0.5F + worldObj.rand.nextFloat() - worldObj.rand.nextFloat(); - float dz = blockZ + 0.5F + worldObj.rand.nextFloat() - worldObj.rand.nextFloat(); - - //worldObj.spawnParticle("mobSpell", blockX + 0.5F, blockY + 0.5F, blockZ + 0.5F, red, grn, blu); - TwilightForestMod.proxy.spawnParticle(worldObj, "protection", dx, dy, dz, d0, d1, d2); - - } - } - - /** - * Incoming structure protection box - */ - @SideOnly(Side.CLIENT) - private void processStructureProtectionData(ByteBuf buf) { - - int minX = buf.readInt(); - int minY = buf.readInt(); - int minZ = buf.readInt(); - int maxX = buf.readInt(); - int maxY = buf.readInt(); - int maxZ = buf.readInt(); - - StructureBoundingBox sbb = new StructureBoundingBox(minX, minY, minZ, maxX, maxY, maxZ); - - World worldObj = Minecraft.getMinecraft().theWorld; - - //System.out.println("Getting a new structure box " + sbb); - - // add weather box if needed - if (worldObj.provider instanceof WorldProviderTwilightForest) { - TFWeatherRenderer weatherRenderer = (TFWeatherRenderer) worldObj.provider.getWeatherRenderer(); - - weatherRenderer.setProtectedBox(sbb); - } - - } - - /** - * Incoming structure all clear - */ - @SideOnly(Side.CLIENT) - private void processStructureProtectionClearData(ByteBuf buf) { - - World worldObj = Minecraft.getMinecraft().theWorld; - - //System.out.println("Getting structure all clear"); - - // add weather box if needed - if (worldObj.provider instanceof WorldProviderTwilightForest) { - TFWeatherRenderer weatherRenderer = (TFWeatherRenderer) worldObj.provider.getWeatherRenderer(); - - weatherRenderer.setProtectedBox(null); - } - - } - - @SideOnly(Side.CLIENT) - private void processEnforcedProgressionStatusData(ByteBuf buf) { - - World worldObj = Minecraft.getMinecraft().theWorld; - - boolean isEnforced = buf.readBoolean(); - - worldObj.getGameRules().setOrCreateGameRule(TwilightForestMod.ENFORCED_PROGRESSION_RULE, Boolean.valueOf(isEnforced).toString()); - } - - - @SideOnly(Side.CLIENT) - private void processAnnihilateBlock(ByteBuf buf) { - int blockX = buf.readInt(); - int blockY = buf.readInt(); - int blockZ = buf.readInt(); - - World worldObj = Minecraft.getMinecraft().theWorld; - - TwilightForestMod.proxy.doBlockAnnihilateEffect(worldObj, blockX, blockY, blockZ); - - } - - - - - - - /** - * Make a FMLProxyPacket that contains the data we need to change a biome in the world. - */ - public static FMLProxyPacket makeBiomeChangePacket(int x, int z, byte biomeID) { - - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - payload.writeByte(TRANSFORM_BIOME); // discriminator byte - payload.writeInt(x); - payload.writeInt(z); - payload.writeByte(biomeID); - - FMLProxyPacket pkt = new FMLProxyPacket(payload, TwilightForestMod.ID); - - return pkt; - } - - - /** - * Make a FMLProxyPacket that contains the data we need to add a velocity to the player - */ - public static FMLProxyPacket makeThrowPlayerPacket(float motionX, float motionY, float motionZ) { - - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - payload.writeByte(THROW_PLAYER); // discriminator byte - payload.writeFloat(motionX); - payload.writeFloat(motionY); - payload.writeFloat(motionZ); - - FMLProxyPacket pkt = new FMLProxyPacket(payload, TwilightForestMod.ID); - - return pkt; - } - - /** - * Make a FMLProxyPacket that contains the data we need to display area protection data - */ - public static FMLProxyPacket makeAreaProtectionPacket(StructureBoundingBox sbb, int blockX, int blockY, int blockZ) { - - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - payload.writeByte(AREA_PROTECTION); // discriminator byte - - payload.writeInt(sbb.minX); - payload.writeInt(sbb.minY); - payload.writeInt(sbb.minZ); - payload.writeInt(sbb.maxX); - payload.writeInt(sbb.maxY); - payload.writeInt(sbb.maxZ); - - payload.writeInt(blockX); - payload.writeInt(blockY); - payload.writeInt(blockZ); - - FMLProxyPacket pkt = new FMLProxyPacket(payload, TwilightForestMod.ID); - - return pkt; - } - - /** - * Make a FMLProxyPacket that contains the data we need to display structure protection data - */ - public static FMLProxyPacket makeStructureProtectionPacket(StructureBoundingBox sbb) { - - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - payload.writeByte(STRUCTURE_PROTECTION); // discriminator byte - - payload.writeInt(sbb.minX); - payload.writeInt(sbb.minY); - payload.writeInt(sbb.minZ); - payload.writeInt(sbb.maxX); - payload.writeInt(sbb.maxY); - payload.writeInt(sbb.maxZ); - - FMLProxyPacket pkt = new FMLProxyPacket(payload, TwilightForestMod.ID); - - return pkt; - } - - /** - * Make a FMLProxyPacket that clears structure protection data on the client - */ - public static FMLProxyPacket makeStructureProtectionClearPacket() { - - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - payload.writeByte(STRUCTURE_PROTECTION_CLEAR); // discriminator byte - - FMLProxyPacket pkt = new FMLProxyPacket(payload, TwilightForestMod.ID); - - return pkt; - } - - /** - * Make a FMLProxyPacket that sets progression enforcement on the client - */ - public static FMLProxyPacket makeEnforcedProgressionStatusPacket(boolean isEnforced) { - - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - payload.writeByte(ENFORCED_PROGRESSION_STATUS); // discriminator byte - - payload.writeBoolean(isEnforced); - - FMLProxyPacket pkt = new FMLProxyPacket(payload, TwilightForestMod.ID); - - return pkt; - } - - - - /** - * Make a FMLProxyPacket that contains a block to display annihilation effects for - */ - public static FMLProxyPacket makeAnnihilateBlockPacket(int blockX, int blockY, int blockZ) { - - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - payload.writeByte(ANNIHILATE_BLOCK); // discriminator byte - - payload.writeInt(blockX); - payload.writeInt(blockY); - payload.writeInt(blockZ); - - FMLProxyPacket pkt = new FMLProxyPacket(payload, TwilightForestMod.ID); - - return pkt; - } -} diff --git a/src/main/java/twilightforest/TFMagicMapData.java b/src/main/java/twilightforest/TFMagicMapData.java index 276e248ebd..18bd399686 100644 --- a/src/main/java/twilightforest/TFMagicMapData.java +++ b/src/main/java/twilightforest/TFMagicMapData.java @@ -1,171 +1,162 @@ package twilightforest; -import java.util.ArrayList; -import java.util.List; - +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraft.world.storage.MapData; -import twilightforest.world.TFWorldChunkManager; - - -public class TFMagicMapData extends MapData -{ - - private static final int FEATURE_DATA_BYTE = 18; - public List featuresVisibleOnMap = new ArrayList(); - - public TFMagicMapData(String par1Str) - { - super(par1Str); - } - - /** - * reads in data from the NBTTagCompound into this MapDataBase - */ +import net.minecraft.world.storage.MapDecoration; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class TFMagicMapData extends MapData { + + public final Set tfDecorations = new HashSet<>(); + + public TFMagicMapData(String name) { + super(name); + } + @Override - public void readFromNBT(NBTTagCompound par1NBTTagCompound) { - super.readFromNBT(par1NBTTagCompound); - - byte[] featureStorage = par1NBTTagCompound.getByteArray("features"); + public void readFromNBT(NBTTagCompound cmp) { + super.readFromNBT(cmp); + + byte[] featureStorage = cmp.getByteArray("features"); if (featureStorage.length > 0) { - this.updateMPMapData(featureStorage); + this.deserializeFeatures(featureStorage); } -// else { -// System.out.println("Can't find feature storage for " + this.mapName); -// } } - /** - * write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities - */ @Override - public void writeToNBT(NBTTagCompound par1NBTTagCompound) { - super.writeToNBT(par1NBTTagCompound); - - if (this.featuresVisibleOnMap.size() > 0) { - byte[] featureStorage = makeFeatureStorageArray(); - par1NBTTagCompound.setByteArray("features", featureStorage); + public NBTTagCompound writeToNBT(NBTTagCompound cmp) { + cmp = super.writeToNBT(cmp); + + if (this.tfDecorations.size() > 0) { + cmp.setByteArray("features", serializeFeatures()); } + return cmp; } - /** - * Adds a twilight forest feature to the map. - */ - public void addFeatureToMap(TFFeature feature, int x, int z) { - byte relativeX = (byte) ((x - this.xCenter) >> this.scale); - byte relativeZ = (byte) ((z - this.zCenter) >> this.scale); - byte rangeX = 64; - byte rangeY = 64; - - if (relativeX >= (-rangeX) && relativeZ >= (-rangeY) && relativeX <= rangeX && relativeZ <= rangeY) - { - byte markerIcon = (byte) feature.featureID; - byte mapX = (byte)(relativeX << 1); - byte mapZ = (byte)(relativeZ << 1); - byte mapRotation = 8; - - boolean featureFound = false; - - // look for a feature already at those coordinates - for (MapCoord existingCoord : featuresVisibleOnMap) { - if (existingCoord.centerX == mapX && existingCoord.centerZ == mapZ) { - featureFound = true; - } - } - - // if we didn't find it, add it - if (!featureFound) - { - this.featuresVisibleOnMap.add(new MapCoord(markerIcon, mapX, mapZ, mapRotation)); - } - } - } - - /** - * Checks existing features against the feature cache and removes/changes wrong ones. Does not add features. - */ - public void checkExistingFeatures(World world) - { - ArrayList toRemove = null; - - for (MapCoord coord : featuresVisibleOnMap) - { - - //System.out.printf("Existing feature at %d, %d.\n", coord.centerX, coord.centerZ); - - int worldX = (coord.centerX << this.scale - 1) + this.xCenter; - int worldZ = (coord.centerZ << this.scale - 1) + this.zCenter; - - if (world != null && world.getWorldChunkManager() instanceof TFWorldChunkManager) - { - TFWorldChunkManager tfManager = (TFWorldChunkManager) world.getWorldChunkManager(); - coord.iconSize = (byte) tfManager.getFeatureID(worldX, worldZ, world); - - if (coord.iconSize == 0) - { - if (toRemove == null) - { - toRemove = new ArrayList(); - } - toRemove.add(coord); - - //System.out.println("Removing bad mapcoord " + coord + " from " + worldX + ", " + worldZ); - } - } - } - - if (toRemove != null) - { - featuresVisibleOnMap.removeAll(toRemove); - } - } - - /** - * Updates the client's map with information from other players in MP - */ - @Override - public void updateMPMapData(byte[] par1ArrayOfByte) - { - if (par1ArrayOfByte[0] == FEATURE_DATA_BYTE) - { - // this is feature data, we can handle that directly - this.featuresVisibleOnMap.clear(); - - for (int i = 0; i < (par1ArrayOfByte.length - 1) / 3; ++i) - { - byte markerIcon = par1ArrayOfByte[i * 3 + 1]; - byte mapX = par1ArrayOfByte[i * 3 + 2]; - byte mapZ = par1ArrayOfByte[i * 3 + 3]; - byte mapRotation = 8; - this.featuresVisibleOnMap.add(new MapCoord(markerIcon, mapX, mapZ, mapRotation)); - } - } - else - { - super.updateMPMapData(par1ArrayOfByte); - } - } - - /** - * This makes a byte array that we store our feature data in to send with map update packets - */ - public byte[] makeFeatureStorageArray() - { - byte[] storage = new byte[this.featuresVisibleOnMap.size() * 3 + 1]; - storage[0] = FEATURE_DATA_BYTE; - - for (int i = 0; i < featuresVisibleOnMap.size(); ++i) - { - MapCoord featureCoord = this.featuresVisibleOnMap.get(i); - storage[i * 3 + 1] = (featureCoord.iconSize); - storage[i * 3 + 2] = featureCoord.centerX; - storage[i * 3 + 3] = featureCoord.centerZ; - } - - return storage; - } + * Checks existing features against the feature cache changes wrong ones + */ + public void checkExistingFeatures(World world) { + List toRemove = new ArrayList<>(); + List toAdd = new ArrayList<>(); + + for (TFMapDecoration coord : tfDecorations) { + int worldX = (coord.getX() << this.scale - 1) + this.xCenter; + int worldZ = (coord.getY() << this.scale - 1) + this.zCenter; + + int trueId = TFFeature.getFeatureID(worldX, worldZ, world); + if (coord.featureId != trueId) { + toRemove.add(coord); + toAdd.add(new TFMapDecoration(trueId, coord.getX(), coord.getY(), coord.getRotation())); + } + } + + tfDecorations.removeAll(toRemove); + tfDecorations.addAll(toAdd); + } + + public void deserializeFeatures(byte[] arr) { + this.tfDecorations.clear(); + + for (int i = 0; i < arr.length / 3; ++i) { + byte featureId = arr[i * 3]; + byte mapX = arr[i * 3 + 1]; + byte mapZ = arr[i * 3 + 2]; + byte mapRotation = 8; + this.tfDecorations.add(new TFMapDecoration(featureId, mapX, mapZ, mapRotation)); + } + } + public byte[] serializeFeatures() { + byte[] storage = new byte[this.tfDecorations.size() * 3]; + + int i = 0; + for (TFMapDecoration featureCoord : tfDecorations) { + storage[i * 3] = (byte) featureCoord.featureId; + storage[i * 3 + 1] = featureCoord.getX(); + storage[i * 3 + 2] = featureCoord.getY(); + i++; + } + + return storage; + } + + // VanillaCopy of super, but adjust origin + @Override + public void calculateMapCenter(double x, double z, int mapScale) { + // magic maps are offset by 1024 from normal maps so that 0,0 is in the middle of the map containing those coords + int mapSize = 128 * (1 << mapScale); + int roundX = (int) Math.round(x / mapSize); + int roundZ = (int) Math.round(z / mapSize); + this.xCenter = roundX * mapSize; + this.zCenter = roundZ * mapSize; + } + + public static class TFMapDecoration extends MapDecoration { + + private static final ResourceLocation MAP_ICONS = TwilightForestMod.prefix("textures/gui/mapicons.png"); + + final int featureId; + + public TFMapDecoration(int featureId, byte xIn, byte yIn, byte rotationIn) { + super(Type.TARGET_X, xIn, yIn, rotationIn); + this.featureId = featureId; + } + + @Override + @SideOnly(Side.CLIENT) + public boolean render(int idx) { + if (TFFeature.getFeatureByID(featureId).isStructureEnabled) { + Minecraft.getMinecraft().renderEngine.bindTexture(MAP_ICONS); + GlStateManager.pushMatrix(); + GlStateManager.translate(0.0F + getX() / 2.0F + 64.0F, 0.0F + getY() / 2.0F + 64.0F, -0.02F); + GlStateManager.rotate((float) (getRotation() * 360) / 16.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.scale(4.0F, 4.0F, 3.0F); + GlStateManager.translate(-0.125F, 0.125F, 0.0F); + float f1 = (float) (featureId % 8) / 8.0F; + float f2 = (float) (featureId / 8) / 8.0F; + float f3 = (float) (featureId % 8 + 1) / 8.0F; + float f4 = (float) (featureId / 8 + 1) / 8.0F; + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX); + bufferbuilder.pos(-1.0D, 1.0D, (float) idx * -0.001F).tex((double) f1, (double) f2).endVertex(); + bufferbuilder.pos(1.0D, 1.0D, (float) idx * -0.001F).tex((double) f3, (double) f2).endVertex(); + bufferbuilder.pos(1.0D, -1.0D, (float) idx * -0.001F).tex((double) f3, (double) f4).endVertex(); + bufferbuilder.pos(-1.0D, -1.0D, (float) idx * -0.001F).tex((double) f1, (double) f4).endVertex(); + tessellator.draw(); + GlStateManager.popMatrix(); + } + return true; + } + + @Override + public boolean equals(Object o) { + if (super.equals(o) && o instanceof TFMapDecoration) { + TFMapDecoration other = (TFMapDecoration) o; + return this.featureId == other.featureId; + } + + return false; + } + + @Override + public int hashCode() { + return super.hashCode() * 31 + featureId; + } + } } diff --git a/src/main/java/twilightforest/TFMapPacketHandler.java b/src/main/java/twilightforest/TFMapPacketHandler.java deleted file mode 100644 index d4eadff167..0000000000 --- a/src/main/java/twilightforest/TFMapPacketHandler.java +++ /dev/null @@ -1,197 +0,0 @@ -package twilightforest; - - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelHandler.Sharable; - -import java.io.IOException; - -import net.minecraft.client.Minecraft; -import net.minecraft.network.Packet; -import net.minecraft.network.PacketBuffer; -import net.minecraft.network.play.server.S34PacketMaps; -import twilightforest.item.ItemTFMagicMap; -import twilightforest.item.ItemTFMazeMap; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@Sharable -public class TFMapPacketHandler -{ - - - /** - * Extract a Packet131MapData packet from a Packet250CustomPayload. This is a little silly, huh? - */ - public S34PacketMaps readMapPacket(ByteBuf byteBuf) { - - S34PacketMaps mapPacket = new S34PacketMaps(); - try { - mapPacket.readPacketData(new PacketBuffer(byteBuf)); - } catch (IOException e) { - e.printStackTrace(); - } - - return mapPacket; - } - - /** - * Make a Packet250CustomPayload that wraps around a MapData packet, and sends on a specific channel - */ - public static Packet makeMagicMapPacket(String mapChannel, short mapID, byte[] datas) { - - S34PacketMaps mapPacket = new S34PacketMaps(mapID, datas); - PacketBuffer payload = new PacketBuffer(Unpooled.buffer()); - - try { - mapPacket.writePacketData(payload); - } catch (IOException e) { - e.printStackTrace(); - } - -// Packet pkt = new S3FPacketCustomPayload(mapChannel, payload); - - FMLProxyPacket pkt = new FMLProxyPacket(payload, mapChannel); - - return pkt; - } - - - /** - * Packet! - */ - @SideOnly(Side.CLIENT) - @SubscribeEvent - public void incomingPacket(ClientCustomPacketEvent event) - { -// System.out.println("Incoming packet detected!"); - - if (event.packet.channel().equals(ItemTFMagicMap.STR_ID)) - { - //System.out.println("Incoming magic map packet detected!"); - S34PacketMaps mapPacket = readMapPacket(event.packet.payload()); - ItemTFMagicMap.getMPMapData(mapPacket.func_149188_c(), TwilightForestMod.proxy.getClientWorld()).updateMPMapData(mapPacket.func_149187_d()); - } - else if (event.packet.channel().equals(ItemTFMazeMap.STR_ID)) - { - //System.out.println("Incoming maze map packet detected!"); - - S34PacketMaps mapPacket = readMapPacket(event.packet.payload()); - TFMazeMapData data = ItemTFMazeMap.getMPMapData(mapPacket.func_149188_c(), TwilightForestMod.proxy.getClientWorld()); - data.updateMPMapData(mapPacket.func_149187_d()); - Minecraft.getMinecraft().entityRenderer.getMapItemRenderer().func_148246_a(data); - } - } - -// @Override -// public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, EntityPlayer player) { -// // read magic map packets -// if (packet.channel.equals("tfmagicmap")) { -// Packet131MapData mapPacket = readMapPacket(packet.data); -// ItemTFMagicMap.getMPMapData(mapPacket.uniqueID, TwilightForestMod.proxy.getClientWorld()).updateMPMapData(mapPacket.itemData); -// } -// -// // read maze map packets -// if (packet.channel.equals("tfmazemap")) { -// Packet131MapData mapPacket = readMapPacket(packet.data); -// ItemTFMazeMap.getMPMapData(mapPacket.uniqueID, TwilightForestMod.proxy.getClientWorld()).updateMPMapData(mapPacket.itemData); -// } -// -// // these packets are probably sent when we first connect -// if (packet.channel.equals(TwilightForestMod.ID) && packet.data[0] == CHANGE_DIM_ID) -// { -// ByteBuffer bBuffer = ByteBuffer.wrap(packet.data); -// -// // discard first byte; -// bBuffer.get(); -// -// // get dimension ID -// int dim = bBuffer.getInt(); -// //System.out.println("The connection packet said that the dim = " + dim); -// TwilightForestMod.setDimensionID(dim); -// } -// -// // these packets are sent by the tree of transformation effect -// if (packet.channel.equals(TwilightForestMod.ID) && packet.data[0] == TRANSFORM_BIOME) -// { -// ByteBuffer bBuffer = ByteBuffer.wrap(packet.data); -// -// // discard first byte; -// bBuffer.get(); -// -// // get coords -// int x = bBuffer.getInt(); -// int z = bBuffer.getInt(); -// // biome? -// byte biomeID = bBuffer.get(); -// -// // change it -// //FMLLog.info("Got tree of transformation effect packet for %d, %d, biomeid = %d", x, z, biomeID); -// -// EntityPlayer playerEntity = (EntityPlayer)player; -// -// Chunk chunkAt = playerEntity.worldObj.getChunkFromBlockCoords(x, z); -// -// chunkAt.getBiomeArray()[(z & 15) << 4 | (x & 15)] = biomeID; -// -// playerEntity.worldObj.markBlockRangeForRenderUpdate(x, 0, z, x, 255, z); -// -// -// } -// -// -// // packets are fun! -// // what other packets do we need?! :D -// } - - -// /** -// * Called when a player logs into the server -// * SERVER SIDE -// */ -// @Override -// public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager) -// { -// } -// -// @Override -// public String connectionReceived(NetLoginHandler netHandler, INetworkManager manager) -// { -// //System.out.println("A player is logging in to the server. We should send them which tf dimension we are using"); -// -// ByteBuffer bBuffer = ByteBuffer.allocate(5); -// bBuffer.put(CHANGE_DIM_ID); -// bBuffer.putInt(TwilightForestMod.dimensionID); -// -// Packet250CustomPayload packet = new Packet250CustomPayload(TwilightForestMod.ID, bBuffer.array()); -// -// manager.addToSendQueue(packet); -// -// return null; -// } -// -// @Override -// public void connectionOpened(NetHandler netClientHandler, String server, int port, INetworkManager manager) { -// ; -// } -// -// @Override -// public void connectionOpened(NetHandler netClientHandler, MinecraftServer server, INetworkManager manager) { -// ; -// } -// -// @Override -// public void connectionClosed(INetworkManager manager) { -// ; -// } -// -// @Override -// public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login) { -// ; -// } - -} diff --git a/src/main/java/twilightforest/TFMazeMapData.java b/src/main/java/twilightforest/TFMazeMapData.java index d501b3fc76..7f32fdec17 100644 --- a/src/main/java/twilightforest/TFMazeMapData.java +++ b/src/main/java/twilightforest/TFMazeMapData.java @@ -1,39 +1,43 @@ package twilightforest; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; import net.minecraft.world.storage.MapData; +import twilightforest.world.TFWorld; +public class TFMazeMapData extends MapData { -public class TFMazeMapData extends MapData -{ - - public int yCenter; + public int yCenter; + public TFMazeMapData(String name) { + super(name); + } - public TFMazeMapData(String par1Str) - { - super(par1Str); - } - - /** - * reads in data from the NBTTagCompound into this MapDataBase - */ @Override - public void readFromNBT(NBTTagCompound par1NBTTagCompound) { - super.readFromNBT(par1NBTTagCompound); - - this.yCenter = par1NBTTagCompound.getInteger("yCenter"); + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.yCenter = nbt.getInteger("yCenter"); } - /** - * write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities - */ @Override - public void writeToNBT(NBTTagCompound par1NBTTagCompound) { - super.writeToNBT(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("yCenter", this.yCenter); - - } + public NBTTagCompound writeToNBT(NBTTagCompound nbt) { + NBTTagCompound ret = super.writeToNBT(nbt); + ret.setInteger("yCenter", this.yCenter); + return ret; + } + public void calculateMapCenter(World world, double x, double y, double z, int mapScale) { + super.calculateMapCenter(x, z, mapScale); + this.yCenter = MathHelper.floor(y); + + // when we are in a labyrinth, snap to the LABYRINTH + if (TFWorld.isTwilightForest(world) && TFFeature.getFeatureForRegion(MathHelper.floor(x) >> 4, MathHelper.floor(z) >> 4, world) == TFFeature.LABYRINTH) { + BlockPos mc = TFFeature.getNearestCenterXYZ(MathHelper.floor(x) >> 4, MathHelper.floor(z) >> 4, world); + this.xCenter = mc.getX(); + this.zCenter = mc.getZ(); + this.yCenter = MathHelper.floor(y); + } + } } diff --git a/src/main/java/twilightforest/TFSounds.java b/src/main/java/twilightforest/TFSounds.java new file mode 100644 index 0000000000..e54985cf55 --- /dev/null +++ b/src/main/java/twilightforest/TFSounds.java @@ -0,0 +1,188 @@ +package twilightforest; + +import net.minecraft.entity.passive.EntityParrot; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import twilightforest.entity.*; +import twilightforest.entity.boss.*; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public final class TFSounds { + + public static final SoundEvent KOBOLD_DEATH = createEvent("mob.kobold.die"); + public static final SoundEvent KOBOLD_AMBIENT = createEvent("mob.kobold.kobold"); + public static final SoundEvent KOBOLD_HURT = createEvent("mob.kobold.hurt"); + public static final SoundEvent KOBOLD_PARROT = createEvent("mob.kobold.parrot"); + public static final SoundEvent CICADA = createEvent("mob.cicada"); + public static final SoundEvent NAGA_HISS = createEvent("mob.naga.hiss"); + public static final SoundEvent NAGA_HURT = createEvent("mob.naga.hurt"); + public static final SoundEvent NAGA_RATTLE = createEvent("mob.naga.rattle"); + public static final SoundEvent NAGA_PARROT = createEvent("mob.naga.parrot"); + public static final SoundEvent RAVEN_CAW = createEvent("mob.raven.caw"); + public static final SoundEvent RAVEN_SQUAWK = createEvent("mob.raven.squawk"); + public static final SoundEvent REDCAP_DEATH = createEvent("mob.redcap.die"); + public static final SoundEvent REDCAP_AMBIENT = createEvent("mob.redcap.redcap"); + public static final SoundEvent REDCAP_HURT = createEvent("mob.redcap.hurt"); + public static final SoundEvent REDCAP_PARROT = createEvent("mob.redcap.parrot"); + public static final SoundEvent TINYBIRD_CHIRP = createEvent("mob.tinybird.chirp"); + public static final SoundEvent TINYBIRD_HURT = createEvent("mob.tinybird.hurt"); + public static final SoundEvent TINYBIRD_SONG = createEvent("mob.tinybird.song"); + public static final SoundEvent URGHAST_TRAP_ACTIVE = createEvent("mob.urghast.trapactive"); + public static final SoundEvent URGHAST_TRAP_ON = createEvent("mob.urghast.trapon"); + public static final SoundEvent URGHAST_TRAP_SPINDOWN = createEvent("mob.urghast.trapspindown"); + public static final SoundEvent URGHAST_TRAP_WARMUP = createEvent("mob.urghast.trapwarmup"); + public static final SoundEvent WRAITH = createEvent("mob.wraith.wraith"); + public static final SoundEvent WRAITH_PARROT = createEvent("mob.wraith.parrot"); + public static final SoundEvent HYDRA_HURT = createEvent("mob.hydra.hurt"); + public static final SoundEvent HYDRA_DEATH = createEvent("mob.hydra.death"); + public static final SoundEvent HYDRA_GROWL = createEvent("mob.hydra.growl"); + public static final SoundEvent HYDRA_ROAR = createEvent("mob.hydra.roar"); + public static final SoundEvent HYDRA_WARN = createEvent("mob.hydra.warn"); + public static final SoundEvent HYDRA_PARROT = createEvent("mob.hydra.parrot"); + public static final SoundEvent MOSQUITO = createEvent("mob.mosquito.mosquito"); + public static final SoundEvent MOSQUITO_PARROT = createEvent("mob.mosquito.parrot"); + public static final SoundEvent ICE_AMBIENT = createEvent("mob.ice.noise"); + public static final SoundEvent ICE_HURT = createEvent("mob.ice.hurt"); + public static final SoundEvent ICE_DEATH = createEvent("mob.ice.death"); + public static final SoundEvent ICE_PARROT = createEvent("mob.ice.parrot"); + public static final SoundEvent MINOTAUR_PARROT = createEvent("mob.minotaur.parrot"); + public static final SoundEvent ALPHAYETI_ALERT = createEvent("mob.alphayeti.alert"); + public static final SoundEvent ALPHAYETI_DIE = createEvent("mob.alphayeti.die"); + public static final SoundEvent ALPHAYETI_GRAB = createEvent("mob.alphayeti.grab"); + public static final SoundEvent ALPHAYETI_GROWL = createEvent("mob.alphayeti.growl"); + public static final SoundEvent ALPHAYETI_HURT = createEvent("mob.alphayeti.hurt"); + public static final SoundEvent ALPHAYETI_PANT = createEvent("mob.alphayeti.pant"); + public static final SoundEvent ALPHAYETI_ROAR = createEvent("mob.alphayeti.roar"); + public static final SoundEvent ALPHAYETI_THROW = createEvent("mob.alphayeti.throw"); + public static final SoundEvent ALPHAYETI_PARROT = createEvent("mob.alphayeti.parrot"); + public static final SoundEvent DEER_DEATH = createEvent("mob.deer.death"); + public static final SoundEvent DEER_HURT = createEvent("mob.deer.hurt"); + public static final SoundEvent DEER_IDLE = createEvent("mob.deer.idle"); + public static final SoundEvent MISTWOLF_TARGET = createEvent("mob.mistwolf.target"); + public static final SoundEvent MISTWOLF_HURT = createEvent("mob.mistwolf.hurt"); + public static final SoundEvent MISTWOLF_IDLE = createEvent("mob.mistwolf.idle"); + public static final SoundEvent MISTWOLF_PARROT = createEvent("mob.mistwolf.parrot"); + public static final SoundEvent TOME_DEATH = createEvent("mob.tome.death"); + public static final SoundEvent TOME_HURT = createEvent("mob.tome.hurt"); + public static final SoundEvent TOME_IDLE = createEvent("mob.tome.idle"); + public static final SoundEvent TOME_PARROT = createEvent("mob.tome.parrot"); + + public static final SoundEvent SLIDER = createEvent("random.slider"); + + public static final SoundEvent MUSIC = createEvent("music.bg"); + + private static SoundEvent createEvent(String sound) { + ResourceLocation name = TwilightForestMod.prefix(sound); + return new SoundEvent(name).setRegistryName(name); + } + + @SubscribeEvent + public static void registerSounds(RegistryEvent.Register event) { + event.getRegistry().registerAll( + KOBOLD_DEATH, + KOBOLD_AMBIENT, + KOBOLD_HURT, + KOBOLD_PARROT, + CICADA, + NAGA_HISS, + NAGA_HURT, + NAGA_RATTLE, + NAGA_PARROT, + RAVEN_CAW, + RAVEN_SQUAWK, + REDCAP_DEATH, + REDCAP_AMBIENT, + REDCAP_HURT, + REDCAP_PARROT, + TINYBIRD_CHIRP, + TINYBIRD_HURT, + TINYBIRD_SONG, + URGHAST_TRAP_ACTIVE, + URGHAST_TRAP_ON, + URGHAST_TRAP_SPINDOWN, + URGHAST_TRAP_WARMUP, + WRAITH, + WRAITH_PARROT, + HYDRA_DEATH, + HYDRA_GROWL, + HYDRA_HURT, + HYDRA_ROAR, + HYDRA_WARN, + HYDRA_PARROT, + MOSQUITO, + MOSQUITO_PARROT, + ICE_AMBIENT, + ICE_DEATH, + ICE_HURT, + ICE_PARROT, + MINOTAUR_PARROT, + ALPHAYETI_ALERT, + ALPHAYETI_DIE, + ALPHAYETI_GRAB, + ALPHAYETI_GROWL, + ALPHAYETI_HURT, + ALPHAYETI_PANT, + ALPHAYETI_ROAR, + ALPHAYETI_THROW, + ALPHAYETI_PARROT, + DEER_DEATH, + DEER_HURT, + DEER_IDLE, + MISTWOLF_TARGET, + MISTWOLF_HURT, + MISTWOLF_IDLE, + MISTWOLF_PARROT, + TOME_DEATH, + TOME_HURT, + TOME_IDLE, + TOME_PARROT, + SLIDER, + MUSIC + ); + + registerParrotSounds(); + } + + private static void registerParrotSounds() { + + EntityParrot.registerMimicSound(EntityTFKobold.class, KOBOLD_PARROT); + EntityParrot.registerMimicSound(EntityTFRedcap.class, REDCAP_PARROT); + EntityParrot.registerMimicSound(EntityTFRedcapSapper.class, REDCAP_PARROT); + EntityParrot.registerMimicSound(EntityTFBlockGoblin.class, REDCAP_PARROT); + EntityParrot.registerMimicSound(EntityTFBoggard.class, REDCAP_PARROT); + EntityParrot.registerMimicSound(EntityTFWraith.class, WRAITH_PARROT); + EntityParrot.registerMimicSound(EntityTFMosquitoSwarm.class, MOSQUITO_PARROT); + EntityParrot.registerMimicSound(EntityTFIceExploder.class, ICE_PARROT); + EntityParrot.registerMimicSound(EntityTFIceShooter.class, ICE_PARROT); + EntityParrot.registerMimicSound(EntityTFSnowGuardian.class, ICE_PARROT); + EntityParrot.registerMimicSound(EntityTFLoyalZombie.class, SoundEvents.E_PARROT_IM_ZOMBIE); + EntityParrot.registerMimicSound(EntityTFMinotaur.class, MINOTAUR_PARROT); + EntityParrot.registerMimicSound(EntityTFKingSpider.class, SoundEvents.E_PARROT_IM_SPIDER); + EntityParrot.registerMimicSound(EntityTFHedgeSpider.class, SoundEvents.E_PARROT_IM_SPIDER); + EntityParrot.registerMimicSound(EntityTFSwarmSpider.class, SoundEvents.E_PARROT_IM_SPIDER); + EntityParrot.registerMimicSound(EntityTFTowerBroodling.class, SoundEvents.E_PARROT_IM_SPIDER); + EntityParrot.registerMimicSound(EntityTFHostileWolf.class, MISTWOLF_PARROT); + EntityParrot.registerMimicSound(EntityTFWinterWolf.class, MISTWOLF_PARROT); + EntityParrot.registerMimicSound(EntityTFSkeletonDruid.class, SoundEvents.E_PARROT_IM_SKELETON); + EntityParrot.registerMimicSound(EntityTFTowerGhast.class, SoundEvents.E_PARROT_IM_GHAST); + EntityParrot.registerMimicSound(EntityTFMiniGhast.class, SoundEvents.E_PARROT_IM_GHAST); + EntityParrot.registerMimicSound(EntityTFTowerTermite.class, SoundEvents.E_PARROT_IM_SILVERFISH); + EntityParrot.registerMimicSound(EntityTFDeathTome.class, TOME_PARROT); + + EntityParrot.registerMimicSound(EntityTFHydra.class, HYDRA_PARROT); + EntityParrot.registerMimicSound(EntityTFKnightPhantom.class, WRAITH_PARROT); + EntityParrot.registerMimicSound(EntityTFLich.class, SoundEvents.E_PARROT_IM_BLAZE); + EntityParrot.registerMimicSound(EntityTFMinoshroom.class, MINOTAUR_PARROT); + EntityParrot.registerMimicSound(EntityTFNaga.class, NAGA_PARROT); + EntityParrot.registerMimicSound(EntityTFSnowQueen.class, ICE_PARROT); + EntityParrot.registerMimicSound(EntityTFUrGhast.class, SoundEvents.E_PARROT_IM_GHAST); + EntityParrot.registerMimicSound(EntityTFYetiAlpha.class, ALPHAYETI_PARROT); + } + + private TFSounds() {} + +} diff --git a/src/main/java/twilightforest/TFTeleporter.java b/src/main/java/twilightforest/TFTeleporter.java index 41f7ca77ed..2b6ff918c6 100644 --- a/src/main/java/twilightforest/TFTeleporter.java +++ b/src/main/java/twilightforest/TFTeleporter.java @@ -1,409 +1,498 @@ package twilightforest; -import java.util.Random; - import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.Teleporter; import net.minecraft.world.World; import net.minecraft.world.WorldServer; -import net.minecraft.world.biome.BiomeGenBase; -import twilightforest.biomes.TFBiomeBase; +import net.minecraft.world.chunk.Chunk; +import twilightforest.block.BlockTFPortal; import twilightforest.block.TFBlocks; +import twilightforest.world.ChunkGeneratorTFBase; import twilightforest.world.TFWorld; -import cpw.mods.fml.common.FMLLog; +import javax.annotation.Nullable; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; +import java.util.function.Predicate; -public class TFTeleporter extends Teleporter -{ - protected WorldServer myWorld; - protected Random rand; +public class TFTeleporter extends Teleporter { - public TFTeleporter(WorldServer par1WorldServer) { - super(par1WorldServer); - myWorld = par1WorldServer; - if (this.rand == null) - { - this.rand = new Random(); + public static TFTeleporter getTeleporterForDim(MinecraftServer server, int dim) { + WorldServer ws = server.getWorld(dim); + + for (Teleporter t : ws.customTeleporters) { + if (t instanceof TFTeleporter) { + return (TFTeleporter) t; + } } + TFTeleporter tp = new TFTeleporter(ws); + ws.customTeleporters.add(tp); + return tp; } - /** - * Place an entity in a nearby portal, creating one if necessary. - */ - public void placeInPortal(Entity par1Entity, double x, double y, double z, float facing) - { - if (!this.placeInExistingPortal(par1Entity, x, y, z, facing)) - { - // if we're in enforced progression mode, check the biomes for safety - if (par1Entity.worldObj.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { - int px = MathHelper.floor_double(par1Entity.posX); - int pz = MathHelper.floor_double(par1Entity.posZ); - if (!isSafeBiomeAt(px, pz, par1Entity)) { - System.out.println("[TwilightForest] Portal destination looks unsafe, rerouting!"); - - ChunkCoordinates safeCoords = findSafeCoords(200, px, pz, par1Entity); - - if (safeCoords != null) { - par1Entity.setLocationAndAngles(safeCoords.posX, par1Entity.posY, safeCoords.posZ, 90.0F, 0.0F); - x = safeCoords.posX; - z = safeCoords.posZ; - - System.out.println("[TwilightForest] Safely rerouted!"); - } else { - System.out.println("[TwilightForest] Did not find a safe spot at first try, trying again with longer range."); - safeCoords = findSafeCoords(400, px, pz, par1Entity); - if (safeCoords != null) { - par1Entity.setLocationAndAngles(safeCoords.posX, par1Entity.posY, safeCoords.posZ, 90.0F, 0.0F); - x = safeCoords.posX; - z = safeCoords.posZ; - - System.out.println("[TwilightForest] Safely rerouted to long range portal. Return trip not guaranteed."); - } else { - System.out.println("[TwilightForest] Did not find a safe spot."); - } - } - } - - } - - - this.makePortal(par1Entity); - this.placeInExistingPortal(par1Entity, x, y, z, facing); + private TFTeleporter(WorldServer dest) { + super(dest); + } + + @Override + public void placeInPortal(Entity entity, float facing) { + if (!this.placeInExistingPortal(entity, facing)) { + this.moveToSafeCoords(entity); + this.makePortal(entity); + this.placeInExistingPortal(entity, facing); + } + } + + private void moveToSafeCoords(Entity entity) { + // if we're in enforced progression mode, check the biomes for safety + boolean checkProgression = TFWorld.isProgressionEnforced(world); + + BlockPos pos = new BlockPos(entity); + if (isSafeAround(pos, entity, checkProgression)) { + return; + } + + TwilightForestMod.LOGGER.debug("Portal destination looks unsafe, rerouting!"); + + BlockPos safeCoords = findSafeCoords(200, pos, entity, checkProgression); + if (safeCoords != null) { + entity.setLocationAndAngles(safeCoords.getX(), entity.posY, safeCoords.getZ(), 90.0F, 0.0F); + TwilightForestMod.LOGGER.debug("Safely rerouted!"); + return; } + + TwilightForestMod.LOGGER.info("Did not find a safe portal spot at first try, trying again with longer range."); + safeCoords = findSafeCoords(400, pos, entity, checkProgression); + + if (safeCoords != null) { + entity.setLocationAndAngles(safeCoords.getX(), entity.posY, safeCoords.getZ(), 90.0F, 0.0F); + TwilightForestMod.LOGGER.info("Safely rerouted to long range portal. Return trip not guaranteed."); + return; + } + + TwilightForestMod.LOGGER.warn("Still did not find a safe portal spot."); } - - /** - * Find some safe coords within range of the destination coords, or return null. - * - * This could sure be a more methodic algorithm - */ - private ChunkCoordinates findSafeCoords(int range, int x, int z, Entity par1Entity) { - for (int i = 0; i < 25; i++) { - int dx = x + (rand.nextInt(range) - rand.nextInt(range)); - int dz = z + (rand.nextInt(range) - rand.nextInt(range)); - if (isSafeBiomeAt(dx, dz, par1Entity)) { - return new ChunkCoordinates(dx, 100, dz); + + @Nullable + private BlockPos findSafeCoords(int range, BlockPos pos, Entity entity, boolean checkProgression) { + int attempts = range / 8; + for (int i = 0; i < attempts; i++) { + BlockPos dPos = new BlockPos( + pos.getX() + random.nextInt(range) - random.nextInt(range), + 100, + pos.getZ() + random.nextInt(range) - random.nextInt(range) + ); + + if (isSafeAround(dPos, entity, checkProgression)) { + return dPos; } } return null; } - /** - * Check if the destination is safe - */ - boolean isSafeBiomeAt(int x, int z, Entity par1Entity) { - BiomeGenBase biomeAt = myWorld.getBiomeGenForCoords(x, z); - - if (biomeAt instanceof TFBiomeBase && par1Entity instanceof EntityPlayerMP) { - TFBiomeBase tfBiome = (TFBiomeBase)biomeAt; - EntityPlayerMP player = (EntityPlayerMP)par1Entity; - - return tfBiome.doesPlayerHaveRequiredAchievement(player); - + public final boolean isSafeAround(BlockPos pos, Entity entity, boolean checkProgression) { + + if (!isSafe(pos, entity, checkProgression)) { + return false; + } + + for (EnumFacing facing : EnumFacing.Plane.HORIZONTAL) { + if (!isSafe(pos.offset(facing, 16), entity, checkProgression)) { + return false; + } + } + + return true; + } + + private boolean isSafe(BlockPos pos, Entity entity, boolean checkProgression) { + return checkPos(pos) && (!checkProgression || checkBiome(pos, entity)) && checkStructure(pos); + } + + private boolean checkPos(BlockPos pos) { + return world.getWorldBorder().contains(pos); + } + + private boolean checkStructure(BlockPos pos) { + ChunkGeneratorTFBase generator = TFWorld.getChunkGenerator(world); + if (generator != null) { + if (!world.isBlockLoaded(pos)) { + generator.recreateStructures(null, pos.getX() >> 4, pos.getZ() >> 4); + } + return !generator.isBlockInFullStructure(pos.getX(), pos.getZ()); + } + return true; + } + + private boolean checkBiome(BlockPos pos, Entity entity) { + return TFWorld.isBiomeSafeFor(world.getBiome(pos), entity); + } + + // [VanillaCopy] copy of super, edits noted + @Override + public boolean placeInExistingPortal(Entity entity, float rotationYaw) { + int i = 200; // TF - scan radius up to 200, and also un-inline this variable back into below + double d0 = -1.0D; + int j = MathHelper.floor(entity.posX); + int k = MathHelper.floor(entity.posZ); + boolean flag = true; + BlockPos blockpos = BlockPos.ORIGIN; + long l = ChunkPos.asLong(j, k); + + if (this.destinationCoordinateCache.containsKey(l)) { + Teleporter.PortalPosition portalPosition = this.destinationCoordinateCache.get(l); + d0 = 0.0D; + blockpos = portalPosition; + portalPosition.lastUpdateTime = this.world.getTotalWorldTime(); + flag = false; } else { - // I guess it's safe, or maybe I just have no way to be sure! + BlockPos blockpos3 = new BlockPos(entity); + + for (int i1 = -i; i1 <= i; ++i1) { + BlockPos blockpos2; + + for (int j1 = -i; j1 <= i; ++j1) { + + // TF - skip positions outside current world border (MC-114796) + if (!this.world.getWorldBorder().contains(blockpos3.add(i1, 0, j1))) { + continue; + } + + // TF - skip chunks that aren't generated + ChunkPos chunkPos = new ChunkPos(blockpos3.add(i1, 0, j1)); + if (!this.world.isChunkGeneratedAt(chunkPos.x, chunkPos.z)) { + continue; + } + + // TF - explicitly fetch chunk so it can be unloaded if needed + Chunk chunk = this.world.getChunk(chunkPos.x, chunkPos.z); + + for (BlockPos blockpos1 = blockpos3.add(i1, getScanHeight(blockpos3) - blockpos3.getY(), j1); blockpos1.getY() >= 0; blockpos1 = blockpos2) { + blockpos2 = blockpos1.down(); + + // TF - don't lookup state if inner condition would fail + if (d0 >= 0.0D && blockpos1.distanceSq(blockpos3) >= d0) { + continue; + } + + // TF - use our portal block + if (isPortal(chunk.getBlockState(blockpos1))) { + for (blockpos2 = blockpos1.down(); isPortal(chunk.getBlockState(blockpos2)); blockpos2 = blockpos2.down()) { + blockpos1 = blockpos2; + } + + double d1 = blockpos1.distanceSq(blockpos3); + + if (d0 < 0.0D || d1 < d0) { + d0 = d1; + blockpos = blockpos1; + // TF - restrict search radius to new distance + i = MathHelper.ceil(MathHelper.sqrt(d1)); + } + } + } + + // TF - mark unwatched chunks for unload + if (!this.world.getPlayerChunkMap().contains(chunkPos.x, chunkPos.z)) { + this.world.getChunkProvider().queueUnload(chunk); + } + } + } + } + + if (d0 >= 0.0D) { + if (flag) { + this.destinationCoordinateCache.put(l, new Teleporter.PortalPosition(blockpos, this.world.getTotalWorldTime())); + } + + // TF - replace with our own placement logic + BlockPos[] portalBorder = getBoundaryPositions(blockpos).toArray(new BlockPos[0]); + BlockPos borderPos = portalBorder[random.nextInt(portalBorder.length)]; + + double portalX = borderPos.getX() + 0.5; + double portalY = borderPos.getY() + 1.0; + double portalZ = borderPos.getZ() + 0.5; + + entity.motionX = entity.motionY = entity.motionZ = 0.0D; + + if (entity instanceof EntityPlayerMP) { + ((EntityPlayerMP) entity).connection.setPlayerLocation(portalX, portalY, portalZ, entity.rotationYaw, entity.rotationPitch); + } else { + entity.setLocationAndAngles(portalX, portalY, portalZ, entity.rotationYaw, entity.rotationPitch); + } + return true; + } else { + return false; } } + private int getScanHeight(BlockPos pos) { + return getScanHeight(pos.getX(), pos.getZ()); + } - @Override - public boolean placeInExistingPortal(Entity entity, double par3, double par5, double par7, float par9) { - - int c = 200; - double d = -1D; - int i = 0; - int j = 0; - int k = 0; - int l = MathHelper.floor_double(entity.posX); - int i1 = MathHelper.floor_double(entity.posZ); - for(int j1 = l - c; j1 <= l + c; j1++) - { - double d1 = (j1 + 0.5D) - entity.posX; - for(int j2 = i1 - c; j2 <= i1 + c; j2++) - { - double d3 = (j2 + 0.5D) - entity.posZ; - for (int k2 = TFWorld.MAXHEIGHT - 1; k2 >= 0; k2--) - { - if(!isBlockPortal(myWorld, j1, k2, j2)) - { - continue; - } - for(; isBlockPortal(myWorld, j1, k2 - 1, j2); k2--) { } - double d5 = (k2 + 0.5D) - entity.posY; - double d7 = d1 * d1 + d5 * d5 + d3 * d3; - if(d < 0.0D || d7 < d) - { - d = d7; - i = j1; - j = k2; - k = j2; - } - } - - } - - } - - if(d >= 0.0D) - { - int k1 = i; - int l1 = j; - int i2 = k; - double portalX = k1 + 0.5D; - double portalY = l1 + 0.5D; - double portalZ = i2 + 0.5D; - if(isBlockPortal(myWorld, k1 - 1, l1, i2)) - { - portalX -= 0.5D; - } - if(isBlockPortal(myWorld, k1 + 1, l1, i2)) - { - portalX += 0.5D; - } - if(isBlockPortal(myWorld, k1, l1, i2 - 1)) - { - portalZ -= 0.5D; - } - if(isBlockPortal(myWorld, k1, l1, i2 + 1)) - { - portalZ += 0.5D; - } - int xOffset = 0; - int zOffset = 0; - while(xOffset == zOffset && xOffset == 0) - { - xOffset = rand.nextInt(3) - rand.nextInt(3); - zOffset = rand.nextInt(3) - rand.nextInt(3); - } - entity.setLocationAndAngles(portalX + xOffset, portalY + 1, portalZ + zOffset, entity.rotationYaw, 0.0F); - entity.motionX = entity.motionY = entity.motionZ = 0.0D; - return true; - } else - { - return false; - } - } - - /** - * Is this block either our portal or an existing nether portal? - */ - public boolean isBlockPortal(World world, int x, int y, int z) - { - return world.getBlock(x, y, z) == TFBlocks.portal; + private int getScanHeight(int x, int z) { + int worldHeight = world.getActualHeight() - 1; + int chunkHeight = world.getChunk(x >> 4, z >> 4).getTopFilledSegment() + 15; + return Math.min(worldHeight, chunkHeight); + } + + private static boolean isPortal(IBlockState state) { + return state.getBlock() == TFBlocks.twilight_portal; + } + + // from the start point, builds a set of all directly adjacent non-portal blocks + private Set getBoundaryPositions(BlockPos start) { + Set result = new HashSet<>(), checked = new HashSet<>(); + checked.add(start); + checkAdjacent(start, checked, result); + return result; + } + + private void checkAdjacent(BlockPos pos, Set checked, Set result) { + for (EnumFacing facing : EnumFacing.Plane.HORIZONTAL) { + BlockPos offset = pos.offset(facing); + if (!checked.add(offset)) continue; + if (isPortalAt(offset)) { + checkAdjacent(offset, checked, result); + } else { + result.add(offset); + } + } + } + + private boolean isPortalAt(BlockPos pos) { + return isPortal(world.getBlockState(pos)); } @Override public boolean makePortal(Entity entity) { - ChunkCoordinates spot = findPortalCoords(entity, true); - - if (spot != null) - { - FMLLog.info("[TwilightForest] Found ideal portal spot"); - makePortalAt(myWorld, spot.posX, spot.posY, spot.posZ); - return true; - } - else - { - FMLLog.info("[TwilightForest] Did not find ideal portal spot, shooting for okay one"); - spot = findPortalCoords(entity, false); - if (spot != null) - { - FMLLog.info("[TwilightForest] Found okay portal spot"); - makePortalAt(myWorld, spot.posX, spot.posY, spot.posZ); - return true; - } - } - - // well I don't think we can actally just return false and fail here - FMLLog.info("[TwilightForest] Did not even find an okay portal spot, just making a random one"); - + + // ensure area is populated first + loadSurroundingArea(entity); + + BlockPos spot = findPortalCoords(entity, this::isPortalAt); + String name = entity.getName(); + + if (spot != null) { + TwilightForestMod.LOGGER.debug("Found existing portal for {} at {}", name, spot); + cachePortalCoords(entity, spot); + return true; + } + + spot = findPortalCoords(entity, this::isIdealForPortal); + + if (spot != null) { + TwilightForestMod.LOGGER.debug("Found ideal portal spot for {} at {}", name, spot); + cachePortalCoords(entity, makePortalAt(world, spot)); + return true; + } + + TwilightForestMod.LOGGER.debug("Did not find ideal portal spot, shooting for okay one for {}", name); + spot = findPortalCoords(entity, this::isOkayForPortal); + + if (spot != null) { + TwilightForestMod.LOGGER.debug("Found okay portal spot for {} at {}", name, spot); + cachePortalCoords(entity, makePortalAt(world, spot)); + return true; + } + + // well I don't think we can actually just return false and fail here + TwilightForestMod.LOGGER.debug("Did not even find an okay portal spot, just making a random one for {}", name); + // adjust the portal height based on what world we're traveling to - double yFactor = myWorld.provider.dimensionId == 0 ? 2 : 0.5; + double yFactor = getYFactor(); // modified copy of base Teleporter method: - int entityX = MathHelper.floor_double(entity.posX); - int entityY = MathHelper.floor_double(entity.posY * yFactor); - int entityZ = MathHelper.floor_double(entity.posZ); - - makePortalAt(myWorld, entityX, entityY, entityZ); + cachePortalCoords(entity, makePortalAt(world, new BlockPos(entity.posX, (entity.posY * yFactor) - 1.0, entity.posZ))); - return false; + return false; } - public ChunkCoordinates findPortalCoords(Entity entity, boolean ideal) { - // adjust the portal height based on what world we're traveling to - double yFactor = myWorld.provider.dimensionId == 0 ? 2 : 0.5; + private void loadSurroundingArea(Entity entity) { + + int x = MathHelper.floor(entity.posX) >> 4; + int z = MathHelper.floor(entity.posZ) >> 4; + + for (int dx = -2; dx <= 2; dx++) { + for (int dz = -2; dz <= 2; dz++) { + world.getChunk(x + dx, z + dz); + } + } + } + + private double getYFactor() { + return world.provider.getDimension() == TFConfig.originDimension ? 2.0 : 0.5; + } + + @Nullable + private BlockPos findPortalCoords(Entity entity, Predicate predicate) { + // adjust the height based on what world we're traveling to + double yFactor = getYFactor(); // modified copy of base Teleporter method: - int entityX = MathHelper.floor_double(entity.posX); - int entityZ = MathHelper.floor_double(entity.posZ); - - double spotWeight = -1D; - - ChunkCoordinates spot = null; - - byte range = 16; - for(int rx = entityX - range; rx <= entityX + range; rx++) - { - double xWeight = (rx + 0.5D) - entity.posX; - for(int rz = entityZ - range; rz <= entityZ + range; rz++) - { - double zWeight = (rz + 0.5D) - entity.posZ; - - for(int ry = 128 - 1; ry >= 0; ry--) - { - if(!myWorld.isAirBlock(rx, ry, rz)) - { - continue; - } - for(; ry > 0 && myWorld.isAirBlock(rx, ry - 1, rz); ry--) { } - - if (ideal ? isIdealPortal(rx, rz, ry) : isOkayPortal(rx, rz, ry)) - { - double yWeight = (ry + 0.5D) - entity.posY * yFactor; - double rPosWeight = xWeight * xWeight + yWeight * yWeight + zWeight * zWeight; - - - if(spotWeight < 0.0D || rPosWeight < spotWeight) - { - spotWeight = rPosWeight; - spot = new ChunkCoordinates(rx, ry, rz); - } - } - } - } - } - + int entityX = MathHelper.floor(entity.posX); + int entityZ = MathHelper.floor(entity.posZ); + + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + + double spotWeight = -1D; + BlockPos spot = null; + + int range = 16; + for (int rx = entityX - range; rx <= entityX + range; rx++) { + double xWeight = (rx + 0.5D) - entity.posX; + for (int rz = entityZ - range; rz <= entityZ + range; rz++) { + double zWeight = (rz + 0.5D) - entity.posZ; + + for (int ry = getScanHeight(rx, rz); ry >= 0; ry--) { + + if (!world.isAirBlock(pos.setPos(rx, ry, rz))) { + continue; + } + + while (ry > 0 && world.isAirBlock(pos.setPos(rx, ry - 1, rz))) { + ry--; + } + + double yWeight = (ry + 0.5D) - entity.posY * yFactor; + double rPosWeight = xWeight * xWeight + yWeight * yWeight + zWeight * zWeight; + + if (spotWeight < 0.0D || rPosWeight < spotWeight) { + // check from the "in ground" pos + if (predicate.test(pos)) { + spotWeight = rPosWeight; + spot = pos.toImmutable(); + } + } + } + } + } + return spot; } - public boolean isIdealPortal(int rx, int rz, int ry) { - for(int potentialZ = 0; potentialZ < 4; potentialZ++) - { - for(int potentialX = 0; potentialX < 4; potentialX++) - { - for(int potentialY = -1; potentialY < 3; potentialY++) - { - int tx = rx + (potentialX - 1); - int ty = ry + potentialY; - int tz = rz + (potentialZ - 1); - if (potentialY == -1 && myWorld.getBlock(tx, ty, tz).getMaterial() != Material.grass || potentialY >= 0 && !myWorld.getBlock(tx, ty, tz).getMaterial().isReplaceable()) - { + private boolean isIdealForPortal(BlockPos pos) { + for (int potentialZ = 0; potentialZ < 4; potentialZ++) { + for (int potentialX = 0; potentialX < 4; potentialX++) { + for (int potentialY = 0; potentialY < 4; potentialY++) { + BlockPos tPos = pos.add(potentialX - 1, potentialY, potentialZ - 1); + Material material = world.getBlockState(tPos).getMaterial(); + if (potentialY == 0 && material != Material.GRASS + || potentialY >= 1 && !material.isReplaceable()) { return false; } } - } - } return true; } - public boolean isOkayPortal(int rx, int rz, int ry) { - for(int potentialZ = 0; potentialZ < 4; potentialZ++) - { - for(int potentialX = 0; potentialX < 4; potentialX++) - { - for(int potentialY = -1; potentialY < 3; potentialY++) - { - int tx = rx + (potentialX - 1); - int ty = ry + potentialY; - int tz = rz + (potentialZ - 1); - if (potentialY == -1 && !myWorld.getBlock(tx, ty, tz).getMaterial().isSolid() || potentialY >= 0 && !myWorld.getBlock(tx, ty, tz).getMaterial().isReplaceable()) - { + private boolean isOkayForPortal(BlockPos pos) { + for (int potentialZ = 0; potentialZ < 4; potentialZ++) { + for (int potentialX = 0; potentialX < 4; potentialX++) { + for (int potentialY = 0; potentialY < 4; potentialY++) { + BlockPos tPos = pos.add(potentialX - 1, potentialY, potentialZ - 1); + Material material = world.getBlockState(tPos).getMaterial(); + if (potentialY == 0 && !material.isSolid() && !material.isLiquid() + || potentialY >= 1 && !material.isReplaceable()) { return false; } } - } - } return true; } - private void makePortalAt(World world, int px, int py, int pz) { + private void cachePortalCoords(Entity entity, BlockPos pos) { + int x = MathHelper.floor(entity.posX), z = MathHelper.floor(entity.posZ); + destinationCoordinateCache.put(ChunkPos.asLong(x, z), new PortalPosition(pos, world.getTotalWorldTime())); + } + + private BlockPos makePortalAt(World world, BlockPos pos) { - if(py < 30) - { - py = 30; - } - world.getClass(); - if(py > 128 - 10) - { - world.getClass(); - py = 128 - 10; + if (pos.getY() < 30) { + pos = new BlockPos(pos.getX(), 30, pos.getZ()); + } else if (pos.getY() > 128 - 10) { + pos = new BlockPos(pos.getX(), 128 - 10, pos.getZ()); } - - // sink the portal 1 into the ground - py--; - // grass all around it - world.setBlock(px - 1, py + 0, pz - 1, Blocks.grass); - world.setBlock(px + 0, py + 0, pz - 1, Blocks.grass); - world.setBlock(px + 1, py + 0, pz - 1, Blocks.grass); - world.setBlock(px + 2, py + 0, pz - 1, Blocks.grass); + IBlockState grass = Blocks.GRASS.getDefaultState(); - world.setBlock(px - 1, py + 0, pz + 0, Blocks.grass); - world.setBlock(px + 2, py + 0, pz + 0, Blocks.grass); + world.setBlockState(pos.west().north(), grass); + world.setBlockState(pos.north(), grass); + world.setBlockState(pos.east().north(), grass); + world.setBlockState(pos.east(2).north(), grass); - world.setBlock(px - 1, py + 0, pz + 1, Blocks.grass); - world.setBlock(px + 2, py + 0, pz + 1, Blocks.grass); + world.setBlockState(pos.west(), grass); + world.setBlockState(pos.east(2), grass); - world.setBlock(px - 1, py + 0, pz + 2, Blocks.grass); - world.setBlock(px + 0, py + 0, pz + 2, Blocks.grass); - world.setBlock(px + 1, py + 0, pz + 2, Blocks.grass); - world.setBlock(px + 2, py + 0, pz + 2, Blocks.grass); + world.setBlockState(pos.west().south(), grass); + world.setBlockState(pos.east(2).south(), grass); + + world.setBlockState(pos.west().south(2), grass); + world.setBlockState(pos.south(2), grass); + world.setBlockState(pos.east().south(2), grass); + world.setBlockState(pos.east(2).south(2), grass); // dirt under it - world.setBlock(px + 0, py - 1, pz + 0, Blocks.dirt); - world.setBlock(px + 1, py - 1, pz + 0, Blocks.dirt); - world.setBlock(px + 0, py - 1, pz + 1, Blocks.dirt); - world.setBlock(px + 1, py - 1, pz + 1, Blocks.dirt); - + IBlockState dirt = Blocks.DIRT.getDefaultState(); + + world.setBlockState(pos.down(), dirt); + world.setBlockState(pos.east().down(), dirt); + world.setBlockState(pos.south().down(), dirt); + world.setBlockState(pos.east().south().down(), dirt); + // portal in it - world.setBlock(px + 0, py + 0, pz + 0, TFBlocks.portal, 0, 2); - world.setBlock(px + 1, py + 0, pz + 0, TFBlocks.portal, 0, 2); - world.setBlock(px + 0, py + 0, pz + 1, TFBlocks.portal, 0, 2); - world.setBlock(px + 1, py + 0, pz + 1, TFBlocks.portal, 0, 2); - + IBlockState portal = TFBlocks.twilight_portal.getDefaultState().withProperty(BlockTFPortal.DISALLOW_RETURN, !TFConfig.shouldReturnPortalBeUsable); + + world.setBlockState(pos, portal, 2); + world.setBlockState(pos.east(), portal, 2); + world.setBlockState(pos.south(), portal, 2); + world.setBlockState(pos.east().south(), portal, 2); + // meh, let's just make a bunch of air over it for 4 squares for (int dx = -1; dx <= 2; dx++) { for (int dz = -1; dz <= 2; dz++) { - for (int dy = 1; dy <=5; dy++) { - world.setBlock(px + dx, py + dy, pz + dz, Blocks.air); + for (int dy = 1; dy <= 5; dy++) { + world.setBlockToAir(pos.add(dx, dy, dz)); } } } // finally, "nature decorations"! - world.setBlock(px - 1, py + 1, pz - 1, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 0, py + 1, pz - 1, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 1, py + 1, pz - 1, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 2, py + 1, pz - 1, randNatureBlock(world.rand), 0, 2); + world.setBlockState(pos.west().north().up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.north().up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.east().north().up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.east(2).north().up(), randNatureBlock(world.rand), 2); - world.setBlock(px - 1, py + 1, pz + 0, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 2, py + 1, pz + 0, randNatureBlock(world.rand), 0, 2); + world.setBlockState(pos.west().up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.east(2).up(), randNatureBlock(world.rand), 2); - world.setBlock(px - 1, py + 1, pz + 1, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 2, py + 1, pz + 1, randNatureBlock(world.rand), 0, 2); + world.setBlockState(pos.west().south().up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.east(2).south().up(), randNatureBlock(world.rand), 2); - world.setBlock(px - 1, py + 1, pz + 2, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 0, py + 1, pz + 2, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 1, py + 1, pz + 2, randNatureBlock(world.rand), 0, 2); - world.setBlock(px + 2, py + 1, pz + 2, randNatureBlock(world.rand), 0, 2); - } - - public Block randNatureBlock(Random random) { - Block[] block = {Blocks.brown_mushroom, Blocks.red_mushroom, Blocks.tallgrass, Blocks.red_flower, Blocks.yellow_flower}; - - return block[random.nextInt(block.length)]; + world.setBlockState(pos.west().south(2).up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.south(2).up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.east().south(2).up(), randNatureBlock(world.rand), 2); + world.setBlockState(pos.east(2).south(2).up(), randNatureBlock(world.rand), 2); + + return pos; } + private IBlockState randNatureBlock(Random random) { + Block[] blocks = {Blocks.BROWN_MUSHROOM, Blocks.RED_MUSHROOM, Blocks.TALLGRASS, Blocks.RED_FLOWER, Blocks.YELLOW_FLOWER}; + return blocks[random.nextInt(blocks.length)].getDefaultState(); + } } diff --git a/src/main/java/twilightforest/TFTickHandler.java b/src/main/java/twilightforest/TFTickHandler.java index ec985f5091..1c445cf98e 100644 --- a/src/main/java/twilightforest/TFTickHandler.java +++ b/src/main/java/twilightforest/TFTickHandler.java @@ -1,192 +1,142 @@ package twilightforest; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3i; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraftforge.event.entity.item.ItemTossEvent; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent; +import twilightforest.advancements.TFAdvancements; import twilightforest.biomes.TFBiomeBase; -import twilightforest.block.BlockTFPortal; import twilightforest.block.TFBlocks; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.WorldProviderTwilightForest; -import cpw.mods.fml.common.FMLLog; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent; -import cpw.mods.fml.common.gameevent.TickEvent.PlayerTickEvent; -import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; - -/** - * This class listens for ticks in the world. If the player is near a diamond in the water, this class attempts to open a portal. - * - * @author Ben - * - */ -public class TFTickHandler -{ - - public Item portalItem = null; - - - /** - * On the tick, we check for eligible portals - */ - @SubscribeEvent - public void playerTick(PlayerTickEvent event) { +import twilightforest.network.PacketStructureProtection; +import twilightforest.network.PacketStructureProtectionClear; +import twilightforest.network.TFPacketHandler; +import twilightforest.util.StructureBoundingBoxUtils; +import twilightforest.world.ChunkGeneratorTFBase; +import twilightforest.world.TFWorld; +import java.util.List; +import java.util.Random; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class TFTickHandler { + + @SubscribeEvent + public static void playerTick(PlayerTickEvent event) { EntityPlayer player = event.player; - World world = player.worldObj; + World world = player.world; // check for portal creation, at least if it's not disabled - if (!TwilightForestMod.disablePortalCreation && event.phase == TickEvent.Phase.END && !world.isRemote && world.getWorldTime() % 20 == 0) { + if (!world.isRemote && !TFConfig.disablePortalCreation && event.phase == TickEvent.Phase.END && player.ticksExisted % (TFConfig.checkPortalDestination ? 100 : 20) == 0) { // skip non admin players when the option is on - if (TwilightForestMod.adminOnlyPortals) { - try { - //if (MinecraftServer.getServer().getConfigurationManager().isPlayerOpped(player.getCommandSenderName().toString())) { - if (MinecraftServer.getServer().getConfigurationManager().func_152596_g(player.getGameProfile())) { - // reduce range to 4.0 when the option is on - checkForPortalCreation(player, world, 4.0F); - - } - } catch (NoSuchMethodError ex) { - // stop checking admin - FMLLog.warning("[TwilightForest] Could not determine op status for adminOnlyPortals option, ignoring option."); - TwilightForestMod.adminOnlyPortals = false; + if (TFConfig.adminOnlyPortals) { + if (FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getOppedPlayers().getPermissionLevel(player.getGameProfile()) != 0) { + // reduce range to 4.0 when the option is on + checkForPortalCreation(player, world, 4.0F); } } else { // normal check, no special options checkForPortalCreation(player, world, 32.0F); - } } // check the player for being in a forbidden progression area, only every 20 ticks - if (!world.isRemote && event.phase == TickEvent.Phase.END && world.getWorldTime() % 20 == 0 && world.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { - if (world.provider instanceof WorldProviderTwilightForest && !player.capabilities.isCreativeMode) { - checkBiomeForProgression(player, world); - } + if (!world.isRemote && event.phase == TickEvent.Phase.END && player.ticksExisted % 20 == 0 + && TFWorld.isProgressionEnforced(world) + && TFWorld.isTwilightForest(world) + && !player.isCreative() && !player.isSpectator()) { + + checkBiomeForProgression(player, world); } - + // check and send nearby forbidden structures, every 100 ticks or so - if (!world.isRemote && event.phase == TickEvent.Phase.END && world.getWorldTime() % 100 == 0 && world.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { - if (world.provider instanceof WorldProviderTwilightForest) { - if (!player.capabilities.isCreativeMode) { - checkForLockedStructuresSendPacket(player, world); - } else { + if (!world.isRemote && event.phase == TickEvent.Phase.END && player.ticksExisted % 100 == 0 && TFWorld.isProgressionEnforced(world)) { + if (TFWorld.isTwilightForest(world)) { + if (player.isCreative() || player.isSpectator()) { sendAllClearPacket(world, player); + } else { + checkForLockedStructuresSendPacket(player, world); } } } } - - private void sendStructureProtectionPacket(World world, EntityPlayer player, StructureBoundingBox sbb) { - // send packet - FMLProxyPacket message = TFGenericPacketHandler.makeStructureProtectionPacket(sbb); + + private static void sendStructureProtectionPacket(World world, EntityPlayer player, StructureBoundingBox sbb) { if (player instanceof EntityPlayerMP) { - TwilightForestMod.genericChannel.sendTo(message, (EntityPlayerMP) player); - //System.out.println("Sent structure protection"); - } else { - //System.err.println("Can't sent packet to player, not an EntityPlayerMP"); + TFPacketHandler.CHANNEL.sendTo(new PacketStructureProtection(sbb), (EntityPlayerMP) player); } } - - private void sendAllClearPacket(World world, EntityPlayer player) { - FMLProxyPacket message = TFGenericPacketHandler.makeStructureProtectionClearPacket(); + + private static void sendAllClearPacket(World world, EntityPlayer player) { if (player instanceof EntityPlayerMP) { - TwilightForestMod.genericChannel.sendTo(message, (EntityPlayerMP) player); - //System.out.println("Sent structure all clear"); - } else { - //System.err.println("Can't sent packet to player, not an EntityPlayerMP"); + TFPacketHandler.CHANNEL.sendTo(new PacketStructureProtectionClear(), (EntityPlayerMP) player); } } - private boolean checkForLockedStructuresSendPacket(EntityPlayer player, World world) { - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)world.provider).getChunkProvider(); - - int px = MathHelper.floor_double(player.posX); - int py = MathHelper.floor_double(player.posY); - int pz = MathHelper.floor_double(player.posZ); - - if (chunkProvider != null && chunkProvider.isBlockNearFullStructure(px, pz, 100)) { - - StructureBoundingBox fullSBB = chunkProvider.getFullSBBNear(px, pz, 100); - - TFFeature nearFeature = TFFeature.getFeatureForRegion(fullSBB.getCenterX() >> 4, fullSBB.getCenterZ() >> 4, world); - - if (!nearFeature.hasProtectionAura || nearFeature.doesPlayerHaveRequiredAchievement(player)) { + @SuppressWarnings("UnusedReturnValue") + private static boolean checkForLockedStructuresSendPacket(EntityPlayer player, World world) { + + ChunkGeneratorTFBase chunkGenerator = TFWorld.getChunkGenerator(world); + if (chunkGenerator == null) return false; + + int px = MathHelper.floor(player.posX); + int pz = MathHelper.floor(player.posZ); + + StructureBoundingBox fullSBB = chunkGenerator.getFullSBBNear(px, pz, 100); + if (fullSBB != null) { + + Vec3i center = StructureBoundingBoxUtils.getCenter(fullSBB); + + TFFeature nearFeature = TFFeature.getFeatureForRegionPos(center.getX(), center.getZ(), world); + + if (!nearFeature.hasProtectionAura || nearFeature.doesPlayerHaveRequiredAdvancements(player)) { sendAllClearPacket(world, player); return false; } else { sendStructureProtectionPacket(world, player, fullSBB); return true; } - - - } else { - return false; } + return false; } - @SubscribeEvent - public void tickStart(ItemTossEvent event) { - System.out.println("ItemTossEvent Tick"); - } - - - - private void checkForPortalCreation(EntityPlayer player, World world, float rangeToCheck) { - // make sure we are allowed to make a portal in this dimension - if (world != null && player != null - && (world.provider.dimensionId == 0 || world.provider.dimensionId == TwilightForestMod.dimensionID - || TwilightForestMod.allowPortalsInOtherDimensions)) - { - @SuppressWarnings("unchecked") - List itemList = world.getEntitiesWithinAABB(EntityItem.class, player.boundingBox.expand(rangeToCheck, rangeToCheck, rangeToCheck)); - - // do we have the item set? if not, can we set it? - if (this.portalItem == null) { - - - - } - - // check to see if someone's thrown the portal item into the water - for (EntityItem entityItem : itemList) - { - if (entityItem.getEntityItem().getItem() == portalItem && world.isMaterialInBB(entityItem.boundingBox, Material.water)) - { - //System.out.println("There is a diamond in the water"); - - // make sparkles in the area - Random rand = new Random(); - for (int k = 0; k < 2; k++) - { - double d = rand.nextGaussian() * 0.02D; - double d1 = rand.nextGaussian() * 0.02D; - double d2 = rand.nextGaussian() * 0.02D; - - world.spawnParticle("spell", entityItem.posX, entityItem.posY + 0.2, entityItem.posZ, d, d1, d2); - } - - // try to make a portal - int dx = MathHelper.floor_double(entityItem.posX); - int dy = MathHelper.floor_double(entityItem.posY); - int dz = MathHelper.floor_double(entityItem.posZ); - - if (((BlockTFPortal)TFBlocks.portal).tryToCreatePortal(world, dx, dy, dz)) { - player.triggerAchievement(TFAchievementPage.twilightPortal); + private static void checkForPortalCreation(EntityPlayer player, World world, float rangeToCheck) { + if (world.provider.getDimension() == TFConfig.originDimension + || world.provider.getDimension() == TFConfig.dimension.dimensionID + || TFConfig.allowPortalsInOtherDimensions) { + + List itemList = world.getEntitiesWithinAABB(EntityItem.class, player.getEntityBoundingBox().grow(rangeToCheck)); + + for (EntityItem entityItem : itemList) { + if (TFConfig.portalIngredient.apply(entityItem.getItem())) { + BlockPos pos = entityItem.getPosition(); + IBlockState state = world.getBlockState(pos); + if (TFBlocks.twilight_portal.canFormPortal(state)) { + Random rand = new Random(); + for (int i = 0; i < 2; i++) { + double vx = rand.nextGaussian() * 0.02D; + double vy = rand.nextGaussian() * 0.02D; + double vz = rand.nextGaussian() * 0.02D; + + world.spawnParticle(EnumParticleTypes.SPELL, entityItem.posX, entityItem.posY + 0.2, entityItem.posZ, vx, vy, vz); + } + + if (TFBlocks.twilight_portal.tryToCreatePortal(world, pos, entityItem, player)) { + TFAdvancements.MADE_TF_PORTAL.trigger((EntityPlayerMP) player); + return; + } } } } @@ -196,18 +146,13 @@ private void checkForPortalCreation(EntityPlayer player, World world, float rang /** * Check what biome the player is in, and see if current progression allows that biome. If not, take appropriate action */ - private void checkBiomeForProgression(EntityPlayer player, World world) { - BiomeGenBase currentBiome = world.getBiomeGenForCoords(MathHelper.floor_double(player.posX), MathHelper.floor_double(player.posZ)); - + private static void checkBiomeForProgression(EntityPlayer player, World world) { + Biome currentBiome = world.getBiome(new BlockPos(player)); if (currentBiome instanceof TFBiomeBase) { - TFBiomeBase tfBiome = (TFBiomeBase)currentBiome; - - boolean dangerousBiome = !tfBiome.doesPlayerHaveRequiredAchievement(player); - if (dangerousBiome) { - tfBiome.enforceProgession(player, world); + TFBiomeBase tfBiome = (TFBiomeBase) currentBiome; + if (!tfBiome.doesPlayerHaveRequiredAdvancements(player)) { + tfBiome.enforceProgression(player, world); } } } - - } diff --git a/src/main/java/twilightforest/TFTreasure.java b/src/main/java/twilightforest/TFTreasure.java deleted file mode 100644 index 781a6c3322..0000000000 --- a/src/main/java/twilightforest/TFTreasure.java +++ /dev/null @@ -1,742 +0,0 @@ -package twilightforest; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntityChest; -import net.minecraft.world.World; -import twilightforest.block.TFBlocks; -import twilightforest.item.TFItems; - - -public class TFTreasure { - - int type; - - Random treasureRNG; - - protected TFTreasureTable useless; // one quarter of common treasures are - // one of these useless items - protected TFTreasureTable common; - protected TFTreasureTable uncommon; - protected TFTreasureTable rare; - protected TFTreasureTable ultrarare; // one quarter of rare treasures are - // one of these ultrarare items. The - // list must be at least as large as - // the large list for this to make - // sense. - - public static TFTreasure hill1 = new TFTreasure(1); - public static TFTreasure hill2 = new TFTreasure(2); - public static TFTreasure hill3 = new TFTreasure(3); - public static TFTreasure hedgemaze = new TFTreasure(4); - public static TFTreasure labyrinth_room = new TFTreasure(5); - public static TFTreasure labyrinth_deadend = new TFTreasure(6); - public static TFTreasure tower_room = new TFTreasure(7); - public static TFTreasure tower_library = new TFTreasure(8); - public static TFTreasure basement = new TFTreasure(9); - public static TFTreasure labyrinth_vault = new TFTreasure(10); - public static TFTreasure darktower_cache = new TFTreasure(11); - public static TFTreasure darktower_key = new TFTreasure(12); - public static TFTreasure darktower_boss = new TFTreasure(13); - public static TFTreasure tree_cache = new TFTreasure(14); - public static TFTreasure stronghold_cache = new TFTreasure(15); - public static TFTreasure stronghold_room = new TFTreasure(16); - public static TFTreasure stronghold_boss = new TFTreasure(17); - public static TFTreasure aurora_cache = new TFTreasure(18); - public static TFTreasure aurora_room = new TFTreasure(19); - public static TFTreasure aurora_boss = new TFTreasure(20); - public static TFTreasure troll_garden = new TFTreasure(21); - public static TFTreasure troll_vault = new TFTreasure(22); - - - /** - * Construct a new treasure of type i - * - * @param i - */ - public TFTreasure(int i) { - this.type = i; - - useless = new TFTreasureTable(); - common = new TFTreasureTable(); - uncommon = new TFTreasureTable(); - rare = new TFTreasureTable(); - ultrarare = new TFTreasureTable(); - - treasureRNG = new Random(); - - // TODO: separate these into plain ol' different classes - fill(i); - } - - /** - * Generates a treasure chest in the world at the specified coordinates. - */ - public boolean generate(World world, Random rand, int cx, int cy, int cz) { - - return this.generate(world, rand, cx, cy, cz, Blocks.chest); - } - - /** - * Generates a treasure chest in the world at the specified coordinates. - */ - public boolean generate(World world, Random rand, int cx, int cy, int cz, Block chestBlock) { - boolean flag = true; - - treasureRNG.setSeed(world.getSeed() * cx + cy ^ cz); - - // make a chest - world.setBlock(cx, cy, cz, chestBlock, 0, 2); - - // add 4 common items - for (int i = 0; i < 4; i++) { - flag &= addItemToChest(world, treasureRNG, cx, cy, cz, getCommonItem(treasureRNG)); - } - - // add 2 uncommon items - for (int i = 0; i < 2; i++) { - flag &= addItemToChest(world, treasureRNG, cx, cy, cz, - getUncommonItem(treasureRNG)); - } - - // add 1 rare item - for (int i = 0; i < 1; i++) { - flag &= addItemToChest(world, treasureRNG, cx, cy, cz, getRareItem(treasureRNG)); - } - - return flag; - } - - /** - * Gets a common item. If the useless list is not empty, - * there is a 1/4 chance we get a useless item instead. - */ - public ItemStack getCommonItem(Random rand) { - if (!useless.isEmpty() && rand.nextInt(4) == 0) { - return useless.getRandomItem(rand); - } else { - return common.getRandomItem(rand); - } - } - - /** - * Gets an uncommon item. - */ - public ItemStack getUncommonItem(Random rand) { - return uncommon.getRandomItem(rand); - } - - /** - * Gets a rare item. If there are items on the ultrarare list, - * there is a 1/4 chance we get a ultrarare item instead. - */ - public ItemStack getRareItem(Random rand) - { - if (!ultrarare.isEmpty() && rand.nextInt(4) == 0) - { - return ultrarare.getRandomItem(rand); - } - else - { - return rare.getRandomItem(rand); - } - } - - /** - * Used internally to add items into chests - */ - protected boolean addItemToChest(World world, Random rand, int cx, int cy, - int cz, ItemStack itemStack) { - - TileEntityChest chest = (TileEntityChest) world.getTileEntity(cx, cy, cz); - - // make sure the chest is not full - if (chest != null) { - int slot = findRandomInventorySlot(chest, rand); - - if (slot != -1) { - chest.setInventorySlotContents(slot, itemStack); - return true; - } - - } - return false; - } - - /** - * Finds an open slot in the chest, or returns -1 if the chest is full. - */ - protected int findRandomInventorySlot(TileEntityChest chest, Random rand) { - // TODO: this is lazy - - // try 100 times to find an empty slot - for (int i = 0; i < 100; i++) { - int slot = rand.nextInt(chest.getSizeInventory()); - if (chest.getStackInSlot(slot) == null) { - return slot; - } - } - - // didn't find one - return -1; - } - - /** - * Fills the table with items for the specified type. This should be - * refactored into seperate functions someday. - */ - protected void fill(int i) { - useless.add(Blocks.red_flower, 4); - useless.add(Blocks.yellow_flower, 4); - useless.add(Items.feather, 3); - useless.add(Items.wheat_seeds, 2); - useless.add(Items.flint, 2); - useless.add(Blocks.cactus, 2); - useless.add(Items.reeds, 4); - useless.add(Blocks.sand, 4); - useless.add(Items.flower_pot, 1); - useless.add(new ItemStack(Items.dye, 1, 0)); - - if (i == 1) { - // hill type 1 chest - common.add(Items.iron_ingot, 4); - common.add(Items.wheat, 4); - common.add(Items.string, 4); - common.add(Items.bucket, 1); - - uncommon.add(Items.bread, 1); - uncommon.add(TFItems.oreMagnet, 1); - uncommon.add(Items.gunpowder, 4); - uncommon.add(Items.arrow, 12); - uncommon.add(Blocks.torch, 12); - - rare.add(Items.gold_ingot, 3); - rare.add(Items.iron_pickaxe, 1); - rare.add(TFItems.liveRoot, 3); - - ultrarare.add(TFItems.transformPowder, 12); - ultrarare.add(Items.diamond, 1); - ultrarare.add(TFItems.steeleafIngot, 3); - } - - if (i == 2) { - // hill type 2 chest - common.add(Items.iron_ingot, 4); - common.add(Items.carrot, 4); - common.add(Blocks.ladder, 6); - common.add(Items.bucket, 1); - - uncommon.add(Items.baked_potato, 2); - uncommon.add(TFItems.oreMagnet, 1); - uncommon.add(TFItems.ironwoodIngot, 4); - uncommon.add(Items.arrow, 12); - uncommon.add(Blocks.torch, 12); - - rare.add(TFItems.nagaScale, 1); - rare.add(TFBlocks.uncraftingTable, 1); - rare.add(TFItems.transformPowder, 12); - - ultrarare.add(TFItems.peacockFan, 1); - ultrarare.add(Items.emerald, 6); - ultrarare.add(Items.diamond, 1); - ultrarare.add(TFItems.charmOfLife1, 1); - } - - if (i == 3) { - // hill type 3 chest - common.add(Items.gold_nugget, 9); - common.add(Items.potato, 4); - common.add(Items.fish, 4); - common.add(TFItems.torchberries, 5); - - uncommon.add(Items.pumpkin_pie, 1); - uncommon.add(TFItems.oreMagnet, 1); - uncommon.add(Items.gunpowder, 4); - uncommon.add(Items.arrow, 12); - uncommon.add(Blocks.torch, 12); - uncommon.add(TFItems.steeleafIngot, 4); - - rare.add(TFItems.nagaScale, 1); - rare.addEnchanted(new ItemStack(TFItems.ironwoodPick, 1), Enchantment.efficiency, 1, Enchantment.fortune, 1); - rare.add(TFItems.transformPowder, 12); - - ultrarare.add(TFItems.moonwormQueen, 1); - ultrarare.add(TFBlocks.sapling, 1, 4); - ultrarare.add(Items.diamond, 2); - ultrarare.add(TFItems.charmOfLife1, 1); - ultrarare.add(TFItems.charmOfKeeping1, 1); - } - - if (i == 4) { - // hedge maze chest - common.add(Blocks.planks, 4); - common.add(Blocks.brown_mushroom, 4); - common.add(Blocks.red_mushroom, 4); - common.add(Items.wheat, 4); - common.add(Items.string, 4); - common.add(Items.stick, 6); - - uncommon.add(Items.melon, 4); - uncommon.add(Items.melon_seeds, 4); - uncommon.add(Items.pumpkin_seeds, 4); - uncommon.add(Items.arrow, 12); - uncommon.add(TFBlocks.firefly, 4); - - rare.add(Blocks.web, 3); - rare.add(Items.shears, 1); - rare.add(Items.saddle, 1); - rare.add(Items.bow, 1); - rare.add(Items.apple, 2); - - ultrarare.add(Items.diamond_hoe, 1); - ultrarare.add(Items.diamond, 1); - ultrarare.add(Items.mushroom_stew, 1); - ultrarare.add(Items.golden_apple, 1); - } - - if (i == 5) { - // labyrinth room chest - useless.clear(); - - common.add(Items.iron_ingot, 4); - common.add(TFItems.mazeWafer, 12); - common.add(Items.gunpowder, 4); - common.add(TFItems.ironwoodIngot, 4); - common.add(TFBlocks.firefly, 5); - common.add(Items.milk_bucket, 1); - - uncommon.add(TFItems.steeleafIngot, 6); - uncommon.add(TFItems.steeleafLegs, 1); - uncommon.add(TFItems.steeleafPlate, 1); - uncommon.add(TFItems.steeleafHelm, 1); - uncommon.add(TFItems.steeleafBoots, 1); - uncommon.add(TFItems.steeleafPick, 1); - uncommon.add(TFItems.ironwoodPlate, 1); - uncommon.add(TFItems.ironwoodSword, 1); - uncommon.add(TFItems.charmOfKeeping1, 1); - - rare.add(TFItems.mazeMapFocus, 1); - rare.add(Blocks.tnt, 3); - rare.add(new ItemStack(Items.potionitem, 1, 16373)); // health ii - } - - if (i == 6) { - // labyrinth dead end chest - common.add(Items.stick, 12); - common.add(Items.coal, 12); - common.add(Items.arrow, 12); - common.add(TFItems.mazeWafer, 9); - common.add(Items.paper, 12); - common.add(Items.leather, 4); - common.add(Items.mushroom_stew, 1); - - uncommon.add(Items.milk_bucket, 1); - uncommon.add(Items.paper, 5); - uncommon.add(Items.iron_ingot, 6); - uncommon.add(TFItems.ironwoodIngot, 8); - uncommon.add(TFBlocks.firefly, 5); - uncommon.add(TFItems.charmOfKeeping1, 1); - - rare.add(TFItems.steeleafIngot, 8); - rare.add(Items.golden_apple, 1); - rare.add(Items.blaze_rod, 2); - } - - if (i == 10) { - // labyrinth vault chest - useless.clear(); - - common.add(Items.iron_ingot, 9); - common.add(Items.emerald, 5); - common.add(TFItems.mazeWafer, 12); - common.add(TFItems.ironwoodIngot, 9); - common.add(new ItemStack(Items.potionitem, 1, 16369)); // regen ii - common.add(new ItemStack(Items.potionitem, 1, 16373)); // health ii - common.add(new ItemStack(Items.potionitem, 1, 16370)); // extended swiftness ii - - uncommon.addEnchanted(new ItemStack(Items.bow), Enchantment.infinity, 1, Enchantment.punch, 2); - uncommon.addEnchanted(new ItemStack(Items.bow), Enchantment.power, 3, Enchantment.flame, 1); - uncommon.addEnchanted(new ItemStack(TFItems.steeleafShovel), Enchantment.efficiency, 4, Enchantment.unbreaking, 2); - uncommon.addEnchanted(new ItemStack(TFItems.steeleafAxe), Enchantment.efficiency, 5); - uncommon.add(TFItems.steeleafIngot, 12); - uncommon.addEnchanted(new ItemStack(TFItems.steeleafPlate), Enchantment.protection, 3); - uncommon.addEnchanted(new ItemStack(TFItems.steeleafLegs), Enchantment.fireProtection, 4); - uncommon.addEnchanted(new ItemStack(TFItems.steeleafBoots), Enchantment.protection, 2); - uncommon.addEnchanted(new ItemStack(TFItems.steeleafHelm), Enchantment.respiration, 3); - - rare.add(Blocks.emerald_block, 1); - rare.add(Blocks.ender_chest, 1); - rare.addEnchanted(new ItemStack(TFItems.steeleafPick), Enchantment.efficiency, 4, Enchantment.silkTouch, 1); - rare.addEnchanted(new ItemStack(TFItems.steeleafSword), Enchantment.sharpness, 4, Enchantment.knockback, 2); - rare.addEnchanted(new ItemStack(TFItems.steeleafSword), Enchantment.baneOfArthropods, 5, Enchantment.fireAspect, 2); - rare.addEnchanted(new ItemStack(TFItems.mazebreakerPick), Enchantment.efficiency, 4, Enchantment.unbreaking, 3, Enchantment.fortune, 2); - } - - if (i == 7) { - // wizards tower treasure room chest - common.add(Items.glass_bottle, 6); - common.add(new ItemStack(Items.potionitem, 1, 0)); - common.add(Items.sugar, 5); - common.add(Items.spider_eye, 3); - common.add(Items.ghast_tear, 1); - common.add(Items.magma_cream, 2); - common.add(Items.fermented_spider_eye, 1); - common.add(Items.speckled_melon, 2); - common.add(Items.blaze_powder, 3); - common.add(Items.paper, 6); - - uncommon.addRandomEnchanted(Items.golden_sword, 10); - uncommon.addRandomEnchanted(Items.golden_boots, 7); - uncommon.add(new ItemStack(Items.potionitem, 1, 16274)); // swiftness - uncommon.add(new ItemStack(Items.potionitem, 1, 16341)); // healing - uncommon.add(new ItemStack(Items.potionitem, 1, 16307)); // fire resist - uncommon.add(new ItemStack(Items.potionitem, 1, 16348)); // harm - - rare.addRandomEnchanted(Items.golden_helmet, 18); - rare.add(new ItemStack(Items.potionitem, 1, 16306)); // swiftness ii - rare.add(new ItemStack(Items.potionitem, 1, 16305)); // regen ii - rare.add(new ItemStack(Items.potionitem, 1, 32725)); // splash health - rare.add(new ItemStack(Items.potionitem, 1, 32764)); // harming ii splash - rare.add(TFItems.transformPowder, 12); - rare.add(TFItems.charmOfLife1, 1); - rare.add(TFItems.charmOfKeeping1, 1); - - ultrarare.addRandomEnchanted(Items.golden_axe, 20); - ultrarare.add(Items.ender_pearl, 1); - ultrarare.add(Blocks.obsidian, 4); - ultrarare.add(Items.diamond, 1); - ultrarare.add(TFItems.moonwormQueen, 1); - ultrarare.add(TFItems.peacockFan, 1); - } - - if (i == 8) { - // wizards tower library chest - common.add(Items.glass_bottle, 6); - common.add(new ItemStack(Items.potionitem, 1, 0)); - common.add(Blocks.ladder, 6); - common.add(Items.paper, 6); - common.add(Items.bone, 6); - common.add(Items.gold_nugget, 6); - common.add(Items.clay_ball, 12); - - uncommon.addRandomEnchanted(Items.iron_leggings, 5); - uncommon.add(Items.fire_charge, 3); - uncommon.add(Items.book, 5); - uncommon.add(Items.map, 1); - uncommon.add(new ItemStack(Items.potionitem, 1, 16)); - uncommon.add(new ItemStack(Items.potionitem, 1, 16276)); // poison - uncommon.add(new ItemStack(Items.potionitem, 1, 16312)); // weakness - - rare.addRandomEnchanted(Items.bow, 5); - rare.addRandomEnchanted(Items.stone_sword, 10); - rare.addRandomEnchanted(Items.wooden_sword, 15); - rare.add(new ItemStack(Items.potionitem, 1, 32696)); // splash weakness - rare.add(new ItemStack(Items.potionitem, 1, 16369)); // regen ii - rare.add(new ItemStack(Items.potionitem, 1, 16373)); // health ii - rare.add(new ItemStack(Items.potionitem, 1, 16370)); // extended swiftness ii - rare.add(TFItems.transformPowder, 12); - rare.add(TFItems.charmOfKeeping1, 1); - - ultrarare.addRandomEnchanted(Items.golden_pickaxe, 10); - ultrarare.addRandomEnchanted(Items.iron_sword, 20); - ultrarare.addRandomEnchanted(Items.bow, 30); - ultrarare.add(Blocks.bookshelf, 5); - ultrarare.add(Items.ender_pearl, 2); - ultrarare.add(Items.experience_bottle, 6); - } - - if (i == 9) { - // basement treasure cache, mostly full of food! - common.add(new ItemStack(Items.potionitem, 1, 0)); - common.add(Items.rotten_flesh, 6); - common.add(Items.poisonous_potato, 2); - common.add(Items.wheat, 6); - common.add(Items.potato, 6); - common.add(Items.carrot, 6); - common.add(Items.melon, 6); - common.add(Items.water_bucket, 1); - common.add(Blocks.torch, 12); - common.add(Items.mushroom_stew, 1); - common.add(Items.milk_bucket, 1); - common.add(Items.melon_seeds, 5); - - uncommon.add(Items.bread, 8); - uncommon.add(Items.cooked_beef, 6); - uncommon.add(Items.cooked_porkchop, 8); - uncommon.add(Items.baked_potato, 8); - uncommon.add(Items.cooked_chicken, 10); - uncommon.add(Items.cooked_fished, 8); - - rare.add(Items.speckled_melon, 12); - rare.add(Items.apple, 12); - rare.add(Items.map, 1); - rare.add(TFItems.charmOfKeeping1, 1); - - ultrarare.add(Items.golden_apple, 2); - ultrarare.add(Items.golden_carrot, 2); - ultrarare.add(Items.cake, 1); - ultrarare.add(Items.boat, 1); - ultrarare.add(new ItemStack(TFBlocks.sapling, 1, 4)); - } - - if (i == 11) { - // dark tower regular treasure cache, contains supplies - common.add(Items.stick, 12); - common.add(new ItemStack(Items.coal, 12, 1)); - common.add(Items.arrow, 12); - common.add(TFItems.experiment115, 9); - common.add(new ItemStack(Blocks.wool, 1, 14)); - common.add(Items.redstone, 6); - - uncommon.add(Blocks.redstone_lamp, 3); - uncommon.add(Items.iron_ingot, 6); - uncommon.add(TFItems.ironwoodIngot, 8); - uncommon.add(TFBlocks.firefly, 5); - uncommon.add(TFItems.charmOfKeeping1, 1); - - rare.add(TFItems.steeleafIngot, 8); - rare.add(Items.diamond, 2); - - } - - if (i == 12) { - // dark tower key treasure chest, contains higher quality treasure - // key will be added seperately - useless.clear(); - - common.add(Items.iron_ingot, 4); - common.add(TFItems.experiment115, 12); - common.add(Items.gunpowder, 4); - common.add(TFItems.ironwoodIngot, 4); - common.add(TFBlocks.firefly, 5); - common.add(Items.redstone, 12); - common.add(Items.glowstone_dust, 12); - - uncommon.add(TFItems.steeleafIngot, 6); - uncommon.add(TFItems.steeleafLegs, 1); - uncommon.add(TFItems.steeleafPlate, 1); - uncommon.add(TFItems.steeleafHelm, 1); - uncommon.add(TFItems.steeleafBoots, 1); - uncommon.add(TFItems.steeleafPick, 1); - uncommon.add(TFItems.ironwoodPlate, 1); - uncommon.add(TFItems.ironwoodSword, 1); - uncommon.add(TFItems.charmOfKeeping1, 1); - - rare.add(TFItems.charmOfLife1, 1); - rare.addEnchantedBook(Enchantment.featherFalling, 3); - rare.addEnchantedBook(Enchantment.knockback, 2); - rare.addEnchantedBook(Enchantment.efficiency, 3); - } - - if (i == 13) { - // dark tower boss treasure - useless.clear(); - - common.add(TFItems.carminite, 3); - uncommon.add(TFItems.fieryTears, 5); - rare.add(new ItemStack(TFItems.trophy, 1, 3)); - } - - if (i == 14) { - // tree branch treasure cache, food and saplings - common.add(Items.poisonous_potato, 2); - common.add(Items.wheat, 6); - common.add(Items.potato, 6); - common.add(Items.carrot, 6); - common.add(Items.melon, 6); - common.add(Items.water_bucket, 1); - common.add(Items.milk_bucket, 1); - common.add(Items.melon_seeds, 5); - - uncommon.add(new ItemStack(TFBlocks.firefly, 12)); - uncommon.add(new ItemStack(TFBlocks.sapling, 4, 0)); - uncommon.add(new ItemStack(TFBlocks.sapling, 4, 1)); - uncommon.add(new ItemStack(TFBlocks.sapling, 4, 2)); - uncommon.add(new ItemStack(TFBlocks.sapling, 4, 3)); - - rare.add(Items.pumpkin_pie, 12); - rare.add(Items.apple, 12); - rare.add(TFItems.charmOfLife1, 1); - rare.add(TFItems.charmOfKeeping1, 1); - - ultrarare.add(new ItemStack(TFBlocks.sapling, 1, 4)); - ultrarare.add(new ItemStack(TFBlocks.sapling, 1, 5)); - ultrarare.add(new ItemStack(TFBlocks.sapling, 1, 6)); - ultrarare.add(new ItemStack(TFBlocks.sapling, 1, 7)); - ultrarare.add(new ItemStack(TFBlocks.sapling, 1, 8)); - } - - if (i == 15) { - // stronghold regular treasure cache, contains supplies - common.add(Items.stick, 12); - common.add(new ItemStack(Items.coal, 12)); - common.add(Items.arrow, 12); - common.add(TFItems.mazeWafer, 9); - common.add(new ItemStack(Blocks.wool, 1, 11)); - common.add(Items.iron_ingot, 2); - - uncommon.add(Items.bucket, 1); - uncommon.add(Items.iron_ingot, 6); - uncommon.add(TFItems.ironwoodIngot, 6); - uncommon.add(TFBlocks.firefly, 5); - uncommon.add(TFItems.charmOfKeeping1, 1); - uncommon.add(TFItems.armorShard, 3); - - rare.add(TFItems.knightMetal, 8); - rare.addRandomEnchanted(Items.bow, 20); - rare.addRandomEnchanted(Items.iron_sword, 20); - rare.addRandomEnchanted(TFItems.ironwoodSword, 15); - rare.addRandomEnchanted(TFItems.steeleafSword, 10); - - ultrarare.addEnchantedBook(Enchantment.baneOfArthropods, 4); - ultrarare.addEnchantedBook(Enchantment.sharpness, 4); - ultrarare.addEnchantedBook(Enchantment.smite, 4); - ultrarare.addEnchantedBook(Enchantment.unbreaking, 2); - ultrarare.addEnchantedBook(Enchantment.unbreaking, 2); - ultrarare.addEnchantedBook(Enchantment.protection, 3); - ultrarare.addEnchantedBook(Enchantment.projectileProtection, 3); - ultrarare.addEnchantedBook(Enchantment.featherFalling, 3); - - } - - if (i == 16) { - // stronghold treasure room chest - kinda rare - useless.clear(); - - common.add(Items.iron_ingot, 4); - common.add(TFItems.mazeWafer, 12); - common.add(Items.gunpowder, 4); - common.add(TFItems.ironwoodIngot, 4); - common.add(TFBlocks.firefly, 5); - common.add(Items.milk_bucket, 1); - - uncommon.add(TFItems.steeleafIngot, 6); - uncommon.add(TFItems.steeleafLegs, 1); - uncommon.add(TFItems.steeleafPlate, 1); - uncommon.add(TFItems.steeleafHelm, 1); - uncommon.add(TFItems.steeleafBoots, 1); - uncommon.add(TFItems.steeleafPick, 1); - uncommon.add(TFItems.ironwoodPlate, 1); - uncommon.add(TFItems.ironwoodSword, 1); - uncommon.add(TFItems.charmOfLife1, 1); - - rare.add(TFItems.mazeMapFocus, 1); - rare.addRandomEnchanted(Items.bow, 30); - rare.addRandomEnchanted(Items.iron_sword, 30); - rare.addRandomEnchanted(TFItems.ironwoodSword, 25); - rare.addRandomEnchanted(TFItems.steeleafSword, 20); - rare.addRandomEnchanted(Items.diamond_sword, 15); - - } - - if (i == 17) { - // stronghold boss treasure - useless.clear(); - - common.addRandomEnchanted(TFItems.knightlySword, 20); - common.addRandomEnchanted(TFItems.knightlyPick, 20); - common.addRandomEnchanted(TFItems.knightlyAxe, 20); - uncommon.addRandomEnchanted(TFItems.phantomHelm, 20); - uncommon.addRandomEnchanted(TFItems.phantomPlate, 20); - rare.addRandomEnchanted(TFItems.phantomHelm, 30); - rare.addRandomEnchanted(TFItems.phantomPlate, 30); - } - - if (i == 18) { - // aurora cache - common.add(Items.stick, 12); - common.add(new ItemStack(Items.coal, 12)); - common.add(Items.arrow, 12); - common.add(TFItems.mazeWafer, 9); - common.add(Blocks.ice, 4); - common.add(Blocks.packed_ice, 4); - common.add(TFItems.ironwoodIngot, 2); - - uncommon.add(TFBlocks.auroraBlock, 12); - uncommon.add(TFItems.ironwoodIngot, 6); - uncommon.add(TFBlocks.firefly, 5); - uncommon.add(TFItems.charmOfKeeping1, 1); - uncommon.add(TFItems.arcticFur, 3); - - rare.add(TFItems.arcticFur, 8); - rare.add(TFItems.iceBow, 1); - rare.add(TFItems.enderBow, 1); - rare.add(TFItems.iceSword, 1); - - ultrarare.addEnchantedBook(Enchantment.sharpness, 4); - ultrarare.addEnchantedBook(Enchantment.power, 4); - ultrarare.addEnchantedBook(Enchantment.punch, 2); - ultrarare.addEnchantedBook(Enchantment.unbreaking, 2); - ultrarare.addEnchantedBook(Enchantment.unbreaking, 2); - ultrarare.addEnchantedBook(Enchantment.infinity, 1); - - } - - if (i == 19) { - // aurora treasure - useless.clear(); - - common.add(Blocks.ice, 4); - common.add(Blocks.packed_ice, 4); - common.add(TFItems.mazeWafer, 12); - common.add(TFItems.iceBomb, 4); - common.add(TFBlocks.firefly, 5); - - uncommon.add(TFItems.arcticFur, 6); - uncommon.add(TFItems.arcticLegs, 1); - uncommon.add(TFItems.arcticPlate, 1); - uncommon.add(TFItems.arcticHelm, 1); - uncommon.add(TFItems.arcticBoots, 1); - uncommon.add(TFItems.knightlyPlate, 1); - uncommon.add(TFItems.knightlySword, 1); - uncommon.add(TFItems.charmOfLife1, 1); - - rare.addRandomEnchanted(TFItems.iceBow, 30); - rare.addRandomEnchanted(TFItems.enderBow, 5); - rare.addRandomEnchanted(TFItems.iceSword, 25); - rare.addRandomEnchanted(TFItems.glassSword, 20); - - } - - if (i == 21) { - // troll garden - useless.clear(); - - common.add(Blocks.red_mushroom, 4); - common.add(Blocks.brown_mushroom, 4); - common.add(Items.wheat_seeds, 6); - common.add(Items.carrot, 6); - common.add(Items.potato, 6); - common.add(Items.melon_seeds, 6); - common.add(new ItemStack(Items.dye, 12, 15)); - - uncommon.add(TFBlocks.uberousSoil, 6); - - rare.add(TFItems.magicBeans, 1); - - } - - if (i == 22) { - // troll vault - useless.clear(); - - useless.clear(); - - common.add(Items.coal, 32); - common.add(TFItems.torchberries, 16); - common.add(Items.emerald, 6); - - uncommon.add(TFBlocks.trollSteinn, 6); - uncommon.add(Blocks.obsidian, 6); - - rare.add(TFItems.lampOfCinders, 1); - - } - - } -} diff --git a/src/main/java/twilightforest/TFTreasureItem.java b/src/main/java/twilightforest/TFTreasureItem.java deleted file mode 100644 index d4b9ba2562..0000000000 --- a/src/main/java/twilightforest/TFTreasureItem.java +++ /dev/null @@ -1,80 +0,0 @@ -package twilightforest; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - - -public class TFTreasureItem { - - ItemStack itemStack; - int rarity; - - int randomEnchantmentLevel = 0; - - public TFTreasureItem(Item item) { - this(item, 1, 10); - } - - public TFTreasureItem(Item item, int quantity) { - this(item, quantity, 10); - } - - public TFTreasureItem(Item item, int quantity, int rarity) { - this.itemStack = new ItemStack(item, quantity); - this.rarity = rarity; - } - - public TFTreasureItem(Block block, int quantity, int rarity) { - this.itemStack = new ItemStack(block, quantity); - this.rarity = rarity; - } - - public TFTreasureItem(ItemStack itemStack, int rarity) { - this.itemStack = itemStack.copy(); - this.rarity = rarity; - } - - - /** - * Get a new ItemStack ready for use! - * - * @param rand - * @return - */ - public ItemStack getItemStack(Random rand) { - ItemStack result = this.itemStack.copy(); - result.stackSize = rand.nextInt(result.stackSize) + 1; - - // randomly enchant this item if needed - if (result.isItemEnchantable() && randomEnchantmentLevel > 0) - { - EnchantmentHelper.addRandomEnchantment(rand, result, randomEnchantmentLevel); - } - - return result; - } - - /** - * Returns this items rarity value - * - * @param total - * @return - */ - public int getRarity() { - return rarity; - } - - public int getRandomEnchantmentLevel() { - return randomEnchantmentLevel; - } - - public void setRandomEnchantmentLevel(int randomEnchantmentLevel) { - this.randomEnchantmentLevel = randomEnchantmentLevel; - } -} - - diff --git a/src/main/java/twilightforest/TFTreasureTable.java b/src/main/java/twilightforest/TFTreasureTable.java deleted file mode 100644 index 7e12954bb9..0000000000 --- a/src/main/java/twilightforest/TFTreasureTable.java +++ /dev/null @@ -1,187 +0,0 @@ -package twilightforest; - -import java.util.ArrayList; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentData; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - - -/** - * This is not much more than a list of TFTreasureEntries. - * - * @author Ben - * - */ -public class TFTreasureTable { - - private static final int DEFAULT_RARITY = 10; - protected ArrayList list; - - public TFTreasureTable() { - this.list = new ArrayList(); - } - - - /** - * Adds the item onto this list to be generated at normal rarity (10), in the specified quantity - * - * @param item - * @param quantity - */ - public void add(Item item, int quantity) { - this.add(item, quantity, DEFAULT_RARITY); - } - - /** - * Adds the item onto the list, with the values specified - * - * @param item - * @param quantity - * @param rarity - */ - public void add(Item item, int quantity, int rarity) { - list.add(new TFTreasureItem(item, quantity, rarity)); - } - - - /** - * Adds the ItemStack onto this list to be generated at normal rarity (10), in the quantity the itemstack contains - * - * @param itemstack - */ - public void add(ItemStack itemstack) { - list.add(new TFTreasureItem(itemstack, DEFAULT_RARITY)); - } - - /** - * Adds the item at the specified enchantment level - */ - public void addEnchanted(ItemStack itemstack, Enchantment ench1, int enchLevel1) { - itemstack.addEnchantment(ench1, enchLevel1); - list.add(new TFTreasureItem(itemstack, DEFAULT_RARITY)); - } - - /** - * Adds an enchanted book at the specified enchantment level - */ - public void addEnchantedBook(Enchantment ench1, int enchLevel1) { - ItemStack itemstack = Items.enchanted_book.getEnchantedItemStack(new EnchantmentData(ench1, enchLevel1)); - list.add(new TFTreasureItem(itemstack, DEFAULT_RARITY)); - } - - /** - * Adds the item at the specified enchantment level, 2 enchantments - */ - public void addEnchanted(ItemStack itemstack, Enchantment ench1, int enchLevel1, Enchantment ench2, int enchLevel2) { - itemstack.addEnchantment(ench1, enchLevel1); - itemstack.addEnchantment(ench2, enchLevel2); - list.add(new TFTreasureItem(itemstack, DEFAULT_RARITY)); - } - - /** - * Adds the item at the specified enchantment level, 3 enchantments - */ - public void addEnchanted(ItemStack itemstack, Enchantment ench1, int enchLevel1, Enchantment ench2, int enchLevel2, Enchantment ench3, int enchLevel3) { - itemstack.addEnchantment(ench1, enchLevel1); - itemstack.addEnchantment(ench2, enchLevel2); - itemstack.addEnchantment(ench3, enchLevel3); - list.add(new TFTreasureItem(itemstack, DEFAULT_RARITY)); - } - - /** - * Adds the item with a random enchantment level - */ - public void addRandomEnchanted(ItemStack itemstack, int randomLevel) - { - TFTreasureItem treasure = new TFTreasureItem(itemstack, DEFAULT_RARITY); - treasure.setRandomEnchantmentLevel(randomLevel); - list.add(treasure); - } - - /** - * Adds the item with a random enchantment level - */ - public void addRandomEnchanted(Item item, int randomLevel) - { - TFTreasureItem treasure = new TFTreasureItem(item, 1, DEFAULT_RARITY); - treasure.setRandomEnchantmentLevel(randomLevel); - list.add(treasure); - } - - /** - * Adds the block onto this list to be generated at normal rarity (10), in the specified quantity - * - * @param block - * @param quantity - */ - public void add(Block block, int quantity) { - this.add(block, quantity, DEFAULT_RARITY); - } - - - /** - * Adds the block onto the list, with the values specified - * - * @param block - * @param quantity - * @param rarity - */ - public void add(Block block, int quantity, int rarity) { - list.add(new TFTreasureItem(block, quantity, rarity)); - } - - - /** - * What is the total of all the rarity entries in our table? - * - * @return - */ - protected int total() { - int value = 0; - - for (TFTreasureItem item : list) { - value += item.getRarity(); - } - - return value; - } - - public ItemStack getRandomItem(Random rand) { - - int value = rand.nextInt(total()); - - for (TFTreasureItem item : list) { - if (item.getRarity() > value) { - return item.getItemStack(rand); - } - else - { - value -= item.getRarity(); - } - } - - // we should not actually get here - return null; - } - - /** - * Is this table empty - */ - public boolean isEmpty() - { - return list.isEmpty(); - } - - /** - * Clear this list - */ - public void clear() - { - list.clear(); - } -} diff --git a/src/main/java/twilightforest/TwilightForestMod.java b/src/main/java/twilightforest/TwilightForestMod.java index dd13d71241..f3c394b49c 100644 --- a/src/main/java/twilightforest/TwilightForestMod.java +++ b/src/main/java/twilightforest/TwilightForestMod.java @@ -1,823 +1,223 @@ package twilightforest; -import com.google.common.base.Function; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockDispenser; -import net.minecraft.block.BlockSlab; -import net.minecraft.entity.Entity; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.server.MinecraftServer; -import net.minecraftforge.common.AchievementPage; +import net.minecraft.item.EnumRarity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.DimensionType; +import net.minecraft.world.gen.structure.MapGenStructureIO; import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.oredict.OreDictionary; -import twilightforest.biomes.TFBiomeBase; -import twilightforest.block.BlockTFAuroraBrick; -import twilightforest.block.BlockTFAuroraPillar; -import twilightforest.block.BlockTFAuroraSlab; -import twilightforest.block.BlockTFBurntThorns; -import twilightforest.block.BlockTFCastleBlock; -import twilightforest.block.BlockTFCastleMagic; -import twilightforest.block.BlockTFDarkLeaves; -import twilightforest.block.BlockTFDeadrock; -import twilightforest.block.BlockTFFluffyCloud; -import twilightforest.block.BlockTFForceField; -import twilightforest.block.BlockTFGiantCobble; -import twilightforest.block.BlockTFGiantLeaves; -import twilightforest.block.BlockTFGiantLog; -import twilightforest.block.BlockTFGiantObsidian; -import twilightforest.block.BlockTFHugeGloomBlock; -import twilightforest.block.BlockTFHugeLilyPad; -import twilightforest.block.BlockTFHugeStalk; -import twilightforest.block.BlockTFHugeWaterLily; -import twilightforest.block.BlockTFKnightmetalBlock; -import twilightforest.block.BlockTFLeaves3; -import twilightforest.block.BlockTFRipeTorchCluster; -import twilightforest.block.BlockTFShield; -import twilightforest.block.BlockTFSlider; -import twilightforest.block.BlockTFThornRose; -import twilightforest.block.BlockTFThorns; -import twilightforest.block.BlockTFTrollRoot; -import twilightforest.block.BlockTFTrollSteinn; -import twilightforest.block.BlockTFTrophy; -import twilightforest.block.BlockTFTrophyPedestal; -import twilightforest.block.BlockTFUberousSoil; -import twilightforest.block.BlockTFUnderBrick; -import twilightforest.block.BlockTFUnripeTorchCluster; -import twilightforest.block.BlockTFWispyCloud; -import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; -import twilightforest.item.BehaviorTFMobEggDispense; -import twilightforest.item.ItemTFMagicMap; -import twilightforest.item.ItemTFMazeMap; +import net.minecraftforge.common.util.EnumHelper; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventHandler; +import net.minecraftforge.fml.common.Mod.Instance; +import net.minecraftforge.fml.common.SidedProxy; +import net.minecraftforge.fml.common.event.*; +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.fml.common.registry.GameRegistry; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import twilightforest.advancements.TFAdvancements; +import twilightforest.capabilities.CapabilityList; +import twilightforest.compat.TFCompat; import twilightforest.item.TFItems; -import twilightforest.item.TFRecipes; -import twilightforest.structures.StructureTFMajorFeatureStart; -import twilightforest.tileentity.TileEntityTFCReactorActive; -import twilightforest.tileentity.TileEntityTFCicada; -import twilightforest.tileentity.TileEntityTFCinderFurnace; -import twilightforest.tileentity.TileEntityTFFirefly; -import twilightforest.tileentity.TileEntityTFFlameJet; -import twilightforest.tileentity.TileEntityTFGhastTrapActive; -import twilightforest.tileentity.TileEntityTFGhastTrapInactive; -import twilightforest.tileentity.TileEntityTFHydraSpawner; -import twilightforest.tileentity.TileEntityTFKnightPhantomsSpawner; -import twilightforest.tileentity.TileEntityTFLichSpawner; -import twilightforest.tileentity.TileEntityTFMoonworm; -import twilightforest.tileentity.TileEntityTFNagaSpawner; -import twilightforest.tileentity.TileEntityTFPoppingJet; -import twilightforest.tileentity.TileEntityTFReverter; -import twilightforest.tileentity.TileEntityTFSmoker; -import twilightforest.tileentity.TileEntityTFSnowQueenSpawner; -import twilightforest.tileentity.TileEntityTFTowerBossSpawner; -import twilightforest.tileentity.TileEntityTFTowerBuilder; -import twilightforest.tileentity.TileEntityTFTrophy; +import twilightforest.loot.TFTreasure; +import twilightforest.network.TFPacketHandler; +import twilightforest.structures.hollowtree.TFHollowTreePieces; +import twilightforest.structures.start.StructureStartNothing; +import twilightforest.tileentity.*; +import twilightforest.tileentity.spawner.*; import twilightforest.world.WorldProviderTwilightForest; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.FMLLog; -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.Mod; -import cpw.mods.fml.common.ModContainer; -import cpw.mods.fml.common.Mod.EventHandler; -import cpw.mods.fml.common.Mod.Instance; -import cpw.mods.fml.common.SidedProxy; -import cpw.mods.fml.common.event.FMLInitializationEvent; -import cpw.mods.fml.common.event.FMLPostInitializationEvent; -import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import cpw.mods.fml.common.event.FMLServerStartingEvent; -import cpw.mods.fml.common.network.FMLEventChannel; -import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.internal.FMLMessage.EntitySpawnMessage; -import cpw.mods.fml.common.registry.EntityRegistry; -import cpw.mods.fml.common.registry.GameRegistry; -import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; -import thaumcraft.api.*; -import thaumcraft.api.aspects.Aspect; -import thaumcraft.api.aspects.AspectList; - -@Mod(modid = TwilightForestMod.ID, name = "The Twilight Forest", version = TwilightForestMod.VERSION) +import twilightforest.world.feature.TFGenCaveStalactite; + +@Mod( modid = TwilightForestMod.ID, + name = TwilightForestMod.NAME, + version = TwilightForestMod.VERSION, + acceptedMinecraftVersions = "[1.12.2]", + dependencies = "after:ctm@[MC1.12.2-0.3.2.18,);before:immersiveengineering@[0.12-83,);before:tconstruct;required-after:forge@[14.23.5.2813,);after:thaumcraft@[6.1.BETA21,)", + updateJSON = "https://raw.githubusercontent.com/TeamTwilight/twilightforest/1.12.x/update.json" +) public class TwilightForestMod { - - public static final String ID = "TwilightForest"; - public static final String VERSION = "2.3.8dev"; - - public static final String MODEL_DIR = "twilightforest:textures/model/"; - public static final String GUI_DIR = "twilightforest:textures/gui/"; - public static final String ENVRIO_DIR = "twilightforest:textures/environment/"; - public static final String ARMOR_DIR = "twilightforest:textures/armor/"; + + public static final String ID = "twilightforest"; + public static final String NAME = "The Twilight Forest"; + public static final String VERSION = "@VERSION@"; + + private static final String MODEL_DIR = "textures/model/"; + private static final String GUI_DIR = "textures/gui/"; + private static final String ENVIRO_DIR = "textures/environment/"; + // odd one out, as armor textures are a stringy mess at present + public static final String ARMOR_DIR = ID + ":textures/armor/"; + public static final String ENFORCED_PROGRESSION_RULE = "tfEnforcedProgression"; - + public static final int GUI_ID_UNCRAFTING = 1; public static final int GUI_ID_FURNACE = 2; + public static DimensionType dimType; + public static int backupDimensionID = -777; + + public static final Logger LOGGER = LogManager.getLogger(ID); + + private static final EnumRarity rarity = EnumHelper.addRarity("TWILIGHT", TextFormatting.DARK_GREEN, "Twilight"); + + private static boolean compat = true; - public static int dimensionID; - public static int backupdimensionID = -777; - public static int dimensionProviderID; - - // misc options - public static boolean creatureCompatibility; - public static boolean silentCicadas; - public static boolean allowPortalsInOtherDimensions; - public static boolean adminOnlyPortals; - public static String twilightForestSeed; - public static boolean disablePortalCreation; - public static boolean disableUncrafting; - public static boolean oldMapGen; - public static String portalCreationItemString; - - // performance - public static float canopyCoverage; - public static int twilightOakChance; - - public static int idMobWildBoar; - public static int idMobBighornSheep; - public static int idMobWildDeer; - public static int idMobRedcap; - public static int idMobSwarmSpider; - public static int idMobNaga; - public static int idMobNagaSegment; - public static int idMobSkeletonDruid; - public static int idMobHostileWolf; - public static int idMobTwilightWraith; - public static int idMobHedgeSpider; - public static int idMobHydra; - public static int idMobLich; - public static int idMobPenguin; - public static int idMobLichMinion; - public static int idMobLoyalZombie; - public static int idMobTinyBird; - public static int idMobSquirrel; - public static int idMobBunny; - public static int idMobRaven; - public static int idMobQuestRam; - public static int idMobKobold; - public static int idMobBoggard; - public static int idMobMosquitoSwarm; - public static int idMobDeathTome; - public static int idMobMinotaur; - public static int idMobMinoshroom; - public static int idMobFireBeetle; - public static int idMobSlimeBeetle; - public static int idMobPinchBeetle; - public static int idMobMazeSlime; - public static int idMobRedcapSapper; - public static int idMobMistWolf; - public static int idMobKingSpider; - public static int idMobFirefly; - public static int idMobMiniGhast; - public static int idMobTowerGhast; - public static int idMobTowerGolem; - public static int idMobTowerTermite; - public static int idMobTowerBroodling; - public static int idMobTowerBoss; - public static int idMobBlockGoblin; - public static int idMobGoblinKnightUpper; - public static int idMobGoblinKnightLower; - public static int idMobHelmetCrab; - public static int idMobKnightPhantom; - public static int idMobYeti; - public static int idMobYetiBoss; - public static int idMobWinterWolf; - public static int idMobSnowGuardian; - public static int idMobStableIceCore; - public static int idMobUnstableIceCore; - public static int idMobSnowQueen; - public static int idMobTroll; - public static int idMobGiantMiner; - public static int idMobArmoredGiant; - public static int idMobIceCrystal; - public static int idMobHarbingerCube; - public static int idMobAdherent; - public static int idMobRovingCube; - - public static int idVehicleSpawnNatureBolt = 1; // non-configurable, since there's no way for them to conflict with anything - public static int idVehicleSpawnLichBolt = 2; - public static int idVehicleSpawnTwilightWandBolt = 3; - public static int idVehicleSpawnTomeBolt = 4; - public static int idVehicleSpawnHydraMortar = 5; - public static int idVehicleSpawnLichBomb = 6; - public static int idVehicleSpawnMoonwormShot = 7; - public static int idVehicleSpawnSlimeBlob = 8; - public static int idVehicleSpawnCharmEffect = 9; - public static int idVehicleSpawnThrownAxe = 10; - public static int idVehicleSpawnThrownPick = 13; - public static int idVehicleSpawnFallingIce = 14; - public static int idVehicleSpawnThrownIce = 15; - public static int idVehicleSpawnSeekerArrow = 16; - public static int idVehicleSpawnIceSnowball = 17; - public static int idVehicleSpawnChainBlock = 18; - public static int idVehicleSpawnCubeOfAnnihilation = 19; - public static int idVehicleSpawnSlideBlock = 20; - - public static int idBiomeLake; - public static int idBiomeTwilightForest; - public static int idBiomeTwilightForestVariant; - public static int idBiomeHighlands; - public static int idBiomeMushrooms; - public static int idBiomeSwamp; - public static int idBiomeStream; - public static int idBiomeSnowfield; - public static int idBiomeGlacier; - public static int idBiomeClearing; - public static int idBiomeOakSavanna; - public static int idBiomeFireflyForest; - public static int idBiomeDeepMushrooms; - public static int idBiomeDarkForestCenter; - public static int idBiomeHighlandsCenter; - public static int idBiomeDarkForest; - public static int idBiomeEnchantedForest; - public static int idBiomeFireSwamp; - public static int idBiomeThornlands; - - // used to report conflicts - public static boolean hasBiomeIdConflicts = false; - public static boolean hasAssignedBiomeID = false; - - public static final TFEventListener eventListener = new TFEventListener(); - public static final TFTickHandler tickHandler = new TFTickHandler(); - public static FMLEventChannel genericChannel; - - @Instance(ID) public static TwilightForestMod instance; @SidedProxy(clientSide = "twilightforest.client.TFClientProxy", serverSide = "twilightforest.TFCommonProxy") public static TFCommonProxy proxy; - public TwilightForestMod() - { - TwilightForestMod.instance = this; - } - - @EventHandler + @EventHandler public void preInit(FMLPreInitializationEvent event) { - // load config - Configuration config = new Configuration(event.getSuggestedConfigurationFile()); - loadConfiguration(config); + if (Loader.isModLoaded("sponge")) { + LOGGER.info("It looks like you have Sponge installed! You may notice Hydras spawning incorrectly with floating heads.\n" + + "If so, please update Sponge to resolve this issue. Have fun!" + ); + } + + registerTileEntities(); + dimType = DimensionType.register("twilight_forest", "_twilightforest", TFConfig.dimension.dimensionID, WorldProviderTwilightForest.class, false); + WorldProviderTwilightForest.syncFromConfig(); + // sounds on client, and whatever else needs to be registered pre-load - proxy.doPreLoadRegistration(); + proxy.preInit(); - // initialize & register blocks - TFBlocks.registerBlocks(); + CapabilityList.registerCapabilities(); - // items - TFItems.registerItems(); - - // cheevos! - AchievementPage.registerAchievementPage(new TFAchievementPage()); - // just call this so that we register structure IDs correctly - new StructureTFMajorFeatureStart(); - - - // check for biome conflicts, load biomes - TFBiomeBase.assignBlankBiomeIds(); - if (TwilightForestMod.hasAssignedBiomeID) { - FMLLog.info("[TwilightForest] Twilight Forest mod has auto-assigned some biome IDs. This will break any existing Twilight Forest saves."); - saveBiomeIds(config); - } - TwilightForestMod.hasBiomeIdConflicts = TFBiomeBase.areThereBiomeIdConflicts(); - } - - @EventHandler - public void load(FMLInitializationEvent evt) { + TFFeature.init(); + LOGGER.debug("There are {} entries in TFFeature enum. Maximum structure size is {}", TFFeature.getCount(), TFFeature.getMaxSize()); - // creatures - registerCreatures(); + MapGenStructureIO.registerStructure(StructureStartNothing.class, "TFNothing"); + TFHollowTreePieces.registerPieces(); - // recipes - TFRecipes.registerRecipes(); + compat = TFConfig.doCompat; - // tile entities - registerTileEntities(); - // GUI - NetworkRegistry.INSTANCE.registerGuiHandler(instance, proxy); - - // event listener, for those events that seem worth listening to - MinecraftForge.EVENT_BUS.register(eventListener); - FMLCommonHandler.instance().bus().register(eventListener); // we're getting events off this bus too - - // tick listener - FMLCommonHandler.instance().bus().register(tickHandler); - - // set up portal item - Item portalItem; - if (Item.itemRegistry.containsKey(portalCreationItemString)) { - portalItem = (Item) Item.itemRegistry.getObject(portalCreationItemString); - if (portalItem != Items.diamond) { - FMLLog.info("Set Twilight Forest portal item to %s", portalItem.getUnlocalizedName()); + if (compat) { + try { + TFCompat.preInitCompat(); + } catch (Exception e) { + compat = false; + LOGGER.error("Had an error loading preInit compatibility!"); + LOGGER.catching(e.fillInStackTrace()); } - } else if (Block.blockRegistry.containsKey(portalCreationItemString)) { - portalItem = Item.getItemFromBlock((Block) Block.blockRegistry.getObject(portalCreationItemString)); - FMLLog.info("Set Twilight Forest portal item to %s", portalItem.getUnlocalizedName()); } else { - FMLLog.info("Twilight Forest config lists portal item as '%s'. Not found, defaulting to diamond.", portalCreationItemString); - portalItem = Items.diamond; + LOGGER.warn("Skipping compatibility!"); } - tickHandler.portalItem = portalItem; - - // make some channels for our maps - TFMapPacketHandler mapPacketHandler = new TFMapPacketHandler(); - NetworkRegistry.INSTANCE.newEventDrivenChannel(ItemTFMagicMap.STR_ID).register(mapPacketHandler); - NetworkRegistry.INSTANCE.newEventDrivenChannel(ItemTFMazeMap.STR_ID).register(mapPacketHandler); - - // generic channel that handles biome change packets, but could handle some other stuff in the future - TwilightForestMod.genericChannel = NetworkRegistry.INSTANCE.newEventDrivenChannel(TwilightForestMod.ID); - - // render and other client stuff - proxy.doOnLoadRegistration(); - - // dimension provider - DimensionManager.registerProviderType(TwilightForestMod.dimensionProviderID, WorldProviderTwilightForest.class, false); - - // enter biomes into dictionary - TFBiomeBase.registerWithBiomeDictionary(); } - - /** - * Post init - */ - @EventHandler - public void postInit(FMLPostInitializationEvent evt) - { - // register dimension with Forge - if (!DimensionManager.isDimensionRegistered(TwilightForestMod.dimensionID)) - { - DimensionManager.registerDimension(TwilightForestMod.dimensionID, TwilightForestMod.dimensionProviderID); - } - else - { - FMLLog.warning("[TwilightForest] Twilight Forest detected that the configured dimension id '%d' is being used. Using backup ID. It is recommended that you configure this mod to use a unique dimension ID.", dimensionID); - DimensionManager.registerDimension(TwilightForestMod.backupdimensionID, TwilightForestMod.dimensionProviderID); - TwilightForestMod.dimensionID = TwilightForestMod.backupdimensionID; - } - - // thaumcraft integration - if (Loader.isModLoaded("Thaumcraft")) - { - registerThaumcraftIntegration(); - } - else - { - FMLLog.info("[TwilightForest] Did not find Thaumcraft, did not load ThaumcraftApi integration."); + + @EventHandler + public void init(FMLInitializationEvent evt) { + TFItems.initRepairMaterials(); + NetworkRegistry.INSTANCE.registerGuiHandler(instance, proxy); + TFPacketHandler.init(); + proxy.init(); + TFAdvancements.init(); + TFTreasure.init(); + + if (compat) { + try { + TFCompat.initCompat(); + } catch (Exception e) { + compat = false; + LOGGER.error("Had an error loading init compatibility!"); + LOGGER.catching(e.fillInStackTrace()); + } } - - // final check for biome ID conflicts - TwilightForestMod.hasBiomeIdConflicts = TFBiomeBase.areThereBiomeIdConflicts(); - } - - @EventHandler - public void startServer(FMLServerStartingEvent event) - { - // dispenser behaviors - registerDispenseBehaviors(event.getServer()); - - //event.registerServerCommand(new CommandTFFeature()); - event.registerServerCommand(new CommandTFProgress()); + + TFDataFixers.init(); } - private void registerCreatures() { - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFBoar.class, "Wild Boar", idMobWildBoar, 0x83653b, 0xffefca); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFBighorn.class, "Bighorn Sheep", idMobBighornSheep, 0xdbceaf, 0xd7c771); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFDeer.class, "Wild Deer", idMobWildDeer, 0x7b4d2e, 0x4b241d); - - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFRedcap.class, "Redcap", idMobRedcap, 0x3b3a6c, 0xab1e14); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFSwarmSpider.class, "Swarm Spider", idMobSwarmSpider, 0x32022e, 0x17251e); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFNaga.class, "Naga", idMobNaga, 0xa4d316, 0x1b380b); - //TFCreatures.registerTFCreature(twilightforest.entity.EntityTFNagaSegmentOld.class, "Naga Segment", idMobNagaSegment); // no longer needed, regenerated instantly as required - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFSkeletonDruid.class, "Skeleton Druid", idMobSkeletonDruid, 0xa3a3a3, 0x2a3b17); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFHostileWolf.class, "Hostile Wolf", idMobHostileWolf, 0xd7d3d3, 0xab1e14); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFWraith.class, "Twilight Wraith", idMobTwilightWraith, 0x505050, 0x838383); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFHedgeSpider.class, "Hedge Spider", idMobHedgeSpider, 0x235f13, 0x562653); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFHydra.class, "Hydra", idMobHydra, 0x142940, 0x29806b); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFLich.class, "Twilight Lich", idMobLich, 0xaca489, 0x360472); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFPenguin.class, "Glacier Penguin", idMobPenguin, 0x12151b, 0xf9edd2); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFLichMinion.class, "Lich Minion", idMobLichMinion); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFLoyalZombie.class, "Loyal Zombie", idMobLoyalZombie); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFTinyBird.class, "Tiny Bird", idMobTinyBird, 0x33aadd, 0x1188ee); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFSquirrel.class, "Forest Squirrel", idMobSquirrel, 0x904f12, 0xeeeeee); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFBunny.class, "Forest Bunny", idMobBunny, 0xfefeee, 0xccaa99); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFRaven.class, "Forest Raven", idMobRaven, 0x000011, 0x222233); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFQuestRam.class, "Questing Ram", idMobQuestRam); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFKobold.class, "Twilight Kobold", idMobKobold, 0x372096, 0x895d1b); - //TFCreatures.registerTFCreature(twilightforest.entity.EntityTFBoggard.class, "Boggard", idMobBoggard); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFMosquitoSwarm.class, "Mosquito Swarm", idMobMosquitoSwarm, 0x080904, 0x2d2f21); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFDeathTome.class, "Death Tome", idMobDeathTome, 0x774e22, 0xdbcdbe); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFMinotaur.class, "Minotaur", idMobMinotaur, 0x3f3024, 0xaa7d66); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFMinoshroom.class, "Minoshroom", idMobMinoshroom, 0xa81012, 0xaa7d66); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFFireBeetle.class, "Fire Beetle", idMobFireBeetle, 0x1d0b00, 0xcb6f25); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFSlimeBeetle.class, "Slime Beetle", idMobSlimeBeetle, 0x0c1606, 0x60a74c); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFPinchBeetle.class, "Pinch Beetle", idMobPinchBeetle, 0xbc9327, 0x241609); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFMazeSlime.class, "Maze Slime", idMobMazeSlime, 0xa3a3a3, 0x2a3b17); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFRedcapSapper.class, "Redcap Sapper", idMobRedcapSapper, 0x575d21, 0xab1e14); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFMistWolf.class, "Mist Wolf", idMobMistWolf, 0x3a1411, 0xe2c88a); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFKingSpider.class, "King Spider", idMobKingSpider, 0x2c1a0e, 0xffc017); - TFCreatures.registerTFCreature(twilightforest.entity.passive.EntityTFMobileFirefly.class, "Firefly", idMobFirefly, 0xa4d316, 0xbaee02); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFMiniGhast.class, "Mini Ghast", idMobMiniGhast, 0xbcbcbc, 0xa74343); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFTowerGhast.class, "Tower Ghast", idMobTowerGhast, 0xbcbcbc, 0xb77878); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFTowerGolem.class, "Tower Golem", idMobTowerGolem, 0x6b3d20, 0xe2ddda); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFTowerTermite.class, "Tower Termite", idMobTowerTermite, 0x5d2b21, 0xaca03a); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFTowerBroodling.class, "Redscale Broodling", idMobTowerBroodling, 0x343c14, 0xbaee02); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFUrGhast.class, "Tower Boss", idMobTowerBoss, 0xbcbcbc, 0xb77878); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFBlockGoblin.class, "Block&Chain Goblin", idMobBlockGoblin, 0xd3e7bc, 0x1f3fff); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFGoblinKnightUpper.class, "Upper Goblin Knight", idMobGoblinKnightUpper); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFGoblinKnightLower.class, "Lower Goblin Knight", idMobGoblinKnightLower, 0x566055, 0xd3e7bc); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFHelmetCrab.class, "Helmet Crab", idMobHelmetCrab, 0xfb904b, 0xd3e7bc); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFKnightPhantom.class, "Knight Phantom", idMobKnightPhantom, 0xa6673b, 0xd3e7bc); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFYeti.class, "Yeti", idMobYeti, 0xdedede, 0x4675bb); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFYetiAlpha.class, "Yeti Boss", idMobYetiBoss, 0xcdcdcd, 0x29486e); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFWinterWolf.class, "WinterWolf", idMobWinterWolf, 0xdfe3e5, 0xb2bcca); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFSnowGuardian.class, "SnowGuardian", idMobSnowGuardian, 0xd3e7bc, 0xfefefe); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFIceShooter.class, "Stable Ice Core", idMobStableIceCore, 0xa1bff3, 0x7000f8); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFIceExploder.class, "Unstable Ice Core", idMobUnstableIceCore, 0x9aacf5, 0x9b0fa5); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFSnowQueen.class, "Snow Queen", idMobSnowQueen, 0xb1b2d4, 0x87006e); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFTroll.class, "Troll", idMobTroll, 0x9ea98f, 0xb0948e); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFGiantMiner.class, "Giant Miner", idMobGiantMiner, 0x211b52, 0x9a9a9a); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFArmoredGiant.class, "Armored Giant", idMobArmoredGiant, 0x239391, 0x9a9a9a); - TFCreatures.registerTFCreature(twilightforest.entity.boss.EntityTFIceCrystal.class, "Ice Crystal", idMobIceCrystal, 0xdce9fe, 0xadcafb); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFHarbingerCube.class, "Harbinger Cube", idMobHarbingerCube, 0x00000a, 0x8b0000); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFAdherent.class, "Adherent", idMobAdherent, 0x0a0000, 0x00008b); - TFCreatures.registerTFCreature(twilightforest.entity.EntityTFRovingCube.class, "RovingCube", idMobRovingCube, 0x0a0000, 0x00009b); - - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFHydraHead.class, "HydraHead", 11, this, 150, 3, false); - - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFNatureBolt.class, "tfnaturebolt", idVehicleSpawnNatureBolt, this, 150, 5, true); - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFLichBolt.class, "tflichbolt", idVehicleSpawnLichBolt, this, 150, 2, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFTwilightWandBolt.class, "tftwilightwandbolt", idVehicleSpawnTwilightWandBolt, this, 150, 5, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFTomeBolt.class, "tftomebolt", idVehicleSpawnTomeBolt, this, 150, 5, true); - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFHydraMortar.class, "tfhydramortar", idVehicleSpawnHydraMortar, this, 150, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFLichBomb.class, "tflichbomb", idVehicleSpawnLichBomb, this, 150, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFMoonwormShot.class, "tfmoonwormshot", idVehicleSpawnMoonwormShot, this, 150, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFSlimeProjectile.class, "tfslimeblob", idVehicleSpawnSlimeBlob, this, 150, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFCharmEffect.class, "tfcharmeffect", idVehicleSpawnCharmEffect, this, 80, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFThrownAxe.class, "tfthrownaxe", idVehicleSpawnThrownAxe, this, 80, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFThrownPick.class, "tfthrownpick", idVehicleSpawnThrownPick, this, 80, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFFallingIce.class, "tffallingice", idVehicleSpawnFallingIce, this, 80, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.boss.EntityTFIceBomb.class, "tfthrownice", idVehicleSpawnThrownIce, this, 80, 2, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntitySeekerArrow.class, "tfSeekerArrow", idVehicleSpawnSeekerArrow, this, 150, 1, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFIceSnowball.class, "tficesnowball", idVehicleSpawnIceSnowball, this, 150, 3, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFChainBlock.class, "tfchainBlock", idVehicleSpawnChainBlock, this, 80, 1, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFCubeOfAnnihilation.class, "tfcubeannihilation", this.idVehicleSpawnCubeOfAnnihilation, this, 80, 1, true); - EntityRegistry.registerModEntity(twilightforest.entity.EntityTFSlideBlock.class, "tfslideblock", this.idVehicleSpawnSlideBlock, this, 80, 1, true); + @EventHandler + public void postInit(FMLPostInitializationEvent evt) { + registerDimension(); + checkOriginDimension(); + + if (compat) { + try { + TFCompat.postInitCompat(); + } catch (Exception e) { + compat = false; + LOGGER.error("Had an error loading postInit compatibility!"); + LOGGER.catching(e.fillInStackTrace()); + } + } + + TFConfig.build(); + TFGenCaveStalactite.loadStalactites(); + } + @EventHandler + public void onIMC(FMLInterModComms.IMCEvent event) { + IMCHandler.onIMC(event); } - - - private void registerTileEntities() { - GameRegistry.registerTileEntity(TileEntityTFFirefly.class, "Firefly"); - GameRegistry.registerTileEntity(TileEntityTFCicada.class, "Cicada"); - GameRegistry.registerTileEntity(TileEntityTFNagaSpawner.class, "Naga Spawner"); - GameRegistry.registerTileEntity(TileEntityTFLichSpawner.class, "Lich Spawner"); - GameRegistry.registerTileEntity(TileEntityTFHydraSpawner.class, "Hydra Spawner"); - GameRegistry.registerTileEntity(TileEntityTFSmoker.class, "Swamp Smoker"); - GameRegistry.registerTileEntity(TileEntityTFPoppingJet.class, "Popping Flame Jet"); - GameRegistry.registerTileEntity(TileEntityTFFlameJet.class, "Lit Flame Jet"); - GameRegistry.registerTileEntity(TileEntityTFMoonworm.class, "Moonworm"); - GameRegistry.registerTileEntity(TileEntityTFTowerBuilder.class, "Tower Builder"); - GameRegistry.registerTileEntity(TileEntityTFReverter.class, "Tower Reverter"); - GameRegistry.registerTileEntity(TileEntityTFTrophy.class, "TF Trophy"); - GameRegistry.registerTileEntity(TileEntityTFTowerBossSpawner.class, "Tower Boss Spawner"); - GameRegistry.registerTileEntity(TileEntityTFGhastTrapInactive.class, "Inactive Ghast Trap"); - GameRegistry.registerTileEntity(TileEntityTFGhastTrapActive.class, "Active Ghast Trap"); - GameRegistry.registerTileEntity(TileEntityTFCReactorActive.class, "Active Carminite Reactor"); - GameRegistry.registerTileEntity(TileEntityTFKnightPhantomsSpawner.class, "Knight Phantom Spawner"); - GameRegistry.registerTileEntity(TileEntityTFSnowQueenSpawner.class, "Snow Queen Spawner"); - GameRegistry.registerTileEntity(TileEntityTFCinderFurnace.class, "Cinder Furnace"); + + @EventHandler + public void startServer(FMLServerStartingEvent event) { + event.registerServerCommand(new CommandTF()); } - /** - * Use the thaumcraft API to register our things with aspects and biomes with values - */ - private void registerThaumcraftIntegration() - { - try { - - // items - registerTCObjectTag(TFItems.nagaScale, -1, (new AspectList()).add(Aspect.MOTION, 2).add(Aspect.ARMOR, 3)); - registerTCObjectTag(TFItems.scepterTwilight, -1, (new AspectList()).add(Aspect.MAGIC, 8).add(Aspect.ELDRITCH, 8).add(Aspect.WEAPON, 8)); - registerTCObjectTag(TFItems.scepterLifeDrain, -1, (new AspectList()).add(Aspect.MAGIC, 8).add(Aspect.LIFE, 8).add(Aspect.HUNGER, 8)); - registerTCObjectTag(TFItems.scepterZombie, -1, (new AspectList()).add(Aspect.MAGIC, 8).add(Aspect.UNDEAD, 8).add(Aspect.ENTROPY, 8)); - registerTCObjectTag(TFItems.magicMapFocus, -1, (new AspectList()).add(Aspect.MAGIC, 4).add(Aspect.SENSES, 8)); - registerTCObjectTag(TFItems.mazeMapFocus, -1, (new AspectList()).add(Aspect.MAGIC, 4).add(Aspect.SENSES, 8).add(Aspect.ORDER, 4)); - registerTCObjectTag(TFItems.feather, -1, (new AspectList()).add(Aspect.FLIGHT, 2).add(Aspect.AIR, 1).add(Aspect.DARKNESS, 1)); - registerTCObjectTag(TFItems.liveRoot, -1, (new AspectList()).add(Aspect.MAGIC, 1).add(Aspect.TREE, 2).add(Aspect.LIFE, 2)); - registerTCObjectTag(TFItems.ironwoodIngot, -1, (new AspectList()).add(Aspect.MAGIC, 2).add(Aspect.TREE, 1).add(Aspect.METAL, 4).add(Aspect.CRAFT, 2)); - registerTCObjectTag(TFItems.torchberries, -1, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.LIGHT, 2)); - registerTCObjectTag(TFItems.fieryBlood, -1, (new AspectList()).add(Aspect.FIRE, 8).add(Aspect.LIFE, 8).add(Aspect.MAGIC, 4)); - registerTCObjectTag(TFItems.trophy, -1, (new AspectList()).add(Aspect.LIFE, 6).add(Aspect.BEAST, 6).add(Aspect.SOUL, 6)); - registerTCObjectTag(TFItems.steeleafIngot, -1, (new AspectList()).add(Aspect.PLANT, 4).add(Aspect.METAL, 2)); - registerTCObjectTag(TFItems.minotaurAxe, -1, (new AspectList()).add(Aspect.TOOL, 2).add(Aspect.WEAPON, 4).add(Aspect.CRYSTAL, 6).add(Aspect.GREED, 8)); - registerTCObjectTag(TFItems.mazebreakerPick, -1, (new AspectList()).add(Aspect.CRYSTAL, 6).add(Aspect.TOOL, 8).add(Aspect.MINE, 8)); - registerTCObjectTag(TFItems.oreMagnet, -1, (new AspectList()).add(Aspect.GREED, 10).add(Aspect.TOOL, 6).add(Aspect.METAL, 8).add(Aspect.MOTION, 6)); - registerTCObjectTag(TFItems.crumbleHorn, -1, (new AspectList()).add(Aspect.ENTROPY, 12).add(Aspect.BEAST, 2)); - registerTCObjectTag(TFItems.peacockFan, -1, (new AspectList()).add(Aspect.AIR, 8).add(Aspect.MOTION, 6).add(Aspect.FLIGHT, 10)); - registerTCObjectTag(TFItems.moonwormQueen, -1, (new AspectList()).add(Aspect.LIGHT, 12).add(Aspect.MAGIC, 1)); - registerTCObjectTag(TFItems.charmOfLife1, -1, (new AspectList()).add(Aspect.LIFE, 2).add(Aspect.HEAL, 2).add(Aspect.GREED, 4)); - registerTCObjectTag(TFItems.charmOfKeeping1, -1, (new AspectList()).add(Aspect.DEATH, 1).add(Aspect.TRAVEL, 2).add(Aspect.GREED, 4)); - registerTCObjectTag(TFItems.towerKey, -1, (new AspectList()).add(Aspect.MECHANISM, 4).add(Aspect.MAGIC, 4)); - registerTCObjectTag(TFItems.transformPowder, -1, (new AspectList()).add(Aspect.MAGIC, 8).add(Aspect.EXCHANGE, 4)); - registerTCObjectTag(TFItems.borerEssence, -1, (new AspectList()).add(Aspect.BEAST, 2).add(Aspect.TREE, 2).add(Aspect.SOUL, 4).add(Aspect.MAGIC, 2)); - registerTCObjectTag(TFItems.armorShard, -1, (new AspectList()).add(Aspect.METAL, 1)); - registerTCObjectTag(TFItems.knightMetal, -1, (new AspectList()).add(Aspect.METAL, 8).add(Aspect.ORDER, 1)); - registerTCObjectTag(TFItems.phantomHelm, -1, (new AspectList()).add(Aspect.METAL, 6).add(Aspect.ARMOR, 6).add(Aspect.UNDEAD, 6)); - registerTCObjectTag(TFItems.phantomPlate, -1, (new AspectList()).add(Aspect.METAL, 8).add(Aspect.ARMOR, 8).add(Aspect.UNDEAD, 8)); - registerTCObjectTag(TFItems.armorShard, -1, (new AspectList()).add(Aspect.METAL, 1)); - registerTCObjectTag(TFItems.lampOfCinders, -1, (new AspectList()).add(Aspect.FIRE, 4).add(Aspect.MAGIC, 4).add(Aspect.TOOL, 4)); - registerTCObjectTag(TFItems.fieryTears, -1, (new AspectList()).add(Aspect.FIRE, 8).add(Aspect.LIFE, 8).add(Aspect.MAGIC, 4)); - registerTCObjectTag(TFItems.alphaFur, -1, (new AspectList()).add(Aspect.COLD, 3).add(Aspect.BEAST, 3).add(Aspect.MAGIC, 4).add(Aspect.ARMOR, 1)); - registerTCObjectTag(TFItems.iceBomb, -1, (new AspectList()).add(Aspect.COLD, 3).add(Aspect.AIR, 1)); - registerTCObjectTag(TFItems.arcticFur, -1, (new AspectList()).add(Aspect.COLD, 3).add(Aspect.BEAST, 3)); - registerTCObjectTag(TFItems.tripleBow, -1, (new AspectList()).add(Aspect.TREE, 6).add(Aspect.BEAST, 6).add(Aspect.CLOTH, 6).add(Aspect.WEAPON, 9).add(Aspect.AIR, 3)); - registerTCObjectTag(TFItems.seekerBow, -1, (new AspectList()).add(Aspect.MIND, 3).add(Aspect.BEAST, 2).add(Aspect.CLOTH, 2).add(Aspect.WEAPON, 3).add(Aspect.AIR, 1)); - registerTCObjectTag(TFItems.iceBow, -1, (new AspectList()).add(Aspect.COLD, 2).add(Aspect.BEAST, 2).add(Aspect.CLOTH, 2).add(Aspect.WEAPON, 3).add(Aspect.AIR, 1)); - registerTCObjectTag(TFItems.enderBow, -1, (new AspectList()).add(Aspect.TRAVEL, 2).add(Aspect.BEAST, 2).add(Aspect.CLOTH, 2).add(Aspect.WEAPON, 3).add(Aspect.AIR, 1)); - registerTCObjectTag(TFItems.iceSword, -1, (new AspectList()).add(Aspect.WEAPON, 4).add(Aspect.CRYSTAL, 4).add(Aspect.COLD, 4)); - registerTCObjectTag(TFItems.glassSword, -1, (new AspectList()).add(Aspect.WEAPON, 5).add(Aspect.CRYSTAL, 4)); - registerTCObjectTag(TFItems.cubeTalisman, -1, (new AspectList()).add(Aspect.VOID, 4).add(Aspect.MAGIC, 4).add(Aspect.ENTROPY, 4)); - registerTCObjectTag(TFItems.cubeOfAnnihilation, -1, (new AspectList()).add(Aspect.VOID, 7).add(Aspect.MAGIC, 7).add(Aspect.ENTROPY, 7)); - - // food - registerTCObjectTag(TFItems.venisonRaw, -1, (new AspectList()).add(Aspect.HUNGER, 2).add(Aspect.FLESH, 4).add(Aspect.BEAST, 2)); - registerTCObjectTag(TFItems.venisonCooked, -1, (new AspectList()).add(Aspect.HUNGER, 4).add(Aspect.FLESH, 4).add(Aspect.CRAFT, 1)); - registerTCObjectTag(TFItems.hydraChop, -1, (new AspectList()).add(Aspect.HUNGER, 6).add(Aspect.FLESH, 6).add(Aspect.LIFE, 4)); - registerTCObjectTag(TFItems.meefRaw, -1, (new AspectList()).add(Aspect.BEAST, 2).add(Aspect.FLESH, 4).add(Aspect.LIFE, 2)); - registerTCObjectTag(TFItems.meefSteak, -1, (new AspectList()).add(Aspect.FIRE, 1).add(Aspect.BEAST, 1).add(Aspect.FLESH, 4).add(Aspect.LIFE, 2)); - registerTCObjectTag(TFItems.meefStroganoff, -1, (new AspectList()).add(Aspect.HUNGER, 4).add(Aspect.BEAST, 2).add(Aspect.FLESH, 4)); - registerTCObjectTag(TFItems.mazeWafer, -1, (new AspectList()).add(Aspect.HUNGER, 2)); - registerTCObjectTag(TFItems.experiment115, -1, (new AspectList()).add(Aspect.HUNGER, 3).add(Aspect.MECHANISM, 1)); - - // blocks - registerTCObjectTag(TFBlocks.firefly, -1, (new AspectList()).add(Aspect.FLIGHT, 1).add(Aspect.LIGHT, 2)); - registerTCObjectTag(TFBlocks.leaves, -1, (new AspectList()).add(Aspect.PLANT, 2)); - registerTCObjectTag(TFBlocks.mazestone, -1, (new AspectList()).add(Aspect.ORDER, 2).add(Aspect.TRAP, 1).add(Aspect.ARMOR, 1)); - registerTCObjectTag(TFBlocks.hedge, 0, (new AspectList()).add(Aspect.PLANT, 1).add(Aspect.WEAPON, 1)); - registerTCObjectTag(TFBlocks.hedge, 1, (new AspectList()).add(Aspect.PLANT, 3).add(Aspect.DARKNESS, 1)); - registerTCObjectTag(TFBlocks.root, -1, (new AspectList()).add(Aspect.TREE, 2)); - registerTCObjectTag(TFBlocks.cicada, -1, (new AspectList()).add(Aspect.SENSES, 2)); - registerTCObjectTag(TFBlocks.uncraftingTable, -1, (new AspectList()).add(Aspect.TREE, 4).add(Aspect.ENTROPY, 8).add(Aspect.EXCHANGE, 12).add(Aspect.CRAFT, 16)); - registerTCObjectTag(TFBlocks.fireJet, -1, (new AspectList()).add(Aspect.FIRE, 4).add(Aspect.AIR, 2).add(Aspect.MOTION, 2)); - registerTCObjectTag(TFBlocks.nagastone, -1, (new AspectList()).add(Aspect.ORDER, 2).add(Aspect.MOTION, 2)); - registerTCObjectTag(TFBlocks.magicLeaves, -1, (new AspectList()).add(Aspect.PLANT, 2)); - registerTCObjectTag(TFBlocks.towerWood, -1, (new AspectList()).add(Aspect.TREE, 2).add(Aspect.MECHANISM, 2)); - registerTCObjectTag(TFBlocks.towerDevice, -1, (new AspectList()).add(Aspect.TREE, 4).add(Aspect.MECHANISM, 4).add(Aspect.MAGIC, 4)); - registerTCObjectTag(TFBlocks.towerTranslucent, -1, (new AspectList()).add(Aspect.TREE, 4).add(Aspect.MECHANISM, 4).add(Aspect.MAGIC, 4).add(Aspect.VOID, 2)); - registerTCObjectTag(TFBlocks.trophy, -1, (new AspectList()).add(Aspect.LIFE, 6).add(Aspect.BEAST, 6).add(Aspect.SOUL, 6)); - registerTCObjectTag(TFBlocks.plant, 3, (new AspectList()).add(Aspect.PLANT, 1)); - registerTCObjectTag(TFBlocks.plant, 4, (new AspectList()).add(Aspect.PLANT, 1)); - registerTCObjectTag(TFBlocks.plant, 5, (new AspectList()).add(Aspect.PLANT, 2)); - registerTCObjectTag(TFBlocks.plant, 8, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.MAGIC, 1)); - registerTCObjectTag(TFBlocks.plant, 9, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.DARKNESS, 1).add(Aspect.LIGHT, 1)); - registerTCObjectTag(TFBlocks.plant, 10, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.DARKNESS, 1)); - registerTCObjectTag(TFBlocks.plant, 11, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.DARKNESS, 1)); - registerTCObjectTag(TFBlocks.plant, 13, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.LIGHT, 2)); - registerTCObjectTag(TFBlocks.plant, 14, (new AspectList()).add(Aspect.PLANT, 2)); - registerTCObjectTag(TFBlocks.sapling, -1, (new AspectList()).add(Aspect.PLANT, 4).add(Aspect.TREE, 2)); - registerTCObjectTag(TFBlocks.moonworm, -1, (new AspectList()).add(Aspect.DARKNESS, 2).add(Aspect.LIGHT, 2)); - registerTCObjectTag(TFBlocks.shield, -1, (new AspectList()).add(Aspect.TRAP, 1).add(Aspect.MAGIC, 1).add(Aspect.ARMOR, 1)); - registerTCObjectTag(TFBlocks.trophyPedestal, -1, (new AspectList()).add(Aspect.GREED, 6).add(Aspect.BEAST, 5)); - registerTCObjectTag(TFBlocks.auroraBlock, -1, (new AspectList()).add(Aspect.COLD, 2).add(Aspect.CRYSTAL, 2)); - registerTCObjectTag(TFBlocks.underBrick, -1, (new AspectList()).add(Aspect.DARKNESS, 2).add(Aspect.EARTH, 2)); - registerTCObjectTag(TFBlocks.portal, -1, (new AspectList()).add(Aspect.MAGIC, 1).add(Aspect.MOTION, 2)); - registerTCObjectTag(TFBlocks.trophy, -1, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.LIGHT, 10)); - registerTCObjectTag(TFBlocks.shield, -1, (new AspectList()).add(Aspect.EARTH, 1).add(Aspect.ORDER, 2).add(Aspect.ARMOR, 2)); - registerTCObjectTag(TFBlocks.thorns, -1, (new AspectList()).add(Aspect.PLANT, 3).add(Aspect.ENTROPY, 2).add(Aspect.TRAP, 2)); - registerTCObjectTag(TFBlocks.thornRose, -1, (new AspectList()).add(Aspect.PLANT, 1).add(Aspect.TRAP, 1).add(Aspect.SENSES, 2)); - registerTCObjectTag(TFBlocks.burntThorns, -1, (new AspectList()).add(Aspect.ENTROPY, 2).add(Aspect.FIRE, 1)); - registerTCObjectTag(TFBlocks.leaves3, -1, (new AspectList()).add(Aspect.PLANT, 2)); - registerTCObjectTag(TFBlocks.deadrock, -1, (new AspectList()).add(Aspect.EARTH, 1).add(Aspect.ENTROPY, 1).add(Aspect.DEATH, 1)); - registerTCObjectTag(TFBlocks.darkleaves, -1, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.DARKNESS, 2)); - registerTCObjectTag(TFBlocks.auroraPillar, -1, (new AspectList()).add(Aspect.COLD, 2).add(Aspect.ORDER, 2)); - registerTCObjectTag(TFBlocks.auroraSlab, -1, (new AspectList()).add(Aspect.COLD, 2).add(Aspect.ORDER, 2)); - registerTCObjectTag(TFBlocks.auroraDoubleSlab, -1, (new AspectList()).add(Aspect.COLD, 2).add(Aspect.ORDER, 2)); - registerTCObjectTag(TFBlocks.trollSteinn, -1, (new AspectList()).add(Aspect.EARTH, 1).add(Aspect.ORDER, 1).add(Aspect.CRYSTAL, 1)); - registerTCObjectTag(TFBlocks.wispyCloud, -1, (new AspectList()).add(Aspect.WEATHER, 1).add(Aspect.AIR, 1).add(Aspect.FLIGHT, 1)); - registerTCObjectTag(TFBlocks.fluffyCloud, -1, (new AspectList()).add(Aspect.WEATHER, 2).add(Aspect.AIR, 2)); - registerTCObjectTag(TFBlocks.giantCobble, -1, (new AspectList()).add(Aspect.EARTH, 8).add(Aspect.ENTROPY, 8)); - registerTCObjectTag(TFBlocks.giantLog, -1, (new AspectList()).add(Aspect.TREE, 32)); - registerTCObjectTag(TFBlocks.giantLeaves, -1, (new AspectList()).add(Aspect.PLANT, 32)); - registerTCObjectTag(TFBlocks.giantObsidian, -1, (new AspectList()).add(Aspect.FIRE, 16).add(Aspect.DARKNESS, 8).add(Aspect.EARTH, 16)); - registerTCObjectTag(TFBlocks.uberousSoil, -1, (new AspectList()).add(Aspect.EARTH, 4).add(Aspect.SENSES, 2).add(Aspect.PLANT, 2)); - registerTCObjectTag(TFBlocks.hugeStalk, -1, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.TREE, 2)); - registerTCObjectTag(TFBlocks.hugeGloomBlock, -1, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.DARKNESS, 1).add(Aspect.LIGHT, 1)); - registerTCObjectTag(TFBlocks.trollVidr, -1, (new AspectList()).add(Aspect.PLANT, 2)); - registerTCObjectTag(TFBlocks.unripeTrollBer, -1, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.DARKNESS, 1)); - registerTCObjectTag(TFBlocks.trollBer, -1, (new AspectList()).add(Aspect.PLANT, 2).add(Aspect.LIGHT, 4)); - registerTCObjectTag(TFBlocks.knightmetalStorage, -1, (new AspectList()).add(Aspect.METAL, 12).add(Aspect.ORDER, 12)); - registerTCObjectTag(TFBlocks.hugeLilyPad, -1, (new AspectList()).add(Aspect.WATER, 3).add(Aspect.PLANT, 6)); - registerTCObjectTag(TFBlocks.hugeWaterLily, -1, (new AspectList()).add(Aspect.WATER, 2).add(Aspect.PLANT, 2).add(Aspect.SENSES, 2)); - registerTCObjectTag(TFBlocks.slider, -1, (new AspectList()).add(Aspect.MOTION, 4).add(Aspect.TRAP, 6)); - registerTCObjectTag(TFBlocks.castleBlock, -1, (new AspectList()).add(Aspect.ORDER, 2)); - registerTCObjectTag(TFBlocks.castleMagic, -1, (new AspectList()).add(Aspect.ORDER, 2).add(Aspect.MAGIC, 3).add(Aspect.ENERGY, 2)); - registerTCObjectTag(TFBlocks.forceField, -1, (new AspectList()).add(Aspect.MAGIC, 3).add(Aspect.ARMOR, 4)); - - FMLLog.info("[TwilightForest] Loaded ThaumcraftApi integration."); - - - } - catch (Exception e) - { - FMLLog.warning("[TwilightForest] Had an %s error while trying to register with ThaumcraftApi.", e.getLocalizedMessage()); - // whatever. + private static void registerDimension() { + if (DimensionManager.isDimensionRegistered(TFConfig.dimension.dimensionID)) { + LOGGER.warn("Detected that the configured dimension ID '{}' is being used. Using backup ID ({}). It is recommended that you configure this mod to use a unique dimension ID.", TFConfig.dimension.dimensionID, backupDimensionID); + TFConfig.dimension.dimensionID = backupDimensionID; } - + DimensionManager.registerDimension(TFConfig.dimension.dimensionID, dimType); } - - /** - * Register a block with Thaumcraft aspects - */ - private void registerTCObjectTag(Block block, int meta, AspectList list) { - if (meta == -1) { - meta = OreDictionary.WILDCARD_VALUE; - } - ThaumcraftApi.registerObjectTag(new ItemStack(block, 1, meta), list); + + static void checkOriginDimension() { + if (!DimensionManager.isDimensionRegistered(TFConfig.originDimension)) { + LOGGER.warn("Detected that the configured origin dimension ID ({}) is not registered. Defaulting to the overworld.", TFConfig.originDimension); + TFConfig.originDimension = 0; + } else if (TFConfig.originDimension == TFConfig.dimension.dimensionID) { + LOGGER.warn("Detected that the configured origin dimension ID ({}) is already used for the Twilight Forest. Defaulting to the overworld.", TFConfig.originDimension); + TFConfig.originDimension = 0; + } } - - /** - * Register an item with Thaumcraft aspects - */ - private void registerTCObjectTag(Item item, int meta, AspectList list) { - if (meta == -1) { - meta = OreDictionary.WILDCARD_VALUE; - } - ThaumcraftApi.registerObjectTag(new ItemStack(item, 1, meta), list); + + private static void registerTileEntities() { + proxy.registerCritterTileEntities(); + + GameRegistry.registerTileEntity(TileEntityTFNagaSpawner .class, prefix("naga_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFLichSpawner .class, prefix("lich_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFHydraSpawner .class, prefix("hydra_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFSmoker .class, prefix("smoker" )); + GameRegistry.registerTileEntity(TileEntityTFPoppingJet .class, prefix("popping_jet" )); + GameRegistry.registerTileEntity(TileEntityTFFlameJet .class, prefix("flame_jet" )); + GameRegistry.registerTileEntity(TileEntityTFTowerBuilder .class, prefix("tower_builder" )); + GameRegistry.registerTileEntity(TileEntityTFAntibuilder .class, prefix("tower_reverter" )); + GameRegistry.registerTileEntity(TileEntityTFTrophy .class, prefix("trophy" )); + GameRegistry.registerTileEntity(TileEntityTFTowerBossSpawner .class, prefix("tower_boss_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFGhastTrapInactive .class, prefix("ghast_trap_inactive" )); + GameRegistry.registerTileEntity(TileEntityTFGhastTrapActive .class, prefix("ghast_trap_active" )); + GameRegistry.registerTileEntity(TileEntityTFCReactorActive .class, prefix("carminite_reactor_active")); + GameRegistry.registerTileEntity(TileEntityTFKnightPhantomsSpawner.class, prefix("knight_phantom_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFSnowQueenSpawner .class, prefix("snow_queen_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFCinderFurnace .class, prefix("cinder_furnace" )); + GameRegistry.registerTileEntity(TileEntityTFMinoshroomSpawner .class, prefix("minoshroom_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFAlphaYetiSpawner .class, prefix("alpha_yeti_spawner" )); + GameRegistry.registerTileEntity(TileEntityTFFinalBossSpawner .class, prefix("final_boss_spawner" )); } + public static ResourceLocation prefix(String name) { + return new ResourceLocation(ID, name); + } - /** - * Register all dispenser behaviors. - */ - private void registerDispenseBehaviors(MinecraftServer minecraftServer) - { - BlockDispenser.dispenseBehaviorRegistry.putObject(TFItems.spawnEgg, new BehaviorTFMobEggDispense(minecraftServer)); + public static ResourceLocation getModelTexture(String name) { + return new ResourceLocation(ID, MODEL_DIR + name); } - - /** - * Load our config file and set default values - */ - private void loadConfiguration(Configuration configFile) { - configFile.load(); - - dimensionID = configFile.get("dimension", "dimensionID", 7).getInt(); - configFile.get("dimension", "dimensionID", 7).comment = "What ID number to assign to the Twilight Forest dimension. Change if you are having conflicts with another mod."; - - dimensionProviderID = configFile.get("dimension", "dimensionProviderID", -777).getInt(); - configFile.get("dimension", "dimensionProviderID", 7).comment = "Dimension provider ID. Does not normally need to be changed, but the option is provided to work around a bug in MCPC+"; - - // other misc otions - silentCicadas = configFile.get(Configuration.CATEGORY_GENERAL, "SilentCicadas", false).getBoolean(false); - configFile.get(Configuration.CATEGORY_GENERAL, "SilentCicadas", false).comment = "Make cicadas silent for those having sound library problems, or otherwise finding them annoying"; - allowPortalsInOtherDimensions = configFile.get(Configuration.CATEGORY_GENERAL, "AllowPortalsInOtherDimensions", false).getBoolean(false); - configFile.get(Configuration.CATEGORY_GENERAL, "AllowPortalsInOtherDimensions", false).comment = "Allow portals to the Twilight Forest to be made outside of dimension 0. May be considered an exploit."; - adminOnlyPortals = configFile.get(Configuration.CATEGORY_GENERAL, "AdminOnlyPortals", false).getBoolean(false); - configFile.get(Configuration.CATEGORY_GENERAL, "AdminOnlyPortals", false).comment = "Allow portals only for admins (ops). This severly reduces the range in which the mod usually scans for valid portal conditions, and it scans near ops only."; - twilightForestSeed = configFile.get(Configuration.CATEGORY_GENERAL, "TwilightForestSeed", "").getString(); - configFile.get(Configuration.CATEGORY_GENERAL, "TwilightForestSeed", "").comment = "If set, this will override the normal world seed when generating parts of the Twilight Forest Dimension."; - disablePortalCreation = configFile.get(Configuration.CATEGORY_GENERAL, "DisablePortalCreation", false).getBoolean(false); - configFile.get(Configuration.CATEGORY_GENERAL, "DisablePortalCreation", false).comment = "Disable Twilight Forest portal creation entirely. Provided for server operators looking to restrict action to the dimension."; - disableUncrafting = configFile.get(Configuration.CATEGORY_GENERAL, "DisableUncrafting", false).getBoolean(false); - configFile.get(Configuration.CATEGORY_GENERAL, "DisableUncrafting", false).comment = "Disable the uncrafting function of the uncrafting table. Provided as an option when interaction with other mods produces exploitable recipes."; - oldMapGen = configFile.get(Configuration.CATEGORY_GENERAL, "OldMapGen", false).getBoolean(false); - configFile.get(Configuration.CATEGORY_GENERAL, "OldMapGen", false).comment = "Use old (pre Minecraft 1.7) map gen. May not be fully supported."; - portalCreationItemString = configFile.get(Configuration.CATEGORY_GENERAL, "PortalCreationItem", "diamond").getString(); - configFile.get(Configuration.CATEGORY_GENERAL, "PortalCreationItem", "diamond").comment = "Item to create the Twilight Forest Portal. Defaults to 'diamond'"; - - canopyCoverage = (float) (configFile.get("Performance", "CanopyCoverage", 1.7).getDouble(1.7)); - configFile.get("performance", "CanopyCoverage", 1.7).comment = "Amount of canopy coverage, from 0.0 on up. Lower numbers improve chunk generation speed at the cost of a thinner forest."; - twilightOakChance = configFile.get("Performance", "TwilightOakChance", 48).getInt(48); - configFile.get("Performance", "TwilightOakChance", 48).comment = "Chance that a chunk in the Twilight Forest will contain a twilight oak tree. Higher numbers reduce the number of trees, increasing performance."; - - // fixed values, don't even read the config - idMobWildBoar = 177; - idMobBighornSheep = 178; - idMobWildDeer = 179; - idMobRedcap = 180; - idMobSwarmSpider = 181; - idMobNaga = 182; - idMobNagaSegment = 183; - idMobSkeletonDruid = 184; - idMobHostileWolf = 185; - idMobTwilightWraith = 186; - idMobHedgeSpider = 187; - idMobHydra = 189; - idMobLich = 190; - idMobPenguin = 191; - idMobLichMinion = 192; - idMobLoyalZombie = 193; - idMobTinyBird = 194; - idMobSquirrel = 195; - idMobBunny = 196; - idMobRaven = 197; - idMobQuestRam = 198; - idMobKobold = 199; - idMobBoggard = 201; - idMobMosquitoSwarm = 202; - idMobDeathTome = 203; - idMobMinotaur = 204; - idMobMinoshroom = 205; - idMobFireBeetle = 206; - idMobSlimeBeetle = 207; - idMobPinchBeetle = 208; - idMobMazeSlime = 209; - idMobRedcapSapper = 210; - idMobMistWolf = 211; - idMobKingSpider = 212; - idMobFirefly = 213; - idMobMiniGhast = 214; - idMobTowerGhast = 215; - idMobTowerGolem = 216; - idMobTowerTermite = 218; - idMobTowerBroodling = 219; - idMobTowerBoss = 217; - idMobBlockGoblin = 220; - idMobGoblinKnightUpper = 221; - idMobGoblinKnightLower = 222; - idMobHelmetCrab = 223; - idMobKnightPhantom = 224; - idMobYeti = 225; - idMobYetiBoss = 226; - idMobWinterWolf = 227; - idMobSnowGuardian = 228; - idMobStableIceCore = 229; - idMobUnstableIceCore = 230; - idMobSnowQueen = 231; - idMobTroll = 232; - idMobGiantMiner = 233; - idMobArmoredGiant = 234; - idMobIceCrystal = 235; - idMobHarbingerCube = 236; - idMobAdherent = 237; - - // biomes - idBiomeLake = configFile.get("biome", "biome.id.Lake", -1).getInt(); - idBiomeTwilightForest = configFile.get("biome", "biome.id.TwilightForest", -1).getInt(); - idBiomeTwilightForestVariant = configFile.get("biome", "biome.id.TwilightForestVariant", -1).getInt(); - idBiomeHighlands = configFile.get("biome", "biome.id.Highlands", -1).getInt(); - idBiomeMushrooms = configFile.get("biome", "biome.id.Mushrooms", -1).getInt(); - idBiomeSwamp = configFile.get("biome", "biome.id.Swamp", -1).getInt(); - idBiomeStream = configFile.get("biome", "biome.id.Stream", -1).getInt(); - idBiomeSnowfield = configFile.get("biome", "biome.id.Snowfield", -1).getInt(); - idBiomeGlacier = configFile.get("biome", "biome.id.Glacier", -1).getInt(); - idBiomeClearing = configFile.get("biome", "biome.id.Clearing", -1).getInt(); - idBiomeOakSavanna = configFile.get("biome", "biome.id.OakSavanna", -1).getInt(); - idBiomeFireflyForest = configFile.get("biome", "biome.id.LightedForest", -1).getInt(); - idBiomeDeepMushrooms = configFile.get("biome", "biome.id.DeepMushrooms", -1).getInt(); - idBiomeDarkForestCenter = configFile.get("biome", "biome.id.DarkForestCenter", -1).getInt(); - idBiomeHighlandsCenter = configFile.get("biome", "biome.id.HighlandsCenter", -1).getInt(); - idBiomeDarkForest = configFile.get("biome", "biome.id.DarkForest", -1).getInt(); - idBiomeEnchantedForest = configFile.get("biome", "biome.id.EnchantedForest", -1).getInt(); - idBiomeFireSwamp = configFile.get("biome", "biome.id.FireSwamp", -1).getInt(); - idBiomeThornlands = configFile.get("biome", "biome.id.Thornlands", -1).getInt(); - - if (configFile.hasChanged()) { - configFile.save(); - } + + public static ResourceLocation getGuiTexture(String name) { + return new ResourceLocation(ID, GUI_DIR + name); } - /** - * Write changed biome IDs back to the config file - */ - private void saveBiomeIds(Configuration config) { - config.get("biome", "biome.id.Lake", -1).set(idBiomeLake); - config.get("biome", "biome.id.TwilightForest", -1).set(idBiomeTwilightForest); - config.get("biome", "biome.id.TwilightForestVariant", -1).set(idBiomeTwilightForestVariant); - config.get("biome", "biome.id.Highlands", -1).set(idBiomeHighlands); - config.get("biome", "biome.id.Mushrooms", -1).set(idBiomeMushrooms); - config.get("biome", "biome.id.Swamp", -1).set(idBiomeSwamp); - config.get("biome", "biome.id.Stream", -1).set(idBiomeStream); - config.get("biome", "biome.id.Snowfield", -1).set(idBiomeSnowfield); - config.get("biome", "biome.id.Glacier", -1).set(idBiomeGlacier); - config.get("biome", "biome.id.Clearing", -1).set(idBiomeClearing); - config.get("biome", "biome.id.OakSavanna", -1).set(idBiomeOakSavanna); - config.get("biome", "biome.id.LightedForest", -1).set(idBiomeFireflyForest); - config.get("biome", "biome.id.DeepMushrooms", -1).set(idBiomeDeepMushrooms); - config.get("biome", "biome.id.DarkForestCenter", -1).set(idBiomeDarkForestCenter); - config.get("biome", "biome.id.HighlandsCenter", -1).set(idBiomeHighlandsCenter); - config.get("biome", "biome.id.DarkForest", -1).set(idBiomeDarkForest); - config.get("biome", "biome.id.EnchantedForest", -1).set(idBiomeEnchantedForest); - config.get("biome", "biome.id.FireSwamp", -1).set(idBiomeFireSwamp); - config.get("biome", "biome.id.Thornlands", -1).set(idBiomeThornlands); - - config.save(); + public static ResourceLocation getEnvTexture(String name) { + return new ResourceLocation(ID, ENVIRO_DIR + name); } - /** - * Change what dimension ID the Twilight Forest is. - * This is called when we connect to a server that has a different dimensionID set. - */ - public static void setDimensionID(int dim) - { - if (TwilightForestMod.dimensionID != dim) - { - FMLLog.info("[TwilightForest] Server has a different dimension ID (%d) for the Twilight Forest. Changing this on the client. This change will not be saved.", dim); - - DimensionManager.unregisterDimension(TwilightForestMod.dimensionID); - TwilightForestMod.dimensionID = dim; - DimensionManager.registerDimension(TwilightForestMod.dimensionID, TwilightForestMod.dimensionProviderID); - } + public static EnumRarity getRarity() { + return rarity != null ? rarity : EnumRarity.EPIC; } } diff --git a/src/main/java/twilightforest/advancements/ActivateGhastTrapTrigger.java b/src/main/java/twilightforest/advancements/ActivateGhastTrapTrigger.java new file mode 100644 index 0000000000..90240e2b52 --- /dev/null +++ b/src/main/java/twilightforest/advancements/ActivateGhastTrapTrigger.java @@ -0,0 +1,96 @@ +package twilightforest.advancements; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.Map; +import java.util.Set; + +public class ActivateGhastTrapTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("activate_ghast_trap"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + ActivateGhastTrapTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + ActivateGhastTrapTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public ActivateGhastTrapTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + return new ActivateGhastTrapTrigger.Instance(); + } + + public void trigger(EntityPlayerMP player) { + ActivateGhastTrapTrigger.Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(); + } + } + + public static class Instance extends AbstractCriterionInstance { + + public Instance() { + super(ActivateGhastTrapTrigger.ID); + } + } + + static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancementsIn) { + this.playerAdvancements = playerAdvancementsIn; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(Listener listener) { + this.listeners.add(listener); + } + + public void remove(Listener listener) { + this.listeners.remove(listener); + } + + public void trigger() { + for (Listener listener : Lists.newArrayList(this.listeners)) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/ArmorInventoryChangedTrigger.java b/src/main/java/twilightforest/advancements/ArmorInventoryChangedTrigger.java new file mode 100644 index 0000000000..71aeb0c323 --- /dev/null +++ b/src/main/java/twilightforest/advancements/ArmorInventoryChangedTrigger.java @@ -0,0 +1,124 @@ +package twilightforest.advancements; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.advancements.critereon.ItemPredicate; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ArmorInventoryChangedTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("armor_changed"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancements, Listener listener) { + Listeners listeners = this.listeners.computeIfAbsent(playerAdvancements, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancements, Listener listener) { + Listeners listeners = this.listeners.get(playerAdvancements); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancements); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancements) { + this.listeners.remove(playerAdvancements); + } + + @Override + public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + ItemPredicate from = ItemPredicate.deserialize(json.get("from")); + ItemPredicate to = ItemPredicate.deserialize(json.get("to")); + return new Instance(from, to); + } + + public void trigger(EntityPlayerMP player, ItemStack from, ItemStack to) { + Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(from, to); + } + } + + public static class Instance extends AbstractCriterionInstance { + + private final ItemPredicate from; + private final ItemPredicate to; + + public Instance(ItemPredicate from, ItemPredicate to) { + super(ArmorInventoryChangedTrigger.ID); + this.from = from; + this.to = to; + } + + public boolean test(ItemStack from, ItemStack to) { + return this.from.test(from) && this.to.test(to); + } + + @Override + public ResourceLocation getId() { + return ArmorInventoryChangedTrigger.ID; + } + } + + static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancementsIn) { + this.playerAdvancements = playerAdvancementsIn; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(Listener listener) { + this.listeners.add(listener); + } + + public void remove(Listener listener) { + this.listeners.remove(listener); + } + + public void trigger(ItemStack from, ItemStack to) { + + List> list = new ArrayList<>(); + + for (Listener listener : this.listeners) { + if (listener.getCriterionInstance().test(from, to)) { + list.add(listener); + } + } + + for (Listener listener : list) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/BlockPredicate.java b/src/main/java/twilightforest/advancements/BlockPredicate.java new file mode 100644 index 0000000000..28fe8839af --- /dev/null +++ b/src/main/java/twilightforest/advancements/BlockPredicate.java @@ -0,0 +1,144 @@ +package twilightforest.advancements; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.advancements.critereon.NBTPredicate; +import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.JsonUtils; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import javax.annotation.Nullable; +import java.util.HashSet; + +public class BlockPredicate { + public static final BlockPredicate ANY = new BlockPredicate(ImmutableSet.of(), Blocks.AIR, NBTPredicate.ANY) { + @Override public boolean test(World world, BlockPos pos) { return true; } + }; + private ImmutableSet propertyPredicates; + private final Block block; + private final NBTPredicate nbtPredicate; + + private BlockPredicate(ImmutableSet propertyPredicates, Block block, NBTPredicate nbt) { + this.propertyPredicates = propertyPredicates; + this.block = block; + this.nbtPredicate = nbt; + } + + public static BlockPredicate deserialize(@Nullable JsonElement element) { + if (element == null || element.isJsonNull()) + return ANY; + + JsonObject json = element.getAsJsonObject(); + + Block block = Block.REGISTRY.getObject(new ResourceLocation(JsonUtils.getString(json, "block"))); + BlockStateContainer container = block.getBlockState(); + HashSet> properties = new HashSet<>(); + + if (json.has("properties")) { + for (JsonElement propertyRawGroup : JsonUtils.getJsonArray(json, "properties")) { + JsonObject propertyGroup = propertyRawGroup.getAsJsonObject(); + + IProperty propertyKey = container.getProperty(JsonUtils.getString(propertyGroup, "property")); + + if (propertyKey != null) + createPropertyPredicateAndAddToSet( + properties, + propertyKey, + JsonUtils.getString(propertyGroup, "value"), + JsonUtils.getString(propertyGroup, "comparator") + ); + } + } + + NBTPredicate nbtPredicate = json.has("nbt") ? NBTPredicate.deserialize(json.get("nbt")) : NBTPredicate.ANY; + + return new BlockPredicate(new ImmutableSet.Builder().addAll(properties).build(), block, nbtPredicate); + } + + private static > void createPropertyPredicateAndAddToSet( + HashSet> predicateSet, + IProperty key, + String value, + String comparisonType) { + + Optional schrodingersVar = key.parseValue(value); + PropertyPredicate.ComparisonType predicateComparator = PropertyPredicate.ComparisonType.get(comparisonType); + + if (predicateComparator == null || !schrodingersVar.isPresent()) return; // Skip + + predicateSet.add(new PropertyPredicate<>(key, schrodingersVar.get(), predicateComparator)); + } + + public boolean test(World world, BlockPos pos) { + if (!test(world.getBlockState(pos))) // If BlockState check fails, we're done + return false; + + if (nbtPredicate == NBTPredicate.ANY) // Do we accept any NBT including lack thereof? + return true; + + TileEntity te = world.getTileEntity(pos); + + return te != null && nbtPredicate.test(te.serializeNBT()); + } + + private boolean test(IBlockState state) { + if (block != state.getBlock()) return false; // Not same block + + for (PropertyPredicate propertyPredicate : propertyPredicates) + if (!propertyPredicate.test(state)) + return false; + + return true; + } + + private static class PropertyPredicate> { + private final IProperty property; + private final T value; + private ComparisonType comparisonType; + + private PropertyPredicate(IProperty key, T value, ComparisonType comparisonType) { + this.property = key; + this.value = value; + this.comparisonType = comparisonType; + } + + private boolean test(IBlockState state) { + return state.getPropertyKeys().contains(property) && comparisonType.test(value, state.getValue(property)); + } + + private enum ComparisonType { + EQUAL { @Override > boolean test(T k, T v) { return k.compareTo(v) == 0; } }, + NOT { @Override > boolean test(T k, T v) { return k.compareTo(v) != 0; } }, + LESSER { @Override > boolean test(T k, T v) { return k.compareTo(v) < 0; } }, + GREATER { @Override > boolean test(T k, T v) { return k.compareTo(v) > 0; } }; + + abstract > boolean test(T key, T value); + + @Nullable + private static ComparisonType get(String type) { + switch (type) { + case "equal": + case "same": return EQUAL; + case "not": + case "different": + case "equaln't": return NOT; + case "lesser": + case "lesser_than": return LESSER; + case "greater": + case "greater_than": return GREATER; + } + + return null; + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/HasAdvancementTrigger.java b/src/main/java/twilightforest/advancements/HasAdvancementTrigger.java new file mode 100644 index 0000000000..1fc18829da --- /dev/null +++ b/src/main/java/twilightforest/advancements/HasAdvancementTrigger.java @@ -0,0 +1,115 @@ +package twilightforest.advancements; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.JsonUtils; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class HasAdvancementTrigger implements ICriterionTrigger { + + private static final ResourceLocation ID = TwilightForestMod.prefix("has_advancement"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + HasAdvancementTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, ICriterionTrigger.Listener listener) { + HasAdvancementTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + ResourceLocation advancementId = new ResourceLocation(JsonUtils.getString(json, "advancement")); + return new HasAdvancementTrigger.Instance(advancementId); + } + + public void trigger(EntityPlayerMP player, Advancement advancement) { + Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(advancement); + } + } + + static class Instance extends AbstractCriterionInstance { + + private final ResourceLocation advancementLocation; + + Instance(ResourceLocation advancementLocation) { + super(HasAdvancementTrigger.ID); + this.advancementLocation = advancementLocation; + } + + boolean test(Advancement advancement) { + return advancementLocation.equals(advancement.getId()); + } + } + + private static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + Listeners(PlayerAdvancements playerAdvancements) { + this.playerAdvancements = playerAdvancements; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(ICriterionTrigger.Listener listener) { + this.listeners.add(listener); + } + + public void remove(ICriterionTrigger.Listener listener) { + this.listeners.remove(listener); + } + + public void trigger(Advancement advancement) { + List> list = new ArrayList<>(); + + for (ICriterionTrigger.Listener listener : this.listeners) { + if (listener.getCriterionInstance().test(advancement)) { + list.add(listener); + } + } + + for (ICriterionTrigger.Listener listener : list) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/HydraChopTrigger.java b/src/main/java/twilightforest/advancements/HydraChopTrigger.java new file mode 100644 index 0000000000..2fff37924f --- /dev/null +++ b/src/main/java/twilightforest/advancements/HydraChopTrigger.java @@ -0,0 +1,94 @@ +package twilightforest.advancements; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.Map; +import java.util.Set; + +public class HydraChopTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("consume_hydra_chop_on_low_hunger"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + HydraChopTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + HydraChopTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public HydraChopTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + return new HydraChopTrigger.Instance(); + } + + public void trigger(EntityPlayerMP player) { + HydraChopTrigger.Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(); + } + } + + public static class Instance extends AbstractCriterionInstance { + public Instance() { + super(HydraChopTrigger.ID); + } + } + + static class Listeners { + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancementsIn) { + this.playerAdvancements = playerAdvancementsIn; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(Listener listener) { + this.listeners.add(listener); + } + + public void remove(Listener listener) { + this.listeners.remove(listener); + } + + public void trigger() { + for (Listener listener : Lists.newArrayList(this.listeners)) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/ItemUseTrigger.java b/src/main/java/twilightforest/advancements/ItemUseTrigger.java new file mode 100644 index 0000000000..db8ba648db --- /dev/null +++ b/src/main/java/twilightforest/advancements/ItemUseTrigger.java @@ -0,0 +1,124 @@ +package twilightforest.advancements; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.advancements.critereon.ItemPredicate; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.TwilightForestMod; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + THIS WILL ONLY WORK ON SPECIFIC ITEMS +*/ +public class ItemUseTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("on_item_use"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + ItemUseTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + ItemUseTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + ItemPredicate item = ItemPredicate.deserialize(json.get("item")); + BlockPredicate block = BlockPredicate.deserialize(json.get("block")); + return new ItemUseTrigger.Instance(item, block); + } + + public void trigger(EntityPlayerMP player, ItemStack item, World world, BlockPos pos) { + ItemUseTrigger.Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(item, world, pos); + } + } + + public static class Instance extends AbstractCriterionInstance { + + private final ItemPredicate item; + private final BlockPredicate block; + + public Instance(ItemPredicate item, BlockPredicate block) { + super(ItemUseTrigger.ID); + this.item = item; + this.block = block; + } + + public boolean test(ItemStack item, World world, BlockPos pos) { + return this.item.test(item) && this.block.test(world, pos); + } + } + + static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancements) { + this.playerAdvancements = playerAdvancements; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(Listener listener) { + this.listeners.add(listener); + } + + public void remove(Listener listener) { + this.listeners.remove(listener); + } + + public void trigger(ItemStack item, World world, BlockPos pos) { + + List> list = new ArrayList<>(); + + for (Listener listener : this.listeners) { + if (listener.getCriterionInstance().test(item, world, pos)) { + list.add(listener); + } + } + + for (Listener listener : list) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/MakePortalTrigger.java b/src/main/java/twilightforest/advancements/MakePortalTrigger.java new file mode 100644 index 0000000000..bfd6ca0484 --- /dev/null +++ b/src/main/java/twilightforest/advancements/MakePortalTrigger.java @@ -0,0 +1,96 @@ +package twilightforest.advancements; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import java.util.Map; +import java.util.Set; + +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +public class MakePortalTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("make_tf_portal"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, ICriterionTrigger.Listener listener) { + MakePortalTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, ICriterionTrigger.Listener listener) { + MakePortalTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public MakePortalTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + return new MakePortalTrigger.Instance(); + } + + public void trigger(EntityPlayerMP player) { + MakePortalTrigger.Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(); + } + } + + public static class Instance extends AbstractCriterionInstance { + + public Instance() { + super(MakePortalTrigger.ID); + } + } + + static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancementsIn) { + this.playerAdvancements = playerAdvancementsIn; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(ICriterionTrigger.Listener listener) { + this.listeners.add(listener); + } + + public void remove(ICriterionTrigger.Listener listener) { + this.listeners.remove(listener); + } + + public void trigger() { + for (ICriterionTrigger.Listener listener : Lists.newArrayList(this.listeners)) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/QuestRamCompletionTrigger.java b/src/main/java/twilightforest/advancements/QuestRamCompletionTrigger.java new file mode 100644 index 0000000000..0ae3635bfb --- /dev/null +++ b/src/main/java/twilightforest/advancements/QuestRamCompletionTrigger.java @@ -0,0 +1,96 @@ +package twilightforest.advancements; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.Map; +import java.util.Set; + +public class QuestRamCompletionTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("complete_quest_ram"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + QuestRamCompletionTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + QuestRamCompletionTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public QuestRamCompletionTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + return new QuestRamCompletionTrigger.Instance(); + } + + public void trigger(EntityPlayerMP player) { + QuestRamCompletionTrigger.Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(); + } + } + + public static class Instance extends AbstractCriterionInstance { + + public Instance() { + super(QuestRamCompletionTrigger.ID); + } + } + + static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancementsIn) { + this.playerAdvancements = playerAdvancementsIn; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(Listener listener) { + this.listeners.add(listener); + } + + public void remove(Listener listener) { + this.listeners.remove(listener); + } + + public void trigger() { + for (Listener listener : Lists.newArrayList(this.listeners)) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/StructureClearedTrigger.java b/src/main/java/twilightforest/advancements/StructureClearedTrigger.java new file mode 100644 index 0000000000..3f99a5e711 --- /dev/null +++ b/src/main/java/twilightforest/advancements/StructureClearedTrigger.java @@ -0,0 +1,115 @@ +package twilightforest.advancements; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.JsonUtils; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class StructureClearedTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("structure_cleared"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + StructureClearedTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + StructureClearedTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public StructureClearedTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + String structureName = JsonUtils.getString(json, "structure"); + return new StructureClearedTrigger.Instance(structureName); + } + + public void trigger(EntityPlayerMP player, String structureName) { + StructureClearedTrigger.Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(structureName); + } + } + + public static class Instance extends AbstractCriterionInstance { + + private final String structureName; + + public Instance(String structureName) { + super(StructureClearedTrigger.ID); + this.structureName = structureName; + } + + boolean test(String structureName) { + return this.structureName.equals(structureName); + } + } + + static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancementsIn) { + this.playerAdvancements = playerAdvancementsIn; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(Listener listener) { + this.listeners.add(listener); + } + + public void remove(Listener listener) { + this.listeners.remove(listener); + } + + public void trigger(String structureName) { + + List> list = new ArrayList<>(); + + for (ICriterionTrigger.Listener listener : this.listeners) { + if (listener.getCriterionInstance().test(structureName)) { + list.add(listener); + } + } + + for (ICriterionTrigger.Listener listener : list) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/TFAdvancements.java b/src/main/java/twilightforest/advancements/TFAdvancements.java new file mode 100644 index 0000000000..b445eef4fd --- /dev/null +++ b/src/main/java/twilightforest/advancements/TFAdvancements.java @@ -0,0 +1,17 @@ +package twilightforest.advancements; + +import net.minecraft.advancements.CriteriaTriggers; + +public class TFAdvancements { + public static final HasAdvancementTrigger ADVANCEMENT_UNLOCKED = CriteriaTriggers.register(new HasAdvancementTrigger()); + public static final MakePortalTrigger MADE_TF_PORTAL = CriteriaTriggers.register(new MakePortalTrigger()); + public static final HydraChopTrigger CONSUME_HYDRA_CHOP = CriteriaTriggers.register(new HydraChopTrigger()); + public static final QuestRamCompletionTrigger QUEST_RAM_COMPLETED = CriteriaTriggers.register(new QuestRamCompletionTrigger()); + public static final TrophyPedestalTrigger PLACED_TROPHY_ON_PEDESTAL = CriteriaTriggers.register(new TrophyPedestalTrigger()); + public static final ActivateGhastTrapTrigger ACTIVATED_GHAST_TRAP = CriteriaTriggers.register(new ActivateGhastTrapTrigger()); + public static final StructureClearedTrigger STRUCTURE_CLEARED = CriteriaTriggers.register(new StructureClearedTrigger()); + public static final ItemUseTrigger ITEM_USE_TRIGGER = CriteriaTriggers.register(new ItemUseTrigger()); + public static final ArmorInventoryChangedTrigger ARMOR_CHANGED = CriteriaTriggers.register(new ArmorInventoryChangedTrigger()); + + public static void init() {} +} diff --git a/src/main/java/twilightforest/advancements/TrophyPedestalTrigger.java b/src/main/java/twilightforest/advancements/TrophyPedestalTrigger.java new file mode 100644 index 0000000000..de3eea16d0 --- /dev/null +++ b/src/main/java/twilightforest/advancements/TrophyPedestalTrigger.java @@ -0,0 +1,96 @@ +package twilightforest.advancements; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import net.minecraft.advancements.ICriterionTrigger; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.advancements.critereon.AbstractCriterionInstance; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.Map; +import java.util.Set; + +public class TrophyPedestalTrigger implements ICriterionTrigger { + + public static final ResourceLocation ID = TwilightForestMod.prefix("placed_on_trophy_pedestal"); + private final Map listeners = Maps.newHashMap(); + + @Override + public ResourceLocation getId() { + return ID; + } + + @Override + public void addListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + TrophyPedestalTrigger.Listeners listeners = this.listeners.computeIfAbsent(playerAdvancementsIn, Listeners::new); + listeners.add(listener); + } + + @Override + public void removeListener(PlayerAdvancements playerAdvancementsIn, Listener listener) { + TrophyPedestalTrigger.Listeners listeners = this.listeners.get(playerAdvancementsIn); + if (listeners != null) { + listeners.remove(listener); + if (listeners.isEmpty()) { + this.listeners.remove(playerAdvancementsIn); + } + } + } + + @Override + public void removeAllListeners(PlayerAdvancements playerAdvancementsIn) { + this.listeners.remove(playerAdvancementsIn); + } + + @Override + public TrophyPedestalTrigger.Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { + return new TrophyPedestalTrigger.Instance(); + } + + public void trigger(EntityPlayerMP player) { + TrophyPedestalTrigger.Listeners listeners = this.listeners.get(player.getAdvancements()); + if (listeners != null) { + listeners.trigger(); + } + } + + public static class Instance extends AbstractCriterionInstance { + + public Instance() { + super(TrophyPedestalTrigger.ID); + } + } + + static class Listeners { + + private final PlayerAdvancements playerAdvancements; + private final Set> listeners = Sets.newHashSet(); + + public Listeners(PlayerAdvancements playerAdvancementsIn) { + this.playerAdvancements = playerAdvancementsIn; + } + + public boolean isEmpty() { + return this.listeners.isEmpty(); + } + + public void add(Listener listener) { + this.listeners.add(listener); + } + + public void remove(Listener listener) { + this.listeners.remove(listener); + } + + public void trigger() { + for (Listener listener : Lists.newArrayList(this.listeners)) { + listener.grantCriterion(this.playerAdvancements); + } + } + } +} diff --git a/src/main/java/twilightforest/advancements/package-info.java b/src/main/java/twilightforest/advancements/package-info.java new file mode 100644 index 0000000000..87cfd513b9 --- /dev/null +++ b/src/main/java/twilightforest/advancements/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.advancements; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/twilightforest/biomes/RegistryBiomeEvent.java b/src/main/java/twilightforest/biomes/RegistryBiomeEvent.java new file mode 100644 index 0000000000..e93430e5f4 --- /dev/null +++ b/src/main/java/twilightforest/biomes/RegistryBiomeEvent.java @@ -0,0 +1,270 @@ +package twilightforest.biomes; + +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biome.BiomeProperties; +import net.minecraftforge.common.BiomeDictionary; +import net.minecraftforge.common.BiomeDictionary.Type; +import net.minecraftforge.event.RegistryEvent.Register; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.registries.IForgeRegistry; +import twilightforest.TwilightForestMod; + +@EventBusSubscriber(modid = TwilightForestMod.ID) +public final class RegistryBiomeEvent { + + public static final Type TWILIGHT = Type.getType("TWILIGHT"); + + @SuppressWarnings("OverlyCoupledMethod") + @SubscribeEvent + public static void onRegisterBiomes(Register event) { + + final BiomeRegistry biomes = new BiomeRegistry(event.getRegistry()); + + biomes.register( + "twilight_lake", + new TFBiomeTwilightLake( + new BiomeProperties("Twilight Lake") + .setTemperature(0.66F) + .setRainfall(1) + .setBaseHeight(-1.8F) + .setHeightVariation(0.1F) + ), + TWILIGHT, Type.OCEAN + ); + + biomes.register( + "twilight_forest", + new TFBiomeBase( + new BiomeProperties("Twilight Forest") + ), + TWILIGHT, Type.FOREST + ); + + biomes.register( + "dense_twilight_forest", + new TFBiomeTwilightForestVariant( + new BiomeProperties("Dense Twilight Forest") + .setWaterColor(0x005522) + .setTemperature(0.7F) + .setRainfall(0.8F) + .setBaseHeight(0.2F) + .setHeightVariation(0.2F) + ), + TWILIGHT, Type.FOREST, Type.DENSE + ); + + biomes.register( + "twilight_highlands", + new TFBiomeHighlands( + new BiomeProperties("Twilight Highlands") + .setTemperature(0.4F) + .setRainfall(0.7F) + .setBaseHeight(3.5F) + .setHeightVariation(0.05F) + ), + TWILIGHT, Type.FOREST, Type.MOUNTAIN, Type.CONIFEROUS + ); + + biomes.register( + "mushroom_forest", + new TFBiomeMushrooms( + new BiomeProperties("Mushroom Forest") + .setTemperature(0.8F) + .setRainfall(0.8F) + ), + TWILIGHT, Type.FOREST, Type.MUSHROOM + ); + + biomes.register( + "twilight_swamp", + new TFBiomeSwamp( + new BiomeProperties("Twilight Swamp") + .setTemperature(0.8F) + .setRainfall(0.9F) + .setBaseHeight(-0.125F) + .setHeightVariation(0.125F) + .setWaterColor(0xE0FFAE) + ), + TWILIGHT, Type.SWAMP, Type.WET + ); + + biomes.register( + "twilight_stream", + new TFBiomeStream( + new BiomeProperties("Twilight Stream") + .setTemperature(0.5F) + .setRainfall(0.1F) + .setBaseHeight(-0.5F) + .setHeightVariation(0) + ), + TWILIGHT, Type.RIVER + ); + + biomes.register( + "snowy_forest", + new TFBiomeSnow( + new BiomeProperties("Snowy Forest") + .setTemperature(0.09F) + .setRainfall(0.9F) + .setBaseHeight(0.2F) + .setHeightVariation(0.2F) + ), + TWILIGHT, Type.FOREST, Type.SNOWY, Type.COLD, Type.CONIFEROUS + ); + + biomes.register( + "twilight_glacier", + new TFBiomeGlacier( + new BiomeProperties("Twilight Glacier") + .setTemperature(0) + .setRainfall(0.1F) + ), + TWILIGHT, Type.COLD, Type.SNOWY, Type.WASTELAND + ); + + biomes.register( + "twilight_clearing", + new TFBiomeClearing( + new BiomeProperties("Twilight Clearing") + .setTemperature(0.8F) + .setRainfall(0.4F) + .setBaseHeight(0.125F) + .setHeightVariation(0.05F) + ), + TWILIGHT, Type.PLAINS, Type.SPARSE + ); + + biomes.register( + "oak_savannah", + new TFBiomeOakSavanna( + new BiomeProperties("Oak Savanna") + .setTemperature(0.9F) + .setRainfall(0) + .setBaseHeight(0.2F) + .setHeightVariation(0.2F) + ), + TWILIGHT, Type.FOREST, Type.SPARSE + ); + + biomes.register( + "firefly_forest", + new TFBiomeFireflyForest( + new BiomeProperties("Firefly Forest") + .setTemperature(0.5F) + .setRainfall(1) + .setBaseHeight(0.125F) + .setHeightVariation(0.05F) + ), + TWILIGHT, Type.FOREST, Type.LUSH + ); + + biomes.register( + "deep_mushroom_forest", + new TFBiomeDeepMushrooms( + new BiomeProperties("Deep Mushroom Forest") + .setTemperature(0.8F) + .setRainfall(1) + .setBaseHeight(0.125F) + .setHeightVariation(0.05F) + ), + TWILIGHT, Type.FOREST, Type.MUSHROOM + ); + + biomes.register( + "dark_forest", + new TFBiomeDarkForest( + new BiomeProperties("Dark Forest") + .setTemperature(0.7F) + .setRainfall(0.8F) + .setBaseHeight(0.125F) + .setHeightVariation(0.05F) + ), + TWILIGHT, Type.FOREST, Type.DENSE, Type.SPOOKY + ); + + biomes.register( + "enchanted_forest", + new TFBiomeEnchantedForest( + new BiomeProperties("Enchanted Forest") + ), + TWILIGHT, Type.FOREST, Type.MAGICAL + ); + + biomes.register( + "fire_swamp", + new TFBiomeFireSwamp( + new BiomeProperties("Fire Swamp") + .setTemperature(1) + .setRainfall(0.4F) + .setWaterColor(0x6C2C2C) + .setBaseHeight(0.1F) + .setHeightVariation(0.2F) + ), + TWILIGHT, Type.SWAMP, Type.WASTELAND, Type.HOT + ); + + biomes.register( + "dark_forest_center", + new TFBiomeDarkForestCenter( + new BiomeProperties("Dark Forest Center") + .setBaseHeight(0.125F) + .setHeightVariation(0.05F) + ), + TWILIGHT, Type.FOREST, Type.DENSE, Type.SPOOKY, Type.MAGICAL + ); + + biomes.register( + "highlands_center", + new TFBiomeFinalPlateau( + new BiomeProperties("Final Plateau") + .setTemperature(0.3F) + .setRainfall(0.2F) + .setBaseHeight(10.5F) + .setHeightVariation(0.025F) + ), + TWILIGHT, Type.MESA, Type.DEAD, Type.DRY, Type.WASTELAND + ); + + biomes.register( + "thornlands", + new TFBiomeThornlands( + new BiomeProperties("Thornlands") + .setTemperature(0.3F) + .setRainfall(0.2F) + .setBaseHeight(6) + .setHeightVariation(0.1F) + ), + TWILIGHT, Type.HILLS, Type.DEAD, Type.DRY, Type.WASTELAND + ); + + biomes.register( + "spooky_forest", + new TFBiomeSpookyForest( + new BiomeProperties("Spooky Forest") + .setTemperature(0.5F) + .setRainfall(1) + .setBaseHeight(0.125F) + .setHeightVariation(0.05F) + .setWaterColor(0XFA9111) + ), + TWILIGHT, Type.FOREST, Type.DEAD, Type.DENSE, Type.SPOOKY + ); + } + + private static class BiomeRegistry { + + private final IForgeRegistry registry; + + BiomeRegistry(IForgeRegistry registry) { + + this.registry = registry; + } + + public void register(String registryName, Biome biome, Type... biomeTypes) { + biome.setRegistryName(TwilightForestMod.ID, registryName); + registry.register(biome); + BiomeDictionary.addTypes(biome, biomeTypes); + } + } +} diff --git a/src/main/java/twilightforest/biomes/TFBiomeBase.java b/src/main/java/twilightforest/biomes/TFBiomeBase.java index 5cc2f3922d..cc74f718aa 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeBase.java +++ b/src/main/java/twilightforest/biomes/TFBiomeBase.java @@ -1,12 +1,9 @@ package twilightforest.biomes; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.block.BlockSand; +import net.minecraft.block.BlockTallGrass; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.monster.EntitySkeleton; @@ -14,536 +11,231 @@ import net.minecraft.entity.monster.EntitySpider; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.passive.EntityBat; +import net.minecraft.entity.passive.EntityChicken; +import net.minecraft.entity.passive.EntityWolf; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.stats.Achievement; -import net.minecraft.stats.StatFileWriter; -import net.minecraft.stats.StatisticsFile; -import net.minecraft.util.MathHelper; -import net.minecraft.world.ColorizerFoliage; -import net.minecraft.world.ColorizerGrass; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeDecorator; -import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.gen.feature.WorldGenAbstractTree; -import net.minecraft.world.gen.feature.WorldGenBigMushroom; import net.minecraft.world.gen.feature.WorldGenBigTree; -import net.minecraft.world.gen.feature.WorldGenForest; +import net.minecraft.world.gen.feature.WorldGenBirchTree; import net.minecraft.world.gen.feature.WorldGenTallGrass; import net.minecraft.world.gen.feature.WorldGenerator; -import net.minecraftforge.common.BiomeDictionary; -import net.minecraftforge.common.BiomeDictionary.Type; -import twilightforest.TwilightForestMod; +import twilightforest.TFFeature; import twilightforest.entity.EntityTFKobold; -import twilightforest.entity.passive.EntityTFMobileFirefly; -import cpw.mods.fml.common.FMLLog; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - - -public abstract class TFBiomeBase extends BiomeGenBase { - - static - { - assignBlankBiomeIds(); - areThereBiomeIdConflicts(); - } - - public static final BiomeGenBase tfLake = (new TFBiomeTwilightLake(TwilightForestMod.idBiomeLake)).setColor(0x0000ff).setBiomeName("Twilight Lake").setHeight(height_DeepOceans); - public static final BiomeGenBase twilightForest = (new TFBiomeTwilightForest(TwilightForestMod.idBiomeTwilightForest)).setColor(0x005500).setBiomeName("Twilight Forest"); - public static final BiomeGenBase twilightForest2 = (new TFBiomeTwilightForestVariant(TwilightForestMod.idBiomeTwilightForestVariant)).setColor(0x005522).setBiomeName("Dense Twilight Forest").setHeight(height_MidPlains); - public static final BiomeGenBase highlands = (new TFBiomeHighlands(TwilightForestMod.idBiomeHighlands)).setColor(0x556644).setBiomeName("Twilight Highlands").setHeight(new Height(3.5F, 0.05F)); - public static final BiomeGenBase mushrooms = (new TFBiomeMushrooms(TwilightForestMod.idBiomeMushrooms)).setColor(0x226622).setBiomeName("Mushroom Forest"); - public static final BiomeGenBase tfSwamp = (new TFBiomeSwamp(TwilightForestMod.idBiomeSwamp)).setColor(0x334422).setBiomeName("Twilight Swamp").setHeight(new Height(-0.125F, 0.125F)); - public static final BiomeGenBase stream = (new TFBiomeStream(TwilightForestMod.idBiomeStream)).setColor(0x3253b7).setBiomeName("Twilight Stream").setHeight(height_ShallowWaters); - public static final BiomeGenBase tfSnow = (new TFBiomeSnow(TwilightForestMod.idBiomeSnowfield)).setColor(0xccffff).setBiomeName("Snowy Forest").setHeight(height_MidPlains); - public static final BiomeGenBase glacier = (new TFBiomeGlacier(TwilightForestMod.idBiomeGlacier)).setColor(0x7777bb).setBiomeName("Twilight Glacier"); - public static final BiomeGenBase clearing = (new TFBiomeClearing(TwilightForestMod.idBiomeClearing)).setColor(0x349b34).setBiomeName("Twilight Clearing").setHeight(height_LowPlains); - public static final BiomeGenBase oakSavanna = (new TFBiomeOakSavanna(TwilightForestMod.idBiomeOakSavanna)).setColor(0x446622).setBiomeName("Oak Savanna").setHeight(height_MidPlains); - public static final BiomeGenBase fireflyForest = (new TFBiomeFireflyForest(TwilightForestMod.idBiomeFireflyForest)).setColor(0x006633).setBiomeName("Firefly Forest").setHeight(height_LowPlains); - public static final BiomeGenBase deepMushrooms = (new TFBiomeDeepMushrooms(TwilightForestMod.idBiomeDeepMushrooms)).setColor(0x663322).setBiomeName("Deep Mushroom Forest").setHeight(height_LowPlains); - public static final BiomeGenBase darkForest = (new TFBiomeDarkForest(TwilightForestMod.idBiomeDarkForest)).setColor(0x003311).setBiomeName("Dark Forest").setHeight(height_LowPlains); - public static final BiomeGenBase enchantedForest = (new TFBiomeEnchantedForest(TwilightForestMod.idBiomeEnchantedForest)).setColor(0x115566).setBiomeName("Enchanted Forest"); - public static final BiomeGenBase fireSwamp = (new TFBiomeFireSwamp(TwilightForestMod.idBiomeFireSwamp)).setColor(0x42231a).setBiomeName("Fire Swamp").setHeight(height_Default); - public static final BiomeGenBase darkForestCenter = (new TFBiomeDarkForestCenter(TwilightForestMod.idBiomeDarkForestCenter)).setColor(0x002200).setBiomeName("Dark Forest Center").setHeight(height_LowPlains); - public static final BiomeGenBase highlandsCenter = (new TFBiomeFinalPlateau(TwilightForestMod.idBiomeHighlandsCenter)).setColor(0x334422).setBiomeName("Highlands Center").setHeight(new Height(10.5F, 0.025F)); - public static final BiomeGenBase thornlands = (new TFBiomeThornlands(TwilightForestMod.idBiomeThornlands)).setColor(0x223322).setBiomeName("Thornlands").setHeight(new Height(6F, 0.1F)); - - protected WorldGenBigMushroom bigMushroomGen; - protected WorldGenForest birchGen; - - /** - * Holds the classes of IMobs (hostile mobs) that can be spawned in the biome. - */ - protected List undergroundMonsterList; - - @SuppressWarnings("unchecked") - public TFBiomeBase(int i) - { - super(i); - - bigMushroomGen = new WorldGenBigMushroom(); - birchGen = new WorldGenForest(false, false); - - // try to stop world leaks - this.worldGeneratorBigTree = null; - - // remove normal monster spawns - spawnableMonsterList.clear(); - // remove squids - spawnableWaterCreatureList.clear(); - // custom creature list. - spawnableCreatureList.clear(); - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFBighorn.class, 12, 4, 4)); - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFBoar.class, 10, 4, 4)); - spawnableCreatureList.add(new SpawnListEntry(net.minecraft.entity.passive.EntityChicken.class, 10, 4, 4)); - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFDeer.class, 15, 4, 5)); - spawnableCreatureList.add(new SpawnListEntry(net.minecraft.entity.passive.EntityWolf.class, 5, 4, 4)); - - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFTinyBird.class, 15, 4, 8)); - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFSquirrel.class, 10, 2, 4)); - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFBunny.class, 10, 4, 5)); - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFRaven.class, 10, 1, 2)); - - undergroundMonsterList = new ArrayList(); - - undergroundMonsterList.add(new SpawnListEntry(EntitySpider.class, 10, 4, 4)); - undergroundMonsterList.add(new SpawnListEntry(EntityZombie.class, 10, 4, 4)); - undergroundMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 10, 4, 4)); - undergroundMonsterList.add(new SpawnListEntry(EntityCreeper.class, 1, 4, 4)); - undergroundMonsterList.add(new SpawnListEntry(EntitySlime.class, 10, 4, 4)); - undergroundMonsterList.add(new SpawnListEntry(EntityEnderman.class, 1, 1, 4)); +import twilightforest.entity.passive.*; +import twilightforest.util.PlayerHelper; +import twilightforest.world.ChunkGeneratorTFBase; +import twilightforest.world.TFWorld; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class TFBiomeBase extends Biome { + + protected final WorldGenAbstractTree birchGen = new WorldGenBirchTree(false, false); + + protected final List undergroundMonsterList = new ArrayList<>(); + + protected final ResourceLocation[] requiredAdvancements = getRequiredAdvancements(); + + public final TFFeature containedFeature = getContainedFeature(); + + public TFBiomeBase(BiomeProperties props) { + super(props); + + // remove normal monster spawns + spawnableMonsterList.clear(); + // remove squids + spawnableWaterCreatureList.clear(); + // custom creature list. + spawnableCreatureList.clear(); + spawnableCreatureList.add(new SpawnListEntry(EntityTFBighorn.class, 12, 4, 4)); + spawnableCreatureList.add(new SpawnListEntry(EntityTFBoar.class, 10, 4, 4)); + spawnableCreatureList.add(new SpawnListEntry(EntityChicken.class, 10, 4, 4)); + spawnableCreatureList.add(new SpawnListEntry(EntityTFDeer.class, 15, 4, 5)); + spawnableCreatureList.add(new SpawnListEntry(EntityWolf.class, 5, 4, 4)); + + spawnableCreatureList.add(new SpawnListEntry(EntityTFTinyBird.class, 15, 4, 8)); + spawnableCreatureList.add(new SpawnListEntry(EntityTFSquirrel.class, 10, 2, 4)); + spawnableCreatureList.add(new SpawnListEntry(EntityTFBunny.class, 10, 4, 5)); + spawnableCreatureList.add(new SpawnListEntry(EntityTFRaven.class, 10, 1, 2)); + + undergroundMonsterList.add(new SpawnListEntry(EntitySpider.class, 10, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntityZombie.class, 10, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 10, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntityCreeper.class, 1, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntitySlime.class, 10, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntityEnderman.class, 1, 1, 4)); undergroundMonsterList.add(new SpawnListEntry(EntityTFKobold.class, 10, 4, 8)); - this.spawnableCaveCreatureList.clear(); - this.spawnableCaveCreatureList.add(new BiomeGenBase.SpawnListEntry(EntityBat.class, 10, 8, 8)); - this.spawnableCaveCreatureList.add(new SpawnListEntry(EntityTFMobileFirefly.class, 10, 8, 8)); - - getTFBiomeDecorator().setTreesPerChunk(10); - getTFBiomeDecorator().setGrassPerChunk(2); + spawnableCaveCreatureList.clear(); + spawnableCaveCreatureList.add(new SpawnListEntry(EntityBat.class, 10, 8, 8)); + spawnableCaveCreatureList.add(new SpawnListEntry(EntityTFMobileFirefly.class, 10, 8, 8)); + + getTFBiomeDecorator().setTreesPerChunk(10); + getTFBiomeDecorator().setGrassPerChunk(2); } - + @Override - public TFBiomeBase setColor(int par1) { - return (TFBiomeBase) super.setColor(par1); - } - - - /** - * returns the chance a creature has to spawn. - */ - @Override - public float getSpawningChance() - { - // okay, 20% more animals - return 0.12F; - } - - /** - * Allocate a new BiomeDecorator for this BiomeGenBase - */ - @Override - public BiomeDecorator createBiomeDecorator() - { - return new TFBiomeDecorator(); - } - - protected TFBiomeDecorator getTFBiomeDecorator() { - return (TFBiomeDecorator)this.theBiomeDecorator; - } - - /** - * Forest trees all over - * - * used to be getRandomWorldGenForTrees() - */ - public WorldGenAbstractTree func_150567_a(Random random) - { - if(random.nextInt(5) == 0) - { - return birchGen; - } - if(random.nextInt(10) == 0) - { - return new WorldGenBigTree(false); - } else - { - return worldGeneratorTrees; - } - } - - /** - * Ferns! - */ - public WorldGenerator getRandomWorldGenForGrass(Random par1Random) - { - if (par1Random.nextInt(4) == 0) - { - return new WorldGenTallGrass(Blocks.tallgrass, 2); - } - else - { - return new WorldGenTallGrass(Blocks.tallgrass, 1); - } - } - - /** - * If any biome IDs are -1, find an open ID for them. - */ - public static boolean assignBlankBiomeIds() { - boolean assigned = false; - - boolean[] usedIDs = new boolean[BiomeGenBase.getBiomeGenArray().length]; - - checkUsedIDs(usedIDs); - - TwilightForestMod.idBiomeLake = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeLake); - TwilightForestMod.idBiomeTwilightForest = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeTwilightForest); - TwilightForestMod.idBiomeTwilightForestVariant = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeTwilightForestVariant); - TwilightForestMod.idBiomeHighlands = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeHighlands); - TwilightForestMod.idBiomeMushrooms = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeMushrooms); - TwilightForestMod.idBiomeSwamp = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeSwamp); - TwilightForestMod.idBiomeStream = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeStream); - TwilightForestMod.idBiomeSnowfield = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeSnowfield); - TwilightForestMod.idBiomeGlacier = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeGlacier); - TwilightForestMod.idBiomeClearing = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeClearing); - TwilightForestMod.idBiomeOakSavanna = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeOakSavanna); - TwilightForestMod.idBiomeFireflyForest = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeFireflyForest); - TwilightForestMod.idBiomeDeepMushrooms = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeDeepMushrooms); - TwilightForestMod.idBiomeDarkForestCenter = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeDarkForestCenter); - TwilightForestMod.idBiomeHighlandsCenter = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeHighlandsCenter); - TwilightForestMod.idBiomeDarkForest = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeDarkForest); - TwilightForestMod.idBiomeEnchantedForest = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeEnchantedForest); - TwilightForestMod.idBiomeFireSwamp = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeFireSwamp); - TwilightForestMod.idBiomeThornlands = assignIdIfNeeded(usedIDs, TwilightForestMod.idBiomeThornlands); - - return assigned; + public float getSpawningChance() { + // okay, 20% more animals + return 0.12F; } - /** - * Populate the array with whether there is a biome using that ID - */ - private static void checkUsedIDs(boolean[] usedIDs) { - for (int i = 0; i < usedIDs.length; i++) { - usedIDs[i] = (BiomeGenBase.getBiomeGenArray()[i] != null); + @Override + public TFBiomeDecorator createBiomeDecorator() { + return new TFBiomeDecorator(); + } + + protected TFBiomeDecorator getTFBiomeDecorator() { + return (TFBiomeDecorator) this.decorator; + } + + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(5) == 0) { + return birchGen; + } else if (random.nextInt(10) == 0) { + return new WorldGenBigTree(false); + } else { + return TREE_FEATURE; } } - /** - * Return a new biome ID if the given id is -1 - */ - private static int assignIdIfNeeded(boolean[] usedIDs, int biomeID) { - if (biomeID == -1) { - biomeID = findNextOpenBiomeId(usedIDs); - TwilightForestMod.hasAssignedBiomeID = true; + @Override + public WorldGenerator getRandomWorldGenForGrass(Random random) { + if (random.nextInt(4) == 0) { + return new WorldGenTallGrass(BlockTallGrass.EnumType.FERN); + } else { + return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); } - - return biomeID; } - /** - * Find an open biome ID - */ - private static int findNextOpenBiomeId(boolean[] usedIDs) { - for (int i = 0; i < 256; i++) { - if (!usedIDs[i]) { - usedIDs[i] = true; - return i; + @Override + public void genTerrainBlocks(World world, Random rand, ChunkPrimer primer, int x, int z, double noiseVal) { + this.genTwilightBiomeTerrain(world, rand, primer, x, z, noiseVal); + } + + // Copy of super's generateBiomeTerrain, relevant edits noted. + protected void genTwilightBiomeTerrain(World world, Random rand, ChunkPrimer primer, int x, int z, double noiseVal) { + int i = TFWorld.SEALEVEL; // TF - set sea level to 31 + IBlockState iblockstate = this.topBlock; + IBlockState iblockstate1 = this.fillerBlock; + IBlockState stoneReplacement = getStoneReplacementState(); // TF - Replace stone + int j = -1; + int k = (int) (noiseVal / 3.0D + 3.0D + rand.nextDouble() * 0.25D); + int l = x & 15; + int i1 = z & 15; + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + boolean generateBedrock = shouldGenerateBedrock(world); // TF - conditional bedrock gen + + for (int j1 = 255; j1 >= 0; --j1) { + // TF - conditional bedrock gen + if (generateBedrock && j1 <= rand.nextInt(5)) { + primer.setBlockState(i1, j1, l, BEDROCK); + } else { + IBlockState iblockstate2 = primer.getBlockState(i1, j1, l); + + // TF - use block check for air + if (iblockstate2.getBlock() == Blocks.AIR) { + // j = -1; TF - commented out? todo 1.9 + } else if (iblockstate2.getBlock() == Blocks.STONE) { + if (j == -1) { + if (k <= 0) { + iblockstate = AIR; + iblockstate1 = STONE; + } else if (j1 >= i - 4 && j1 <= i + 1) { + iblockstate = this.topBlock; + iblockstate1 = this.fillerBlock; + } + + // TF - use block check for air + if (j1 < i && (iblockstate == null || iblockstate.getBlock() == Blocks.AIR)) { + if (this.getTemperature(blockpos$mutableblockpos.setPos(x, j1, z)) < 0.15F) { + iblockstate = ICE; + } else { + iblockstate = WATER; + } + } + + j = k; + + if (j1 >= i - 1) { + primer.setBlockState(i1, j1, l, iblockstate); + } else if (j1 < i - 7 - k) { + iblockstate = AIR; + iblockstate1 = STONE; + primer.setBlockState(i1, j1, l, GRAVEL); + } else { + primer.setBlockState(i1, j1, l, iblockstate1); + } + } else if (j > 0) { + --j; + primer.setBlockState(i1, j1, l, iblockstate1); + + if (j == 0 && iblockstate1.getBlock() == Blocks.SAND) { + j = rand.nextInt(4) + Math.max(0, j1 - 63); + iblockstate1 = iblockstate1.getValue(BlockSand.VARIANT) == BlockSand.EnumType.RED_SAND ? RED_SANDSTONE : SANDSTONE; + } + } else if (stoneReplacement != null) { + // TF - Replace stone + primer.setBlockState(i1, j1, l, stoneReplacement); + } + } } } - - // Uh oh... - FMLLog.warning("[TwilightForest] Could not find open biome ID. Edit the Twilight Forest config to give all biomes unique IDs."); - return -1; } - /** - * Check all of our biome IDs. If there is a biome in them that is not null and does not inherit from TFBiomeBase, make a warning. - */ - public static boolean areThereBiomeIdConflicts() - { - boolean conflict = TwilightForestMod.hasBiomeIdConflicts; - - //FMLLog.info("[TwilightForest] Starting biome conflict detection. Conflict = " + conflict); - - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeLake); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeTwilightForest); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeTwilightForestVariant); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeHighlands); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeMushrooms); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeSwamp); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeStream); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeSnowfield); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeGlacier); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeClearing); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeOakSavanna); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeFireflyForest); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeDeepMushrooms); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeDarkForestCenter); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeHighlandsCenter); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeDarkForest); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeEnchantedForest); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeFireSwamp); - conflict |= isConflictAtBiomeID(TwilightForestMod.idBiomeThornlands); - - if (conflict) { - FMLLog.warning("[TwilightForest] Biome ID conflict detected. Edit the Twilight Forest config to give all biomes unique IDs."); - } else { - //FMLLog.info("[TwilightForest] No biome ID conflicts detected! You're safe!"); - } - - TwilightForestMod.hasBiomeIdConflicts |= conflict; - - return conflict; - } - - /** - * Check the ID for conflicts - */ - public static boolean isConflictAtBiomeID(int id) { - BiomeGenBase biomeAt = BiomeGenBase.getBiome(id); - - if (biomeAt == null || biomeAt instanceof TFBiomeBase) { - //FMLLog.warning("[TwilightForest] Biome ID %d contains a biome named %s.", id, biomeAt); - return false; - } else { - FMLLog.warning("[TwilightForest] Biome ID conflict. Biome ID %d contains a biome named %s, but Twilight Forest is set to use that ID.", id, biomeAt.biomeName); - return true; - } + private static boolean shouldGenerateBedrock(World world) { + ChunkGeneratorTFBase generator = TFWorld.getChunkGenerator(world); + return generator == null || generator.shouldGenerateBedrock(); } - + /** - * Register our biomes with the Forge biome dictionary + * Return a block if you want it to replace stone in the terrain generation */ - public static void registerWithBiomeDictionary() - { - BiomeDictionary.registerBiomeType(tfLake, Type.OCEAN); - BiomeDictionary.registerBiomeType(twilightForest, Type.FOREST); - BiomeDictionary.registerBiomeType(twilightForest2, Type.FOREST, Type.DENSE); - BiomeDictionary.registerBiomeType(highlands, Type.FOREST, Type.MOUNTAIN, Type.CONIFEROUS); - BiomeDictionary.registerBiomeType(mushrooms, Type.FOREST, Type.MUSHROOM); - BiomeDictionary.registerBiomeType(tfSwamp, Type.SWAMP, Type.WET); - BiomeDictionary.registerBiomeType(stream, Type.RIVER); - BiomeDictionary.registerBiomeType(tfSnow, Type.FOREST, Type.SNOWY, Type.COLD, Type.CONIFEROUS); - BiomeDictionary.registerBiomeType(glacier, Type.COLD, Type.SNOWY, Type.WASTELAND); - BiomeDictionary.registerBiomeType(clearing, Type.PLAINS, Type.SPARSE); - BiomeDictionary.registerBiomeType(oakSavanna, Type.FOREST, Type.SPARSE); - BiomeDictionary.registerBiomeType(fireflyForest, Type.FOREST, Type.LUSH); - BiomeDictionary.registerBiomeType(deepMushrooms, Type.FOREST, Type.MUSHROOM); - BiomeDictionary.registerBiomeType(darkForest, Type.FOREST, Type.DENSE, Type.SPOOKY); - BiomeDictionary.registerBiomeType(enchantedForest, Type.FOREST, Type.MAGICAL); - BiomeDictionary.registerBiomeType(fireSwamp, Type.SWAMP, Type.WASTELAND, Type.HOT); - BiomeDictionary.registerBiomeType(darkForestCenter, Type.FOREST, Type.DENSE, Type.SPOOKY, Type.MAGICAL); - BiomeDictionary.registerBiomeType(highlandsCenter, Type.MESA, Type.DEAD, Type.DRY, Type.WASTELAND); - BiomeDictionary.registerBiomeType(thornlands, Type.HILLS, Type.DEAD, Type.DRY, Type.WASTELAND); - } - - -// /** -// * Provides the basic grass color based on the biome temperature and rainfall -// */ -// @SideOnly(Side.CLIENT) -// @Override -// public int getBiomeGrassColor(int x, int y, int z) -// { -// // I hate to be grumpy, but using events for this is a waste of memory and GC resources -// double d0 = (double)MathHelper.clamp_float(this.getFloatTemperature(x, y, z), 0.0F, 1.0F); -// double d1 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); -// return ColorizerGrass.getGrassColor(d0, d1); -// } - -// /** -// * Provides the basic foliage color based on the biome temperature and rainfall -// */ -// @SideOnly(Side.CLIENT) -// @Override -// public int getBiomeFoliageColor(int x, int y, int z) -// { -// // I hate to be grumpy, but using events for this is a waste of memory and GC resources -// double d0 = (double)MathHelper.clamp_float(this.getFloatTemperature(x, y, z), 0.0F, 1.0F); -// double d1 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); -// return ColorizerFoliage.getFoliageColor(d0, d1); -// } - - -// @SideOnly(Side.CLIENT) -// public int getWaterColorMultiplier() -// { -// // I hate to be grumpy, but using events for this is a waste of memory and GC resources -// return this.waterColorMultiplier; -// } - - public void genTerrainBlocks(World world, Random rand, Block[] blockStorage, byte[] metaStorage, int x, int z, double stoneNoise) - { - this.genTwilightBiomeTerrain(world, rand, blockStorage, metaStorage, x, z, stoneNoise); - } - - /** - * This is just the biome terrain gen function modified to have sea level at 32 instead of 64 - */ - public void genTwilightBiomeTerrain(World world, Random rand, Block[] blockStorage, byte[] metaStorage, int x, int z, double stoneNoise) - { - Block topBlock = this.topBlock; - byte topMeta = (byte)(this.field_150604_aj & 255); - Block fillerBlock = this.fillerBlock; - byte fillerMeta = (byte)(this.field_76754_C & 255); - int currentFillerDepth = -1; - int maxFillerDepth = (int)(stoneNoise / 3.0D + 3.0D + rand.nextDouble() * 0.25D); - int maskX = x & 15; - int maskZ = z & 15; - int worldHeight = blockStorage.length / 256; - - int seaLevel = 32; - - for (int y = 255; y >= 0; --y) - { - int index = (maskZ * 16 + maskX) * worldHeight + y; - - if (y <= 0 + rand.nextInt(5)) - { - blockStorage[index] = Blocks.bedrock; - } - else - { - Block currentBlock = blockStorage[index]; - - if (currentBlock != null && currentBlock.getMaterial() != Material.air) - { - if (currentBlock == Blocks.stone) - { - // ADDED STONE REPLACEMENT - if (this.getStoneReplacementBlock() != null) { - blockStorage[index] = this.getStoneReplacementBlock(); - metaStorage[index] = this.getStoneReplacementMeta(); - } - - if (currentFillerDepth == -1) - { - if (maxFillerDepth <= 0) - { - topBlock = null; - topMeta = 0; - fillerBlock = Blocks.stone; - fillerMeta = 0; - } - else if (y >= (seaLevel - 5) && y <= seaLevel) - { - topBlock = this.topBlock; - topMeta = (byte)(this.field_150604_aj & 255); - fillerBlock = this.fillerBlock; - fillerMeta = (byte)(this.field_76754_C & 255); - } - - if (y < (seaLevel - 1) && (topBlock == null || topBlock.getMaterial() == Material.air)) - { - if (this.getFloatTemperature(x, y, z) < 0.15F) - { - topBlock = Blocks.ice; - topMeta = 0; - } - else - { - topBlock = Blocks.water; - topMeta = 0; - } - } - - currentFillerDepth = maxFillerDepth; - - if (y >= (seaLevel - 2)) - { - blockStorage[index] = topBlock; - metaStorage[index] = topMeta; - } - else if (y < (seaLevel - 8) - maxFillerDepth) - { - topBlock = null; - fillerBlock = Blocks.stone; - fillerMeta = 0; - blockStorage[index] = Blocks.gravel; - } - else - { - blockStorage[index] = fillerBlock; - metaStorage[index] = fillerMeta; - } - } - else if (currentFillerDepth > 0) - { - --currentFillerDepth; - blockStorage[index] = fillerBlock; - metaStorage[index] = fillerMeta; - - if (currentFillerDepth == 0 && fillerBlock == Blocks.sand) - { - currentFillerDepth = rand.nextInt(4) + Math.max(0, y - (seaLevel - 1)); - fillerBlock = Blocks.sandstone; - fillerMeta = 0; - } - } - } - } - else - { - //currentFillerDepth = -1; - } - } - } - } - - /** - * Return a block if you want it to replace stone in the terrain generation - */ - public Block getStoneReplacementBlock() { + @Nullable + public IBlockState getStoneReplacementState() { return null; } - - /** - * Metadata for the stone replacement block - */ - public byte getStoneReplacementMeta() { - return 0; - } /** - * Does the player have the achievement needed to be in this biome? - * Defaults to true for no achievement required biomes. + * Does the player have the advancements needed to be in this biome? */ - public boolean doesPlayerHaveRequiredAchievement(EntityPlayer player) { - - if (getRequiredAchievement() != null && player instanceof EntityPlayerMP && ((EntityPlayerMP)player).func_147099_x() != null) { - StatisticsFile stats = ((EntityPlayerMP)player).func_147099_x(); - - return stats.hasAchievementUnlocked(this.getRequiredAchievement()); - } else if (getRequiredAchievement() != null && player instanceof EntityClientPlayerMP && ((EntityClientPlayerMP)player).getStatFileWriter() != null) { - StatFileWriter stats = ((EntityClientPlayerMP)player).getStatFileWriter(); - - return stats.hasAchievementUnlocked(this.getRequiredAchievement()); - } else { - return true; - } + public boolean doesPlayerHaveRequiredAdvancements(EntityPlayer player) { + return PlayerHelper.doesPlayerHaveRequiredAdvancements(player, requiredAdvancements); + } + + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[0]; } /** - * If there is a required achievement to be here, return it, otherwise return null + * Do something bad to a player in the wrong biome. */ - protected Achievement getRequiredAchievement() { - return null; + public void enforceProgression(EntityPlayer player, World world) {} + + protected void trySpawnHintMonster(EntityPlayer player, World world) { + if (world.rand.nextInt(4) == 0) { + containedFeature.trySpawnHintMonster(world, player); + } + } + + protected TFFeature getContainedFeature() { + return TFFeature.NOTHING; } /** - * Do something bad to a player in the wrong biome. + * Returns the list of underground creatures. */ - public void enforceProgession(EntityPlayer player, World world) { - ; + public List getUndergroundSpawnableList(EnumCreatureType type) { + return type == EnumCreatureType.MONSTER ? this.undergroundMonsterList : getSpawnableList(type); } - - /** - * Returns the list of underground creatures. - */ - public List getUndergroundSpawnableList() { - return this.undergroundMonsterList; - } } - diff --git a/src/main/java/twilightforest/biomes/TFBiomeCenter.java b/src/main/java/twilightforest/biomes/TFBiomeCenter.java deleted file mode 100644 index 944e608276..0000000000 --- a/src/main/java/twilightforest/biomes/TFBiomeCenter.java +++ /dev/null @@ -1,14 +0,0 @@ -package twilightforest.biomes; - - - -public class TFBiomeCenter extends TFBiomeBase { - - public TFBiomeCenter(int i) { - super(i); - -// this.topBlock = (byte) Blocks.stone; -// this.fillerBlock = (byte) Blocks.stone; - } - -} diff --git a/src/main/java/twilightforest/biomes/TFBiomeCenter2.java b/src/main/java/twilightforest/biomes/TFBiomeCenter2.java deleted file mode 100644 index b903f2abfa..0000000000 --- a/src/main/java/twilightforest/biomes/TFBiomeCenter2.java +++ /dev/null @@ -1,14 +0,0 @@ -package twilightforest.biomes; - - - -public class TFBiomeCenter2 extends TFBiomeBase { - - public TFBiomeCenter2(int i) { - super(i); - -// this.topBlock = (byte) Blocks.stone; -// this.fillerBlock = (byte) Blocks.stone; - } - -} diff --git a/src/main/java/twilightforest/biomes/TFBiomeClearing.java b/src/main/java/twilightforest/biomes/TFBiomeClearing.java index 7f14fccf3c..9264ec1d98 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeClearing.java +++ b/src/main/java/twilightforest/biomes/TFBiomeClearing.java @@ -1,36 +1,25 @@ package twilightforest.biomes; -import java.util.Random; - -import net.minecraft.init.Blocks; +import net.minecraft.block.BlockTallGrass; import net.minecraft.world.gen.feature.WorldGenTallGrass; import net.minecraft.world.gen.feature.WorldGenerator; +import java.util.Random; public class TFBiomeClearing extends TFBiomeBase { - public TFBiomeClearing(int i) { - super(i); - - this.temperature = 0.8F; - this.rainfall = 0.4F; - -// this.rootHeight = 0.01F; -// this.heightVariation = 0F; + public TFBiomeClearing(BiomeProperties props) { + super(props); - getTFBiomeDecorator().canopyPerChunk = -999; + getTFBiomeDecorator().hasCanopy = false; getTFBiomeDecorator().setTreesPerChunk(-999); - + getTFBiomeDecorator().setFlowersPerChunk(4); getTFBiomeDecorator().setGrassPerChunk(10); } - /** - * No ferns - */ - public WorldGenerator getRandomWorldGenForGrass(Random par1Random) - { - return new WorldGenTallGrass(Blocks.tallgrass, 1); - } - + @Override + public WorldGenerator getRandomWorldGenForGrass(Random random) { + return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeDarkForest.java b/src/main/java/twilightforest/biomes/TFBiomeDarkForest.java index 0a025f274b..1a19b1e958 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeDarkForest.java +++ b/src/main/java/twilightforest/biomes/TFBiomeDarkForest.java @@ -1,167 +1,128 @@ package twilightforest.biomes; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockOldLeaf; +import net.minecraft.block.BlockOldLog; +import net.minecraft.block.BlockPlanks; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntityWitch; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.potion.Potion; +import net.minecraft.init.Blocks; +import net.minecraft.init.MobEffects; import net.minecraft.potion.PotionEffect; -import net.minecraft.stats.Achievement; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.ColorizerFoliage; import net.minecraft.world.ColorizerGrass; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeDecorator; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenShrub; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; import twilightforest.entity.EntityTFKingSpider; import twilightforest.entity.EntityTFKobold; import twilightforest.entity.EntityTFMistWolf; import twilightforest.entity.EntityTFSkeletonDruid; - +import java.util.ArrayList; +import java.util.List; +import java.util.Random; public class TFBiomeDarkForest extends TFBiomeBase { - + private static final int MONSTER_SPAWN_RATE = 20; - Random monsterRNG; - ArrayList emptyList = new ArrayList(); - @SuppressWarnings("unchecked") - public TFBiomeDarkForest(int i) { - super(i); - - this.temperature = 0.7F; - this.rainfall = 0.8F; + private final Random monsterRNG = new Random(53439L); + + public TFBiomeDarkForest(BiomeProperties props) { + super(props); getTFBiomeDecorator().canopyPerChunk = 5.5F; - + getTFBiomeDecorator().setTreesPerChunk(10); getTFBiomeDecorator().setGrassPerChunk(-99); getTFBiomeDecorator().setFlowersPerChunk(-99); - getTFBiomeDecorator().setMushroomsPerChunk(2); - getTFBiomeDecorator().setDeadBushPerChunk(10); - - - this.rootHeight = 0.05F; - this.heightVariation = 0.05F; - - this.monsterRNG = new Random(); - - this.spawnableMonsterList.add(new SpawnListEntry(EntityEnderman.class, 1, 1, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityZombie.class, 5, 1, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 5, 1, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityTFMistWolf.class, 10, 1, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityTFSkeletonDruid.class, 10, 1, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityTFKingSpider.class, 10, 1, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityTFKobold.class, 10, 4, 8)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityWitch.class, 1, 1, 1)); - - this.theBiomeDecorator.generateLakes = false; + getTFBiomeDecorator().setMushroomsPerChunk(2); + getTFBiomeDecorator().setDeadBushPerChunk(10); + + this.spawnableMonsterList.add(new SpawnListEntry(EntityEnderman.class, 1, 1, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityZombie.class, 5, 1, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 5, 1, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityTFMistWolf.class, 10, 1, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityTFSkeletonDruid.class, 10, 1, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityTFKingSpider.class, 10, 1, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityTFKobold.class, 10, 4, 8)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityWitch.class, 1, 1, 1)); + + this.decorator.generateFalls = false; + } + + @Override + public TFBiomeDecorator createBiomeDecorator() { + return new TFDarkForestBiomeDecorator(); + } + + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(5) == 0) { + return new WorldGenShrub( + Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE), + Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK).withProperty(BlockLeaves.CHECK_DECAY, false) + ); + } else if (random.nextInt(8) == 0) { + return this.birchGen; + } else { + return TREE_FEATURE; + } + } + + @Override + public int getGrassColorAtPos(BlockPos pos) { + double temperature = (double) MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); + double humidity = (double) MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); + return ((ColorizerGrass.getGrassColor(temperature, humidity) & 0xFEFEFE) + 0x1E0E4E) / 2; } - - /** - * We have our own decorator since we have strange generation - */ - public BiomeDecorator createBiomeDecorator() - { - return new TFDarkForestBiomeDecorator(); - } - - /** - * Occasional shrub, no big trees - */ - public WorldGenAbstractTree func_150567_a(Random random) - { - if(random.nextInt(5) == 0) - { - return new WorldGenShrub(3, 0); - } - if(random.nextInt(8) == 0) - { - return this.birchGen; - } - else { - return worldGeneratorTrees; - } - } - - /** - * Provides the basic grass color based on the biome temperature and rainfall - */ - @Override - public int getBiomeGrassColor(int x, int y, int z) - { - double var1 = (double)MathHelper.clamp_float(this.getFloatTemperature(x, y, z), 0.0F, 1.0F); - double var3 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); - return ((ColorizerGrass.getGrassColor(var1, var3) & 0xFEFEFE) + 0x1E0E4E) / 2; - -// return 0x554114; - } - - /** - * Provides the basic foliage color based on the biome temperature and rainfall - */ - @Override - public int getBiomeFoliageColor(int x, int y, int z) - { - double var1 = (double)MathHelper.clamp_float(this.getFloatTemperature(x, y, z), 0.0F, 1.0F); - double var3 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); - return ((ColorizerFoliage.getFoliageColor(var1, var3) & 0xFEFEFE) + 0x1E0E4E) / 2; - } - - - /** - * Returns the correspondent list of the EnumCreatureType informed. - */ - @SuppressWarnings("rawtypes") + + @Override + public int getFoliageColorAtPos(BlockPos pos) { + double temperature = (double) MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); + double humidity = (double) MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); + return ((ColorizerFoliage.getFoliageColor(temperature, humidity) & 0xFEFEFE) + 0x1E0E4E) / 2; + } + @Override - public List getSpawnableList(EnumCreatureType par1EnumCreatureType) - { - // if is is monster, then only give it the real list 1/MONSTER_SPAWN_RATE of the time - if (par1EnumCreatureType == EnumCreatureType.monster) { - return monsterRNG.nextInt(MONSTER_SPAWN_RATE) == 0 ? this.spawnableMonsterList : emptyList; - } - else { - return par1EnumCreatureType == EnumCreatureType.creature ? this.spawnableCreatureList : (par1EnumCreatureType == EnumCreatureType.waterCreature ? this.spawnableWaterCreatureList : (par1EnumCreatureType == EnumCreatureType.ambient ? this.spawnableCaveCreatureList : null)); - } - } - - /** - * This just seems to act as a fire discouragement - */ + public List getSpawnableList(EnumCreatureType creatureType) { + // if it is monster, then only give it the real list 1/MONSTER_SPAWN_RATE of the time + if (creatureType == EnumCreatureType.MONSTER) { + return monsterRNG.nextInt(MONSTER_SPAWN_RATE) == 0 ? this.spawnableMonsterList : new ArrayList<>(); + } + return super.getSpawnableList(creatureType); + } + @Override public boolean isHighHumidity() { return true; } - - - /** - * If there is a required achievement to be here, return it, otherwise return null - */ - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressHydra; + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_lich") }; } - /** - * Do something bad to a player in the wrong biome. - */ - public void enforceProgession(EntityPlayer player, World world) { - if (!world.isRemote && world.getWorldTime() % 60 == 0) { - player.addPotionEffect(new PotionEffect(Potion.blindness.id, 100, 0)); - - // hint monster? - if (world.rand.nextInt(4) == 0) { - TFFeature.tfStronghold.trySpawnHintMonster(world, player); - } + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 60 == 0) { + player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 100, 0)); + trySpawnHintMonster(player, world); } } + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.KNIGHT_STRONGHOLD; + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeDarkForestCenter.java b/src/main/java/twilightforest/biomes/TFBiomeDarkForestCenter.java index 25df5dfa03..18e9c14aac 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeDarkForestCenter.java +++ b/src/main/java/twilightforest/biomes/TFBiomeDarkForestCenter.java @@ -1,29 +1,36 @@ package twilightforest.biomes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + public class TFBiomeDarkForestCenter extends TFBiomeDarkForest { - public TFBiomeDarkForestCenter(int i) { - super(i); + public TFBiomeDarkForestCenter(BiomeProperties props) { + super(props); + } + + @Override + public int getGrassColorAtPos(BlockPos pos) { + double d0 = GRASS_COLOR_NOISE.getValue(pos.getX() * 0.0225D, pos.getZ() * 0.0225D); + return d0 < -0.2D ? 0x667540 : 0x554114; + } + + @Override + public int getFoliageColorAtPos(BlockPos pos) { + double d0 = GRASS_COLOR_NOISE.getValue(pos.getX() * 0.0225D, pos.getZ() * 0.0225D); + return d0 < -0.1D ? 0xf9821e : 0xe94e14; + } + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_knights") }; + } + + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.DARK_TOWER; } - - - /** - * Provides the basic grass color based on the biome temperature and rainfall - */ - @Override - public int getBiomeGrassColor(int x, int y, int z) - { - double d0 = plantNoise.func_151601_a((double)x * 0.0225D, (double)z * 0.0225D); - return d0 < -0.2D ? 0x667540 : 0x554114; - } - - /** - * Provides the basic foliage color based on the biome temperature and rainfall - */ - @Override - public int getBiomeFoliageColor(int x, int y, int z) - { - double d0 = plantNoise.func_151601_a((double)x * 0.0225D, (double)z * 0.0225D); - return d0 < -0.1D ? 0xf9821e : 0xe94e14; - } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeDecorator.java b/src/main/java/twilightforest/biomes/TFBiomeDecorator.java index 52bbf69ab5..471d8d3cbf 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeDecorator.java +++ b/src/main/java/twilightforest/biomes/TFBiomeDecorator.java @@ -1,131 +1,95 @@ package twilightforest.biomes; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockStone; import net.minecraft.init.Blocks; import net.minecraft.util.WeightedRandom; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.BiomeDecorator; -import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.gen.ChunkGeneratorSettings; import net.minecraft.world.gen.feature.WorldGenLakes; import net.minecraft.world.gen.feature.WorldGenLiquids; +import net.minecraft.world.gen.feature.WorldGenMinable; +import net.minecraft.world.gen.feature.WorldGenerator; +import twilightforest.TFConfig; import twilightforest.TFFeature; -import twilightforest.TwilightForestMod; -import twilightforest.world.TFGenCanopyMushroom; -import twilightforest.world.TFGenCanopyTree; -import twilightforest.world.TFGenFallenHollowLog; -import twilightforest.world.TFGenFallenSmallLog; -import twilightforest.world.TFGenFoundation; -import twilightforest.world.TFGenGroveRuins; -import twilightforest.world.TFGenTorchBerries; -import twilightforest.world.TFGenHollowStump; -import twilightforest.world.TFGenHollowTree; -import twilightforest.world.TFGenMangroveTree; -import twilightforest.world.TFGenMonolith; -import twilightforest.world.TFGenMyceliumBlob; -import twilightforest.world.TFGenOutsideStalagmite; -import twilightforest.world.TFGenPlantRoots; -import twilightforest.world.TFGenStoneCircle; -import twilightforest.world.TFGenWell; -import twilightforest.world.TFGenWitchHut; -import twilightforest.world.TFGenWoodRoots; -import twilightforest.world.TFGenerator; -import twilightforest.world.TFTreeGenerator; - +import twilightforest.features.GenDruidHut; +import twilightforest.world.feature.*; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.function.Supplier; public class TFBiomeDecorator extends BiomeDecorator { - - TFGenCanopyTree canopyTreeGen; - TFTreeGenerator alternateCanopyGen; - TFGenHollowTree hollowTreeGen; - TFGenMyceliumBlob myceliumBlobGen; - WorldGenLakes extraLakeGen; - WorldGenLakes extraLavaPoolGen; - TFGenMangroveTree mangroveTreeGen; - - TFGenPlantRoots plantRootGen; - TFGenWoodRoots woodRootGen; - WorldGenLiquids caveWaterGen; - TFGenTorchBerries torchBerryGen; - - public float canopyPerChunk; - public float alternateCanopyChance; - public int myceliumPerChunk; - public int mangrovesPerChunk; - public int lakesPerChunk; - public float lavaPoolChance; - - static final List ruinList = new ArrayList(); - static { - // make list of ruins - ruinList.add(new RuinEntry(new TFGenStoneCircle(), 10)); - ruinList.add(new RuinEntry(new TFGenWell(), 10)); - ruinList.add(new RuinEntry(new TFGenWitchHut(), 5)); - ruinList.add(new RuinEntry(new TFGenOutsideStalagmite(), 12)); - ruinList.add(new RuinEntry(new TFGenFoundation(), 10)); - ruinList.add(new RuinEntry(new TFGenMonolith(), 10)); - ruinList.add(new RuinEntry(new TFGenGroveRuins(), 5)); - ruinList.add(new RuinEntry(new TFGenHollowStump(), 12)); - ruinList.add(new RuinEntry(new TFGenFallenHollowLog(), 10)); - ruinList.add(new RuinEntry(new TFGenFallenSmallLog(), 10)); - } - - /** - * WeightedRandomItem for making the minor features - */ - static class RuinEntry extends WeightedRandom.Item - { - public final TFGenerator generator; - public RuinEntry(TFGenerator generator, int weight) - { - super(weight); - this.generator = generator; - } - } - - - public TFBiomeDecorator() { - super(); - - canopyTreeGen = new TFGenCanopyTree(); - alternateCanopyGen = new TFGenCanopyMushroom(); - mangroveTreeGen = new TFGenMangroveTree(); - myceliumBlobGen = new TFGenMyceliumBlob(5); - hollowTreeGen = new TFGenHollowTree(); - extraLakeGen = new WorldGenLakes(Blocks.water); - extraLavaPoolGen = new WorldGenLakes(Blocks.lava); - - plantRootGen = new TFGenPlantRoots(); - woodRootGen = new TFGenWoodRoots(); - caveWaterGen = new WorldGenLiquids(Blocks.flowing_water); - torchBerryGen = new TFGenTorchBerries(); - - canopyPerChunk = TwilightForestMod.canopyCoverage; - alternateCanopyChance = 0; - myceliumPerChunk = 0; - lakesPerChunk = 0; - lavaPoolChance = 0; - mangrovesPerChunk = 0; + + WorldGenerator canopyTreeGen = new TFGenCanopyTree(); + WorldGenerator alternateCanopyGen = new TFGenCanopyMushroom(); + + //private final WorldGenerator hollowTreeGen = new TFGenHollowTree(); + private final WorldGenerator myceliumBlobGen = new TFGenMyceliumBlob(5); + private final WorldGenerator extraLakeGen = new WorldGenLakes(Blocks.WATER); + private final WorldGenerator extraLavaPoolGen = new WorldGenLakes(Blocks.LAVA); + private final WorldGenerator mangroveTreeGen = new TFGenMangroveTree(); + private final WorldGenerator plantRootGen = new TFGenPlantRoots(); + private final WorldGenerator woodRootGen = new TFGenWoodRoots(); + private final WorldGenerator caveWaterGen = new WorldGenLiquids(Blocks.FLOWING_WATER); + private final WorldGenerator torchBerryGen = new TFGenTorchBerries(); + + public float canopyPerChunk = TFConfig.performance.canopyCoverage; + public boolean hasCanopy = true; + public float alternateCanopyChance = 0f; + public int myceliumPerChunk = 0; + public int mangrovesPerChunk = 0; + public int lakesPerChunk = 0; + public float lavaPoolChance = 0f; + + private static final List ruinList = new ArrayList<>(); + + static { + // make list of ruins + addRuin(TFGenStoneCircle::new , TFConfig.dimension.worldGenWeights.stoneCircleWeight ); + addRuin(TFGenWell::new , TFConfig.dimension.worldGenWeights.wellWeight ); + addRuin(TFGenOutsideStalagmite::new, TFConfig.dimension.worldGenWeights.stalagmiteWeight ); + addRuin(TFGenFoundation::new , TFConfig.dimension.worldGenWeights.foundationWeight ); + addRuin(TFGenMonolith::new , TFConfig.dimension.worldGenWeights.monolithWeight ); + addRuin(TFGenGroveRuins::new , TFConfig.dimension.worldGenWeights.groveRuinsWeight ); + addRuin(TFGenHollowStump::new , TFConfig.dimension.worldGenWeights.hollowStumpWeight ); + addRuin(TFGenFallenHollowLog::new , TFConfig.dimension.worldGenWeights.fallenHollowLogWeight); + addRuin(TFGenFallenSmallLog::new , TFConfig.dimension.worldGenWeights.fallenSmallLogWeight ); + + addRuin(GenDruidHut::new , TFConfig.dimension.worldGenWeights.druidHutWeight ); + } + + private static void addRuin(Supplier generator, int weight) { + if (weight > 0) { + ruinList.add(new RuinEntry(generator.get(), weight)); + } + } + + private static class RuinEntry extends WeightedRandom.Item { + + public final TFGenerator generator; + + RuinEntry(TFGenerator generator, int weight) { + super(weight); + this.generator = generator; + } } - /** - * Decorates the world. Calls code that was formerly (pre-1.8) in ChunkProviderGenerate.populate - */ @Override - public void decorateChunk(World world, Random rand, BiomeGenBase biome, int mapX, int mapZ) - { + public void decorate(World world, Random rand, Biome biome, BlockPos pos) { - // check for features - TFFeature nearFeature = TFFeature.getNearestFeature(mapX >> 4, mapZ >> 4, world); + // check for features + TFFeature nearFeature = TFFeature.getNearestFeature(pos.getX() >> 4, pos.getZ() >> 4, world); - if (!nearFeature.areChunkDecorationsEnabled) { - // no normal decorations here, these parts supply their own decorations. - decorateUnderground(world, rand, mapX, mapZ); - decorateOnlyOres(world, rand, mapX, mapZ); - } else { + if (!nearFeature.areChunkDecorationsEnabled) { + // no normal decorations here, these parts supply their own decorations. + decorateUnderground(world, rand, pos); + decorateOnlyOres(world, rand, pos); + } else { // // hollow trees! // if (rand.nextInt(24) == 0) { // int rx = mapX + rand.nextInt(16) + 8; @@ -133,184 +97,176 @@ public void decorateChunk(World world, Random rand, BiomeGenBase biome, int mapX // int ry = world.getHeightValue(rx, rz); // hollowTreeGen.generate(world, rand, rx, ry, rz); // } - - // regular decorations - this.currentWorld = null; // suppress "Already decorating" error. I'm fairly sure that this mod does not cause this on its own, but cross-mod interactions seem to. - super.decorateChunk(world, rand, biome, mapX, mapZ); - - } - - } - - /** - * The method that does the work of actually decorating chunks - */ - protected void genDecorations(BiomeGenBase biome) - { - - // random features! - if(randomGenerator.nextInt(6) == 0) - { - int rx = chunk_X + randomGenerator.nextInt(16) + 8; - int rz = chunk_Z + randomGenerator.nextInt(16) + 8; - int ry = currentWorld.getHeightValue(rx, rz); - TFGenerator rf = randomFeature(randomGenerator); - if (rf.generate(currentWorld, randomGenerator, rx, ry, rz)) - { -// System.out.println(rf + " success at " + rx + ", " + ry + ", " + rz); - } - } - - // add canopy trees - int nc = (int)canopyPerChunk + ((randomGenerator.nextFloat() < (canopyPerChunk - (int)canopyPerChunk)) ? 1 : 0); - for (int i = 0; i < nc; i++) { - int rx = chunk_X + randomGenerator.nextInt(16) + 8; - int rz = chunk_Z + randomGenerator.nextInt(16) + 8; - int ry = currentWorld.getHeightValue(rx, rz); - if (this.alternateCanopyChance > 0 && randomGenerator.nextFloat() <= alternateCanopyChance) { - alternateCanopyGen.generate(currentWorld, randomGenerator, rx, ry, rz); - } else { - canopyTreeGen.generate(currentWorld, randomGenerator, rx, ry, rz); - } - } - - // mangrove trees - for (int i = 0; i < mangrovesPerChunk; i++) { - int rx = chunk_X + randomGenerator.nextInt(16) + 8; - int rz = chunk_Z + randomGenerator.nextInt(16) + 8; - int ry = currentWorld.getHeightValue(rx, rz); - mangroveTreeGen.generate(currentWorld, randomGenerator, rx, ry, rz); - } - // add extra lakes for swamps - for (int i = 0; i < lakesPerChunk; i++) { - int rx = chunk_X + randomGenerator.nextInt(16) + 8; - int rz = chunk_Z + randomGenerator.nextInt(16) + 8; - int ry = currentWorld.getHeightValue(rx, rz); - extraLakeGen.generate(currentWorld, randomGenerator, rx, ry, rz); - } - - // add extra lava for fire swamps - if (randomGenerator.nextFloat() <= lavaPoolChance) { - int rx = chunk_X + randomGenerator.nextInt(16) + 8; - int rz = chunk_Z + randomGenerator.nextInt(16) + 8; - int ry = currentWorld.getHeightValue(rx, rz); - extraLavaPoolGen.generate(currentWorld, randomGenerator, rx, ry, rz); - } - - // mycelium blobs - for (int i = 0; i < myceliumPerChunk; i++) { - int rx = chunk_X + randomGenerator.nextInt(16) + 8; - int rz = chunk_Z + randomGenerator.nextInt(16) + 8; - int ry = currentWorld.getHeightValue(rx, rz); - myceliumBlobGen.generate(currentWorld, randomGenerator, rx, ry, rz); - } - - super.genDecorations(biome); - - decorateUnderground(currentWorld, randomGenerator, chunk_X, chunk_Z); - - - } - - /** - * Generate the Twilight Forest underground decorations - */ - protected void decorateUnderground(World world, Random rand, int mapX, int mapZ) { + + // regular decorations + super.decorate(world, rand, biome, pos); + } + } + + @Override + protected void genDecorations(Biome biome, World world, Random randomGenerator) { + // random features! + if (randomGenerator.nextInt(6) == 0) { + int rx = chunkPos.getX() + randomGenerator.nextInt(14) + 8; + int rz = chunkPos.getZ() + randomGenerator.nextInt(14) + 8; + TFGenerator rf = randomFeature(randomGenerator); + if (rf != null) { + rf.generate(world, randomGenerator, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + } + + if (this.hasCanopy) { + //TODO: is there a better place for this? We want to load this value once the config file is loaded. + this.canopyPerChunk = TFConfig.performance.canopyCoverage; + + // add canopy trees + int nc = (int) canopyPerChunk + ((randomGenerator.nextFloat() < (canopyPerChunk - (int) canopyPerChunk)) ? 1 : 0); + for (int i = 0; i < nc; i++) { + int rx = chunkPos.getX() + randomGenerator.nextInt(16) + 8; + int rz = chunkPos.getZ() + randomGenerator.nextInt(16) + 8; + BlockPos genPos = new BlockPos(rx, world.getHeight(rx, rz), rz); + if (alternateCanopyChance > 0 && randomGenerator.nextFloat() < alternateCanopyChance) { + alternateCanopyGen.generate(world, randomGenerator, genPos); + } else { + canopyTreeGen.generate(world, randomGenerator, genPos); + } + } + } + + // mangrove trees + for (int i = 0; i < mangrovesPerChunk; i++) { + int rx = chunkPos.getX() + randomGenerator.nextInt(16) + 8; + int rz = chunkPos.getZ() + randomGenerator.nextInt(16) + 8; + mangroveTreeGen.generate(world, randomGenerator, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + // add extra lakes for swamps + for (int i = 0; i < lakesPerChunk; i++) { + int rx = chunkPos.getX() + randomGenerator.nextInt(16) + 8; + int rz = chunkPos.getZ() + randomGenerator.nextInt(16) + 8; + extraLakeGen.generate(world, randomGenerator, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + + // add extra lava for fire swamps + if (randomGenerator.nextFloat() < lavaPoolChance) { + int rx = chunkPos.getX() + randomGenerator.nextInt(16) + 8; + int rz = chunkPos.getZ() + randomGenerator.nextInt(16) + 8; + extraLavaPoolGen.generate(world, randomGenerator, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + + // mycelium blobs + for (int i = 0; i < myceliumPerChunk; i++) { + int rx = chunkPos.getX() + randomGenerator.nextInt(16) + 8; + int rz = chunkPos.getZ() + randomGenerator.nextInt(16) + 8; + myceliumBlobGen.generate(world, randomGenerator, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + + super.genDecorations(biome, world, randomGenerator); + decorateUnderground(world, randomGenerator, chunkPos); + } + + /** + * Generate the Twilight Forest underground decorations + */ + protected void decorateUnderground(World world, Random rand, BlockPos pos) { // generate roots - for (int i = 0; i < 12; ++i) - { - int rx = mapX + rand.nextInt(16) + 8; - byte ry = 64; - int rz = mapZ + rand.nextInt(16) + 8; - plantRootGen.generate(world, rand, rx, ry, rz); + for (int i = 0; i < 12; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int ry = 64; + int rz = pos.getZ() + rand.nextInt(16) + 8; + plantRootGen.generate(world, rand, new BlockPos(rx, ry, rz)); } // generate roots - for (int i = 0; i < 20; ++i) - { - int rx = mapX + rand.nextInt(16) + 8; - int ry = rand.nextInt(64); - int rz = mapZ + rand.nextInt(16) + 8; - woodRootGen.generate(world, rand, rx, ry, rz); + for (int i = 0; i < 20; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int ry = rand.nextInt(64); + int rz = pos.getZ() + rand.nextInt(16) + 8; + woodRootGen.generate(world, rand, new BlockPos(rx, ry, rz)); } - + // extra underground water sources - if (this.generateLakes) { - for (int i = 0; i < 50; ++i) - { - int rx = mapX + rand.nextInt(16) + 8; + if (this.generateFalls) { + for (int i = 0; i < 50; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; int ry = rand.nextInt(24) + 4; - int rz = mapZ + rand.nextInt(16) + 8; - caveWaterGen.generate(world, rand, rx, ry, rz); + int rz = pos.getZ() + rand.nextInt(16) + 8; + caveWaterGen.generate(world, rand, new BlockPos(rx, ry, rz)); } } - - // torch berries are almost guaranteed to spawn so we don't need many - for (int i = 0; i < 3; ++i) - { - int rx = mapX + rand.nextInt(16) + 8; - int ry = 64; - int rz = mapZ + rand.nextInt(16) + 8; - torchBerryGen.generate(world, rand, rx, ry, rz); - } + + // torch berries are almost guaranteed to spawn so we don't need many + for (int i = 0; i < 3; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int ry = 64; + int rz = pos.getZ() + rand.nextInt(16) + 8; + torchBerryGen.generate(world, rand, new BlockPos(rx, ry, rz)); + } } - + /** * Generates ores only */ - public void decorateOnlyOres(World world, Random rand, int mapX, int mapZ) { - this.currentWorld = world; - this.randomGenerator = rand; - this.chunk_X = mapX; - this.chunk_Z = mapZ; - this.generateOres(); - this.currentWorld = null; - this.randomGenerator = null; + public void decorateOnlyOres(World world, Random rand, BlockPos pos) { + this.chunkPos = pos; + if (this.chunkProviderSettings == null) { + this.chunkProviderSettings = ChunkGeneratorSettings.Factory.jsonToFactory(world.getWorldInfo().getGeneratorOptions()).build(); + this.chunkPos = pos; + this.dirtGen = new WorldGenMinable(Blocks.DIRT.getDefaultState(), this.chunkProviderSettings.dirtSize); + this.gravelOreGen = new WorldGenMinable(Blocks.GRAVEL.getDefaultState(), this.chunkProviderSettings.gravelSize); + this.graniteGen = new WorldGenMinable(Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.GRANITE), this.chunkProviderSettings.graniteSize); + this.dioriteGen = new WorldGenMinable(Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.DIORITE), this.chunkProviderSettings.dioriteSize); + this.andesiteGen = new WorldGenMinable(Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.ANDESITE), this.chunkProviderSettings.andesiteSize); + this.coalGen = new WorldGenMinable(Blocks.COAL_ORE.getDefaultState(), this.chunkProviderSettings.coalSize); + this.ironGen = new WorldGenMinable(Blocks.IRON_ORE.getDefaultState(), this.chunkProviderSettings.ironSize); + this.goldGen = new WorldGenMinable(Blocks.GOLD_ORE.getDefaultState(), this.chunkProviderSettings.goldSize); + this.redstoneGen = new WorldGenMinable(Blocks.REDSTONE_ORE.getDefaultState(), this.chunkProviderSettings.redstoneSize); + this.diamondGen = new WorldGenMinable(Blocks.DIAMOND_ORE.getDefaultState(), this.chunkProviderSettings.diamondSize); + this.lapisGen = new WorldGenMinable(Blocks.LAPIS_ORE.getDefaultState(), this.chunkProviderSettings.lapisSize); + } + this.generateOres(world, rand); + } + + /** + * Gets a random feature suitable for the current biome. + */ + @Nullable + public TFGenerator randomFeature(Random rand) { + return ruinList.isEmpty() ? null : WeightedRandom.getRandomItem(rand, ruinList).generator; } - /** - * Gets a random feature suitible to the current biome. - */ - public TFGenerator randomFeature(Random rand) - { - return ((RuinEntry)WeightedRandom.getRandomItem(rand, ruinList)).generator; - } - - public void setTreesPerChunk(int treesPerChunk) { - this.treesPerChunk = treesPerChunk; - } - - public void setBigMushroomsPerChunk(int bigMushroomsPerChunk) { - this.bigMushroomsPerChunk = bigMushroomsPerChunk; - } - - public void setClayPerChunk(int clayPerChunk) { - this.clayPerChunk = clayPerChunk; - } - - public void setDeadBushPerChunk(int deadBushPerChunk) { - this.deadBushPerChunk = deadBushPerChunk; - } - - public void setMushroomsPerChunk(int mushroomsPerChunk) { - this.mushroomsPerChunk = mushroomsPerChunk; - } - - public void setFlowersPerChunk(int flowersPerChunk) { - this.flowersPerChunk = flowersPerChunk; - } - - public void setReedsPerChunk(int reedsPerChunk) { - this.reedsPerChunk = reedsPerChunk; - } - - public void setWaterlilyPerChunk(int waterlilyPerChunk) { - this.waterlilyPerChunk = waterlilyPerChunk; - } - - public void setGrassPerChunk(int grassPerChunk) { - this.grassPerChunk = grassPerChunk; - } - - + public void setTreesPerChunk(int treesPerChunk) { + this.treesPerChunk = treesPerChunk; + } + + public void setBigMushroomsPerChunk(int bigMushroomsPerChunk) { + this.bigMushroomsPerChunk = bigMushroomsPerChunk; + } + + public void setClayPerChunk(int clayPerChunk) { + this.clayPerChunk = clayPerChunk; + } + + public void setDeadBushPerChunk(int deadBushPerChunk) { + this.deadBushPerChunk = deadBushPerChunk; + } + + public void setMushroomsPerChunk(int mushroomsPerChunk) { + this.mushroomsPerChunk = mushroomsPerChunk; + } + + public void setFlowersPerChunk(int flowersPerChunk) { + this.flowersPerChunk = flowersPerChunk; + } + + public void setReedsPerChunk(int reedsPerChunk) { + this.reedsPerChunk = reedsPerChunk; + } + + public void setWaterlilyPerChunk(int waterlilyPerChunk) { + this.waterlilyPerChunk = waterlilyPerChunk; + } + + public void setGrassPerChunk(int grassPerChunk) { + this.grassPerChunk = grassPerChunk; + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeDeepMushrooms.java b/src/main/java/twilightforest/biomes/TFBiomeDeepMushrooms.java index 71525b61a9..d183a24bfb 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeDeepMushrooms.java +++ b/src/main/java/twilightforest/biomes/TFBiomeDeepMushrooms.java @@ -1,26 +1,23 @@ package twilightforest.biomes; +import twilightforest.TFFeature; public class TFBiomeDeepMushrooms extends TFBiomeBase { - public TFBiomeDeepMushrooms(int i) { - super(i); + public TFBiomeDeepMushrooms(BiomeProperties props) { + super(props); - - this.temperature = 0.8F; - this.rainfall = 1.0F; - - this.rootHeight = 0.15F; - this.heightVariation = 0.4F; - getTFBiomeDecorator().setTreesPerChunk(1); - - getTFBiomeDecorator().setMushroomsPerChunk(12); - getTFBiomeDecorator().setBigMushroomsPerChunk(8); - - getTFBiomeDecorator().myceliumPerChunk = 3; - getTFBiomeDecorator().alternateCanopyChance = 0.9F; - + + getTFBiomeDecorator().setMushroomsPerChunk(12); + getTFBiomeDecorator().setBigMushroomsPerChunk(8); + + getTFBiomeDecorator().myceliumPerChunk = 3; + getTFBiomeDecorator().alternateCanopyChance = 0.9F; + } + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.MUSHROOM_TOWER; } - } diff --git a/src/main/java/twilightforest/biomes/TFBiomeEnchantedForest.java b/src/main/java/twilightforest/biomes/TFBiomeEnchantedForest.java index 04e0e73694..f3d9d395d1 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeEnchantedForest.java +++ b/src/main/java/twilightforest/biomes/TFBiomeEnchantedForest.java @@ -1,161 +1,148 @@ package twilightforest.biomes; -import java.util.Random; - +import net.minecraft.block.BlockDoublePlant; import net.minecraft.block.BlockFlower; +import net.minecraft.block.BlockTallGrass; import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenBigTree; import net.minecraft.world.gen.feature.WorldGenTallGrass; -import net.minecraft.world.gen.feature.WorldGenVines; import net.minecraft.world.gen.feature.WorldGenerator; +import twilightforest.TFFeature; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenLargeRainboak; -import twilightforest.world.TFGenSmallRainboak; +import twilightforest.enums.PlantVariant; +import twilightforest.world.feature.TFGenLargeRainboak; +import twilightforest.world.feature.TFGenSmallRainboak; +import twilightforest.world.feature.TFGenTallGrass; +import twilightforest.world.feature.TFGenVines; import twilightforest.world.TFWorld; - +import java.util.Random; public class TFBiomeEnchantedForest extends TFBiomeBase { - - Random colorRNG; - public TFBiomeEnchantedForest(int i) { - super(i); + private final Random colorRNG; + + public TFBiomeEnchantedForest(BiomeProperties props) { + super(props); colorRNG = new Random(); - getTFBiomeDecorator().setGrassPerChunk(12); getTFBiomeDecorator().setFlowersPerChunk(8); } - - /** - * Provides the basic grass color based on the biome temperature and rainfall - */ - @Override - public int getBiomeGrassColor(int x, int y, int z) - { - return (super.getBiomeGrassColor(x, y, z) & 0xFFFF00) + getEnchantedColor(x, z); - } - - /** - * Provides the basic foliage color based on the biome temperature and rainfall - */ - @Override - public int getBiomeFoliageColor(int x, int y, int z) - { - return (super.getBiomeFoliageColor(x, y, z) & 0xFFFF00) + getEnchantedColor(x, z); - - //return (ColorizerGrass.getGrassColor(colorRNG.nextFloat(), colorRNG.nextFloat()) & 0xFFFF00) + colorRNG.nextInt(256); - } - - /** - * Find a number between 0 and 255. currently returns concentric circles from the biome center - */ + + @Override + public int getGrassColorAtPos(BlockPos pos) { + return (super.getGrassColorAtPos(pos) & 0xFFFF00) + getEnchantedColor(pos.getX(), pos.getZ()); + } + + @Override + public int getFoliageColorAtPos(BlockPos pos) { + return (super.getFoliageColorAtPos(pos) & 0xFFFF00) + getEnchantedColor(pos.getX(), pos.getZ()); + } + + /** + * Find a number between 0 and 255. currently returns concentric circles from the biome center + */ private int getEnchantedColor(int x, int z) { // center of the biome is at % 256 - 8 - int cx = 256 * Math.round((x - 8) / 256F) + 8; - int cz = 256 * Math.round((z - 8) / 256F) + 8; - - int dist = (int) MathHelper.sqrt_float((cx - x) * (cx - x) + (cz - z) * (cz - z)); - int color = dist * 64; - color %= 512; - - if (color > 255) { - color = 511 - color; - } - - color = 255 - color; - - int randomFlicker = colorRNG.nextInt(32) - 16; - - if (0 < color + randomFlicker && color + randomFlicker > 255) { - color += randomFlicker; - } - + int cx = 256 * Math.round((x - 8) / 256F) + 8; + int cz = 256 * Math.round((z - 8) / 256F) + 8; + + int dist = (int) MathHelper.sqrt((cx - x) * (cx - x) + (cz - z) * (cz - z)); + int color = dist * 64; + color %= 512; + + if (color > 255) { + color = 511 - color; + } + + color = 255 - color; + + int randomFlicker = colorRNG.nextInt(32) - 16; + + if (0 < color + randomFlicker && color + randomFlicker > 255) { + color += randomFlicker; + } + return color; } - - /** - * Occasional shrub, no big trees - */ - public WorldGenAbstractTree func_150567_a(Random random) - { - if (random.nextInt(15) == 0) - { - return new TFGenSmallRainboak(); - } - else if (random.nextInt(50) == 0) - { - return new TFGenLargeRainboak(); - } - else if (random.nextInt(5) == 0) - { - return birchGen; - } - else if (random.nextInt(10) == 0) - { - return new WorldGenBigTree(false); - } - else - { - return worldGeneratorTrees; - } - } - - /** - * EVEN MOAR FERNZ! - */ - public WorldGenerator getRandomWorldGenForGrass(Random par1Random) - { - if (par1Random.nextInt(3) > 0) { - return new WorldGenTallGrass(Blocks.tallgrass, 2); - } - else if (par1Random.nextInt(3) == 0) { - return new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_FIDDLEHEAD); - } - else { - return new WorldGenTallGrass(Blocks.tallgrass, 1); - } - } - - /** - * Decorate this biome with extra decorations! - */ - @Override - public void decorate(World par1World, Random par2Random, int par3, int par4) - { - WorldGenVines worldgenvines = new WorldGenVines(); - - for (int i = 0; i < 20; i++) - { - int j = par3 + par2Random.nextInt(16) + 8; - byte byte0 = (byte) TFWorld.SEALEVEL; - int k = par4 + par2Random.nextInt(16) + 8; - worldgenvines.generate(par1World, par2Random, j, byte0, k); - } - - // tall ferns - genTallFlowers.func_150548_a(3); - - for (int i = 0; i < 20; ++i) { - int rx = par3 + par2Random.nextInt(16) + 8; - int rz = par4 + par2Random.nextInt(16) + 8; - int ry = par2Random.nextInt(par1World.getHeightValue(rx, rz) + 32); - genTallFlowers.generate(par1World, par2Random, rx, ry, rz); - } - - super.decorate(par1World, par2Random, par3, par4); - } - - /** - * Customize flower colors - */ - public String func_150572_a(Random p_150572_1_, int p_150572_2_, int p_150572_3_, int p_150572_4_) - { - return p_150572_1_.nextInt(3) > 0 ? BlockFlower.field_149859_a[1] : p_150572_1_.nextBoolean() ? BlockFlower.field_149859_a[2] : BlockFlower.field_149859_a[3]; - } + + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(15) == 0) { + return new TFGenSmallRainboak(); + } else if (random.nextInt(50) == 0) { + return new TFGenLargeRainboak(); + } else if (random.nextInt(5) == 0) { + return birchGen; + } else if (random.nextInt(10) == 0) { + return new WorldGenBigTree(false); + } else { + return TREE_FEATURE; + } + } + + @Override + public WorldGenerator getRandomWorldGenForGrass(Random random) { + if (random.nextInt(3) > 0) { + return new WorldGenTallGrass(BlockTallGrass.EnumType.FERN); + } else if (random.nextInt(3) == 0) { + return new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.FIDDLEHEAD)); + } else { + return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); + } + } + + @Override + public void decorate(World world, Random rand, BlockPos pos) { + + BlockPos.MutableBlockPos mutPos = new BlockPos.MutableBlockPos(); + + WorldGenerator vines = new TFGenVines(); + for (int i = 0; i < 20; i++) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int ry = TFWorld.SEALEVEL + 128; + int rz = pos.getZ() + rand.nextInt(16) + 8; + vines.generate(world, rand, mutPos.setPos(rx, ry, rz)); + } + + // tall ferns + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.FERN); + for (int i = 0; i < 20; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = rand.nextInt(world.getHeight(rx, rz) + 32); + DOUBLE_PLANT_GENERATOR.generate(world, rand, mutPos.setPos(rx, ry, rz)); + } + + super.decorate(world, rand, pos); + } + + //VanillaCopy from BiomeForest.pickRandomFlower, removed conditional + @Override + public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos) { + double d0 = MathHelper.clamp((1.0D + GRASS_COLOR_NOISE.getValue((double) pos.getX() / 48.0D, (double) pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D); + BlockFlower.EnumFlowerType blockflower$enumflowertype = BlockFlower.EnumFlowerType.values()[(int) (d0 * (double) BlockFlower.EnumFlowerType.values().length)]; + return blockflower$enumflowertype == BlockFlower.EnumFlowerType.BLUE_ORCHID ? BlockFlower.EnumFlowerType.POPPY : blockflower$enumflowertype; + } + + @Override + public void addDefaultFlowers() { + for (BlockFlower.EnumFlowerType flowerType : Blocks.YELLOW_FLOWER.getTypeProperty().getAllowedValues()) { + addFlower(Blocks.YELLOW_FLOWER.getDefaultState().withProperty(Blocks.YELLOW_FLOWER.getTypeProperty(), flowerType), 10); + } + for (BlockFlower.EnumFlowerType flowerType : Blocks.RED_FLOWER.getTypeProperty().getAllowedValues()) { + addFlower(Blocks.RED_FLOWER.getDefaultState().withProperty(Blocks.RED_FLOWER.getTypeProperty(), flowerType), 10); + } + } + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.QUEST_GROVE; + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeFinalPlateau.java b/src/main/java/twilightforest/biomes/TFBiomeFinalPlateau.java index 6f0ae3b30f..77b08a3835 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeFinalPlateau.java +++ b/src/main/java/twilightforest/biomes/TFBiomeFinalPlateau.java @@ -1,58 +1,65 @@ package twilightforest.biomes; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.stats.Achievement; -import net.minecraft.world.biome.BiomeGenBase.SpawnListEntry; -import net.minecraft.world.gen.feature.WorldGenAbstractTree; -import net.minecraft.world.gen.feature.WorldGenBigTree; -import net.minecraft.world.gen.feature.WorldGenTaiga2; -import twilightforest.TFAchievementPage; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFDeadrock; import twilightforest.block.TFBlocks; +import twilightforest.entity.passive.EntityTFRaven; +import twilightforest.enums.DeadrockVariant; +import java.util.Random; public class TFBiomeFinalPlateau extends TFBiomeBase { - public TFBiomeFinalPlateau(int i) { - super(i); - - this.topBlock = TFBlocks.deadrock; - this.field_150604_aj = 0; - this.fillerBlock = TFBlocks.deadrock; - this.field_76754_C = 1; - -// this.rootHeight = 7F; -// this.heightVariation = 0.4F; - - this.temperature = 0.3F; - this.rainfall = 0.2F; - - getTFBiomeDecorator().canopyPerChunk = -999; + public TFBiomeFinalPlateau(BiomeProperties props) { + super(props); + + this.topBlock = TFBlocks.deadrock.getDefaultState().withProperty(BlockTFDeadrock.VARIANT, DeadrockVariant.SURFACE); + this.fillerBlock = TFBlocks.deadrock.getDefaultState().withProperty(BlockTFDeadrock.VARIANT, DeadrockVariant.CRACKED); + + getTFBiomeDecorator().hasCanopy = false; getTFBiomeDecorator().setTreesPerChunk(-999); - - this.theBiomeDecorator.generateLakes = false; - - // custom creature list. - spawnableCreatureList.clear(); - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFRaven.class, 10, 4, 4)); + + this.decorator.generateFalls = false; + + // custom creature list. + spawnableCreatureList.clear(); + spawnableCreatureList.add(new SpawnListEntry(EntityTFRaven.class, 10, 4, 4)); + } + + @Override + public IBlockState getStoneReplacementState() { + return TFBlocks.deadrock.getDefaultState().withProperty(BlockTFDeadrock.VARIANT, DeadrockVariant.SOLID); } - - /** - * Return a block if you want it to replace stone in the terrain generation - */ - public Block getStoneReplacementBlock() { - return TFBlocks.deadrock; + + @Override + public void decorate(World world, Random rand, BlockPos pos) {} + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_troll") }; } - - /** - * Metadata for the stone replacement block - */ - public byte getStoneReplacementMeta() { - return 2; + + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 5 == 0) { + player.attackEntityFrom(DamageSource.MAGIC, 1.5F); + world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, SoundCategory.PLAYERS, 1.0F, 1.0F); + // TODO: change this when there's a book for the castle + if (world.rand.nextInt(4) == 0) TFFeature.TROLL_CAVE.trySpawnHintMonster(world, player); + } } - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressGlacier; + @Override + protected TFFeature getContainedFeature() { + return TFFeature.FINAL_CASTLE; } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeFireSwamp.java b/src/main/java/twilightforest/biomes/TFBiomeFireSwamp.java index 2201d4dc74..59621c69ca 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeFireSwamp.java +++ b/src/main/java/twilightforest/biomes/TFBiomeFireSwamp.java @@ -1,136 +1,118 @@ package twilightforest.biomes; -import java.util.Random; - +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockOldLeaf; +import net.minecraft.block.BlockOldLog; +import net.minecraft.block.BlockPlanks; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.stats.Achievement; +import net.minecraft.init.Blocks; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenShrub; -import net.minecraft.world.gen.feature.WorldGenVines; -import twilightforest.TFAchievementPage; +import net.minecraft.world.gen.feature.WorldGenerator; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TFFeature; -import twilightforest.block.BlockTFFireJet; -import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenFireJet; +import twilightforest.TwilightForestMod; +import twilightforest.enums.FireJetVariant; +import twilightforest.world.feature.TFGenFireJet; +import twilightforest.world.feature.TFGenVines; import twilightforest.world.TFWorld; +import java.util.Random; + public class TFBiomeFireSwamp extends TFBiomeBase { - protected TFBiomeFireSwamp(int i) { - super(i); + public TFBiomeFireSwamp(BiomeProperties props) { + super(props); -// this.rootHeight = -0.25F; -// this.heightVariation = 0.0F; + getTFBiomeDecorator().setDeadBushPerChunk(2); + getTFBiomeDecorator().setMushroomsPerChunk(8); + getTFBiomeDecorator().setReedsPerChunk(4); + getTFBiomeDecorator().setClayPerChunk(1); + getTFBiomeDecorator().setTreesPerChunk(3); + getTFBiomeDecorator().setWaterlilyPerChunk(6); + + getTFBiomeDecorator().hasCanopy = false; + getTFBiomeDecorator().lavaPoolChance = 0.125F; + getTFBiomeDecorator().mangrovesPerChunk = 3; + } + + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(3) == 0) { + return new WorldGenShrub( + Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE), + Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK).withProperty(BlockLeaves.CHECK_DECAY, false) + ); + } else { + return SWAMP_FEATURE; + } + } - this.temperature = 1.0F; - this.rainfall = 0.4F; + @Override + public void decorate(World world, Random rand, BlockPos pos) { + super.decorate(world, rand, pos); + + TFFeature nearFeature = TFFeature.getNearestFeature(pos.getX() >> 4, pos.getZ() >> 4, world); + if (nearFeature.areChunkDecorationsEnabled) { + BlockPos.MutableBlockPos mutPos = new BlockPos.MutableBlockPos(); + + WorldGenerator vines = new TFGenVines(); + for (int i = 0; i < 20; i++) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int ry = TFWorld.SEALEVEL + 128; + int rz = pos.getZ() + rand.nextInt(16) + 8; + vines.generate(world, rand, mutPos.setPos(rx, ry, rz)); + } + + WorldGenerator genSmoker = new TFGenFireJet(FireJetVariant.SMOKER); + if (rand.nextInt(4) == 0) { + int rx = pos.getX() + rand.nextInt(14) + 8; + int ry = TFWorld.SEALEVEL; + int rz = pos.getZ() + rand.nextInt(14) + 8; + genSmoker.generate(world, rand, mutPos.setPos(rx, ry, rz)); + } + + WorldGenerator genFireJet = new TFGenFireJet(FireJetVariant.JET_IDLE); + for (int i = 0; i < 1; i++) { + int rx = pos.getX() + rand.nextInt(14) + 8; + int ry = TFWorld.SEALEVEL; + int rz = pos.getZ() + rand.nextInt(14) + 8; + genFireJet.generate(world, rand, mutPos.setPos(rx, ry, rz)); + } + } + } - getTFBiomeDecorator().setDeadBushPerChunk(2); - getTFBiomeDecorator().setMushroomsPerChunk(8); - getTFBiomeDecorator().setReedsPerChunk(4); - getTFBiomeDecorator().setClayPerChunk(1); - getTFBiomeDecorator().setTreesPerChunk(3); - getTFBiomeDecorator().setWaterlilyPerChunk(6); - waterColorMultiplier = 0x6C2C2C; + @Override + @SideOnly(Side.CLIENT) + public int getGrassColorAtPos(BlockPos pos) { + return 0x572e23; + } - - getTFBiomeDecorator().canopyPerChunk = -999; - getTFBiomeDecorator().lavaPoolChance = 0.125F; - getTFBiomeDecorator().mangrovesPerChunk = 3; + @Override + @SideOnly(Side.CLIENT) + public int getFoliageColorAtPos(BlockPos pos) { + return 0x64260f; } - - - /** - * Gets a WorldGen appropriate for this biome. - */ - public WorldGenAbstractTree func_150567_a(Random random) - { - if (random.nextInt(3) == 0) - { - return new WorldGenShrub(3, 0); - } - - return worldGeneratorSwamp; - } - - /** - * Decorate this biome. This is stolen from the jungle code - */ - @Override - public void decorate(World par1World, Random par2Random, int mapX, int mapZ) - { - super.decorate(par1World, par2Random, mapX, mapZ); - - TFFeature nearFeature = TFFeature.getNearestFeature(mapX >> 4, mapZ >> 4, par1World); - if (nearFeature.areChunkDecorationsEnabled) { - WorldGenVines worldgenvines = new WorldGenVines(); - - for (int i = 0; i < 50; i++) - { - int j = mapX + par2Random.nextInt(16) + 8; - byte byte0 = (byte) TFWorld.SEALEVEL; - int k = mapZ + par2Random.nextInt(16) + 8; - worldgenvines.generate(par1World, par2Random, j, byte0, k); - } - - TFGenFireJet genSmoker = new TFGenFireJet(TFBlocks.fireJet, BlockTFFireJet.META_SMOKER); - - if (par2Random.nextInt(4) == 0) - { - int j = mapX + par2Random.nextInt(16) + 8; - byte byte0 = (byte) TFWorld.SEALEVEL; - int k = mapZ + par2Random.nextInt(16) + 8; - genSmoker.generate(par1World, par2Random, j, byte0, k); - } - - TFGenFireJet genFireJet = new TFGenFireJet(TFBlocks.fireJet, BlockTFFireJet.META_JET_IDLE); - - for (int i = 0; i < 1; i++) - { - int j = mapX + par2Random.nextInt(16) + 8; - byte byte0 = (byte) TFWorld.SEALEVEL; - int k = mapZ + par2Random.nextInt(16) + 8; - genFireJet.generate(par1World, par2Random, j, byte0, k); - } - } - } - - /** - * Provides the basic grass color based on the biome temperature and rainfall - */ - @Override - public int getBiomeGrassColor(int x, int y, int z) - { - return 0x572e23;//0x8c4c35;//0x3f3555;// 0x8C0C0C;//0xd79e2f;// - } - - /** - * Provides the basic foliage color based on the biome temperature and rainfall - */ - @Override - public int getBiomeFoliageColor(int x, int y, int z) - { - return 0x64260f;//0x6C2020;//0x8f2839;//0x6c464d;// - } - - /** - * If there is a required achievement to be here, return it, otherwise return null - */ - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressLabyrinth; + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_labyrinth") }; } - /** - * Do something bad to a player in the wrong biome. - */ - public void enforceProgession(EntityPlayer player, World world) { - if (!world.isRemote && world.getWorldTime() % 60 == 0) { + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 60 == 0) { player.setFire(8); } - // hint monster? - if (world.rand.nextInt(4) == 0) { - TFFeature.hydraLair.trySpawnHintMonster(world, player); - } + trySpawnHintMonster(player, world); + } + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.HYDRA_LAIR; } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeFireflyForest.java b/src/main/java/twilightforest/biomes/TFBiomeFireflyForest.java index 5cbc48c32b..ee038a9608 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeFireflyForest.java +++ b/src/main/java/twilightforest/biomes/TFBiomeFireflyForest.java @@ -1,163 +1,80 @@ package twilightforest.biomes; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockFlower; -import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; +import net.minecraft.init.Biomes; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.biome.BiomeForest; import net.minecraft.world.gen.feature.WorldGenPumpkin; -import net.minecraft.world.gen.feature.WorldGenTallGrass; +import net.minecraft.world.gen.feature.WorldGenerator; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenHangingLamps; -import twilightforest.world.TFGenLampposts; +import twilightforest.enums.PlantVariant; +import twilightforest.world.feature.TFGenHangingLamps; +import twilightforest.world.feature.TFGenLampposts; +import twilightforest.world.feature.TFGenTallGrass; import twilightforest.world.TFWorld; -public class TFBiomeFireflyForest extends TFBiomeTwilightForest { - +import java.util.Random; + +public class TFBiomeFireflyForest extends TFBiomeBase { + private static final int LAMPPOST_CHANCE = 4; - TFGenHangingLamps tfGenHangingLamps; - TFGenLampposts tfGenLampposts; - WorldGenTallGrass worldGenMushgloom; - - public TFBiomeFireflyForest(int i) { - super(i); - this.worldGenMushgloom = new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_MUSHGLOOM); - this.tfGenHangingLamps = new TFGenHangingLamps(); - this.tfGenLampposts = new TFGenLampposts(); + private final WorldGenerator tfGenHangingLamps = new TFGenHangingLamps(); + private final WorldGenerator tfGenLampposts = new TFGenLampposts(TFBlocks.firefly_jar.getDefaultState()); + private final WorldGenerator worldGenMushgloom = new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MUSHGLOOM)); - this.temperature = 0.5F; - this.rainfall = 1.0F; - - this.theBiomeDecorator.flowersPerChunk = 4; - this.theBiomeDecorator.grassPerChunk = 1; + public TFBiomeFireflyForest(BiomeProperties props) { + super(props); - this.getTFBiomeDecorator().setTreesPerChunk(2); + this.decorator.flowersPerChunk = 4; + this.decorator.grassPerChunk = 1; + this.getTFBiomeDecorator().setTreesPerChunk(2); } - - /** - * Decorate this biome. This is stolen from the flower forest code - */ - @Override - public void decorate(World world, Random rand, int mapX, int mapZ) - { - int flowerCycles = rand.nextInt(3) - 1; - - int successfulFlowers = 0; - - while (successfulFlowers < flowerCycles) - { - int flowerType = rand.nextInt(3); - - if (flowerType == 0) - { - genTallFlowers.func_150548_a(1); - } - else if (flowerType == 1) - { - genTallFlowers.func_150548_a(4); - } - else if (flowerType == 2) - { - genTallFlowers.func_150548_a(5); - } - - int tallFlowerTries = 0; - - while (true) - { - if (tallFlowerTries < 1) - { - int k1 = mapX + rand.nextInt(16) + 8; - int i2 = mapZ + rand.nextInt(16) + 8; - int l1 = rand.nextInt(world.getHeightValue(k1, i2) + 32); - - if (!genTallFlowers.generate(world, rand, k1, l1, i2)) - { - ++tallFlowerTries; - continue; - } - } - - ++successfulFlowers; - break; - } - } - - super.decorate(world, rand, mapX, mapZ); - - if (rand.nextInt(24) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); + @Override + public void decorate(World world, Random rand, BlockPos pos) { + int flowerCycles = rand.nextInt(3) - 1; + // Handle mods not staying in the class hierarchy when replacing vanilla + if (Biomes.MUTATED_FOREST instanceof BiomeForest) { + ((BiomeForest) Biomes.MUTATED_FOREST).addDoublePlants(world, rand, pos, flowerCycles); + } + + super.decorate(world, rand, pos); + + if (rand.nextInt(24) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); // mushglooms - this.worldGenMushgloom.generate(world, rand, rx, ry, rz); + this.worldGenMushgloom.generate(world, rand, new BlockPos(rx, ry, rz)); } - - // hanging lamps - for (int i = 0; i < 30; i++) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; + + // hanging lamps + for (int i = 0; i < 30; i++) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; int ry = TFWorld.SEALEVEL + rand.nextInt(TFWorld.CHUNKHEIGHT - TFWorld.SEALEVEL); - this.tfGenHangingLamps.generate(world, rand, rx, ry, rz); - } - - if (rand.nextInt(LAMPPOST_CHANCE) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - - this.tfGenLampposts.generate(world, rand, rx, ry, rz); - } - - // extra pumpkins (should they be lit?) - if (rand.nextInt(32) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - (new WorldGenPumpkin()).generate(world, rand, rx, ry, rz); - } - - } - - public int getGroundLevel(World world, int x, int z) { - // go from sea level up. If we get grass, return that, otherwise return the last dirt, stone or gravel we got - Chunk chunk = world.getChunkFromBlockCoords(x, z); - int lastDirt = TFWorld.SEALEVEL; - for (int y = TFWorld.SEALEVEL; y < TFWorld.CHUNKHEIGHT - 1; y++) { - Block blockID = chunk.getBlock(x & 15, y, z & 15); - // grass = return immediately - if (blockID == Blocks.grass) { - return y + 1; - } - else if (blockID == Blocks.dirt || blockID == Blocks.stone || blockID == Blocks.gravel) { - lastDirt = y + 1; - } + this.tfGenHangingLamps.generate(world, rand, new BlockPos(rx, ry, rz)); } - - return lastDirt; - } - - /** - * Every color flower! - */ - public String func_150572_a(Random p_150572_1_, int p_150572_2_, int p_150572_3_, int p_150572_4_) - { - double flowerVar = MathHelper.clamp_double((1.0D + plantNoise.func_151601_a((double)p_150572_2_ / 48.0D, (double)p_150572_4_ / 48.0D)) / 2.0D, 0.0D, 0.9999D); - int flowerIndex = (int)(flowerVar * (double)BlockFlower.field_149859_a.length); - - if (flowerIndex == 1) - { - flowerIndex = 0; + + if (rand.nextInt(LAMPPOST_CHANCE) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + + this.tfGenLampposts.generate(world, rand, new BlockPos(rx, ry, rz)); } - return BlockFlower.field_149859_a[flowerIndex]; + // extra pumpkins (should they be lit?) + if (rand.nextInt(32) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + + new WorldGenPumpkin().generate(world, rand, new BlockPos(rx, ry, rz)); + } } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeGlacier.java b/src/main/java/twilightforest/biomes/TFBiomeGlacier.java index 1edd50252e..d05e7b0737 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeGlacier.java +++ b/src/main/java/twilightforest/biomes/TFBiomeGlacier.java @@ -1,114 +1,89 @@ -/** - * - */ package twilightforest.biomes; -import java.util.Random; - import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.stats.Achievement; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenTaiga1; import net.minecraft.world.gen.feature.WorldGenTaiga2; -import twilightforest.TFAchievementPage; +import net.minecraft.world.gen.feature.WorldGenerator; import twilightforest.TFFeature; -import twilightforest.world.TFGenPenguins; +import twilightforest.TwilightForestMod; +import twilightforest.entity.passive.EntityTFPenguin; +import twilightforest.potions.TFPotions; +import twilightforest.world.feature.TFGenPenguins; import twilightforest.world.TFWorld; - +import java.util.Random; /** * @author Ben - * */ public class TFBiomeGlacier extends TFBiomeBase { - /** - * @param i - */ - @SuppressWarnings("unchecked") - public TFBiomeGlacier(int i) { - super(i); - + public TFBiomeGlacier(BiomeProperties props) { + super(props); + getTFBiomeDecorator().setTreesPerChunk(1); getTFBiomeDecorator().setGrassPerChunk(0); + getTFBiomeDecorator().hasCanopy = false; - this.temperature = 0.0F; - this.rainfall = 0.1F; - getTFBiomeDecorator().canopyPerChunk = -999; - - spawnableCreatureList.add(new SpawnListEntry(twilightforest.entity.passive.EntityTFPenguin.class, 10, 4, 4)); - + spawnableCreatureList.clear(); + spawnableCreatureList.add(new SpawnListEntry(EntityTFPenguin.class, 10, 4, 4)); } - - - public WorldGenAbstractTree func_150567_a(Random random) - { - if(random.nextInt(3) == 0) - { - return new WorldGenTaiga1(); - } else - { - return new WorldGenTaiga2(true); - } - } - /** - * Let it snow! - */ - @Override - public boolean getEnableSnow() - { - return true; - } - - /** - * Required for actual snow? - */ - @Override - public boolean canSpawnLightningBolt() - { - return false; - } - - /** - * Decorate this biome. Weeeee should generate penguins - */ - @Override - public void decorate(World par1World, Random par2Random, int par3, int par4) - { - super.decorate(par1World, par2Random, par3, par4); - TFGenPenguins penguins = new TFGenPenguins(); + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(3) == 0) { + return new WorldGenTaiga1(); + } else { + return new WorldGenTaiga2(true); + } + } - if (par2Random.nextInt(4) == 0) - { - int j = par3 + par2Random.nextInt(16) + 8; - byte byte0 = (byte) TFWorld.SEALEVEL; - int k = par4 + par2Random.nextInt(16) + 8; - penguins.generate(par1World, par2Random, j, byte0, k); - } - } + @Override + public boolean getEnableSnow() { + return true; + } /** - * If there is a required achievement to be here, return it, otherwise return null + * Required for actual snow? */ - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressUrghast; + @Override + public boolean canRain() { + return false; } - /** - * Do something bad to a player in the wrong biome. - */ - public void enforceProgession(EntityPlayer player, World world) { - if (!world.isRemote && world.getWorldTime() % 60 == 0) { - player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 3)); + @Override + public void decorate(World world, Random random, BlockPos pos) { + super.decorate(world, random, pos); + + WorldGenerator penguins = new TFGenPenguins(); + if (random.nextInt(4) == 0) { + int x = pos.getX() + random.nextInt(16) + 8; + int y = TFWorld.SEALEVEL; + int z = pos.getZ() + random.nextInt(16) + 8; + penguins.generate(world, random, new BlockPos(x, y, z)); } - // hint monster? - if (world.rand.nextInt(4) == 0) { - TFFeature.iceTower.trySpawnHintMonster(world, player); + } + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_yeti") }; + } + + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 60 == 0) { + player.addPotionEffect(new PotionEffect(TFPotions.frosty, 100, 3)); } + trySpawnHintMonster(player, world); + } + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.ICE_TOWER; } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeHighlands.java b/src/main/java/twilightforest/biomes/TFBiomeHighlands.java index 0d39620cd2..c6b1a47c57 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeHighlands.java +++ b/src/main/java/twilightforest/biomes/TFBiomeHighlands.java @@ -1,19 +1,20 @@ package twilightforest.biomes; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockFlower; +import net.minecraft.block.BlockDirt; +import net.minecraft.block.BlockDoublePlant; +import net.minecraft.block.BlockTallGrass; import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntitySlime; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; -import net.minecraft.stats.Achievement; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenBlockBlob; import net.minecraft.world.gen.feature.WorldGenMegaPineTree; @@ -21,179 +22,142 @@ import net.minecraft.world.gen.feature.WorldGenTaiga2; import net.minecraft.world.gen.feature.WorldGenTallGrass; import net.minecraft.world.gen.feature.WorldGenerator; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; import twilightforest.entity.EntityTFTroll; -import twilightforest.world.TFGenTrollRoots; +import twilightforest.world.feature.TFGenTallGrass; +import twilightforest.world.feature.TFGenTrollRoots; +import java.util.Random; public class TFBiomeHighlands extends TFBiomeBase { - - - private static final WorldGenTaiga1 taigaGen1 = new WorldGenTaiga1(); - private static final WorldGenTaiga2 taigaGen2 = new WorldGenTaiga2(false); - private static final WorldGenMegaPineTree megaPineGen1 = new WorldGenMegaPineTree(false, false); - private static final WorldGenMegaPineTree megaPineGen2 = new WorldGenMegaPineTree(false, true); - private static final WorldGenBlockBlob genBoulder = new WorldGenBlockBlob(Blocks.mossy_cobblestone, 0); - private static final TFGenTrollRoots genTrollRoots = new TFGenTrollRoots(); - private static final WorldGenTallGrass worldGenMushgloom = new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_MUSHGLOOM); - - - public TFBiomeHighlands(int i) { - super(i); - - this.temperature = 0.4F; - this.rainfall = 0.7F; - - ((TFBiomeDecorator)theBiomeDecorator).canopyPerChunk = -999; - - this.theBiomeDecorator.grassPerChunk = 7; - this.theBiomeDecorator.deadBushPerChunk = 1; - this.theBiomeDecorator.generateLakes = false; // actually underground water sources - - - //this.spawnableMonsterList.add(new SpawnListEntry(EntityTFTroll.class, 10, 4, 4)); - - - undergroundMonsterList.clear(); - undergroundMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 10, 4, 4)); - undergroundMonsterList.add(new SpawnListEntry(EntityCreeper.class, 1, 4, 4)); - undergroundMonsterList.add(new SpawnListEntry(EntitySlime.class, 10, 4, 4)); - - undergroundMonsterList.add(new SpawnListEntry(EntityTFTroll.class, 10, 4, 4)); + + private final WorldGenAbstractTree taigaGen1 = new WorldGenTaiga1(); + private final WorldGenAbstractTree taigaGen2 = new WorldGenTaiga2(false); + private final WorldGenAbstractTree megaPineGen1 = new WorldGenMegaPineTree(false, false); + private final WorldGenAbstractTree megaPineGen2 = new WorldGenMegaPineTree(false, true); + + private final WorldGenerator genBoulder = new WorldGenBlockBlob(Blocks.MOSSY_COBBLESTONE, 0); + private final WorldGenerator genTrollRoots = new TFGenTrollRoots(); + private final WorldGenerator worldGenMushgloom = new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MUSHGLOOM)); + + public TFBiomeHighlands(BiomeProperties props) { + super(props); + + getTFBiomeDecorator().hasCanopy = false; + + this.decorator.grassPerChunk = 7; + this.decorator.deadBushPerChunk = 1; + this.decorator.generateFalls = false; + + undergroundMonsterList.clear(); + undergroundMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 10, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntityCreeper.class, 1, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntitySlime.class, 10, 4, 4)); + undergroundMonsterList.add(new SpawnListEntry(EntityTFTroll.class, 10, 4, 4)); + } + + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(4) == 0) { + return taigaGen1; + } else if (random.nextInt(10) == 0) { + return taigaGen2; + } else if (random.nextInt(3) == 0) { + return megaPineGen1; + } else if (random.nextInt(13) == 0) { + return megaPineGen2; + } else { + return birchGen; + } } - - /** - * Birches and large trees only - */ - public WorldGenAbstractTree func_150567_a(Random random) - { - if(random.nextInt(4) == 0){ - return taigaGen1; - } else if(random.nextInt(10) == 0){ - return taigaGen2; - } else if(random.nextInt(3) == 0){ - return megaPineGen1; - } else if(random.nextInt(13) == 0){ - return megaPineGen2; - } else { - return birchGen; - } - } - - /** - * Gets a WorldGen appropriate for this biome. - */ - public WorldGenerator getRandomWorldGenForGrass(Random par1Random) - { - return par1Random.nextInt(5) > 0 ? new WorldGenTallGrass(Blocks.tallgrass, 2) : new WorldGenTallGrass(Blocks.tallgrass, 1); - } - - public void genTerrainBlocks(World world, Random rand, Block[] blockStorage, byte[] metaStorage, int x, int z, double noiseVal) - { - if (true) - { - this.topBlock = Blocks.grass; - this.field_150604_aj = 0; - this.fillerBlock = Blocks.dirt; - - if (noiseVal > 1.75D) - { - this.topBlock = Blocks.dirt; - this.field_150604_aj = 1; - } - else if (noiseVal > -0.95D) - { - this.topBlock = Blocks.dirt; - this.field_150604_aj = 2; - } - } - - this.genTwilightBiomeTerrain(world, rand, blockStorage, metaStorage, x, z, noiseVal); - } - - /** - * Add extra decorations - */ - public void decorate(World par1World, Random par2Random, int mapX, int mapZ) - { - int dx, dy, dz; - - // boulders - int maxBoulders = par2Random.nextInt(2); - for (int i = 0; i < maxBoulders; ++i) - { - dx = mapX + par2Random.nextInt(16) + 8; - dz = mapZ + par2Random.nextInt(16) + 8; - dy = par1World.getHeightValue(dx, dz); - genBoulder.generate(par1World, par2Random, dx, dy, dz); - } - - // giant ferns - genTallFlowers.func_150548_a(3); - for (int i = 0; i < 7; ++i) - { - dx = mapX + par2Random.nextInt(16) + 8; - dz = mapZ + par2Random.nextInt(16) + 8; - dy = par2Random.nextInt(par1World.getHeightValue(dx, dz) + 32); - genTallFlowers.generate(par1World, par2Random, dx, dy, dz); - } - - // mushglooms - for (int i = 0; i < 1; ++i) - { - int rx = mapX + par2Random.nextInt(16) + 8; - int rz = mapZ + par2Random.nextInt(16) + 8; - int ry = par2Random.nextInt(64); - // mushglooms - worldGenMushgloom.generate(par1World, par2Random, rx, ry, rz); - } + + @Override + public WorldGenerator getRandomWorldGenForGrass(Random random) { + return random.nextInt(5) > 0 + ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) + : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); + } + + @Override + public void genTerrainBlocks(World world, Random rand, ChunkPrimer primer, int x, int z, double noiseVal) { + this.topBlock = Blocks.GRASS.getDefaultState(); + this.fillerBlock = Blocks.DIRT.getDefaultState(); + + if (noiseVal > 1.75D) { + this.topBlock = Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT); + } else if (noiseVal > -0.95D) { + this.topBlock = Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.PODZOL); + } + + this.genTwilightBiomeTerrain(world, rand, primer, x, z, noiseVal); + } + + @Override + public void decorate(World world, Random rand, BlockPos pos) { + + // boulders + int maxBoulders = rand.nextInt(2); + for (int i = 0; i < maxBoulders; ++i) { + int dx = pos.getX() + rand.nextInt(16) + 8; + int dz = pos.getZ() + rand.nextInt(16) + 8; + int dy = world.getHeight(dx, dz); + genBoulder.generate(world, rand, new BlockPos(dx, dy, dz)); + } + + // giant ferns + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.FERN); + for (int i = 0; i < 7; ++i) { + int dx = pos.getX() + rand.nextInt(16) + 8; + int dz = pos.getZ() + rand.nextInt(16) + 8; + int dy = rand.nextInt(world.getHeight(dx, dz) + 32); + DOUBLE_PLANT_GENERATOR.generate(world, rand, new BlockPos(dx, dy, dz)); + } + + // mushglooms + for (int i = 0; i < 1; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = rand.nextInt(64); + // mushglooms + worldGenMushgloom.generate(world, rand, new BlockPos(rx, ry, rz)); + } // generate roots - for (int i = 0; i < 24; ++i) - { - int rx = mapX + par2Random.nextInt(16) + 8; - byte ry = 64; - int rz = mapZ + par2Random.nextInt(16) + 8; - genTrollRoots.generate(par1World, par2Random, rx, ry, rz); + for (int i = 0; i < 24; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int ry = 64; + int rz = pos.getZ() + rand.nextInt(16) + 8; + genTrollRoots.generate(world, rand, new BlockPos(rx, ry, rz)); } - super.decorate(par1World, par2Random, mapX, mapZ); - } - - /** - * Flowers - */ - public String func_150572_a(Random rand, int x, int y, int z) - { - return rand.nextBoolean() ? BlockFlower.field_149858_b[0] : BlockFlower.field_149859_a[8]; - } - - - - /** - * If there is a required achievement to be here, return it, otherwise return null - */ - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressGlacier; + super.decorate(world, rand, pos); } - /** - * Do something bad to a player in the wrong biome. - */ - public void enforceProgession(EntityPlayer player, World world) { - if (!world.isRemote && world.getWorldTime() % 5 == 0) { - player.attackEntityFrom(DamageSource.magic, 0.5F); - world.playSoundAtEntity(player, "random.fizz", 1.0F, 1.0F); - //player.playSound("random.fizz", 1.0F, 1.0F); - - // hint monster? - if (world.rand.nextInt(4) == 0) { - TFFeature.trollCave.trySpawnHintMonster(world, player); - } + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[] { + //TwilightForestMod.prefix("progress_hydra"), + //TwilightForestMod.prefix("progress_ur_ghast"), + //TwilightForestMod.prefix("progress_glacier") + TwilightForestMod.prefix("progress_merge") + }; + } + + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 5 == 0) { + player.attackEntityFrom(DamageSource.MAGIC, 0.5F); + world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, SoundCategory.PLAYERS, 1.0F, 1.0F); + trySpawnHintMonster(player, world); } } + @Override + protected TFFeature getContainedFeature() { + return TFFeature.TROLL_CAVE; + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeMushrooms.java b/src/main/java/twilightforest/biomes/TFBiomeMushrooms.java index 49e944c7ce..4fb66a0c0e 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeMushrooms.java +++ b/src/main/java/twilightforest/biomes/TFBiomeMushrooms.java @@ -1,21 +1,13 @@ package twilightforest.biomes; - public class TFBiomeMushrooms extends TFBiomeBase { - public TFBiomeMushrooms(int i) { - super(i); - - this.rainfall = 0.8F; - this.temperature = 0.8F; - - getTFBiomeDecorator().setTreesPerChunk(8); - - getTFBiomeDecorator().setMushroomsPerChunk(8); - getTFBiomeDecorator().setBigMushroomsPerChunk(2); - - getTFBiomeDecorator().alternateCanopyChance = 0.2F; + public TFBiomeMushrooms(BiomeProperties props) { + super(props); + getTFBiomeDecorator().setTreesPerChunk(8); + getTFBiomeDecorator().setMushroomsPerChunk(8); + getTFBiomeDecorator().setBigMushroomsPerChunk(2); + getTFBiomeDecorator().alternateCanopyChance = 0.2F; } - } diff --git a/src/main/java/twilightforest/biomes/TFBiomeOakSavanna.java b/src/main/java/twilightforest/biomes/TFBiomeOakSavanna.java index f506bef84e..2710264b8d 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeOakSavanna.java +++ b/src/main/java/twilightforest/biomes/TFBiomeOakSavanna.java @@ -1,9 +1,8 @@ package twilightforest.biomes; -import java.util.Random; - -import net.minecraft.block.BlockFlower; -import net.minecraft.init.Blocks; +import net.minecraft.block.BlockDoublePlant; +import net.minecraft.block.BlockTallGrass; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenBigTree; @@ -11,99 +10,58 @@ import net.minecraft.world.gen.feature.WorldGenerator; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenCanopyOak; -import twilightforest.world.TFGenNoTree; +import twilightforest.enums.PlantVariant; +import twilightforest.world.feature.TFGenCanopyOak; +import twilightforest.world.feature.TFGenNoTree; +import twilightforest.world.feature.TFGenTallGrass; + +import java.util.Random; -public class TFBiomeOakSavanna extends TFBiomeTwilightForest { +public class TFBiomeOakSavanna extends TFBiomeBase { + + public TFBiomeOakSavanna(BiomeProperties props) { + super(props); - public TFBiomeOakSavanna(int i) { - super(i); - getTFBiomeDecorator().canopyTreeGen = new TFGenCanopyOak(); - - getTFBiomeDecorator().alternateCanopyChance = 0.8F; - getTFBiomeDecorator().alternateCanopyGen = new TFGenNoTree(); - - this.temperature = 0.9F; - this.rainfall = 0.0F; + getTFBiomeDecorator().alternateCanopyChance = 0.8F; + getTFBiomeDecorator().alternateCanopyGen = new TFGenNoTree(); - - this.theBiomeDecorator.treesPerChunk = 1; - this.theBiomeDecorator.flowersPerChunk = 4; - this.theBiomeDecorator.grassPerChunk = 20; + this.decorator.treesPerChunk = 1; + this.decorator.flowersPerChunk = 4; + this.decorator.grassPerChunk = 20; } - - /** - * Oak trees all over - */ - public WorldGenAbstractTree func_150567_a(Random random) - { - if(random.nextInt(10) == 0) - { - return new WorldGenBigTree(false); - } else - { - return worldGeneratorTrees; - } - } - - /** - * Oak savanna fern mix - */ - public WorldGenerator getRandomWorldGenForGrass(Random par1Random) - { - if (par1Random.nextInt(10) == 0) - { - return new WorldGenTallGrass(Blocks.tallgrass, 2); - } - else if (par1Random.nextInt(10) == 0) - { - return new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_MAYAPPLE); - } - else - { - return new WorldGenTallGrass(Blocks.tallgrass, 1); - } - } - - /** - * Multi-color flowers! - */ - public String func_150572_a(Random p_150572_1_, int p_150572_2_, int p_150572_3_, int p_150572_4_) - { - double d0 = plantNoise.func_151601_a((double)p_150572_2_ / 200.0D, (double)p_150572_4_ / 200.0D); - int l; + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(10) == 0) { + return new WorldGenBigTree(false); + } else { + return TREE_FEATURE; + } + } - if (d0 < -0.8D) - { - l = p_150572_1_.nextInt(4); - return BlockFlower.field_149859_a[4 + l]; - } - else if (p_150572_1_.nextInt(3) > 0) - { - l = p_150572_1_.nextInt(3); - return l == 0 ? BlockFlower.field_149859_a[0] : (l == 1 ? BlockFlower.field_149859_a[3] : BlockFlower.field_149859_a[8]); - } - else - { - return BlockFlower.field_149858_b[0]; - } - } + @Override + public WorldGenerator getRandomWorldGenForGrass(Random random) { + if (random.nextInt(10) == 0) { + return new WorldGenTallGrass(BlockTallGrass.EnumType.FERN); + } else if (random.nextInt(10) == 0) { + return new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MAYAPPLE)); + } else { + return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); + } + } - public void decorate(World par1World, Random par2Random, int par3, int par4) - { - // 2-tall grass! - genTallFlowers.func_150548_a(2); + @Override + public void decorate(World world, Random random, BlockPos pos) { - for (int k = 0; k < 7; ++k) - { - int l = par3 + par2Random.nextInt(16) + 8; - int i1 = par4 + par2Random.nextInt(16) + 8; - int j1 = par2Random.nextInt(par1World.getHeightValue(l, i1) + 32); - genTallFlowers.generate(par1World, par2Random, l, j1, i1); - } + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.GRASS); + for (int i = 0; i < 7; ++i) { + int x = pos.getX() + random.nextInt(16) + 8; + int z = pos.getZ() + random.nextInt(16) + 8; + int y = random.nextInt(world.getHeight(x, z) + 32); + DOUBLE_PLANT_GENERATOR.generate(world, random, new BlockPos(x, y, z)); + } - super.decorate(par1World, par2Random, par3, par4); - } + super.decorate(world, random, pos); + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeSnow.java b/src/main/java/twilightforest/biomes/TFBiomeSnow.java index e5f0d26ac2..a4c2656232 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeSnow.java +++ b/src/main/java/twilightforest/biomes/TFBiomeSnow.java @@ -1,127 +1,91 @@ -/** - * - */ package twilightforest.biomes; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.stats.Achievement; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenTaiga1; import net.minecraft.world.gen.feature.WorldGenTaiga2; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; import twilightforest.entity.EntityTFWinterWolf; import twilightforest.entity.EntityTFYeti; -import twilightforest.world.TFGenLargeWinter; +import twilightforest.potions.TFPotions; +import twilightforest.world.feature.TFGenLargeWinter; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; /** * @author Ben - * */ public class TFBiomeSnow extends TFBiomeBase { - private static final int MONSTER_SPAWN_RATE = 10; - Random monsterRNG = new Random(53439L); - ArrayList emptyList = new ArrayList(); - - /** - * @param i - */ - @SuppressWarnings("unchecked") - public TFBiomeSnow(int i) { - super(i); - + + private final Random monsterRNG = new Random(53439L); + + public TFBiomeSnow(BiomeProperties props) { + super(props); + getTFBiomeDecorator().setTreesPerChunk(7); getTFBiomeDecorator().setGrassPerChunk(1); - - this.temperature = 0.125F; - this.rainfall = 0.9F; - - getTFBiomeDecorator().canopyPerChunk = -999; - getTFBiomeDecorator().generateLakes = false; - - this.spawnableMonsterList.add(new SpawnListEntry(EntityTFYeti.class, 20, 4, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityTFWinterWolf.class, 5, 1, 4)); + getTFBiomeDecorator().hasCanopy = false; + getTFBiomeDecorator().generateFalls = false; + + this.spawnableMonsterList.add(new SpawnListEntry(EntityTFYeti.class, 20, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityTFWinterWolf.class, 5, 1, 4)); } - public WorldGenAbstractTree func_150567_a(Random random) - { - if (random.nextInt(3) == 0) { - return new WorldGenTaiga1(); - } - else if (random.nextInt(8) == 0) { - return new TFGenLargeWinter(); - } - else { - return new WorldGenTaiga2(true); - } - } - - /** - * Let it snow! - */ - @Override - public boolean getEnableSnow() - { - return true; - } - - /** - * Required for actual snow? - */ - @Override - public boolean canSpawnLightningBolt() - { - return false; - } - - /** - * Returns the correspondent list of the EnumCreatureType informed. - */ - @SuppressWarnings("rawtypes") @Override - public List getSpawnableList(EnumCreatureType par1EnumCreatureType) - { - // if is is monster, then only give it the real list 1/MONSTER_SPAWN_RATE of the time - if (par1EnumCreatureType == EnumCreatureType.monster) { - return monsterRNG.nextInt(MONSTER_SPAWN_RATE) == 0 ? this.spawnableMonsterList : emptyList; - } - else { - return par1EnumCreatureType == EnumCreatureType.creature ? this.spawnableCreatureList : (par1EnumCreatureType == EnumCreatureType.waterCreature ? this.spawnableWaterCreatureList : (par1EnumCreatureType == EnumCreatureType.ambient ? this.spawnableCaveCreatureList : null)); - } - } - - /** - * If there is a required achievement to be here, return it, otherwise return null - */ - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressUrghast; + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(3) == 0) { + return new WorldGenTaiga1(); + } else if (random.nextInt(8) == 0) { + return new TFGenLargeWinter(); + } else { + return new WorldGenTaiga2(true); + } } - /** - * Do something bad to a player in the wrong biome. - */ - public void enforceProgession(EntityPlayer player, World world) { - if (!world.isRemote && world.getWorldTime() % 60 == 0) { - player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 2)); - - // hint monster? - if (world.rand.nextInt(4) == 0) { - TFFeature.yetiCave.trySpawnHintMonster(world, player); - } + @Override + public boolean getEnableSnow() { + return true; + } + + @Override + public boolean canRain() { + return false; + } + + @Override + public List getSpawnableList(EnumCreatureType creatureType) { + // if it is monster, then only give it the real list 1/MONSTER_SPAWN_RATE of the time + if (creatureType == EnumCreatureType.MONSTER) { + return monsterRNG.nextInt(MONSTER_SPAWN_RATE) == 0 ? this.spawnableMonsterList : new ArrayList<>(); } + return super.getSpawnableList(creatureType); + } + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_lich") }; + } + + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 60 == 0) { + player.addPotionEffect(new PotionEffect(TFPotions.frosty, 100, 2)); + trySpawnHintMonster(player, world); + } + } + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.YETI_CAVE; } - - } diff --git a/src/main/java/twilightforest/biomes/TFBiomeSpookyForest.java b/src/main/java/twilightforest/biomes/TFBiomeSpookyForest.java new file mode 100644 index 0000000000..aa18900003 --- /dev/null +++ b/src/main/java/twilightforest/biomes/TFBiomeSpookyForest.java @@ -0,0 +1,136 @@ +package twilightforest.biomes; + +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.entity.monster.EntitySpider; +import net.minecraft.entity.passive.EntityBat; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenPumpkin; +import net.minecraft.world.gen.feature.WorldGenerator; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.block.BlockTFPlant; +import twilightforest.block.TFBlocks; +import twilightforest.entity.EntityTFSkeletonDruid; +import twilightforest.enums.PlantVariant; +import twilightforest.features.TFGenGraveyard; +import twilightforest.world.TFWorld; +import twilightforest.world.feature.TFGenCanopyTree; +import twilightforest.world.feature.TFGenFallenLeaves; +import twilightforest.world.feature.TFGenLampposts; +import twilightforest.world.feature.TFGenTallGrass; +import twilightforest.world.feature.TFGenWebs; + +import java.util.Random; + +public class TFBiomeSpookyForest extends TFBiomeBase { + + private final WorldGenerator tfGenWebs = new TFGenWebs(); + private final WorldGenerator tfGenLeaf = new TFGenFallenLeaves(); + private final WorldGenerator tfGenLampposts = new TFGenLampposts(Blocks.LIT_PUMPKIN.getDefaultState()); + private final WorldGenerator worldGenMushgloom = new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MUSHGLOOM)); + private final WorldGenerator worldGenDeadBush = new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.DEADBUSH), 8); + private final WorldGenerator graveyardGen = new TFGenGraveyard(); + private final WorldGenerator worldGenPumpkin = new WorldGenPumpkin(); + + public TFBiomeSpookyForest(BiomeProperties props) { + super(props); + + getTFBiomeDecorator().setFlowersPerChunk(1); + getTFBiomeDecorator().setGrassPerChunk(4); + getTFBiomeDecorator().setTreesPerChunk(2); + getTFBiomeDecorator().hasCanopy = false; + + spawnableCreatureList.add(new SpawnListEntry(EntityBat.class, 20, 8, 8)); + + spawnableMonsterList.add(new SpawnListEntry(EntitySpider.class, 50, 1, 4)); + spawnableMonsterList.add(new SpawnListEntry(EntitySkeleton.class, 20, 1, 4)); + spawnableMonsterList.add(new SpawnListEntry(EntityTFSkeletonDruid.class, 5, 1, 1)); + } + + @Override + public void decorate(World world, Random rand, BlockPos pos) { + super.decorate(world, rand, pos); + + float canopyPerChunk = 1.7F; + + // add canopy trees + int nc = (int) canopyPerChunk + ((rand.nextFloat() < (canopyPerChunk - (int) canopyPerChunk)) ? 1 : 0); + for (int i = 0; i < nc; i++) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + BlockPos genPos = new BlockPos(rx, world.getHeight(rx, rz), rz); + ((TFGenCanopyTree) getTFBiomeDecorator().canopyTreeGen).generate(world, rand, genPos, false); + } + + // shroom + if (rand.nextInt(24) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + // mushglooms + this.worldGenMushgloom.generate(world, rand, new BlockPos(rx, ry, rz)); + } + + // webs + for (int i = 0; i < 36; i++) { + int rx = pos.getX() + rand.nextInt(30) + 2; + int rz = pos.getZ() + rand.nextInt(30) + 2; + int ry = TFWorld.SEALEVEL + rand.nextInt(TFWorld.CHUNKHEIGHT - TFWorld.SEALEVEL); + + this.tfGenWebs.generate(world, rand, new BlockPos(rx, ry, rz)); + } + + // lamps with PUMPKINSSSSSS + if (rand.nextInt(2) == 0) { + int rx = pos.getX() + rand.nextInt(30) + 2; + int rz = pos.getZ() + rand.nextInt(30) + 2; + int ry = TFWorld.getGroundLevel(world, rx, rz); + + this.tfGenLampposts.generate(world, rand, new BlockPos(rx, ry, rz)); + } + + // extra pumpkins + if (rand.nextInt(16) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + + this.worldGenPumpkin.generate(world, rand, new BlockPos(rx, ry, rz)); + } + + // Dried Bush + for (int i = 0; i < 6; i++) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + worldGenDeadBush.generate(world, rand, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + + // Leaf Piles + for (int i = 0; i < 6; i++) { + int rx = pos.getX() + rand.nextInt(25) + 2; + int rz = pos.getZ() + rand.nextInt(25) + 2; + tfGenLeaf.generate(world, rand, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + + // graveyards for spooky forests + if (rand.nextFloat() < 0.05F) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + graveyardGen.generate(world, rand, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } + } + + @Override + @SideOnly(Side.CLIENT) + public int getGrassColorAtPos(BlockPos pos) { + return 0xC45123; + } + + @Override + @SideOnly(Side.CLIENT) + public int getFoliageColorAtPos(BlockPos pos) { + return 0xFF8501; + } +} diff --git a/src/main/java/twilightforest/biomes/TFBiomeStream.java b/src/main/java/twilightforest/biomes/TFBiomeStream.java index 1f991f541d..71b7b40685 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeStream.java +++ b/src/main/java/twilightforest/biomes/TFBiomeStream.java @@ -2,19 +2,9 @@ public class TFBiomeStream extends TFBiomeBase { - public TFBiomeStream(int i) { - super(i); - -// this.rootHeight = -0.75F; -// this.heightVariation = -0.10F; - - this.temperature = 0.5F; - this.rainfall = 1F; - - getTFBiomeDecorator().setWaterlilyPerChunk(2); - - spawnableCreatureList.clear(); - + public TFBiomeStream(BiomeProperties props) { + super(props); + getTFBiomeDecorator().setWaterlilyPerChunk(2); + spawnableCreatureList.clear(); } - } diff --git a/src/main/java/twilightforest/biomes/TFBiomeSwamp.java b/src/main/java/twilightforest/biomes/TFBiomeSwamp.java index 0e73433b67..6e68c7bb6a 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeSwamp.java +++ b/src/main/java/twilightforest/biomes/TFBiomeSwamp.java @@ -1,200 +1,162 @@ package twilightforest.biomes; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockOldLeaf; +import net.minecraft.block.BlockOldLog; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockTallGrass; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.potion.Potion; +import net.minecraft.init.MobEffects; import net.minecraft.potion.PotionEffect; -import net.minecraft.stats.Achievement; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.ColorizerFoliage; import net.minecraft.world.ColorizerGrass; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenAbstractTree; import net.minecraft.world.gen.feature.WorldGenShrub; import net.minecraft.world.gen.feature.WorldGenTallGrass; -import net.minecraft.world.gen.feature.WorldGenVines; import net.minecraft.world.gen.feature.WorldGenerator; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; import twilightforest.entity.EntityTFMosquitoSwarm; -import twilightforest.world.TFGenHugeLilyPad; +import twilightforest.world.feature.TFGenHugeLilyPad; +import twilightforest.world.feature.TFGenHugeWaterLily; +import twilightforest.world.feature.TFGenTallGrass; +import twilightforest.world.feature.TFGenVines; import twilightforest.world.TFWorld; - +import java.util.ArrayList; +import java.util.List; +import java.util.Random; public class TFBiomeSwamp extends TFBiomeBase { - + private static final int MONSTER_SPAWN_RATE = 20; - Random monsterRNG = new Random(53439L); - ArrayList emptyList = new ArrayList(); - - WorldGenVines worldgenvines = new WorldGenVines(); - WorldGenerator hugeLilyPadGen = new TFGenHugeLilyPad(); - WorldGenerator hugeWaterLilyGen = new TFGenHugeWaterLily(); - - - - @SuppressWarnings("unchecked") - public TFBiomeSwamp(int i) { - super(i); - -// this.rootHeight = -0.25F; -// this.heightVariation = 0.0F; - - this.temperature = 0.8F; - this.rainfall = 0.9F; - - getTFBiomeDecorator().setDeadBushPerChunk(1); - getTFBiomeDecorator().setMushroomsPerChunk(8); - getTFBiomeDecorator().setReedsPerChunk(10); - getTFBiomeDecorator().setClayPerChunk(1); - getTFBiomeDecorator().setTreesPerChunk(2); - getTFBiomeDecorator().setWaterlilyPerChunk(20); - waterColorMultiplier = 0xE0FFAE; - - - getTFBiomeDecorator().canopyPerChunk = -999; - getTFBiomeDecorator().lakesPerChunk = 2; - getTFBiomeDecorator().mangrovesPerChunk = 3; - - this.spawnableMonsterList.add(new SpawnListEntry(EntityTFMosquitoSwarm.class, 10, 1, 1)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityCreeper.class, 10, 4, 4)); - this.spawnableMonsterList.add(new SpawnListEntry(EntityZombie.class, 10, 4, 4)); + + private final Random monsterRNG = new Random(53439L); + + private final WorldGenerator vinesGen = new TFGenVines(); + private final WorldGenerator hugeLilyPadGen = new TFGenHugeLilyPad(); + private final WorldGenerator hugeWaterLilyGen = new TFGenHugeWaterLily(); + + public TFBiomeSwamp(BiomeProperties props) { + super(props); + + getTFBiomeDecorator().setDeadBushPerChunk(1); + getTFBiomeDecorator().setMushroomsPerChunk(8); + getTFBiomeDecorator().setReedsPerChunk(10); + getTFBiomeDecorator().setClayPerChunk(1); + getTFBiomeDecorator().setTreesPerChunk(2); + getTFBiomeDecorator().setWaterlilyPerChunk(20); + + getTFBiomeDecorator().hasCanopy = false; + getTFBiomeDecorator().lakesPerChunk = 2; + getTFBiomeDecorator().mangrovesPerChunk = 3; + + this.spawnableMonsterList.add(new SpawnListEntry(EntityTFMosquitoSwarm.class, 10, 1, 1)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityCreeper.class, 10, 4, 4)); + this.spawnableMonsterList.add(new SpawnListEntry(EntityZombie.class, 10, 4, 4)); } - public WorldGenAbstractTree func_150567_a(Random random) - { - if (random.nextInt(3) == 0) - { - return new WorldGenShrub(3, 0); - } - - return worldGeneratorSwamp; - } - - /** - * Ferns! - */ - public WorldGenerator getRandomWorldGenForGrass(Random par1Random) - { - if (par1Random.nextInt(4) == 0) - { - return new WorldGenTallGrass(Blocks.tallgrass, 2); - } - else if (par1Random.nextInt(4) == 0) - { - return new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_MAYAPPLE); - } - else - { - return new WorldGenTallGrass(Blocks.tallgrass, 1); - } - } - - /** - * Decorate this biome. This is stolen from the jungle code - */ - @Override - public void decorate(World par1World, Random par2Random, int par3, int par4) - { - super.decorate(par1World, par2Random, par3, par4); - - for (int i = 0; i < 50; i++) - { - int j = par3 + par2Random.nextInt(16) + 8; - byte byte0 = (byte) TFWorld.SEALEVEL; - int k = par4 + par2Random.nextInt(16) + 8; - worldgenvines.generate(par1World, par2Random, j, byte0, k); - } - for (int i = 0; i < 25; i++) - { - int x = par3 + par2Random.nextInt(16) + 8; - int y = TFWorld.SEALEVEL; - int z = par4 + par2Random.nextInt(16) + 8; - hugeLilyPadGen.generate(par1World, par2Random, x, y, z); - } - for (int i = 0; i < 2; i++) - { - int x = par3 + par2Random.nextInt(16) + 8; - int y = TFWorld.SEALEVEL; - int z = par4 + par2Random.nextInt(16) + 8; - hugeWaterLilyGen.generate(par1World, par2Random, x, y, z); - } - } - - /** - * Provides the basic grass color based on the biome temperature and rainfall - */ - @Override - public int getBiomeGrassColor(int x, int y, int z) - { - double var1 = (double)MathHelper.clamp_float(this.getFloatTemperature(x, y, z), 0.0F, 1.0F); - double var3 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); - return ((ColorizerGrass.getGrassColor(var1, var3) & 0xFEFEFE) + 0x4E0E4E) / 2; - } - - /** - * Provides the basic foliage color based on the biome temperature and rainfall - */ - @Override - public int getBiomeFoliageColor(int x, int y, int z) - { - double var1 = (double)MathHelper.clamp_float(this.getFloatTemperature(x, y, z), 0.0F, 1.0F); - double var3 = (double)MathHelper.clamp_float(this.getFloatRainfall(), 0.0F, 1.0F); - return ((ColorizerFoliage.getFoliageColor(var1, var3) & 0xFEFEFE) + 0x4E0E4E) / 2; - } - - - /** - * Returns the correspondent list of the EnumCreatureType informed. - */ - @SuppressWarnings("rawtypes") @Override - public List getSpawnableList(EnumCreatureType par1EnumCreatureType) - { - // if is is monster, then only give it the real list 1/MONSTER_SPAWN_RATE of the time - if (par1EnumCreatureType == EnumCreatureType.monster) { - return monsterRNG.nextInt(MONSTER_SPAWN_RATE) == 0 ? this.spawnableMonsterList : emptyList; - } - else { - return par1EnumCreatureType == EnumCreatureType.creature ? this.spawnableCreatureList : (par1EnumCreatureType == EnumCreatureType.waterCreature ? this.spawnableWaterCreatureList : (par1EnumCreatureType == EnumCreatureType.ambient ? this.spawnableCaveCreatureList : null)); - } - } - - /** - * If there is a required achievement to be here, return it, otherwise return null - */ - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressLich; + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(3) == 0) { + return new WorldGenShrub( + Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE), + Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK).withProperty(BlockLeaves.CHECK_DECAY, false) + ); + } else { + return SWAMP_FEATURE; + } } - /** - * Do something bad to a player in the wrong biome. - */ - public void enforceProgession(EntityPlayer player, World world) { - if (!world.isRemote && world.getWorldTime() % 60 == 0) { - //System.out.println("Player " + player.getDisplayName() + " is in the swamp without the achievement"); + @Override + public WorldGenerator getRandomWorldGenForGrass(Random random) { + if (random.nextInt(4) == 0) { + return new WorldGenTallGrass(BlockTallGrass.EnumType.FERN); + } else if (random.nextInt(4) == 0) { + return new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MAYAPPLE)); + } else { + return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); + } + } + + @Override + public void decorate(World world, Random random, BlockPos pos) { + super.decorate(world, random, pos); + + for (int i = 0; i < 50; i++) { + int x = pos.getX() + random.nextInt(16) + 8; + int y = TFWorld.SEALEVEL + 128; + int z = pos.getZ() + random.nextInt(16) + 8; + vinesGen.generate(world, random, new BlockPos(x, y, z)); + } + for (int i = 0; i < 25; i++) { + int x = pos.getX() + random.nextInt(15) + 8; + int y = TFWorld.SEALEVEL; + int z = pos.getZ() + random.nextInt(15) + 8; + hugeLilyPadGen.generate(world, random, new BlockPos(x, y, z)); + } + for (int i = 0; i < 2; i++) { + int x = pos.getX() + random.nextInt(16) + 8; + int y = TFWorld.SEALEVEL; + int z = pos.getZ() + random.nextInt(16) + 8; + hugeWaterLilyGen.generate(world, random, new BlockPos(x, y, z)); + } + } + + @Override + public int getGrassColorAtPos(BlockPos pos) { + double temperature = (double) MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); + double humidity = (double) MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); + return ((ColorizerGrass.getGrassColor(temperature, humidity) & 0xFEFEFE) + 0x4E0E4E) / 2; + } + + @Override + public int getFoliageColorAtPos(BlockPos pos) { + double temperature = (double) MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F); + double humidity = (double) MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F); + return ((ColorizerFoliage.getFoliageColor(temperature, humidity) & 0xFEFEFE) + 0x4E0E4E) / 2; + } + + @Override + public List getSpawnableList(EnumCreatureType creatureType) { + // if it is monster, then only give it the real list 1/MONSTER_SPAWN_RATE of the time + if (creatureType == EnumCreatureType.MONSTER) { + return monsterRNG.nextInt(MONSTER_SPAWN_RATE) == 0 ? this.spawnableMonsterList : new ArrayList<>(); + } + return super.getSpawnableList(creatureType); + } + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_lich") }; + } + + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 60 == 0) { + PotionEffect currentHunger = player.getActivePotionEffect(MobEffects.HUNGER); - PotionEffect currentHunger = player.getActivePotionEffect(Potion.hunger); - int hungerLevel = currentHunger != null ? currentHunger.getAmplifier() + 1 : 1; - - player.addPotionEffect(new PotionEffect(Potion.hunger.id, 100, hungerLevel)); - //((EntityLivingBase)par1Entity).addPotionEffect(new PotionEffect(Potion.hunger.id, duration * 20, 0)); - - // hint monster? - if (world.rand.nextInt(4) == 0) { - TFFeature.labyrinth.trySpawnHintMonster(world, player); - } + + player.addPotionEffect(new PotionEffect(MobEffects.HUNGER, 100, hungerLevel)); + + trySpawnHintMonster(player, world); } } + + @Override + protected TFFeature getContainedFeature() { + return TFFeature.LABYRINTH; + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeThornlands.java b/src/main/java/twilightforest/biomes/TFBiomeThornlands.java index a87ffb18a6..294c664390 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeThornlands.java +++ b/src/main/java/twilightforest/biomes/TFBiomeThornlands.java @@ -1,93 +1,78 @@ package twilightforest.biomes; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.stats.Achievement; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; -import twilightforest.TFAchievementPage; +import net.minecraft.world.gen.feature.WorldGenerator; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFDeadrock; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenThorns; +import twilightforest.enums.DeadrockVariant; +import twilightforest.world.feature.TFGenThorns; import twilightforest.world.TFWorld; +import java.util.Random; +import java.util.function.Predicate; + public class TFBiomeThornlands extends TFBiomeBase { - private TFGenThorns tfGenThorns; + private final WorldGenerator tfGenThorns = new TFGenThorns(); + + public TFBiomeThornlands(BiomeProperties props) { + super(props); + this.topBlock = TFBlocks.deadrock.getDefaultState().withProperty(BlockTFDeadrock.VARIANT, DeadrockVariant.SURFACE); + this.fillerBlock = TFBlocks.deadrock.getDefaultState().withProperty(BlockTFDeadrock.VARIANT, DeadrockVariant.CRACKED); - public TFBiomeThornlands(int i) { - super(i); - - this.topBlock = TFBlocks.deadrock; - this.field_150604_aj = 0; - this.fillerBlock = TFBlocks.deadrock; - this.field_76754_C = 1; - - this.temperature = 0.3F; - this.rainfall = 0.2F; - - getTFBiomeDecorator().canopyPerChunk = -999; + getTFBiomeDecorator().hasCanopy = false; getTFBiomeDecorator().setTreesPerChunk(-999); - this.theBiomeDecorator.deadBushPerChunk = 2; - this.theBiomeDecorator.cactiPerChunk = -9999; - this.spawnableCreatureList.clear(); - - this.tfGenThorns = new TFGenThorns(); - - this.theBiomeDecorator.generateLakes = false; + this.decorator.deadBushPerChunk = 2; + this.decorator.cactiPerChunk = -9999; // gotta be sure + this.spawnableCreatureList.clear(); + + this.decorator.generateFalls = false; } - - - public void decorate(World world, Random rand, int mapX, int mapZ) - { - super.decorate(world, rand, mapX, mapZ); - - // add thorns! - for (int i = 0; i < 128; i++) - { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - this.tfGenThorns.generate(world, rand, rx, ry, rz); - } - } + @Override + public void decorate(World world, Random rand, BlockPos pos) { + // add thorns! + for (int i = 0; i < 128; i++) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz, otherGround); - public int getGroundLevel(World world, int x, int z) { - // go from sea level up. If we get grass, return that, otherwise return the last dirt, stone or gravel we got - Chunk chunk = world.getChunkFromBlockCoords(x, z); - int lastDirt = TFWorld.SEALEVEL; - for (int y = TFWorld.SEALEVEL; y < TFWorld.CHUNKHEIGHT - 1; y++) { - Block blockID = chunk.getBlock(x & 15, y, z & 15); - // grass = return immediately - if (blockID == Blocks.grass) { - return y + 1; - } - else if (blockID == Blocks.dirt || blockID == Blocks.stone || blockID == Blocks.gravel || blockID == Blocks.sandstone || blockID == Blocks.sand || blockID == Blocks.clay || blockID == TFBlocks.deadrock) { - lastDirt = y + 1; - } + this.tfGenThorns.generate(world, rand, new BlockPos(rx, ry, rz)); } - - return lastDirt; } - - /** - * Return a block if you want it to replace stone in the terrain generation - */ - public Block getStoneReplacementBlock() { - return TFBlocks.deadrock; + + private final Predicate otherGround = block -> block == Blocks.SANDSTONE || block == Blocks.SAND || block == Blocks.CLAY || block == TFBlocks.deadrock; + + @Override + public IBlockState getStoneReplacementState() { + return TFBlocks.deadrock.getDefaultState().withProperty(BlockTFDeadrock.VARIANT, DeadrockVariant.SOLID); } - - /** - * Metadata for the stone replacement block - */ - public byte getStoneReplacementMeta() { - return 2; + + @Override + protected ResourceLocation[] getRequiredAdvancements() { + return new ResourceLocation[]{ TwilightForestMod.prefix("progress_troll") }; } - - protected Achievement getRequiredAchievement() { - return TFAchievementPage.twilightProgressGlacier; + + @Override + public void enforceProgression(EntityPlayer player, World world) { + if (!world.isRemote && player.ticksExisted % 5 == 0) { + player.attackEntityFrom(DamageSource.MAGIC, 1.0F); + world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, SoundCategory.PLAYERS, 1.0F, 1.0F); + + // hint monster? + if (world.rand.nextInt(4) == 0) TFFeature.TROLL_CAVE.trySpawnHintMonster(world, player); + } } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeTwilightForest.java b/src/main/java/twilightforest/biomes/TFBiomeTwilightForest.java deleted file mode 100644 index 43a96f8890..0000000000 --- a/src/main/java/twilightforest/biomes/TFBiomeTwilightForest.java +++ /dev/null @@ -1,12 +0,0 @@ -package twilightforest.biomes; - - -public class TFBiomeTwilightForest extends TFBiomeBase { - - public TFBiomeTwilightForest(int i) - { - super(i); - - } - -} diff --git a/src/main/java/twilightforest/biomes/TFBiomeTwilightForestVariant.java b/src/main/java/twilightforest/biomes/TFBiomeTwilightForestVariant.java index 1074fe07e1..1dd0897af3 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeTwilightForestVariant.java +++ b/src/main/java/twilightforest/biomes/TFBiomeTwilightForestVariant.java @@ -1,90 +1,68 @@ package twilightforest.biomes; -import java.util.Random; - -import net.minecraft.init.Blocks; +import net.minecraft.block.BlockDoublePlant; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockTallGrass; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenAbstractTree; -import net.minecraft.world.gen.feature.WorldGenBigTree; -import net.minecraft.world.gen.feature.WorldGenShrub; -import net.minecraft.world.gen.feature.WorldGenTallGrass; -import net.minecraft.world.gen.feature.WorldGenerator; +import net.minecraft.world.gen.feature.*; +import twilightforest.block.BlockTFLeaves; +import twilightforest.block.BlockTFLog; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; +import twilightforest.enums.LeavesVariant; +import twilightforest.enums.PlantVariant; +import twilightforest.enums.WoodVariant; +import twilightforest.world.feature.TFGenTallGrass; +import java.util.Random; public class TFBiomeTwilightForestVariant extends TFBiomeBase { - public TFBiomeTwilightForestVariant(int i) { - super(i); - - this.temperature = 0.7F; - this.rainfall = 0.8F; - -// this.rootHeight = 0.15F; -// this.heightVariation = 0.4F; - + public TFBiomeTwilightForestVariant(BiomeProperties props) { + super(props); + getTFBiomeDecorator().setTreesPerChunk(25); getTFBiomeDecorator().setGrassPerChunk(15); getTFBiomeDecorator().setFlowersPerChunk(8); } - - /** - * Occasional shrub, no birches - */ - public WorldGenAbstractTree func_150567_a(Random random) - { - if(random.nextInt(5) == 0) - { - return new WorldGenShrub(3, 0); - } - else if(random.nextInt(10) == 0) - { - return new WorldGenBigTree(false); - } - else - { - return worldGeneratorTrees; - } - } - - /** - * EVEN MOAR FERNZ! - */ - public WorldGenerator getRandomWorldGenForGrass(Random par1Random) - { - if (par1Random.nextInt(4) != 0) - { - return new WorldGenTallGrass(Blocks.tallgrass, 2); - } - else if (par1Random.nextBoolean()) - { - return new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_MAYAPPLE); - } - else - { - return new WorldGenTallGrass(Blocks.tallgrass, 1); - } - } - - /** - * Add tall ferns - */ - public void decorate(World par1World, Random par2Random, int par3, int par4) - { - genTallFlowers.func_150548_a(3); + @Override + public WorldGenAbstractTree getRandomTreeFeature(Random random) { + if (random.nextInt(5) == 0) { + return new WorldGenShrub( + TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.OAK), + TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockTFLeaves.VARIANT, LeavesVariant.OAK).withProperty(BlockLeaves.CHECK_DECAY, false) + ); + } else if (random.nextInt(10) == 0) { + return new WorldGenBigTree(false); + } else { + return TREE_FEATURE; + } + } - for (int i = 0; i < 7; ++i) - { - int rx = par3 + par2Random.nextInt(16) + 8; - int rz = par4 + par2Random.nextInt(16) + 8; - int ry = par2Random.nextInt(par1World.getHeightValue(rx, rz) + 32); - genTallFlowers.generate(par1World, par2Random, rx, ry, rz); - } + @Override + public WorldGenerator getRandomWorldGenForGrass(Random random) { + if (random.nextInt(4) != 0) { + return new WorldGenTallGrass(BlockTallGrass.EnumType.FERN); + } else if (random.nextBoolean()) { + return new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MAYAPPLE)); + } else { + return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS); + } + } - super.decorate(par1World, par2Random, par3, par4); - } + @Override + public void decorate(World world, Random random, BlockPos pos) { + DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.FERN); + for (int i = 0; i < 7; ++i) { + int rx = pos.getX() + random.nextInt(16) + 8; + int rz = pos.getZ() + random.nextInt(16) + 8; + int ry = random.nextInt(world.getHeight(rx, rz) + 32); + DOUBLE_PLANT_GENERATOR.generate(world, random, new BlockPos(rx, ry, rz)); + } + super.decorate(world, random, pos); + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomeTwilightLake.java b/src/main/java/twilightforest/biomes/TFBiomeTwilightLake.java index d28692088f..66473184be 100644 --- a/src/main/java/twilightforest/biomes/TFBiomeTwilightLake.java +++ b/src/main/java/twilightforest/biomes/TFBiomeTwilightLake.java @@ -1,23 +1,17 @@ package twilightforest.biomes; import net.minecraft.entity.passive.EntitySquid; +import twilightforest.TFFeature; public class TFBiomeTwilightLake extends TFBiomeBase { - @SuppressWarnings("unchecked") - public TFBiomeTwilightLake(int i) { - super(i); - - -// this.rootHeight = -1.9F; -// this.heightVariation = 0.5F; - - this.temperature = 0.66F; - this.rainfall = 1F; - - //spawnableCreatureList.clear(); - this.spawnableWaterCreatureList.add(new SpawnListEntry(EntitySquid.class, 10, 4, 4)); - + public TFBiomeTwilightLake(BiomeProperties props) { + super(props); + this.spawnableWaterCreatureList.add(new SpawnListEntry(EntitySquid.class, 10, 4, 4)); } + @Override + protected TFFeature getContainedFeature() { + return TFFeature.QUEST_ISLAND; + } } diff --git a/src/main/java/twilightforest/biomes/TFBiomes.java b/src/main/java/twilightforest/biomes/TFBiomes.java new file mode 100644 index 0000000000..c7a8a5037e --- /dev/null +++ b/src/main/java/twilightforest/biomes/TFBiomes.java @@ -0,0 +1,75 @@ +package twilightforest.biomes; + +import net.minecraft.world.biome.Biome; +import twilightforest.TwilightForestMod; + +import static net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; + +@SuppressWarnings("all") +@ObjectHolder(TwilightForestMod.ID) +public class TFBiomes { + @ObjectHolder("twilight_lake") + public static final Biome tfLake; + @ObjectHolder("twilight_forest") + public static final Biome twilightForest; + @ObjectHolder("dense_twilight_forest") + public static final Biome denseTwilightForest; + @ObjectHolder("twilight_highlands") + public static final Biome highlands; + @ObjectHolder("mushroom_forest") + public static final Biome mushrooms; + @ObjectHolder("twilight_swamp") + public static final Biome tfSwamp; + @ObjectHolder("twilight_stream") + public static final Biome stream; + @ObjectHolder("snowy_forest") + public static final Biome snowy_forest; + @ObjectHolder("twilight_glacier") + public static final Biome glacier; + @ObjectHolder("twilight_clearing") + public static final Biome clearing; + @ObjectHolder("oak_savannah") + public static final Biome oakSavanna; + @ObjectHolder("firefly_forest") + public static final Biome fireflyForest; + @ObjectHolder("deep_mushroom_forest") + public static final Biome deepMushrooms; + @ObjectHolder("dark_forest") + public static final Biome darkForest; + @ObjectHolder("enchanted_forest") + public static final Biome enchantedForest; + @ObjectHolder("fire_swamp") + public static final Biome fireSwamp; + @ObjectHolder("dark_forest_center") + public static final Biome darkForestCenter; + @ObjectHolder("highlands_center") + public static final Biome highlandsCenter; + @ObjectHolder("thornlands") + public static final Biome thornlands; + @ObjectHolder("spooky_forest") + public static final Biome spookyForest; + + //Much as I hate doing this, it tricks IntelliJ into thinking they're not null + static { + tfLake = null; + twilightForest = null; + denseTwilightForest = null; + highlands = null; + mushrooms = null; + tfSwamp = null; + stream = null; + snowy_forest = null; + glacier = null; + clearing = null; + oakSavanna = null; + fireflyForest = null; + deepMushrooms = null; + darkForest = null; + enchantedForest = null; + fireSwamp = null; + darkForestCenter = null; + highlandsCenter = null; + thornlands = null; + spookyForest = null; + } +} diff --git a/src/main/java/twilightforest/biomes/TFDarkForestBiomeDecorator.java b/src/main/java/twilightforest/biomes/TFDarkForestBiomeDecorator.java index 0b57d6c009..6832fb99b1 100644 --- a/src/main/java/twilightforest/biomes/TFDarkForestBiomeDecorator.java +++ b/src/main/java/twilightforest/biomes/TFDarkForestBiomeDecorator.java @@ -1,155 +1,113 @@ package twilightforest.biomes; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.feature.WorldGenPumpkin; -import net.minecraft.world.gen.feature.WorldGenTallGrass; import net.minecraft.world.gen.feature.WorldGenerator; import twilightforest.TFFeature; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenDarkCanopyTree; -import twilightforest.world.TFGenTallGrass; -import twilightforest.world.TFTreeGenerator; +import twilightforest.enums.PlantVariant; +import twilightforest.world.feature.TFGenDarkCanopyTree; +import twilightforest.world.feature.TFGenTallGrass; import twilightforest.world.TFWorld; -public class TFDarkForestBiomeDecorator extends TFBiomeDecorator { - - TFTreeGenerator darkCanopyTreeGen; - TFGenTallGrass worldGenDeadBush; - WorldGenTallGrass worldGenForestGrass; - WorldGenTallGrass worldGenMushgloom; - +import java.util.Random; - public TFDarkForestBiomeDecorator() { - super(); +public class TFDarkForestBiomeDecorator extends TFBiomeDecorator { - darkCanopyTreeGen = new TFGenDarkCanopyTree(); - worldGenDeadBush = new TFGenTallGrass(TFBlocks.plant, BlockTFPlant.META_DEADBUSH, 8); - worldGenForestGrass = new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_FORESTGRASS); - worldGenMushgloom = new WorldGenTallGrass(TFBlocks.plant, BlockTFPlant.META_MUSHGLOOM); - } + private final WorldGenerator darkCanopyTreeGen = new TFGenDarkCanopyTree(); + private final WorldGenerator worldGenDeadBush = new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.DEADBUSH), 8); + private final WorldGenerator worldGenForestGrass = new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.FORESTGRASS)); + private final WorldGenerator worldGenMushgloom = new TFGenTallGrass(TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MUSHGLOOM)); - /** - * Decorates the world. Calls code that was formerly (pre-1.8) in ChunkProviderGenerate.populate - */ @Override - public void decorateChunk(World world, Random rand, BiomeGenBase biome, int mapX, int mapZ) { + public void decorate(World world, Random rand, Biome biome, BlockPos pos) { // just decorate with what we need here - TFFeature nearFeature = TFFeature.getNearestFeature(mapX >> 4, mapZ >> 4, world); - if (nearFeature.areChunkDecorationsEnabled) { - // add dark canopy trees - int nc = (int)canopyPerChunk + ((rand.nextFloat() < (canopyPerChunk - (int)canopyPerChunk)) ? 1 : 0); - for (int i = 0; i < nc; i++) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = world.getHeightValue(rx, rz); - darkCanopyTreeGen.generate(world, rand, rx, ry, rz); - } + TFFeature nearFeature = TFFeature.getNearestFeature(pos.getX() >> 4, pos.getZ() >> 4, world); + if (nearFeature.areChunkDecorationsEnabled) { + // add dark canopy trees + int nc = (int) canopyPerChunk + ((rand.nextFloat() < (canopyPerChunk - (int) canopyPerChunk)) ? 1 : 0); + for (int i = 0; i < nc; i++) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + darkCanopyTreeGen.generate(world, rand, new BlockPos(rx, world.getHeight(rx, rz), rz)); + } - // regular trees - for (int i = 0; i < this.treesPerChunk; ++i) - { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - WorldGenerator var5 = biome.func_150567_a(rand); - var5.setScale(1.0D, 1.0D, 1.0D); - var5.generate(world, rand, rx, ry, rz); - } + // regular trees + for (int i = 0; i < this.treesPerChunk; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + WorldGenerator treeFeature = biome.getRandomTreeFeature(rand); + treeFeature.setDecorationDefaults(); + treeFeature.generate(world, rand, new BlockPos(rx, ry, rz)); + } - // dead bushes - for (int i = 0; i < this.deadBushPerChunk; ++i) - { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = rand.nextInt(128); - worldGenDeadBush.generate(world, rand, rx, ry, rz); - } + // dead bushes + for (int i = 0; i < this.deadBushPerChunk; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = rand.nextInt(128); + worldGenDeadBush.generate(world, rand, new BlockPos(rx, ry, rz)); + } - // forest grass bushes - for (int i = 0; i < this.deadBushPerChunk; ++i) - { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = rand.nextInt(128); - worldGenForestGrass.generate(world, rand, rx, ry, rz); - } + // forest grass bushes + for (int i = 0; i < this.deadBushPerChunk; ++i) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = rand.nextInt(128); + worldGenForestGrass.generate(world, rand, new BlockPos(rx, ry, rz)); + } - // mushrooms - for (int i = 0; i < this.mushroomsPerChunk; ++i) - { - if (rand.nextInt(8) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - this.mushroomBrownGen.generate(world, rand, rx, ry, rz); - } - if (rand.nextInt(16) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - this.mushroomRedGen.generate(world, rand, rx, ry, rz); - } - if (rand.nextInt(24) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - // mushglooms - worldGenMushgloom.generate(world, rand, rx, ry, rz); - } - } - if (rand.nextInt(4) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = rand.nextInt(128); - this.mushroomBrownGen.generate(world, rand, rx, ry, rz); - } - if (rand.nextInt(8) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = rand.nextInt(128); - this.mushroomRedGen.generate(world, rand, rx, ry, rz); - } - - // pumpkins - if (rand.nextInt(32) == 0) { - int rx = mapX + rand.nextInt(16) + 8; - int rz = mapZ + rand.nextInt(16) + 8; - int ry = getGroundLevel(world, rx, rz); - (new WorldGenPumpkin()).generate(world, rand, rx, ry, rz); - } + // mushrooms + for (int i = 0; i < this.mushroomsPerChunk; ++i) { + if (rand.nextInt(8) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + this.mushroomBrownGen.generate(world, rand, new BlockPos(rx, ry, rz)); + } + if (rand.nextInt(16) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + this.mushroomRedGen.generate(world, rand, new BlockPos(rx, ry, rz)); + } + if (rand.nextInt(24) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + // mushglooms + worldGenMushgloom.generate(world, rand, new BlockPos(rx, ry, rz)); + } + } + if (rand.nextInt(4) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = rand.nextInt(128); + this.mushroomBrownGen.generate(world, rand, new BlockPos(rx, ry, rz)); + } + if (rand.nextInt(8) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = rand.nextInt(128); + this.mushroomRedGen.generate(world, rand, new BlockPos(rx, ry, rz)); + } - } - - // do underground decorations - decorateUnderground(world, rand, mapX, mapZ); - decorateOnlyOres(world, rand, mapX, mapZ); + // pumpkins + if (rand.nextInt(32) == 0) { + int rx = pos.getX() + rand.nextInt(16) + 8; + int rz = pos.getZ() + rand.nextInt(16) + 8; + int ry = TFWorld.getGroundLevel(world, rx, rz); + new WorldGenPumpkin().generate(world, rand, new BlockPos(rx, ry, rz)); + } - } - - - public int getGroundLevel(World world, int x, int z) { - // go from sea level up. If we get grass, return that, otherwise return the last dirt, stone or gravel we got - Chunk chunk = world.getChunkFromBlockCoords(x, z); - int lastDirt = TFWorld.SEALEVEL; - for (int y = TFWorld.SEALEVEL; y < TFWorld.CHUNKHEIGHT - 1; y++) { - Block blockID = chunk.getBlock(x & 15, y, z & 15); - // grass = return immediately - if (blockID == Blocks.grass) { - return y + 1; - } - else if (blockID == Blocks.dirt || blockID == Blocks.stone || blockID == Blocks.gravel) { - lastDirt = y + 1; - } - } - - return lastDirt; - } + } + // do underground decorations + decorateUnderground(world, rand, pos); + decorateOnlyOres(world, rand, pos); + } } diff --git a/src/main/java/twilightforest/biomes/TFGenHugeWaterLily.java b/src/main/java/twilightforest/biomes/TFGenHugeWaterLily.java deleted file mode 100644 index fc965cf2d6..0000000000 --- a/src/main/java/twilightforest/biomes/TFGenHugeWaterLily.java +++ /dev/null @@ -1,44 +0,0 @@ -package twilightforest.biomes; - -import java.util.Random; - -import twilightforest.block.TFBlocks; -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenerator; - - -/** - * Generate huge lily pads - * - * @author Ben - * - */ -public class TFGenHugeWaterLily extends WorldGenerator -{ - - private Random rand = new Random(); - - - public boolean generate(World world, Random random, int x, int y, int z) - { - for (int i = 0; i < 4; i++) { - int dx = x + random.nextInt(8) - random.nextInt(8); - int dy = y + random.nextInt(4) - random.nextInt(4); - int dz = z + random.nextInt(8) - random.nextInt(8); - - if (shouldPlacePadAt(world, dx, dy, dz)) { - world.setBlock(dx, dy, dz, TFBlocks.hugeWaterLily); - } - } - - return true; - } - - - private boolean shouldPlacePadAt(World world, int dx, int dy, int dz) { - return world.isAirBlock(dx, dy, dz) && world.getBlock(dx, dy - 1, dz).getMaterial() == Material.water; - } -} diff --git a/src/main/java/twilightforest/block/BlockTF.java b/src/main/java/twilightforest/block/BlockTF.java new file mode 100644 index 0000000000..e90868614a --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTF.java @@ -0,0 +1,18 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTF extends Block implements ModelRegisterCallback { + public BlockTF(Material blockMaterialIn, MapColor blockMapColorIn) { + super(blockMaterialIn, blockMapColorIn); + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFAuroraBrick.java b/src/main/java/twilightforest/block/BlockTFAuroraBrick.java index 66def7d507..419bc658a3 100644 --- a/src/main/java/twilightforest/block/BlockTFAuroraBrick.java +++ b/src/main/java/twilightforest/block/BlockTFAuroraBrick.java @@ -1,165 +1,273 @@ package twilightforest.block; -import java.util.List; - import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyInteger; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFAuroraBrick extends Block { - - private static IIcon[] icons; +public class BlockTFAuroraBrick extends Block implements ModelRegisterCallback { + public static final IProperty VARIANT = PropertyInteger.create("variant", 0, 15); public BlockTFAuroraBrick() { - super(Material.packedIce); - + super(Material.PACKED_ICE); + this.setCreativeTab(TFItems.creativeTab); this.setHardness(2.0F); this.setResistance(10.0F); } + private static float getFractalNoise(int iteration, float size, BlockPos pos) { + return iteration == 0 ? 0 : ((SimplexNoise.noise( + ((float) pos.getX() + (iteration * size)) / size, + ((float) pos.getY() + (iteration * size)) / size, + ((float) pos.getZ() + (iteration * size)) / size) + + 1.0f) * 0.5f) + getFractalNoise(iteration - 1, size, pos); + } + + public static float fractalNoise(int iterations, float size, BlockPos pos) { + return getFractalNoise(iterations, size, pos) / (float) iterations; + } + + public static float rippleFractialNoise(int iterations, float size, BlockPos pos, float minimum, float maximum, float frequency) { + float i = maximum - minimum; + return Math.abs(((getFractalNoise(iterations, size, pos) * frequency) % (2 * i)) - i) + minimum; + } @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFAuroraBrick.icons = new IIcon[8]; - BlockTFAuroraBrick.icons[0] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick0"); - BlockTFAuroraBrick.icons[1] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick1"); - BlockTFAuroraBrick.icons[2] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick2"); - BlockTFAuroraBrick.icons[3] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick3"); - BlockTFAuroraBrick.icons[4] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick4"); - BlockTFAuroraBrick.icons[5] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick5"); - BlockTFAuroraBrick.icons[6] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick6"); - BlockTFAuroraBrick.icons[7] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick7"); - -// BlockTFAuroraBrick.icons[0] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick0"); -// BlockTFAuroraBrick.icons[1] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick2"); -// BlockTFAuroraBrick.icons[2] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick4"); -// BlockTFAuroraBrick.icons[3] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurorabrick6"); + @Deprecated + public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) { + return getDefaultState().withProperty(VARIANT, ((int) ((fractalNoise(3, 48.0f, pos) * 120.0f) % 16.0f)) % 16); + } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); } + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT); + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ @Override - public IIcon getIcon(int side, int meta) { - if (meta < 8) { - return icons[meta]; - } else { - return icons[15 - meta]; - } - -// switch (meta % 8) { -// default: -// return icons[(meta % 8) * 2]; -// case 4: -// case 5: -// case 6: -// case 7: -// return icons[(7 - (meta % 8)) * 2]; -// } - + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState(); } - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ @Override - public int colorMultiplier(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int red = 0; - int green = 0; - int blue = 0; + public void getSubBlocks(CreativeTabs tab, NonNullList items) { + items.add(new ItemStack(this, 1, 0)); + } + + @Override + public int damageDropped(IBlockState state) { + return 0; + } + /* + * A speed-improved simplex noise algorithm for 2D, 3D and 4D in Java. + * + * Based on example code by Stefan Gustavson (stegu@itn.liu.se). + * Optimisations by Peter Eastman (peastman@drizzle.stanford.edu). + * Better rank ordering method for 4D by Stefan Gustavson in 2012. + * + * This could be speeded up even further, but it's useful as it is. + * + * Version 2012-03-09 + * + * This code was placed in the public domain by its original author, + * Stefan Gustavson. You may use it as you see fit, but + * attribution is appreciated. + * + */ - // aurora fade - red = 16; + private static class SimplexNoise { // Simplex noise in 2D, 3D and 4D + private static Grad grad3[] = {new Grad(1, 1, 0), new Grad(-1, 1, 0), new Grad(1, -1, 0), new Grad(-1, -1, 0), + new Grad(1, 0, 1), new Grad(-1, 0, 1), new Grad(1, 0, -1), new Grad(-1, 0, -1), + new Grad(0, 1, 1), new Grad(0, -1, 1), new Grad(0, 1, -1), new Grad(0, -1, -1)}; - blue = x * 12 + z * 6; - if ((blue & 256) != 0){ - blue = 255 - (blue & 255); - } - blue ^= 255; - blue &= 255; + private static short p[] = {151, 160, 137, 91, 90, 15, + 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, + 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, + 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, + 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, + 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, + 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, + 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, + 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, + 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, + 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, + 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, + 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180}; + // To remove the need for index wrapping, double the permutation table length + private static short perm[] = new short[512]; + private static short permMod12[] = new short[512]; - green = x * 4 + z * 8; - if ((green & 256) != 0){ - green = 255 - (green & 255); + static { + for (int i = 0; i < 512; i++) { + perm[i] = p[i & 255]; + permMod12[i] = (short) (perm[i] % 12); + } } - green &= 255; - // don't let things get black - if (green + blue < 128){ - green = 128 - blue; + // Skewing and unskewing factors for 2, 3, and 4 dimensions + private static final float F3 = 1.0f / 3.0f; + private static final float G3 = 1.0f / 6.0f; + + // This method is a *lot* faster than using (int)Math.floor(x) + private static int fastfloor(float x) { + int xi = (int) x; + return x < xi ? xi - 1 : xi; } - return red << 16 | blue << 8 | green; - } + private static float dot(Grad g, float x, float y, float z) { + return g.x * x + g.y * y + g.z * z; + } + // 3D simplex noise + static float noise(float xin, float yin, float zin) { + float n0, n1, n2, n3; // Noise contributions from the four corners + // Skew the input space to determine which simplex cell we're in + float s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D + int i = fastfloor(xin + s); + int j = fastfloor(yin + s); + int k = fastfloor(zin + s); + float t = (i + j + k) * G3; + float X0 = i - t; // Unskew the cell origin back to (x,y,z) space + float Y0 = j - t; + float Z0 = k - t; + float x0 = xin - X0; // The x,y,z distances from the cell origin + float y0 = yin - Y0; + float z0 = zin - Z0; + // For the 3D case, the simplex shape is a slightly irregular tetrahedron. + // Determine which simplex we are in. + int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords + int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords + if (x0 >= y0) { + if (y0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 1; + k2 = 0; + } // X Y Z order + else if (x0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 0; + k2 = 1; + } // X Z Y order + else { + i1 = 0; + j1 = 0; + k1 = 1; + i2 = 1; + j2 = 0; + k2 = 1; + } // Z X Y order + } else { // x0> 16) & 255; - blue = normalColor & 255; - green = (normalColor >> 8) & 255; - - float[] hsb = Color.RGBtoHSB(red, blue, green, null); - - return Color.HSBtoRGB(hsb[0], hsb[1] * 0.5F, Math.min(hsb[2] + 0.4F, 0.9F)); - } - - @SideOnly(Side.CLIENT) - public int getBlockColor() { - return this.colorMultiplier(null, 16, 0, 16); - } - - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @SideOnly(Side.CLIENT) - public int getRenderColor(int meta) { - return this.getBlockColor(); - } - - - @SideOnly(Side.CLIENT) - @Override - protected IIcon getSideIcon(int meta) - { - return this.sideIcon; - } - - @SideOnly(Side.CLIENT) - @Override - protected IIcon getTopIcon(int p_150161_1_) - { - return this.topIcon; - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.sideIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurora_pillar_side"); - this.topIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":aurora_pillar_top"); - } - -} diff --git a/src/main/java/twilightforest/block/BlockTFAuroraSlab.java b/src/main/java/twilightforest/block/BlockTFAuroraSlab.java index c37daa24f3..0b0212389f 100644 --- a/src/main/java/twilightforest/block/BlockTFAuroraSlab.java +++ b/src/main/java/twilightforest/block/BlockTFAuroraSlab.java @@ -1,127 +1,119 @@ package twilightforest.block; -import java.util.Random; - -import net.minecraft.block.Block; import net.minecraft.block.BlockSlab; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.Facing; -import net.minecraft.util.IIcon; -import net.minecraft.world.IBlockAccess; -import twilightforest.TwilightForestMod; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import java.util.Locale; +import java.util.Random; -public class BlockTFAuroraSlab extends BlockSlab { +public class BlockTFAuroraSlab extends BlockSlab implements ModelRegisterCallback { - private IIcon sideIcon; + private static final IProperty VARIANT = PropertyEnum.create("variant", AuroraSlabVariant.class); + + private final boolean isDouble; public BlockTFAuroraSlab(boolean isDouble) { - super(isDouble, Material.packedIce); + super(Material.PACKED_ICE); + this.isDouble = isDouble; this.setCreativeTab(TFItems.creativeTab); this.setHardness(2.0F); this.setResistance(10.0F); - - this.setLightOpacity(isDouble ? 255 : 0); + this.setLightOpacity(isDouble ? 255 : 0); + this.useNeighborBrightness = !isDouble; + + IBlockState state = this.blockState.getBaseState().withProperty(VARIANT, AuroraSlabVariant.AURORA); + if (!this.isDouble()) state = state.withProperty(HALF, EnumBlockHalf.BOTTOM); + + this.setDefaultState(state); } - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ @Override - public int colorMultiplier(IBlockAccess par1IBlockAccess, int x, int y, int z) { - return TFBlocks.auroraPillar.colorMultiplier(par1IBlockAccess, -x, y, -z); + protected BlockStateContainer createBlockState() { + return this.isDouble() ? new BlockStateContainer(this, VARIANT) : new BlockStateContainer(this, VARIANT, HALF); } - - - @SideOnly(Side.CLIENT) - public int getBlockColor() { - return this.colorMultiplier(null, 0, 0, 16); + + @Override + public String getTranslationKey(int meta) { + return super.getTranslationKey(); + } + + @Override + public boolean isDouble() { + return isDouble; + } + + @Override + public IProperty getVariantProperty() { + return VARIANT; + } + + @Override + public Comparable getTypeForItem(ItemStack stack) { + return AuroraSlabVariant.AURORA; } - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @SideOnly(Side.CLIENT) - public int getRenderColor(int meta) { - return this.getBlockColor(); - } - @Override - public String func_150002_b(int var1) { - return super.getUnlocalizedName(); + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return Item.getItemFromBlock(TFBlocks.aurora_slab); } - - /** - * Gets the block's texture. Args: side, meta - */ - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta){ - if (side == 0 || side == 1) { - return this.blockIcon; - } else { - return this.sideIcon; - } - } - - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister iconRegister) - { - this.blockIcon = TFBlocks.auroraPillar.getIcon(0, 0); - this.sideIcon = iconRegister.registerIcon(TwilightForestMod.ID + ":aurora_slab_side"); - } - - public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) - { - return Item.getItemFromBlock(TFBlocks.auroraSlab); - } - - /** - * Returns an item stack containing a single instance of the current block type. 'i' is the block's subtype/damage - * and is ignored for blocks which do not support subtypes. Blocks which cannot be harvested should return null. - */ - protected ItemStack createStackedBlock(int meta) - { - return new ItemStack(Item.getItemFromBlock(TFBlocks.auroraSlab), 2, 0); - } - - - /** - * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given - * coordinates. Args: blockAccess, x, y, z, side - */ - @SideOnly(Side.CLIENT) - public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side) - { - if (this.field_150004_a) - { - return super.shouldSideBeRendered(world, x, y, z, side); - } - else if (side != 1 && side != 0 && !super.shouldSideBeRendered(world, x, y, z, side)) - { - return false; - } - else - { - int i1 = x + Facing.offsetsXForSide[Facing.oppositeSide[side]]; - int j1 = y + Facing.offsetsYForSide[Facing.oppositeSide[side]]; - int k1 = z + Facing.offsetsZForSide[Facing.oppositeSide[side]]; - boolean flag = (world.getBlockMetadata(i1, j1, k1) & 8) != 0; - return flag ? (side == 0 ? true : (side == 1 && super.shouldSideBeRendered(world, x, y, z, side) ? true : !isSingleSlab(world.getBlock(x, y, z)) || (world.getBlockMetadata(x, y, z) & 8) == 0)) : (side == 1 ? true : (side == 0 && super.shouldSideBeRendered(world, x, y, z, side) ? true : !isSingleSlab(world.getBlock(x, y, z)) || (world.getBlockMetadata(x, y, z) & 8) != 0)); - } - } - - @SideOnly(Side.CLIENT) - private static boolean isSingleSlab(Block p_150003_0_) - { - return p_150003_0_ == TFBlocks.auroraSlab; - } + @Override + public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { + return new ItemStack(Item.getItemFromBlock(TFBlocks.aurora_slab)); + } + + @Override + protected ItemStack getSilkTouchDrop(IBlockState state) { + return new ItemStack(Item.getItemFromBlock(TFBlocks.aurora_slab), isDouble() ? 2 : 1, 0); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return this.isDouble() ? this.getDefaultState() : this.getDefaultState().withProperty(HALF, EnumBlockHalf.values()[meta % EnumBlockHalf.values().length]); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(HALF).ordinal(); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + if (this.isDouble()) + ModelLoader.setCustomStateMapper(this, new StateMap.Builder().ignore(VARIANT, HALF).build()); + else { + IStateMapper stateMapper = new StateMap.Builder().ignore(VARIANT).build(); + ModelLoader.setCustomStateMapper(this, stateMapper); + ModelUtils.registerToState(this, 0, getDefaultState(), stateMapper); + } + } + + private enum AuroraSlabVariant implements IStringSerializable { + AURORA; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + } } diff --git a/src/main/java/twilightforest/block/BlockTFAuroralizedGlass.java b/src/main/java/twilightforest/block/BlockTFAuroralizedGlass.java new file mode 100644 index 0000000000..e82df798a5 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFAuroralizedGlass.java @@ -0,0 +1,20 @@ +package twilightforest.block; + +import net.minecraft.block.BlockGlass; +import net.minecraft.block.material.Material; +import net.minecraft.util.BlockRenderLayer; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +public class BlockTFAuroralizedGlass extends BlockGlass implements ModelRegisterCallback { + + public BlockTFAuroralizedGlass() { + super(Material.ICE, false); + this.setCreativeTab(TFItems.creativeTab); + } + + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.TRANSLUCENT; + } +} diff --git a/src/main/java/twilightforest/block/BlockTFBossSpawner.java b/src/main/java/twilightforest/block/BlockTFBossSpawner.java index 182fc4666c..3ea70ebc0f 100644 --- a/src/main/java/twilightforest/block/BlockTFBossSpawner.java +++ b/src/main/java/twilightforest/block/BlockTFBossSpawner.java @@ -1,148 +1,114 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.BlockContainer; +import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.init.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.init.Items; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.IIcon; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.BossVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import twilightforest.tileentity.TileEntityTFHydraSpawner; -import twilightforest.tileentity.TileEntityTFKnightPhantomsSpawner; -import twilightforest.tileentity.TileEntityTFLichSpawner; -import twilightforest.tileentity.TileEntityTFNagaSpawner; -import twilightforest.tileentity.TileEntityTFSnowQueenSpawner; -import twilightforest.tileentity.TileEntityTFTowerBossSpawner; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import javax.annotation.Nullable; +import java.util.Random; +public class BlockTFBossSpawner extends Block implements ModelRegisterCallback { -public class BlockTFBossSpawner extends BlockContainer { + public static final IProperty VARIANT = PropertyEnum.create("boss", BossVariant.class); - protected BlockTFBossSpawner() - { - super(Material.rock); + protected BlockTFBossSpawner() { + super(Material.ROCK); this.setHardness(20F); - //this.setResistance(10F); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, BossVariant.NAGA)); } - - - /** - * Called throughout the code as a replacement for block instanceof BlockContainer - * Moving this to the Block base class allows for mods that wish to extend vinella - * blocks, and also want to have a tile entity on that block, may. - * - * Return true from this function to specify this block has a tile entity. - * - * @param metadata Metadata of the current block - * @return True if block has a tile entity, false otherwise - */ + @Override - public boolean hasTileEntity(int metadata) - { - return true; + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); } - - /** - * This is where we actually give out our tile entity - */ @Override - public TileEntity createTileEntity(World world, int metadata) - { - if (metadata == 0) - { - return new TileEntityTFNagaSpawner(); - } - else if (metadata == 1) - { - return new TileEntityTFLichSpawner(); - } - else if (metadata == 2) - { - return new TileEntityTFHydraSpawner(); - } - else if (metadata == 3) - { - return new TileEntityTFTowerBossSpawner(); - } - else if (metadata == 4) - { - return new TileEntityTFKnightPhantomsSpawner(); - } - else if (metadata == 5) - { - return new TileEntityTFSnowQueenSpawner(); - } - else - { - return null; + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, BossVariant.getVariant(meta)); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + for (BossVariant variant : BossVariant.values()) { + if (variant.hasSpawner()) { + list.add(new ItemStack(this, 1, variant.ordinal())); + } } - } + } @Override - public TileEntity createNewTileEntity(World var1, int var2) { - return createTileEntity(var1, var2); + public boolean hasTileEntity(IBlockState state) { + return state.getValue(VARIANT).hasSpawner(); } + @Override + @Nullable + public TileEntity createTileEntity(World world, IBlockState state) { + return state.getValue(VARIANT).getSpawner(); + } @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return null; + public Item getItemDropped(IBlockState state, Random random, int fortune) { + return Items.AIR; } - /** - * quantity dropped - */ @Override - public int quantityDropped(Random random) - { + public int quantityDropped(Random random) { return 0; } @Override - public boolean isOpaqueCube() - { + public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) { + return blockHardness >= 0f; + } + + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { return false; } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - //par3List.add(new ItemStack(par1, 1, 0)); - //par3List.add(new ItemStack(par1, 1, 1)); - //par3List.add(new ItemStack(par1, 1, 2)); - //par3List.add(new ItemStack(par1, 1, 3)); - //par3List.add(new ItemStack(par1, 1, 4)); - } - - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int metadata) - { - return Blocks.mob_spawner.getIcon(side, metadata); - } - - @Override @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - ; // don't load anything - } + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + IStateMapper stateMapper = new StateMap.Builder().ignore(VARIANT).build(); + ModelLoader.setCustomStateMapper(this, stateMapper); + ModelUtils.registerToStateSingleVariant(this, VARIANT, stateMapper); + } } diff --git a/src/main/java/twilightforest/block/BlockTFBurntThorns.java b/src/main/java/twilightforest/block/BlockTFBurntThorns.java index a27ea918bf..7da54b81c8 100644 --- a/src/main/java/twilightforest/block/BlockTFBurntThorns.java +++ b/src/main/java/twilightforest/block/BlockTFBurntThorns.java @@ -1,59 +1,79 @@ package twilightforest.block; -import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.pathfinding.PathNodeType; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; +import javax.annotation.Nullable; + public class BlockTFBurntThorns extends BlockTFThorns { protected BlockTFBurntThorns() { super(); this.setHardness(0.01F); this.setResistance(0.0F); - this.setStepSound(soundTypeSand); + this.setSoundType(SoundType.SAND); this.setCreativeTab(TFItems.creativeTab); - - this.setNames(new String[] {"burnt"}); - - } - - - /** - * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity - */ - public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) - { - // dissolve - if (!world.isRemote && entity instanceof EntityLivingBase) { - int metadata = world.getBlockMetadata(x, y, z); - world.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(this) + (metadata << 12)); - world.setBlockToAir(x, y, z); - } - } - - /** - * Break normally - */ - public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { - world.setBlockToAir(x, y, z); - return true; - } - - @Override - public boolean canSustainLeaves(IBlockAccess world, int x, int y, int z) - { - return false; - } - - /** - * no need for leaf decay, I think - */ - public void breakBlock(World world, int x, int y, int z, Block logBlock, int metadata) - { - ; - } + } + + @Override + protected IProperty[] getAdditionalProperties() { + return new IProperty[0]; + } + + @Override + protected boolean hasVariant() { + return false; + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return MapColor.STONE; + } + + @Override + @Nullable + public PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos) { + return null; + } + + @Override + public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity) { + // dissolve + if (!world.isRemote && entity instanceof EntityLivingBase) { + world.destroyBlock(pos, false); + } + } + + @Override + public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean harvest) { + world.setBlockToAir(pos); + return true; + } + + @Override + public boolean canSustainLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { + return false; + } + + @Override + public void breakBlock(World world, BlockPos pos, IBlockState state) {} + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, this.getDefaultState()); + } } diff --git a/src/main/java/twilightforest/block/BlockTFButtonWood.java b/src/main/java/twilightforest/block/BlockTFButtonWood.java new file mode 100644 index 0000000000..5982e57079 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFButtonWood.java @@ -0,0 +1,13 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockButtonWood; +import net.minecraft.block.SoundType; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFButtonWood extends BlockButtonWood implements ModelRegisterCallback { + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFCastleBlock.java b/src/main/java/twilightforest/block/BlockTFCastleBlock.java index 04c694960b..afa823172a 100644 --- a/src/main/java/twilightforest/block/BlockTFCastleBlock.java +++ b/src/main/java/twilightforest/block/BlockTFCastleBlock.java @@ -1,117 +1,103 @@ package twilightforest.block; -import java.util.List; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemTool; -import net.minecraft.util.IIcon; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.CastleBrickVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.ItemTFMazebreakerPick; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import javax.annotation.Nullable; /** - * * Castle block makes a castle - * - * @author Ben * + * @author Ben */ -public class BlockTFCastleBlock extends Block { - - private static IIcon brickIcon; - private static IIcon crackIcon; - private static IIcon fadedIcon; - private static IIcon roofIcon; +public class BlockTFCastleBlock extends Block implements ModelRegisterCallback { - /** - * Note that the texture called for here will only be used when the meta value is not a good block to mimic - * - * @param id - * @param texture - */ - public BlockTFCastleBlock() - { - super(Material.rock); - this.setHardness(100F); - this.setResistance(15F); - this.setStepSound(Block.soundTypeStone); + public static final IProperty VARIANT = PropertyEnum.create("variant", CastleBrickVariant.class); + + public BlockTFCastleBlock() { + super(Material.ROCK, MapColor.QUARTZ); + this.setHardness(100F); + this.setResistance(35F); + this.setSoundType(SoundType.STONE); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, CastleBrickVariant.NORMAL)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, CastleBrickVariant.values()[meta]); + } - } + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.getValue(VARIANT) == CastleBrickVariant.ROOF ? MapColor.GRAY : super.getMapColor(state, world, pos); + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ @Override - public IIcon getIcon(int side, int meta) { - switch (meta) - { - case 0: - default: - return brickIcon; - case 1: - return fadedIcon; - case 2: - return crackIcon; - case 3: - return roofIcon; + public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack) { + ItemStack cei = player.getHeldItemMainhand(); + if (cei.getItem() instanceof ItemTool && !(cei.getItem() instanceof ItemTFMazebreakerPick)) { + cei.damageItem(16, player); } + + super.harvestBlock(world, player, pos, state, te, stack); } @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFCastleBlock.brickIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":castleblock_brick"); - BlockTFCastleBlock.fadedIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":castleblock_faded"); - BlockTFCastleBlock.crackIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":castleblock_cracked"); - BlockTFCastleBlock.roofIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":castleblock_roof"); + public void getSubBlocks(CreativeTabs creativeTab, NonNullList items) { + for (CastleBrickVariant variant : CastleBrickVariant.values()) { + items.add(new ItemStack(this, 1, variant.ordinal())); + } } @Override - public void harvestBlock(World world, EntityPlayer entityplayer, int x, int y, int z, int meta) - { - // damage the player's pickaxe - ItemStack cei = entityplayer.getCurrentEquippedItem(); - if(cei != null && cei.getItem() instanceof ItemTool && !(cei.getItem() instanceof ItemTFMazebreakerPick)) - { - cei.damageItem(16, entityplayer); - } - - super.harvestBlock(world, entityplayer, x, y, z, meta); - } - - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } + + @SideOnly(Side.CLIENT) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return meta; + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); } + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } } diff --git a/src/main/java/twilightforest/block/BlockTFCastleDoor.java b/src/main/java/twilightforest/block/BlockTFCastleDoor.java index c44c444e13..45b366370e 100644 --- a/src/main/java/twilightforest/block/BlockTFCastleDoor.java +++ b/src/main/java/twilightforest/block/BlockTFCastleDoor.java @@ -1,367 +1,334 @@ package twilightforest.block; -import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -import java.util.List; -import java.util.Random; - -import twilightforest.TFGenericPacketHandler; -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.WorldProviderTwilightForest; import net.minecraft.block.Block; -import net.minecraft.block.BlockPane; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.properties.PropertyInteger; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; +import net.minecraft.util.*; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import static net.minecraftforge.common.util.ForgeDirection.*; - -public class BlockTFCastleDoor extends Block -{ - - private IIcon activeIcon; - private boolean isVanished; - - public BlockTFCastleDoor(boolean isVanished) - { - super(isVanished ? Material.glass : Material.rock); - - this.isVanished = isVanished; - this.lightOpacity = isVanished ? 0 : 255; - - this.setCreativeTab(TFItems.creativeTab); - } - - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister register) - { - //TODO: this is the opposite of object oriented. - - if (this.isVanished) { - this.blockIcon = register.registerIcon(TwilightForestMod.ID + ":castle_door_vanished"); - this.activeIcon = register.registerIcon(TwilightForestMod.ID + ":castle_door_vanished_active"); - } else { - this.blockIcon = register.registerIcon(TwilightForestMod.ID + ":castle_door"); - this.activeIcon = register.registerIcon(TwilightForestMod.ID + ":castle_door_active"); - } - } - - - @SideOnly(Side.CLIENT) - public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { - int meta = world.getBlockMetadata(x, y, z); - - if (isMetaActive(meta)) { - return this.activeIcon; - } else { - return this.blockIcon; - } - } - - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return !this.isVanished; - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.network.TFPacketHandler; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.item.TFItems; +import twilightforest.network.PacketAnnihilateBlock; +import twilightforest.world.ChunkGeneratorTFBase; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class BlockTFCastleDoor extends Block implements ModelRegisterCallback { + + public static final IProperty ACTIVE = PropertyBool.create("active"); + public static final IProperty LOCK_INDEX = PropertyInteger.create("lock_index", 0, 3); + + private final boolean isVanished; + + private static final AxisAlignedBB REAPPEARING_BB = new AxisAlignedBB(0.375F, 0.375F, 0.375F, 0.625F, 0.625F, 0.625F); + + public BlockTFCastleDoor(boolean isVanished) { + super(isVanished ? Material.GLASS : Material.ROCK, isVanished ? MapColor.AIR : MapColor.CYAN); + + //this.setBlockUnbreakable(); + //this.setResistance(Float.MAX_VALUE); + + this.setHardness(100F); + this.setResistance(35F); + + this.isVanished = isVanished; + this.lightOpacity = isVanished ? 0 : 255; + + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(ACTIVE, false)); + } + @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int x, int y, int z) - { - if (this.isVanished) - { - return null; - } - else - { - this.setBlockBoundsBasedOnState(par1World, x, y, z); - return super.getCollisionBoundingBoxFromPool(par1World, x, y, z); + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, ACTIVE, LOCK_INDEX); + } + + @Override + public int getMetaFromState(IBlockState state) { + int meta = state.getValue(LOCK_INDEX); + meta |= state.getValue(ACTIVE) ? 8 : 0; + return meta; + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState() + .withProperty(ACTIVE, (meta & 8) != 0) + .withProperty(LOCK_INDEX, meta & 3); + } + + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return !this.isVanished; + } + + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return !this.isVanished; + } + + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return isVanished ? BlockFaceShape.UNDEFINED : super.getBlockFaceShape(worldIn, state, pos, face); + } + + @Override + @Deprecated + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return isVanished ? NULL_AABB : super.getCollisionBoundingBox(state, world, pos); + } + + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return isVanished ? REAPPEARING_BB : super.getBoundingBox(state, world, pos); + } + + @Override + public boolean isPassable(IBlockAccess blockAccess, BlockPos pos) { + return this.isVanished; + } + + @Override + public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + return onActivation(world, pos, state); + } + + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) { + if (!(block instanceof BlockTFCastleDoor) && world.isBlockPowered(pos)) { + onActivation(world, pos, state); } } - - @Override - public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) - { - return !this.isVanished; - } - - - /** - * Called upon block activation (right click on the block.) - */ - @Override - public boolean onBlockActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) - { - int meta = par1World.getBlockMetadata(x, y, z); - - if (!isMetaActive(meta)) - { - if (isBlockLocked(par1World, x, y, z)) - { - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 1.0F, 0.3F); - } - else - { - changeToActiveBlock(par1World, x, y, z, meta); - } - return true; - } - else - { - return false; - } - } + private boolean onActivation(World world, BlockPos pos, IBlockState state) { - /** - * Change this block to be active - */ - public static void changeToActiveBlock(World par1World, int x, int y, int z, int meta) - { - changeToBlockMeta(par1World, x, y, z, meta | 8); - playVanishSound(par1World, x, y, z); + if (isVanished || state.getValue(ACTIVE)) return false; - Block blockAt = par1World.getBlock(x, y, z); - par1World.scheduleBlockUpdate(x, y, z, blockAt, 2 + par1World.rand.nextInt(5)); + if (isBlockLocked(world, pos)) { + world.playSound(null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 1.0F, 0.3F); + } else { + changeToActiveBlock(world, pos, state); + } + return true; } + private static void changeToActiveBlock(World world, BlockPos pos, IBlockState originState) { + changeActiveState(world, pos, true, originState); + playVanishSound(world, pos); - /** - * Change this block into an different device block - */ - private static void changeToBlockMeta(World par1World, int x, int y, int z, int meta) - { - Block blockAt = par1World.getBlock(x, y, z); - - if (blockAt == TFBlocks.castleDoor || blockAt == TFBlocks.castleDoorVanished) - { - par1World.setBlock(x, y, z, blockAt, meta, 3); - par1World.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - par1World.notifyBlocksOfNeighborChange(x, y, z, blockAt); + world.scheduleUpdate(pos, originState.getBlock(), 2 + world.rand.nextInt(5)); + } + + private static void changeActiveState(World world, BlockPos pos, boolean active, IBlockState originState) { + if (originState.getBlock() instanceof BlockTFCastleDoor) { + world.setBlockState(pos, originState.withProperty(ACTIVE, active), 3); + world.markBlockRangeForRenderUpdate(pos, pos); + world.notifyNeighborsRespectDebug(pos, originState.getBlock(), false); } } - - - public static boolean isBlockLocked(World par1World, int x, int y, int z) { + + private static boolean isBlockLocked(World world, BlockPos pos) { // check if we are in a structure, and if that structure says that we are locked - - int meta = par1World.getBlockMetadata(x, y, z); - - if (!par1World.isRemote && par1World.provider instanceof WorldProviderTwilightForest) { - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)par1World.provider).getChunkProvider(); + if (!world.isRemote) { + ChunkGeneratorTFBase generator = TFWorld.getChunkGenerator(world); + return generator != null && generator.isStructureLocked(pos, world.getBlockState(pos).getValue(LOCK_INDEX)); + } + return false; + } - return chunkProvider.isStructureLocked(x, y, z, meta); + @Override + public int tickRate(World world) { + return 5; + } + + @Override // todo 1.10 recheck all of this + public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { + + if (world.isRemote) return; + + if (this.isVanished) { + if (state.getValue(ACTIVE)) { + world.setBlockState(pos, TFBlocks.castle_door.getDefaultState().withProperty(LOCK_INDEX, state.getValue(LOCK_INDEX))); + playVanishSound(world, pos); + } else { + changeToActiveBlock(world, pos, state); + } } else { - return false; + // if we have an active castle door, turn it into a vanished door block + if (state.getValue(ACTIVE)) { + world.setBlockState(pos, getOtherBlock(this).getDefaultState().withProperty(LOCK_INDEX, state.getValue(LOCK_INDEX))); + world.scheduleUpdate(pos, getOtherBlock(this), 80); + + playReappearSound(world, pos); + + this.sendAnnihilateBlockPacket(world, pos); + + // activate all adjacent inactive doors + for (EnumFacing e : EnumFacing.VALUES) { + checkAndActivateCastleDoor(world, pos.offset(e)); + } + } + // inactive solid door blocks we don't care about updates } } - public static boolean isMetaActive(int meta) { - return (meta & 8) != 0; - } - - - /** - * How many world ticks before ticking - */ - public int tickRate() - { - return 5; - } - - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getCastleMagicBlockRenderID(); - } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World par1World, int x, int y, int z, Random par5Random) - { - if (!par1World.isRemote) - { - //System.out.println("Update castle door"); - - int meta = par1World.getBlockMetadata(x, y, z); - - if (this.isVanished) { - if (isMetaActive(meta)) { - par1World.setBlock(x, y, z, TFBlocks.castleDoor, meta & 7, 3); - par1World.notifyBlocksOfNeighborChange(x, y, z, this); - playVanishSound(par1World, x, y, z); - - //par1World.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - } else { - changeToActiveBlock(par1World, x, y, z, meta); - } - } else { - - // if we have an active castle door, turn it into a vanished door block - if (isMetaActive(meta)) - { - par1World.setBlock(x, y, z, getOtherBlock(this), meta & 7, 3); - par1World.scheduleBlockUpdate(x, y, z, getOtherBlock(this), 80); - - par1World.notifyBlocksOfNeighborChange(x, y, z, this); - playReappearSound(par1World, x, y, z); - par1World.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - - this.sendAnnihilateBlockPacket(par1World, x, y, z); - - - // activate all adjacent inactive doors - checkAndActivateCastleDoor(par1World, x - 1, y, z); - checkAndActivateCastleDoor(par1World, x + 1, y, z); - checkAndActivateCastleDoor(par1World, x, y + 1, z); - checkAndActivateCastleDoor(par1World, x, y - 1, z); - checkAndActivateCastleDoor(par1World, x, y, z + 1); - checkAndActivateCastleDoor(par1World, x, y, z - 1); - - } - - // inactive solid door blocks we don't care about updates - } - - } - } - - private void sendAnnihilateBlockPacket(World world, int x, int y, int z) { - // send packet - FMLProxyPacket message = TFGenericPacketHandler.makeAnnihilateBlockPacket(x, y, z); - - NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.dimensionId, x, y, z, 64); - - TwilightForestMod.genericChannel.sendToAllAround(message, targetPoint); - } - - private static void playVanishSound(World par1World, int x, int y, int z) { - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.fizz", 0.125f, par1World.rand.nextFloat() * 0.25F + 1.75F); -// par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "note.harp", 0.2F, par1World.rand.nextFloat() * 2F); - } - - private static void playReappearSound(World par1World, int x, int y, int z) { - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.fizz", 0.125f, par1World.rand.nextFloat() * 0.25F + 1.25F); -// par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "note.harp", 0.2F, par1World.rand.nextFloat() * 2F); + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return TFItems.castle_door; + } + + @Override + public int damageDropped(IBlockState state) { + return state.getValue(LOCK_INDEX); + } + + private void sendAnnihilateBlockPacket(World world, BlockPos pos) { + IMessage message = new PacketAnnihilateBlock(pos); + NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 64); + TFPacketHandler.CHANNEL.sendToAllAround(message, targetPoint); + } + + private static void playVanishSound(World world, BlockPos pos) { + world.playSound(null, pos, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.125f, world.rand.nextFloat() * 0.25F + 1.75F); + } + + private static void playReappearSound(World world, BlockPos pos) { + world.playSound(null, pos, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.125f, world.rand.nextFloat() * 0.25F + 1.25F); } private static Block getOtherBlock(Block block) { - return block == TFBlocks.castleDoor ? TFBlocks.castleDoorVanished : TFBlocks.castleDoor; - } - - /** - * If the targeted block is a vanishing block, activate it - */ - public static void checkAndActivateCastleDoor(World world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - int meta = world.getBlockMetadata(x, y, z); - - if (block == TFBlocks.castleDoor && !isMetaActive(meta) && !isBlockLocked(world, x, y, z)) - { - changeToActiveBlock(world, x, y, z, meta); - } -// if (block == TFBlocks.castleDoorVanished && !isMetaActive(meta) && !isBlockLocked(world, x, y, z)) -// { + return block == TFBlocks.castle_door ? TFBlocks.castle_door_vanished : TFBlocks.castle_door; + } + + /** + * If the targeted block is a vanishing block, activate it + */ + public static void checkAndActivateCastleDoor(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + + if (state.getBlock() == TFBlocks.castle_door && !state.getValue(ACTIVE) && !isBlockLocked(world, pos)) { + changeToActiveBlock(world, pos, state); + } +// if (state.getBlock() == TFBlocks.castle_door_vanished && !state.getValue(ACTIVE) && !isBlockLocked(world, pos)) { // changeToActiveBlock(world, x, y, z, meta); // } } - - + @Override @SideOnly(Side.CLIENT) + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) { + if (state.getValue(ACTIVE)) ; + { + for (int i = 0; i < 1; ++i) { + //this.sparkle(world, x, y, z, random); + } + } + } + + // [VanillaCopy] BlockRedStoneOre.spawnParticles with own rand + @SuppressWarnings("unused") + private void sparkle(World worldIn, BlockPos pos, Random rand) { + Random random = rand; + double d0 = 0.0625D; + + for (int i = 0; i < 6; ++i) { + double d1 = (double) ((float) pos.getX() + random.nextFloat()); + double d2 = (double) ((float) pos.getY() + random.nextFloat()); + double d3 = (double) ((float) pos.getZ() + random.nextFloat()); + + if (i == 0 && !worldIn.getBlockState(pos.up()).isOpaqueCube()) { + d2 = (double) pos.getY() + 0.0625D + 1.0D; + } - /** - * A randomly called display update to be able to add particles or other items for display - */ - public void randomDisplayTick(World par1World, int x, int y, int z, Random par5Random) - { - int meta = par1World.getBlockMetadata(x, y, z); - - if (isMetaActive(meta)); - { - for (int i = 0; i < 1; ++i) { - //this.sparkle(par1World, x, y, z, par5Random); - } - } - } - - - /** - * Shine bright like a DIAMOND! (or actually, sparkle like redstone ore) - */ - public void sparkle(World world, int x, int y, int z, Random rand) - { - double offset = 0.0625D; - - for (int side = 0; side < 6; ++side) - { - double rx = x + rand.nextFloat(); - double ry = y + rand.nextFloat(); - double rz = z + rand.nextFloat(); - - if (side == 0 && !world.getBlock(x, y + 1, z).isOpaqueCube()) - { - ry = y + 1 + offset; - } - - if (side == 1 && !world.getBlock(x, y - 1, z).isOpaqueCube()) - { - ry = y + 0 - offset; - } - - if (side == 2 && !world.getBlock(x, y, z + 1).isOpaqueCube()) - { - rz = z + 1 + offset; - } - - if (side == 3 && !world.getBlock(x, y, z - 1).isOpaqueCube()) - { - rz = z + 0 - offset; - } - - if (side == 4 && !world.getBlock(x + 1, y, z).isOpaqueCube()) - { - rx = x + 1 + offset; - } - - if (side == 5 && !world.getBlock(x - 1, y, z).isOpaqueCube()) - { - rx = x + 0 - offset; - } - - if (rx < x || rx > x + 1 || ry < 0.0D || ry > y + 1 || rz < z || rz > z + 1) - { - world.spawnParticle("reddust", rx, ry, rz, 0.0D, 0.0D, 0.0D); - } - } - } - -} \ No newline at end of file + if (i == 1 && !worldIn.getBlockState(pos.down()).isOpaqueCube()) { + d2 = (double) pos.getY() - 0.0625D; + } + + if (i == 2 && !worldIn.getBlockState(pos.south()).isOpaqueCube()) { + d3 = (double) pos.getZ() + 0.0625D + 1.0D; + } + + if (i == 3 && !worldIn.getBlockState(pos.north()).isOpaqueCube()) { + d3 = (double) pos.getZ() - 0.0625D; + } + + if (i == 4 && !worldIn.getBlockState(pos.east()).isOpaqueCube()) { + d1 = (double) pos.getX() + 0.0625D + 1.0D; + } + + if (i == 5 && !worldIn.getBlockState(pos.west()).isOpaqueCube()) { + d1 = (double) pos.getX() - 0.0625D; + } + + if (d1 < (double) pos.getX() || d1 > (double) (pos.getX() + 1) || d2 < 0.0D || d2 > (double) (pos.getY() + 1) || d3 < (double) pos.getZ() || d3 > (double) (pos.getZ() + 1)) { + worldIn.spawnParticle(EnumParticleTypes.REDSTONE, d1, d2, d3, 0.0D, 0.0D, 0.0D, new int[0]); + } + } + } + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return isVanished ? BlockRenderLayer.TRANSLUCENT : BlockRenderLayer.CUTOUT; + } + + @SideOnly(Side.CLIENT) + @Override + @Deprecated + public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { + return !(blockAccess.getBlockState(pos.offset(side)).getBlock() instanceof BlockTFCastleDoor) && super.shouldSideBeRendered(blockState, blockAccess, pos, side); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + if (this == TFBlocks.castle_door) { + for (int i = 0; i < LOCK_INDEX.getAllowedValues().size(); i++) { + list.add(new ItemStack(this, 1, i)); + } + } + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + if (!isVanished) { + ModelUtils.registerToStateSingleVariant(this, LOCK_INDEX); + } + } + + @Override + public ItemStack getItem(World world, BlockPos pos, IBlockState state) { + return new ItemStack(TFItems.castle_door, 1, damageDropped(state)); + } + + @Override + protected ItemStack getSilkTouchDrop(IBlockState state) { + return new ItemStack(TFItems.castle_door, 1, damageDropped(state)); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFCastleMagic.java b/src/main/java/twilightforest/block/BlockTFCastleMagic.java index 27d086b9de..81a6812cc7 100644 --- a/src/main/java/twilightforest/block/BlockTFCastleMagic.java +++ b/src/main/java/twilightforest/block/BlockTFCastleMagic.java @@ -1,106 +1,84 @@ package twilightforest.block; -import java.util.List; - +import com.google.common.collect.ImmutableList; import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemTool; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import twilightforest.item.ItemTFMazebreakerPick; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import java.util.List; /** - * * Castle block makes a castle - * - * @author Ben * + * @author Ben */ -public class BlockTFCastleMagic extends Block { - - public static IIcon[] magicIcons = new IIcon[8]; - public static int[] magicColors = new int[] { 0x00FFFF, 0xFFFF00, 0xFF00FF, 0x4B0082 }; +public class BlockTFCastleMagic extends Block implements ModelRegisterCallback { + + public static final List VALID_COLORS = ImmutableList.of(EnumDyeColor.PINK, EnumDyeColor.BLUE, EnumDyeColor.YELLOW, EnumDyeColor.PURPLE); + public static final IProperty COLOR = PropertyEnum.create("color", EnumDyeColor.class, VALID_COLORS); - public BlockTFCastleMagic() - { - super(Material.rock); - this.setHardness(100F); - this.setResistance(15F); - this.setStepSound(Block.soundTypeStone); + public BlockTFCastleMagic() { + super(Material.ROCK, MapColor.QUARTZ); + this.setHardness(100F); + this.setResistance(15F); + this.setSoundType(SoundType.STONE); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(COLOR, EnumDyeColor.PINK)); + } - } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, COLOR); + } + @Override + public int getMetaFromState(IBlockState state) { + return VALID_COLORS.indexOf(state.getValue(COLOR)); + } @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.blockIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":castleblock_brick"); - for (int i = 0; i < 8; i++) { - this.magicIcons[i] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":castleblock_magic_" + i); - } + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(COLOR, VALID_COLORS.get(meta)); } - - public static IIcon getMagicIconFor(int x, int y, int z) { - - long seed = x * 3129871 ^ y * 116129781L ^ z; - seed = seed * seed * 42317861L + seed * 11L; - - int index = (int) (seed >> 12 & 7L); - - return magicIcons[index]; + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); } - public static int getMagicColorFor(int meta) { - int color = magicColors[meta & 3]; - - if ((meta & 8) != 0) { - color = 0xFFFFFF ^ color; - } - - return color; + @Override + public int damageDropped(IBlockState state) { + return getMetaFromState(state); } - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getCastleMagicBlockRenderID(); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SideOnly(Side.CLIENT) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return meta; + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, COLOR); } + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } } diff --git a/src/main/java/twilightforest/block/BlockTFCastlePillar.java b/src/main/java/twilightforest/block/BlockTFCastlePillar.java new file mode 100644 index 0000000000..cfc863d68a --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFCastlePillar.java @@ -0,0 +1,99 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLog; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.CastlePillarVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.item.TFItems; + +import static net.minecraft.block.BlockLog.LOG_AXIS; + +public class BlockTFCastlePillar extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", CastlePillarVariant.class); + + BlockTFCastlePillar() { + super(Material.ROCK, MapColor.QUARTZ); + this.setHardness(100F); + this.setResistance(35F); + this.setSoundType(SoundType.STONE); + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, CastlePillarVariant.ENCASED).withProperty(LOG_AXIS, BlockLog.EnumAxis.Y)); + } + + @Override + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { + ItemStack stack = placer.getHeldItem(hand); + return this.getDefaultState() + .withProperty(LOG_AXIS, (stack.getMetadata() & 1) == 1 ? BlockLog.EnumAxis.NONE : BlockLog.EnumAxis.fromFacingAxis(facing.getAxis())) + .withProperty(VARIANT, CastlePillarVariant.values()[stack.getMetadata() / 2 & 1]); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, LOG_AXIS, VARIANT); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal() << 2 | state.getValue(LOG_AXIS).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(VARIANT, CastlePillarVariant.values()[(meta & 0b1100) >> 2 & 1]).withProperty(LOG_AXIS, BlockLog.EnumAxis.values()[meta & 0b11]); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + for (CastlePillarVariant variant : CastlePillarVariant.values()) { + list.add(new ItemStack(this, 1, variant.ordinal()*2)); + list.add(new ItemStack(this, 1, (variant.ordinal()*2)+1)); + } + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + CastlePillarVariant[] variantsList = CastlePillarVariant.values(); + + for (int i = 0; i < variantsList.length; i++) { + ModelUtils.registerToState(this, i*2, this.getDefaultState() + .withProperty(LOG_AXIS, BlockLog.EnumAxis.Y) + .withProperty(VARIANT, variantsList[i])); + + ModelUtils.registerToState(this, (i*2)+1, this.getDefaultState() + .withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE) + .withProperty(VARIANT, variantsList[i])); + } + } + + @Override + public int damageDropped(IBlockState state) { + return state.getValue(VARIANT).ordinal() << 1 | (state.getValue(LOG_AXIS) == BlockLog.EnumAxis.NONE ? 1 : 0); + } + + @Override + protected ItemStack getSilkTouchDrop(IBlockState state) { + return new ItemStack(this, 1, damageDropped(state)); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/block/BlockTFCastleStairs.java b/src/main/java/twilightforest/block/BlockTFCastleStairs.java new file mode 100644 index 0000000000..14d43133c8 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFCastleStairs.java @@ -0,0 +1,68 @@ +package twilightforest.block; + +import net.minecraft.block.BlockStairs; +import net.minecraft.block.SoundType; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.CastlePillarVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.item.TFItems; + +public class BlockTFCastleStairs extends BlockStairs implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", CastlePillarVariant.class); + + BlockTFCastleStairs(IBlockState state) { + super(state); + this.setHardness(100F); + this.setResistance(35F); + this.setSoundType(SoundType.STONE); + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(getDefaultState().withProperty(VARIANT, CastlePillarVariant.ENCASED)); + this.useNeighborBrightness = true; + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING, HALF, SHAPE, VARIANT); + } + + @Override + public int getMetaFromState(IBlockState state) { + return super.getMetaFromState(state) + (state.getValue(VARIANT) == CastlePillarVariant.BOLD ? 8 : 0); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return super.getStateFromMeta(meta & 0b0111).withProperty(VARIANT, (meta & 0b1000) == 8 ? CastlePillarVariant.BOLD : CastlePillarVariant.ENCASED); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 8)); + } + + @Override + public int damageDropped(IBlockState state) { + return state.getValue(VARIANT) == CastlePillarVariant.BOLD ? 8 : 0; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, getDefaultState().withProperty(FACING, EnumFacing.EAST)); + ModelUtils.registerToState(this, 8, getDefaultState().withProperty(FACING, EnumFacing.EAST).withProperty(VARIANT, CastlePillarVariant.BOLD)); + } + +} diff --git a/src/main/java/twilightforest/block/BlockTFCastleUnlock.java b/src/main/java/twilightforest/block/BlockTFCastleUnlock.java index 1f602da2f5..49a2b0740f 100644 --- a/src/main/java/twilightforest/block/BlockTFCastleUnlock.java +++ b/src/main/java/twilightforest/block/BlockTFCastleUnlock.java @@ -7,8 +7,7 @@ public class BlockTFCastleUnlock extends Block { protected BlockTFCastleUnlock() { - super(Material.rock); - // TODO Auto-generated constructor stub + super(Material.ROCK); } } diff --git a/src/main/java/twilightforest/block/BlockTFCicada.java b/src/main/java/twilightforest/block/BlockTFCicada.java index 6a2b73615c..344cbdff7e 100644 --- a/src/main/java/twilightforest/block/BlockTFCicada.java +++ b/src/main/java/twilightforest/block/BlockTFCicada.java @@ -1,20 +1,59 @@ package twilightforest.block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.block.statemap.StateMap; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.init.Items; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.translation.I18n; import net.minecraft.world.World; -import twilightforest.tileentity.TileEntityTFCicada; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.compat.TFCompat; +import twilightforest.tileentity.critters.TileEntityTFCicadaTicking; -public class BlockTFCicada extends BlockTFCritter { +import javax.annotation.Nullable; +import java.util.List; - public static int sprCicada = 5; - - - protected BlockTFCicada() { - super(); +public class BlockTFCicada extends BlockTFCritter implements ModelRegisterCallback { + + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + return TwilightForestMod.proxy.getNewCicadaTE(); + } + + @Override + public ItemStack getSquishResult() { + return new ItemStack(Items.DYE, 1, EnumDyeColor.GRAY.getDyeDamage()); } + //Atomic: Forge would like to get rid of registerTESRItemStack, but there's no alternative yet (as at 1.11) + @SuppressWarnings("deprecation") + @SideOnly(Side.CLIENT) @Override - public TileEntity createTileEntity(World world, int metadata) { - return new TileEntityTFCicada(); + public void registerModel() { + ModelLoader.setCustomStateMapper(this, new StateMap.Builder().ignore(BlockDirectional.FACING).build()); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + ForgeHooksClient.registerTESRItemStack(Item.getItemFromBlock(this), 0, TileEntityTFCicadaTicking.class); + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + super.addInformation(stack, world, tooltip, flag); + + if (TFCompat.IMMERSIVEENGINEERING.isActivated()) { + tooltip.add(TextFormatting.ITALIC.toString() + TwilightForestMod.getRarity().color.toString() + I18n.translateToLocalFormatted("tile.twilightforest.Cicada.desc")); + } } } diff --git a/src/main/java/twilightforest/block/BlockTFCinderFurnace.java b/src/main/java/twilightforest/block/BlockTFCinderFurnace.java index b0fcc2620b..c4ace4737d 100644 --- a/src/main/java/twilightforest/block/BlockTFCinderFurnace.java +++ b/src/main/java/twilightforest/block/BlockTFCinderFurnace.java @@ -1,242 +1,146 @@ package twilightforest.block; -import java.util.Random; - -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; -import twilightforest.tileentity.TileEntityTFCinderFurnace; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; -import net.minecraft.block.BlockContainer; +import net.minecraft.block.BlockFurnace; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.inventory.InventoryHelper; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; +import twilightforest.tileentity.TileEntityTFCinderFurnace; -public class BlockTFCinderFurnace extends BlockContainer{ +import java.util.Random; + +public class BlockTFCinderFurnace extends Block implements ModelRegisterCallback { + + private static boolean keepInventory; + private final boolean isBurning; + + BlockTFCinderFurnace(boolean isLit) { + super(Material.WOOD); - private static boolean isUpdating; - private Boolean isLit; - private IIcon topIcon; - private Random furnaceRandom = new Random(); + this.isBurning = isLit; - protected BlockTFCinderFurnace(Boolean isLit) { - super(Material.wood); - - this.isLit = isLit; - this.setHardness(7.0F); - + this.setLightLevel(isLit ? 1F : 0); - + if (!isLit) { this.setCreativeTab(TFItems.creativeTab); } - + + this.setDefaultState(blockState.getBaseState().withProperty(BlockFurnace.FACING, EnumFacing.NORTH)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, BlockFurnace.FACING); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(BlockFurnace.FACING).getHorizontalIndex(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(BlockFurnace.FACING, EnumFacing.byHorizontalIndex(meta)); + } + + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + return new TileEntityTFCinderFurnace(); + } + + @Override + public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + if (!world.isRemote && world.getTileEntity(pos) instanceof TileEntityTFCinderFurnace) { + player.openGui(TwilightForestMod.instance, TwilightForestMod.GUI_ID_FURNACE, world, pos.getX(), pos.getY(), pos.getZ()); + } + + return true; } @Override - public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) { - return new TileEntityTFCinderFurnace(); + public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack itemStack) { + if (itemStack.hasDisplayName()) { + ((TileEntityFurnace) world.getTileEntity(pos)).setCustomInventoryName(itemStack.getDisplayName()); + } + } + + public static void setState(boolean active, World worldIn, BlockPos pos) { + IBlockState iblockstate = worldIn.getBlockState(pos); + TileEntity tileentity = worldIn.getTileEntity(pos); + keepInventory = true; + + if (active) { + worldIn.setBlockState(pos, TFBlocks.cinder_furnace_lit.getDefaultState().withProperty(BlockFurnace.FACING, iblockstate.getValue(BlockFurnace.FACING)), 3); + } else { + worldIn.setBlockState(pos, TFBlocks.cinder_furnace.getDefaultState().withProperty(BlockFurnace.FACING, iblockstate.getValue(BlockFurnace.FACING)), 3); + } + + keepInventory = false; + + if (tileentity != null) { + tileentity.validate(); + worldIn.setTileEntity(pos, tileentity); + } + } + + @SideOnly(Side.CLIENT) + @Override + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) { + if (this.isBurning) { + Blocks.LIT_FURNACE.randomDisplayTick(state, world, pos, random); + } } - - /** - * Gets the block's texture. Args: side, meta - */ - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) - { - return side == 1 ? this.topIcon : (side == 0 ? this.topIcon : this.blockIcon); - } - - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister p_149651_1_) - { - this.blockIcon = p_149651_1_.registerIcon(this.isLit ? "furnace_front_on" : "furnace_front_off"); - this.topIcon = p_149651_1_.registerIcon("furnace_top"); - } - - - /** - * Called upon block activation (right click on the block.) - */ - public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_) - { - if (world.isRemote) - { - return true; - } - else - { - TileEntityTFCinderFurnace tileentityfurnace = (TileEntityTFCinderFurnace)world.getTileEntity(x, y, z); - - if (tileentityfurnace != null) - { - player.openGui(TwilightForestMod.instance, TwilightForestMod.GUI_ID_FURNACE, world, x, y, z); - return true; - } - - return true; - } - } - - /** - * Called when the block is placed in the world. - */ - public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase p_149689_5_, ItemStack itemStack) - { - - if (itemStack.hasDisplayName()) - { - ((TileEntityFurnace)world.getTileEntity(x, y, z)).func_145951_a(itemStack.getDisplayName()); - } - } - - - /** - * Update which block the furnace is using depending on whether or not it is burning - */ - public static void updateFurnaceBlockState(boolean isBurning, World world, int x, int y, int z) - { - TileEntity tileentity = world.getTileEntity(x, y, z); - isUpdating = true; - - if (isBurning) - { - world.setBlock(x, y, z, TFBlocks.cinderFurnaceLit); - } - else - { - world.setBlock(x, y, z, TFBlocks.cinderFurnace); - } - - isUpdating = false; - - if (tileentity != null) - { - tileentity.validate(); - world.setTileEntity(x, y, z, tileentity); - } - } - - /** - * A randomly called display update to be able to add particles or other items for display - */ - @SideOnly(Side.CLIENT) - public void randomDisplayTick(World world, int x, int y, int z, Random random) - { - - if (this.isLit) - { - float f = (float)x + 0.5F; - float f1 = (float)y + 0.0F + random.nextFloat() * 6.0F / 16.0F; - float f2 = (float)z + 0.5F; - float f3 = 0.52F; - float f4 = random.nextFloat() * 0.6F - 0.3F; - - int l = random.nextInt(4) + 2; - - if (l == 4) - { - world.spawnParticle("smoke", (double)(f - f3), (double)f1, (double)(f2 + f4), 0.0D, 0.0D, 0.0D); - world.spawnParticle("flame", (double)(f - f3), (double)f1, (double)(f2 + f4), 0.0D, 0.0D, 0.0D); - } - else if (l == 5) - { - world.spawnParticle("smoke", (double)(f + f3), (double)f1, (double)(f2 + f4), 0.0D, 0.0D, 0.0D); - world.spawnParticle("flame", (double)(f + f3), (double)f1, (double)(f2 + f4), 0.0D, 0.0D, 0.0D); - } - else if (l == 2) - { - world.spawnParticle("smoke", (double)(f + f4), (double)f1, (double)(f2 - f3), 0.0D, 0.0D, 0.0D); - world.spawnParticle("flame", (double)(f + f4), (double)f1, (double)(f2 - f3), 0.0D, 0.0D, 0.0D); - } - else if (l == 3) - { - world.spawnParticle("smoke", (double)(f + f4), (double)f1, (double)(f2 + f3), 0.0D, 0.0D, 0.0D); - world.spawnParticle("flame", (double)(f + f4), (double)f1, (double)(f2 + f3), 0.0D, 0.0D, 0.0D); - } - } - } - - - /** - * Dump things all over if broken - */ - public void breakBlock(World world, int x, int y, int z, Block block, int p_149749_6_) - { - if (!isUpdating) - { - TileEntityTFCinderFurnace tileEntity = (TileEntityTFCinderFurnace)world.getTileEntity(x, y, z); - - if (tileEntity != null) - { - for (int i = 0; i < tileEntity.getSizeInventory(); ++i) - { - ItemStack itemstack = tileEntity.getStackInSlot(i); - - if (itemstack != null) - { - float dx = this.furnaceRandom.nextFloat() * 0.8F + 0.1F; - float dy = this.furnaceRandom.nextFloat() * 0.8F + 0.1F; - float dz = this.furnaceRandom.nextFloat() * 0.8F + 0.1F; - - while (itemstack.stackSize > 0) - { - int j1 = this.furnaceRandom.nextInt(21) + 10; - - if (j1 > itemstack.stackSize) - { - j1 = itemstack.stackSize; - } - - itemstack.stackSize -= j1; - EntityItem entityitem = new EntityItem(world, (double)((float)x + dx), (double)((float)y + dy), (double)((float)z + dz), new ItemStack(itemstack.getItem(), j1, itemstack.getItemDamage())); - - if (itemstack.hasTagCompound()) - { - entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy()); - } - - float pointFive = 0.05F; - entityitem.motionX = (double)((float)this.furnaceRandom.nextGaussian() * pointFive); - entityitem.motionY = (double)((float)this.furnaceRandom.nextGaussian() * pointFive + 0.2F); - entityitem.motionZ = (double)((float)this.furnaceRandom.nextGaussian() * pointFive); - world.spawnEntityInWorld(entityitem); - } - } - } - - world.func_147453_f(x, y, z, block); - } - } - - super.breakBlock(world, x, y, z, block, p_149749_6_); - } - - public Item getItemDropped(int meta, Random rand, int fortune) - { - return Item.getItemFromBlock(TFBlocks.cinderFurnace); - } - - /** - * Gets an item for the block being called on. Args: world, x, y, z - */ - @SideOnly(Side.CLIENT) - public Item getItem(World world, int x, int y, int z) - { - return Item.getItemFromBlock(TFBlocks.cinderFurnace); - } + @Override + public void breakBlock(World world, BlockPos pos, IBlockState state) { + if (!keepInventory) { + TileEntity tileentity = world.getTileEntity(pos); + + if (tileentity instanceof TileEntityFurnace) { + InventoryHelper.dropInventoryItems(world, pos, (TileEntityFurnace) tileentity); + world.updateComparatorOutputLevel(pos, this); + } + } + + super.breakBlock(world, pos, state); + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return Item.getItemFromBlock(TFBlocks.cinder_furnace); + } + + @Override + public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) { + return new ItemStack(Item.getItemFromBlock(TFBlocks.cinder_furnace)); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + if (!isBurning) { + ModelRegisterCallback.super.registerModel(); + } + } } diff --git a/src/main/java/twilightforest/block/BlockTFCinderLog.java b/src/main/java/twilightforest/block/BlockTFCinderLog.java index 37b8ec7a3d..96bd98d4c2 100644 --- a/src/main/java/twilightforest/block/BlockTFCinderLog.java +++ b/src/main/java/twilightforest/block/BlockTFCinderLog.java @@ -1,64 +1,59 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.block.Block; import net.minecraft.block.BlockLog; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import twilightforest.TwilightForestMod; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -public class BlockTFCinderLog extends BlockLog { - - private IIcon topIcon; - private IIcon cornerIcon; - +public class BlockTFCinderLog extends BlockLog implements ModelRegisterCallback { protected BlockTFCinderLog() { - super(); this.setHardness(1.0F); - this.setStepSound(Block.soundTypeWood); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(LOG_AXIS, EnumAxis.Y)); } - - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - int orient = meta & 12; - - return orient == 12 ? this.cornerIcon : (orient == 0 && (side == 1 || side == 0) ? this.topIcon : (orient == 4 && (side == 5 || side == 4) ? this.topIcon : (orient == 8 && (side == 2 || side == 3) ? this.topIcon : blockIcon))); - } - - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.blockIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":cinder_side"); - this.topIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":cinder_top"); - this.cornerIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":cinder_corner"); - } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, LOG_AXIS); + } - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return Item.getItemFromBlock(TFBlocks.cinderLog); // hey that's my block ID! - } + @Override + public int getMetaFromState(IBlockState state) { + switch (state.getValue(LOG_AXIS)) { + case X: + return 4; + case Y: + return 0; + case Z: + return 8; + case NONE: + default: + return 12; + } + } + @Override + public IBlockState getStateFromMeta(int meta) { + switch (meta) { + case 0: + return getDefaultState().withProperty(LOG_AXIS, EnumAxis.Y); + case 4: + return getDefaultState().withProperty(LOG_AXIS, EnumAxis.X); + case 8: + return getDefaultState().withProperty(LOG_AXIS, EnumAxis.Z); + case 12: + default: + return getDefaultState().withProperty(LOG_AXIS, EnumAxis.NONE); + } + } + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return MapColor.GRAY; + } } diff --git a/src/main/java/twilightforest/block/BlockTFCompressed.java b/src/main/java/twilightforest/block/BlockTFCompressed.java new file mode 100644 index 0000000000..ad1c0985d8 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFCompressed.java @@ -0,0 +1,193 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemShears; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.enums.CompressedVariant; +import twilightforest.item.TFItems; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +public class BlockTFCompressed extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", CompressedVariant.class); + + public BlockTFCompressed() { + super(Material.IRON, MapColor.IRON); + this.setHardness(5.0F); + this.setResistance(10.0F); + this.setSoundType(SoundType.METAL); + this.setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, CompressedVariant.IRONWOOD)); + this.setCreativeTab(TFItems.creativeTab); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, CompressedVariant.values()[meta]); + } + + @Override + public void getSubBlocks(CreativeTabs tab, NonNullList list) { + for (CompressedVariant variation : CompressedVariant.values() ) { + list.add(new ItemStack(this, 1, variation.ordinal())); + } + } + + @Override + @SideOnly(Side.CLIENT) + public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos) { + return state.getValue(VARIANT) == CompressedVariant.FIERY ? 15728880 : super.getPackedLightmapCoords(state, source, pos); + } + + @Override + public boolean getUseNeighborBrightness(IBlockState state) { + return state.getValue(VARIANT) == CompressedVariant.FIERY || super.getUseNeighborBrightness(state); + } + + @Override + public SoundType getSoundType(IBlockState state, World world, BlockPos pos, @Nullable Entity entity) { + return state.getValue(VARIANT).soundType; + } + + @Override + public Material getMaterial(IBlockState state) { + return state.getValue(VARIANT).material; + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.getValue(VARIANT).mapColor; + } + + @Override + public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World worldIn, BlockPos pos) { + // ItemShears#getDestroySpeed is really dumb and doesn't check IShearable so we have to do it this way to try to match the wool break speed with shears + return state.getValue(VARIANT) == CompressedVariant.ARCTIC_FUR && player.getHeldItemMainhand().getItem() instanceof ItemShears ? 0.2F : super.getPlayerRelativeBlockHardness(state, player, worldIn, pos); + } + + @Override + public float getBlockHardness(IBlockState blockState, World worldIn, BlockPos pos) { + switch (blockState.getValue(VARIANT)) { + default: + case FIERY: + case IRONWOOD: + case STEELLEAF: + return super.getBlockHardness(blockState, worldIn, pos); + case ARCTIC_FUR: + return 0.8F; + case CARMINITE: + return 0.0F; + } + } + + @Override + public boolean isBeaconBase(IBlockAccess worldObj, BlockPos pos, BlockPos beacon) { + return true; + } + + @Override + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + List variants = new ArrayList<>(VARIANT.getAllowedValues()); + + for (int i = 0; i < variants.size(); i++) + if (i != CompressedVariant.FIERY.ordinal()) + ModelUtils.registerToState(this, i, this.getDefaultState().withProperty(VARIANT, variants.get(i))); + + ModelResourceLocation mrl = new ModelResourceLocation(this.getRegistryName(), "inventory_fiery"); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), CompressedVariant.FIERY.ordinal(), mrl); + } + + @Override + public void onEntityWalk(World worldIn, BlockPos pos, Entity entityIn) { + if ((!entityIn.isImmuneToFire()) + && entityIn instanceof EntityLivingBase + && (!EnchantmentHelper.hasFrostWalkerEnchantment((EntityLivingBase)entityIn)) + && worldIn.getBlockState(pos).getValue(VARIANT) == CompressedVariant.FIERY) { + entityIn.attackEntityFrom(DamageSource.HOT_FLOOR, 1.0F); + } + + super.onEntityWalk(worldIn, pos, entityIn); + } + + @Override + public void onFallenUpon(World worldIn, BlockPos pos, Entity entityIn, float fallDistance) { + switch(worldIn.getBlockState(pos).getValue(VARIANT)) { + case STEELLEAF: + entityIn.fall(fallDistance, 0.75F); + break; + case ARCTIC_FUR: + entityIn.fall(fallDistance, 0.1F); + break; + } + } + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + @Override + public boolean isFireSource(World world, BlockPos pos, EnumFacing face) { + return CompressedVariant.FIERY == world.getBlockState(pos).getValue(VARIANT); + } + + @Override + public boolean isStickyBlock(IBlockState state) { + return state.getValue(VARIANT) == CompressedVariant.CARMINITE; + } + + @Override + @Deprecated + @SideOnly(Side.CLIENT) + public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { + if (blockState.getValue(VARIANT) == CompressedVariant.FIERY) { + IBlockState state = blockAccess.getBlockState(pos.offset(side)); + return state.getBlock() != this || state.getValue(VARIANT) != CompressedVariant.FIERY; + } else return super.shouldSideBeRendered(blockState, blockAccess, pos, side); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFConnectableRotatedPillar.java b/src/main/java/twilightforest/block/BlockTFConnectableRotatedPillar.java new file mode 100644 index 0000000000..6c07da8683 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFConnectableRotatedPillar.java @@ -0,0 +1,270 @@ +package twilightforest.block; + +import net.minecraft.block.BlockFence; +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import twilightforest.TwilightForestMod; + +import javax.annotation.Nullable; +import java.util.List; + +public abstract class BlockTFConnectableRotatedPillar extends BlockRotatedPillar { + + final double boundingBoxWidthLower; + final double boundingBoxWidthUpper; + + private final double boundingBoxHeightLower; + private final double boundingBoxHeightUpper; + + BlockTFConnectableRotatedPillar(Material material, double size) { + this(material, material.getMaterialMapColor(), size, size); + } + + BlockTFConnectableRotatedPillar(Material material, double width, double height) { + this(material, material.getMaterialMapColor(), width, height); + } + + BlockTFConnectableRotatedPillar(Material material, MapColor mapColor, double size) { + this(material, mapColor, size, size); + } + + BlockTFConnectableRotatedPillar(Material material, MapColor mapColor, double width, double height) { + super(material, mapColor); + + if (width >= 16d) { + this.boundingBoxWidthLower = 0d; + this.boundingBoxWidthUpper = 16d; + } else { + this.boundingBoxWidthLower = 8d-(width/2d); + this.boundingBoxWidthUpper = 16d-this.boundingBoxWidthLower; + } + + if (height >= 16d) { + this.boundingBoxHeightLower = 0d; + this.boundingBoxHeightUpper = 16d; + } else { + this.boundingBoxHeightLower = 8d-(height/2d); + this.boundingBoxHeightUpper = 16d-this.boundingBoxHeightLower; + } + + this.setDefaultState(blockState.getBaseState().withProperty(AXIS, EnumFacing.Axis.Y) + .withProperty(BlockFence.NORTH, false).withProperty(BlockFence.WEST, false) + .withProperty(BlockFence.SOUTH, false).withProperty(BlockFence.EAST, false)); + } + + protected abstract IProperty[] getAdditionalProperties(); + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer.Builder(this) + .add(AXIS, BlockFence.NORTH, BlockFence.EAST, BlockFence.SOUTH, BlockFence.WEST) + .add(getAdditionalProperties()) + .build(); + } + + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) { + // If our axis is rotated (i.e. not upright), then adjust the actual sides tested + // This allows the entire model to be rotated in the assets in a cleaner way + + EnumFacing.Axis axis = state.getValue(AXIS); + + for (PairHelper pair : PairHelper.values()) { + EnumFacing connectTo = PairHelper.getFacingFromPropertyWithAxis(pair.property, axis); + state = state.withProperty(pair.property, canConnectTo(state, world.getBlockState(pos.offset(connectTo)), world, pos, connectTo)); + } + + return state; + } + + protected boolean canConnectTo(IBlockState state, IBlockState otherState, IBlockAccess world, BlockPos pos, EnumFacing connectTo) { + return state.getBlock() == otherState.getBlock() && state.getValue(AXIS) != connectTo.getAxis(); + } + + @Override + public void addCollisionBoxToList(IBlockState state, World world, BlockPos pos, AxisAlignedBB aabb, List list, @Nullable Entity entity, boolean useActualState) { + if (!useActualState) state = this.getActualState(state, world, pos); + + EnumFacing.Axis axis = state.getValue(AXIS); + + // Add main pillar + addCollisionBoxToList(pos, aabb, list, makeQuickAABB( + axis == EnumFacing.Axis.X ? 16d : this.boundingBoxWidthLower, + axis == EnumFacing.Axis.Y ? 16d : this.boundingBoxWidthLower, + axis == EnumFacing.Axis.Z ? 16d : this.boundingBoxWidthLower, + axis == EnumFacing.Axis.X ? 0d : this.boundingBoxWidthUpper, + axis == EnumFacing.Axis.Y ? 0d : this.boundingBoxWidthUpper, + axis == EnumFacing.Axis.Z ? 0d : this.boundingBoxWidthUpper)); + + // Add axillary pillar connections + // Cycle through all possible faces + for (EnumFacing facing : EnumFacing.VALUES) { + // If the facing in loop doesn't cover the axis of the block and if that side's state is true, then add to list + if (facing.getAxis() != axis && state.getValue(PairHelper.getPropertyFromFacingWithAxis(facing, axis))) { + // Create AABB piece and add to list + addCollisionBoxToList(pos, aabb, list, getSidedAABBStraight(facing, axis)); + } + } + } + + // Utility to make a bounding-box piece + protected AxisAlignedBB getSidedAABBStraight(EnumFacing facing, EnumFacing.Axis axis) { + return makeQuickAABB( + facing == EnumFacing.EAST ? 16d : axis == EnumFacing.Axis.X ? this.boundingBoxHeightLower : this.boundingBoxWidthLower, + facing == EnumFacing.UP ? 16d : axis == EnumFacing.Axis.Y ? this.boundingBoxHeightLower : this.boundingBoxWidthLower, + facing == EnumFacing.SOUTH ? 16d : axis == EnumFacing.Axis.Z ? this.boundingBoxHeightLower : this.boundingBoxWidthLower, + facing == EnumFacing.WEST ? 0d : axis == EnumFacing.Axis.X ? this.boundingBoxHeightUpper : this.boundingBoxWidthUpper, + facing == EnumFacing.DOWN ? 0d : axis == EnumFacing.Axis.Y ? this.boundingBoxHeightUpper : this.boundingBoxWidthUpper, + facing == EnumFacing.NORTH ? 0d : axis == EnumFacing.Axis.Z ? this.boundingBoxHeightUpper : this.boundingBoxWidthUpper); + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + state = this.getActualState(state, world, pos); + + switch (state.getValue(AXIS)) { + case X: + return makeQuickAABB( + 0d, + state.getValue(BlockFence.NORTH) ? 0d : this.boundingBoxWidthLower, + state.getValue(BlockFence.WEST ) ? 0d : this.boundingBoxWidthLower, + 16d, + state.getValue(BlockFence.SOUTH) ? 16d : this.boundingBoxWidthUpper, + state.getValue(BlockFence.EAST ) ? 16d : this.boundingBoxWidthUpper + ); + case Z: + return makeQuickAABB( + state.getValue(BlockFence.EAST ) ? 0d : this.boundingBoxWidthLower, + state.getValue(BlockFence.SOUTH) ? 0d : this.boundingBoxWidthLower, + 0d, + state.getValue(BlockFence.WEST ) ? 16d : this.boundingBoxWidthUpper, + state.getValue(BlockFence.NORTH) ? 16d : this.boundingBoxWidthUpper, + 16d + ); + default: + return makeQuickAABB( + state.getValue(BlockFence.WEST) ? 0d : this.boundingBoxWidthLower, + 0d, + state.getValue(BlockFence.NORTH) ? 0d : this.boundingBoxWidthLower, + state.getValue(BlockFence.EAST) ? 16d : this.boundingBoxWidthUpper, + 16d, + state.getValue(BlockFence.SOUTH) ? 16d : this.boundingBoxWidthUpper + ); + } + } + + protected AxisAlignedBB makeQuickAABB(double x1, double y1, double z1, double x2, double y2, double z2) { + return new AxisAlignedBB( + x1/16.0d, y1/16.0d, + z1/16.0d, x2/16.0d, + y2/16.0d, z2/16.0d); + } + + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } + + enum PairHelper { + NORTH(EnumFacing.NORTH, BlockFence.NORTH), + EAST (EnumFacing.EAST , BlockFence.EAST ), + SOUTH(EnumFacing.SOUTH, BlockFence.SOUTH), + WEST (EnumFacing.WEST , BlockFence.WEST ); + + final EnumFacing facing; + final PropertyBool property; + + PairHelper(EnumFacing facing, PropertyBool property) { + this.facing = facing; + this.property = property; + } + + static EnumFacing getFacingFromPropertyWithAxis(PropertyBool property, EnumFacing.Axis axis) { + switch (axis) { + case X: + if (property == BlockFence.NORTH) return EnumFacing.DOWN; + if (property == BlockFence.SOUTH) return EnumFacing.UP; + if (property == BlockFence.WEST ) return EnumFacing.NORTH; + if (property == BlockFence.EAST ) return EnumFacing.SOUTH; + break; + case Y: + if (property == BlockFence.NORTH) return EnumFacing.NORTH; + if (property == BlockFence.SOUTH) return EnumFacing.SOUTH; + if (property == BlockFence.WEST ) return EnumFacing.WEST; + if (property == BlockFence.EAST ) return EnumFacing.EAST; + break; + case Z: + if (property == BlockFence.NORTH) return EnumFacing.UP; + if (property == BlockFence.SOUTH) return EnumFacing.DOWN; + if (property == BlockFence.WEST ) return EnumFacing.EAST; + if (property == BlockFence.EAST ) return EnumFacing.WEST; + break; + } + + TwilightForestMod.LOGGER.warn("ConnectableRotatedPillar helper (getFacingFromPropertyWithAxis) had a problem? (property '{}' with axis '{}')", property.getName(), axis.getName()); + return EnumFacing.UP; + } + + static PropertyBool getPropertyFromFacingWithAxis(EnumFacing facing, EnumFacing.Axis axis) { + switch (axis) { + case X: + switch (facing) { + case DOWN: + return BlockFence.NORTH; + case UP: + return BlockFence.SOUTH; + case NORTH: + return BlockFence.WEST; + case SOUTH: + return BlockFence.EAST; + } + break; + case Y: + switch (facing) { + case NORTH: + return BlockFence.NORTH; + case SOUTH: + return BlockFence.SOUTH; + case WEST: + return BlockFence.WEST; + case EAST: + return BlockFence.EAST; + } + break; + case Z: + switch (facing) { + case DOWN: + return BlockFence.SOUTH; + case UP: + return BlockFence.NORTH; + case WEST: + return BlockFence.EAST; + case EAST: + return BlockFence.WEST; + } + break; + } + + TwilightForestMod.LOGGER.warn("ConnectableRotatedPillar helper (getPropertyFromFacingWithAxis) had a problem? (facing '{}' with axis '{}')", facing.getName(), axis.getName()); + return BlockFence.NORTH; + } + } +} diff --git a/src/main/java/twilightforest/block/BlockTFCritter.java b/src/main/java/twilightforest/block/BlockTFCritter.java index d55ce3ef7e..78126e1911 100644 --- a/src/main/java/twilightforest/block/BlockTFCritter.java +++ b/src/main/java/twilightforest/block/BlockTFCritter.java @@ -1,307 +1,173 @@ package twilightforest.block; -import static net.minecraftforge.common.util.ForgeDirection.EAST; -import static net.minecraftforge.common.util.ForgeDirection.NORTH; -import static net.minecraftforge.common.util.ForgeDirection.SOUTH; -import static net.minecraftforge.common.util.ForgeDirection.WEST; - -import java.util.List; - import net.minecraft.block.Block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import java.util.Random; public abstract class BlockTFCritter extends Block { - - - protected BlockTFCritter() - { - super(Material.circuits); + private final float WIDTH = getWidth(); + + private final AxisAlignedBB DOWN_BB = new AxisAlignedBB(0.5F - WIDTH, 1.0F - WIDTH * 2.0F, 0.2F, 0.5F + WIDTH, 1.0F, 0.8F); + private final AxisAlignedBB UP_BB = new AxisAlignedBB(0.5F - WIDTH, 0.0F, 0.2F, 0.5F + WIDTH, WIDTH * 2.0F, 0.8F); + private final AxisAlignedBB NORTH_BB = new AxisAlignedBB(0.5F - WIDTH, 0.2F, 1.0F - WIDTH * 2.0F, 0.5F + WIDTH, 0.8F, 1.0F); + private final AxisAlignedBB SOUTH_BB = new AxisAlignedBB(0.5F - WIDTH, 0.2F, 0.0F, 0.5F + WIDTH, 0.8F, WIDTH * 2.0F); + private final AxisAlignedBB WEST_BB = new AxisAlignedBB(1.0F - WIDTH * 2.0F, 0.2F, 0.5F - WIDTH, 1.0F, 0.8F, 0.5F + WIDTH); + private final AxisAlignedBB EAST_BB = new AxisAlignedBB(0.0F, 0.2F, 0.5F - WIDTH, WIDTH * 2.0F, 0.8F, 0.5F + WIDTH); + + protected BlockTFCritter() { + super(Material.CIRCUITS); this.setHardness(0.0F); this.setCreativeTab(TFItems.creativeTab); - - this.stepSound = new StepSoundTFInsect("squish", 0.25F, 0.6F); - } - - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - @Override - public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) - { - int facing = world.getBlockMetadata(x, y, z) & 7; - float wide = 0.15F; - if (facing == 1) - { - setBlockBounds(0.0F, 0.2F, 0.5F - wide, wide * 2.0F, 0.8F, 0.5F + wide); - } - else if(facing == 2) - { - setBlockBounds(1.0F - wide * 2.0F, 0.2F, 0.5F - wide, 1.0F, 0.8F, 0.5F + wide); - } - else if(facing == 3) - { - setBlockBounds(0.5F - wide, 0.2F, 0.0F, 0.5F + wide, 0.8F, wide * 2.0F); - } - else if(facing == 4) - { - setBlockBounds(0.5F - wide, 0.2F, 1.0F - wide * 2.0F, 0.5F + wide, 0.8F, 1.0F); - } - else if(facing == 5) - { - setBlockBounds(0.5F - wide, 0.0F, 0.2F, 0.5F + wide, wide * 2.0F, 0.8F); - } - else if(facing == 6) - { - setBlockBounds(0.5F - wide, 1.0F - wide * 2.0F, 0.2F, 0.5F + wide, 1.0F, 0.8F); - } - else - { - float f1 = 0.1F; - setBlockBounds(0.5F - f1, 0.0F, 0.5F - f1, 0.5F + f1, 0.6F, 0.5F + f1); - } - } - - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) - { - return null; - } + this.setSoundType(SoundType.SLIME); + this.setDefaultState(blockState.getBaseState().withProperty(BlockDirectional.FACING, EnumFacing.UP)); + } + + public float getWidth() { + return 0.15F; + } @Override - public boolean isOpaqueCube() - { - return false; + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, BlockDirectional.FACING); } @Override - public boolean renderAsNormalBlock() - { - return false; + public int getMetaFromState(IBlockState state) { + return state.getValue(BlockDirectional.FACING).getIndex(); } - - /** - * The type of render function that is called for this block - */ + @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getCritterBlockRenderID(); + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.byIndex(meta)); } - @Override - public boolean canPlaceBlockAt(World world, int x, int y, int z) { - if (canPlaceAt(world, x - 1, y, z)) { - return true; - } else if (canPlaceAt(world, x + 1, y, z)) { - return true; - } else if (canPlaceAt(world, x, y, z - 1)) { - return true; - } else if (canPlaceAt(world, x, y, z + 1)) { - return true; - } else if (canPlaceAt(world, x, y - 1, z)) { - return true; - } else if (canPlaceAt(world, x, y + 1, z)) { - return true; - } else { - return false; + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + switch (state.getValue(BlockDirectional.FACING)) { + case DOWN: + return DOWN_BB; + case UP: + default: + return UP_BB; + case NORTH: + return NORTH_BB; + case SOUTH: + return SOUTH_BB; + case WEST: + return WEST_BB; + case EAST: + return EAST_BB; } } - @Override - public int onBlockPlaced(World par1World, int x, int y, int z, int placementFacing, float par6, float par7, float par8, int meta) - { - if (placementFacing == 1 && this.canPlaceAt(par1World, x, y - 1, z)) - { - meta = 5; - } + @Deprecated + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return NULL_AABB; + } - if (placementFacing == 0 && this.canPlaceAt(par1World, x, y + 1, z)) - { - meta = 6; - } + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } - if (placementFacing == 2 && par1World.isSideSolid(x, y, z + 1, NORTH, true)) - { - meta = 4; - } + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } - if (placementFacing == 3 && par1World.isSideSolid(x, y, z - 1, SOUTH, true)) - { - meta = 3; - } + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } - if (placementFacing == 4 && par1World.isSideSolid(x + 1, y, z, WEST, true)) - { - meta = 2; - } + @Override + public boolean canPlaceBlockOnSide(World world, BlockPos pos, EnumFacing side) { + return canPlaceAt(world, pos.offset(side.getOpposite()), side); + } - if (placementFacing == 5 && par1World.isSideSolid(x - 1, y, z, EAST, true)) - { - meta = 1; - } - - return meta; - } + @Override + public boolean canPlaceBlockAt(World world, BlockPos pos) { + for (EnumFacing side : EnumFacing.values()) { + if (canPlaceAt(world, pos.offset(side.getOpposite()), side)) { + return true; + } + } + return false; + } + + @Override + @Deprecated + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing sideHit, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + IBlockState state = getDefaultState(); - - /** - * Called whenever the block is added into the world. Args: world, x, y, z - */ - @Override - public void onBlockAdded(World world, int x, int y, int z) - { - if (world.getBlockMetadata(x, y, z) == 0) - { - if (canPlaceAt(world, x - 1, y, z)) { - world.setBlockMetadataWithNotify(x, y, z, 1, 2); - } - else if (canPlaceAt(world, x + 1, y, z)) { - world.setBlockMetadataWithNotify(x, y, z, 2, 2); - } - else if (canPlaceAt(world, x, y, z - 1)) { - world.setBlockMetadataWithNotify(x, y, z, 3, 2); - } - else if (canPlaceAt(world, x, y, z + 1)) { - world.setBlockMetadataWithNotify(x, y, z, 4, 2); - } - else if (canPlaceAt(world, x, y - 1, z)) { - world.setBlockMetadataWithNotify(x, y, z, 5, 2); - } - else if (canPlaceAt(world, x, y + 1, z)) { - world.setBlockMetadataWithNotify(x, y, z, 6, 2); - } - } + if (canPlaceAt(world, pos.offset(sideHit.getOpposite()), sideHit)) { + state = state.withProperty(BlockDirectional.FACING, sideHit); + } + + return state; + } + + @Override + public void onBlockAdded(World world, BlockPos pos, IBlockState state) { + world.scheduleUpdate(pos, this, 1); + } - dropCritterIfCantStay(world, x, y, z); - - // for fireflies, schedule a lighting update - int meta = world.getBlockMetadata(x, y, z); - if (meta == 0) { - world.scheduleBlockUpdate(x, y, z, this, tickRate(world)); - } - } + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { + checkAndDrop(world, pos, state); + } - public boolean dropCritterIfCantStay(World world, int x, int y, int z) - { - if(!canPlaceBlockAt(world, x, y, z)) - { - dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); - world.setBlockToAir(x, y, z); - return false; - } else - { - return true; - } - } + protected boolean checkAndDrop(World world, BlockPos pos, IBlockState state) { + EnumFacing facing = state.getValue(BlockDirectional.FACING); + if (!canPlaceAt(world, pos.offset(facing.getOpposite()), facing)) { + world.destroyBlock(pos, true); + return false; + } + return true; + } - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor blockID - */ - @Override - public void onNeighborBlockChange(World world, int x, int y, int z, Block blockID) - { - if(dropCritterIfCantStay(world, x, y, z)) - { - int facing = world.getBlockMetadata(x, y, z) & 7; - - boolean flag = false; - if (!canPlaceAt(world, x - 1, y, z) && facing == 1) { - flag = true; - } - if (!canPlaceAt(world, x + 1, y, z) && facing == 2) { - flag = true; - } - if (!canPlaceAt(world, x, y, z - 1) && facing == 3) { - flag = true; - } - if (!canPlaceAt(world, x, y, z + 1) && facing == 4) { - flag = true; - } - if (!canPlaceAt(world, x, y - 1, z) && facing == 5) { - flag = true; - } - if (!canPlaceAt(world, x, y + 1, z) && facing == 6) { - flag = true; - } - if (flag) { - dropBlockAsItem(world, x, y, z, 0, 0); - world.setBlockToAir(x, y, z); - } - } - } + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) { + checkAndDrop(world, pos, state); + } + protected boolean canPlaceAt(IBlockAccess world, BlockPos pos, EnumFacing facing) { + IBlockState state = world.getBlockState(pos); + return state.getBlockFaceShape(world, pos, facing) == BlockFaceShape.SOLID + && (!isExceptBlockForAttachWithPiston(state.getBlock()) + || state.getMaterial() == Material.LEAVES || state.getMaterial() == Material.CACTUS); + } - /** - * We can place fireflies on any normal block or on leaves. - */ - public boolean canPlaceAt(World world, int x, int y, int z) - { - return world.isBlockNormalCubeDefault(x, y, z, true) || world.getBlock(x, y, z).getMaterial() == Material.leaves || world.getBlock(x, y, z).getMaterial() == Material.cactus; - } - - /** - * Called throughout the code as a replacement for block instanceof BlockContainer - * Moving this to the Block base class allows for mods that wish to extend vinella - * blocks, and also want to have a tile entity on that block, may. - * - * Return true from this function to specify this block has a tile entity. - * - * @param metadata Metadata of the current block - * @return True if block has a tile entity, false otherwise - */ - @Override - public boolean hasTileEntity(int metadata) { - return true; - } - - /** - * Called throughout the code as a replacement for BlockContainer.getBlockEntity - * Return the same thing you would from that function. - * This will fall back to BlockContainer.getBlockEntity if this block is a BlockContainer. - * - * @param metadata The Metadata of the current block - * @return A instance of a class extending TileEntity - */ - @Override - public abstract TileEntity createTileEntity(World world, int metadata); + @Override + public boolean hasTileEntity(IBlockState state) { + return true; + } - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - } + public abstract TileEntity createTileEntity(World world, IBlockState state); - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.blockIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + public abstract ItemStack getSquishResult(); // oh no! } - - diff --git a/src/main/java/twilightforest/block/BlockTFDarkLeaves.java b/src/main/java/twilightforest/block/BlockTFDarkLeaves.java index 9d3f9089f4..ab991cb643 100644 --- a/src/main/java/twilightforest/block/BlockTFDarkLeaves.java +++ b/src/main/java/twilightforest/block/BlockTFDarkLeaves.java @@ -1,151 +1,67 @@ package twilightforest.block; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.world.ColorizerFoliage; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFDarkLeaves extends Block { +import java.util.Random; + +public class BlockTFDarkLeaves extends Block implements ModelRegisterCallback { protected BlockTFDarkLeaves() { - super(Material.leaves); + super(Material.LEAVES); this.setHardness(2F); this.setResistance(10F); - this.setStepSound(Block.soundTypeGrass); + this.setSoundType(SoundType.PLANT); this.setCreativeTab(TFItems.creativeTab); - - this.textureName = TwilightForestMod.ID + ":darkwood_leaves2"; } - - - @SideOnly(Side.CLIENT) - public int getBlockColor() - { - double d0 = 0.5D; - double d1 = 1.0D; - return ColorizerFoliage.getFoliageColor(d0, d1); - } - - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @SideOnly(Side.CLIENT) - public int getRenderColor(int p_149741_1_) - { - return ColorizerFoliage.getFoliageColorBasic(); - } - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @SideOnly(Side.CLIENT) - public int colorMultiplier(IBlockAccess world, int x, int y, int z) - { - int red = 0; - int grn = 0; - int blu = 0; - - for (int dz = -1; dz <= 1; ++dz) - { - for (int dx = -1; dx <= 1; ++dx) - { - int i2 = world.getBiomeGenForCoords(x + dx, z + dz).getBiomeFoliageColor(x + dx, y, z + dz); - red += (i2 & 16711680) >> 16; - grn += (i2 & 65280) >> 8; - blu += i2 & 255; - } - } - - return (red / 9 & 255) << 16 | (grn / 9 & 255) << 8 | blu / 9 & 255; - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return 3; + @Override + public int damageDropped(IBlockState state) { + return 3; } - - /** - * Chance that fire will spread and consume this block. - * 300 being a 100% chance, 0, being a 0% chance. - * - * @param world The current world - * @param x The blocks X position - * @param y The blocks Y position - * @param z The blocks Z position - * @param metadata The blocks current metadata - * @param face The face that the fire is coming from - * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire - */ - @Override - public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + @Override + public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing side) { return 1; } - /** - * Called when fire is updating on a neighbor block. - * The higher the number returned, the faster fire will spread around this block. - * - * @param world The current world - * @param x The blocks X position - * @param y The blocks Y position - * @param z The blocks Z position - * @param metadata The blocks current metadata - * @param face The face that the fire is coming from - * @return A number that is used to determine the speed of fire growth around the block - */ @Override - public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing side) { return 0; } - /** - * Returns the quantity of items to drop on block destruction. - */ - @Override - public int quantityDropped(Random par1Random) - { - return par1Random.nextInt(40) == 0 ? 1 : 0; - } + @Override + public int quantityDropped(Random random) { + return random.nextInt(40) == 0 ? 1 : 0; + } - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int meta, Random par2Random, int par3) - { - return Item.getItemFromBlock(TFBlocks.sapling); - } + @Override + public Item getItemDropped(IBlockState state, Random random, int fortune) { + return Item.getItemFromBlock(TFBlocks.twilight_sapling); + } - /** - * Drops the block items with a specified chance of dropping the specified items - */ - @Override - public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int meta, float par6, int fortune) - { - if (!par1World.isRemote) - { - if (par1World.rand.nextInt(40) == 0) - { - Item var9 = this.getItemDropped(meta, par1World.rand, fortune); - this.dropBlockAsItem(par1World, par2, par3, par4, new ItemStack(var9, 1, this.damageDropped(meta))); - } - } - } + @Override + public ItemStack getItem(World world, BlockPos pos, IBlockState state) { + return new ItemStack(this); + } + @Override + public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { + Random rand = world instanceof World ? ((World)world).rand : RANDOM; + if (rand.nextInt(40) == 0) { + Item item = this.getItemDropped(state, rand, fortune); + drops.add(new ItemStack(item, 1, this.damageDropped(state))); + } + } } - diff --git a/src/main/java/twilightforest/block/BlockTFDeadrock.java b/src/main/java/twilightforest/block/BlockTFDeadrock.java index b048c0d076..c9b6ccfaaa 100644 --- a/src/main/java/twilightforest/block/BlockTFDeadrock.java +++ b/src/main/java/twilightforest/block/BlockTFDeadrock.java @@ -1,72 +1,67 @@ package twilightforest.block; -import java.util.List; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import twilightforest.TwilightForestMod; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.DeadrockVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFDeadrock extends Block { - - public static final String[] names = new String[] {"surface", "cracked", "solid"}; - private IIcon[] icons; +public class BlockTFDeadrock extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", DeadrockVariant.class); protected BlockTFDeadrock() { - super(Material.rock); - this.setHardness(100F); + super(Material.ROCK); + this.setHardness(100F); this.setResistance(6000000.0F); - this.setStepSound(soundTypePiston); + this.setSoundType(SoundType.STONE); this.disableStats(); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, DeadrockVariant.SURFACE)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); } - - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister iconRegister) - { - this.icons = new IIcon[names.length]; - - for (int i = 0; i < names.length; i++) { - this.icons[i] = iconRegister.registerIcon(TwilightForestMod.ID + ":deadrock_" + names[i]); - } - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - if (meta > this.names.length) { - meta = 0; - } - - return this.icons[meta]; - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ + @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - for (int i = 0; i < names.length; i++) { - par3List.add(new ItemStack(par1, 1, i)); - } - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - public int damageDropped(int meta) - { - return meta; - } + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, DeadrockVariant.values()[meta]); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + for (DeadrockVariant variant : DeadrockVariant.values()) { + list.add(new ItemStack(this, 1, variant.ordinal())); + } + } + + @Override + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } } diff --git a/src/main/java/twilightforest/block/BlockTFDiagonal.java b/src/main/java/twilightforest/block/BlockTFDiagonal.java new file mode 100644 index 0000000000..a12c97fae0 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFDiagonal.java @@ -0,0 +1,65 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFDiagonal extends Block implements ModelRegisterCallback { + + public static final PropertyBool IS_ROTATED = PropertyBool.create("is_rotated"); + + public BlockTFDiagonal(Material material) { + super(material); + } + + public BlockTFDiagonal(Material material, MapColor mapColor) { + super(material, mapColor); + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, IS_ROTATED); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(IS_ROTATED, meta != 0); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(IS_ROTATED) ? 1 : 0; + } + + @Override + public IBlockState withRotation(IBlockState state, Rotation rot) { + return rot == Rotation.NONE || rot == Rotation.CLOCKWISE_180 ? state : state.withProperty(IS_ROTATED, !state.getValue(IS_ROTATED)); + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { + return mirrorIn == Mirror.NONE ? state : state.withProperty(IS_ROTATED, !state.getValue(IS_ROTATED)); + } + + @Override + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return this.getDefaultState().withProperty(IS_ROTATED, EnumFacing.byHorizontalIndex(MathHelper.floor(placer.rotationYaw * 4.0F / 360.0F) & 1) == EnumFacing.WEST); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFDirectionalRotatedPillar.java b/src/main/java/twilightforest/block/BlockTFDirectionalRotatedPillar.java new file mode 100644 index 0000000000..c2f14db555 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFDirectionalRotatedPillar.java @@ -0,0 +1,64 @@ +package twilightforest.block; + +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public abstract class BlockTFDirectionalRotatedPillar extends BlockRotatedPillar { + + public static final IProperty REVERSED = PropertyBool.create("reversed"); + + public BlockTFDirectionalRotatedPillar(Material materialIn) { + super(materialIn); + } + + public BlockTFDirectionalRotatedPillar(Material materialIn, MapColor color) { + super(materialIn, color); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + IBlockState state = super.getStateFromMeta(meta); + return state.withProperty(REVERSED, (meta & 1) != 0); + } + + @Override + public int getMetaFromState(IBlockState state) { + int meta = super.getMetaFromState(state); + return meta | (state.getValue(REVERSED) ? 1 : 0); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, AXIS, REVERSED); + } + + @Override + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return super.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer) + .withProperty(REVERSED, facing.getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE); + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirror) { + if (mirror != Mirror.NONE) { + EnumFacing.Axis axis = state.getValue(AXIS); + if (axis == EnumFacing.Axis.Y + || mirror == Mirror.LEFT_RIGHT && axis == EnumFacing.Axis.Z + || mirror == Mirror.FRONT_BACK && axis == EnumFacing.Axis.X) { + + return state.cycleProperty(REVERSED); + } + } + return super.withMirror(state, mirror); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFDoor.java b/src/main/java/twilightforest/block/BlockTFDoor.java new file mode 100644 index 0000000000..6d07bb928f --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFDoor.java @@ -0,0 +1,59 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockDoor; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import twilightforest.client.ModelRegisterCallback; + +import java.util.Random; + +public class BlockTFDoor extends BlockDoor implements ModelRegisterCallback { + + private final MapColor mapColor; + private final ResourceLocation itemLocation; + + private Item item; + + protected BlockTFDoor(Material material, MapColor mapColor, ResourceLocation itemLocation) { + super(material); + this.mapColor = mapColor; + this.itemLocation = itemLocation; + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return mapColor; + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return state.getValue(HALF) == BlockDoor.EnumDoorHalf.UPPER ? Items.AIR : this.getItem(); + } + + @Override + public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { + return new ItemStack(this.getItem()); + } + + private Item getItem() { + if (item == null) { + item = Item.REGISTRY.getObject(itemLocation); + } + return item; + } +} diff --git a/src/main/java/twilightforest/block/BlockTFExperiment115.java b/src/main/java/twilightforest/block/BlockTFExperiment115.java new file mode 100644 index 0000000000..d17a0856b8 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFExperiment115.java @@ -0,0 +1,211 @@ +package twilightforest.block; + +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.properties.PropertyInteger; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatList; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +import java.util.Random; + +public class BlockTFExperiment115 extends Block implements ModelRegisterCallback { + + public static final IProperty NOMS = PropertyInteger.create("omnomnom", 0, 7); + public static final IProperty REGENERATE = PropertyBool.create("regenerate"); + + private static final AxisAlignedBB[] AABB = new AxisAlignedBB[] { + new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.9375D, 0.5D, 0.9375D), + new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.5D, 0.5D, 0.9375D), + new AxisAlignedBB(0.0625D, 0.0D, 0.0625D, 0.5D, 0.5D, 0.5D) + }; + + public BlockTFExperiment115() { + super(Material.CAKE, MapColor.IRON); + this.setTickRandomly(true); + this.setDefaultState(this.blockState.getBaseState().withProperty(NOMS, 7).withProperty(REGENERATE, false)); + this.setSoundType(SoundType.CLOTH); + } + + @Override + public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) { + return new ItemStack(TFItems.experiment_115); + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + switch (state.getValue(NOMS)) { + default: + return AABB[0]; + case 4: + case 5: + return AABB[1]; + case 6: + case 7: + return AABB[2]; + } + } + + @Override + public boolean isFullCube(IBlockState state) + { + return false; + } + + @Override + public boolean isOpaqueCube(IBlockState state) + { + return false; + } + + @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } + + @Override + public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + int bitesTaken = state.getValue(NOMS); + ItemStack stack = player.getHeldItem(hand); + + if (!player.isSneaking()) { + if (bitesTaken > 0 && stack.getItem() == TFItems.experiment_115) { + worldIn.setBlockState(pos, state.withProperty(NOMS, bitesTaken - 1)); + if (!player.isCreative()) stack.shrink(1); + if (player instanceof EntityPlayerMP) CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, pos, stack); + return true; + } else if (((!state.getValue(REGENERATE)) && stack.getItem() == Items.REDSTONE) && (player.isCreative() || bitesTaken == 0)) { + worldIn.setBlockState(pos, state.withProperty(REGENERATE,true)); + if (!player.isCreative()) stack.shrink(1); + if (player instanceof EntityPlayerMP) CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, pos, stack); + return true; + } + } + + return this.eatCake(worldIn, pos, state, player) || stack.isEmpty(); + } + + private boolean eatCake(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + if (!player.canEat(false)) return false; + else { + player.addStat(StatList.CAKE_SLICES_EATEN); + player.getFoodStats().addStats(4, 0.3F); + int i = state.getValue(NOMS); + + if (i < 7) world.setBlockState(pos, state.withProperty(NOMS, i + 1), 3); + else world.setBlockToAir(pos); + + if (player instanceof EntityPlayerMP) + CriteriaTriggers.CONSUME_ITEM.trigger((EntityPlayerMP) player, new ItemStack(TFItems.experiment_115, 8 - i)); + + return true; + } + } + + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (state.getValue(REGENERATE) && state.getValue(NOMS) != 0) { + worldIn.setBlockState(pos, state.withProperty(NOMS, state.getValue(NOMS) - 1)); + } + } + + @Override + public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) { + if (!this.canBlockStay(worldIn, pos)) { + worldIn.setBlockToAir(pos); + } + } + + private boolean canBlockStay(World world, BlockPos pos) { + return world.getBlockState(pos.down()).getMaterial().isSolid(); + } + + @Override + public boolean canPlaceBlockAt(World world, BlockPos pos) { + return super.canPlaceBlockAt(world, pos) && canBlockStay(world, pos); + } + + @Override + public int quantityDropped(Random random) + { + return 0; + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(NOMS, meta & 7).withProperty(REGENERATE, (meta & 8) == 8); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(NOMS) | (state.getValue(REGENERATE) ? 8 : 0); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, NOMS, REGENERATE); + } + + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + @Override + public int getComparatorInputOverride(IBlockState state, World world, BlockPos pos) { + return 15-(state.getValue(NOMS)*2); + } + + @Override + public boolean hasComparatorInputOverride(IBlockState state) + { + return true; + } + + @Override + public boolean canProvidePower(IBlockState state) { + return state.getValue(REGENERATE); + } + + @Override + public int getWeakPower(IBlockState state, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { + return state.getValue(REGENERATE) ? 15-(state.getValue(NOMS)*2) : 0; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerModel() { + ModelLoader.setCustomModelResourceLocation(TFItems.experiment_115, 0, new ModelResourceLocation(TwilightForestMod.ID + ":experiment_115", "inventory")); + ModelLoader.setCustomModelResourceLocation(TFItems.experiment_115, 1, new ModelResourceLocation(TwilightForestMod.ID + ":experiment_115", "inventory_full")); + ModelLoader.setCustomModelResourceLocation(TFItems.experiment_115, 2, new ModelResourceLocation(TwilightForestMod.ID + ":experiment_115", "inventory_think")); + + // Sorry, just gonna tack this here for now. The Shielding Scepter doesn't allow me to tack on another model like I would here. I'd like to not make a placeholder item either >.> + ModelLoader.setCustomModelResourceLocation(TFItems.experiment_115, 3, new ModelResourceLocation(TwilightForestMod.ID + ":shield", "inventory")); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFFence.java b/src/main/java/twilightforest/block/BlockTFFence.java new file mode 100644 index 0000000000..b838615388 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFFence.java @@ -0,0 +1,19 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockFence; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFFence extends BlockFence implements ModelRegisterCallback { + public BlockTFFence(Material materialIn, MapColor mapColorIn) { + super(materialIn, mapColorIn); + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFFenceGate.java b/src/main/java/twilightforest/block/BlockTFFenceGate.java new file mode 100644 index 0000000000..3599983b4c --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFFenceGate.java @@ -0,0 +1,18 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockFenceGate; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.SoundType; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFFenceGate extends BlockFenceGate implements ModelRegisterCallback { + public BlockTFFenceGate(BlockPlanks.EnumType plankEnum) { + super(plankEnum); + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFFireJet.java b/src/main/java/twilightforest/block/BlockTFFireJet.java index fca068bed4..c6c3655c78 100644 --- a/src/main/java/twilightforest/block/BlockTFFireJet.java +++ b/src/main/java/twilightforest/block/BlockTFFireJet.java @@ -1,407 +1,249 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Blocks; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemStack; +import net.minecraft.pathfinding.PathNodeType; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.IIcon; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fluids.BlockFluidBase; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.FireJetVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; import twilightforest.tileentity.TileEntityTFFlameJet; import twilightforest.tileentity.TileEntityTFPoppingJet; import twilightforest.tileentity.TileEntityTFSmoker; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFFireJet extends Block { +import javax.annotation.Nullable; +import java.util.EnumSet; +import java.util.Random; +import java.util.Set; + +public class BlockTFFireJet extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", FireJetVariant.class); + private static final Set ENCASED = EnumSet.of(FireJetVariant.ENCASED_JET_IDLE, FireJetVariant.ENCASED_JET_FLAME, FireJetVariant.ENCASED_SMOKER_OFF, FireJetVariant.ENCASED_SMOKER_ON, FireJetVariant.ENCASED_JET_POPPING); - public static final int META_SMOKER = 0; - public static final int META_ENCASED_SMOKER_OFF = 1; - public static final int META_ENCASED_SMOKER_ON = 2; - public static final int META_JET_IDLE = 8; - public static final int META_JET_POPPING = 9; - public static final int META_JET_FLAME = 10; - public static final int META_ENCASED_JET_IDLE = 11; - public static final int META_ENCASED_JET_POPPING = 12; - public static final int META_ENCASED_JET_FLAME = 13; - - private IIcon iconJet; - private IIcon iconSide; - private IIcon iconSmokerInactive; - private IIcon iconSmokerActive; - private IIcon iconJetInactive; - private IIcon iconJetActive; - protected BlockTFFireJet() { - super(Material.rock); + super(Material.ROCK); this.setHardness(1.5F); - //this.setResistance(10.0F); - this.setStepSound(Block.soundTypeWood); + this.setSoundType(SoundType.WOOD); this.setCreativeTab(TFItems.creativeTab); this.setTickRandomly(true); } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + final FireJetVariant[] values = FireJetVariant.values(); + final FireJetVariant variant = values[meta % values.length]; - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - switch (meta) - { - default : - return meta; - case META_ENCASED_SMOKER_ON : - return META_ENCASED_SMOKER_OFF; - case META_ENCASED_JET_POPPING : - case META_ENCASED_JET_FLAME : - return META_ENCASED_JET_IDLE; - case META_JET_POPPING : - case META_JET_FLAME : - return META_JET_IDLE; - } - + return getDefaultState().withProperty(VARIANT, variant); } + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - if (meta == META_ENCASED_SMOKER_OFF) - { - if (side >= 2) - { - return iconSmokerInactive; - } - else if (side == 1) - { - return TFBlocks.towerDevice.getIcon(side, BlockTFTowerDevice.META_GHASTTRAP_INACTIVE); - } - else - { - return TFBlocks.towerWood.getIcon(side, 1); - } - } - else if (meta == META_ENCASED_SMOKER_ON) - { - if (side >= 2) - { - return iconSmokerActive; - } - else if (side == 1) - { - return TFBlocks.towerDevice.getIcon(side, BlockTFTowerDevice.META_GHASTTRAP_ACTIVE); - } - else - { - return TFBlocks.towerWood.getIcon(side, 1); - } - } - if (meta == META_ENCASED_JET_IDLE) - { - if (side >= 2) - { - return iconJetInactive; - } - else if (side == 1) - { - return TFBlocks.towerDevice.getIcon(side, BlockTFTowerDevice.META_GHASTTRAP_INACTIVE); - } - else - { - return TFBlocks.towerWood.getIcon(side, 1); - } + @Override + public int damageDropped(IBlockState state) { + switch (state.getValue(VARIANT)) { + case ENCASED_SMOKER_ON: + state = state.withProperty(VARIANT, FireJetVariant.ENCASED_SMOKER_OFF); + break; + case ENCASED_JET_POPPING: + state = state.withProperty(VARIANT, FireJetVariant.ENCASED_JET_IDLE); + break; + case ENCASED_JET_FLAME: + state = state.withProperty(VARIANT, FireJetVariant.ENCASED_JET_IDLE); + break; + case JET_POPPING: + state = state.withProperty(VARIANT, FireJetVariant.JET_IDLE); + break; + case JET_FLAME: + state = state.withProperty(VARIANT, FireJetVariant.JET_IDLE); + break; + default: + break; } - else if (meta == META_ENCASED_JET_POPPING || meta == META_ENCASED_JET_FLAME) - { - if (side >= 2) - { - return iconJetActive; - } - else if (side == 1) - { - return TFBlocks.towerDevice.getIcon(side, BlockTFTowerDevice.META_GHASTTRAP_ACTIVE); - } - else - { - return TFBlocks.towerWood.getIcon(side, 1); - } - } - else - { - // normal fire jet - if (side == 1) - { - return iconJet; - } - else - { - return iconSide; - } - } - } - - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.iconSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":firejet_side"); - this.iconJet = par1IconRegister.registerIcon(TwilightForestMod.ID + ":firejet_top"); - this.iconSmokerInactive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_smoker_off"); - this.iconSmokerActive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_smoker_on"); - this.iconJetInactive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_firejet_off"); - this.iconJetActive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_firejet_on"); } - - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @Override - @SideOnly(Side.CLIENT) - public int colorMultiplier(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int meta = par1IBlockAccess.getBlockMetadata(x, y, z); - - if (meta == META_ENCASED_SMOKER_OFF || meta == META_ENCASED_SMOKER_ON - || meta == META_ENCASED_JET_IDLE || meta == META_ENCASED_JET_POPPING || meta == META_ENCASED_JET_FLAME) - { - return super.colorMultiplier(par1IBlockAccess, x, y, z); - } - else - { - int red = 0; - int grn = 0; - int blu = 0; - for (int var8 = -1; var8 <= 1; ++var8) - { - for (int var9 = -1; var9 <= 1; ++var9) - { - int biomeColor = par1IBlockAccess.getBiomeGenForCoords(x + var9, z + var8).getBiomeGrassColor(x + var9, y, z + var8); - red += (biomeColor & 16711680) >> 16; - grn += (biomeColor & 65280) >> 8; - blu += biomeColor & 255; - } - } - - return (red / 9 & 255) << 16 | (grn / 9 & 255) << 8 | blu / 9 & 255; - } - } + return getMetaFromState(state); + } + @Override + public Material getMaterial(IBlockState state) { + return ENCASED.contains(state.getValue(VARIANT)) ? Material.WOOD : Material.ROCK; + } - /** - * Get a light value for this block, normal ranges are between 0 and 15 - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return The light value - */ - @Override - public int getLightValue(IBlockAccess world, int x, int y, int z) - { - if (world.getBlock(x, y, z) == this) - { - int meta = world.getBlockMetadata(x, y, z); + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return ENCASED.contains(state.getValue(VARIANT)) ? MapColor.SAND : MapColor.GRASS; + } - switch (meta) { - case META_SMOKER: - default : - return 0; - case META_JET_FLAME : - case META_ENCASED_JET_FLAME : - return 15; - } - } - else - { - return 0; - } - } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World world, int x, int y, int z, Random random) - { - // idle jets may turn active - if (!world.isRemote && world.getBlockMetadata(x, y, z) == META_JET_IDLE) { - ChunkCoordinates lavaPos = findLavaAround(world, x, y - 1, z); - - if (isLava(world, lavaPos.posX, lavaPos.posY, lavaPos.posZ)) - { - // deplete lava reservoir - world.setBlock(lavaPos.posX, lavaPos.posY, lavaPos.posZ, Blocks.air, 0, 2); - // change jet state - world.setBlock(x, y, z, this, META_JET_POPPING, 0); - } - else - { - //System.out.println("Can't fire jet because reservoir is empty. Block meta is " + world.getBlockMetadata(lavaPos.posX, lavaPos.posY, lavaPos.posZ)); - } - } + @Override + public int getLightValue(IBlockState state) { + switch (state.getValue(VARIANT)) { + case JET_FLAME: + case ENCASED_JET_FLAME: + return 15; + case SMOKER: + default: + return 0; + } } - - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor blockID - */ - @Override - public void onNeighborBlockChange(World par1World, int x, int y, int z, Block myBlockID) - { - int meta = par1World.getBlockMetadata(x, y, z); - if (!par1World.isRemote) - { - if (meta == META_ENCASED_SMOKER_OFF && par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - par1World.setBlock(x, y, z, this, META_ENCASED_SMOKER_ON, 3); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); - } - - if (meta == META_ENCASED_SMOKER_ON && !par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - par1World.setBlock(x, y, z, this, META_ENCASED_SMOKER_OFF, 3); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); - } - - if (meta == META_ENCASED_JET_IDLE && par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - par1World.setBlock(x, y, z, this, META_ENCASED_JET_POPPING, 3); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); - } + @Nullable + @Override + public PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos) { + switch (state.getValue(VARIANT)) { + case JET_POPPING: + case ENCASED_JET_POPPING: + return PathNodeType.DANGER_FIRE; + case JET_FLAME: + case ENCASED_JET_FLAME: + return PathNodeType.DAMAGE_FIRE; + default: + return null; + } + } - } - } + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random random) { + if (!world.isRemote && state.getValue(VARIANT) == FireJetVariant.JET_IDLE) { + BlockPos lavaPos = findLavaAround(world, pos.down()); - /** - * Find a full block of lava near the designated block. This is intentionally not really that reliable. - * - * - */ - private ChunkCoordinates findLavaAround(World world, int x, int y, int z) { - if (isLava(world, x, y, z)) { - return new ChunkCoordinates(x, y, z); + if (isLava(world, lavaPos)) { + world.setBlockState(lavaPos, Blocks.AIR.getDefaultState()); + world.setBlockState(pos, state.withProperty(VARIANT, FireJetVariant.JET_POPPING), 2); + } } - // try three random spots nearby - int rx = x + world.rand.nextInt(3) - 1; - int rz = z + world.rand.nextInt(3) - 1; - if (isLava(world, rx, y, rz)) { - return new ChunkCoordinates(rx, y, rz); + } + + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block myBlockID, BlockPos fromPos) { + + if (world.isRemote) return; + + FireJetVariant variant = state.getValue(VARIANT); + boolean powered = world.isBlockPowered(pos); + + if (variant == FireJetVariant.ENCASED_SMOKER_OFF && powered) { + world.setBlockState(pos, state.withProperty(VARIANT, FireJetVariant.ENCASED_SMOKER_ON), 3); + world.playSound(null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, 0.6F); } - - rx = x + world.rand.nextInt(3) - 1; - rz = z + world.rand.nextInt(3) - 1; - if (isLava(world, rx, y, rz)) { - return new ChunkCoordinates(rx, y, rz); + + if (variant == FireJetVariant.ENCASED_SMOKER_ON && !powered) { + world.setBlockState(pos, state.withProperty(VARIANT, FireJetVariant.ENCASED_SMOKER_OFF), 3); + world.playSound(null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, 0.6F); } - - rx = x + world.rand.nextInt(3) - 1; - rz = z + world.rand.nextInt(3) - 1; - if (isLava(world, rx, y, rz)) { - return new ChunkCoordinates(rx, y, rz); + + if (variant == FireJetVariant.ENCASED_JET_IDLE && powered) { + world.setBlockState(pos, state.withProperty(VARIANT, FireJetVariant.ENCASED_JET_POPPING), 3); + world.playSound(null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, 0.6F); } - - - // finally, give up - return new ChunkCoordinates(x, y, z); } - - private boolean isLava(World world, int x, int y, int z) - { - return world.getBlock(x, y, z).getMaterial() == Material.lava && world.getBlockMetadata(x, y, z) == 0; - } + /** + * Find a full block of lava near the designated block. This is intentionally not really that reliable. + */ + private BlockPos findLavaAround(World world, BlockPos pos) { + if (isLava(world, pos)) { + return pos; + } + for (int i = 0; i < 3; i++) { + BlockPos randPos = pos.add(world.rand.nextInt(3) - 1, 0, world.rand.nextInt(3) - 1); + if (isLava(world, randPos)) { + return randPos; + } + } - /** - * Called throughout the code as a replacement for block instanceof BlockContainer - * Moving this to the Block base class allows for mods that wish to extend vinella - * blocks, and also want to have a tile entity on that block, may. - * - * Return true from this function to specify this block has a tile entity. - * - * @param metadata Metadata of the current block - * @return True if block has a tile entity, false otherwise - */ - @Override - public boolean hasTileEntity(int metadata) { - if (metadata == META_SMOKER || metadata == META_JET_POPPING || metadata == META_JET_FLAME - || metadata == META_ENCASED_SMOKER_ON || metadata == META_ENCASED_JET_POPPING || metadata == META_ENCASED_JET_FLAME) - { - return true; - } - else - { - return false; - } - } - - /** - * Called throughout the code as a replacement for BlockContainer.getBlockEntity - * Return the same thing you would from that function. - * This will fall back to BlockContainer.getBlockEntity if this block is a BlockContainer. - * - * @param metadata The Metadata of the current block - * @return A instance of a class extending TileEntity - */ - @Override - public TileEntity createTileEntity(World world, int metadata) { - if (metadata == META_SMOKER || metadata == META_ENCASED_SMOKER_ON) - { - return new TileEntityTFSmoker(); - } - else if (metadata == META_JET_POPPING) - { - return new TileEntityTFPoppingJet(META_JET_FLAME); - } - else if (metadata == META_JET_FLAME) - { - return new TileEntityTFFlameJet(META_JET_IDLE); - } - else if (metadata == META_ENCASED_JET_POPPING) - { - return new TileEntityTFPoppingJet(META_ENCASED_JET_FLAME); - } - else if (metadata == META_ENCASED_JET_FLAME) - { - return new TileEntityTFFlameJet(META_ENCASED_JET_IDLE); - } - else - { - return null; - } - } + return pos; + } + + private boolean isLava(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + Block b = state.getBlock(); + IProperty levelProp = b instanceof BlockLiquid || b instanceof BlockFluidBase + ? BlockLiquid.LEVEL + : null; + return state.getMaterial() == Material.LAVA + && (levelProp == null || state.getValue(levelProp) == 0); + } + @Override + public boolean hasTileEntity(IBlockState state) { + switch (state.getValue(VARIANT)) { + case SMOKER: + case JET_POPPING: + case JET_FLAME: + case ENCASED_SMOKER_ON: + case ENCASED_JET_POPPING: + case ENCASED_JET_FLAME: + return true; + default: + return false; + } + } - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, META_SMOKER)); - par3List.add(new ItemStack(par1, 1, META_JET_IDLE)); - par3List.add(new ItemStack(par1, 1, META_ENCASED_SMOKER_OFF)); - par3List.add(new ItemStack(par1, 1, META_ENCASED_JET_IDLE)); - } + @Nullable + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + switch (state.getValue(VARIANT)) { + case SMOKER: + case ENCASED_SMOKER_ON: + return new TileEntityTFSmoker(); + case JET_POPPING: + return new TileEntityTFPoppingJet(FireJetVariant.JET_FLAME); + case JET_FLAME: + return new TileEntityTFFlameJet(FireJetVariant.JET_IDLE); + case ENCASED_JET_POPPING: + return new TileEntityTFPoppingJet(FireJetVariant.ENCASED_JET_FLAME); + case ENCASED_JET_FLAME: + return new TileEntityTFFlameJet(FireJetVariant.ENCASED_JET_IDLE); + default: + return null; + } + } + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, FireJetVariant.SMOKER.ordinal())); + list.add(new ItemStack(this, 1, FireJetVariant.JET_IDLE.ordinal())); + list.add(new ItemStack(this, 1, FireJetVariant.ENCASED_SMOKER_OFF.ordinal())); + list.add(new ItemStack(this, 1, FireJetVariant.ENCASED_JET_IDLE.ordinal())); + } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + FireJetVariant[] variants = {FireJetVariant.SMOKER, FireJetVariant.JET_IDLE, FireJetVariant.ENCASED_SMOKER_OFF, FireJetVariant.ENCASED_JET_IDLE}; + for (FireJetVariant variant : variants) { + ModelUtils.registerToState(this, variant.ordinal(), getDefaultState().withProperty(VARIANT, variant)); + } + } } diff --git a/src/main/java/twilightforest/block/BlockTFFirefly.java b/src/main/java/twilightforest/block/BlockTFFirefly.java index 43c0d03e3e..50741fb06d 100644 --- a/src/main/java/twilightforest/block/BlockTFFirefly.java +++ b/src/main/java/twilightforest/block/BlockTFFirefly.java @@ -1,80 +1,45 @@ package twilightforest.block; -import java.util.Random; - +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.block.statemap.StateMap; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.EnumSkyBlock; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.tileentity.TileEntityTFFirefly; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.tileentity.critters.TileEntityTFFireflyTicking; -public class BlockTFFirefly extends BlockTFCritter { +public class BlockTFFirefly extends BlockTFCritter implements ModelRegisterCallback { - - public static int sprFirefly = 4; - - public static Random rand = new Random(); - protected BlockTFFirefly() { - super(); - this.setLightLevel(0.9375F); + this.setLightLevel(1.0F); } - - /** - * How often do we check for incorrect lighting on fireflies, etc. - */ - public int tickRate() - { - return 50 + rand.nextInt(50); - } - - /** - * Get a light value for this block, normal ranges are between 0 and 15 - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return The light value - */ + @Override - public int getLightValue(IBlockAccess world, int x, int y, int z) { - return 15; + public TileEntity createTileEntity(World world, IBlockState state) { + return TwilightForestMod.proxy.getNewFireflyTE(); } - @Override - public TileEntity createTileEntity(World world, int metadata) { - return new TileEntityTFFirefly(); + public ItemStack getSquishResult() { + return new ItemStack(Items.GLOWSTONE_DUST); } - - - /** - * Called whenever the block is added into the world. Args: world, x, y, z - */ - @Override - public void onBlockAdded(World world, int x, int y, int z) - { - super.onBlockAdded(world, x, y, z); -// if (!world.isRemote) -// { -// world.scheduleBlockUpdate(x, y, z, blockID, tickRate()); -// } - } - /** - * Ticks the block if it's been scheduled - * Check the lighting and make the world relight it if it's incorrect. - */ - @Override - public void updateTick(World world, int x, int y, int z, Random random) - { - if (!world.isRemote && world.getBlockLightValue(x, y, z) < 12) { - //world.updateLightByType(EnumSkyBlock.Block, x, y, z); - world.markBlockForUpdate(x, y, z); // do we need this now? - //System.out.println("Updating firefly light value"); - // do another update to check that we got it right - world.scheduleBlockUpdate(x, y, z, this, tickRate()); - } + //Atomic: Forge would like to get rid of registerTESRItemStack, but there's no alternative yet (as at 1.11) + @SuppressWarnings("deprecation") + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomStateMapper(this, new StateMap.Builder().ignore(BlockDirectional.FACING).build()); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + ForgeHooksClient.registerTESRItemStack(Item.getItemFromBlock(this), 0, TileEntityTFFireflyTicking.class); } } diff --git a/src/main/java/twilightforest/block/BlockTFFireflyJar.java b/src/main/java/twilightforest/block/BlockTFFireflyJar.java index 2398db6baa..4f37bb5a77 100644 --- a/src/main/java/twilightforest/block/BlockTFFireflyJar.java +++ b/src/main/java/twilightforest/block/BlockTFFireflyJar.java @@ -1,170 +1,89 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.fml.common.Optional; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import thaumcraft.api.crafting.IInfusionStabiliser; import twilightforest.TwilightForestMod; -import twilightforest.entity.passive.EntityTFTinyFirefly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.particle.TFParticleType; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFFireflyJar extends Block { - - public static IIcon jarTop; - public static IIcon jarSide; - public static IIcon jarCork; - +import java.util.Random; + +@Optional.Interface(modid = "thaumcraft", iface = "thaumcraft.api.crafting.IInfusionStabiliser") +public class BlockTFFireflyJar extends Block implements ModelRegisterCallback, IInfusionStabiliser { + + private static final AxisAlignedBB AABB = new AxisAlignedBB(0.1875F, 0.0F, 0.1875F, 0.8125F, 1.0F, 0.8125F); + protected BlockTFFireflyJar() { - super(Material.glass); - this.setBlockBounds(0.1875F, 0.0F, 0.1875F, 0.8125F, 1.0F, 0.8125F); + super(Material.GLASS); this.setHardness(0.3F); - this.setStepSound(Block.soundTypeWood); + this.setSoundType(SoundType.WOOD); this.setCreativeTab(TFItems.creativeTab); this.setLightLevel(1.0F); } + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - @Override - public boolean renderAsNormalBlock() - { - return false; - } - - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return false; - } - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getComplexBlockRenderID(); - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - return (side == 1 || side == 0) ? jarTop : jarSide; - } - - /** - * Get a light value for this block, normal ranges are between 0 and 15 - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return The light value - */ - @Override - public int getLightValue(IBlockAccess world, int x, int y, int z) - { - return 15; - } - - /** - * Return true if the block is a normal, solid cube. This - * determines indirect power state, entity ejection from blocks, and a few - * others. - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return True if the block is a full cube - */ - public boolean isBlockNormalCube(World world, int x, int y, int z) - { - return false; - } - - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - @Override - public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { - this.setBlockBounds(0.1875F, 0.0F, 0.1875F, 0.8125F, 1.0F, 0.8125F); - } - + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } - /** - * Sets the block's bounds for rendering it as an item - */ - @Override - public void setBlockBoundsForItemRender() - { - this.setBlockBounds(0.1875F, 0.0F, 0.1875F, 0.8125F, 1.0F, 0.8125F); - } + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } - - /** - * A randomly called display update to be able to add particles or other items for display - */ - @Override + @Override @SideOnly(Side.CLIENT) - public void randomDisplayTick(World world, int x, int y, int z, Random rand) - { - - - double dx = x + ((rand.nextFloat() - rand.nextFloat()) * 0.3F + 0.5F); - double dy = y - 0.1F + ((rand.nextFloat() - rand.nextFloat()) * 0.4F); - double dz = z + ((rand.nextFloat() - rand.nextFloat()) * 0.3F + 0.5F); - - EntityTFTinyFirefly tinyfly = new EntityTFTinyFirefly(world, dx, dy, dz); - world.addWeatherEffect(tinyfly); - - dx = x + ((rand.nextFloat() - rand.nextFloat()) * 0.3F + 0.5F); - dy = y - 0.1F + ((rand.nextFloat() - rand.nextFloat()) * 0.4F); - dz = z + ((rand.nextFloat() - rand.nextFloat()) * 0.3F + 0.5F); - - tinyfly = new EntityTFTinyFirefly(world, dx, dy, dz); - world.addWeatherEffect(tinyfly); - } - + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - } + @Override + public boolean isNormalCube(IBlockState state) { + return false; + } + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return AABB; + } - @Override + @Override @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFFireflyJar.jarTop = par1IconRegister.registerIcon(TwilightForestMod.ID + ":fireflyjar_top"); - BlockTFFireflyJar.jarSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":fireflyjar_side"); - BlockTFFireflyJar.jarCork = par1IconRegister.registerIcon(TwilightForestMod.ID + ":fireflyjar_cork"); - } - + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random rand) { + for (int i = 0; i < 2; i++) { + double dx = pos.getX() + ((rand.nextFloat() - rand.nextFloat()) * 0.2F + 0.5F); + double dy = pos.getY() + 0.4F + ((rand.nextFloat() - rand.nextFloat()) * 0.3F); + double dz = pos.getZ() + ((rand.nextFloat() - rand.nextFloat()) * 0.2F + 0.5F); + + TwilightForestMod.proxy.spawnParticle(TFParticleType.FIREFLY, dx, dy, dz, 0, 0, 0); + } + } + @Override + public boolean canStabaliseInfusion(World world, BlockPos blockPos) { + return true; + } } diff --git a/src/main/java/twilightforest/block/BlockTFFluffyCloud.java b/src/main/java/twilightforest/block/BlockTFFluffyCloud.java index 159ed71576..11b1973cb6 100644 --- a/src/main/java/twilightforest/block/BlockTFFluffyCloud.java +++ b/src/main/java/twilightforest/block/BlockTFFluffyCloud.java @@ -1,20 +1,18 @@ package twilightforest.block; import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -public class BlockTFFluffyCloud extends Block { +public class BlockTFFluffyCloud extends Block implements ModelRegisterCallback { protected BlockTFFluffyCloud() { - super(Material.packedIce); - this.setStepSound(soundTypeCloth); + super(Material.PACKED_ICE); + this.setSoundType(SoundType.CLOTH); this.setCreativeTab(TFItems.creativeTab); this.setHardness(0.8F); - - this.setBlockTextureName(TwilightForestMod.ID + ":fluffy_cloud"); } - } diff --git a/src/main/java/twilightforest/block/BlockTFFluid.java b/src/main/java/twilightforest/block/BlockTFFluid.java new file mode 100644 index 0000000000..9a8cf366f4 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFFluid.java @@ -0,0 +1,23 @@ +package twilightforest.block; + +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fluids.BlockFluidClassic; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFFluid extends BlockFluidClassic implements ModelRegisterCallback { + + public BlockTFFluid(Fluid fluid, Material material) { + super(fluid, material); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomStateMapper(this, new SingleStateMapper(new ModelResourceLocation(getRegistryName(), "fluid"))); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFForceField.java b/src/main/java/twilightforest/block/BlockTFForceField.java index 0fca8b70f3..f9e8b49ee9 100644 --- a/src/main/java/twilightforest/block/BlockTFForceField.java +++ b/src/main/java/twilightforest/block/BlockTFForceField.java @@ -1,140 +1,141 @@ package twilightforest.block; -import static net.minecraftforge.common.util.ForgeDirection.EAST; -import static net.minecraftforge.common.util.ForgeDirection.NORTH; -import static net.minecraftforge.common.util.ForgeDirection.SOUTH; -import static net.minecraftforge.common.util.ForgeDirection.WEST; - -import java.util.List; - -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.block.Block; -import net.minecraft.block.BlockPane; -import net.minecraft.block.BlockSlab; -import net.minecraft.block.BlockStainedGlassPane; +import com.google.common.collect.ImmutableList; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; -import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +import java.util.List; +import java.util.Random; -public class BlockTFForceField extends BlockPane { - - public static String[] names = new String[] {"purple", "pink", "orange", "green", "blue"}; - - public static IIcon[] sides; - public static IIcon top; +public class BlockTFForceField extends BlockTFConnectableRotatedPillar implements ModelRegisterCallback { - protected BlockTFForceField() { - super("glass", "glass_pane_top", Material.grass, false); + public static final List VALID_COLORS = ImmutableList.of(EnumDyeColor.PURPLE, EnumDyeColor.PINK, EnumDyeColor.ORANGE, EnumDyeColor.GREEN, EnumDyeColor.BLUE); + public static final IProperty COLOR = PropertyEnum.create("color", EnumDyeColor.class, VALID_COLORS); + + BlockTFForceField() { + super(Material.BARRIER, 2); + this.setBlockUnbreakable(); + this.setResistance(Float.MAX_VALUE); this.setLightLevel(2F / 15F); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(this.getDefaultState().withProperty(COLOR, EnumDyeColor.PURPLE)); + } + + @Override + public int getMetaFromState(IBlockState state) { + return VALID_COLORS.indexOf(state.getValue(COLOR)) + (((state.getValue(AXIS).ordinal() + 1) % 3) * 5); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(COLOR, VALID_COLORS.get(meta % 5)).withProperty(AXIS, EnumFacing.Axis.values()[((meta / 5) + 1) % 3]); + } + + @Override + protected IProperty[] getAdditionalProperties() { + return new IProperty[]{ COLOR }; + } + + @Override + protected AxisAlignedBB getSidedAABBStraight(EnumFacing facing, EnumFacing.Axis axis) { + return makeQuickAABB( + facing == EnumFacing.EAST || axis == EnumFacing.Axis.X ? 16 : this.boundingBoxWidthLower, + facing == EnumFacing.UP || axis == EnumFacing.Axis.Y ? 16 : this.boundingBoxWidthLower, + facing == EnumFacing.SOUTH || axis == EnumFacing.Axis.Z ? 16 : this.boundingBoxWidthLower, + facing == EnumFacing.WEST || axis == EnumFacing.Axis.X ? 0 : this.boundingBoxWidthUpper, + facing == EnumFacing.DOWN || axis == EnumFacing.Axis.Y ? 0 : this.boundingBoxWidthUpper, + facing == EnumFacing.NORTH || axis == EnumFacing.Axis.Z ? 0 : this.boundingBoxWidthUpper); + } + + @Override + protected boolean canConnectTo(IBlockState state, IBlockState otherState, IBlockAccess world, BlockPos pos, EnumFacing connectTo) { + BlockFaceShape blockFaceShape = otherState.getBlockFaceShape(world, pos, connectTo); + + return blockFaceShape == BlockFaceShape.SOLID + || blockFaceShape == BlockFaceShape.MIDDLE_POLE_THIN + || super.canConnectTo(state, otherState, world, pos, connectTo); + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return Items.AIR; + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + for (int i = 0; i < COLOR.getAllowedValues().size(); i++) { + list.add(new ItemStack(this, 1, i)); + } + } + + @Override + public boolean isOpaqueCube(IBlockState state) + { + return false; + } + + @Override + public boolean isFullCube(IBlockState state) + { + return false; + } + + @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face) { + return face.getAxis() != state.getValue(AXIS) ? BlockFaceShape.MIDDLE_POLE_THIN : BlockFaceShape.CENTER_SMALL; } - /** - * Gets the block's texture. Args: side, meta - */ - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) - { - return this.sides[meta % names.length]; - } - - @SideOnly(Side.CLIENT) - public IIcon func_150097_e() - { - return this.top; - } - - - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister register) - { - super.registerBlockIcons(register); - - this.sides = new IIcon[names.length]; - - for (int i = 0; i < names.length; i++) { - this.sides[i] = register.registerIcon(TwilightForestMod.ID + ":forcefield_" + names[i]); - } - - this.top = register.registerIcon(TwilightForestMod.ID + ":forcefield_top"); - - } - - /** - * How bright to render this block based on the light its receiving. Args: iBlockAccess, x, y, z - */ - @SideOnly(Side.CLIENT) - public int getMixedBrightnessForBlock(IBlockAccess world, int x, int y, int z) - { - return 15 << 20 | 15 << 4; - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - public int damageDropped(int meta) - { - return meta % names.length; - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - for (int i = 0; i < names.length; i++) { - par3List.add(new ItemStack(par1, 1, i)); - } - } - - /** - * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha - */ - @SideOnly(Side.CLIENT) - public int getRenderBlockPass() - { - return 1; - } - - /** - * Adds all intersecting collision boxes to a list. (Be sure to only add boxes to the list if they intersect the - * mask.) Parameters: World, X, Y, Z, mask, list, colliding entity - */ - public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB aabb, List list, Entity entity) - { - super.addCollisionBoxesToList(world, x, y, z, aabb, list, entity); - - // just fill in the whole bounding box when we connect on all sides - boolean north = this.canPaneConnectTo(world, x, y, z - 1, NORTH); - boolean south = this.canPaneConnectTo(world, x, y, z + 1, SOUTH); - boolean east = this.canPaneConnectTo(world, x - 1, y, z, WEST ); - boolean west = this.canPaneConnectTo(world, x + 1, y, z, EAST ); - - if (north && south && east && west) { - this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - } - - // manually add to the list, since super.method is overwritten - AxisAlignedBB myAABB = this.getCollisionBoundingBoxFromPool(world, x, y, z); - - if (myAABB != null && aabb.intersectsWith(myAABB)) - { - list.add(myAABB); - } - - } + public int damageDropped(IBlockState state) { + return VALID_COLORS.indexOf(state.getValue(COLOR)); + } + + @Override + public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) { + return false; // TODO: ??? + } + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.TRANSLUCENT; + } + @Override + @SideOnly(Side.CLIENT) + public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { + return blockAccess.getBlockState(pos.offset(side)).getBlock() != this && super.shouldSideBeRendered(blockState, blockAccess, pos, side); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelResourceLocation mrl = new ModelResourceLocation(getRegistryName(), "inventory"); + for (int i = 0; i < VALID_COLORS.size(); i++) { + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), i, mrl); + } + + //ModelLoader.setCustomStateMapper(this, new StateMap.Builder().ignore(blockState.getProperties().toArray(new IProperty[blockState.getProperties().size()])).build()); + } } diff --git a/src/main/java/twilightforest/block/BlockTFGiantBlock.java b/src/main/java/twilightforest/block/BlockTFGiantBlock.java index ca96e5afc4..343a7cbfb6 100644 --- a/src/main/java/twilightforest/block/BlockTFGiantBlock.java +++ b/src/main/java/twilightforest/block/BlockTFGiantBlock.java @@ -1,268 +1,102 @@ package twilightforest.block; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; -import net.minecraft.client.particle.EffectRenderer; -import net.minecraft.client.particle.EntityDiggingFX; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.material.EnumPushReaction; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; -import net.minecraft.world.Explosion; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public abstract class BlockTFGiantBlock extends Block { +public abstract class BlockTFGiantBlock extends Block implements ModelRegisterCallback { - private IIcon[][][] giantIcon; - private Block baseBlock; private boolean isSelfDestructing; - public BlockTFGiantBlock(Block baseBlock) { - super(baseBlock.getMaterial()); - this.setStepSound(baseBlock.stepSound); - - this.baseBlock = baseBlock; + //Atomic: Suppressing deprecation because this seems like a reasonable use for it. + @SuppressWarnings("deprecation") + public BlockTFGiantBlock(IBlockState state) { + super(state.getMaterial()); + this.setSoundType(state.getBlock().getSoundType()); } - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) { - this.giantIcon = new GiantBlockIcon[4][4][6]; - - for (int x = 0; x < 4; x++) { - for (int y = 0; y < 4; y++) { - for (int side = 0; side < 6; side++) { - this.giantIcon[x][y][side] = new GiantBlockIcon(this.baseBlock.getBlockTextureFromSide(side), x, y); - } + public boolean canPlaceBlockAt(World world, BlockPos pos) { + for (BlockPos dPos : getVolume(pos)) { + IBlockState state = world.getBlockState(dPos); + if (!state.getBlock().isReplaceable(world, dPos)) { + return false; } } + return super.canPlaceBlockAt(world, pos); } - - - - @SideOnly(Side.CLIENT) - public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { - // return an icon from the icon matrix! - switch (side) { - case 0: - default: - return this.giantIcon[x & 3][z & 3][side]; - case 1: - return this.giantIcon[x & 3][z & 3][side]; - case 2: - return this.giantIcon[3 - (x & 3)][3 - (y & 3)][side]; - case 3: - return this.giantIcon[x & 3][3 - (y & 3)][side]; - case 4: - return this.giantIcon[z & 3][3 - (y & 3)][side]; - case 5: - return this.giantIcon[3 - (z & 3)][3 - (y & 3)][side]; - } - - } - - /** - * Gets the block's texture. Args: side, meta - */ - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) - { - return this.giantIcon[0][0][side]; - } - - /** - * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z - */ - public boolean canPlaceBlockAt(World world, int x, int y, int z) { - - int bx = (x >> 2) << 2; - int by = (y >> 2) << 2; - int bz = (z >> 2) << 2; - - boolean allReplaceable = true; - - for (int dx = 0; dx < 4; dx++) { - for (int dy = 0; dy < 4; dy++) { - for (int dz = 0; dz < 4; dz++) { - allReplaceable &= world.getBlock(bx + dx, by + dy, bz + dz).isReplaceable(world, bx + dx, by + dy, bz + dz); - } - } - } - return super.canPlaceBlockAt(world, x, y, z) && allReplaceable; - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { - int bx = (x >> 2) << 2; - int by = (y >> 2) << 2; - int bz = (z >> 2) << 2; - - return AxisAlignedBB.getBoundingBox((double)bx + this.minX, (double)by + this.minY, (double)bz + this.minZ, (double)bx + this.maxX * 4F, (double)by + this.maxY * 4F, (double)bz + this.maxZ * 4F); - } - - /** - * Called when the block is placed in the world. - */ - public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) { - if (!world.isRemote) { - int bx = (x >> 2) << 2; - int by = (y >> 2) << 2; - int bz = (z >> 2) << 2; - - for (int dx = 0; dx < 4; dx++) { - for (int dy = 0; dy < 4; dy++) { - for (int dz = 0; dz < 4; dz++) { - world.setBlock(bx + dx, by + dy, bz + dz, this, 0, 2); - } - } - } - } - } + @Override + public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase player, ItemStack itemStack) { + if (!world.isRemote) { + for (BlockPos dPos : getVolume(pos)) { + world.setBlockState(dPos, getDefaultState(), 2); + } + } + } - /** - * Spawn particles for when the block is destroyed. Due to the nature - * of how this is invoked, the x/y/z locations are not always guaranteed - * to host your block. So be sure to do proper sanity checks before assuming - * that the location is this block. - * - * @param world The current world - * @param x X position to spawn the particle - * @param y Y position to spawn the particle - * @param z Z position to spawn the particle - * @param meta The metadata for the block before it was destroyed. - * @param effectRenderer A reference to the current effect renderer. - * @return True to prevent vanilla break particles from spawning. - */ @Override - @SideOnly(Side.CLIENT) - public boolean addDestroyEffects(World world, int x, int y, int z, int meta, EffectRenderer effectRenderer) { - - int bx = (x >> 2) << 2; - int by = (y >> 2) << 2; - int bz = (z >> 2) << 2; - - Block blockThere = world.getBlock(x, y, z); - int metaThere = world.getBlockMetadata(x, y, z); - - byte b0 = 16; + public void breakBlock(World world, BlockPos pos, IBlockState state) { + super.breakBlock(world, pos, state); + if (!this.isSelfDestructing && !canBlockStay(world, pos)) { + this.setGiantBlockToAir(world, pos); + } + } - for (int i1 = 0; i1 < b0; ++i1) - { - for (int j1 = 0; j1 < b0; ++j1) - { - for (int k1 = 0; k1 < b0; ++k1) - { - double d0 = (double)bx + ((double)i1 + 0.5D) / 4F; - double d1 = (double)by + ((double)j1 + 0.5D) / 4F; - double d2 = (double)bz + ((double)k1 + 0.5D) / 4F; - effectRenderer.addEffect((new EntityDiggingFX(world, d0, d1, d2, d0 - (double)x - 0.5D, d1 - (double)y - 0.5D, d2 - (double)z - 0.5D, blockThere, metaThere)).applyColourMultiplier(x, y, z)); - } - } - } + private void setGiantBlockToAir(World world, BlockPos pos) { + // this flag is maybe not totally perfect + this.isSelfDestructing = true; + for (BlockPos iterPos : getVolume(pos)) { + if (!pos.equals(iterPos)) { + if (world.getBlockState(iterPos).getBlock() == this) { + world.destroyBlock(iterPos, false); + } + } + } - return true; + this.isSelfDestructing = false; } + private boolean canBlockStay(World world, BlockPos pos) { + for (BlockPos dPos : getVolume(pos)) { + if (world.getBlockState(dPos).getBlock() != this) { + return false; + } + } + return true; + } - /** - * Called when the block is attempted to be harvested - */ - public void onBlockHarvested(World world, int x, int y, int z, int meta, EntityPlayer player) { - this.setGiantBlockToAir(world, x, y, z); - } - - /** - * Called when the block is destroyed by an explosion. - * Useful for allowing the block to take into account tile entities, - * metadata, etc. when exploded, before it is removed. - * - * @param world The current world - * @param x X Position - * @param y Y Position - * @param z Z Position - * @param Explosion The explosion instance affecting the block - */ - public void onBlockExploded(World world, int x, int y, int z, Explosion explosion) - { - world.setBlockToAir(x, y, z); - this.setGiantBlockToAir(world, x, y, z); - } - - - /** - * Called on server worlds only when the block is about to be replaced by a different block or the same block with a - * different metadata value. Args: world, x, y, z, old metadata - */ - public void onBlockPreDestroy(World world, int x, int y, int z, int meta) { - if (!this.isSelfDestructing && !canBlockStay(world, x, y, z)) { - this.setGiantBlockToAir(world, x, y, z); - } - } - - /** - * Set the whole giant block area to air - */ - private void setGiantBlockToAir(World world, int x, int y, int z) { - // this flag is maybe not totally perfect - this.isSelfDestructing = true; - - int bx = (x >> 2) << 2; - int by = (y >> 2) << 2; - int bz = (z >> 2) << 2; - - for (int dx = 0; dx < 4; dx++) { - for (int dy = 0; dy < 4; dy++) { - for (int dz = 0; dz < 4; dz++) { - if (!(x == bx + dx && y == by + dy && z == bz + dz)) { - if (world.getBlock(bx + dx, by + dy, bz + dz) == this) { - world.setBlockToAir(bx + dx, by + dy, bz + dz); - } - } - } - } - } - - this.isSelfDestructing = false; + @Override + @Deprecated + public EnumPushReaction getPushReaction(IBlockState state) { + return EnumPushReaction.BLOCK; } + public static BlockPos roundCoords(BlockPos pos) { + return new BlockPos(pos.getX() & ~0b11, pos.getY() & ~0b11, pos.getZ() & ~0b11); + } - /** - * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. - */ - public boolean canBlockStay(World world, int x, int y, int z) { - boolean allThisBlock = true; - - int bx = (x >> 2) << 2; - int by = (y >> 2) << 2; - int bz = (z >> 2) << 2; + public static Iterable getVolume(BlockPos pos) { + return BlockPos.getAllInBox( + pos.getX() & ~0b11, pos.getY() & ~0b11, pos.getZ() & ~0b11, + pos.getX() | 0b11, pos.getY() | 0b11, pos.getZ() | 0b11 + ); + } - for (int dx = 0; dx < 4; dx++) { - for (int dy = 0; dy < 4; dy++) { - for (int dz = 0; dz < 4; dz++) { - allThisBlock &= world.getBlock(bx + dx, by + dy, bz + dz) == this; - } - } - } - - return allThisBlock; - } - - /** - * Returns the mobility information of the block, 0 = free, 1 = can't push but can move over, 2 = total immobility - * and stop pistons - */ - public int getMobilityFlag() - { - return 2; - } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + } } diff --git a/src/main/java/twilightforest/block/BlockTFGiantCobble.java b/src/main/java/twilightforest/block/BlockTFGiantCobble.java index 7a7e597d75..c0bdedcbdc 100644 --- a/src/main/java/twilightforest/block/BlockTFGiantCobble.java +++ b/src/main/java/twilightforest/block/BlockTFGiantCobble.java @@ -1,17 +1,14 @@ package twilightforest.block; -import twilightforest.item.TFItems; import net.minecraft.init.Blocks; +import twilightforest.item.TFItems; -public class BlockTFGiantCobble extends BlockTFGiantBlock { - +public class BlockTFGiantCobble extends BlockTFGiantBlock { protected BlockTFGiantCobble() { - super(Blocks.cobblestone); + super(Blocks.COBBLESTONE.getDefaultState()); this.setHardness(2.0F * 64F); this.setResistance(10.0F); - this.setCreativeTab(TFItems.creativeTab); } - } diff --git a/src/main/java/twilightforest/block/BlockTFGiantLeaves.java b/src/main/java/twilightforest/block/BlockTFGiantLeaves.java index b4d056f3d9..8aba165430 100644 --- a/src/main/java/twilightforest/block/BlockTFGiantLeaves.java +++ b/src/main/java/twilightforest/block/BlockTFGiantLeaves.java @@ -1,97 +1,54 @@ package twilightforest.block; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import twilightforest.item.TFItems; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; -import net.minecraft.world.ColorizerFoliage; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; +import twilightforest.item.TFItems; public class BlockTFGiantLeaves extends BlockTFGiantBlock { public BlockTFGiantLeaves() { - super(Blocks.leaves); - - this.setHardness(0.2F * 64F); - this.setLightOpacity(1); - + super(Blocks.LEAVES.getDefaultState()); + this.setHardness(0.2F * 64F); + this.setLightOpacity(1); this.setCreativeTab(TFItems.creativeTab); } - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - public boolean isOpaqueCube() - { - return false; - } - - - @SideOnly(Side.CLIENT) - public int getBlockColor() - { - double d0 = 0.5D; - double d1 = 1.0D; - return ColorizerFoliage.getFoliageColor(d0, d1); - } - - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @SideOnly(Side.CLIENT) - public int getRenderColor(int p_149741_1_) - { - return ColorizerFoliage.getFoliageColorBasic(); - } - - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @SideOnly(Side.CLIENT) - public int colorMultiplier(IBlockAccess world, int x, int y, int z) - { - int red = 0; - int grn = 0; - int blu = 0; - - for (int dz = -1; dz <= 1; ++dz) - { - for (int dx = -1; dx <= 1; ++dx) - { - int nearbyColor = world.getBiomeGenForCoords(x + dx, z + dz).getBiomeFoliageColor(x + dx, y, z + dz); - red += (nearbyColor & 16711680) >> 16; - grn += (nearbyColor & 65280) >> 8; - blu += nearbyColor & 255; - } - } - - return (red / 9 & 255) << 16 | (grn / 9 & 255) << 8 | blu / 9 & 255; - } + @Override + public int getLightOpacity(IBlockState state) { + return TFConfig.performance.leavesLightOpacity; + } + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } - /** - * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given - * coordinates. Args: blockAccess, x, y, z, side - */ - @SideOnly(Side.CLIENT) - public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side) { - switch (side) { - case 0: - return (y & 3) == 3; - case 1: - return (y & 3) == 0; - case 2: - return (z & 3) == 3; - case 3: - return (z & 3) == 0; - case 4: - return (x & 3) == 3; - case 5: - return (x & 3) == 0; - } - - return super.shouldSideBeRendered(world, x, y, z, side); - } + @SideOnly(Side.CLIENT) + @Override + @Deprecated + public boolean shouldSideBeRendered(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing side) { + switch (side) { + case DOWN: + return (pos.getY() & 3) == 0; + case UP: + return (pos.getY() & 3) == 3; + case NORTH: + return (pos.getZ() & 3) == 0; + case SOUTH: + return (pos.getZ() & 3) == 3; + case WEST: + return (pos.getX() & 3) == 0; + case EAST: + return (pos.getX() & 3) == 3; + } + + return super.shouldSideBeRendered(state, world, pos, side); + } } diff --git a/src/main/java/twilightforest/block/BlockTFGiantLog.java b/src/main/java/twilightforest/block/BlockTFGiantLog.java index 04c2c754f2..207234d0a1 100644 --- a/src/main/java/twilightforest/block/BlockTFGiantLog.java +++ b/src/main/java/twilightforest/block/BlockTFGiantLog.java @@ -1,16 +1,13 @@ package twilightforest.block; -import twilightforest.item.TFItems; import net.minecraft.init.Blocks; +import twilightforest.item.TFItems; -public class BlockTFGiantLog extends BlockTFGiantBlock { - - +public class BlockTFGiantLog extends BlockTFGiantBlock { protected BlockTFGiantLog() { - super(Blocks.log); - this.setHardness(2.0F * 64F); - + super(Blocks.LOG.getDefaultState()); + this.setHardness(2.0F * 64F); this.setCreativeTab(TFItems.creativeTab); } diff --git a/src/main/java/twilightforest/block/BlockTFGiantObsidian.java b/src/main/java/twilightforest/block/BlockTFGiantObsidian.java index 6a680f5d34..ec5dd23dfe 100644 --- a/src/main/java/twilightforest/block/BlockTFGiantObsidian.java +++ b/src/main/java/twilightforest/block/BlockTFGiantObsidian.java @@ -1,18 +1,14 @@ package twilightforest.block; -import twilightforest.item.TFItems; import net.minecraft.init.Blocks; +import twilightforest.item.TFItems; -public class BlockTFGiantObsidian extends BlockTFGiantBlock { - - +public class BlockTFGiantObsidian extends BlockTFGiantBlock { protected BlockTFGiantObsidian() { - super(Blocks.obsidian); - this.setHardness(50.0F * 64F * 64F); - this.setResistance(2000.0F * 64F * 64F); - + super(Blocks.OBSIDIAN.getDefaultState()); + this.setHardness(50.0F * 64F * 64F); + this.setResistance(2000.0F * 64F * 64F); this.setCreativeTab(TFItems.creativeTab); } - } diff --git a/src/main/java/twilightforest/block/BlockTFHedge.java b/src/main/java/twilightforest/block/BlockTFHedge.java index 09b1cf6b60..91d1a5e389 100644 --- a/src/main/java/twilightforest/block/BlockTFHedge.java +++ b/src/main/java/twilightforest/block/BlockTFHedge.java @@ -1,351 +1,210 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; -import net.minecraft.block.BlockLeavesBase; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.monster.EntitySpider; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.pathfinding.PathNodeType; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.DamageSource; -import net.minecraft.util.IIcon; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.HedgeVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.util.EntityUtil; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Random; -public class BlockTFHedge extends BlockLeavesBase { - - public int damageDone; +public class BlockTFHedge extends Block implements ModelRegisterCallback { - public static IIcon sprHedge; - public static IIcon sprDarkwoodLeaves; + public static final IProperty VARIANT = PropertyEnum.create("variant", HedgeVariant.class); + private static final AxisAlignedBB HEDGE_BB = new AxisAlignedBB(0, 0, 0, 1, 0.9375, 1); + + private final int damageDone; protected BlockTFHedge() { - super(Material.cactus, false); + super(Material.CACTUS); this.damageDone = 3; + this.setSoundType(SoundType.PLANT); this.setHardness(2F); this.setResistance(10F); - this.setStepSound(Block.soundTypeGrass); this.setCreativeTab(TFItems.creativeTab); } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) - { - int meta = world.getBlockMetadata(x, y, z); - switch (meta) { - case 0: - float f = 0.0625F; - return AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1 - f, z + 1); - default : - case 1 : - return AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1); - } - - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return true; - } - - @SideOnly(Side.CLIENT) - - /** - * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given - * coordinates. Args: blockAccess, x, y, z, side - */ - @Override - public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) - { - Block i1 = par1IBlockAccess.getBlock(par2, par3, par4); - return !this.field_150121_P && i1 == this ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - if (meta == 2) { - // temporary workaround - meta = 0; - } - if (meta == 1) { - // darkwood sapling for darkwood leaves - return 3; - } + @Override + @Deprecated + public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { + return blockAccess.getBlockState(pos.offset(side)).getBlock() != this && super.shouldSideBeRendered(blockState, blockAccess, pos, side); + } - return meta; + @Override + @Deprecated + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + if (state.getValue(VARIANT) == HedgeVariant.HEDGE) { + return HEDGE_BB; + } else { + return FULL_BLOCK_AABB; + } } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - switch (meta) { - case 1: - return BlockTFHedge.sprDarkwoodLeaves; - default : - case 0 : - return BlockTFHedge.sprHedge; - } - } - @Override - public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) - { - int meta = world.getBlockMetadata(x, y, z); + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return true; + } - if (meta == 2) { - // temporary workaround - meta = 0; - } + @Override + public int damageDropped(IBlockState state) { + if (state.getValue(VARIANT) == HedgeVariant.DARKWOOD_LEAVES) { + // Darkwood sapling + return 3; + } else { + return getMetaFromState(state); + } + } - if (meta == 0 && shouldDamage(entity)) { - entity.attackEntityFrom(DamageSource.cactus, damageDone); - } - } + @Nullable + @Override + public PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos, @Nullable EntityLiving entity) { + return entity != null && state.getValue(VARIANT) == HedgeVariant.HEDGE && shouldDamage(entity) ? PathNodeType.DAMAGE_CACTUS : null; + } - @Override - public void onEntityWalking(World world, int x, int y, int z, Entity entity) - { - int meta = world.getBlockMetadata(x, y, z); - if (meta == 2) { - // temporary workaround - meta = 0; - } + @Override + public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity) { + if (state.getValue(VARIANT) == HedgeVariant.HEDGE && shouldDamage(entity)) { + entity.attackEntityFrom(DamageSource.CACTUS, damageDone); + } + } - if (meta == 0 && shouldDamage(entity)) { - entity.attackEntityFrom(DamageSource.cactus, damageDone); - } - } + @Override + public void onEntityWalk(World world, BlockPos pos, Entity entity) { + if (world.getBlockState(pos).getValue(VARIANT) == HedgeVariant.HEDGE && shouldDamage(entity)) { + entity.attackEntityFrom(DamageSource.CACTUS, damageDone); + } + } - @Override - public void onBlockClicked(World world, int x, int y, int z, EntityPlayer entityplayer) - { - int meta = world.getBlockMetadata(x, y, z); - if (meta == 2) { - // temporary workaround - meta = 0; - } + @Override + public void onBlockClicked(World world, BlockPos pos, EntityPlayer player) { + if (!world.isRemote && world.getBlockState(pos).getValue(VARIANT) == HedgeVariant.HEDGE) { + world.scheduleUpdate(pos, this, 10); + } + } - if (meta == 0 && !world.isRemote) { - world.scheduleBlockUpdate(x, y, z, this, 10); - } - } - - /** - * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the - * block and l is the block's subtype/damage. - */ - @Override - public void harvestBlock(World world, EntityPlayer entityplayer, int i, int j, int k, int meta) - { - super.harvestBlock(world, entityplayer, i, j, k, meta); - if (meta == 2) { - // temporary workaround - meta = 0; - } - if (meta == 0) { - entityplayer.attackEntityFrom(DamageSource.cactus, damageDone); - } - } - - - /** - * This should be called 5 ticks after we've received a click event from a player. - * If we see player nearby swinging at a hedge block, prick them - */ - @SuppressWarnings("unchecked") @Override - public void updateTick(World world, int x, int y, int z, Random random) - { - double range = 4.0; // do we need to get this with a better method than hardcoding it? + public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack) { + super.harvestBlock(world, player, pos, state, te, stack); + if (state.getValue(VARIANT) == HedgeVariant.HEDGE) { + player.attackEntityFrom(DamageSource.CACTUS, damageDone); + } + } - // find players within harvest range - List nearbyPlayers = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1).expand(range, range, range)); + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random random) { + // find players within range + List nearbyPlayers = world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB(pos).grow(8.0)); + + for (EntityPlayer player : nearbyPlayers) { + // are they swinging? + if (player.isSwingInProgress) { + RayTraceResult ray = EntityUtil.rayTrace(player); + // are they pointing at this block? + if (ray != null && ray.typeOfHit == RayTraceResult.Type.BLOCK && pos.equals(ray.getBlockPos())) { + // prick them! prick them hard! + player.attackEntityFrom(DamageSource.CACTUS, damageDone); + + // trigger this again! + world.scheduleUpdate(pos, this, 10); + } + } + } + } - // are they swinging? - for (EntityPlayer player : nearbyPlayers) { - if (player.isSwingInProgress) { - // are they pointing at this block? - MovingObjectPosition mop = getPlayerPointVec(world, player, range); + private boolean shouldDamage(Entity entity) { + return !(entity instanceof EntitySpider || entity instanceof EntityItem || entity.doesEntityNotTriggerPressurePlate()); + } - if (mop != null && world.getBlock(mop.blockX, mop.blockY, mop.blockZ) == this) { - // prick them! prick them hard! - player.attackEntityFrom(DamageSource.cactus, damageDone); + @Override + public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing side) { + IBlockState state = world.getBlockState(pos); + return state.getValue(VARIANT) == HedgeVariant.DARKWOOD_LEAVES ? 1 : 0; + } - // trigger this again! - world.scheduleBlockUpdate(x, y, z, this, 10); - } - } - } - } + @Override + public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing side) { + return 0; + } - - /** - * What block is the player pointing the wand at? - * - * This very similar to player.rayTrace, but that method is not available on the server. - * - * @return - */ - private MovingObjectPosition getPlayerPointVec(World worldObj, EntityPlayer player, double range) { - Vec3 position = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 look = player.getLook(1.0F); - Vec3 dest = position.addVector(look.xCoord * range, look.yCoord * range, look.zCoord * range); - return worldObj.rayTraceBlocks(position, dest); + @Override + public int quantityDropped(Random random) { + return random.nextInt(40) == 0 ? 1 : 0; } - -// /** -// * Is the player swinging, server version. Ugggh. Okay, this sucks and we don't really need it -// */ -// private boolean isPlayerSwinging(EntityPlayer player) { -// if (player instanceof EntityPlayerMP) { -// ItemInWorldManager iiwm = ((EntityPlayerMP)player).itemInWorldManager; -// // curblockDamage > initialDamage -// return ((Integer)ModLoader.getPrivateValue(ItemInWorldManager.class, iiwm, 9)).intValue() > ((Integer)ModLoader.getPrivateValue(ItemInWorldManager.class, iiwm, 5)).intValue(); -// -//// for (int i = 0; i < ItemInWorldManager.class.getDeclaredFields().length; i++) { -//// // if we find a boolean in here, just assume that's it for the time being -//// if (ModLoader.getPrivateValue(ItemInWorldManager.class, iiwm, i) instanceof Boolean) { -//// return ((Boolean)ModLoader.getPrivateValue(ItemInWorldManager.class, iiwm, i)).booleanValue(); -//// } -//// } -// } -// // we didn't find it -// return false; -// } - - private boolean shouldDamage(Entity entity) { - return !(entity instanceof EntitySpider) && !(entity instanceof EntityItem) && !entity.doesEntityNotTriggerPressurePlate(); - } - - /** - * Chance that fire will spread and consume this block. - * 300 being a 100% chance, 0, being a 0% chance. - * - * @param world The current world - * @param x The blocks X position - * @param y The blocks Y position - * @param z The blocks Z position - * @param metadata The blocks current metadata - * @param face The face that the fire is coming from - * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire - */ - @Override - public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { - int metadata = world.getBlockMetadata(x, y, z); - return metadata == 1 ? 1 : 0; + @Override + public Item getItemDropped(IBlockState state, Random random, int fortune) { + if (state.getValue(VARIANT) == HedgeVariant.DARKWOOD_LEAVES) { + return Item.getItemFromBlock(TFBlocks.twilight_sapling); + } else { + return Items.AIR; + } } - /** - * Called when fire is updating on a neighbor block. - * The higher the number returned, the faster fire will spread around this block. - * - * @param world The current world - * @param x The blocks X position - * @param y The blocks Y position - * @param z The blocks Z position - * @param metadata The blocks current metadata - * @param face The face that the fire is coming from - * @return A number that is used to determine the speed of fire growth around the block - */ @Override - public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { - return 0; + public ItemStack getItem(World world, BlockPos pos, IBlockState state) { + return new ItemStack(this, 1, getMetaFromState(state)); } - /** - * Returns the quantity of items to drop on block destruction. - */ - @Override - public int quantityDropped(Random par1Random) - { - return par1Random.nextInt(40) == 0 ? 1 : 0; - } + @Override + public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { + if (state.getValue(VARIANT) == HedgeVariant.DARKWOOD_LEAVES) { + Random rand = world instanceof World ? ((World)world).rand : RANDOM; + if (rand.nextInt(40) == 0) { + Item item = this.getItemDropped(state, rand, fortune); + drops.add(new ItemStack(item, 1, this.damageDropped(state))); + } + } + } - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int meta, Random par2Random, int par3) - { - if (meta == 1) - { - return Item.getItemFromBlock(TFBlocks.sapling); - } - else - { - return null; - } - } + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } - /** - * Called when a user uses the creative pick block button on this block - * - * @param target The full target the player is looking at - * @return A ItemStack to add to the player's inventory, Null if nothing should be added. - */ - @Override - public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z) - { - return new ItemStack(this, 1, world.getBlockMetadata(x, y, z)); - } + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(VARIANT, HedgeVariant.values()[meta % HedgeVariant.values().length]); + } - /** - * Drops the block items with a specified chance of dropping the specified items - */ - @Override - public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int meta, float par6, int fortune) - { - if (!par1World.isRemote && meta == 1) - { - if (par1World.rand.nextInt(40) == 0) - { - Item var9 = this.getItemDropped(meta, par1World.rand, fortune); - this.dropBlockAsItem(par1World, par2, par3, par4, new ItemStack(var9, 1, this.damageDropped(meta))); - } - } - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFHedge.sprHedge = par1IconRegister.registerIcon(TwilightForestMod.ID + ":hedge"); - BlockTFHedge.sprDarkwoodLeaves = par1IconRegister.registerIcon(TwilightForestMod.ID + ":darkwood_leaves"); - } + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } } - diff --git a/src/main/java/twilightforest/block/BlockTFHorizontal.java b/src/main/java/twilightforest/block/BlockTFHorizontal.java new file mode 100644 index 0000000000..7ec7c1389f --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFHorizontal.java @@ -0,0 +1,62 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFHorizontal extends BlockHorizontal implements ModelRegisterCallback { + + protected BlockTFHorizontal(Material material) { + super(material); + } + + protected BlockTFHorizontal(Material material, MapColor mapColor) { + super(material, mapColor); + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(FACING, EnumFacing.byHorizontalIndex(meta)); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(FACING).getHorizontalIndex(); + } + + @Override + public IBlockState withRotation(IBlockState state, Rotation rot) { + return state.withProperty(FACING, rot.rotate(state.getValue(FACING))); + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { + return state.withRotation(mirrorIn.toRotation(state.getValue(FACING))); + } + + @Override + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFHugeGloomBlock.java b/src/main/java/twilightforest/block/BlockTFHugeGloomBlock.java index 506bbd6fca..13fd2f098f 100644 --- a/src/main/java/twilightforest/block/BlockTFHugeGloomBlock.java +++ b/src/main/java/twilightforest/block/BlockTFHugeGloomBlock.java @@ -1,74 +1,17 @@ package twilightforest.block; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.item.Item; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFHugeGloomBlock extends Block { - - @SideOnly(Side.CLIENT) - private IIcon capTex; - @SideOnly(Side.CLIENT) - private IIcon stemTex; - @SideOnly(Side.CLIENT) - private IIcon insideTex; - - public BlockTFHugeGloomBlock() - { - super(Material.wood); - this.setHardness(0.2F); - this.setStepSound(soundTypeWood); - this.setBlockTextureName(TwilightForestMod.ID + ":huge_gloom"); - this.setLightLevel(5F / 16F); - } - - /** - * Gets the block's texture. Args: side, meta - */ - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) { - return meta == 10 && side > 1 ? this.stemTex : (meta >= 1 && meta <= 9 && side == 1 ? this.capTex : (meta >= 1 && meta <= 3 && side == 2 ? this.capTex : (meta >= 7 && meta <= 9 && side == 3 ? this.capTex : ((meta == 1 || meta == 4 || meta == 7) && side == 4 ? this.capTex : ((meta == 3 || meta == 6 || meta == 9) && side == 5 ? this.capTex : (meta == 14 ? this.capTex : (meta == 15 ? this.stemTex : this.insideTex))))))); - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random rand) - { - int i = rand.nextInt(10) - 7; - - if (i < 0) - { - i = 0; - } - - return i; - } - - public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) { - return Item.getItemById(Block.getIdFromBlock(TFBlocks.plant)); - } +import twilightforest.client.ModelRegisterCallback; - /** - * Gets an item for the block being called on. Args: world, x, y, z - */ - @SideOnly(Side.CLIENT) - public Item getItem(World p_149694_1_, int p_149694_2_, int p_149694_3_, int p_149694_4_) { - return Item.getItemById(Block.getIdFromBlock(TFBlocks.plant)); - } +public class BlockTFHugeGloomBlock extends BlockHugeMushroom implements ModelRegisterCallback { - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister iconRegister) { - this.capTex = iconRegister.registerIcon(this.getTextureName() + "_cap"); - this.insideTex = iconRegister.registerIcon(this.getTextureName() + "_inside"); - this.stemTex = iconRegister.registerIcon(this.getTextureName() + "_stem"); - } + public BlockTFHugeGloomBlock() { + super(Material.WOOD, MapColor.ADOBE, TFBlocks.twilight_plant); + this.setHardness(0.2F); + this.setSoundType(SoundType.WOOD); + this.setLightLevel(5F / 16F); + } } \ No newline at end of file diff --git a/src/main/java/twilightforest/block/BlockTFHugeLilyPad.java b/src/main/java/twilightforest/block/BlockTFHugeLilyPad.java index ccd2e5ac68..0af717e81e 100644 --- a/src/main/java/twilightforest/block/BlockTFHugeLilyPad.java +++ b/src/main/java/twilightforest/block/BlockTFHugeLilyPad.java @@ -1,263 +1,193 @@ package twilightforest.block; -import java.util.List; - -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.block.Block; +import com.google.common.collect.Lists; import net.minecraft.block.BlockBush; +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.EnumPushReaction; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityBoat; import net.minecraft.init.Blocks; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; -import net.minecraft.world.Explosion; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.HugeLilypadPiece; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; -public class BlockTFHugeLilyPad extends BlockBush { - - private IIcon pad1; - private IIcon pad2; - private IIcon pad3; - private IIcon blank; - private boolean isSelfDestructing = false; +import javax.annotation.Nullable; +import java.util.List; +public class BlockTFHugeLilyPad extends BlockBush implements ModelRegisterCallback { - protected BlockTFHugeLilyPad() { - super(Material.plants); - - float f = 0.5F; - float f1 = 0.015625F; - this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); - this.setStepSound(soundTypeGrass); + public static final IProperty FACING = BlockHorizontal.FACING; + public static final IProperty PIECE = PropertyEnum.create("piece", HugeLilypadPiece.class); + private static final AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 1, 0.015625, 1); + private boolean isSelfDestructing = false; + + protected BlockTFHugeLilyPad() { + super(Material.PLANTS); + this.setSoundType(SoundType.PLANT); this.setCreativeTab(TFItems.creativeTab); - - Item lily; + this.setDefaultState(blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH).withProperty(PIECE, HugeLilypadPiece.NW)); + } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING, PIECE); } - - /** - * The type of render function that is called for this block - */ - public int getRenderType() - { - return TwilightForestMod.proxy.getHugeLilyPadBlockRenderID(); - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - public AxisAlignedBB getCollisionBoundingBoxFromPool(World p_149668_1_, int p_149668_2_, int p_149668_3_, int p_149668_4_) - { - return AxisAlignedBB.getBoundingBox((double)p_149668_2_ + this.minX, (double)p_149668_3_ + this.minY, (double)p_149668_4_ + this.minZ, (double)p_149668_2_ + this.maxX, (double)p_149668_3_ + this.maxY, (double)p_149668_4_ + this.maxZ); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - } - + public int getMetaFromState(IBlockState state) { + return (state.getValue(FACING).getHorizontalIndex() | (state.getValue(PIECE).ordinal() << 2)) & 0b1111; + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ @Override - public IIcon getIcon(int side, int meta) { - // sides blank - if (side > 1) { - return this.blank; - } - - int orient = meta >> 2; - int piece = meta & 3; - - // why can't this just be simple? - if (orient == 1) { - orient = 3; - } else if (orient == 3) { - orient = 1; + @Deprecated + public IBlockState getStateFromMeta(int meta) { + meta = meta & 0b1111; + return getDefaultState().withProperty(FACING, EnumFacing.byHorizontalIndex(meta & 0b0011)).withProperty(PIECE, HugeLilypadPiece.values()[(meta & 0b1100) >> 2]); + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return AABB; + } + + @Override + public boolean canPlaceBlockAt(World world, BlockPos pos) { + return world.getBlockState(pos.down()).getBlock() == Blocks.WATER; + } + + @Override + public void breakBlock(World world, BlockPos pos, IBlockState state) { + //TwilightForestMod.LOGGER.info("Destroying giant lilypad at {}, state {}", pos, state); + + if (!this.isSelfDestructing) { + this.setGiantBlockToAir(world, pos, state); } - - - int display = (piece + orient) % 4; - + } - switch (display) { - case 0: - default: - return this.blockIcon; - case 1: - return this.pad1; - case 2: - return this.pad2; - case 3: - return this.pad3; + private void setGiantBlockToAir(World world, BlockPos pos, IBlockState state) { + // this flag is not threadsafe + this.isSelfDestructing = true; + + for (BlockPos check : this.getAllMyBlocks(pos, state)) { + IBlockState stateThere = world.getBlockState(check); + if (stateThere.getBlock() == this) { + world.destroyBlock(check, false); + } } + + this.isSelfDestructing = false; } @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.blockIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":huge_lilypad_0"); - this.pad1 = par1IconRegister.registerIcon(TwilightForestMod.ID + ":huge_lilypad_1"); - this.pad2 = par1IconRegister.registerIcon(TwilightForestMod.ID + ":huge_lilypad_2"); - this.pad3 = par1IconRegister.registerIcon(TwilightForestMod.ID + ":huge_lilypad_3"); - this.blank = par1IconRegister.registerIcon(TwilightForestMod.ID + ":blank"); + public boolean canBlockStay(World world, BlockPos pos, IBlockState state) { + for (BlockPos check : this.getAllMyBlocks(pos, state)) { + IBlockState dStateBelow = world.getBlockState(check.down()); + + if (!(dStateBelow.getBlock() == Blocks.WATER || dStateBelow.getBlock() == Blocks.FLOWING_WATER) + || dStateBelow.getValue(BlockLiquid.LEVEL) != 0) { + return false; + } + + if (world.getBlockState(check).getBlock() != this) { + //TwilightForestMod.LOGGER.info("giant lilypad cannot stay because we can't find all 4 pieces"); + return false; + } + } + + return true; } - - /** - * is the block grass, dirt or farmland - */ - protected boolean canPlaceBlockOn(Block block) - { - return block == Blocks.water; - } /** - * Called when the block is attempted to be harvested - */ - public void onBlockHarvested(World world, int x, int y, int z, int meta, EntityPlayer player) { - this.setGiantBlockToAir(world, x, y, z); - } - - /** - * Called when the block is destroyed by an explosion. - * Useful for allowing the block to take into account tile entities, - * metadata, etc. when exploded, before it is removed. - * - * @param world The current world - * @param x X Position - * @param y Y Position - * @param z Z Position - * @param Explosion The explosion instance affecting the block - */ - public void onBlockExploded(World world, int x, int y, int z, Explosion explosion) - { - world.setBlockToAir(x, y, z); - this.setGiantBlockToAir(world, x, y, z); - } - - - /** - * Called on server worlds only when the block is about to be replaced by a different block or the same block with a - * different metadata value. Args: world, x, y, z, old metadata - */ - public void onBlockPreDestroy(World world, int x, int y, int z, int meta) { - - int orient = meta >> 2; - int piece = meta & 3; - - int display = (piece + orient) % 4; - - if (!this.isSelfDestructing && !canBlockStay(world, x, y, z)) { - this.setGiantBlockToAir(world, x, y, z); - } - } - - /** - * Set the whole giant block area to air - */ - private void setGiantBlockToAir(World world, int x, int y, int z) { - // this flag is maybe not totally perfect - this.isSelfDestructing = true; - - int bx = (x >> 1) << 1; - int bz = (z >> 1) << 1; + * Get all 4 coordinates for all parts of this lily pad. + */ + public List getAllMyBlocks(BlockPos pos, IBlockState state) { + List pieces = Lists.newArrayListWithCapacity(4); + if (state.getBlock() == this) { + // find NW corner + BlockPos nwPos = pos; + switch (state.getValue(PIECE)) { + case NE: + nwPos = nwPos.west(); + break; + case SE: + nwPos = nwPos.north().west(); + break; + case SW: + nwPos = nwPos.north(); + break; + default: + break; + } + + pieces.add(nwPos); + pieces.add(nwPos.south()); + pieces.add(nwPos.east()); + pieces.add(nwPos.south().east()); + } - // this is the best loop over 3 items that I've ever programmed! - for (int dx = 0; dx < 2; dx++) { - for (int dz = 0; dz < 2; dz++) { - if (!(x == bx + dx && z == bz + dz)) { - if (world.getBlock(bx + dx, y, bz + dz) == this) { - world.setBlock(bx + dx, y, bz + dz, Blocks.air, 0, 2); - } - } - } - } + return pieces; + } - this.isSelfDestructing = false; + // [VanillaCopy] of super without dropping + @Override + protected void checkAndDropBlock(World worldIn, BlockPos pos, IBlockState state) { + if (!this.canBlockStay(worldIn, pos, state)) { + // this.dropBlockAsItem(worldIn, pos, state, 0); TF - nodrop + worldIn.setBlockState(pos, Blocks.AIR.getDefaultState(), 3); + } } + @Override + @Deprecated + public EnumPushReaction getPushReaction(IBlockState state) { + return EnumPushReaction.BLOCK; + } - /** - * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. - */ - public boolean canBlockStay(World world, int x, int y, int z) { - boolean allThisBlock = true; - boolean allWater = true; - - int bx = (x >> 1) << 1; - int bz = (z >> 1) << 1; + @Override + @Deprecated + public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List collidingBoxes, @Nullable Entity entityIn, boolean p_185477_7_) { + if (!(entityIn instanceof EntityBoat)) { + addCollisionBoxToList(pos, entityBox, collidingBoxes, AABB); + } + } - for (int dx = 0; dx < 2; dx++) { - for (int dz = 0; dz < 2; dz++) { - allThisBlock &= world.getBlock(bx + dx, y, bz + dz) == this; - allWater &= (world.getBlock(bx + dx, y - 1, bz + dz).getMaterial() == Material.water && world.getBlockMetadata(bx + dx, y - 1, bz + dz) == 0); - } - } + @Override + public void onEntityCollision(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) { + super.onEntityCollision(worldIn, pos, state, entityIn); - return allThisBlock && allWater; - } - - /** - * checks if the block can stay, if not drop as item - */ - protected void checkAndDropBlock(World p_149855_1_, int p_149855_2_, int p_149855_3_, int p_149855_4_) - { - if (!this.canBlockStay(p_149855_1_, p_149855_2_, p_149855_3_, p_149855_4_)) - { - //this.dropBlockAsItem(p_149855_1_, p_149855_2_, p_149855_3_, p_149855_4_, p_149855_1_.getBlockMetadata(p_149855_2_, p_149855_3_, p_149855_4_), 0); - p_149855_1_.setBlock(p_149855_2_, p_149855_3_, p_149855_4_, getBlockById(0), 0, 2); - } - } - - /** - * Returns the mobility information of the block, 0 = free, 1 = can't push but can move over, 2 = total immobility - * and stop pistons - */ - public int getMobilityFlag() - { - return 2; - } - - @SideOnly(Side.CLIENT) - public int getBlockColor() - { - return 2129968; - } + if (entityIn instanceof EntityBoat) { + worldIn.destroyBlock(new BlockPos(pos), true); + } + } - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @SideOnly(Side.CLIENT) - public int getRenderColor(int p_149741_1_) - { - return 2129968; - } + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @SideOnly(Side.CLIENT) - public int colorMultiplier(IBlockAccess p_149720_1_, int p_149720_2_, int p_149720_3_, int p_149720_4_) - { - return 2129968; - } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + } } diff --git a/src/main/java/twilightforest/block/BlockTFHugeStalk.java b/src/main/java/twilightforest/block/BlockTFHugeStalk.java index c09ab68d60..1406fe2b18 100644 --- a/src/main/java/twilightforest/block/BlockTFHugeStalk.java +++ b/src/main/java/twilightforest/block/BlockTFHugeStalk.java @@ -1,86 +1,49 @@ package twilightforest.block; import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.util.IIcon; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFHugeStalk extends Block { - - private IIcon topIcon; +public class BlockTFHugeStalk extends Block implements ModelRegisterCallback { protected BlockTFHugeStalk() { - super(Material.wood); - + super(Material.WOOD, MapColor.FOLIAGE); + this.setHardness(1.25F); this.setResistance(7.0F); - - this.setBlockTextureName(TwilightForestMod.ID + ":huge_stalk"); - - this.setStepSound(soundTypeGrass); + + this.setSoundType(SoundType.PLANT); this.setCreativeTab(TFItems.creativeTab); } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) { - super.registerBlockIcons(par1IconRegister); - - this.topIcon = par1IconRegister.registerIcon(this.getTextureName() + "_top"); + @Override + public boolean canSustainLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { + return true; } - - /** - * Gets the block's texture. Args: side, meta - */ - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) { - if (side == 0 || side == 1) { - return this.topIcon; - } else { - return this.blockIcon; - } - } - /** - * Determines if this block can prevent leaves connected to it from decaying. - * - * @param world The current world - * @param x X Position - * @param y Y Position - * @param z Z Position - * @return true if the presence this block can prevent leaves from decaying. - */ + // [VanillaCopy] BlockLog + @SuppressWarnings("unused") @Override - public boolean canSustainLeaves(IBlockAccess world, int x, int y, int z) { - return true; + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { + int i = 4; + int j = 5; + + if (worldIn.isAreaLoaded(pos.add(-5, -5, -5), pos.add(5, 5, 5))) { + for (BlockPos blockpos : BlockPos.getAllInBox(pos.add(-4, -4, -4), pos.add(4, 4, 4))) { + IBlockState iblockstate = worldIn.getBlockState(blockpos); + + if (iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos)) { + iblockstate.getBlock().beginLeavesDecay(iblockstate, worldIn, blockpos); + } + } + } } - - /** - * Begin leaf decay when this block is broken - */ - public void breakBlock(World world, int x, int y, int z, Block myBlock, int meta) { - byte radius = 4; - int rad1 = radius + 1; - if (world.checkChunksExist(x - rad1, y - rad1, z - rad1, x + rad1, y + rad1, z + rad1)) { - for (int dx = -radius; dx <= radius; ++dx) { - for (int dy = -radius; dy <= radius; ++dy) { - for (int dz = -radius; dz <= radius; ++dz) { - Block block = world.getBlock(x + dx, y + dy, z + dz); - if (block.isLeaves(world, x + dx, y + dy, z + dz)) { - block.beginLeavesDecay(world, x + dx, y + dy, z + dz); - } - } - } - } - } - } - } diff --git a/src/main/java/twilightforest/block/BlockTFHugeWaterLily.java b/src/main/java/twilightforest/block/BlockTFHugeWaterLily.java index 78c3b23275..33c0e7f9f3 100644 --- a/src/main/java/twilightforest/block/BlockTFHugeWaterLily.java +++ b/src/main/java/twilightforest/block/BlockTFHugeWaterLily.java @@ -1,48 +1,60 @@ package twilightforest.block; -import net.minecraft.block.Block; -import net.minecraft.block.BlockBush; -import net.minecraft.block.material.Material; +import net.minecraft.block.*; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.init.Blocks; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; +import net.minecraft.item.Item; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -public class BlockTFHugeWaterLily extends BlockBush { +public class BlockTFHugeWaterLily extends BlockLilyPad implements ModelRegisterCallback { + + private static final AxisAlignedBB AABB = new AxisAlignedBB(0.1, 0.1, 0.1, 0.9, 0.9, 0.9); protected BlockTFHugeWaterLily() { - super(Material.plants); - - this.setStepSound(soundTypeGrass); + this.setSoundType(SoundType.PLANT); this.setCreativeTab(TFItems.creativeTab); - - float radius = 0.4F; - this.setBlockBounds(0.5F - radius, 0.5F - radius, 0.5F - radius, 0.5F + radius, .5F + radius, 0.5F + radius); } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) - { - return null; - } - - /** - * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. - */ - public boolean canBlockStay(World world, int x, int y, int z) { - return world.getBlock(x, y - 1, z).getMaterial() == Material.water && world.getBlockMetadata(x, y - 1, z) == 0; + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return AABB; + } + + /*@Override + public boolean canBlockStay(World world, BlockPos pos, IBlockState state) { + IBlockState down = world.getBlockState(pos.down()); + Block b = down.getBlock(); + IProperty levelProp = b instanceof BlockLiquid || b instanceof BlockFluidBase + ? BlockLiquid.LEVEL + : null; + + return down.getMaterial() == Material.WATER + && (levelProp == null || down.getValue(levelProp) == 0); + }*/ + + @Override + protected boolean canSustainBush(IBlockState state) { + return state.getBlock() == Blocks.WATER; } + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } - /** - * is the block grass, dirt or farmland - */ - protected boolean canPlaceBlockOn(Block p_149854_1_) - { - return p_149854_1_ == Blocks.water; - } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + } } diff --git a/src/main/java/twilightforest/block/BlockTFKnightmetalBlock.java b/src/main/java/twilightforest/block/BlockTFKnightmetalBlock.java index 97ba4d80c6..98a8bc303f 100644 --- a/src/main/java/twilightforest/block/BlockTFKnightmetalBlock.java +++ b/src/main/java/twilightforest/block/BlockTFKnightmetalBlock.java @@ -1,90 +1,67 @@ package twilightforest.block; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; -import net.minecraft.block.BlockCompressed; -import net.minecraft.block.material.MapColor; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.pathfinding.PathNodeType; import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -public class BlockTFKnightmetalBlock extends BlockCompressed { +public class BlockTFKnightmetalBlock extends Block implements ModelRegisterCallback { + private static final AxisAlignedBB AABB = new AxisAlignedBB(1 / 16F, 1 / 16F, 1 / 16F, 15 / 16F, 15 / 16F, 15 / 16F); private static final float BLOCK_DAMAGE = 4; public BlockTFKnightmetalBlock() { - super(MapColor.ironColor); + super(Material.IRON); this.setHardness(5.0F); this.setResistance(41.0F); - this.setStepSound(Block.soundTypeMetal); - this.setBlockTextureName(TwilightForestMod.ID + ":knightmetal_block"); + this.setSoundType(SoundType.METAL); this.setCreativeTab(TFItems.creativeTab); - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ + @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) - { - float f = 1F / 16F; - return AxisAlignedBB.getBoundingBox(x + f, y + f, z + f, x + 1 - f, y + 1 - f, z + 1 - f); + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return AABB; + } + @Override + public PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos) { + return PathNodeType.DAMAGE_CACTUS; } - - /** - * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity - */ - public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) - { - entity.attackEntityFrom(DamageSource.cactus, BLOCK_DAMAGE); - } - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - @Override - public boolean renderAsNormalBlock() - { - return false; - } - + @Override + public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity) { + entity.attackEntityFrom(DamageSource.CACTUS, BLOCK_DAMAGE); + } - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return false; - } + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getKnightmetalBlockRenderID(); - } + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } - /** - * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given - * coordinates. Args: blockAccess, x, y, z, side - */ - @Override + @Override @SideOnly(Side.CLIENT) - public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) - { - return true; - } + @Deprecated + public boolean shouldSideBeRendered(IBlockState state, IBlockAccess access, BlockPos pos, EnumFacing side) { + return !access.getBlockState(pos.offset(side)).doesSideBlockRendering(access, pos.offset(side), side.getOpposite()); + } } diff --git a/src/main/java/twilightforest/block/BlockTFLadderBars.java b/src/main/java/twilightforest/block/BlockTFLadderBars.java new file mode 100644 index 0000000000..8f8489e679 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFLadderBars.java @@ -0,0 +1,82 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLadder; +import net.minecraft.block.SoundType; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; + +import static net.minecraft.util.EnumFacing.*; + +public class BlockTFLadderBars extends BlockLadder implements ModelRegisterCallback { + public static final PropertyBool LEFT = PropertyBool.create("left"); + public static final PropertyBool RIGHT = PropertyBool.create("right"); + + BlockTFLadderBars() { + this.setDefaultState(this.getDefaultState().withProperty(LEFT, false).withProperty(RIGHT, false)); + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, BlockLadder.FACING, LEFT, RIGHT); + } + + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { + EnumFacing facing = state.getValue(BlockLadder.FACING); + + IBlockState leftState = worldIn.getBlockState(pos.offset(rotateCW (facing))); + IBlockState rightState = worldIn.getBlockState(pos.offset(rotateCCW(facing))); + + return super.getActualState(state, worldIn, pos) + .withProperty(LEFT , leftState .getBlock() instanceof BlockTFLadderBars && leftState .getValue(BlockLadder.FACING) == facing) + .withProperty(RIGHT, rightState.getBlock() instanceof BlockTFLadderBars && rightState.getValue(BlockLadder.FACING) == facing); + } + + private static EnumFacing rotateCW(EnumFacing facing) { + switch (facing) { + case NORTH: + return WEST; + case WEST: + return SOUTH; + case SOUTH: + return EAST; + case EAST: + return NORTH; + default: + return facing; + } + } + + private static EnumFacing rotateCCW(EnumFacing facing) { + switch (facing) { + case NORTH: + return EAST; + case EAST: + return SOUTH; + case SOUTH: + return WEST; + case WEST: + return NORTH; + default: + return facing; + } + } + + @Override + public void registerModel() { + ModelUtils.registerIncludingItemModels(this, "inventory", new IProperty[0]); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFLapisBlock.java b/src/main/java/twilightforest/block/BlockTFLapisBlock.java new file mode 100644 index 0000000000..4b637d7954 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFLapisBlock.java @@ -0,0 +1,17 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import twilightforest.item.TFItems; + +public class BlockTFLapisBlock extends Block { + + protected BlockTFLapisBlock() { + super(Material.IRON); + this.setSoundType(SoundType.STONE); + this.setCreativeTab(TFItems.creativeTab); + this.setHardness(3.0F); + this.setResistance(5.0F); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/block/BlockTFLeaves.java b/src/main/java/twilightforest/block/BlockTFLeaves.java index 3bd6ecf115..2ed54edfd5 100644 --- a/src/main/java/twilightforest/block/BlockTFLeaves.java +++ b/src/main/java/twilightforest/block/BlockTFLeaves.java @@ -1,223 +1,137 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.init.Blocks; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.ColorizerFoliage; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.enums.LeavesVariant; import twilightforest.item.TFItems; +import java.util.List; +import java.util.Random; +public class BlockTFLeaves extends BlockLeaves implements ModelRegisterCallback { - -public class BlockTFLeaves extends BlockLeaves { - - int oakColor = 0x48B518; - int canopyColor = 0x609860; - int mangroveColor = 0x80A755; - - public static final String[] unlocalizedNameArray = new String[] {"twilightoak", "canopy", "mangrove", "rainboak"}; - + public static final IProperty VARIANT = PropertyEnum.create("variant", LeavesVariant.class); protected BlockTFLeaves() { - super(); this.setHardness(0.2F); - this.setLightOpacity(2); - this.setStepSound(Block.soundTypeGrass); + this.setLightOpacity(1); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(CHECK_DECAY, true).withProperty(DECAYABLE, true).withProperty(VARIANT, LeavesVariant.OAK)); + } + + @Override + public int getLightOpacity(IBlockState state) { + return TFConfig.performance.leavesLightOpacity; + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, CHECK_DECAY, DECAYABLE, VARIANT); } - - @Override - public int getBlockColor() - { - double var1 = 0.5D; - double var3 = 1.0D; - return ColorizerFoliage.getFoliageColor(var1, var3); - } - - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @Override - public int getRenderColor(int par1) - { - return (par1 & 3) == 1 ? canopyColor : ((par1 & 3) == 2 ? mangroveColor : oakColor); - } - - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @Override - public int colorMultiplier(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int meta = par1IBlockAccess.getBlockMetadata(x, y, z); - - int red = 0; - int green = 0; - int blue = 0; - - for (int var9 = -1; var9 <= 1; ++var9) - { - for (int var10 = -1; var10 <= 1; ++var10) - { - int var11 = par1IBlockAccess.getBiomeGenForCoords(x + var10, z + var9).getBiomeFoliageColor(x, y, z); - red += (var11 & 16711680) >> 16; - green += (var11 & 65280) >> 8; - blue += var11 & 255; - } - } - - int normalColor = (red / 9 & 0xFF) << 16 | (green / 9 & 0xFF) << 8 | blue / 9 & 0xFF; - - if ((meta & 3) == 1) - { - // canopy colorizer - return ((normalColor & 0xFEFEFE) + 0x469A66) / 2; - //return ((normalColor & 0xFEFEFE) + 0x009822) / 2; - } - else if ((meta & 3) == 2) - { - // mangrove colors - return ((normalColor & 0xFEFEFE) + 0xC0E694) / 2; - } - else if ((meta & 3) == 3) - { - // RAINBOW! - red = x * 32 + y * 16; - if ((red & 256) != 0) - { - red = 255 - (red & 255); - } - red &= 255; - - blue = y * 32 + z * 16; - if ((blue & 256) != 0) - { - blue = 255 - (blue & 255); - } - blue ^= 255; - - green = x * 16 + z * 32; - if ((green & 256) != 0) - { - green = 255 - (green & 255); - } - green &= 255; - - - return red << 16 | blue << 8 | green; - } - else - { - return normalColor; - } - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return Blocks.leaves.isOpaqueCube(); - } - - @Override - public IIcon getIcon(int i, int j) - { - return Blocks.leaves.getIcon(i, (j & 3) == 3 ? 0 : j); - } - - @Override - public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l) - { - return Blocks.leaves.shouldSideBeRendered(iblockaccess, i, j, k, l); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + LeavesVariant variant = LeavesVariant.values()[meta & 0b11]; + return this.getDefaultState().withProperty(VARIANT, variant).withProperty(DECAYABLE, (meta & 4) == 0).withProperty(CHECK_DECAY, (meta & 8) > 0); + } + + @Override + public int getMetaFromState(IBlockState state) { + int i = state.getValue(VARIANT).ordinal(); + + if (!state.getValue(DECAYABLE)) { + i |= 4; + } + + if (state.getValue(CHECK_DECAY)) { + i |= 8; + } + + return i; + } + + @Override + public BlockPlanks.EnumType getWoodType(int meta) { + return BlockPlanks.EnumType.OAK; + } + @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(this, 1, 2)); - par3List.add(new ItemStack(this, 1, 3)); - - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - @Override - public int quantityDropped(Random par1Random) - { - return par1Random.nextInt(40) == 0 ? 1 : 0; - } - - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return Item.getItemFromBlock(TFBlocks.sapling); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int par1) - { - int leafType = par1 & 3; - - return leafType; - } - - /** - * Drops the block items with a specified chance of dropping the specified items - */ - @Override - public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int meta, float par6, int par7) - { - if (!par1World.isRemote) - { - byte chance = 40; - - if ((meta & 3) == 2) - { - chance = 20; - } - - if (par1World.rand.nextInt(chance) == 0) - { - Item item = this.getItemDropped(meta, par1World.rand, par7); - this.dropBlockAsItem(par1World, par2, par3, par4, new ItemStack(item, 1, this.getSaplingMeta(meta))); - } - } - } - - public int getSaplingMeta(int leafMeta) { - int leafType = leafMeta & 3; - - return leafType == 3 ? 9 : leafType; - } + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); + } + + @Override + public Item getItemDropped(IBlockState state, Random random, int fortune) { + return Item.getItemFromBlock(TFBlocks.twilight_sapling); + } + + @Override + public int damageDropped(IBlockState state) { + LeavesVariant leafType = state.getValue(VARIANT); + return leafType == LeavesVariant.RAINBOAK ? 9 : leafType.ordinal(); + } + + @Override + public ItemStack getSilkTouchDrop(IBlockState state) { + return new ItemStack(this, 1, state.getValue(VARIANT).ordinal()); + } + + @Override + public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) { + return new ItemStack(this, 1, state.getValue(VARIANT).ordinal()); + } + + @Override + public int getSaplingDropChance(IBlockState state) { + return state.getValue(VARIANT) == LeavesVariant.MANGROVE ? 20 : 40; + } + + @Override + public List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { + return NonNullList.withSize(1, new ItemStack(this, 1, world.getBlockState(pos).getValue(VARIANT).ordinal())); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + IStateMapper stateMapper = new StateMap.Builder().ignore(CHECK_DECAY, DECAYABLE).build(); + ModelLoader.setCustomStateMapper(this, stateMapper); + ModelUtils.registerToStateSingleVariant(this, VARIANT, stateMapper); + } + + @Override + public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face) { + return 60; + } @Override - public String[] func_150125_e() { - return unlocalizedNameArray; + public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face) { + return 30; } } diff --git a/src/main/java/twilightforest/block/BlockTFLeaves3.java b/src/main/java/twilightforest/block/BlockTFLeaves3.java index 7469652d39..4cf0206f93 100644 --- a/src/main/java/twilightforest/block/BlockTFLeaves3.java +++ b/src/main/java/twilightforest/block/BlockTFLeaves3.java @@ -1,129 +1,141 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.block.Block; import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.ColorizerFoliage; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; +import twilightforest.enums.Leaves3Variant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -public class BlockTFLeaves3 extends BlockLeaves { - - public static final String[] names = new String[] {"thorn", "beanstalk"}; +import java.util.List; +import java.util.Random; + +public class BlockTFLeaves3 extends BlockLeaves implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", Leaves3Variant.class); protected BlockTFLeaves3() { - super(); - this.setStepSound(Block.soundTypeGrass); this.setCreativeTab(TFItems.creativeTab); + this.setLightOpacity(1); + this.setDefaultState( + blockState.getBaseState() + .withProperty(CHECK_DECAY, true) + .withProperty(DECAYABLE, true) + .withProperty(VARIANT, Leaves3Variant.THORN) + ); + } + + @Override + public int getLightOpacity(IBlockState state) { + return TFConfig.performance.leavesLightOpacity; + } + + // [VanillaCopy] BlockLeavesNew.getMetaFromState - could subclass, but different VARIANT property + @Override + public int getMetaFromState(IBlockState state) { + int i = 0; + i |= state.getValue(VARIANT).ordinal(); + + if (!state.getValue(DECAYABLE)) { + i |= 4; + } + + if (state.getValue(CHECK_DECAY)) { + i |= 8; + } + + return i; + } + + // [VanillaCopy] BlockLeavesNew.getStateFromMeta - could subclass, but different VARIANT property + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + int variant = meta & 3; + final Leaves3Variant[] values = Leaves3Variant.values(); + + return getDefaultState() + .withProperty(VARIANT, values[variant % values.length]) + .withProperty(DECAYABLE, (meta & 4) == 0) + .withProperty(CHECK_DECAY, (meta & 8) > 0); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, CHECK_DECAY, DECAYABLE, VARIANT); + } + + @Override + public BlockPlanks.EnumType getWoodType(int meta) { + return BlockPlanks.EnumType.OAK; + } + + @Override + public ItemStack getItem(World world, BlockPos pos, IBlockState state) { + return new ItemStack(this, 1, state.getValue(VARIANT).ordinal()); + } + + @Override + public Item getItemDropped(IBlockState state, Random random, int fortune) { + return TFItems.magic_beans; } - public String[] func_150125_e() - { - return names; - } - - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @SideOnly(Side.CLIENT) - public int getRenderColor(int meta) - { - return (meta & 3) == 1 ? ColorizerFoliage.getFoliageColorPine() : ((meta & 3) == 2 ? ColorizerFoliage.getFoliageColorBirch() : super.getRenderColor(meta)); - } - - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @SideOnly(Side.CLIENT) - public int colorMultiplier(IBlockAccess world, int x, int y, int z) - { - int meta = world.getBlockMetadata(x, y, z); - return (meta & 3) == 1 ? ColorizerFoliage.getFoliageColorPine() : ((meta & 3) == 2 ? ColorizerFoliage.getFoliageColorBirch() : super.colorMultiplier(world, x, y, z)); - } - - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - public int damageDropped(int p_149692_1_) - { - return super.damageDropped(p_149692_1_) + 4; - } - - @Override - public boolean isOpaqueCube() - { - return Blocks.leaves.isOpaqueCube(); - } - - /** - * Get the block's damage value (for use with pick block). - */ - public int getDamageValue(World world, int x, int y, int z) - { - return world.getBlockMetadata(x, y, z) & 3; - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random rand) - { - return 0; - } - - /** - * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given - * coordinates. Args: blockAccess, x, y, z, side - */ - @Override - public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int side) - { - return Blocks.leaves.shouldSideBeRendered(iblockaccess, i, j, k, side); - } - - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return TFItems.magicBeans; - } - - @Override - public IIcon getIcon(int i, int j) - { - return Blocks.leaves.getIcon(i, 0 & 3); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - for (int i = 0; i < names.length; i++) { - par3List.add(new ItemStack(par1, 1, i)); - } - } + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + int n = Leaves3Variant.values().length; + for (int i = 0; i < n; i++) { + list.add(new ItemStack(this, 1, i)); + } + } @Override - public boolean canBeReplacedByLeaves(IBlockAccess world, int x, int y, int z) { + public boolean canBeReplacedByLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { return true; } - - + + @Override + public List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { + return NonNullList.withSize(1, new ItemStack(this, 1, world.getBlockState(pos).getValue(VARIANT).ordinal())); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + IStateMapper stateMapper = new StateMap.Builder().ignore(CHECK_DECAY, DECAYABLE).build(); + ModelLoader.setCustomStateMapper(this, stateMapper); + ModelUtils.registerToStateSingleVariant(this, VARIANT, stateMapper); + } + + @Override + public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face) { + return 60; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face) { + return 30; + } + + @Override + public ItemStack getSilkTouchDrop(IBlockState state) { + return new ItemStack(this, 1, state.getValue(VARIANT).ordinal()); + } } diff --git a/src/main/java/twilightforest/block/BlockTFLog.java b/src/main/java/twilightforest/block/BlockTFLog.java index 69959ab59f..0febf213cd 100644 --- a/src/main/java/twilightforest/block/BlockTFLog.java +++ b/src/main/java/twilightforest/block/BlockTFLog.java @@ -1,99 +1,118 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; import net.minecraft.block.BlockLog; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import twilightforest.TwilightForestMod; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.WoodVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFLog extends BlockLog { - - - public static IIcon sprOakSide; - public static IIcon sprOakTop; - public static IIcon sprCanopySide; - public static IIcon sprCanopyTop; - public static IIcon sprMangroveSide; - public static IIcon sprMangroveTop; - public static IIcon sprDarkwoodSide; - public static IIcon sprDarkwoodTop; - - //public static int sprRottenSide = 15; - + +public class BlockTFLog extends BlockLog implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", WoodVariant.class); + protected BlockTFLog() { - super(); this.setHardness(2.0F); - this.setStepSound(Block.soundTypeWood); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(this.getDefaultState().withProperty(LOG_AXIS, EnumAxis.Y)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT, LOG_AXIS); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + IBlockState iblockstate = this.getDefaultState().withProperty(VARIANT, WoodVariant.values()[meta & 3]); + + switch (meta & 0b1100) { + case 0: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.Y); + break; + case 4: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.X); + break; + case 8: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.Z); + break; + default: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE); + } + + return iblockstate; + } + + @Override + public int getMetaFromState(IBlockState state) { + int i = state.getValue(VARIANT).ordinal(); + + switch (state.getValue(LOG_AXIS)) { + case X: + i |= 4; + break; + case Y: + i |= 0; + break; + case Z: + i |= 8; + break; + case NONE: + i |= 12; + } + + return i; + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.getValue(VARIANT).supplyMapColor(); + } + + @Override + protected boolean canSilkHarvest() { + return false; + } + + @Override + public int damageDropped(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - int orient = meta & 12; - int woodType = meta & 3; - - switch (woodType) - { - default: - case 0 : - return orient == 0 && (side == 1 || side == 0) ? sprOakTop : (orient == 4 && (side == 5 || side == 4) ? sprOakTop : (orient == 8 && (side == 2 || side == 3) ? sprOakTop : sprOakSide)); - case 1 : - return orient == 0 && (side == 1 || side == 0) ? sprCanopyTop : (orient == 4 && (side == 5 || side == 4) ? sprCanopyTop : (orient == 8 && (side == 2 || side == 3) ? sprCanopyTop : sprCanopySide)); - case 2 : - return orient == 0 && (side == 1 || side == 0) ? sprMangroveTop : (orient == 4 && (side == 5 || side == 4) ? sprMangroveTop : (orient == 8 && (side == 2 || side == 3) ? sprMangroveTop : sprMangroveSide)); - case 3 : - return orient == 0 && (side == 1 || side == 0) ? sprDarkwoodTop : (orient == 4 && (side == 5 || side == 4) ? sprDarkwoodTop : (orient == 8 && (side == 2 || side == 3) ? sprDarkwoodTop : sprDarkwoodSide)); - } - } - - - @Override @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFLog.sprOakSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":oak_side"); - BlockTFLog.sprOakTop = par1IconRegister.registerIcon(TwilightForestMod.ID + ":oak_top"); - BlockTFLog.sprCanopySide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":canopy_side"); - BlockTFLog.sprCanopyTop = par1IconRegister.registerIcon(TwilightForestMod.ID + ":canopy_top"); - BlockTFLog.sprMangroveSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mangrove_side"); - BlockTFLog.sprMangroveTop = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mangrove_top"); - BlockTFLog.sprDarkwoodSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":darkwood_side"); - BlockTFLog.sprDarkwoodTop = par1IconRegister.registerIcon(TwilightForestMod.ID + ":darkwood_top"); - } - - - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return Item.getItemFromBlock(TFBlocks.log); // hey that's my block ID! - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); - } + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } + + @Override + public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing face) { + return 5; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face) { + return 5; + } } diff --git a/src/main/java/twilightforest/block/BlockTFMagicLeaves.java b/src/main/java/twilightforest/block/BlockTFMagicLeaves.java index 1fa2554fb3..7e02aef454 100644 --- a/src/main/java/twilightforest/block/BlockTFMagicLeaves.java +++ b/src/main/java/twilightforest/block/BlockTFMagicLeaves.java @@ -1,306 +1,174 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; import net.minecraft.block.BlockLeaves; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; import twilightforest.TwilightForestMod; +import twilightforest.enums.MagicWoodVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.client.particle.TFParticleType; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - - +import java.util.List; +import java.util.Random; -public class BlockTFMagicLeaves extends BlockLeaves { - - int oakColor = 0x48B518; - int canopyColor = 0x609860; - int mangroveColor = 0x80A755; - - public static final int META_TIME = 0; - public static final int META_TRANS = 1; - public static final int META_MINE = 2; - public static final int META_SORT = 3; - - public static IIcon SPR_TIMELEAVES; - public static IIcon SPR_TIMEFX; - public static IIcon SPR_TRANSLEAVES; - public static IIcon SPR_TRANSFX; - public static IIcon SPR_SORTLEAVES; - public static IIcon SPR_SORTFX; - +public class BlockTFMagicLeaves extends BlockLeaves implements ModelRegisterCallback { protected BlockTFMagicLeaves() { - super(); this.setHardness(0.2F); - this.setLightOpacity(2); - this.setStepSound(Block.soundTypeGrass); + this.setLightOpacity(1); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(CHECK_DECAY, true).withProperty(DECAYABLE, true) + .withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.TIME)); } - - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @Override - public int getRenderColor(int par1) - { - switch (par1 & 3) - { - case META_TIME : - return 106 << 16 | 156 << 8 | 23; - case META_TRANS : - return 108 << 16 | 204 << 8 | 234; - case META_MINE : - return 252 << 16 | 241 << 8 | 68; - case META_SORT : - return 54 << 16 | 76 << 8 | 3; - } - - return 16777215; - } + @Override + public int getLightOpacity(IBlockState state) { + return TFConfig.performance.leavesLightOpacity; + } - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @Override - public int colorMultiplier(IBlockAccess world, int x, int y, int z) - { - int leafType = world.getBlockMetadata(x, y, z) & 0x03; + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, BlockTFMagicLog.VARIANT, CHECK_DECAY, DECAYABLE); + } - int red = 0; - int green = 0; - int blue = 0; + @Override + public int getMetaFromState(IBlockState state) { + int i = 0; + i |= state.getValue(BlockTFMagicLog.VARIANT).ordinal(); - if (leafType == META_TIME) - { - int fade = x * 16 + y * 16 + z * 16; - if ((fade & 256) != 0) - { - fade = 255 - (fade & 255); - } - fade &= 255; - - float spring = (255 - fade) / 255F; - float fall = fade / 255F; - - red = (int) (spring * 106 + fall * 251); - green = (int) (spring * 156 + fall * 108); - blue = (int) (spring * 23 + fall * 27); - } - else if (leafType == META_MINE) - { - int fade = x * 31 + y * 33 + z * 32; - if ((fade & 256) != 0) - { - fade = 255 - (fade & 255); - } - fade &= 255; - - float spring = (255 - fade) / 255F; - float fall = fade / 255F; - - red = (int) (spring * 252 + fall * 237); - green = (int) (spring * 241 + fall * 172); - blue = (int) (spring * 68 + fall * 9); - } - else if (leafType == META_TRANS) - { - int fade = x * 27 + y * 63 + z * 39; - if ((fade & 256) != 0) - { - fade = 255 - (fade & 255); - } - fade &= 255; - - float spring = (255 - fade) / 255F; - float fall = fade / 255F; - - red = (int) (spring * 108 + fall * 96); - green = (int) (spring * 204 + fall * 107); - blue = (int) (spring * 234 + fall * 121); - } - else if (leafType == META_SORT) - { - int fade = x * 63 + y * 63 + z * 63; - if ((fade & 256) != 0) - { - fade = 255 - (fade & 255); - } - fade &= 255; - - float spring = (255 - fade) / 255F; - float fall = fade / 255F; - - red = (int) (spring * 54 + fall * 168); - green = (int) (spring * 76 + fall * 199); - blue = (int) (spring * 3 + fall * 43); - } - - return red << 16 | green << 8 | blue; + if (!state.getValue(DECAYABLE)) { + i |= 4; + } - } - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() { - return TwilightForestMod.proxy.getMagicLeavesBlockRenderID(); - } + if (state.getValue(CHECK_DECAY)) { + i |= 8; + } - /** - * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha - */ - @Override - public int getRenderBlockPass() - { - return 0; - } + return i; + } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ @Override - public boolean isOpaqueCube() - { - return false; - } + @Deprecated + public IBlockState getStateFromMeta(int meta) { + int variant = meta & 3; + final MagicWoodVariant[] values = MagicWoodVariant.values(); + + return getDefaultState() + .withProperty(BlockTFMagicLog.VARIANT, values[variant % values.length]) + .withProperty(DECAYABLE, (meta & 4) == 0) + .withProperty(CHECK_DECAY, (meta & 8) > 0); + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - switch (meta & 0x03) - { - default: - return SPR_TIMELEAVES; - case 1: - return SPR_TRANSLEAVES; - case 3: - return SPR_SORTLEAVES; - - } - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFMagicLeaves.SPR_TIMELEAVES = par1IconRegister.registerIcon(TwilightForestMod.ID + ":time_leaves"); - BlockTFMagicLeaves.SPR_TRANSLEAVES = par1IconRegister.registerIcon(TwilightForestMod.ID + ":trans_leaves"); - BlockTFMagicLeaves.SPR_SORTLEAVES = par1IconRegister.registerIcon(TwilightForestMod.ID + ":sort_leaves"); - } - + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); + } - /** - * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given - * coordinates. Args: blockAccess, x, y, z, side - */ - @Override - public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int side) - { - return Blocks.leaves.shouldSideBeRendered(iblockaccess, i, j, k, side); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) { + if (state.getValue(BlockTFMagicLog.VARIANT) == MagicWoodVariant.TRANS) { + for (int i = 0; i < 1; ++i) { + this.sparkleRunes(world, pos, random); + } + } + } - } + @Override + public BlockPlanks.EnumType getWoodType(int meta) { + return BlockPlanks.EnumType.OAK; + } - /** - * A randomly called display update to be able to add particles or other items for display - */ - @Override - public void randomDisplayTick(World par1World, int x, int y, int z, Random par5Random) - { - int meta = par1World.getBlockMetadata(x, y, z); + private void sparkleRunes(World world, BlockPos pos, Random rand) { + double offset = 0.0625D; - if ((meta & 3) == META_TRANS) - { - for (int i = 0; i < 1; ++i) { - this.sparkleRunes(par1World, x, y, z, par5Random); - } - } - } + EnumFacing side = EnumFacing.random(rand); + double rx = pos.getX() + rand.nextFloat(); + double ry = pos.getY() + rand.nextFloat(); + double rz = pos.getZ() + rand.nextFloat(); - /** - * The leaf sparkles. - */ - private void sparkleRunes(World world, int x, int y, int z, Random rand) - { - double offset = 0.0625D; + if (side == EnumFacing.DOWN && world.isAirBlock(pos.up())) { + ry = pos.getY() + 1 + offset; + } - int side = rand.nextInt(5) + 1; - double rx = x + rand.nextFloat(); - double ry = y + rand.nextFloat(); - double rz = z + rand.nextFloat(); + if (side == EnumFacing.UP && world.isAirBlock(pos.down())) { + ry = pos.getY() + 0 - offset; + } - if (side == 0 && world.isAirBlock(x, y + 1, z)) - { - ry = y + 1 + offset; - } + if (side == EnumFacing.NORTH && world.isAirBlock(pos.south())) { + rz = pos.getZ() + 1 + offset; + } - if (side == 1 && world.isAirBlock(x, y - 1, z)) - { - ry = y + 0 - offset; - } + if (side == EnumFacing.SOUTH && world.isAirBlock(pos.north())) { + rz = pos.getZ() + 0 - offset; + } - if (side == 2 && world.isAirBlock(x, y, z + 1)) - { - rz = z + 1 + offset; - } + if (side == EnumFacing.WEST && world.isAirBlock(pos.east())) { + rx = pos.getX() + 1 + offset; + } - if (side == 3 && world.isAirBlock(x, y, z - 1)) - { - rz = z + 0 - offset; - } + if (side == EnumFacing.EAST && world.isAirBlock(pos.west())) { + rx = pos.getX() + 0 - offset; + } + + if (rx < pos.getX() || rx > pos.getX() + 1 || ry < pos.getY() || ry > pos.getY() + 1 || rz < pos.getZ() || rz > pos.getZ() + 1) { + TwilightForestMod.proxy.spawnParticle(TFParticleType.LEAF_RUNE, rx, ry, rz, 0.0D, 0.0D, 0.0D); + } + } - if (side == 4 && world.isAirBlock(x + 1, y, z)) - { - rx = x + 1 + offset; - } + @Override + public List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { + return NonNullList.withSize(1, new ItemStack(this, 1, world.getBlockState(pos).getValue(BlockTFMagicLog.VARIANT).ordinal())); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + IStateMapper stateMapper = new StateMap.Builder().ignore(CHECK_DECAY, DECAYABLE).build(); + ModelLoader.setCustomStateMapper(this, stateMapper); + ModelUtils.registerToStateSingleVariant(this, BlockTFMagicLog.VARIANT, stateMapper); + } - if (side == 5 && world.isAirBlock(x - 1, y, z)) - { - rx = x + 0 - offset; - } + @Override + protected boolean canSilkHarvest() { + return false; + } - if (rx < x || rx > x + 1 || ry < y|| ry > y + 1 || rz < z || rz > z + 1) - { - TwilightForestMod.proxy.spawnParticle(world, "leafrune", rx, ry, rz, 0.0D, 0.0D, 0.0D); - } - } + @Override + public int damageDropped(IBlockState state) { + return state.getValue(BlockTFMagicLog.VARIANT).ordinal(); + } + @Override + public int quantityDropped(Random random) { + return 0; + } @Override - public String[] func_150125_e() { - // TODO Auto-generated method stub - return null; + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return Items.AIR; } + @Override + public void getDrops(NonNullList drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {} } diff --git a/src/main/java/twilightforest/block/BlockTFMagicLog.java b/src/main/java/twilightforest/block/BlockTFMagicLog.java index 1efdfd2020..192e72a6a7 100644 --- a/src/main/java/twilightforest/block/BlockTFMagicLog.java +++ b/src/main/java/twilightforest/block/BlockTFMagicLog.java @@ -1,131 +1,106 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; import net.minecraft.block.BlockLog; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.MagicWoodVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFMagicLog extends BlockLog { - - public static final int META_TIME = 0; - public static final int META_TRANS = 1; - public static final int META_MINE = 2; - public static final int META_SORT = 3; - - public static IIcon SPR_TIMESIDE; - public static IIcon SPR_TIMETOP; - public static IIcon SPR_TIMECLOCK; - public static IIcon SPR_TIMECLOCKOFF; - public static IIcon SPR_TRANSSIDE; - public static IIcon SPR_TRANSTOP; - public static IIcon SPR_TRANSHEART; - public static IIcon SPR_TRANSHEARTOFF; - public static IIcon SPR_MINESIDE; - public static IIcon SPR_MINETOP; - public static IIcon SPR_MINEGEM; - public static IIcon SPR_MINEGEMOFF; - public static IIcon SPR_SORTSIDE; - public static IIcon SPR_SORTTOP; - public static IIcon SPR_SORTEYE; - public static IIcon SPR_SORTEYEOFF; - - + +public class BlockTFMagicLog extends BlockLog implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", MagicWoodVariant.class); + protected BlockTFMagicLog() { - super(); this.setHardness(2.0F); - this.setStepSound(Block.soundTypeWood); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, MagicWoodVariant.TIME).withProperty(LOG_AXIS, EnumAxis.Y)); } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - int orient = meta & 12; - int woodType = meta & 3; - - switch (woodType) - { - default: - case META_TIME : - return orient == 0 && (side == 1 || side == 0) ? SPR_TIMETOP : (orient == 4 && (side == 5 || side == 4) ? SPR_TIMETOP : (orient == 8 && (side == 2 || side == 3) ? SPR_TIMETOP : SPR_TIMESIDE)); - case META_TRANS : - return orient == 0 && (side == 1 || side == 0) ? SPR_TRANSTOP : (orient == 4 && (side == 5 || side == 4) ? SPR_TRANSTOP : (orient == 8 && (side == 2 || side == 3) ? SPR_TRANSTOP : SPR_TRANSSIDE)); - case META_MINE : - return orient == 0 && (side == 1 || side == 0) ? SPR_MINETOP : (orient == 4 && (side == 5 || side == 4) ? SPR_MINETOP : (orient == 8 && (side == 2 || side == 3) ? SPR_MINETOP : SPR_MINESIDE)); - case META_SORT : - return orient == 0 && (side == 1 || side == 0) ? SPR_SORTTOP : (orient == 4 && (side == 5 || side == 4) ? SPR_SORTTOP : (orient == 8 && (side == 2 || side == 3) ? SPR_SORTTOP : SPR_SORTSIDE)); - } - - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFMagicLog.SPR_TIMESIDE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":time_side"); - BlockTFMagicLog.SPR_TIMETOP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":time_section"); - BlockTFMagicLog.SPR_TIMECLOCK = par1IconRegister.registerIcon(TwilightForestMod.ID + ":time_clock"); - BlockTFMagicLog.SPR_TIMECLOCKOFF = par1IconRegister.registerIcon(TwilightForestMod.ID + ":time_clock_off"); - BlockTFMagicLog.SPR_TRANSSIDE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":trans_side"); - BlockTFMagicLog.SPR_TRANSTOP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":trans_section"); - BlockTFMagicLog.SPR_TRANSHEART = par1IconRegister.registerIcon(TwilightForestMod.ID + ":trans_heart"); - BlockTFMagicLog.SPR_TRANSHEARTOFF = par1IconRegister.registerIcon(TwilightForestMod.ID + ":trans_heart_off"); - BlockTFMagicLog.SPR_MINESIDE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mine_side"); - BlockTFMagicLog.SPR_MINETOP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mine_section"); - BlockTFMagicLog.SPR_MINEGEM = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mine_gem"); - BlockTFMagicLog.SPR_MINEGEMOFF = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mine_gem_off"); - BlockTFMagicLog.SPR_SORTSIDE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":sort_side"); - BlockTFMagicLog.SPR_SORTTOP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":sort_section"); - BlockTFMagicLog.SPR_SORTEYE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":sort_eye"); - BlockTFMagicLog.SPR_SORTEYEOFF = par1IconRegister.registerIcon(TwilightForestMod.ID + ":sort_eye_off"); - } - - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return Item.getItemFromBlock(this); // hey that's my block ID! - } - - @Override - @SideOnly(Side.CLIENT) - /** - * A randomly called display update to be able to add particles or other items for display - */ - public void randomDisplayTick(World world, int x, int y, int z, Random rand) - { - - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT, LOG_AXIS); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + IBlockState iblockstate = this.getDefaultState().withProperty(VARIANT, MagicWoodVariant.values()[meta & 3]); + + switch (meta & 0b1100) { + case 0: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.Y); + break; + case 4: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.X); + break; + case 8: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.Z); + break; + default: + iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE); + } + + return iblockstate; + } + + @Override + public int getMetaFromState(IBlockState state) { + int i = state.getValue(VARIANT).ordinal(); + + switch (state.getValue(LOG_AXIS)) { + case X: + i |= 4; + break; + case Y: + i |= 0; + break; + case Z: + i |= 8; + break; + case NONE: + i |= 12; + } + + return i; + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.getValue(VARIANT).supplyMapColor(); + } + + @Override + protected boolean canSilkHarvest() { + return false; + } + @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); + public int damageDropped(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } - } - + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); + } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } } diff --git a/src/main/java/twilightforest/block/BlockTFMagicLogSpecial.java b/src/main/java/twilightforest/block/BlockTFMagicLogSpecial.java index 52c99e7836..a80de13827 100644 --- a/src/main/java/twilightforest/block/BlockTFMagicLogSpecial.java +++ b/src/main/java/twilightforest/block/BlockTFMagicLogSpecial.java @@ -1,477 +1,324 @@ package twilightforest.block; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.BlockChest; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryLargeChest; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.IBlockAccess; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.*; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldServer; -import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.biome.Biome; import net.minecraft.world.chunk.Chunk; -import twilightforest.TFGenericPacketHandler; -import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import twilightforest.network.TFPacketHandler; +import twilightforest.biomes.TFBiomes; import twilightforest.item.ItemTFOreMagnet; import twilightforest.item.TFItems; -import cpw.mods.fml.common.ObfuscationReflectionHelper; -import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFMagicLogSpecial extends BlockTFMagicLog -{ +import twilightforest.network.PacketChangeBiome; +import twilightforest.util.WorldUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class BlockTFMagicLogSpecial extends BlockTFMagicLog { + protected BlockTFMagicLogSpecial() { - super(); this.setCreativeTab(TFItems.creativeTab); } - - /** - * How many world ticks before ticking - */ + @Override - public int tickRate(World par1World) - { + public int tickRate(World world) { return 20; } - - /** - * Called whenever the block is added into the world. Args: world, x, y, z - */ - @Override - public void onBlockAdded(World par1World, int par2, int par3, int par4) - { - par1World.scheduleBlockUpdate(par2, par3, par4, this, this.tickRate(par1World)); - } - - - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return Item.getItemFromBlock(TFBlocks.magicLog); // change into normal magic log - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - int orient = meta & 12; - int woodType = meta & 3; - - if (orient == 12) - { - //off blocks - switch (woodType) - { - default: - case META_TIME : - return (side == 1 || side == 0) ? SPR_TIMETOP : SPR_TIMECLOCKOFF; - case META_TRANS : - return (side == 1 || side == 0) ? SPR_TRANSTOP : SPR_TRANSHEARTOFF; - case META_MINE : - return (side == 1 || side == 0) ? SPR_MINETOP : SPR_MINEGEMOFF; - case META_SORT : - return (side == 1 || side == 0) ? SPR_SORTTOP : SPR_SORTEYEOFF; - } - } - else - { - switch (woodType) - { - default: - case META_TIME : - return orient == 0 && (side == 1 || side == 0) ? SPR_TIMETOP : (orient == 4 && (side == 5 || side == 4) ? SPR_TIMETOP : (orient == 8 && (side == 2 || side == 3) ? SPR_TIMETOP : SPR_TIMECLOCK)); - case META_TRANS : - return orient == 0 && (side == 1 || side == 0) ? SPR_TRANSTOP : (orient == 4 && (side == 5 || side == 4) ? SPR_TRANSTOP : (orient == 8 && (side == 2 || side == 3) ? SPR_TRANSTOP : SPR_TRANSHEART)); - case META_MINE : - return orient == 0 && (side == 1 || side == 0) ? SPR_MINETOP : (orient == 4 && (side == 5 || side == 4) ? SPR_MINETOP : (orient == 8 && (side == 2 || side == 3) ? SPR_MINETOP : SPR_MINEGEM)); - case META_SORT : - return orient == 0 && (side == 1 || side == 0) ? SPR_SORTTOP : (orient == 4 && (side == 5 || side == 4) ? SPR_SORTTOP : (orient == 8 && (side == 2 || side == 3) ? SPR_SORTTOP : SPR_SORTEYE)); - } - } - } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World world, int x, int y, int z, Random rand) - { - int meta = world.getBlockMetadata(x, y, z); - - if ((meta & 12) == 12) - { - // block is off, do not tick - return; - } - - if ((meta & 3) == 0 && !world.isRemote) - { - // tree of time effect - world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.1F, 0.5F); - - doTreeOfTimeEffect(world, x, y, z, rand); - } - else if ((meta & 3) == 1 && !world.isRemote) - { - // tree of transformation effect - doTreeOfTransformationEffect(world, x, y, z, rand); - } - else if ((meta & 3) == 2 && !world.isRemote) - { - // miner's tree effect - doMinersTreeEffect(world, x, y, z, rand); - } - else if ((meta & 3) == 3 && !world.isRemote) - { - // sorting tree effect - doSortingTreeEffect(world, x, y, z, rand); - } - - - world.scheduleBlockUpdate(x, y, z, this, this.tickRate(world)); - - } - - /** - * Called upon block activation (right click on the block.) - */ - @Override - public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) - { - int meta = world.getBlockMetadata(x, y, z); - - int orient = meta & 12; - int woodType = meta & 3; - - if (orient == 0) - { - // turn off - world.setBlockMetadataWithNotify(x, y, z, woodType | 12, 3); - return true; - } - if (orient == 12) - { - // turn on - world.setBlockMetadataWithNotify(x, y, z, woodType | 0, 3); - world.scheduleBlockUpdate(x, y, z, this, this.tickRate(world)); - return true; - } - - return false; - } - - /** - * The tree of time adds extra ticks to blocks, so that they have twice the normal chance to get a random tick - */ - private void doTreeOfTimeEffect(World world, int x, int y, int z, Random rand) { + @Override + public void onBlockAdded(World world, BlockPos pos, IBlockState state) { + world.scheduleUpdate(pos, this, this.tickRate(world)); + } + + @Override + public Item getItemDropped(IBlockState state, Random random, int fortune) { + return Item.getItemFromBlock(TFBlocks.magic_log); + } + + @Override + public int damageDropped(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { + + if (world.isRemote || state.getValue(LOG_AXIS) != EnumAxis.NONE) return; + + switch (state.getValue(VARIANT)) { + case TIME: + world.playSound(null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.1F, 0.5F); + doTreeOfTimeEffect(world, pos, rand); + break; + case TRANS: + world.playSound(null, pos, SoundEvents.BLOCK_NOTE_HARP, SoundCategory.BLOCKS, 0.1F, rand.nextFloat() * 2F); + doTreeOfTransformationEffect(world, pos, rand); + break; + case MINE: + doMinersTreeEffect(world, pos, rand); + break; + case SORT: + doSortingTreeEffect(world, pos, rand); + break; + } + + world.scheduleUpdate(pos, this, this.tickRate(world)); + } + + @Override + public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + if (state.getValue(LOG_AXIS) != EnumAxis.NONE) { + world.setBlockState(pos, state.withProperty(LOG_AXIS, EnumAxis.NONE)); + world.scheduleUpdate(pos, this, this.tickRate(world)); + return true; + } else if (state.getValue(LOG_AXIS) == EnumAxis.NONE) { + world.setBlockState(pos, state.withProperty(LOG_AXIS, EnumAxis.Y)); + return true; + } + + return false; + } + + /** + * The tree of time adds extra ticks to blocks, so that they have twice the normal chance to get a random tick + */ + private void doTreeOfTimeEffect(World world, BlockPos pos, Random rand) { + int numticks = 8 * 3 * this.tickRate(world); - - int successes = 0; - - for (int i = 0; i < numticks; i++) - { - // find a nearby block - int dx = rand.nextInt(32) - 16; - int dy = rand.nextInt(32) - 16; - int dz = rand.nextInt(32) - 16; - - Block thereID = world.getBlock(x + dx, y + dy, z + dz); - - if (thereID != Blocks.air && thereID.getTickRandomly()) - { - thereID.updateTick(world, x + dx, y + dy, z + dz, rand); - - //System.out.println("tree of time ticked a block at " + (x + dx) + ", " + (y + dy) + ", " + (z + dz) + " and the block was " + Blocks.blocksList[thereID] ); - - successes++; + + for (int i = 0; i < numticks; i++) { + + BlockPos dPos = WorldUtil.randomOffset(rand, pos, 16); + + IBlockState state = world.getBlockState(dPos); + Block block = state.getBlock(); + + if (block != Blocks.AIR && block.getTickRandomly()) { + block.updateTick(world, dPos, state, rand); + } + + TileEntity te = world.getTileEntity(dPos); + if (te instanceof ITickable && !te.isInvalid()) { + ((ITickable) te).update(); } } - - //System.out.println("Tree of time had " + successes + " successes out of " + numticks + " attempts"); } /** * The tree of transformation transforms the biome in the area near it into the enchanted forest biome. - * + *

* TODO: also change entities */ - private void doTreeOfTransformationEffect(World world, int x, int y, int z, Random rand) { - for (int i = 0; i < 1; i++) - { - int dx = rand.nextInt(32) - 16; - int dz = rand.nextInt(32) - 16; - - world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "note.harp", 0.1F, rand.nextFloat() * 2F); - + private void doTreeOfTransformationEffect(World world, BlockPos pos, Random rand) { - if (Math.sqrt(dx * dx + dz * dz) < 16) - { - BiomeGenBase biomeAt = world.getBiomeGenForCoords(x + dx, z + dz); + Biome targetBiome = TFBiomes.enchantedForest; - if (biomeAt != TFBiomeBase.enchantedForest) - { - // I wonder how possible it is to change this + for (int i = 0; i < 16; i++) { - Chunk chunkAt = world.getChunkFromBlockCoords(x + dx, z + dz); + BlockPos dPos = WorldUtil.randomOffset(rand, pos, 16, 0, 16); + if (dPos.distanceSq(pos) > 256.0) continue; - chunkAt.getBiomeArray()[((z + dz) & 15) << 4 | ((x + dx) & 15)] = (byte)TFBiomeBase.enchantedForest.biomeID; + Biome biomeAt = world.getBiome(dPos); + if (biomeAt == targetBiome) continue; - world.markBlockForUpdate((x + dx), y, (z + dz)); - - //System.out.println("Set biome at " + (x + dx) + ", " + (z + dz) + " to enchanted forest."); - - // send chunk?! - - if (world instanceof WorldServer) - { - sendChangedBiome(world, x + dx, z + dz, chunkAt); - } - - } + Chunk chunkAt = world.getChunk(dPos); + chunkAt.getBiomeArray()[(dPos.getZ() & 15) << 4 | (dPos.getX() & 15)] = (byte) Biome.getIdForBiome(targetBiome); + if (world instanceof WorldServer) { + sendChangedBiome(world, dPos, targetBiome); } + break; } } /** * Send a tiny update packet to the client to inform it of the changed biome */ - private void sendChangedBiome(World world, int x, int z, Chunk chunkAt) { - FMLProxyPacket message = TFGenericPacketHandler.makeBiomeChangePacket(x, z, (byte)TFBiomeBase.enchantedForest.biomeID); - - NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.dimensionId, x, 128, z, 128); - - TwilightForestMod.genericChannel.sendToAllAround(message, targetPoint); - //FMLLog.info("Sent chunk update packet from tree."); - + private void sendChangedBiome(World world, BlockPos pos, Biome biome) { + IMessage message = new PacketChangeBiome(pos, biome); + NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 128); + TFPacketHandler.CHANNEL.sendToAllTracking(message, targetPoint); } /** * The miner's tree generates the ore magnet effect randomly every second */ - private void doMinersTreeEffect(World world, int x, int y, int z, Random rand) { - int dx = rand.nextInt(64) - 32; - int dy = rand.nextInt(64) - 32; - int dz = rand.nextInt(64) - 32; - + private void doMinersTreeEffect(World world, BlockPos pos, Random rand) { + + BlockPos dPos = WorldUtil.randomOffset(rand, pos, 32); + //world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.1F, 0.5F); - - - int moved = ItemTFOreMagnet.doMagnet(world, x, y, z, x + dx, y + dy, z + dz); - - if (moved > 0) - { - world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "mob.endermen.portal", 0.1F, 1.0F); - } - else - { - //System.out.println("Miner block did not find ore at " + (x + dx) + ", " + (y + dy) + ", " + (z + dz) + ", nope."); + + int moved = ItemTFOreMagnet.doMagnet(world, pos, dPos); + + if (moved > 0) { + world.playSound(null, pos, SoundEvents.ENTITY_ENDERMEN_TELEPORT, SoundCategory.BLOCKS, 0.1F, 1.0F); } } /** * The sorting tree finds two chests nearby and then attempts to sort a random item. */ - private void doSortingTreeEffect(World world, int x, int y, int z, Random rand) { + private void doSortingTreeEffect(World world, BlockPos pos, Random rand) { + // find all the chests nearby - int XSEARCH = 16; - int YSEARCH = 16; - int ZSEARCH = 16; - - ArrayList chests = new ArrayList(); + List chests = new ArrayList<>(); int itemCount = 0; - - for (int sx = x - XSEARCH; sx < x + XSEARCH; sx++) - { - for (int sy = y - YSEARCH; sy < y + YSEARCH; sy++) - { - for (int sz = z - ZSEARCH; sz < z + ZSEARCH; sz++) - { - if (world.getBlock(sx, sy, sz) == Blocks.chest) - { - IInventory thisChest = Blocks.chest.func_149951_m(world, sx, sy, sz); - - // make sure we haven't counted this chest - if (thisChest != null && !checkIfChestsContains(chests, (IInventory)world.getTileEntity(sx, sy, sz))) - { - int itemsInChest = 0; - - // count items - for (int i = 0; i < thisChest.getSizeInventory(); i++) - { - if (thisChest.getStackInSlot(i) != null) - { - itemsInChest++; - itemCount++; - } - } - - // only add non-empty chests - if (itemsInChest > 0) - { - chests.add(thisChest); - } - } + + for (BlockPos iterPos : WorldUtil.getAllAround(pos, 16)) { + + IInventory chestInventory = null, teInventory = null; + + Block block = world.getBlockState(iterPos).getBlock(); + if (block instanceof BlockChest) { + chestInventory = ((BlockChest) block).getContainer(world, iterPos, true); + } + + TileEntity te = world.getTileEntity(iterPos); + if (te instanceof IInventory && !te.isInvalid()) { + teInventory = (IInventory) te; + } + + // make sure we haven't counted this chest + if (chestInventory != null && teInventory != null && !checkIfChestsContains(chests, teInventory)) { + + boolean empty = true; + // count items + for (int i = 0; i < chestInventory.getSizeInventory(); i++) { + if (!chestInventory.getStackInSlot(i).isEmpty()) { + empty = false; + itemCount++; } } + + // only add non-empty chests + if (!empty) { + chests.add(chestInventory); + } } } - - //FMLLog.info("Found " + chests.size() + " non-empty chests, containing " + itemCount + " items"); - + + //TwilightForestMod.LOGGER.info("Found " + chests.size() + " non-empty chests, containing " + itemCount + " items"); + // find a random item in one of the chests - ItemStack beingSorted = null; + ItemStack beingSorted = ItemStack.EMPTY; int sortedChestNum = -1; int sortedSlotNum = -1; - - if (itemCount > 0) - { - int itemNumber = rand.nextInt(itemCount); - int currentNumber = 0; - - for (int i = 0; i < chests.size(); i++) - { - IInventory chest = chests.get(i); - for (int slotNum = 0; slotNum < chest.getSizeInventory(); slotNum++) - { - ItemStack currentItem = chest.getStackInSlot(slotNum); - - if (currentItem != null) - { - if (currentNumber++ == itemNumber) - { - beingSorted = currentItem; - sortedChestNum = i; - sortedSlotNum = slotNum; - } + + if (itemCount == 0) return; + + int itemNumber = rand.nextInt(itemCount); + int currentNumber = 0; + + for (int i = 0; i < chests.size(); i++) { + IInventory chest = chests.get(i); + for (int slotNum = 0; slotNum < chest.getSizeInventory(); slotNum++) { + ItemStack currentItem = chest.getStackInSlot(slotNum); + + if (!currentItem.isEmpty()) { + if (currentNumber++ == itemNumber) { + beingSorted = currentItem; + sortedChestNum = i; + sortedSlotNum = slotNum; } } } } - - //FMLLog.info("Decided to sort item " + beingSorted); - - if (beingSorted != null) - { - int matchChestNum = -1; - int matchCount = 0; - - // decide where to put it, if anywhere - for (int chestNum = 0; chestNum < chests.size(); chestNum++) - { - IInventory chest = chests.get(chestNum); - int currentChestMatches = 0; - - for (int slotNum = 0; slotNum < chest.getSizeInventory(); slotNum++) - { - - ItemStack currentItem = chest.getStackInSlot(slotNum); - if (currentItem != null && isSortingMatch(beingSorted, currentItem)) - { - currentChestMatches += currentItem.stackSize; - } - } - - if (currentChestMatches > matchCount) - { - matchCount = currentChestMatches; - matchChestNum = chestNum; + + //TwilightForestMod.LOGGER.info("Decided to sort item " + beingSorted); + + if (beingSorted.isEmpty()) return; + + int matchChestNum = -1; + int matchCount = 0; + + // decide where to put it, if anywhere + for (int chestNum = 0; chestNum < chests.size(); chestNum++) { + IInventory chest = chests.get(chestNum); + int currentChestMatches = 0; + + for (int slotNum = 0; slotNum < chest.getSizeInventory(); slotNum++) { + + ItemStack currentItem = chest.getStackInSlot(slotNum); + if (!currentItem.isEmpty() && isSortingMatch(beingSorted, currentItem)) { + currentChestMatches += currentItem.getCount(); } } - - // soooo, did we find a better match? - if (matchChestNum >= 0 && matchChestNum != sortedChestNum) - { - IInventory moveChest = chests.get(matchChestNum); - IInventory oldChest = chests.get(sortedChestNum); - - // is there an empty inventory slot in the new chest? - int moveSlot = getEmptySlotIn(moveChest); - - if (moveSlot >= 0) - { - // remove old item - oldChest.setInventorySlotContents(sortedSlotNum, null); - - // add new item - moveChest.setInventorySlotContents(moveSlot, beingSorted); - - //FMLLog.info("Moved sorted item " + beingSorted + " to chest " + matchChestNum + ", slot " + moveSlot); - } + + if (currentChestMatches > matchCount) { + matchCount = currentChestMatches; + matchChestNum = chestNum; } - - // if the stack is not full, combine items from other stacks - if (beingSorted.stackSize < beingSorted.getMaxStackSize()) - { - for (IInventory chest : chests) - { - for (int slotNum = 0; slotNum < chest.getSizeInventory(); slotNum++) - { - ItemStack currentItem = chest.getStackInSlot(slotNum); - - if (currentItem!= null && currentItem != beingSorted && beingSorted.isItemEqual(currentItem)) - { - if (currentItem.stackSize <= (beingSorted.getMaxStackSize() - beingSorted.stackSize)) - { - chest.setInventorySlotContents(slotNum, null); - beingSorted.stackSize += currentItem.stackSize; - currentItem.stackSize = 0; - } + } + + // soooo, did we find a better match? + if (matchChestNum >= 0 && matchChestNum != sortedChestNum) { + IInventory moveChest = chests.get(matchChestNum); + IInventory oldChest = chests.get(sortedChestNum); + + // is there an empty inventory slot in the new chest? + int moveSlot = getEmptySlotIn(moveChest); + + if (moveSlot >= 0) { + // remove old item + oldChest.setInventorySlotContents(sortedSlotNum, ItemStack.EMPTY); + + // add new item + moveChest.setInventorySlotContents(moveSlot, beingSorted); + + //TwilightForestMod.LOGGER.info("Moved sorted item " + beingSorted + " to chest " + matchChestNum + ", slot " + moveSlot); + } + } + + // if the stack is not full, combine items from other stacks + if (beingSorted.getCount() < beingSorted.getMaxStackSize()) { + for (IInventory chest : chests) { + for (int slotNum = 0; slotNum < chest.getSizeInventory(); slotNum++) { + ItemStack currentItem = chest.getStackInSlot(slotNum); + + if (!currentItem.isEmpty() && currentItem != beingSorted && beingSorted.isItemEqual(currentItem)) { + if (currentItem.getCount() <= (beingSorted.getMaxStackSize() - beingSorted.getCount())) { + chest.setInventorySlotContents(slotNum, ItemStack.EMPTY); + beingSorted.grow(currentItem.getCount()); + currentItem.setCount(0); } } } } - } } - private boolean isSortingMatch(ItemStack beingSorted, ItemStack currentItem) - { - return getCreativeTab(currentItem.getItem()) == getCreativeTab(beingSorted.getItem()); - } - - private Object getCreativeTab(Item item) - { - try { - return ObfuscationReflectionHelper.getPrivateValue(Item.class, item, 0); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (SecurityException e) { - e.printStackTrace(); - } - return null; + private boolean isSortingMatch(ItemStack beingSorted, ItemStack currentItem) { + return beingSorted.getItem().getCreativeTab() == currentItem.getItem().getCreativeTab(); } /** * Is the chest we're testing part of our chest list already? */ - private boolean checkIfChestsContains(ArrayList chests, IInventory testChest) { - for (IInventory chest : chests) - { - if (chest == testChest) - { + private boolean checkIfChestsContains(List chests, IInventory testChest) { + for (IInventory chest : chests) { + if (chest == testChest) { return true; } - - if (chest instanceof InventoryLargeChest && ((InventoryLargeChest)chest).isPartOfLargeChest(testChest)) - { + + if (chest instanceof InventoryLargeChest && ((InventoryLargeChest) chest).isPartOfLargeChest(testChest)) { return true; } } @@ -482,55 +329,36 @@ private boolean checkIfChestsContains(ArrayList chests, IInventory t * @return an empty slot number in the chest, or -1 if the chest is full */ private int getEmptySlotIn(IInventory chest) { - for (int i = 0; i < chest.getSizeInventory(); i++) - { - if (chest.getStackInSlot(i) == null) - { + for (int i = 0; i < chest.getSizeInventory(); i++) { + if (chest.getStackInSlot(i).isEmpty()) { return i; } } - + return -1; } @Override - @SideOnly(Side.CLIENT) - /** - * A randomly called display update to be able to add particles or other items for display - */ - public void randomDisplayTick(World world, int x, int y, int z, Random rand) - { - - } - - /** - * Get a light value for this block, normal ranges are between 0 and 15 - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return The light value - */ - @Override - public int getLightValue(IBlockAccess world, int x, int y, int z) - { - return 15; - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @Deprecated + public int getLightValue(IBlockState state) { + return 15; + } + @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); + } - } - + @Override + protected boolean canSilkHarvest() { + return false; + } - } + @Override + public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + return false; + } +} diff --git a/src/main/java/twilightforest/block/BlockTFMazestone.java b/src/main/java/twilightforest/block/BlockTFMazestone.java index 4cae304519..f2a1d3cd17 100644 --- a/src/main/java/twilightforest/block/BlockTFMazestone.java +++ b/src/main/java/twilightforest/block/BlockTFMazestone.java @@ -1,137 +1,88 @@ package twilightforest.block; -import java.util.List; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemTool; -import net.minecraft.util.IIcon; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.MazestoneVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.ItemTFMazebreakerPick; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - - /** - * * Mazestone mimics other types of stone in appearance, but is much harder to mine - * - * @author Ben * + * @author Ben */ -public class BlockTFMazestone extends Block { - - private static IIcon TEX_PLAIN; - private static IIcon TEX_BRICK; - private static IIcon TEX_PILLAR; - private static IIcon TEX_DECO; - private static IIcon TEX_CRACKED; - private static IIcon TEX_MOSSY; - private static IIcon TEX_MOSAIC; - private static IIcon TEX_BORDER; +public class BlockTFMazestone extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", MazestoneVariant.class); - /** - * Note that the texture called for here will only be used when the meta value is not a good block to mimic - * - * @param id - * @param texture - */ - public BlockTFMazestone() - { - super(Material.rock); - this.setHardness(100F); - this.setResistance(5F); - this.setStepSound(Block.soundTypeStone); + public BlockTFMazestone() { + super(Material.ROCK); + this.setHardness(100F); + this.setResistance(5F); + this.setSoundType(SoundType.STONE); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, MazestoneVariant.PLAIN)); + } - } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ @Override - public IIcon getIcon(int side, int meta) { - switch (meta) - { - case 0: - default: - return TEX_PLAIN; - case 1: - return TEX_BRICK; - case 2: - return side > 1 ? TEX_PILLAR : TEX_PLAIN; - case 3: - return side > 1 ? TEX_DECO : TEX_BRICK; - case 4: - return TEX_CRACKED; - case 5: - return TEX_MOSSY; - case 6: - return side > 1 ? TEX_BRICK : TEX_MOSAIC; - case 7: - return side > 1 ? TEX_BRICK : TEX_BORDER; - } + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); } @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFMazestone.TEX_PLAIN = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_plain"); - BlockTFMazestone.TEX_BRICK = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_brick"); - BlockTFMazestone.TEX_PILLAR = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_pillar"); - BlockTFMazestone.TEX_DECO = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_decorative"); - BlockTFMazestone.TEX_CRACKED = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_cracked"); - BlockTFMazestone.TEX_MOSSY = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_mossy"); - BlockTFMazestone.TEX_MOSAIC = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_mosaic"); - BlockTFMazestone.TEX_BORDER = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mazestone_border"); + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, MazestoneVariant.values()[meta]); } @Override - public void harvestBlock(World world, EntityPlayer entityplayer, int x, int y, int z, int meta) - { + public void onBlockHarvested(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + super.onBlockHarvested(world, pos, state, player); + ItemStack stack = player.getHeldItem(EnumHand.MAIN_HAND); + // damage the player's pickaxe - ItemStack cei = entityplayer.getCurrentEquippedItem(); - if(cei != null && cei.getItem() instanceof ItemTool && !(cei.getItem() instanceof ItemTFMazebreakerPick)) - { - cei.damageItem(16, entityplayer); - } - - super.harvestBlock(world, entityplayer, x, y, z, meta); - } - - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + if (!world.isRemote && !stack.isEmpty() && stack.getItem().isDamageable() && !(stack.getItem() instanceof ItemTFMazebreakerPick)) { + stack.damageItem(16, player); + } + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + for (MazestoneVariant variant : MazestoneVariant.values()) { + list.add(new ItemStack(this, 1, variant.ordinal())); + } + } + + @Override + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } + + @SideOnly(Side.CLIENT) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); - par3List.add(new ItemStack(par1, 1, 4)); - par3List.add(new ItemStack(par1, 1, 5)); - par3List.add(new ItemStack(par1, 1, 6)); - par3List.add(new ItemStack(par1, 1, 7)); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return meta; + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); } } diff --git a/src/main/java/twilightforest/block/BlockTFMiniatureStructure.java b/src/main/java/twilightforest/block/BlockTFMiniatureStructure.java new file mode 100644 index 0000000000..d3833c7ec5 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFMiniatureStructure.java @@ -0,0 +1,88 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.enums.StructureVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +public class BlockTFMiniatureStructure extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", StructureVariant.class); + + public BlockTFMiniatureStructure() { + super(Material.BARRIER); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, StructureVariant.TWILIGHT_PORTAL)); + } + + @Override + public boolean isOpaqueCube(IBlockState state) + { + return false; + } + + @Override + public boolean isFullCube(IBlockState state) + { + return false; + } + + @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, StructureVariant.values()[meta]); + } + + @Override + public void getSubBlocks(CreativeTabs tab, NonNullList list) { + for (StructureVariant variation : StructureVariant.values() ) { + list.add(new ItemStack(this, 1, variation.ordinal())); + } + } + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + for (StructureVariant variation : StructureVariant.values()) { + ModelLoader.setCustomModelResourceLocation( TFItems.miniature_structure, variation.ordinal(), new ModelResourceLocation(TwilightForestMod.ID + ":miniature_structure", "inventory_"+variation.getName())); + } + } +} diff --git a/src/main/java/twilightforest/block/BlockTFMoonworm.java b/src/main/java/twilightforest/block/BlockTFMoonworm.java index e0d0275703..f22fe59048 100644 --- a/src/main/java/twilightforest/block/BlockTFMoonworm.java +++ b/src/main/java/twilightforest/block/BlockTFMoonworm.java @@ -1,147 +1,70 @@ package twilightforest.block; -import java.util.Random; - +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.block.statemap.StateMap; +import net.minecraft.init.Items; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.EnumSkyBlock; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.tileentity.TileEntityTFMoonworm; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.tileentity.critters.TileEntityTFMoonwormTicking; + +import java.util.Random; -public class BlockTFMoonworm extends BlockTFCritter { +public class BlockTFMoonworm extends BlockTFCritter implements ModelRegisterCallback { - - public static int sprMoonworm = 52; - protected BlockTFMoonworm() { - super(); + this.setLightLevel(0.9375F); } - - /** - * How often do we check for incorrect lighting on fireflies, etc. - */ - public int tickRate() - { - return 50; - } - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - @Override - public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) - { - int facing = world.getBlockMetadata(x, y, z) & 7; - float wide = 0.25F; - if (facing == 1) - { - setBlockBounds(0.0F, 0.25F, 0.5F - wide, wide, 0.75F, 0.5F + wide); - } - else if(facing == 2) - { - setBlockBounds(1.0F - wide, 0.25F, 0.5F - wide, 1.0F, 0.75F, 0.5F + wide); - } - else if(facing == 3) - { - setBlockBounds(0.5F - wide, 0.25F, 0.0F, 0.5F + wide, 0.75F, wide); - } - else if(facing == 4) - { - setBlockBounds(0.5F - wide, 0.25F, 1.0F - wide, 0.5F + wide, 0.75F, 1.0F); - } - else if(facing == 5) - { - setBlockBounds(0.5F - wide, 0.0F, 0.25F, 0.5F + wide, wide, 0.75F); - } - else if(facing == 6) - { - setBlockBounds(0.5F - wide, 1.0F - wide, 0.25F, 0.5F + wide, 1.0F, 0.75F); - } - else - { - float f1 = 0.1F; - setBlockBounds(0.5F - f1, 0.0F, 0.5F - f1, 0.5F + f1, 0.6F, 0.5F + f1); - } - } - - /** - * Get a light value for this block, normal ranges are between 0 and 15 - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return The light value - */ @Override - public int getLightValue(IBlockAccess world, int x, int y, int z) { - return 14; + public float getWidth() { + return 0.25F; } + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + return TwilightForestMod.proxy.getNewMoonwormTE(); + } @Override - public TileEntity createTileEntity(World world, int metadata) { - return new TileEntityTFMoonworm(); - + protected boolean checkAndDrop(World world, BlockPos pos, IBlockState state) { + EnumFacing facing = state.getValue(BlockDirectional.FACING); + if (!canPlaceAt(world, pos.offset(facing.getOpposite()), facing)) { + world.destroyBlock(pos, false); + return false; + } + return true; } - - - /** - * Called whenever the block is added into the world. Args: world, x, y, z - */ + @Override - public void onBlockAdded(World world, int x, int y, int z) - { - super.onBlockAdded(world, x, y, z); - world.scheduleBlockUpdate(x, y, z, this, tickRate()); - } + public int quantityDropped(IBlockState state, int fortune, Random random) { + return 0; + } - /** - * Ticks the block if it's been scheduled - * Check the lighting and make the world relight it if it's incorrect. - */ - @Override - public void updateTick(World world, int x, int y, int z, Random random) - { - if (world.getBlockLightValue(x, y, z) < 12) { - //world.updateLightByType(EnumSkyBlock.Block, x, y, z); - //world.markBlockForUpdate(x, y, z); // do we need this now? - //System.out.println("Updating moonworm light value"); - // do another update to check that we got it right - world.scheduleBlockUpdate(x, y, z, this, tickRate()); - } + @Override + public ItemStack getSquishResult() { + return new ItemStack(Items.DYE, 1, EnumDyeColor.LIME.getDyeDamage()); } - - /** - * Don't drop anything - */ - @Override - public boolean dropCritterIfCantStay(World world, int x, int y, int z) - { - if(!canPlaceBlockAt(world, x, y, z)) - { - world.setBlockToAir(x, y, z); - return false; - } else - { - return true; - } - } - - /** - * Metadata and fortune sensitive version, this replaces the old (int meta, Random rand) - * version in 1.1. - * - * @param meta Blocks Metadata - * @param fortune Current item fortune level - * @param random Random number generator - * @return The number of items to drop - */ - @Override - public int quantityDropped(int meta, int fortune, Random random) - { - return 0; - } - + //Atomic: Forge would like to get rid of registerTESRItemStack, but there's no alternative yet (as at 1.11) + @SuppressWarnings("deprecation") + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomStateMapper(this, new StateMap.Builder().ignore(BlockDirectional.FACING).build()); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + ForgeHooksClient.registerTESRItemStack(Item.getItemFromBlock(this), 0, TileEntityTFMoonwormTicking.class); + } } diff --git a/src/main/java/twilightforest/block/BlockTFNagastone.java b/src/main/java/twilightforest/block/BlockTFNagastone.java index f9c6dac1cf..06dd0bcc62 100644 --- a/src/main/java/twilightforest/block/BlockTFNagastone.java +++ b/src/main/java/twilightforest/block/BlockTFNagastone.java @@ -1,811 +1,163 @@ package twilightforest.block; -import java.util.List; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.NonNullList; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.NagastoneVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFNagastone extends Block { +import javax.annotation.Nonnull; +import java.util.Random; - private static IIcon FACE_LEFT; - private static IIcon FACE_RIGHT; - private static IIcon CROSS_SECTION; - private static IIcon FACE_FRONT; - private static IIcon TOP_TIP; - private static IIcon TOP_LONG; - private static IIcon BOTTOM_TIP; - private static IIcon BOTTOM_LONG; - private static IIcon LEFT_DOWN; - private static IIcon RIGHT_DOWN; - private static IIcon LEFT_UP; - private static IIcon RIGHT_UP; - private static IIcon TIP_LEFT; - private static IIcon LONG_SIDE; - private static IIcon TIP_RIGHT; - private static IIcon TURN_TOP; +public class BlockTFNagastone extends Block implements ModelRegisterCallback { + public static final IProperty VARIANT = PropertyEnum.create("variant", NagastoneVariant.class); public BlockTFNagastone() { - super(Material.rock); - this.setHardness(1.5F); - this.setResistance(10.0F); - this.setStepSound(Block.soundTypeStone); + super(Material.ROCK); + this.setHardness(1.5F); + this.setResistance(10.0F); + this.setSoundType(SoundType.STONE); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, NagastoneVariant.SOLID)); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTabs, NonNullList stackList) { + stackList.add(new ItemStack(this, 1, 0)); + stackList.add(new ItemStack(this, 1, 1)); } - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getNagastoneBlockRenderID(); - } - -// /** -// * Called when the block is placed in the world. -// */ -// @Override -// public void onBlockPlacedBy(World par1World, int x, int y, int z, EntityLivingBase par5EntityLiving, ItemStack par6ItemStack) -// { -// int metadata = par1World.getBlockMetadata(x, y, z) & 12; -// int direction = 0; -// -// // first: are there two blocks, one up/down and one to the side? -// if (metadata > 0 && placePerfectFitBody(par1World, x, y, z)) -// { -// // we placed it, we're done -// //System.out.println("Found a perfect fit and placed it"); -// return; -// } -// else if (metadata == 0 && placePerfectFitHead(par1World, x, y, z)) -// { -// // we placed it, we're done -// return; -// } -// -// // get preliminary orientation as if we were placing a straight block -// int pistonOrient = BlockPistonBase.determineOrientation(par1World, x, y, z, par5EntityLiving); -// -// switch (pistonOrient) -// { -// case 0: -// case 1: -// direction = 2; -// break; -// case 2: -// case 3: -// direction = 1; -// break; -// case 4: -// case 5: -// direction = 0; -// } -// -// // if there is a block up or down and we are placing a straight block (that's not up and down), modify so we connect -// if (metadata > 0 && (direction == 0 || direction == 1) && par1World.getBlock(x, y - 1, z) == this) { -// metadata = 4; -// } -// if (metadata > 0 && (direction == 0 || direction == 1) && par1World.getBlock(x, y + 1, z) == this) { -// metadata = 8; -// } -// // if we have decided not to place a straight block, face the block in question towards the player -// if (metadata == 0 || metadata == 4 || metadata == 8) -// { -// direction = BlockTFNagastone.determineOrientation(par1World, x, y, z, (EntityPlayer)par5EntityLiving); -// } -// -// // if we are placing a block up and down, see if there is block to the side, and if so, modify to connect -// if (metadata > 0 && direction == 2) -// { -// int connect = getOnlyNSEWConnection(par1World, x, y, z); -// -// if (connect != -1) -// { -// // recall that pistonOrient variable to determine if we're connecting up or down -// metadata = pistonOrient == 0 ? 4 : 8; -// direction = connect; -// } -// } -// -// // if, after all this, we've decided to place a straight block, and there is only one place to connect it, connect it -// if (metadata == 12) -// { -// int connect = getOnlyConnection(par1World, x, y, z); -// //System.out.println("Trying to orient straight block. Connection = " + connect); -// -// -// if (connect != -1) -// { -// switch (connect) -// { -// case 0: -// case 1: -// direction = 1; -// break; -// case 2: -// case 3: -// direction = 0; -// break; -// case 4: -// case 5: -// direction = 2; -// } -// } -// } -// -// // I think we've covered it -// par1World.setBlockMetadataWithNotify(x, y, z, metadata | direction, 3); -// } - - /** - * Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY, hitZ, block metadata - * - * 0 - 3 head directions - * 4 - 7 bend down - * 8 - 11 bend up - * 12 straight n/s - * 13 straight e/w - * 14 straight u/d - * 15 weird middle piece - */ - @Override - public int onBlockPlaced(World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, int metadata) - { - int type = metadata & 12; - int orient = 0; - if (type == 0) - { - // head! - switch (side) { - case 0: - case 1: - default: - // don't know - orient = 1; - break; - case 2: - orient = 0; - break; - case 3: - orient = 1; - break; - case 4: - orient = 2; - break; - case 5: - orient = 3; - break; - } - } - if (type == 12) - { - // straight - switch (side) { - case 0: - case 1: - orient = 2; // u/d - break; - case 2: - case 3: - orient = 1; // e/w - break; - case 4: - case 5: - orient = 0; // n/s - break; - } - } - - return type | orient; - } - - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor blockID - */ - @Override - public void onNeighborBlockChange(World par1World, int x, int y, int z, Block neighborID) - { -// // is the block that changed nagastone? -// if (true || neighborID == this) { // this seems to be lies - int type = par1World.getBlockMetadata(x, y, z) & 12; - if (type == 0) - { - placePerfectFitHead(par1World, x, y, z); - } - else - { - placePerfectFitBody(par1World, x, y, z); - } - } - - /** - * Check if there is a perfect fit naga body block at the specified position, and if so, place it. - * - * A perfect fit is when there are two nagastone blocks in exactly two directions. - * - * TODO: and possibly the two other blocks should be "facing" this one? - */ - public boolean placePerfectFitBody(World world, int x, int y, int z) - { - int firstConnection = getPosibleConnection(world, x, y, z, -1, -1); - int secondConnection = getPosibleConnection(world, x, y, z, firstConnection, -1); - - // if we aren't connecting twice, fail - if (firstConnection == -1 || secondConnection == -1) - { - //System.out.println("Perfect fit failed because we did not find two connections"); - return false; - } - - // third connection == fail - if (getPosibleConnection(world, x, y, z, firstConnection, secondConnection) != -1) { - //System.out.println("Perfect fit failed because of 3 connections"); - return false; - } - - // place the perfect block - if ((firstConnection == 2 && secondConnection == 3) || (firstConnection == 3 && secondConnection == 2)){ - // e/w straight piece - world.setBlockMetadataWithNotify(x, y, z, 12, 3); - return true; - } - else if (firstConnection + secondConnection == 1){ - // n/s straight piece - world.setBlockMetadataWithNotify(x, y, z, 13, 3); - return true; - } - else if (firstConnection + secondConnection == 9){ - // up/down straight piece - world.setBlockMetadataWithNotify(x, y, z, 14, 3); - return true; - } - else if (firstConnection == 4) { - // curve up towards second connection - world.setBlockMetadataWithNotify(x, y, z, 4 | secondConnection, 3); - return true; - } - else if (firstConnection == 5) { - // curve down towards second connection - world.setBlockMetadataWithNotify(x, y, z, 8 | secondConnection, 3); - return true; - } - else if (secondConnection == 4) { - // curve up towards first connection - world.setBlockMetadataWithNotify(x, y, z, 4 | firstConnection, 3); - return true; - } - else if (secondConnection == 5) { - // curve down towards first connection - world.setBlockMetadataWithNotify(x, y, z, 8 | firstConnection, 3); - return true; - } - else - { - // block 15! - world.setBlockMetadataWithNotify(x, y, z, 15, 3); - return true; - } - } - - /** - * If we can place the perfect head bit, do it, otherwise do nothing. - */ - public boolean placePerfectFitHead(World world, int x, int y, int z) - { - int connect = getOnlyNSEWConnection(world, x, y, z); - - if (connect != -1) - { - // if the first connection is n/s/e/w, and the second connection is not, we win! - //System.out.println("Got a perfect head fit : " + connect); - switch (connect) - { - case 0 : - world.setBlock(x, y, z, this, 1, 3); - return true; - case 1 : - world.setBlock(x, y, z, this, 0, 3); - return true; - case 2 : - world.setBlock(x, y, z, this, 3, 3); - return true; - case 3 : - world.setBlock(x, y, z, this, 2, 3); - return true; - } - return false; // this is impossible - } - else - { - return false; - } - } - - /** - * Return a direction only if it is the only possible connection, otherwise return -1. This only returns n/s/e/w - */ - public int getOnlyNSEWConnection(World world, int x, int y, int z) - { - int firstConnection = getPosibleConnection(world, x, y, z, -1, -1); - int secondConnection = getPosibleConnection(world, x, y, z, firstConnection, -1); - - if (firstConnection > 0 && firstConnection < 4 && (secondConnection < 0 || secondConnection > 3)) - { - return firstConnection; - } - else - { - return -1; - } - - } - - /** - * Return a direction only if it is the only possible connection, otherwise return -1. - */ - public int getOnlyConnection(World world, int x, int y, int z) - { - int firstConnection = getPosibleConnection(world, x, y, z, -1, -1); - int secondConnection = getPosibleConnection(world, x, y, z, firstConnection, -1); - - if (firstConnection > 0 && firstConnection < 6 && secondConnection == -1) - { - return firstConnection; - } - else - { - return -1; - } - - } - - /** - * Return a direction we have found nagastone in, excluding the two exclude directions. - */ - public int getPosibleConnection(World world, int x, int y, int z, int exclude1, int exclude2) - { - for (int i = 0; i < 6; i++) - { - if (i != exclude1 && i != exclude2 && isNagaStoneInDirection(world, x, y, z, i)) - { - return i; - } - } - // none found - return -1; - } - - /** - * Is there nagastone in the following direction? 0 = n, 1 = s, 2 = w, 3 = e, 4 = u, 5 = d; - */ - public boolean isNagaStoneInDirection(World par1World, int x, int y, int z, int direction) - { - switch (direction) - { - case 0 : - return par1World.getBlock(x, y, z - 1) == this; - case 1 : - return par1World.getBlock(x, y, z + 1) == this; - case 2 : - return par1World.getBlock(x - 1, y, z) == this; - case 3 : - return par1World.getBlock(x + 1, y, z) == this; - case 4 : - return par1World.getBlock(x, y - 1, z) == this; - case 5 : - return par1World.getBlock(x, y + 1, z) == this; - } - // welp, - return false; - } - - /** - * Returns only 0-4. 0 = n, 1 = s, 2 = w, 3 = e. - */ - public static int determineOrientation(World par0World, int par1, int par2, int par3, EntityPlayer par4EntityPlayer) - { - int rot = MathHelper.floor_double(par4EntityPlayer.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; - return rot == 0 ? 0 : (rot == 1 ? 3 : (rot == 2 ? 1 : (rot == 3 ? 2 : 0))); - } + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - * - * 0 - 3 head directions - * 4 - 7 bend down - * 8 - 11 bend up - * 12 straight n/s - * 13 straight e/w - * 14 straight u/d - * 15 weird middle piece - * - * TODO: Surely there is a way to do this that's not just specifying all 6 * 16 values. - */ - @Override - public IIcon getIcon(int side, int meta) - { - int type = meta & 12; - int orient = meta & 3; - - if (type == 0) - { - if (orient == 0) - { - // north - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return TOP_TIP; - case 2: - return FACE_FRONT; - case 3: - return CROSS_SECTION; - case 4: - return FACE_LEFT; - case 5: - return FACE_RIGHT; - } - } - else if (orient == 1) - { - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return TOP_TIP; - case 2: - return CROSS_SECTION; - case 3: - return FACE_FRONT; - case 4: - return FACE_RIGHT; - case 5: - return FACE_LEFT; - } - } - else if (orient == 2) - { - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return TOP_TIP; - case 2: - return FACE_RIGHT; - case 3: - return FACE_LEFT; - case 4: - return FACE_FRONT; - case 5: - return CROSS_SECTION; - } - } - else if (orient == 3) - { - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return TOP_TIP; - case 2: - return FACE_LEFT; - case 3: - return FACE_RIGHT; - case 4: - return CROSS_SECTION; - case 5: - return FACE_FRONT; - } - } - } - - // TURN DOWN - if (type == 4) - { - if (orient == 0) - { - // north - switch (side) - { - case 0: - return CROSS_SECTION; - case 1: - return TOP_TIP; - case 2: - return CROSS_SECTION; - case 3: - return TIP_RIGHT; - case 4: - return LEFT_DOWN; - case 5: - return RIGHT_DOWN; - } - } - else if (orient == 1) - { - switch (side) - { - case 0: - return CROSS_SECTION; - case 1: - return TOP_TIP; - case 2: - return TIP_LEFT; - case 3: - return CROSS_SECTION; - case 4: - return RIGHT_DOWN; - case 5: - return LEFT_DOWN; - } - } - else if (orient == 2) - { - switch (side) - { - case 0: - return CROSS_SECTION; - case 1: - return TOP_TIP; - case 2: - return RIGHT_DOWN; - case 3: - return LEFT_DOWN; - case 4: - return CROSS_SECTION; - case 5: - return TIP_LEFT; - } - } - else if (orient == 3) - { - switch (side) - { - case 0: - return CROSS_SECTION; - case 1: - return TOP_TIP; - case 2: - return LEFT_DOWN; - case 3: - return RIGHT_DOWN; - case 4: - return TIP_RIGHT; - case 5: - return CROSS_SECTION; - } - } + @Nonnull + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(VARIANT, NagastoneVariant.values()[(meta & 15)]); + } + + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) { + world.scheduleUpdate(pos, this, this.tickRate(world)); + } - } - - if (type == 8) - { - // TURN UP - if (orient == 0) - { - // north - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return CROSS_SECTION; - case 2: - return CROSS_SECTION; - case 3: - return TIP_LEFT; - case 4: - return LEFT_UP; - case 5: - return RIGHT_UP; - } - } - else if (orient == 1) - { - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return CROSS_SECTION; - case 2: - return TIP_RIGHT; - case 3: - return CROSS_SECTION; - case 4: - return RIGHT_UP; - case 5: - return LEFT_UP; - } - } - else if (orient == 2) - { - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return CROSS_SECTION; - case 2: - return RIGHT_UP; - case 3: - return LEFT_UP; - case 4: - return CROSS_SECTION; - case 5: - return TIP_RIGHT; - } - } - else if (orient == 3) - { - switch (side) - { - case 0: - return BOTTOM_TIP; - case 1: - return CROSS_SECTION; - case 2: - return LEFT_UP; - case 3: - return RIGHT_UP; - case 4: - return TIP_LEFT; - case 5: - return CROSS_SECTION; - } - } + @Override + public void onBlockAdded(World world, BlockPos pos, IBlockState state) { + world.scheduleUpdate(pos, this, this.tickRate(world)); + } - } - - if (type == 12) - { - if (orient == 0) - { - // north - switch (side) - { - case 0: - return BOTTOM_LONG; - case 1: - return TOP_LONG; - case 2: - return LONG_SIDE; - case 3: - return LONG_SIDE; - case 4: - return CROSS_SECTION; - case 5: - return CROSS_SECTION; - } - } - else if (orient == 1) - { - switch (side) - { - case 0: - return BOTTOM_LONG; - case 1: - return TOP_LONG; - case 2: - return CROSS_SECTION; - case 3: - return CROSS_SECTION; - case 4: - return LONG_SIDE; - case 5: - return LONG_SIDE; - } - } - else if (orient == 2) - { - switch (side) - { - case 0: - return CROSS_SECTION; - case 1: - return CROSS_SECTION; - case 2: - return LONG_SIDE; - case 3: - return LONG_SIDE; - case 4: - return LONG_SIDE; - case 5: - return LONG_SIDE; - } - } - else if (orient == 3) - { - switch (side) - { - case 0: - return CROSS_SECTION; - case 1: - return TURN_TOP; - case 2: - return LONG_SIDE; - case 3: - return LONG_SIDE; - case 4: - return LONG_SIDE; - case 5: - return LONG_SIDE; - } - } + // Blockstate to meta 0-3 will be heads + // Blockstate to meta 4-15 will be body components + // BUT: + // Item meta 0 will be head + // Item meta 1 will be body + // todo fix getStateForPlacement to respect this + @Override + public int damageDropped(IBlockState state) { + return NagastoneVariant.isHead(state.getValue(VARIANT)) ? 0 : 1; + } - } - - return null; - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 13)); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return meta; -// // only drop meta 1 for head or 13 for body -// if (meta < 4) -// { -// return 1; -// } -// else -// { -// return 13; -// } + // Heads are manually placed, bodys are automatically connected + // If player places head on horz side of block, use that block face. Else, defer to player rotation. + @Nonnull + @Override + @Deprecated + public IBlockState getStateForPlacement(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing facing, float hitX, float hitY, float hitZ, int meta, @Nonnull EntityLivingBase placer) { + return meta == 0 + ? this.getDefaultState().withProperty(VARIANT, NagastoneVariant.getHeadFromFacing(facing.getAxis().isHorizontal() ? facing : placer.getHorizontalFacing().getOpposite())) + : this.getDefaultState(); } - - @Override + + @Override + public void updateTick(World world, BlockPos pos, IBlockState stateIn, Random rand) { + if (NagastoneVariant.isHead(stateIn.getValue(VARIANT))) + return; + + // If state is not a head then you may go ahead and update + int connectionCount = 0; + IBlockState stateOut; + EnumFacing[] facings = new EnumFacing[2]; + + // get sides + for (EnumFacing side : EnumFacing.VALUES) + if (world.getBlockState(pos.offset(side)).getBlock() == TFBlocks.naga_stone) + if (++connectionCount > 2) break; + else facings[connectionCount - 1] = side; + + + // if there are 2 sides that don't line on same axis, use an elbow part, else use axis part + // if there is 1 side, then use an axis part + // if there are 0 or greater than 2 sides, use solid + // use default if there are more than 3 connections or 0 + switch (connectionCount) { + case 1: + facings[1] = facings[0]; // No null, for next statement + case 2: + stateOut = stateIn.withProperty(VARIANT, NagastoneVariant.getVariantFromDoubleFacing(facings[0], facings[1])); + break; + default: + stateOut = this.getDefaultState(); + break; + } + + // if result matches state in world, no need to add more effort + if (stateIn != stateOut) world.setBlockState(pos, stateOut); + } + + @Nonnull + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFNagastone.FACE_LEFT = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_face_left"); - BlockTFNagastone.FACE_RIGHT = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_face_right"); - BlockTFNagastone.CROSS_SECTION = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_cross_section"); - BlockTFNagastone.FACE_FRONT = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_face_front"); - BlockTFNagastone.TOP_TIP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_top_tip"); - BlockTFNagastone.TOP_LONG = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_tip_long"); - BlockTFNagastone.BOTTOM_TIP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_bottom_tip"); - BlockTFNagastone.BOTTOM_LONG = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_bottom_long"); - BlockTFNagastone.LEFT_DOWN = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_left_down"); - BlockTFNagastone.RIGHT_DOWN = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_right_down"); - BlockTFNagastone.LEFT_UP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_left_up"); - BlockTFNagastone.RIGHT_UP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_right_up"); - BlockTFNagastone.TIP_LEFT = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_tip_left"); - BlockTFNagastone.LONG_SIDE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_long_side"); - BlockTFNagastone.TIP_RIGHT = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_tip_right"); - BlockTFNagastone.TURN_TOP = par1IconRegister.registerIcon(TwilightForestMod.ID + ":nagastone_turn_top"); - } + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, this.getDefaultState().withProperty(VARIANT, NagastoneVariant.EAST_HEAD)); + ModelUtils.registerToState(this, 1, this.getDefaultState().withProperty(VARIANT, NagastoneVariant.AXIS_X)); + } + @Override + public IBlockState withRotation(IBlockState state, Rotation rotation) { + return state.withProperty(VARIANT, NagastoneVariant.rotate(state.getValue(VARIANT), rotation)); + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirror) { + return state.withProperty(VARIANT, NagastoneVariant.mirror(state.getValue(VARIANT), mirror)); + } + + @Override + protected boolean canSilkHarvest() { + return false; + } + + @Override + public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + return false; + } } diff --git a/src/main/java/twilightforest/block/BlockTFNagastoneEtched.java b/src/main/java/twilightforest/block/BlockTFNagastoneEtched.java new file mode 100644 index 0000000000..0484554b87 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFNagastoneEtched.java @@ -0,0 +1,70 @@ +package twilightforest.block; + +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.item.TFItems; + +public class BlockTFNagastoneEtched extends BlockDirectional implements ModelRegisterCallback { + protected BlockTFNagastoneEtched() { + super(Material.ROCK); + this.setSoundType(SoundType.STONE); + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.DOWN)); + } + + @Override + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return this.getDefaultState().withProperty(FACING, placer.isSneaking() ? facing.getOpposite() : facing); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(FACING, EnumFacing.values()[meta % EnumFacing.values().length]); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(FACING).ordinal(); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING); + } + + @Override + public IBlockState withRotation(IBlockState state, Rotation rot) { + return state.withProperty(FACING, rot.rotate(state.getValue(FACING))); + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { + return state.withProperty(FACING, mirrorIn.mirror(state.getValue(FACING))); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, this.getDefaultState()); + } + + @Override + protected ItemStack getSilkTouchDrop(IBlockState state) { + return new ItemStack(Item.getItemFromBlock(this)); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFNagastonePillar.java b/src/main/java/twilightforest/block/BlockTFNagastonePillar.java new file mode 100644 index 0000000000..9a2bb92b74 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFNagastonePillar.java @@ -0,0 +1,29 @@ +package twilightforest.block; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.item.TFItems; + +/** + * Created by Drullkus on 12/12/17. + */ +public class BlockTFNagastonePillar extends BlockTFDirectionalRotatedPillar implements ModelRegisterCallback { + + protected BlockTFNagastonePillar() { + super(Material.ROCK); + this.setSoundType(SoundType.STONE); + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(this.blockState.getBaseState().withProperty(AXIS, EnumFacing.Axis.Y).withProperty(REVERSED, false)); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, this.getDefaultState()); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFNagastoneStairs.java b/src/main/java/twilightforest/block/BlockTFNagastoneStairs.java new file mode 100644 index 0000000000..d40f3f7c68 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFNagastoneStairs.java @@ -0,0 +1,83 @@ +package twilightforest.block; + +import net.minecraft.block.BlockStairs; +import net.minecraft.block.SoundType; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.Mirror; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.item.TFItems; + +import java.util.Locale; + +public class BlockTFNagastoneStairs extends BlockStairs implements ModelRegisterCallback { + + public static final IProperty DIRECTION = PropertyEnum.create("direction", LeftRight.class); + + BlockTFNagastoneStairs(IBlockState state) { + super(state); + this.setSoundType(SoundType.STONE); + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(this.getDefaultState().withProperty(DIRECTION, LeftRight.LEFT)); + this.useNeighborBrightness = true; + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING, HALF, SHAPE, DIRECTION); + } + + @Override + public int getMetaFromState(IBlockState state) { + return super.getMetaFromState(state) + (state.getValue(DIRECTION) == LeftRight.RIGHT ? 8 : 0); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return super.getStateFromMeta(meta & 0b0111).withProperty(DIRECTION, (meta & 0b1000) == 8 ? LeftRight.RIGHT : LeftRight.LEFT); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 8)); + } + + @Override + public int damageDropped(IBlockState state) { + return state.getValue(DIRECTION) == LeftRight.RIGHT ? 8 : 0; + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { + return super.withMirror(state, mirrorIn).withProperty(DIRECTION, state.getValue(DIRECTION) == LeftRight.LEFT ? LeftRight.RIGHT : LeftRight.LEFT); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, getDefaultState().withProperty(FACING, EnumFacing.EAST)); + ModelUtils.registerToState(this, 8, getDefaultState().withProperty(FACING, EnumFacing.EAST).withProperty(DIRECTION, LeftRight.RIGHT)); + } + + private enum LeftRight implements IStringSerializable { + LEFT, + RIGHT; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + } +} diff --git a/src/main/java/twilightforest/block/BlockTFPillar.java b/src/main/java/twilightforest/block/BlockTFPillar.java new file mode 100644 index 0000000000..4951697df1 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFPillar.java @@ -0,0 +1,17 @@ +package twilightforest.block; + +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.material.Material; +import net.minecraft.util.EnumFacing; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +public class BlockTFPillar extends BlockRotatedPillar implements ModelRegisterCallback { + + protected BlockTFPillar(Material material) { + super(material); + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(this.blockState.getBaseState().withProperty(AXIS, EnumFacing.Axis.Y)); + } + +} diff --git a/src/main/java/twilightforest/block/BlockTFPlant.java b/src/main/java/twilightforest/block/BlockTFPlant.java index f6ee5a0da0..751da9642e 100644 --- a/src/main/java/twilightforest/block/BlockTFPlant.java +++ b/src/main/java/twilightforest/block/BlockTFPlant.java @@ -1,325 +1,206 @@ package twilightforest.block; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; import net.minecraft.block.BlockBush; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; -import net.minecraft.world.ColorizerFoliage; -import net.minecraft.world.ColorizerGrass; -import net.minecraft.world.EnumSkyBlock; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.EnumPlantType; import net.minecraftforge.common.IShearable; -import net.minecraftforge.common.util.ForgeDirection; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.particle.TFParticleFactory; +import twilightforest.client.particle.TFParticleType; +import twilightforest.enums.PlantVariant; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFPlant extends BlockBush implements IShearable { - - boolean[] isGrassColor = {false, false, false, false, true, true, false, false, true, false, true, false, false, false, false, false}; - int[] lightValue = {0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0}; - - private IIcon[] icons; - private String[] iconNames = new String[] {null, null, null, "mosspatch", "mayapple", "cloverpatch", null, null, "fiddlehead", "mushgloom", null, null, null, "torchberry", "rootstrand", null}; - public static IIcon mayappleSide; - - public static final int META_MOSSPATCH = 3; - public static final int META_MAYAPPLE = 4; - public static final int META_CLOVERPATCH = 5; - public static final int META_FIDDLEHEAD = 8; - public static final int META_MUSHGLOOM = 9; - public static final int META_FORESTGRASS = 10; - public static final int META_DEADBUSH = 11; - public static final int META_TORCHBERRY = 13; - public static final int META_ROOT_STRAND = 14; - - + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Random; + +public class BlockTFPlant extends BlockBush implements IShearable, ModelRegisterCallback { + public static final IProperty VARIANT = PropertyEnum.create("variant", PlantVariant.class); + protected BlockTFPlant() { - super(Material.plants); - this.setTickRandomly(true); - float var3 = 0.4F; - this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, 0.8F, 0.5F + var3); - this.setHardness(0.0F); - this.setStepSound(Block.soundTypeGrass); + super(Material.PLANTS); + this.setTickRandomly(true); + this.setHardness(0.0F); + this.setSoundType(SoundType.PLANT); this.setCreativeTab(TFItems.creativeTab); } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int metadata) - { - return this.icons[metadata]; - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.icons = new IIcon[iconNames.length]; - - for (int i = 0; i < this.icons.length; ++i) - { - if (this.iconNames[i] != null) - { - this.icons[i] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + iconNames[i]); - } - } - - this.icons[META_FORESTGRASS] = Blocks.tallgrass.getIcon(2, 1); - this.icons[META_DEADBUSH] = Blocks.deadbush.getBlockTextureFromSide(2); - - BlockTFPlant.mayappleSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":mayapple_side"); - } - @Override - public int getBlockColor() - { - double var1 = 0.5D; - double var3 = 1.0D; - return ColorizerGrass.getGrassColor(var1, var3); - } - - /** - * Schedule an update to try to get lighting right - */ @Override - public void onBlockAdded(World world, int i, int j, int k) { - world.scheduleBlockUpdate(i, j, k, this, world.rand.nextInt(50) + 20); + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + PlantVariant variant = PlantVariant.values()[MathHelper.clamp(meta, 0, PlantVariant.values().length)]; + return getDefaultState().withProperty(VARIANT, variant); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + public void onBlockAdded(World world, BlockPos pos, IBlockState state) { + world.scheduleUpdate(pos, this, world.rand.nextInt(50) + 20); + } + + @Override + public boolean canPlaceBlockAt(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + return (state.getBlock().isAir(state, world, pos) || state.getMaterial().isReplaceable()) && canBlockStay(world, pos, state); + } + + @Override + public boolean canBlockStay(World world, BlockPos pos, IBlockState state) { + IBlockState soil = world.getBlockState(pos.down()); + + /* + Comment from superclass: + Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. + Therefore, we just take the OR of all the conditions below as the most general "can block stay" check + */ + if (state.getBlock() != this) { + return BlockTFPlant.canPlaceRootAt(world, pos) + || soil.getBlock().canSustainPlant(soil, world, pos.down(), EnumFacing.UP, this) + || soil.isSideSolid(world, pos, EnumFacing.UP) + || ((world.getLight(pos) >= 3 || world.canSeeSky(pos)) && soil.getBlock().canSustainPlant(soil, world, pos.down(), EnumFacing.UP, this)); + } else { + switch (state.getValue(VARIANT)) { + case TORCHBERRY: + case ROOT_STRAND: + return BlockTFPlant.canPlaceRootAt(world, pos); + case FORESTGRASS: + case DEADBUSH: + return soil.getBlock().canSustainPlant(soil, world, pos.down(), EnumFacing.UP, this); + case FALLEN_LEAVES: + case MUSHGLOOM: + case MOSSPATCH: + return soil.isSideSolid(world, pos, EnumFacing.UP); + default: + return (world.getLight(pos) >= 3 || world.canSeeSky(pos)) && soil.getBlock().canSustainPlant(soil, world, pos.down(), EnumFacing.UP, this); + } + } + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess access, BlockPos pos) { + PlantVariant variant = state.getValue(VARIANT); + + long seed = pos.getX() * 3129871 ^ pos.getY() * 116129781L ^ pos.getZ(); + seed = seed * seed * 42317861L + seed * 11L; + + if (variant == PlantVariant.MOSSPATCH) { + int xOff0 = (int) (seed >> 12 & 3L); + int xOff1 = (int) (seed >> 15 & 3L); + int zOff0 = (int) (seed >> 18 & 3L); + int zOff1 = (int) (seed >> 21 & 3L); + + boolean xConnect0 = access.getBlockState(pos.east()).getBlock() == this && access.getBlockState(pos.east()).getValue(VARIANT) == PlantVariant.MOSSPATCH; + boolean xConnect1 = access.getBlockState(pos.west()).getBlock() == this && access.getBlockState(pos.west()).getValue(VARIANT) == PlantVariant.MOSSPATCH; + boolean zConnect0 = access.getBlockState(pos.south()).getBlock() == this && access.getBlockState(pos.south()).getValue(VARIANT) == PlantVariant.MOSSPATCH; + boolean zConnect1 = access.getBlockState(pos.north()).getBlock() == this && access.getBlockState(pos.north()).getValue(VARIANT) == PlantVariant.MOSSPATCH; + + return new AxisAlignedBB(xConnect1 ? 0F : (1F + xOff1) / 16F, 0.0F, zConnect1 ? 0F : (1F + zOff1) / 16F, + xConnect0 ? 1F : (15F - xOff0) / 16F, 1F / 16F, zConnect0 ? 1F : (15F - zOff0) / 16F); + + } else if (variant == PlantVariant.CLOVERPATCH) { + int xOff0 = (int) (seed >> 12 & 3L); + int xOff1 = (int) (seed >> 15 & 3L); + int zOff0 = (int) (seed >> 18 & 3L); + int zOff1 = (int) (seed >> 21 & 3L); + + int yOff0 = (int) (seed >> 24 & 1L); + int yOff1 = (int) (seed >> 27 & 1L); + + boolean xConnect0 = access.getBlockState(pos.east()).getBlock() == this && access.getBlockState(pos.east()).getValue(VARIANT) == PlantVariant.CLOVERPATCH; + boolean xConnect1 = access.getBlockState(pos.west()).getBlock() == this && access.getBlockState(pos.west()).getValue(VARIANT) == PlantVariant.CLOVERPATCH; + boolean zConnect0 = access.getBlockState(pos.south()).getBlock() == this && access.getBlockState(pos.south()).getValue(VARIANT) == PlantVariant.CLOVERPATCH; + boolean zConnect1 = access.getBlockState(pos.north()).getBlock() == this && access.getBlockState(pos.north()).getValue(VARIANT) == PlantVariant.CLOVERPATCH; + + return new AxisAlignedBB(xConnect1 ? 0F : (1F + xOff1) / 16F, 0.0F, zConnect1 ? 0F : (1F + zOff1) / 16F, + xConnect0 ? 1F : (15F - xOff0) / 16F, (1F + yOff0 + yOff1) / 16F, zConnect0 ? 1F : (15F - zOff0) / 16F); + } else if (variant == PlantVariant.MAYAPPLE) { + return new AxisAlignedBB(4F / 16F, 0, 4F / 16F, 13F / 16F, 6F / 16F, 13F / 16F); + } else if (variant == PlantVariant.FALLEN_LEAVES) { + return new AxisAlignedBB(0F, 0F, 0F, 1F, 1F / 16F, 1F); + } else { + return FULL_BLOCK_AABB; + } } - - @Override - public boolean canReplace(World par1World, int x, int y, int z, int par5, ItemStack par6ItemStack) - { - // we need to get the metadata - Block blockAt = par1World.getBlock(x, y, z); - - return (blockAt == Blocks.air || blockAt.getMaterial().isReplaceable()) && canBlockStay(par1World, x, y, z, par6ItemStack.getItemDamage()); - } - - /** - * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. - */ - @Override - public boolean canBlockStay(World world, int x, int y, int z) { - int meta = world.getBlockMetadata(x, y, z); - - return canBlockStay(world, x, y, z, meta); - } - - /** - * Can this block stay at this position? with metadata - */ - public boolean canBlockStay(World world, int x, int y, int z, int meta) { - - //System.out.println("Can block stay? meta is " + meta); - Block soil = world.getBlock(x, y - 1, z); - - switch (meta) { - case META_TORCHBERRY : - case META_ROOT_STRAND : - return BlockTFPlant.canPlaceRootBelow(world, x, y + 1, z); - case 0: // let's make this happen - case META_FORESTGRASS: - case META_DEADBUSH: - return (soil != null && soil.canSustainPlant(world, x, y - 1, z, ForgeDirection.UP, this)); - case META_MUSHGLOOM: - case META_MOSSPATCH: - return soil != null && soil.isSideSolid(world, x, y, z, ForgeDirection.UP); - default : - return (world.getFullBlockLightValue(x, y, z) >= 3 || world.canBlockSeeTheSky(x, y, z)) && - (soil != null && soil.canSustainPlant(world, x, y - 1, z, ForgeDirection.UP, this)); - } - } - - - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - @Override - public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int meta = par1IBlockAccess.getBlockMetadata(x, y, z); - - if (meta == META_MOSSPATCH) - { - long seed = x * 3129871 ^ y * 116129781L ^ z; - seed = seed * seed * 42317861L + seed * 11L; - - int xOff0 = (int) (seed >> 12 & 3L); - int xOff1 = (int) (seed >> 15 & 3L); - int zOff0 = (int) (seed >> 18 & 3L); - int zOff1 = (int) (seed >> 21 & 3L); - - boolean xConnect0 = par1IBlockAccess.getBlock(x + 1, y, z) == this && par1IBlockAccess.getBlockMetadata(x + 1, y, z) == META_MOSSPATCH; - boolean xConnect1 = par1IBlockAccess.getBlock(x - 1, y, z) == this && par1IBlockAccess.getBlockMetadata(x - 1, y, z) == META_MOSSPATCH; - boolean zConnect0 = par1IBlockAccess.getBlock(x, y, z + 1) == this && par1IBlockAccess.getBlockMetadata(x, y, z + 1) == META_MOSSPATCH; - boolean zConnect1 = par1IBlockAccess.getBlock(x, y, z - 1) == this && par1IBlockAccess.getBlockMetadata(x, y, z - 1) == META_MOSSPATCH; - - this.setBlockBounds(xConnect1 ? 0F : (1F + xOff1) / 16F, 0.0F, zConnect1 ? 0F : (1F + zOff1) / 16F, - xConnect0 ? 1F : (15F - xOff0) / 16F, 1F / 16F, zConnect0 ? 1F : (15F - zOff0) / 16F); - - } - else if (meta == META_CLOVERPATCH) - { - long seed = x * 3129871 ^ y * 116129781L ^ z; - seed = seed * seed * 42317861L + seed * 11L; - - int xOff0 = (int) (seed >> 12 & 3L); - int xOff1 = (int) (seed >> 15 & 3L); - int zOff0 = (int) (seed >> 18 & 3L); - int zOff1 = (int) (seed >> 21 & 3L); - - int yOff0 = (int) (seed >> 24 & 1L); - int yOff1 = (int) (seed >> 27 & 1L); - - - boolean xConnect0 = par1IBlockAccess.getBlock(x + 1, y, z) == this && par1IBlockAccess.getBlockMetadata(x + 1, y, z) == META_CLOVERPATCH; - boolean xConnect1 = par1IBlockAccess.getBlock(x - 1, y, z) == this && par1IBlockAccess.getBlockMetadata(x - 1, y, z) == META_CLOVERPATCH; - boolean zConnect0 = par1IBlockAccess.getBlock(x, y, z + 1) == this && par1IBlockAccess.getBlockMetadata(x, y, z + 1) == META_CLOVERPATCH; - boolean zConnect1 = par1IBlockAccess.getBlock(x, y, z - 1) == this && par1IBlockAccess.getBlockMetadata(x, y, z - 1) == META_CLOVERPATCH; - - this.setBlockBounds(xConnect1 ? 0F : (1F + xOff1) / 16F, 0.0F, zConnect1 ? 0F : (1F + zOff1) / 16F, - xConnect0 ? 1F : (15F - xOff0) / 16F, (1F + yOff0 + yOff1) / 16F, zConnect0 ? 1F : (15F - zOff0) / 16F); - - //this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 2F / 16F, 1.0F); - } - else if (meta == META_MAYAPPLE) - { - this.setBlockBounds(4F / 16F, 0, 4F / 16F, 13F / 16F, 6F / 16F, 13F / 16F); - } - else - { - this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - } - } - - - /** - * Returns the color this block should be rendered. Used by leaves. - */ - @Override - public int getRenderColor(int par1) - { - return isGrassColor[par1] ? ColorizerFoliage.getFoliageColorBasic() : 0xFFFFFF; - } - - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @Override - public int colorMultiplier(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int meta = par1IBlockAccess.getBlockMetadata(x, y, z); - return isGrassColor[meta] ? par1IBlockAccess.getBiomeGenForCoords(x, z).getBiomeGrassColor(x, y, z) : 0xFFFFFF; - } - - - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int x, int y, int z) - { - par1World.getBlockMetadata(x, y, z); - - return null; - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return false; - } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - @Override - public boolean renderAsNormalBlock() - { - return false; - } - - /** - * The type of render function that is called for this block - */ + @Override - public int getRenderType() { - return TwilightForestMod.proxy.getPlantBlockRenderID(); + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return NULL_AABB; } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World par1World, int x, int y, int z, Random par5Random) - { - int meta = par1World.getBlockMetadata(x, y, z); - if (par1World.getBlockLightValue(x, y, z) < lightValue[meta]) { - //par1World.updateLightByType(EnumSkyBlock.Block, x, y, z); - //par1World.markBlockForUpdate(x, y, z); // do we need this now? + + @Override + public boolean isOpaqueCube(IBlockState state) { + return false; + } + + @Override + public int getLightValue(IBlockState state) { + switch (state.getValue(VARIANT)) { + case MUSHGLOOM: + return 3; + case TORCHBERRY: + return 8; + default: + return 0; } + } + + public static boolean canPlaceRootAt(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos.up()); + if (state.getMaterial() == Material.GROUND || state.getMaterial() == Material.GRASS) { + // can always hang below dirt blocks + return true; + } else { + return (state.getBlock() == TFBlocks.twilight_plant && state.getValue(BlockTFPlant.VARIANT) == PlantVariant.ROOT_STRAND) + || state == TFBlocks.root.getDefaultState(); + } + } - } - - /** - * Get a light value for this block, normal ranges are between 0 and 15 - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return The light value - */ @Override - public int getLightValue(IBlockAccess world, int x, int y, int z) { - int meta = world.getBlockMetadata(x, y, z); - return lightValue[meta]; + public Block.EnumOffsetType getOffsetType() { + return Block.EnumOffsetType.NONE; } - - - /** - * Root-specific method. - * @return true if the root can be placed in the block immediately below this one - */ - public static boolean canPlaceRootBelow(World world, int x, int y, int z) { - Block blockID = world.getBlock(x, y, z); - if (blockID != null && (blockID.getMaterial() == Material.ground || blockID.getMaterial() == Material.grass)) { - // can always hang below dirt blocks - return true; - } - else { - int blockMeta = world.getBlockMetadata(x, y, z); - return (blockID == TFBlocks.plant && blockMeta == META_ROOT_STRAND) || (blockID == TFBlocks.root && blockMeta == BlockTFRoots.ROOT_META); - } - - } - - -// /** + + +// /** todo thaumcraft // * Drops the block items with a specified chance of dropping the specified items // */ // public void dropBlockAsItemWithChance(World var1, int var2, int var3, int var4, int var5, float var6, int var7) @@ -342,182 +223,167 @@ public static boolean canPlaceRootBelow(World world, int x, int y, int z) { // } // } // - - /** - * This returns a complete list of items dropped from this block. - * - * @param world The current world - * @param x X Position - * @param Y Y Position - * @param Z Z Position - * @param metadata Current metadata - * @param fortune Breakers fortune level - * @return A ArrayList containing all items this block drops - */ - @Override - public ArrayList getDrops(World world, int x, int y, int z, int meta, int fortune) - { - ArrayList ret = new ArrayList(); - - //TODO: this needs to not drop if the player is shearing! Grrr! - - // blah - switch (meta) { - case META_TORCHBERRY : - ret.add(new ItemStack(TFItems.torchberries)); - break; - case META_MOSSPATCH : - case META_MAYAPPLE : - case META_CLOVERPATCH : - case META_ROOT_STRAND : - case META_FORESTGRASS : - case META_DEADBUSH : - // Just don't drop anythin - break; - default : - ret.add(new ItemStack(this, 1, meta)); - break; - } - - return ret; - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int par1) - { - return par1; - } - - /** - * Checks if the object is currently shearable - * Example: Sheep return false when they have no wool - * - * @param item The itemstack that is being used, Possible to be null - * @param world The current world - * @param x The X Position - * @param y The Y Position - * @param z The Z Position - * @return If this is shearable, and onSheared should be called. - */ + + @Override + public List getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune) { + List ret = NonNullList.create(); + + switch (state.getValue(VARIANT)) { + case TORCHBERRY: + ret.add(new ItemStack(TFItems.torchberries)); + break; + case FALLEN_LEAVES: + case MOSSPATCH: + case MAYAPPLE: + case CLOVERPATCH: + case FIDDLEHEAD: + case FORESTGRASS: + case DEADBUSH: + case ROOT_STRAND: + break; + default: + ret.add(new ItemStack(this, 1, damageDropped(state))); + break; + } + + return ret; + } + @Override - public boolean isShearable(ItemStack item, IBlockAccess world, int x, int y, int z) { - // TODO Auto-generated method stub + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } + + @Override + public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) { return true; } - - /** - * Performs the shear function on this object. - * This is called for both client, and server. - * The object should perform all actions related to being sheared, - * except for dropping of the items. - * - * Returns a list of items that resulted from the shearing process. - * - * For entities, they should trust there internal location information - * over the values passed into this function. - * - * @param item The itemstack that is being used, Possible to be null - * @param world The current world - * @param x The X Position - * @param y The Y Position - * @param z The Z Position - * @param fortune The fortune level of the shears being used - * @return A ArrayList containing all items from this shearing. Possible to be null. - */ + + @Override + public List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { + List ret = NonNullList.create(); + ret.add(new ItemStack(this, 1, damageDropped(world.getBlockState(pos)))); + return ret; + } + + @Override + public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack) { + // do not call normal harvest if the player is shearing + if (world.isRemote || stack.getItem() != Items.SHEARS) { + super.harvestBlock(world, player, pos, state, te, stack); + } + } + @Override - public ArrayList onSheared(ItemStack item, IBlockAccess world, int x, int y, int z, int fortune) { - ArrayList ret = new ArrayList(); - ret.add(new ItemStack(this, 1, world.getBlockMetadata(x, y, z))); - //world.setBlockToAir(x, y, z); - return ret; + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + int n = PlantVariant.values().length; + for (int i = 0; i < n; i++) { + list.add(new ItemStack(this, 1, i)); + } + } + + @Override + public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) { + IBlockState blockState = world.getBlockState(pos); + if (blockState.getBlock() == this) { + switch (blockState.getValue(VARIANT)) { + case MOSSPATCH: + case MUSHGLOOM: + return EnumPlantType.Cave; + default: + return EnumPlantType.Plains; + } + } + return EnumPlantType.Plains; + } + + @Override + @SideOnly(Side.CLIENT) + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) { + super.randomDisplayTick(state, world, pos, random); + + if (state.getValue(VARIANT) == PlantVariant.MOSSPATCH && random.nextInt(10) == 0) { + world.spawnParticle(EnumParticleTypes.TOWN_AURA, pos.getX() + random.nextFloat(), pos.getY() + 0.1F, pos.getZ() + random.nextFloat(), 0.0D, 0.0D, 0.0D); + } else if (state.getValue(VARIANT) == PlantVariant.FALLEN_LEAVES && random.nextInt(50) == 0) { + float dist = 10F; + if (!world.canSeeSky(pos)) { + for (int y = 0; y <= dist; y++) + if (world.getBlockState(pos.up(y)).getMaterial() == Material.LEAVES) { + dist = y; + break; + } + if (dist > 10F) + return; + } + Particle leaf = TFParticleFactory.createParticle(TFParticleType.FALLEN_LEAF, world, pos.getX() + random.nextFloat(), pos.getY() + dist - 0.25F, pos.getZ() + random.nextFloat(), 0.0D, 0.0D, 0.0D); + int color = Minecraft.getMinecraft().getBlockColors().colorMultiplier(Blocks.LEAVES.getDefaultState(), world, pos, 0); + leaf.setRBGColorF( + + MathHelper.clamp(((color >> 16) & 0xFF) + RANDOM.nextInt(0x22) - 0x11, 0x00, 0xFF) / 255F, + + MathHelper.clamp(((color >> 8) & 0xFF) + RANDOM.nextInt(0x22) - 0x11, 0x00, 0xFF) / 255F, + + MathHelper.clamp((color & 0xFF) + RANDOM.nextInt(0x22) - 0x11, 0x00, 0xFF) / 255F + + ); + Minecraft.getMinecraft().effectRenderer.addEffect(leaf); + } + } - - /** - * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the - * block and l is the block's subtype/damage. - */ - public void harvestBlock(World world, EntityPlayer player, int x, int y, int z, int meta) - { - // do not call normal harvest if the player is shearing - if (world.isRemote || player.getCurrentEquippedItem() == null || player.getCurrentEquippedItem().getItem() != Items.shears) - { - super.harvestBlock(world, player, x, y, z, meta); - } - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(this, 1, META_MOSSPATCH)); - par3List.add(new ItemStack(this, 1, META_MAYAPPLE)); - //par3List.add(new ItemStack(this, 1, META_CLOVERPATCH)); - par3List.add(new ItemStack(this, 1, 8)); - par3List.add(new ItemStack(this, 1, 9)); - par3List.add(new ItemStack(this, 1, META_FORESTGRASS)); - par3List.add(new ItemStack(this, 1, META_DEADBUSH)); - par3List.add(new ItemStack(this, 1, 13)); - par3List.add(new ItemStack(this, 1, 14)); - - } - - /** - * - */ + public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entityIn) { + super.onEntityCollision(world, pos, state, entityIn); + if (world.isRemote && state.getValue(VARIANT) == PlantVariant.FALLEN_LEAVES && entityIn instanceof EntityLivingBase && (entityIn.motionX != 0 || entityIn.motionZ != 0) && RANDOM.nextBoolean()) { + int color = Minecraft.getMinecraft().getBlockColors().colorMultiplier(Blocks.LEAVES.getDefaultState(), world, pos, 0); + Particle leaf = TFParticleFactory.createParticle(TFParticleType.FALLEN_LEAF, + + world, + + pos.getX() + world.rand.nextFloat(), + + pos.getY(), + + pos.getZ() + world.rand.nextFloat(), + + (world.rand.nextFloat() * -0.5F) * entityIn.motionX, + + world.rand.nextFloat() * 0.5F + 0.25F, + + (world.rand.nextFloat() * -0.5F) * entityIn.motionZ + + ); + leaf.setRBGColorF( + + MathHelper.clamp(((color >> 16) & 0xFF) + RANDOM.nextInt(0x22) - 0x11, 0x00, 0xFF) / 255F, + + MathHelper.clamp(((color >> 8) & 0xFF) + RANDOM.nextInt(0x22) - 0x11, 0x00, 0xFF) / 255F, + + MathHelper.clamp((color & 0xFF) + RANDOM.nextInt(0x22) - 0x11, 0x00, 0xFF) / 255F + + ); + Minecraft.getMinecraft().effectRenderer.addEffect(leaf); + } + } + + @SideOnly(Side.CLIENT) @Override - public void setBlockBoundsForItemRender() { - this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; } - - @Override - public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) - { - int meta = world.getBlockMetadata(x, y, z); - - switch (meta) - { - case META_MOSSPATCH : - case META_MUSHGLOOM : - return EnumPlantType.Cave; - default : - return EnumPlantType.Plains; - } - } - - @Override - public Block getPlant(IBlockAccess world, int x, int y, int z) - { - return this; - } - - @Override - public int getPlantMetadata(IBlockAccess world, int x, int y, int z) - { - return world.getBlockMetadata(x, y, z); - } - - - /** - * A randomly called display update to be able to add particles or other items for display - */ - @Override + @SideOnly(Side.CLIENT) - public void randomDisplayTick(World par1World, int x, int y, int z, Random par5Random) - { - super.randomDisplayTick(par1World, x, y, z, par5Random); - - int meta = par1World.getBlockMetadata(x, y, z); - - if (meta == META_MOSSPATCH && par5Random.nextInt(10) == 0) - { - par1World.spawnParticle("townaura", x + par5Random.nextFloat(), y + 0.1F, z + par5Random.nextFloat(), 0.0D, 0.0D, 0.0D); - } - - } + @Override + public void registerModel() { + for (int i = 0; i < PlantVariant.values().length; i++) { + String variant = "inventory_" + PlantVariant.values()[i].getName(); + ModelResourceLocation mrl = new ModelResourceLocation(getRegistryName(), variant); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), i, mrl); + } + } + + @Override + public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos pos) { + return super.getExtendedState(state, world, pos); + } } diff --git a/src/main/java/twilightforest/block/BlockTFPortal.java b/src/main/java/twilightforest/block/BlockTFPortal.java index 8954ff9204..bfb01688e9 100644 --- a/src/main/java/twilightforest/block/BlockTFPortal.java +++ b/src/main/java/twilightforest/block/BlockTFPortal.java @@ -1,439 +1,307 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; import net.minecraft.block.BlockBreakable; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList; import net.minecraft.entity.effect.EntityLightningBolt; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import twilightforest.TFAchievementPage; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.apache.commons.lang3.mutable.MutableInt; +import twilightforest.TFConfig; import twilightforest.TFTeleporter; import twilightforest.TwilightForestMod; -import cpw.mods.fml.common.FMLLog; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFPortal extends BlockBreakable -{ - - public BlockTFPortal() - { - super("TFPortal", Material.portal, false); - this.setHardness(-1F); - this.setStepSound(Block.soundTypeGlass); - this.setLightLevel(0.75F); - //this.setCreativeTab(TFItems.creativeTab); - } - - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) - { - return null; - } - - @Override - public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, int i, int j, int k) - { - setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); - } - - @Override - public boolean isOpaqueCube() - { - return false; - } - - @Override - public boolean renderAsNormalBlock() - { - return false; - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - return Blocks.portal.getIcon(side, meta); - } - - @Override +import twilightforest.world.TFWorld; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class BlockTFPortal extends BlockBreakable { + + public static final IProperty DISALLOW_RETURN = PropertyBool.create("is_one_way"); + + private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0F, 0.0F, 0.0F, 1.0F, 0.8125F, 1.0F); + private static final AxisAlignedBB AABB_ITEM = new AxisAlignedBB(0.0F, 0.0F, 0.0F, 1.0F, 0.4F, 1.0F); + + private static final int MIN_PORTAL_SIZE = 4; + private static final int MAX_PORTAL_SIZE = 64; + + public BlockTFPortal() { + super(Material.PORTAL, false); + this.setHardness(-1F); + this.setSoundType(SoundType.GLASS); + this.setLightLevel(0.75F); + this.setDefaultState(this.blockState.getBaseState().withProperty(DISALLOW_RETURN, false)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, DISALLOW_RETURN); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(DISALLOW_RETURN) ? 1 : 0; + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(DISALLOW_RETURN, meta == 1); + } + + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return AABB; + } + + @Override + @Deprecated + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.getValue(DISALLOW_RETURN) ? AABB : NULL_AABB; + } + + @Override + @Deprecated + public void addCollisionBoxToList(IBlockState state, World world, BlockPos pos, AxisAlignedBB entityBB, List blockBBs, @Nullable Entity entity, boolean isActualState) { + addCollisionBoxToList(pos, entityBB, blockBBs, entity instanceof EntityItem ? AABB_ITEM : state.getCollisionBoundingBox(world, pos)); + } + + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } + + public boolean tryToCreatePortal(World world, BlockPos pos, EntityItem catalyst, @Nullable EntityPlayer player) { + + IBlockState state = world.getBlockState(pos); + + if (canFormPortal(state) && world.getBlockState(pos.down()).isFullCube()) { + Map blocksChecked = new HashMap<>(); + blocksChecked.put(pos, true); + + MutableInt size = new MutableInt(0); + + if (recursivelyValidatePortal(world, pos, blocksChecked, size, state) && size.intValue() >= MIN_PORTAL_SIZE) { + + if (TFConfig.checkPortalDestination) { + TFTeleporter teleporter = TFTeleporter.getTeleporterForDim(catalyst.getServer(), getDestination(catalyst)); + boolean checkProgression = TFWorld.isProgressionEnforced(catalyst.world); + if (!teleporter.isSafeAround(pos, catalyst, checkProgression)) { + // TODO: "failure" effect - particles? + if (player != null) { + player.sendStatusMessage(new TextComponentTranslation(TwilightForestMod.ID + ".twilight_portal.unsafe"), true); + } + return false; + } + } + + catalyst.getItem().shrink(1); + causeLightning(world, pos, TFConfig.portalLightning); + + for (Map.Entry checkedPos : blocksChecked.entrySet()) { + if (checkedPos.getValue()) { + world.setBlockState(checkedPos.getKey(), TFBlocks.twilight_portal.getDefaultState(), 2); + } + } + + return true; + } + } + + return false; + } + + public boolean canFormPortal(IBlockState state) { + return state == Blocks.WATER.getDefaultState() || state.getBlock() == this && state.getValue(DISALLOW_RETURN); + } + + private static void causeLightning(World world, BlockPos pos, boolean fake) { + EntityLightningBolt bolt = new EntityLightningBolt(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, fake); + world.addWeatherEffect(bolt); + + if (fake) { + double range = 3.0D; + List list = world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos).grow(range)); + + for (Entity victim : list) { + if (!ForgeEventFactory.onEntityStruckByLightning(victim, bolt)) { + victim.onStruckByLightning(bolt); + } + } + } + } + + private static boolean recursivelyValidatePortal(World world, BlockPos pos, Map blocksChecked, MutableInt portalSize, IBlockState requiredState) { + + if (portalSize.incrementAndGet() > MAX_PORTAL_SIZE) return false; + + boolean isPoolProbablyEnclosed = true; + + for (int i = 0; i < EnumFacing.HORIZONTALS.length && portalSize.intValue() <= MAX_PORTAL_SIZE; i++) { + BlockPos positionCheck = pos.offset(EnumFacing.HORIZONTALS[i]); + + if (!blocksChecked.containsKey(positionCheck)) { + IBlockState state = world.getBlockState(positionCheck); + + if (state == requiredState && world.getBlockState(positionCheck.down()).isFullCube()) { + blocksChecked.put(positionCheck, true); + if (isPoolProbablyEnclosed) { + isPoolProbablyEnclosed = recursivelyValidatePortal(world, positionCheck, blocksChecked, portalSize, requiredState); + } + + } else if (isGrassOrDirt(state) && isNatureBlock(world.getBlockState(positionCheck.up())) || state.getBlock() == TFBlocks.uberous_soil) { + blocksChecked.put(positionCheck, false); + + } else return false; + } + } + + return isPoolProbablyEnclosed; + } + + private static boolean isNatureBlock(IBlockState state) { + Material mat = state.getMaterial(); + return mat == Material.PLANTS || mat == Material.VINE || mat == Material.LEAVES; + } + + private static boolean isGrassOrDirt(IBlockState state) { + Material mat = state.getMaterial(); + return state.isFullCube() && (mat == Material.GRASS || mat == Material.GROUND); + } + + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block notUsed, BlockPos fromPos) { + boolean good = world.getBlockState(pos.down()).isFullCube(); + + for (EnumFacing facing : EnumFacing.HORIZONTALS) { + if (!good) break; + + IBlockState neighboringState = world.getBlockState(pos.offset(facing)); + + good = isGrassOrDirt(neighboringState) || neighboringState == state; + } + + if (!good) { + world.playEvent(2001, pos, Block.getStateId(state)); + world.setBlockState(pos, Blocks.WATER.getDefaultState(), 0b11); + } + } + + @Override + public int quantityDropped(Random random) { + return 0; + } + + @Override @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - ; // don't load anything - } - - /** - * The function name says it all. Tries to create a portal at the specified location. - * In this case, the location is the location of a pool with very specific parameters. - */ - public boolean tryToCreatePortal(World world, int dx, int dy, int dz) - { - if (isGoodPortalPool(world, dx, dy, dz)) - { - world.addWeatherEffect(new EntityLightningBolt(world, dx, dy, dz)); - - transmuteWaterToPortal(world, dx, dy, dz); - - return true; - } - else - { - return false; - } - } - - /** - * Changes the pool it's been given to all portal. No checks done, only does 4 squares. - */ - public void transmuteWaterToPortal(World world, int dx, int dy, int dz) - { - int px = dx; - int pz = dz; - - // adjust so that the other 3 water squares are in the +x, +z directions. - if (world.getBlock(px - 1, dy, pz).getMaterial() == Material.water) - { - px--; - } - if (world.getBlock(px, dy, pz - 1).getMaterial() == Material.water) - { - pz--; - } - - world.setBlock(px + 0, dy, pz + 0, TFBlocks.portal, 0, 2); - world.setBlock(px + 1, dy, pz + 0, TFBlocks.portal, 0, 2); - world.setBlock(px + 1, dy, pz + 1, TFBlocks.portal, 0, 2); - world.setBlock(px + 0, dy, pz + 1, TFBlocks.portal, 0, 2); - - //System.out.println("Transmuting water to portal"); - } - - /** - * If this spot, or a spot in any one of the 8 directions around me is good, we're good. - */ - public boolean isGoodPortalPool(World world, int dx, int dy, int dz) - { - boolean flag = false; - - flag |= isGoodPortalPoolStrict(world, dx + 0, dy, dz + 0); - - flag |= isGoodPortalPoolStrict(world, dx - 1, dy, dz - 1); - flag |= isGoodPortalPoolStrict(world, dx + 0, dy, dz - 1); - flag |= isGoodPortalPoolStrict(world, dx + 1, dy, dz - 1); - - flag |= isGoodPortalPoolStrict(world, dx - 1, dy, dz + 0); - flag |= isGoodPortalPoolStrict(world, dx + 1, dy, dz + 0); - - flag |= isGoodPortalPoolStrict(world, dx - 1, dy, dz + 1); - flag |= isGoodPortalPoolStrict(world, dx + 0, dy, dz + 1); - flag |= isGoodPortalPoolStrict(world, dx + 1, dy, dz + 1); - - - return flag; - } - - /** - * Returns true only if there is water here, and at dx + 1, dy + 1, grass surrounding it, and solid beneath. - * - * - * GGGG - * G+wG - * GwwG - * GGGG - * - * - */ - public boolean isGoodPortalPoolStrict(World world, int dx, int dy, int dz) - { - boolean flag = true; - - // 4 squares of water - flag &= world.getBlock(dx + 0, dy, dz + 0).getMaterial() == Material.water; - flag &= world.getBlock(dx + 1, dy, dz + 0).getMaterial() == Material.water; - flag &= world.getBlock(dx + 1, dy, dz + 1).getMaterial() == Material.water; - flag &= world.getBlock(dx + 0, dy, dz + 1).getMaterial() == Material.water; - - //System.out.println("water in 4 squares = " + flag); - - // grass in the 12 squares surrounding - flag &= isGrassOrDirt(world, dx - 1, dy, dz - 1); - flag &= isGrassOrDirt(world, dx - 1, dy, dz + 0); - flag &= isGrassOrDirt(world, dx - 1, dy, dz + 1); - flag &= isGrassOrDirt(world, dx - 1, dy, dz + 2); - - flag &= isGrassOrDirt(world, dx + 0, dy, dz - 1); - flag &= isGrassOrDirt(world, dx + 1, dy, dz - 1); - - flag &= isGrassOrDirt(world, dx + 0, dy, dz + 2); - flag &= isGrassOrDirt(world, dx + 1, dy, dz + 2); - - flag &= isGrassOrDirt(world, dx + 2, dy, dz - 1); - flag &= isGrassOrDirt(world, dx + 2, dy, dz + 0); - flag &= isGrassOrDirt(world, dx + 2, dy, dz + 1); - flag &= isGrassOrDirt(world, dx + 2, dy, dz + 2); - - //System.out.println("grass surrounding = " + flag); - - - - // solid underneath - flag &= world.getBlock(dx + 0, dy - 1, dz + 0).getMaterial().isSolid(); - flag &= world.getBlock(dx + 1, dy - 1, dz + 0).getMaterial().isSolid(); - flag &= world.getBlock(dx + 1, dy - 1, dz + 1).getMaterial().isSolid(); - flag &= world.getBlock(dx + 0, dy - 1, dz + 1).getMaterial().isSolid(); - - //System.out.println("solid under = " + flag); - - - // 12 nature blocks above the grass? - flag &= isNatureBlock(world, dx - 1, dy + 1, dz - 1); - flag &= isNatureBlock(world, dx - 1, dy + 1, dz + 0); - flag &= isNatureBlock(world, dx - 1, dy + 1, dz + 1); - flag &= isNatureBlock(world, dx - 1, dy + 1, dz + 2); - - flag &= isNatureBlock(world, dx + 0, dy + 1, dz - 1); - flag &= isNatureBlock(world, dx + 1, dy + 1, dz - 1); - - flag &= isNatureBlock(world, dx + 0, dy + 1, dz + 2); - flag &= isNatureBlock(world, dx + 1, dy + 1, dz + 2); - - flag &= isNatureBlock(world, dx + 2, dy + 1, dz - 1); - flag &= isNatureBlock(world, dx + 2, dy + 1, dz + 0); - flag &= isNatureBlock(world, dx + 2, dy + 1, dz + 1); - flag &= isNatureBlock(world, dx + 2, dy + 1, dz + 2); - - //System.out.println("nature blocks = " + flag); - - - return flag; - } - - /** - * Does the block at this location count as a "nature" block for portal purposes? - */ - public boolean isNatureBlock(World world, int dx, int dy, int dz) - { - Material mat = world.getBlock(dx, dy, dz).getMaterial(); - - if (mat == Material.plants || mat == Material.vine || mat == Material.leaves) { - return true; - } - - // plants = tallgrass - // vine = flower - - - return false; - } - - - /** - * Each twilight portal pool block should have grass or dirt on one side and a portal on the other. If this is not true, delete this block, presumably causing a chain reaction. - */ - @Override - public void onNeighborBlockChange(World world, int x, int y, int z, Block notUsed) - { - boolean good = true; - - if (world.getBlock(x - 1, y, z) == this) { - good &= isGrassOrDirt(world, x + 1, y, z); - } - else if (world.getBlock(x + 1, y, z) == this) { - good &= isGrassOrDirt(world, x - 1, y, z); - } - else - { - good = false; - } - - if (world.getBlock(x, y, z - 1) == this) { - good &= isGrassOrDirt(world, x, y, z + 1); - } - else if (world.getBlock(x, y, z + 1) == this) { - good &= isGrassOrDirt(world, x, y, z - 1); - } - else - { - good = false; - } - - // if we're not good, remove this block - if (!good) - { - world.setBlock(x, y, z, Blocks.water, 0, 3); - } - } - - protected boolean isGrassOrDirt(World world, int dx, int dy, int dz) - { - return world.getBlock(dx, dy, dz).getMaterial() == Material.grass || world.getBlock(dx, dy, dz).getMaterial() == Material.ground; - // grass = grass - // ground = dirt - } - - @Override - public int quantityDropped(Random random) - { - return 0; - } - - @Override - public int getRenderBlockPass() - { - return 1; - } - - @Override - public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity) - { - if(entity.ridingEntity == null && entity.riddenByEntity == null && entity.timeUntilPortal <= 0) - { - if (entity instanceof EntityPlayerMP) - { - EntityPlayerMP playerMP = (EntityPlayerMP) entity; - - if (playerMP.timeUntilPortal > 0) - { - // do not switch dimensions if the player has any time on this thinger - playerMP.timeUntilPortal = 10; - } - else { - - // send to twilight - if (playerMP.dimension != TwilightForestMod.dimensionID) { - playerMP.triggerAchievement(TFAchievementPage.twilightPortal); - playerMP.triggerAchievement(TFAchievementPage.twilightArrival); - FMLLog.info("[TwilightForest] Player touched the portal block. Sending the player to dimension " + TwilightForestMod.dimensionID); - - playerMP.mcServer.getConfigurationManager().transferPlayerToDimension(playerMP, TwilightForestMod.dimensionID, new TFTeleporter(playerMP.mcServer.worldServerForDimension(TwilightForestMod.dimensionID))); - playerMP.addExperienceLevel(0); - playerMP.triggerAchievement(TFAchievementPage.twilightPortal); - playerMP.triggerAchievement(TFAchievementPage.twilightArrival); - - // set respawn point for TF dimension to near the arrival portal - int spawnX = MathHelper.floor_double(playerMP.posX); - int spawnY = MathHelper.floor_double(playerMP.posY); - int spawnZ = MathHelper.floor_double(playerMP.posZ); - - playerMP.setSpawnChunk(new ChunkCoordinates(spawnX, spawnY, spawnZ), true, TwilightForestMod.dimensionID); - } - else { - //System.out.println("Player touched the portal block. Sending the player to dimension 0"); - //playerMP.travelToDimension(0); - playerMP.mcServer.getConfigurationManager().transferPlayerToDimension(playerMP, 0, new TFTeleporter(playerMP.mcServer.worldServerForDimension(0))); - playerMP.addExperienceLevel(0); - } - } - } - else - { - if (entity.dimension != TwilightForestMod.dimensionID) - { - //sendEntityToDimension(entity, TwilightForestMod.dimensionID); - } - else - { - sendEntityToDimension(entity, 0); - } - } - } - - } - - /** - * This copy of the entity.travelToDimension method exists so that we can use our own teleporter - */ - public void sendEntityToDimension(Entity entity, int par1) { - // transfer a random entity? - if (!entity.worldObj.isRemote && !entity.isDead) - { - entity.worldObj.theProfiler.startSection("changeDimension"); - MinecraftServer minecraftserver = MinecraftServer.getServer(); - int dim = entity.dimension; - WorldServer worldserver = minecraftserver.worldServerForDimension(dim); - WorldServer worldserver1 = minecraftserver.worldServerForDimension(par1); - entity.dimension = par1; - entity.worldObj.removeEntity(entity); - entity.isDead = false; - entity.worldObj.theProfiler.startSection("reposition"); - minecraftserver.getConfigurationManager().transferEntityToWorld(entity, dim, worldserver, worldserver1, new TFTeleporter(worldserver1)); - entity.worldObj.theProfiler.endStartSection("reloading"); - Entity transferEntity = EntityList.createEntityByName(EntityList.getEntityString(entity), worldserver1); - - if (transferEntity != null) - { - transferEntity.copyDataFrom(entity, true); - worldserver1.spawnEntityInWorld(transferEntity); - } - - entity.isDead = true; - entity.worldObj.theProfiler.endSection(); - worldserver.resetUpdateEntityTick(); - worldserver1.resetUpdateEntityTick(); - entity.worldObj.theProfiler.endSection(); + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.TRANSLUCENT; + } + + @Override + public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity) { + if (state == this.getDefaultState()) { + attemptSendPlayer(entity, false); } } - @Override - public void randomDisplayTick(World world, int i, int j, int k, Random random) - { - if(random.nextInt(100) == 0) - { - world.playSoundEffect(i + 0.5D, j + 0.5D, k + 0.5D, "portal.portal", 1.0F, random.nextFloat() * 0.4F + 0.8F); - } - for(int l = 0; l < 4; l++) - { - double d = i + random.nextFloat(); - double d1 = j + random.nextFloat(); - double d2 = k + random.nextFloat(); - double d3 = 0.0D; - double d4 = 0.0D; - double d5 = 0.0D; - int i1 = random.nextInt(2) * 2 - 1; - d3 = (random.nextFloat() - 0.5D) * 0.5D; - d4 = (random.nextFloat() - 0.5D) * 0.5D; - d5 = (random.nextFloat() - 0.5D) * 0.5D; - if(world.getBlock(i - 1, j, k) == this || world.getBlock(i + 1, j, k) == this) - { - d2 = k + 0.5D + 0.25D * i1; - d5 = random.nextFloat() * 2.0F * i1; - } else - { - d = i + 0.5D + 0.25D * i1; - d3 = random.nextFloat() * 2.0F * i1; - } - world.spawnParticle("portal", d, d1, d2, d3, d4, d5); - } - - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + private static int getDestination(Entity entity) { + return entity.dimension != TFConfig.dimension.dimensionID + ? TFConfig.dimension.dimensionID : TFConfig.originDimension; + } + + public static void attemptSendPlayer(Entity entity, boolean forcedEntry) { + + if (entity.isDead || entity.world.isRemote) { + return; + } + + if (entity.isRiding() || entity.isBeingRidden() || !entity.isNonBoss()) { + return; + } + + if (!forcedEntry && entity.timeUntilPortal > 0) { + return; + } + + // set a cooldown before this can run again + entity.timeUntilPortal = 10; + + int destination = getDestination(entity); + + entity.changeDimension(destination, TFTeleporter.getTeleporterForDim(entity.getServer(), destination)); + + if (destination == TFConfig.dimension.dimensionID && entity instanceof EntityPlayerMP) { + EntityPlayerMP playerMP = (EntityPlayerMP) entity; + // set respawn point for TF dimension to near the arrival portal + playerMP.setSpawnChunk(new BlockPos(playerMP), true, TFConfig.dimension.dimensionID); + } + } + + // Full [VanillaCopy] of BlockPortal.randomDisplayTick + // TODO Eeeh... Let's look at changing this too alongside a new model. @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - } + @SideOnly(Side.CLIENT) + public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) { + int random = rand.nextInt(100); + if (stateIn.getValue(DISALLOW_RETURN) && random < 80) return; + + if (random == 0) { + worldIn.playSound((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.BLOCK_PORTAL_AMBIENT, SoundCategory.BLOCKS, 0.5F, rand.nextFloat() * 0.4F + 0.8F, false); + } + + for (int i = 0; i < 4; ++i) { + double xPos = (double) ((float) pos.getX() + rand.nextFloat()); + double yPos = pos.getY()+1D; + double zPos = (double) ((float) pos.getZ() + rand.nextFloat()); + double xSpeed = ((double) rand.nextFloat() - 0.5D) * 0.5D; + double ySpeed = rand.nextFloat(); + double zSpeed = ((double) rand.nextFloat() - 0.5D) * 0.5D; + //int j = rand.nextInt(2) * 2 - 1; + + //if (worldIn.getBlockState(pos.west()).getBlock() != this && worldIn.getBlockState(pos.east()).getBlock() != this) { + // xPos = (double) pos.getX() + 0.5D + 0.25D * (double) j; + // xSpeed = (double) (rand.nextFloat() * 2.0F * (float) j); + //} else { + // zPos = (double) pos.getZ() + 0.5D + 0.25D * (double) j; + // zSpeed = (double) (rand.nextFloat() * 2.0F * (float) j); + //} + + worldIn.spawnParticle(EnumParticleTypes.PORTAL, xPos, yPos, zPos, xSpeed, ySpeed, zSpeed); + } + } } diff --git a/src/main/java/twilightforest/block/BlockTFPressurePlate.java b/src/main/java/twilightforest/block/BlockTFPressurePlate.java new file mode 100644 index 0000000000..3c57acd1aa --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFPressurePlate.java @@ -0,0 +1,31 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockPressurePlate; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFPressurePlate extends BlockPressurePlate implements ModelRegisterCallback { + + private final MapColor mapColor; + + public BlockTFPressurePlate(Material material, MapColor mapColor, BlockPressurePlate.Sensitivity sensitivity) { + super(material, sensitivity); + this.mapColor = mapColor; + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return mapColor; + } +} diff --git a/src/main/java/twilightforest/block/BlockTFRipeTorchCluster.java b/src/main/java/twilightforest/block/BlockTFRipeTorchCluster.java index d4a7f2f505..a3ba96a4f0 100644 --- a/src/main/java/twilightforest/block/BlockTFRipeTorchCluster.java +++ b/src/main/java/twilightforest/block/BlockTFRipeTorchCluster.java @@ -1,83 +1,68 @@ package twilightforest.block; -import java.util.Random; - +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.item.TFItems; +import javax.annotation.Nullable; +import java.util.Random; + public class BlockTFRipeTorchCluster extends BlockTFTrollRoot { protected BlockTFRipeTorchCluster() { - super(); + this.setLightLevel(1.0F); + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return TFItems.torchberries; + } - this.setBlockTextureName(TwilightForestMod.ID + ":ripe_torch_cluster"); - this.setLightLevel(1.0F); + @Override + public int quantityDropped(IBlockState state, int fortune, Random random) { + return quantityDroppedWithBonus(fortune, random); + } + @Override + public int quantityDropped(Random rand) { + return 4 + rand.nextInt(5); } - - public Item getItemDropped(int meta, Random rand, int fortune) - { - return TFItems.torchberries; - } - - /** - * Metadata and fortune sensitive version, this replaces the old (int meta, Random rand) - * version in 1.1. - * - * @param meta Blocks Metadata - * @param fortune Current item fortune level - * @param random Random number generator - * @return The number of items to drop - */ - public int quantityDropped(int meta, int fortune, Random random) { - return quantityDroppedWithBonus(fortune, random); - } - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random rand) - { - return 4 + rand.nextInt(5); - } + @Override + public int quantityDroppedWithBonus(int bonus, Random rand) { + if (bonus > 0 && Item.getItemFromBlock(this) != this.getItemDropped(getDefaultState(), rand, bonus)) { + int j = rand.nextInt(bonus + 2) - 1; + + if (j < 0) { + j = 0; + } - /** - * Returns the usual quantity dropped by the block plus a bonus of 1 to 'i' (inclusive). - */ - public int quantityDroppedWithBonus(int bonus, Random rand) - { - if (bonus > 0 && Item.getItemFromBlock(this) != this.getItemDropped(0, rand, bonus)) - { - int j = rand.nextInt(bonus + 2) - 1; + return this.quantityDropped(rand) * (j + 1); + } else { + return this.quantityDropped(rand); + } + } - if (j < 0) - { - j = 0; - } + @Override + public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack stack) { + // do not call normal harvest if the player is shearing + if (world.isRemote || stack.getItem() != Items.SHEARS) { + super.harvestBlock(world, player, pos, state, te, stack); + } + } - return this.quantityDropped(rand) * (j + 1); - } - else - { - return this.quantityDropped(rand); - } - } - - /** - * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the - * block and l is the block's subtype/damage. - */ - public void harvestBlock(World world, EntityPlayer player, int x, int y, int z, int meta) - { - // do not call normal harvest if the player is shearing - if (world.isRemote || player.getCurrentEquippedItem() == null || player.getCurrentEquippedItem().getItem() != Items.shears) - { - super.harvestBlock(world, player, x, y, z, meta); - } - } + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } } diff --git a/src/main/java/twilightforest/block/BlockTFRoots.java b/src/main/java/twilightforest/block/BlockTFRoots.java index 470662771a..62414a563d 100644 --- a/src/main/java/twilightforest/block/BlockTFRoots.java +++ b/src/main/java/twilightforest/block/BlockTFRoots.java @@ -1,128 +1,83 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import twilightforest.TwilightForestMod; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.RootVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFRoots extends Block { - - public static IIcon spRootSide; - public static IIcon spOreRootSide; +import java.util.Random; - - public static final int ROOT_META = 0; - public static final int OREROOT_META = 1; +public class BlockTFRoots extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", RootVariant.class); public BlockTFRoots() { - super(Material.wood); + super(Material.WOOD); this.setCreativeTab(TFItems.creativeTab); - this.setHardness(2.0F); - this.setStepSound(Block.soundTypeWood); + this.setHardness(2.0F); + this.setSoundType(SoundType.WOOD); } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - if (meta == 1) { - return spOreRootSide; - } - else { - return spRootSide; - } - } - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFRoots.spRootSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":rootblock"); - BlockTFRoots.spOreRootSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":oreroots"); + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, RootVariant.values()[meta]); + } + + @Override + public Item getItemDropped(IBlockState state, Random random, int j) { + switch (state.getValue(VARIANT)) { + default: + case ROOT: + return Items.STICK; + case LIVEROOT: + return TFItems.liveroot; + } + } + + @Override + public int quantityDropped(IBlockState state, int fortune, Random random) { + if (state.getValue(VARIANT) == RootVariant.ROOT) { + return 3 + random.nextInt(2); + } else { + return super.quantityDropped(state, fortune, random); + } } - - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int meta, Random random, int j) - { - switch (meta) { - case ROOT_META : - // roots drop sticks - return Items.stick; - case OREROOT_META : - // oreroots drop liveroot - return TFItems.liveRoot; - default: - return Item.getItemFromBlock(this); - } - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) - { - switch (meta) { - case ROOT_META : - // roots drop sticks, no meta - return 0; - case OREROOT_META : - // oreroots drop liveroot, no meta - return 0; - default: - // set log flag on wood blocks - return meta | 8; - } - } - - /** - * Metadata and fortune sensitive version, this replaces the old (int meta, Random rand) - * version in 1.1. - * - * @param meta Blocks Metadata - * @param fortune Current item fortune level - * @param random Random number generator - * @return The number of items to drop - */ - @Override - public int quantityDropped(int meta, int fortune, Random random) { - switch (meta) { - case ROOT_META : - // roots drop several sticks - return 3 + random.nextInt(2); - default: - return super.quantityDropped(meta, fortune, random); - } + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override @SideOnly(Side.CLIENT) - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - } + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } } diff --git a/src/main/java/twilightforest/block/BlockTFSapling.java b/src/main/java/twilightforest/block/BlockTFSapling.java index 2a8b3c31a4..c0917d0c7a 100644 --- a/src/main/java/twilightforest/block/BlockTFSapling.java +++ b/src/main/java/twilightforest/block/BlockTFSapling.java @@ -1,200 +1,168 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.BlockSapling; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.BlockBush; +import net.minecraft.block.IGrowable; +import net.minecraft.block.SoundType; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenerator; -import twilightforest.TwilightForestMod; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.SaplingVariant; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -import twilightforest.world.TFGenCanopyTree; -import twilightforest.world.TFGenDarkCanopyTree; -import twilightforest.world.TFGenHollowTree; -import twilightforest.world.TFGenLargeRainboak; -import twilightforest.world.TFGenMangroveTree; -import twilightforest.world.TFGenMinersTree; -import twilightforest.world.TFGenSmallRainboak; -import twilightforest.world.TFGenSmallTwilightOak; -import twilightforest.world.TFGenSortingTree; -import twilightforest.world.TFGenTreeOfTime; -import twilightforest.world.TFGenTreeOfTransformation; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFSapling extends BlockSapling -{ - - private IIcon[] icons; - private String[] iconNames = new String[] {"sapling_oak", "sapling_canopy", "sapling_mangrove", "sapling_darkwood", "sapling_hollow_oak", "sapling_time", "sapling_transformation", "sapling_mining", "sapling_sorting", "sapling_rainboak"}; +import twilightforest.world.feature.TFGenCanopyTree; +import twilightforest.world.feature.TFGenDarkCanopyTree; +import twilightforest.world.feature.TFGenHollowTree; +import twilightforest.world.feature.TFGenLargeRainboak; +import twilightforest.world.feature.TFGenMangroveTree; +import twilightforest.world.feature.TFGenMinersTree; +import twilightforest.world.feature.TFGenSmallRainboak; +import twilightforest.world.feature.TFGenSmallTwilightOak; +import twilightforest.world.feature.TFGenSortingTree; +import twilightforest.world.feature.TFGenTreeOfTime; +import twilightforest.world.feature.TFGenTreeOfTransformation; + +import java.util.Random; + +public class BlockTFSapling extends BlockBush implements IGrowable, ModelRegisterCallback { + + public static final IProperty TF_TYPE = PropertyEnum.create("tf_type", SaplingVariant.class); + protected static final AxisAlignedBB SAPLING_AABB = new AxisAlignedBB(0.09999999403953552D, 0.0D, 0.09999999403953552D, 0.8999999761581421D, 0.800000011920929D, 0.8999999761581421D); protected BlockTFSapling() { - super(); - float var3 = 0.4F; - this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var3 * 2.0F, 0.5F + var3); this.setCreativeTab(TFItems.creativeTab); + this.setSoundType(SoundType.PLANT); + this.setDefaultState(blockState.getBaseState() + .withProperty(TF_TYPE, SaplingVariant.OAK)); } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World par1World, int x, int y, int z, Random par5Random) - { - if (!par1World.isRemote) - { - //this.checkFlowerChange(par1World, x, y, z); - - if (par1World.getBlockLightValue(x, y + 1, z) >= 9 && par5Random.nextInt(7) == 0) - { - this.func_149878_d(par1World, x, y, z, par5Random); - } - } - } - - - /** - * Attempts to grow a sapling into a tree - */ - @Override - public void func_149878_d(World world, int x, int y, int z, Random rand) { - int meta = world.getBlockMetadata(x, y, z); - WorldGenerator treeGenerator = null; - int var8 = 0; - int var9 = 0; - boolean largeTree = false; - - if (meta == 1) - { - treeGenerator = new TFGenCanopyTree(true); - } - else if (meta == 2) - { - treeGenerator = new TFGenMangroveTree(true); - } - else if (meta == 3) - { - treeGenerator = new TFGenDarkCanopyTree(true); - } - else if (meta == 4) - { - treeGenerator = new TFGenHollowTree(true); - } - else if (meta == 5) - { - treeGenerator = new TFGenTreeOfTime(true); - } - else if (meta == 6) - { - treeGenerator = new TFGenTreeOfTransformation(true); - } - else if (meta == 7) - { - treeGenerator = new TFGenMinersTree(true); - } - else if (meta == 8) - { - treeGenerator = new TFGenSortingTree(true); - } - else if (meta == 9) - { - treeGenerator = rand.nextInt(7) == 0 ? new TFGenLargeRainboak(true) : new TFGenSmallRainboak(true); - } - else - { - treeGenerator = new TFGenSmallTwilightOak(true); - } - - if (largeTree) - { - world.setBlock(x + var8, y, z + var9, Blocks.air, 0, 4); - world.setBlock(x + var8 + 1, y, z + var9, Blocks.air, 0, 4); - world.setBlock(x + var8, y, z + var9 + 1, Blocks.air, 0, 4); - world.setBlock(x + var8 + 1, y, z + var9 + 1, Blocks.air, 0, 4); - } - else - { - world.setBlock(x, y, z, Blocks.air, 0, 4); - } - - if (!treeGenerator.generate(world, rand, x + var8, y, z + var9)) - { - if (largeTree) - { - world.setBlock(x + var8, y, z + var9, this, meta, 4); - world.setBlock(x + var8 + 1, y, z + var9, this, meta, 4); - world.setBlock(x + var8, y, z + var9 + 1, this, meta, 4); - world.setBlock(x + var8 + 1, y, z + var9 + 1, this, meta, 4); - } - else - { - world.setBlock(x, y, z, this, meta, 4); - } - } - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int metadata) - { - if (metadata < this.icons.length) - { - return this.icons[metadata]; - } - else - { - return null; - } - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.icons = new IIcon[iconNames.length]; - - for (int i = 0; i < this.icons.length; ++i) - { - this.icons[i] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + iconNames[i]); - } - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ + @Override - public int damageDropped(int par1) - { - return par1; - } + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, TF_TYPE); + } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - @SideOnly(Side.CLIENT) + public void grow(World world, Random rand, BlockPos pos, IBlockState state) { + WorldGenerator treeGenerator; + + switch (state.getValue(TF_TYPE)) { + case CANOPY: + treeGenerator = new TFGenCanopyTree(true); + break; + case MANGROVE: + treeGenerator = new TFGenMangroveTree(true); + break; + case DARKWOOD: + treeGenerator = new TFGenDarkCanopyTree(true); + break; + case HOLLOW_OAK: + treeGenerator = new TFGenHollowTree(true); + break; + case TIME: + treeGenerator = new TFGenTreeOfTime(true); + break; + case TRANSFORMATION: + treeGenerator = new TFGenTreeOfTransformation(true); + break; + case MINING: + treeGenerator = new TFGenMinersTree(true); + break; + case SORTING: + treeGenerator = new TFGenSortingTree(true); + break; + case RAINBOW: + treeGenerator = rand.nextInt(7) == 0 ? new TFGenLargeRainboak(true) : new TFGenSmallRainboak(true); + break; + case OAK: + default: + treeGenerator = new TFGenSmallTwilightOak(true); + break; + } + + world.setBlockState(pos, Blocks.AIR.getDefaultState(), 4); + + if (!treeGenerator.generate(world, rand, pos)) { + world.setBlockState(pos, state, 4); + } + } - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); - par3List.add(new ItemStack(par1, 1, 4)); - par3List.add(new ItemStack(par1, 1, 5)); - par3List.add(new ItemStack(par1, 1, 6)); - par3List.add(new ItemStack(par1, 1, 7)); - par3List.add(new ItemStack(par1, 1, 8)); - par3List.add(new ItemStack(par1, 1, 9)); - } + @Override + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); + list.add(new ItemStack(this, 1, 4)); + list.add(new ItemStack(this, 1, 5)); + list.add(new ItemStack(this, 1, 6)); + list.add(new ItemStack(this, 1, 7)); + list.add(new ItemStack(this, 1, 8)); + list.add(new ItemStack(this, 1, 9)); + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return SAPLING_AABB; + } + @Override + public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { + if (!worldIn.isRemote) { + super.updateTick(worldIn, pos, state, rand); + + if (worldIn.getLightFromNeighbors(pos.up()) >= 9 && rand.nextInt(7) == 0) { + this.grow(worldIn, rand, pos, state); + } + } + } + + @Override + public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient) { + return true; + } + + @Override + public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state) { + return (double) worldIn.rand.nextFloat() < 0.45D; + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(TF_TYPE).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(TF_TYPE, SaplingVariant.values()[meta % SaplingVariant.values().length]); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + for (int i = 0; i < SaplingVariant.values().length; i++) { + String variant = "inventory_" + SaplingVariant.values()[i].getName(); + ModelResourceLocation mrl = new ModelResourceLocation(getRegistryName(), variant); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), i, mrl); + } + } } diff --git a/src/main/java/twilightforest/block/BlockTFShield.java b/src/main/java/twilightforest/block/BlockTFShield.java index 8c7bba1b89..2ee2f86a6e 100644 --- a/src/main/java/twilightforest/block/BlockTFShield.java +++ b/src/main/java/twilightforest/block/BlockTFShield.java @@ -1,173 +1,97 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; -import net.minecraft.block.BlockPistonBase; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFShield extends Block -{ - - public static IIcon sprSide; - private IIcon sprInside; - private IIcon sprOutside; - - public BlockTFShield() - { - super(Material.rock); - this.setBlockUnbreakable(); - //this.setResistance(2000.0F); - this.setResistance(6000000.0F); - this.setStepSound(Block.soundTypeMetal); +import twilightforest.util.EntityUtil; + +import java.util.Random; + +public class BlockTFShield extends Block implements ModelRegisterCallback { + + public BlockTFShield() { + super(Material.ROCK); + this.setBlockUnbreakable(); + this.setResistance(6000000.0F); + this.setSoundType(SoundType.METAL); this.setCreativeTab(TFItems.creativeTab); - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - if (side == meta) - { - return sprInside; - } - else - { - return sprOutside; - } - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.sprInside = par1IconRegister.registerIcon(TwilightForestMod.ID + ":shield_inside"); - this.sprOutside = par1IconRegister.registerIcon(TwilightForestMod.ID + ":shield_outside"); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + this.setDefaultState(blockState.getBaseState().withProperty(BlockDirectional.FACING, EnumFacing.DOWN)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, BlockDirectional.FACING); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(BlockDirectional.FACING).getIndex(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.byIndex(meta)); + } + + @Override + public int quantityDropped(Random random) { + return 0; + } + + @Override + @Deprecated + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.getDirectionFromEntityLiving(pos, placer)); + } + + @Override + @Deprecated + public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World world, BlockPos pos) { + // why can't we just pass the side to this method? This is annoying and failure-prone + RayTraceResult ray = EntityUtil.rayTrace(player, range -> range + 1.0); + + EnumFacing hitFace = ray != null ? ray.sideHit : null; + EnumFacing blockFace = state.getValue(BlockDirectional.FACING); + + if (hitFace == blockFace) { + return player.getDigSpeed(Blocks.STONE.getDefaultState(), pos) / 1.5F / 100F; + } else { + return super.getPlayerRelativeBlockHardness(state, player, world, pos); + } + } + @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - } - - - /** - * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha - */ - @Override - public int getRenderBlockPass() - { - return 0; - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return true; - } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - @Override - public boolean renderAsNormalBlock() - { - return true; - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return 0; + protected boolean canSilkHarvest() { + return false; } - - /** - * Returns the quantity of items to drop on block destruction. - */ - @Override - public int quantityDropped(Random par1Random) - { - return 0; - } - - /** - * Called when the block is placed in the world. - */ - @Override - public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLiving, ItemStack par6ItemStack) - { - int l = BlockPistonBase.determineOrientation(par1World, par2, par3, par4, par5EntityLiving); - par1World.setBlockMetadataWithNotify(par2, par3, par4, l, 2); - } - - /** - * Gets the hardness of block at the given coordinates in the given world, relative to the ability of the given - * EntityPlayer. - */ - @Override - public float getPlayerRelativeBlockHardness(EntityPlayer player, World world, int x, int y, int z) - { - // why can't we just pass the side to this method? This is annoying and failure-prone - MovingObjectPosition mop = getPlayerPointVec(world, player, 6.0); - - int facing = mop != null ? mop.sideHit : -1; - int meta = world.getBlockMetadata(x, y, z); - - //System.out.printf("Determining relative hardness; facing = %d, meta = %d\n", facing, meta); - - if (facing == meta) - { - return player.getBreakSpeed(Blocks.stone, false, 0, x, y, z) / 1.5F / 100F; - } - else - { - return super.getPlayerRelativeBlockHardness(player, world, x, y, z); - } - } - - /** - * What block is the player pointing at? - * - * This very similar to player.rayTrace, but that method is not available on the server. - * - * @return - */ - private MovingObjectPosition getPlayerPointVec(World worldObj, EntityPlayer player, double range) { - Vec3 position = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 look = player.getLook(1.0F); - Vec3 dest = position.addVector(look.xCoord * range, look.yCoord * range, look.zCoord * range); - return worldObj.rayTraceBlocks(position, dest); + + @Override + public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + return false; + } + + @Override + public int damageDropped(IBlockState state) { + return 0; + } + + @Override + public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) { + return false; } } diff --git a/src/main/java/twilightforest/block/BlockTFSlab.java b/src/main/java/twilightforest/block/BlockTFSlab.java new file mode 100644 index 0000000000..f5a2ed10ab --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFSlab.java @@ -0,0 +1,78 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.client.ModelRegisterCallback; + +import java.util.Random; + +public abstract class BlockTFSlab> extends BlockSlab implements ModelRegisterCallback { + + private final Comparable propertyValue; + + BlockTFSlab(Material material, MapColor mapColor, T propertyValue) { + super(material, mapColor); + this.propertyValue = propertyValue; + + if (this.isDouble()) this.setDefaultState(this.blockState.getBaseState().withProperty(this.getVariantProperty(), propertyValue)); + else this.setDefaultState(this.blockState.getBaseState().withProperty(this.getVariantProperty(), propertyValue).withProperty(HALF, EnumBlockHalf.BOTTOM)); + } + + @Override + protected BlockStateContainer createBlockState() { + return this.isDouble() ? new BlockStateContainer(this, this.getVariantProperty()) : new BlockStateContainer(this, this.getVariantProperty(), HALF); + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return Item.getItemFromBlock(getSingle()); + } + + @Override + public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { + return new ItemStack(Item.getItemFromBlock(getSingle())); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return this.isDouble() ? this.getDefaultState() : this.getDefaultState().withProperty(HALF, meta == 0 ? EnumBlockHalf.BOTTOM : EnumBlockHalf.TOP); + } + + @Override + public int getMetaFromState(IBlockState state) { + return this.isDouble() ? 0 : state.getValue(HALF) == EnumBlockHalf.BOTTOM ? 0 : 1; + } + + @Override + public String getTranslationKey(int meta) { + return this.getTranslationKey(); + } + + @Override + public abstract boolean isDouble(); + + @Override + public abstract IProperty getVariantProperty(); + + @Override + public Comparable getTypeForItem(ItemStack stack) { + return propertyValue; + } + + protected abstract Block getSingle(); + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFSlider.java b/src/main/java/twilightforest/block/BlockTFSlider.java index 3536c94862..09e8417957 100644 --- a/src/main/java/twilightforest/block/BlockTFSlider.java +++ b/src/main/java/twilightforest/block/BlockTFSlider.java @@ -1,319 +1,184 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import org.lwjgl.opengl.GL11; - -import twilightforest.TwilightForestMod; -import twilightforest.entity.EntityTFSlideBlock; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.block.Block; import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyInteger; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityFallingBlock; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; -import net.minecraft.util.IIcon; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.entity.EntityTFSlideBlock; +import twilightforest.item.TFItems; + +import java.util.Random; + +public class BlockTFSlider extends BlockRotatedPillar implements ModelRegisterCallback { + + public static final IProperty DELAY = PropertyInteger.create("delay", 0, 3); -public class BlockTFSlider extends BlockRotatedPillar { - private static final int TICK_TIME = 80; private static final int OFFSET_TIME = 20; private static final int PLAYER_RANGE = 32; private static final float BLOCK_DAMAGE = 5; - private IIcon horiIcon; - private IIcon vertIcon; - private IIcon topIcon; + private static final AxisAlignedBB Y_BB = new AxisAlignedBB(0.3125, 0, 0.3125, 0.6875, 1F, 0.6875); + private static final AxisAlignedBB Z_BB = new AxisAlignedBB(0.3125, 0.3125, 0, 0.6875, 0.6875, 1F); + private static final AxisAlignedBB X_BB = new AxisAlignedBB(0, 0.3125, 0.3125, 1F, 0.6875, 0.6875); protected BlockTFSlider() { - super(Material.iron); + super(Material.IRON, MapColor.DIRT); this.setCreativeTab(TFItems.creativeTab); this.setHardness(2.0F); this.setResistance(10.0F); + this.setDefaultState(blockState.getBaseState().withProperty(AXIS, EnumFacing.Axis.Y).withProperty(DELAY, 0)); } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) - { - int meta = world.getBlockMetadata(x, y, z); - - int rotation = meta & 12; - float pixel = 0.0625F; - float inset = 5F; - - switch (rotation) { - case 0: - default: - return AxisAlignedBB.getBoundingBox(x + pixel * inset, y, z + pixel * inset, x + 1F - pixel * inset, y + 1F, z + 1F - pixel * inset); - case 4: - return AxisAlignedBB.getBoundingBox(x, y + pixel * inset, z + pixel * inset, x + 1F, y + 1F - pixel * inset, z + 1F - pixel * inset); - case 8: - return AxisAlignedBB.getBoundingBox(x + pixel * inset, y + pixel * inset, z, x + 1F - pixel * inset, y + 1F - pixel * inset, z + 1F); - } - } - + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, AXIS, DELAY); + } - /** - * Returns the bounding box of the wired rectangular prism to render. - */ - @SideOnly(Side.CLIENT) - public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int x, int y, int z) - { - return this.getCollisionBoundingBoxFromPool(world, x, y, z); - } - - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) - { - int meta = world.getBlockMetadata(x, y, z); - - setBlockBoundsBasedOnMeta(meta); - } + @Override + public int getMetaFromState(IBlockState state) { + return super.getMetaFromState(state) | state.getValue(DELAY); + } - public void setBlockBoundsBasedOnMeta(int meta) { - int rotation = meta & 12; - float pixel = 0.0625F; - float inset = 5F; - - switch (rotation) { - case 0: - default: - this.setBlockBounds(pixel * inset, 0, pixel * inset, 1F - pixel * inset, 1F, 1F - pixel * inset); - break; - case 4: - this.setBlockBounds(0, pixel * inset, pixel * inset, 1F, 1F - pixel * inset, 1F - pixel * inset); - break; - case 8: - this.setBlockBounds(pixel * inset, pixel * inset, 0, 1F - pixel * inset, 1F - pixel * inset, 1F); - break; - } + @Override + public IBlockState getStateFromMeta(int meta) { + return super.getStateFromMeta(meta).withProperty(DELAY, meta & 0b11); } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - public boolean renderAsNormalBlock() - { - return false; - } - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - public boolean isOpaqueCube() - { - return false; - } - - /** - * The type of render function that is called for this block - */ - public int getRenderType() - { - return 0; - } - - /** - * Gets the block's texture. Args: side, meta - */ - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) - { - int rotation = meta & 12; - - if (rotation == 0) { - switch (side) { - case 0: - case 1: - return this.topIcon; - default: - return this.vertIcon; - } - } else if (rotation == 4) { - switch (side) { - case 4: - case 5: - return this.topIcon; - default: - return this.horiIcon; - } - } else { // rotation == 8 - switch (side) { - case 2: - case 3: - return this.topIcon; - case 0: - case 1: - return this.vertIcon; - default: - return this.horiIcon; - } - } - - -// int type = 0; -// return rotation == 0 && (side == 1 || side == 0) ? this.getTopIcon(type) : (rotation == 4 && (side == 5 || side == 4) ? this.getTopIcon(type) : (rotation == 8 && (side == 2 || side == 3) ? this.getTopIcon(type) : this.getSideIcon(type))); - } + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + switch (state.getValue(AXIS)) { + case Y: + default: + return Y_BB; + case X: + return X_BB; + case Z: + return Z_BB; + } + } - @SideOnly(Side.CLIENT) @Override - protected IIcon getSideIcon(int meta) - { - if ((meta & 12) == 0) { - return this.horiIcon; - } else if ((meta & 12) == 8) { - return this.horiIcon; - } - return this.vertIcon; - } + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } - @SideOnly(Side.CLIENT) @Override - protected IIcon getTopIcon(int p_150161_1_) - { - return this.topIcon; - } - - + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } + @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.horiIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":slider_h"); - this.vertIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":slider_v"); - this.topIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":slider_top"); + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World world, int x, int y, int z, Random par5Random) - { - if (!world.isRemote && this.isConnectedInRange(world, x, y, z)) - { - //world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, TwilightForestMod.ID + ":random.creakstart", 0.75F, 1.5F); - - EntityTFSlideBlock slideBlock = new EntityTFSlideBlock(world, x + 0.5, y, z + 0.5, this, world.getBlockMetadata(x, y, z)); - world.spawnEntityInWorld(slideBlock); - - } - - scheduleBlockUpdate(world, x, y, z); - } - - /** - * Check if there is any players in range, and also recursively check connected blocks - */ - public boolean isConnectedInRange(World world, int x, int y, int z) { - int meta = world.getBlockMetadata(x, y, z); - - if ((meta & 12) == 0) { - return this.anyPlayerInRange(world, x, y, z) || this.isConnectedInRangeRecursive(world, x, y, z, ForgeDirection.UP) || this.isConnectedInRangeRecursive(world, x, y, z, ForgeDirection.DOWN); - } else if ((meta & 12) == 4) { - return this.anyPlayerInRange(world, x, y, z) || this.isConnectedInRangeRecursive(world, x, y, z, ForgeDirection.WEST) || this.isConnectedInRangeRecursive(world, x, y, z, ForgeDirection.EAST); - } else if ((meta & 12) == 8) { - return this.anyPlayerInRange(world, x, y, z) || this.isConnectedInRangeRecursive(world, x, y, z, ForgeDirection.NORTH) || this.isConnectedInRangeRecursive(world, x, y, z, ForgeDirection.SOUTH); - } else { - // why are we here? - return this.anyPlayerInRange(world, x, y, z); - } - } + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random random) { + if (!world.isRemote && this.isConnectedInRange(world, pos)) { + //world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, TwilightForestMod.ID + ":random.creakstart", 0.75F, 1.5F); + + EntityTFSlideBlock slideBlock = new EntityTFSlideBlock(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, state); + world.spawnEntity(slideBlock); + } - private boolean isConnectedInRangeRecursive(World world, int x, int y, int z, ForgeDirection dir) { - // where is the coords we're talking about - int dx = x + dir.offsetX; - int dy = y + dir.offsetY; - int dz = z + dir.offsetZ; - - // are the blocks connected? (block and meta are the same - if (world.getBlock(x, y, z) == world.getBlock(dx, dy, dz) && world.getBlockMetadata(x, y, z) == world.getBlockMetadata(dx, dy, dz)) { - return this.anyPlayerInRange(world, dx, dy, dz) || this.isConnectedInRangeRecursive(world, dx, dy, dz, dir); + scheduleBlockUpdate(world, pos); + } + + /** + * Check if there is any players in range, and also recursively check connected blocks + */ + public boolean isConnectedInRange(World world, BlockPos pos) { + EnumFacing.Axis axis = world.getBlockState(pos).getValue(AXIS); + + switch (axis) { + case Y: + return this.anyPlayerInRange(world, pos) || this.isConnectedInRangeRecursive(world, pos, EnumFacing.UP) || this.isConnectedInRangeRecursive(world, pos, EnumFacing.DOWN); + case X: + return this.anyPlayerInRange(world, pos) || this.isConnectedInRangeRecursive(world, pos, EnumFacing.WEST) || this.isConnectedInRangeRecursive(world, pos, EnumFacing.EAST); + case Z: + return this.anyPlayerInRange(world, pos) || this.isConnectedInRangeRecursive(world, pos, EnumFacing.NORTH) || this.isConnectedInRangeRecursive(world, pos, EnumFacing.SOUTH); + default: + return this.anyPlayerInRange(world, pos); + } + } + + private boolean isConnectedInRangeRecursive(World world, BlockPos pos, EnumFacing dir) { + BlockPos dPos = pos.offset(dir); + + if (world.getBlockState(pos) == world.getBlockState(dPos)) { + return this.anyPlayerInRange(world, dPos) || this.isConnectedInRangeRecursive(world, dPos, dir); } else { return false; } } - /** - * Returns true if there is a player in range (using World.getClosestPlayer) - * @param world - * @param z - * @param y - * @param x - */ - public boolean anyPlayerInRange(World world, int x, int y, int z) { - return world.getClosestPlayer((double)x + 0.5D, (double)y + 0.5D, (double)z + 0.5D, PLAYER_RANGE) != null; - } + private boolean anyPlayerInRange(World world, BlockPos pos) { + return world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, PLAYER_RANGE, false) != null; + } - public void scheduleBlockUpdate(World world, int x, int y, int z) { - int offset = world.getBlockMetadata(x, y, z) & 3; - int update = TICK_TIME - ((int)(world.getWorldTime() - (offset * OFFSET_TIME)) % TICK_TIME); - world.scheduleBlockUpdate(x, y, z, this, update); - - //System.out.println("The current world time is " + world.getWorldTime() + " so update scheduled for " + update + " ticks."); + public void scheduleBlockUpdate(World world, BlockPos pos) { + int offset = world.getBlockState(pos).getValue(DELAY); + int update = TICK_TIME - ((int) (world.getWorldTime() - (offset * OFFSET_TIME)) % TICK_TIME); + world.scheduleUpdate(pos, this, update); } - /** - * Schedule an update to try to get lighting right - */ @Override - public void onBlockAdded(World world, int x, int y, int z) { - scheduleBlockUpdate(world, x, y, z); + public void onBlockAdded(World world, BlockPos pos, IBlockState state) { + scheduleBlockUpdate(world, pos); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, 0)); + list.add(new ItemStack(this, 1, 1)); + list.add(new ItemStack(this, 1, 2)); + list.add(new ItemStack(this, 1, 3)); + } + + @Override + public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity) { + entity.attackEntityFrom(DamageSource.GENERIC, BLOCK_DAMAGE); + if (entity instanceof EntityLivingBase) { + double kx = (pos.getX() + 0.5 - entity.posX) * 2.0; + double kz = (pos.getZ() + 0.5 - entity.posZ) * 2.0; + + ((EntityLivingBase) entity).knockBack(null, 2, kx, kz); + } + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + IStateMapper stateMapper = new StateMap.Builder().ignore(DELAY).build(); + ModelLoader.setCustomStateMapper(this, stateMapper); + for (int i = 0; i < 4; i++) { + ModelUtils.registerToState(this, i, getDefaultState(), stateMapper); + } } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); - } - - /** - * Sets the block's bounds for rendering it as an item - */ - public void setBlockBoundsForItemRender() - { - this.setBlockBoundsBasedOnMeta(0); - } - - /** - * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity - */ - public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) - { - entity.attackEntityFrom(DamageSource.generic, BLOCK_DAMAGE); - if (entity instanceof EntityLivingBase) { - double kx = (x + 0.5 - entity.posX) * 2.0; - double kz = (z + 0.5 - entity.posZ) * 2.0; - - ((EntityLivingBase) entity).knockBack(null, 5, kx, kz); - } - } } diff --git a/src/main/java/twilightforest/block/BlockTFSpiralBrick.java b/src/main/java/twilightforest/block/BlockTFSpiralBrick.java new file mode 100644 index 0000000000..9a761ae4e5 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFSpiralBrick.java @@ -0,0 +1,222 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.enums.Diagonals; +import twilightforest.item.TFItems; + +import javax.annotation.Nullable; + +public class BlockTFSpiralBrick extends Block implements ModelRegisterCallback { + + public static final IProperty DIAGONAL = PropertyEnum.create("diagonal", Diagonals.class); + public static final IProperty AXIS_FACING = PropertyEnum.create("axis", EnumFacing.Axis.class); + + public BlockTFSpiralBrick() { + super(Material.ROCK, MapColor.STONE); + this.setHardness(1.5F); + this.setResistance(10.0F); + this.setSoundType(SoundType.STONE); + this.setLightOpacity(255); + this.useNeighborBrightness = true; + this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(this.blockState.getBaseState().withProperty(DIAGONAL, Diagonals.TOP_RIGHT).withProperty(AXIS_FACING, EnumFacing.Axis.X)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, AXIS_FACING, DIAGONAL); + } + + @Override + public int getMetaFromState(IBlockState state) { + return (state.getValue(AXIS_FACING).ordinal() << 2) | (state.getValue(DIAGONAL).ordinal()); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(DIAGONAL, Diagonals.values()[meta & 0b0011]).withProperty(AXIS_FACING, EnumFacing.Axis.values()[(meta & 0b1100) >> 2]); + } + + @Override + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + IBlockState state = worldIn.getBlockState(pos.offset(facing.getOpposite())); + + if (!placer.isSneaking() && worldIn.getBlockState(pos.offset(facing.getOpposite())).getBlock() instanceof BlockTFSpiralBrick) { + EnumFacing.Axis axis = state.getValue(AXIS_FACING); + + return super.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer) + .withProperty(AXIS_FACING, axis) + .withProperty(DIAGONAL, Diagonals.mirror(state.getValue(DIAGONAL), facing.getAxis() == EnumFacing.Axis.X ? Mirror.LEFT_RIGHT : Mirror.FRONT_BACK)); + } + + EnumFacing playerFacing = EnumFacing.getDirectionFromEntityLiving(pos, placer); + + return super.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer) + .withProperty(AXIS_FACING, playerFacing.getAxis()) + .withProperty(DIAGONAL, getDiagonalFromPlayerPlacement(placer, facing)); + } + + private static Diagonals getDiagonalFromPlayerPlacement(EntityLivingBase placer, EnumFacing facing) { + int angleX = (int) ((placer.rotationPitch + 180f) / 180f) & 1; + int angleY = (int) ((placer.rotationYaw + 180f) / 90f) & 3; + + switch (facing) { + case DOWN: + case UP: + switch (angleY) { + default: return Diagonals.TOP_RIGHT; // NORTH EAST + case 1: return Diagonals.BOTTOM_RIGHT; // SOUTH EAST + case 2: return Diagonals.BOTTOM_LEFT; // SOUTH WEST + case 3: return Diagonals.TOP_LEFT; // NORTH WEST + } + + /* + NORTH + 3 0 + + 2 1 + */ + + case NORTH: + return Diagonals.getDiagonalFromUpDownLeftRight( isEast(angleY), angleX < 1); + case SOUTH: + return Diagonals.getDiagonalFromUpDownLeftRight( !isEast(angleY), angleX < 1); + case EAST: + return Diagonals.getDiagonalFromUpDownLeftRight( isNorth(angleY), angleX < 1); + case WEST: + return Diagonals.getDiagonalFromUpDownLeftRight(!isNorth(angleY), angleX < 1); + } + + return Diagonals.TOP_RIGHT; + } + + private static boolean isNorth(int intIn) { + return intIn == 0 || intIn == 3; + } + + private static boolean isEast(int intIn) { + return intIn == 0 || intIn == 1; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + IStateMapper stateMapper = new StateMap.Builder().withName(AXIS_FACING).withSuffix("_spiral_bricks").build(); + ModelLoader.setCustomStateMapper(this, stateMapper); + ModelUtils.registerToState(this, 0, this.getDefaultState().withProperty(DIAGONAL, Diagonals.BOTTOM_LEFT), stateMapper); + } + + @Override + public IBlockState withRotation(IBlockState state, Rotation rot) { + if (rot == Rotation.NONE) return state; + + EnumFacing.Axis axis = state.getValue(AXIS_FACING); + + if (axis == EnumFacing.Axis.Y) { + return state.withProperty(DIAGONAL, Diagonals.rotate(state.getValue(DIAGONAL), rot)); + } else { + if (rot == Rotation.CLOCKWISE_180 || (axis == EnumFacing.Axis.X && rot == Rotation.COUNTERCLOCKWISE_90) || (axis == EnumFacing.Axis.Z && rot == Rotation.CLOCKWISE_90)) + state = state.withProperty(DIAGONAL, Diagonals.mirror(state.getValue(DIAGONAL), Mirror.LEFT_RIGHT)); + + return rot.ordinal() % 2 == 0 ? state : state.withProperty(AXIS_FACING, axis == EnumFacing.Axis.X ? EnumFacing.Axis.Z : EnumFacing.Axis.X); + } + } + + @Override + public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { + return state.withProperty(DIAGONAL, Diagonals.mirrorOn(state.getValue(AXIS_FACING), state.getValue(DIAGONAL), mirrorIn)); + } + + @Override + public boolean rotateBlock(World world, BlockPos pos, EnumFacing facing) { + IBlockState state = world.getBlockState(pos); + + if (facing.getAxis() == state.getValue(AXIS_FACING)) { + state = state.cycleProperty(DIAGONAL); + } else { + switch (facing.getAxis()) { + case X: + state = state.withProperty(AXIS_FACING, state.getValue(AXIS_FACING) == EnumFacing.Axis.Y ? EnumFacing.Axis.Z : EnumFacing.Axis.Y); + break; + case Y: + state = state.withProperty(AXIS_FACING, state.getValue(AXIS_FACING) == EnumFacing.Axis.X ? EnumFacing.Axis.Z : EnumFacing.Axis.X); + break; + case Z: + state = state.withProperty(AXIS_FACING, state.getValue(AXIS_FACING) == EnumFacing.Axis.Y ? EnumFacing.Axis.X : EnumFacing.Axis.Y); + break; + } + } + + world.setBlockState(pos, state); + return true; + } + + @Override + @Nullable + public EnumFacing[] getValidRotations(World world, BlockPos pos) { + return EnumFacing.values(); + } + + @Override + public boolean isFullCube(IBlockState state) { + return false; + } + + @Override + public boolean isOpaqueCube(IBlockState state) { + return false; + } + + @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + + EnumFacing.Axis axis = state.getValue(AXIS_FACING); + if (face.getAxis() == axis) { + return BlockFaceShape.UNDEFINED; + } + + EnumFacing top = axis == EnumFacing.Axis.Y ? EnumFacing.NORTH : EnumFacing.UP; + EnumFacing left = axis == EnumFacing.Axis.X ? EnumFacing.SOUTH : EnumFacing.WEST; + + Diagonals diagonal = state.getValue(DIAGONAL); + if (face == (diagonal.isLeft() ? left : left.getOpposite()) || face == (diagonal.isTop() ? top : top.getOpposite())) { + return BlockFaceShape.SOLID; + } else { + return BlockFaceShape.UNDEFINED; + } + } + + @Override + public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) { + return getBlockFaceShape(world, state, pos, face) == BlockFaceShape.SOLID; + } + + @Override + protected ItemStack getSilkTouchDrop(IBlockState state) { + return new ItemStack(Item.getItemFromBlock(this)); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFStairs.java b/src/main/java/twilightforest/block/BlockTFStairs.java new file mode 100644 index 0000000000..04c300d4a9 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFStairs.java @@ -0,0 +1,25 @@ +package twilightforest.block; + +import net.minecraft.block.BlockStairs; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.item.TFItems; + +public class BlockTFStairs extends BlockStairs implements ModelRegisterCallback { + + protected BlockTFStairs(IBlockState modelState) { + super(modelState); + this.setCreativeTab(TFItems.creativeTab); + this.useNeighborBrightness = true; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, getDefaultState().withProperty(FACING, EnumFacing.EAST)); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFThornRose.java b/src/main/java/twilightforest/block/BlockTFThornRose.java index ed4386bb3e..c692828f6b 100644 --- a/src/main/java/twilightforest/block/BlockTFThornRose.java +++ b/src/main/java/twilightforest/block/BlockTFThornRose.java @@ -1,96 +1,101 @@ package twilightforest.block; import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.item.Item; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -public class BlockTFThornRose extends Block { +public class BlockTFThornRose extends Block implements ModelRegisterCallback { + + private static final float RADIUS = 0.4F; + private static final AxisAlignedBB AABB = new AxisAlignedBB(0.5F - RADIUS, 0.5F - RADIUS, 0.5F - RADIUS, 0.5F + RADIUS, .5F + RADIUS, 0.5F + RADIUS); protected BlockTFThornRose() { - super(Material.plants); - + super(Material.PLANTS); + this.setHardness(10.0F); - this.setStepSound(soundTypeGrass); + this.setSoundType(SoundType.PLANT); this.setCreativeTab(TFItems.creativeTab); - - float radius = 0.4F; - this.setBlockBounds(0.5F - radius, 0.5F - radius, 0.5F - radius, 0.5F + radius, .5F + radius, 0.5F + radius); } - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return 1; - } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - public boolean renderAsNormalBlock() - { - return false; - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - public boolean isOpaqueCube() - { - return false; - } - - /** - * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z - */ - public boolean canPlaceBlockAt(World world, int x, int y, int z) - { - return canBlockStay(world, x, y, z); - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) - { - return null; - } - - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor Block - */ - public void onNeighborBlockChange(World world, int x, int y, int z, Block block) - { - if (!canBlockStay(world, x, y, z)) { - this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); - world.setBlockToAir(x, y, z); - } - } - - /** - * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. - */ - public boolean canBlockStay(World world, int x, int y, int z) { - boolean supported = false; - - for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { - int dx = x + dir.offsetX; - int dy = y + dir.offsetY; - int dz = z + dir.offsetZ; - - if (world.getBlock(dx, dy, dz).canSustainLeaves(world, dx, dy, dz)) { - supported = true; - } - } - return supported; + + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return AABB; + } + + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } + + @Override + public boolean canPlaceBlockAt(World world, BlockPos pos) { + return canBlockStay(world, pos); } + @Override + @Deprecated + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return NULL_AABB; + } + + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) { + if (!canBlockStay(world, pos)) { + world.destroyBlock(pos, true); + } + } + + private boolean canBlockStay(World world, BlockPos pos) { + for (EnumFacing dir : EnumFacing.VALUES) { + BlockPos pos_ = pos.offset(dir); + IBlockState state = world.getBlockState(pos_); + + if (state.getBlock().canSustainLeaves(state, world, pos_)) { + return true; + } + } + return false; + } + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + } } diff --git a/src/main/java/twilightforest/block/BlockTFThorns.java b/src/main/java/twilightforest/block/BlockTFThorns.java index c3cc96771c..f0f8c4ac92 100644 --- a/src/main/java/twilightforest/block/BlockTFThorns.java +++ b/src/main/java/twilightforest/block/BlockTFThorns.java @@ -1,293 +1,232 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.EnumPushReaction; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.pathfinding.PathNodeType; +import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.DamageSource; -import net.minecraft.util.IIcon; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.Leaves3Variant; +import twilightforest.enums.ThornVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class BlockTFThorns extends BlockRotatedPillar { - - private static final float THORN_DAMAGE = 4.0F; - - private String[] names; - private IIcon sideIcons[]; - private IIcon topIcons[]; - - protected BlockTFThorns() { - super(Material.wood); - - this.setNames(new String[] {"brown", "green"}); - +import twilightforest.util.WorldUtil; + +import java.util.Random; + +public class BlockTFThorns extends BlockTFConnectableRotatedPillar implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", ThornVariant.class); + + private static final float THORN_DAMAGE = 4.0F; + + BlockTFThorns() { + super(Material.WOOD, MapColor.OBSIDIAN, 10); this.setHardness(50.0F); this.setResistance(2000.0F); - this.setStepSound(soundTypeWood); + this.setSoundType(SoundType.WOOD); this.setCreativeTab(TFItems.creativeTab); + + if (hasVariant()) { + this.setDefaultState(this.getDefaultState().withProperty(VARIANT, ThornVariant.BROWN)); + } + } + + @Override + protected IProperty[] getAdditionalProperties() { + return new IProperty[]{VARIANT}; + } + + protected boolean hasVariant() { + return true; + } + + @Override + public int getMetaFromState(IBlockState state) { + return hasVariant() ? super.getMetaFromState(state) | state.getValue(VARIANT).ordinal() : super.getMetaFromState(state); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return hasVariant() ? super.getStateFromMeta(meta).withProperty(VARIANT, ThornVariant.values()[meta & 0b11]) : super.getStateFromMeta(meta); + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.getValue(VARIANT) == ThornVariant.GREEN ? MapColor.FOLIAGE : super.getMapColor(state, world, pos); + } + + @Override + protected boolean canConnectTo(IBlockState state, IBlockState otherState, IBlockAccess world, BlockPos pos, EnumFacing connectTo) { + return (otherState.getBlock() instanceof BlockTFThorns + || otherState.getBlock() == TFBlocks.thorn_rose + ||(otherState.getBlock() == TFBlocks.twilight_leaves_3 && otherState.getValue(BlockTFLeaves3.VARIANT) == Leaves3Variant.THORN) + || otherState.getMaterial() == Material.GRASS + || otherState.getMaterial() == Material.GROUND) + || super.canConnectTo(state, otherState, world, pos, connectTo); + } + + @Override + public int damageDropped(IBlockState state) { + return hasVariant() ? state.getValue(VARIANT).ordinal() : 0; + } + + @Override + public PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos) { + return PathNodeType.DAMAGE_CACTUS; + } + + @Override + public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity) { + entity.attackEntityFrom(DamageSource.CACTUS, THORN_DAMAGE); + } + + @Override + public void onEntityWalk(World world, BlockPos pos, Entity entity) { + IBlockState state = world.getBlockState(pos); + + if (state.getBlock() instanceof BlockTFThorns && state.getValue(AXIS) == EnumFacing.Axis.Y) + onEntityCollision(world, pos, state, entity); + + super.onEntityWalk(world, pos, entity); + } + + @Override + public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean harvest) { + if (!player.capabilities.isCreativeMode) { + if (!world.isRemote) { + // grow back + world.setBlockState(pos, state, 2); + // grow more + this.doThornBurst(world, pos, state); + } + } else { + world.setBlockToAir(pos); + } + + return true; } - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getThornsBlockRenderID(); - } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - public boolean renderAsNormalBlock() - { - return false; - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - public boolean isOpaqueCube() - { - return false; - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) - { - int meta = world.getBlockMetadata(x, y, z); - - int rotation = meta & 12; - float pixel = 0.0625F; - - switch (rotation) { - case 0: - default: - return AxisAlignedBB.getBoundingBox(x + pixel * 3F, y, z + pixel * 3F, x + 1F - pixel * 3F, y + 1F, z + 1F - pixel * 3F); - case 4: - return AxisAlignedBB.getBoundingBox(x, y + pixel * 3F, z + pixel * 3F, x + 1F, y + 1F - pixel * 3F, z + 1F - pixel * 3F); - case 8: - return AxisAlignedBB.getBoundingBox(x + pixel * 3F, y + pixel * 3F, z, x + 1F - pixel * 3F, y + 1F - pixel * 3F, z + 1F); - } - - } - - /** - * Returns the bounding box of the wired rectangular prism to render. - */ - @SideOnly(Side.CLIENT) - public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int x, int y, int z) - { - return this.getCollisionBoundingBoxFromPool(world, x, y, z); - } - - - /** - * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity - */ - public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) - { - entity.attackEntityFrom(DamageSource.cactus, THORN_DAMAGE); - } - - /** - * When we are chopped, things get bad - */ - public boolean removedByPlayer(World world, EntityPlayer player, int x, int y, int z) { - int meta = world.getBlockMetadata(x, y, z); - if (!player.capabilities.isCreativeMode) { - if (!world.isRemote) { - // grow back - world.setBlock(x, y, z, this, (meta & 12) | 1, 2); - // grow more - this.doThornBurst(world, x, y, z, meta); - } - } else { - world.setBlockToAir(x, y, z); - } - - return true; - } - - /** - * Returns the mobility information of the block, 0 = free, 1 = can't push but can move over, 2 = total immobility - * and stop pistons - */ - public int getMobilityFlag() - { - return 2; - } - - /** - * Grow thorns out of both the ends, then maybe in another direction too - */ - private void doThornBurst(World world, int x, int y, int z, int meta) { - int rotation = meta & 12; - - switch (rotation) { - case 0: - growThorns(world, x, y, z, ForgeDirection.UP); - growThorns(world, x, y, z, ForgeDirection.DOWN); - break; - case 4: - growThorns(world, x, y, z, ForgeDirection.EAST); - growThorns(world, x, y, z, ForgeDirection.WEST); - break; - case 8: - growThorns(world, x, y, z, ForgeDirection.NORTH); - growThorns(world, x, y, z, ForgeDirection.SOUTH); - break; + + @Override + @Deprecated + public EnumPushReaction getPushReaction(IBlockState state) { + return EnumPushReaction.BLOCK; + } + + /** + * Grow thorns out of both the ends, then maybe in another direction too + */ + private void doThornBurst(World world, BlockPos pos, IBlockState state) { + switch (state.getValue(AXIS)) { + case Y: + growThorns(world, pos, EnumFacing.UP); + growThorns(world, pos, EnumFacing.DOWN); + break; + case X: + growThorns(world, pos, EnumFacing.EAST); + growThorns(world, pos, EnumFacing.WEST); + break; + case Z: + growThorns(world, pos, EnumFacing.NORTH); + growThorns(world, pos, EnumFacing.SOUTH); + break; } - - // also try three random directions - growThorns(world, x, y, z, ForgeDirection.VALID_DIRECTIONS[world.rand.nextInt(ForgeDirection.VALID_DIRECTIONS.length)]); - growThorns(world, x, y, z, ForgeDirection.VALID_DIRECTIONS[world.rand.nextInt(ForgeDirection.VALID_DIRECTIONS.length)]); - growThorns(world, x, y, z, ForgeDirection.VALID_DIRECTIONS[world.rand.nextInt(ForgeDirection.VALID_DIRECTIONS.length)]); + // also try three random directions + growThorns(world, pos, EnumFacing.random(world.rand)); + growThorns(world, pos, EnumFacing.random(world.rand)); + growThorns(world, pos, EnumFacing.random(world.rand)); } - /** - * grow several green thorns in the specified direction - */ - private void growThorns(World world, int x, int y, int z, ForgeDirection dir) { + /** + * grow several green thorns in the specified direction + */ + private void growThorns(World world, BlockPos pos, EnumFacing dir) { int length = 1 + world.rand.nextInt(3); - + for (int i = 1; i < length; i++) { - int dx = x + (dir.offsetX * i); - int dy = y + (dir.offsetY * i); - int dz = z + (dir.offsetZ * i); - - if (world.isAirBlock(dx, dy, dz)) { - world.setBlock(dx, dy, dz, this, getMetaFor(dir) | 1, 2); + BlockPos dPos = pos.offset(dir, i); + + if (world.isAirBlock(dPos)) { + world.setBlockState(dPos, getDefaultState().withProperty(AXIS, dir.getAxis()).withProperty(VARIANT, ThornVariant.GREEN), 2); } else { break; } } } - /** - * Get the meta we need to place a new block in the specified direction - * @param dir - * @return - */ - public static int getMetaFor(ForgeDirection dir) { - switch (dir) { - case UNKNOWN: - default: - case UP: - case DOWN: - return 0; - case EAST: - case WEST: - return 4; - case NORTH: - case SOUTH: - return 8; + @Override + public void breakBlock(World world, BlockPos pos, IBlockState state) { + int range = 4; + int exRange = range + 1; + + if (world.isAreaLoaded(pos, exRange)) { + for (BlockPos pos_ : WorldUtil.getAllAround(pos, range)) { + IBlockState state_ = world.getBlockState(pos_); + if (state_.getBlock().isLeaves(state_, world, pos_)) { + state.getBlock().beginLeavesDecay(state_, world, pos_); + } + } } } - - /** - * Like logs, we start leaf decay when broken - */ - public void breakBlock(World world, int x, int y, int z, Block logBlock, int metadata) - { - byte range = 4; - int exRange = range + 1; - - if (world.checkChunksExist(x - exRange, y - exRange, z - exRange, x + exRange, y + exRange, z + exRange)) - { - for (int dx = -range; dx <= range; ++dx) - { - for (int dy = -range; dy <= range; ++dy) - { - for (int dz = -range; dz <= range; ++dz) - { - Block block = world.getBlock(x + dx, y + dy, z + dz); - if (block.isLeaves(world, x + dx, y + dy, z + dz)) - { - block.beginLeavesDecay(world, x + dx, y + dy, z + dz); - } - } - } - } - } - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random p_149745_1_) - { - return 0; - } - - @SideOnly(Side.CLIENT) + @Override - protected IIcon getSideIcon(int meta) { - return this.sideIcons[meta & 3]; + public int quantityDropped(Random random) { + return 0; } - @SideOnly(Side.CLIENT) - protected IIcon getTopIcon(int meta) - { - return this.topIcons[meta & 3]; - } - - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister iconRegister) - { - this.sideIcons = new IIcon[getNames().length]; - this.topIcons = new IIcon[getNames().length]; - - for (int i = 0; i < getNames().length; i++) { - this.sideIcons[i] = iconRegister.registerIcon(TwilightForestMod.ID + ":" + getNames()[i] + "_thorns_side"); - this.topIcons[i] = iconRegister.registerIcon(TwilightForestMod.ID + ":" + getNames()[i] + "_thorns_top"); - } - } - - @Override - public boolean canSustainLeaves(IBlockAccess world, int x, int y, int z) - { - return true; - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - for (int i = 0; i < getNames().length; i++) { - par3List.add(new ItemStack(par1, 1, i)); - } - } - - public String[] getNames() { - return names; + public boolean canSustainLeaves(IBlockState state, IBlockAccess world, BlockPos pos) { + return true; } - public void setNames(String[] names) { - this.names = names; + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + int n = hasVariant() ? ThornVariant.values().length : 1; + for (int i = 0; i < n; i++) { + list.add(new ItemStack(this, 1, i)); + } + } + + @Override + public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face) { + return face.getAxis() != state.getValue(AXIS) ? BlockFaceShape.MIDDLE_POLE_THICK : BlockFaceShape.CENTER_BIG; + } + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } + + @SideOnly(Side.CLIENT) + @Override + @Deprecated + public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { + return (blockAccess.getBlockState(pos.offset(side)).getBlock() instanceof BlockTFThorns || super.shouldSideBeRendered(blockState, blockAccess, pos, side)); } } diff --git a/src/main/java/twilightforest/block/BlockTFTowerDevice.java b/src/main/java/twilightforest/block/BlockTFTowerDevice.java index 11997dc59d..5530f40a18 100644 --- a/src/main/java/twilightforest/block/BlockTFTowerDevice.java +++ b/src/main/java/twilightforest/block/BlockTFTowerDevice.java @@ -1,789 +1,534 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; -import net.minecraft.block.BlockSourceImpl; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.IIcon; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.Explosion; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.advancements.TFAdvancements; +import twilightforest.enums.TowerDeviceVariant; +import twilightforest.enums.TowerTranslucentVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import twilightforest.tileentity.TileEntityTFCReactorActive; -import twilightforest.tileentity.TileEntityTFGhastTrapActive; -import twilightforest.tileentity.TileEntityTFGhastTrapInactive; -import twilightforest.tileentity.TileEntityTFReverter; -import twilightforest.tileentity.TileEntityTFTowerBuilder; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - - - -/** - * - * Tower wood is a type of plank block that forms the walls of Dark Towers - * - * @author Ben - * - */ -public class BlockTFTowerDevice extends Block { - - private static IIcon TEX_REAPPEARING_INACTIVE; - private static IIcon TEX_REAPPEARING_ACTIVE; - private static IIcon TEX_VANISH_INACTIVE; - private static IIcon TEX_VANISH_ACTIVE; - private static IIcon TEX_VANISH_LOCKED; - private static IIcon TEX_VANISH_UNLOCKED; - private static IIcon TEX_BUILDER_INACTIVE; - private static IIcon TEX_BUILDER_ACTIVE; - private static IIcon TEX_ANTIBUILDER; - private static IIcon TEX_BUILDER_TIMEOUT; - private static IIcon TEX_GHASTTRAP_INACTIVE; - private static IIcon TEX_GHASTTRAP_ACTIVE; - private static IIcon TEX_REACTOR_INACTIVE; - private static IIcon TEX_REACTOR_ACTIVE; - private static IIcon TEX_GHASTTRAP_LID_INACTIVE; - private static IIcon TEX_GHASTTRAP_LID_ACTIVE; - private static IIcon TEX_SMOKER_ACTIVE; - private static IIcon TEX_SMOKER_INACTIVE; - private static IIcon TEX_FIREJET_ACTIVE; - private static IIcon TEX_FIREJET_INACTIVE; - - public static final int META_REAPPEARING_INACTIVE = 0; - public static final int META_REAPPEARING_ACTIVE = 1; - public static final int META_VANISH_INACTIVE = 2; - public static final int META_VANISH_ACTIVE = 3; - public static final int META_VANISH_LOCKED = 4; - public static final int META_VANISH_UNLOCKED = 5; - public static final int META_BUILDER_INACTIVE = 6; - public static final int META_BUILDER_ACTIVE = 7; - public static final int META_BUILDER_TIMEOUT = 8; - public static final int META_ANTIBUILDER = 9; - public static final int META_GHASTTRAP_INACTIVE = 10; - public static final int META_GHASTTRAP_ACTIVE = 11; - public static final int META_REACTOR_INACTIVE = 12; - public static final int META_REACTOR_ACTIVE = 13; - - public BlockTFTowerDevice() - { - super(Material.wood); - this.setHardness(10F); - this.setResistance(35F); - this.setStepSound(Block.soundTypeWood); +import twilightforest.tileentity.*; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +public class BlockTFTowerDevice extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", TowerDeviceVariant.class); + + public BlockTFTowerDevice() { + super(Material.WOOD, MapColor.SAND); + this.setHardness(10F); + this.setResistance(35F); + this.setSoundType(SoundType.WOOD); this.setCreativeTab(TFItems.creativeTab); - } - - /** - * How many world ticks before ticking - */ - public int tickRate() - { - return 15; - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, TowerDeviceVariant.REAPPEARING_INACTIVE)); + } + @Override - public IIcon getIcon(int side, int meta) { - switch (meta) - { - case META_REAPPEARING_INACTIVE: - default: - return TEX_REAPPEARING_INACTIVE; - case META_REAPPEARING_ACTIVE: - return TEX_REAPPEARING_ACTIVE; - case META_VANISH_INACTIVE: - return TEX_VANISH_INACTIVE; - case META_VANISH_ACTIVE: - return TEX_VANISH_ACTIVE; - case META_VANISH_LOCKED: - return TEX_VANISH_LOCKED; - case META_VANISH_UNLOCKED: - return TEX_VANISH_UNLOCKED; - case META_BUILDER_INACTIVE: - return TEX_BUILDER_INACTIVE; - case META_BUILDER_TIMEOUT: - return TEX_BUILDER_TIMEOUT; - case META_BUILDER_ACTIVE: - return TEX_BUILDER_ACTIVE; - case META_ANTIBUILDER: - return TEX_ANTIBUILDER; - case META_GHASTTRAP_INACTIVE: - if (side >= 2) - { - return TEX_GHASTTRAP_INACTIVE; - } - else if (side == 1) - { - return TEX_GHASTTRAP_LID_INACTIVE; - } - else - { - return TFBlocks.towerWood.getIcon(side, 1); - } - case META_GHASTTRAP_ACTIVE: - if (side >= 2) - { - return TEX_GHASTTRAP_ACTIVE; + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, TowerDeviceVariant.values()[meta]); + } + + @Override + public int tickRate(World world) { + return 15; + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + list.add(new ItemStack(this, 1, TowerDeviceVariant.REAPPEARING_INACTIVE.ordinal())); + list.add(new ItemStack(this, 1, TowerDeviceVariant.VANISH_INACTIVE.ordinal())); + list.add(new ItemStack(this, 1, TowerDeviceVariant.VANISH_LOCKED.ordinal())); + list.add(new ItemStack(this, 1, TowerDeviceVariant.VANISH_UNLOCKED.ordinal())); + list.add(new ItemStack(this, 1, TowerDeviceVariant.BUILDER_INACTIVE.ordinal())); + list.add(new ItemStack(this, 1, TowerDeviceVariant.ANTIBUILDER.ordinal())); + list.add(new ItemStack(this, 1, TowerDeviceVariant.GHASTTRAP_INACTIVE.ordinal())); + list.add(new ItemStack(this, 1, TowerDeviceVariant.REACTOR_INACTIVE.ordinal())); + } + + @Override + public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + + TowerDeviceVariant variant = state.getValue(VARIANT); + + if (variant == TowerDeviceVariant.VANISH_INACTIVE) { + if (areBlocksLocked(world, pos)) { + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_OFF, SoundCategory.BLOCKS, 1.0F, 0.3F); + } else { + changeToActiveVanishBlock(world, pos, TowerDeviceVariant.VANISH_ACTIVE); } - else if (side == 1) - { - return TEX_GHASTTRAP_LID_ACTIVE; + return true; + + } else if (variant == TowerDeviceVariant.REAPPEARING_INACTIVE) { + if (areBlocksLocked(world, pos)) { + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_OFF, SoundCategory.BLOCKS, 1.0F, 0.3F); + } else { + changeToActiveVanishBlock(world, pos, TowerDeviceVariant.REAPPEARING_ACTIVE); } - else - { - return TFBlocks.towerWood.getIcon(side, 1); - } - case META_REACTOR_INACTIVE: - return TEX_REACTOR_INACTIVE; - case META_REACTOR_ACTIVE: - return TEX_REACTOR_ACTIVE; + return true; } + return false; } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFTowerDevice.TEX_REAPPEARING_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_reappearing_off"); - BlockTFTowerDevice.TEX_REAPPEARING_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_reappearing_on"); - BlockTFTowerDevice.TEX_VANISH_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_vanish_off"); - BlockTFTowerDevice.TEX_VANISH_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_vanish_on"); - BlockTFTowerDevice.TEX_VANISH_LOCKED = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_lock_on"); - BlockTFTowerDevice.TEX_VANISH_UNLOCKED = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_lock_off"); - BlockTFTowerDevice.TEX_BUILDER_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_builder_off"); - BlockTFTowerDevice.TEX_BUILDER_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_builder_on"); - BlockTFTowerDevice.TEX_ANTIBUILDER = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_antibuilder"); - BlockTFTowerDevice.TEX_BUILDER_TIMEOUT = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_builder_timeout"); - BlockTFTowerDevice.TEX_GHASTTRAP_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_ghasttrap_off"); - BlockTFTowerDevice.TEX_GHASTTRAP_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_ghasttrap_on"); - BlockTFTowerDevice.TEX_REACTOR_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_reactor_off"); - BlockTFTowerDevice.TEX_REACTOR_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_reactor_on"); - BlockTFTowerDevice.TEX_GHASTTRAP_LID_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_ghasttraplid_off"); - BlockTFTowerDevice.TEX_GHASTTRAP_LID_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_ghasttraplid_on"); - BlockTFTowerDevice.TEX_SMOKER_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_smoker_off"); - BlockTFTowerDevice.TEX_SMOKER_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_smoker_on"); - BlockTFTowerDevice.TEX_FIREJET_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_firejet_off"); - BlockTFTowerDevice.TEX_FIREJET_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_firejet_on"); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, META_REAPPEARING_INACTIVE)); - par3List.add(new ItemStack(par1, 1, META_VANISH_INACTIVE)); - par3List.add(new ItemStack(par1, 1, META_VANISH_LOCKED)); - par3List.add(new ItemStack(par1, 1, META_VANISH_UNLOCKED)); - par3List.add(new ItemStack(par1, 1, META_BUILDER_INACTIVE)); - par3List.add(new ItemStack(par1, 1, META_ANTIBUILDER)); - par3List.add(new ItemStack(par1, 1, META_GHASTTRAP_INACTIVE)); - par3List.add(new ItemStack(par1, 1, META_REACTOR_INACTIVE)); - } - - /** - * Called upon block activation (right click on the block.) - */ - @Override - public boolean onBlockActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) - { - int meta = par1World.getBlockMetadata(x, y, z); - - if (meta == META_VANISH_INACTIVE) - { - if (areNearbyLockBlocks(par1World, x, y, z)) - { - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 1.0F, 0.3F); - } - else - { - changeToActiveVanishBlock(par1World, x, y, z, META_VANISH_ACTIVE); - } - return true; - } - if (meta == META_REAPPEARING_INACTIVE) - { - if (areNearbyLockBlocks(par1World, x, y, z)) - { - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 1.0F, 0.3F); - } - else - { - changeToActiveVanishBlock(par1World, x, y, z, META_REAPPEARING_ACTIVE); - } - return true; - } - else - { - return false; - } - } - - /** - * Location sensitive version of getExplosionRestance - * - * @param par1Entity The entity that caused the explosion - * @param world The current world - * @param x X Position - * @param y Y Position - * @param z Z Position - * @param explosionX Explosion source X Position - * @param explosionY Explosion source X Position - * @param explosionZ Explosion source X Position - * @return The amount of the explosion absorbed. - */ - @Override - public float getExplosionResistance(Entity par1Entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ) - { - int meta = world.getBlockMetadata(x, y, z); - - if (meta == META_VANISH_INACTIVE) - { - return 6000F; - } - else if (meta == META_VANISH_LOCKED) - { - return 6000000.0F; - } - else - { - return super.getExplosionResistance(par1Entity, world, x, y, z, explosionX, explosionY, explosionZ); - } - } - - /** - * Returns the block hardness at a location. Args: world, x, y, z - */ - @Override - public float getBlockHardness(World world, int x, int y, int z) - { - // most vanish blocks can't be broken - int meta = world.getBlockMetadata(x, y, z); - - switch (meta) - { - case META_REAPPEARING_ACTIVE : - case META_VANISH_INACTIVE : - case META_VANISH_ACTIVE : - case META_VANISH_LOCKED : - case META_VANISH_UNLOCKED : - return -1; - default : - return super.getBlockHardness(world, x, y, z); - } - } - - /** - * Are any of the 26 adjacent blocks a locked vanishing block? - */ - public static boolean areNearbyLockBlocks(World world, int x, int y, int z) - { - boolean locked = false; - - //TODO: this is hacky. We really need to determine the exact blocks of the door and check those for locks. - for (int dx = x - 2; dx <= x + 2; dx++) - { - for (int dy = y - 2; dy <= y + 2; dy++) - { - for (int dz = z - 2; dz <= z + 2; dz++) - { - if (world.getBlock(dx, dy, dz) == TFBlocks.towerDevice && world.getBlockMetadata(dx, dy, dz) == META_VANISH_LOCKED) - { - locked = true; - } + + @Override + public float getExplosionResistance(World world, BlockPos pos, @Nullable Entity exploder, Explosion explosion) { + switch (world.getBlockState(pos).getValue(VARIANT)) { + case VANISH_INACTIVE: + return 6000F; + case VANISH_LOCKED: + return 6000000.0F; + default: + return super.getExplosionResistance(world, pos, exploder, explosion); + } + } + + @Override + @Deprecated + public float getBlockHardness(IBlockState state, World world, BlockPos pos) { + // most vanish blocks can't be broken + switch (state.getValue(VARIANT)) { + case REAPPEARING_ACTIVE: + case VANISH_INACTIVE: + case VANISH_ACTIVE: + case VANISH_LOCKED: + case VANISH_UNLOCKED: + return -1; + default: + return super.getBlockHardness(state, world, pos); + } + } + + @Override + public boolean canEntityDestroy(IBlockState state, IBlockAccess world, BlockPos pos, Entity entity) { + switch (state.getValue(VARIANT)) { + case VANISH_INACTIVE: + return !areBlocksLocked(world, pos); + case VANISH_LOCKED: + return false; + default: + return super.canEntityDestroy(state, world, pos, entity); + } + } + + /** + * Are any of the connected tower device blocks a locked vanishing block? + */ + private static boolean areBlocksLocked(IBlockAccess world, BlockPos pos) { + Set checked = new HashSet<>(); + checked.add(pos); + return areBlocksLocked(world, pos, checked); + } + + private static boolean areBlocksLocked(IBlockAccess world, BlockPos pos, Set checked) { + for (EnumFacing facing : EnumFacing.values()) { + BlockPos offset = pos.offset(facing); + if (!checked.add(offset)) continue; + IBlockState state = world.getBlockState(offset); + if (state.getBlock() == TFBlocks.tower_device) { + if (state.getValue(VARIANT) == TowerDeviceVariant.VANISH_LOCKED) { + return true; + } + if (areBlocksLocked(world, offset, checked)) { + return true; } } } - - return locked; + return false; } /** - * Change this block into an different device block - */ - public static void unlockBlock(World par1World, int x, int y, int z) - { - Block thereBlockID = par1World.getBlock(x, y, z); - int thereBlockMeta = par1World.getBlockMetadata(x, y, z); - - if (thereBlockID == TFBlocks.towerDevice || thereBlockMeta == META_VANISH_LOCKED) - { - changeToBlockMeta(par1World, x, y, z, META_VANISH_UNLOCKED); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); + * Change this block into an different device block + */ + public static void unlockBlock(World world, BlockPos pos) { + IBlockState thereState = world.getBlockState(pos); + + if (thereState.getBlock() == TFBlocks.tower_device || thereState.getValue(BlockTFTowerDevice.VARIANT) == TowerDeviceVariant.VANISH_LOCKED) { + changeToBlockState(world, pos, thereState.withProperty(VARIANT, TowerDeviceVariant.VANISH_UNLOCKED)); + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.6F); + } + } + + /** + * Change this block into an different device block + */ + private static void changeToBlockState(World world, BlockPos pos, IBlockState state) { + Block thereBlock = world.getBlockState(pos).getBlock(); + + if (thereBlock == TFBlocks.tower_device || thereBlock == TFBlocks.tower_translucent) { + world.setBlockState(pos, state, 3); + world.markBlockRangeForRenderUpdate(pos, pos); + world.notifyNeighborsRespectDebug(pos, thereBlock, false); + } + } + + @Override + public void onBlockAdded(World world, BlockPos pos, IBlockState state) { + + if (world.isRemote) return; + + if (state.getValue(VARIANT) == TowerDeviceVariant.BUILDER_INACTIVE && world.isBlockPowered(pos)) { + changeToBlockState(world, pos, state.withProperty(VARIANT, TowerDeviceVariant.BUILDER_ACTIVE)); + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.6F); + } + } + + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) { + + if (world.isRemote) return; + + TowerDeviceVariant variant = state.getValue(VARIANT); + + if (variant == TowerDeviceVariant.VANISH_INACTIVE && world.isBlockPowered(pos) && !areBlocksLocked(world, pos)) { + changeToActiveVanishBlock(world, pos, TowerDeviceVariant.VANISH_ACTIVE); + } + + if (variant == TowerDeviceVariant.REAPPEARING_INACTIVE && world.isBlockPowered(pos) && !areBlocksLocked(world, pos)) { + changeToActiveVanishBlock(world, pos, TowerDeviceVariant.REAPPEARING_ACTIVE); + } + + if (variant == TowerDeviceVariant.BUILDER_INACTIVE && world.isBlockPowered(pos)) { + changeToBlockState(world, pos, state.withProperty(VARIANT, TowerDeviceVariant.BUILDER_ACTIVE)); + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.6F); + world.scheduleUpdate(pos, this, 4); + } + + if (variant == TowerDeviceVariant.BUILDER_ACTIVE && !world.isBlockPowered(pos)) { + changeToBlockState(world, pos, state.withProperty(VARIANT, TowerDeviceVariant.BUILDER_INACTIVE)); + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.6F); + world.scheduleUpdate(pos, this, 4); + } + + if (variant == TowerDeviceVariant.BUILDER_TIMEOUT && !world.isBlockPowered(pos)) { + changeToBlockState(world, pos, state.withProperty(VARIANT, TowerDeviceVariant.BUILDER_INACTIVE)); + } + + if (variant == TowerDeviceVariant.GHASTTRAP_INACTIVE && isInactiveTrapCharged(world, pos) && world.isBlockPowered(pos)) { + for (EntityPlayerMP player : world.getEntitiesWithinAABB(EntityPlayerMP.class, new AxisAlignedBB(pos).grow(6.0D))) { + TFAdvancements.ACTIVATED_GHAST_TRAP.trigger(player); + } + + changeToBlockState(world, pos, state.withProperty(VARIANT, TowerDeviceVariant.GHASTTRAP_ACTIVE)); + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.6F); + world.scheduleUpdate(pos, this, 4); + } + + if (variant == TowerDeviceVariant.REACTOR_INACTIVE && isReactorReady(world, pos)) { + // check if we should fire up the reactor + changeToBlockState(world, pos, state.withProperty(VARIANT, TowerDeviceVariant.REACTOR_ACTIVE)); + } + } + + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random random) { + + if (world.isRemote) return; + + TowerDeviceVariant variant = state.getValue(VARIANT); + + if (variant == TowerDeviceVariant.VANISH_ACTIVE || variant == TowerDeviceVariant.REAPPEARING_ACTIVE) { + if (variant == TowerDeviceVariant.VANISH_ACTIVE) { + world.setBlockToAir(pos); + } else { + world.setBlockState(pos, TFBlocks.tower_translucent.getDefaultState().withProperty(BlockTFTowerTranslucent.VARIANT, TowerTranslucentVariant.REAPPEARING_INACTIVE)); + world.scheduleUpdate(pos, TFBlocks.tower_translucent, 80); + } + world.notifyNeighborsRespectDebug(pos, this, false); + world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 0.3F, 0.5F); + //world.markBlockRangeForRenderUpdate(x, y, z, x, y, z); + + // activate all adjacent inactive vanish blocks + for (EnumFacing e : EnumFacing.VALUES) { + checkAndActivateVanishBlock(world, pos.offset(e)); + } + } + + if (variant == TowerDeviceVariant.BUILDER_ACTIVE && world.isBlockPowered(pos)) { + this.letsBuild(world, pos); + } + + if (variant == TowerDeviceVariant.BUILDER_INACTIVE || variant == TowerDeviceVariant.BUILDER_TIMEOUT) { + // activate all adjacent inactive vanish blocks + for (EnumFacing e : EnumFacing.VALUES) { + checkAndActivateVanishBlock(world, pos.offset(e)); + } } } - /** - * Change this block into an different device block - */ - private static void changeToBlockMeta(World par1World, int x, int y, int z, int meta) - { - Block thereBlockID = par1World.getBlock(x, y, z); - - if (thereBlockID == TFBlocks.towerDevice || thereBlockID == TFBlocks.towerTranslucent) - { - par1World.setBlock(x, y, z, thereBlockID, meta, 3); - par1World.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - par1World.notifyBlocksOfNeighborChange(x, y, z, thereBlockID); + * Start the builder block tileentity building! + */ + private void letsBuild(World world, BlockPos pos) { + TileEntityTFTowerBuilder tileEntity = (TileEntityTFTowerBuilder) world.getTileEntity(pos); + + if (tileEntity != null && !tileEntity.makingBlocks) { + tileEntity.startBuilding(); } } - - /** - * Called whenever the block is added into the world. Args: world, x, y, z - */ - @Override - public void onBlockAdded(World par1World, int x, int y, int z) - { - int meta = par1World.getBlockMetadata(x, y, z); - - if (!par1World.isRemote) - { - if (meta == META_BUILDER_INACTIVE && par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - changeToBlockMeta(par1World, x, y, z, META_BUILDER_ACTIVE); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); - } - - } - - } - - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor blockID - */ - @Override - public void onNeighborBlockChange(World par1World, int x, int y, int z, Block myBlockID) - { - int meta = par1World.getBlockMetadata(x, y, z); - - if (!par1World.isRemote) - { - if (meta == META_VANISH_INACTIVE && par1World.isBlockIndirectlyGettingPowered(x, y, z) && !areNearbyLockBlocks(par1World, x, y, z)) - { - changeToActiveVanishBlock(par1World, x, y, z, META_VANISH_ACTIVE); - } - - if (meta == META_REAPPEARING_INACTIVE && par1World.isBlockIndirectlyGettingPowered(x, y, z) && !areNearbyLockBlocks(par1World, x, y, z)) - { - changeToActiveVanishBlock(par1World, x, y, z, META_REAPPEARING_ACTIVE); - } - - if (meta == META_BUILDER_INACTIVE && par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - changeToBlockMeta(par1World, x, y, z, META_BUILDER_ACTIVE); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); - - par1World.scheduleBlockUpdate(x, y, z, this, 4); - } - - if (meta == META_BUILDER_ACTIVE && !par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - changeToBlockMeta(par1World, x, y, z, META_BUILDER_INACTIVE); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); - - par1World.scheduleBlockUpdate(x, y, z, this, 4); - } - - if (meta == META_BUILDER_TIMEOUT && !par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - changeToBlockMeta(par1World, x, y, z, META_BUILDER_INACTIVE); - } - - if (meta == META_GHASTTRAP_INACTIVE && isInactiveTrapCharged(par1World, x, y, z) && par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - changeToBlockMeta(par1World, x, y, z, META_GHASTTRAP_ACTIVE); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.6F); - - par1World.scheduleBlockUpdate(x, y, z, this, 4); - } - - if (meta == META_REACTOR_INACTIVE && isReactorReady(par1World, x, y, z)) - { - // check if we should fire up the reactor - changeToBlockMeta(par1World, x, y, z, META_REACTOR_ACTIVE); - } - } - } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World par1World, int x, int y, int z, Random par5Random) - { - if (!par1World.isRemote) - { - int meta = par1World.getBlockMetadata(x, y, z); - - if (meta == META_VANISH_ACTIVE || meta == META_REAPPEARING_ACTIVE) - { - if (meta == META_VANISH_ACTIVE) - { - par1World.setBlock(x, y, z, Blocks.air, 0, 3); - } - else - { - par1World.setBlock(x, y, z, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_REAPPEARING_INACTIVE, 3); - par1World.scheduleBlockUpdate(x, y, z, TFBlocks.towerTranslucent, 80); - } - par1World.notifyBlocksOfNeighborChange(x, y, z, this); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.pop", 0.3F, 0.5F); - //par1World.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - - // activate all adjacent inactive vanish blocks - checkAndActivateVanishBlock(par1World, x - 1, y, z); - checkAndActivateVanishBlock(par1World, x + 1, y, z); - checkAndActivateVanishBlock(par1World, x, y + 1, z); - checkAndActivateVanishBlock(par1World, x, y - 1, z); - checkAndActivateVanishBlock(par1World, x, y, z + 1); - checkAndActivateVanishBlock(par1World, x, y, z - 1); - - } - - if (meta == META_BUILDER_ACTIVE && par1World.isBlockIndirectlyGettingPowered(x, y, z)) - { - this.letsBuild(par1World, x, y, z); - } - - if (meta == META_BUILDER_INACTIVE || meta == META_BUILDER_TIMEOUT) - { - // activate all adjacent inactive vanish blocks - checkAndActivateVanishBlock(par1World, x - 1, y, z); - checkAndActivateVanishBlock(par1World, x + 1, y, z); - checkAndActivateVanishBlock(par1World, x, y + 1, z); - checkAndActivateVanishBlock(par1World, x, y - 1, z); - checkAndActivateVanishBlock(par1World, x, y, z + 1); - checkAndActivateVanishBlock(par1World, x, y, z - 1); - } - } - } /** - * Start the builder block tileentity building! - */ - private void letsBuild(World par1World, int x, int y, int z) { - BlockSourceImpl blockSource = new BlockSourceImpl(par1World, x, y, z); - TileEntityTFTowerBuilder tileEntity = (TileEntityTFTowerBuilder)blockSource.getBlockTileEntity(); - - if (tileEntity != null && !tileEntity.makingBlocks) - { - tileEntity.startBuilding(); - } - - } - - /** * Check if the inactive trap block is fully charged */ - private boolean isInactiveTrapCharged(World par1World, int x, int y, int z) - { - BlockSourceImpl blockSource = new BlockSourceImpl(par1World, x, y, z); - TileEntityTFGhastTrapInactive tileEntity = (TileEntityTFGhastTrapInactive)blockSource.getBlockTileEntity(); - - if (tileEntity != null && tileEntity.isCharged()) - { - return true; - } - else - { - return false; - } - } - + private boolean isInactiveTrapCharged(World world, BlockPos pos) { + TileEntityTFGhastTrapInactive tileEntity = (TileEntityTFGhastTrapInactive) world.getTileEntity(pos); + return tileEntity != null && tileEntity.isCharged(); + } /** * Check if the reactor has all the specified things around it */ - private boolean isReactorReady(World world, int x, int y, int z) - { - if (world.getBlock(x, y + 1, z) != Blocks.redstone_block - || world.getBlock(x, y - 1, z) != Blocks.redstone_block - || world.getBlock(x + 1, y, z) != Blocks.redstone_block - || world.getBlock(x - 1, y, z) != Blocks.redstone_block - || world.getBlock(x, y, z + 1) != Blocks.redstone_block - || world.getBlock(x, y, z - 1) != Blocks.redstone_block) - { - return false; - } - - return true; + private boolean isReactorReady(World world, BlockPos pos) { + return Arrays.stream(EnumFacing.VALUES) + .allMatch(e -> world.getBlockState(pos.offset(e)).getBlock() == Blocks.REDSTONE_BLOCK); } @Override @SideOnly(Side.CLIENT) + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) { + TowerDeviceVariant variant = state.getValue(VARIANT); - /** - * A randomly called display update to be able to add particles or other items for display - */ - public void randomDisplayTick(World par1World, int x, int y, int z, Random par5Random) - { - int meta = par1World.getBlockMetadata(x, y, z); - - if (meta == META_VANISH_ACTIVE || meta == META_REAPPEARING_ACTIVE || meta == BlockTFTowerDevice.META_BUILDER_ACTIVE) - { - for (int i = 0; i < 1; ++i) { - this.sparkle(par1World, x, y, z, par5Random); - } - } - } - - /** - * Shine bright like a DIAMOND! (or actually, sparkle like redstone ore) - */ - public void sparkle(World world, int x, int y, int z, Random rand) - { - double offset = 0.0625D; - - for (int side = 0; side < 6; ++side) - { - double rx = x + rand.nextFloat(); - double ry = y + rand.nextFloat(); - double rz = z + rand.nextFloat(); - - if (side == 0 && !world.getBlock(x, y + 1, z).isOpaqueCube()) - { - ry = y + 1 + offset; - } - - if (side == 1 && !world.getBlock(x, y - 1, z).isOpaqueCube()) - { - ry = y + 0 - offset; - } - - if (side == 2 && !world.getBlock(x, y, z + 1).isOpaqueCube()) - { - rz = z + 1 + offset; - } - - if (side == 3 && !world.getBlock(x, y, z - 1).isOpaqueCube()) - { - rz = z + 0 - offset; - } - - if (side == 4 && !world.getBlock(x + 1, y, z).isOpaqueCube()) - { - rx = x + 1 + offset; - } - - if (side == 5 && !world.getBlock(x - 1, y, z).isOpaqueCube()) - { - rx = x + 0 - offset; - } - - if (rx < x || rx > x + 1 || ry < 0.0D || ry > y + 1 || rz < z || rz > z + 1) - { - world.spawnParticle("reddust", rx, ry, rz, 0.0D, 0.0D, 0.0D); - } - } - } - - /** - * If the targeted block is a vanishing block, activate it - */ - public static void checkAndActivateVanishBlock(World world, int x, int y, int z) { - Block thereID = world.getBlock(x, y, z); - int thereMeta = world.getBlockMetadata(x, y, z); - - if (thereID == TFBlocks.towerDevice && (thereMeta == META_VANISH_INACTIVE || thereMeta == META_VANISH_UNLOCKED) && !areNearbyLockBlocks(world, x, y, z)) - { - changeToActiveVanishBlock(world, x, y, z, META_VANISH_ACTIVE); - } - else if (thereID == TFBlocks.towerDevice && thereMeta == META_REAPPEARING_INACTIVE && !areNearbyLockBlocks(world, x, y, z)) - { - changeToActiveVanishBlock(world, x, y, z, META_REAPPEARING_ACTIVE); - } - else if (thereID == TFBlocks.towerTranslucent && thereMeta == BlockTFTowerTranslucent.META_BUILT_INACTIVE) - { - changeToActiveVanishBlock(world, x, y, z, BlockTFTowerTranslucent.META_BUILT_ACTIVE); - } + if (variant == TowerDeviceVariant.VANISH_ACTIVE || variant == TowerDeviceVariant.REAPPEARING_ACTIVE || variant == TowerDeviceVariant.BUILDER_ACTIVE) { + this.sparkle(world, pos); + } + } + + // [VanillaCopy] BlockRedstoneOre.spawnParticles. Unchanged. + public void sparkle(World worldIn, BlockPos pos) { + Random random = worldIn.rand; + double d0 = 0.0625D; + + for (int i = 0; i < 6; ++i) { + double d1 = (double) ((float) pos.getX() + random.nextFloat()); + double d2 = (double) ((float) pos.getY() + random.nextFloat()); + double d3 = (double) ((float) pos.getZ() + random.nextFloat()); + + if (i == 0 && !worldIn.getBlockState(pos.up()).isOpaqueCube()) { + d2 = (double) pos.getY() + d0 + 1.0D; + } + + if (i == 1 && !worldIn.getBlockState(pos.down()).isOpaqueCube()) { + d2 = (double) pos.getY() - d0; + } + + if (i == 2 && !worldIn.getBlockState(pos.south()).isOpaqueCube()) { + d3 = (double) pos.getZ() + d0 + 1.0D; + } + + if (i == 3 && !worldIn.getBlockState(pos.north()).isOpaqueCube()) { + d3 = (double) pos.getZ() - d0; + } + + if (i == 4 && !worldIn.getBlockState(pos.east()).isOpaqueCube()) { + d1 = (double) pos.getX() + d0 + 1.0D; + } + + if (i == 5 && !worldIn.getBlockState(pos.west()).isOpaqueCube()) { + d1 = (double) pos.getX() - d0; + } + + if (d1 < (double) pos.getX() || d1 > (double) (pos.getX() + 1) || d2 < 0.0D || d2 > (double) (pos.getY() + 1) || d3 < (double) pos.getZ() || d3 > (double) (pos.getZ() + 1)) { + worldIn.spawnParticle(EnumParticleTypes.REDSTONE, d1, d2, d3, 0.0D, 0.0D, 0.0D); + } + } + } + + /** + * If the targeted block is a vanishing block, activate it + */ + public static void checkAndActivateVanishBlock(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + + if (block == TFBlocks.tower_device && (state.getValue(VARIANT) == TowerDeviceVariant.VANISH_INACTIVE || state.getValue(VARIANT) == TowerDeviceVariant.VANISH_UNLOCKED) && !areBlocksLocked(world, pos)) { + changeToActiveVanishBlock(world, pos, TowerDeviceVariant.VANISH_ACTIVE); + } else if (block == TFBlocks.tower_device && state.getValue(VARIANT) == TowerDeviceVariant.REAPPEARING_INACTIVE && !areBlocksLocked(world, pos)) { + changeToActiveVanishBlock(world, pos, TowerDeviceVariant.REAPPEARING_ACTIVE); + } else if (block == TFBlocks.tower_translucent && state.getValue(BlockTFTowerTranslucent.VARIANT) == TowerTranslucentVariant.BUILT_INACTIVE) { + changeToActiveVanishBlock(world, pos, TowerTranslucentVariant.BUILT_ACTIVE); + } + } + + public static void changeToActiveVanishBlock(World world, BlockPos pos, TowerDeviceVariant variant) { + changeToActiveVanishBlock(world, pos, TFBlocks.tower_device.getDefaultState().withProperty(VARIANT, variant)); + } + + public static void changeToActiveVanishBlock(World world, BlockPos pos, TowerTranslucentVariant variant) { + changeToActiveVanishBlock(world, pos, TFBlocks.tower_translucent.getDefaultState().withProperty(BlockTFTowerTranslucent.VARIANT, variant)); } /** * Change this block into an active vanishing block */ - public static void changeToActiveVanishBlock(World par1World, int x, int y, int z, int meta) - { - changeToBlockMeta(par1World, x, y, z, meta); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.pop", 0.3F, 0.6F); - - Block thereBlockID = par1World.getBlock(x, y, z); - par1World.scheduleBlockUpdate(x, y, z, thereBlockID, getTickRateFor(thereBlockID, meta, par1World.rand)); - } - - /** - * We need variable, metadata-based tick rates - */ - private static int getTickRateFor(Block thereBlockID, int meta, Random rand) - { - if (thereBlockID == TFBlocks.towerDevice && (meta == META_VANISH_ACTIVE || meta == META_REAPPEARING_ACTIVE)) - { + private static void changeToActiveVanishBlock(World world, BlockPos pos, IBlockState state) { + changeToBlockState(world, pos, state); + world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 0.3F, 0.6F); + world.scheduleUpdate(pos, state.getBlock(), getTickRateFor(state, world.rand)); + } + + /** + * We need variable, metadata-based tick rates + */ + private static int getTickRateFor(IBlockState state, Random rand) { + if (state.getBlock() == TFBlocks.tower_device && (state.getValue(VARIANT) == TowerDeviceVariant.VANISH_ACTIVE || state.getValue(VARIANT) == TowerDeviceVariant.REAPPEARING_ACTIVE)) { return 2 + rand.nextInt(5); - } - else if (thereBlockID == TFBlocks.towerTranslucent && meta == BlockTFTowerTranslucent.META_BUILT_ACTIVE) - { + } else if (state.getBlock() == TFBlocks.tower_translucent && state.getValue(BlockTFTowerTranslucent.VARIANT) == TowerTranslucentVariant.BUILT_ACTIVE) { return 10; } - + return 15; } - /** - * Get a light value for this block, normal ranges are between 0 and 15 - * - * @param world The current world - * @param x X Position - * @param y Y position - * @param z Z position - * @return The light value - */ - @Override - public int getLightValue(IBlockAccess world, int x, int y, int z) - { - Block blockID = world.getBlock(x, y, z); - int meta = world.getBlockMetadata(x, y, z); - - if (blockID != this) - { - // why are you asking me? - return 0; - } - - switch (meta) - { - case META_BUILDER_ACTIVE : - case META_VANISH_ACTIVE : - case META_REAPPEARING_ACTIVE : - return 4; - case META_ANTIBUILDER : - return 10; - case META_GHASTTRAP_ACTIVE : - case META_REACTOR_ACTIVE : - return 15; - default : - return 0; - } - } - - - /** - * Called throughout the code as a replacement for block instanceof BlockContainer - * Moving this to the Block base class allows for mods that wish to extend vinella - * blocks, and also want to have a tile entity on that block, may. - * - * Return true from this function to specify this block has a tile entity. - * - * @param metadata Metadata of the current block - * @return True if block has a tile entity, false otherwise - */ @Override - public boolean hasTileEntity(int metadata) - { - return metadata == META_BUILDER_ACTIVE || metadata == META_ANTIBUILDER || metadata == META_REACTOR_ACTIVE - || metadata == META_GHASTTRAP_INACTIVE || metadata == META_GHASTTRAP_ACTIVE; + public int getLightValue(IBlockState state) { + switch (state.getValue(VARIANT)) { + case BUILDER_ACTIVE: + case VANISH_ACTIVE: + case REAPPEARING_ACTIVE: + return 4; + case ANTIBUILDER: + return 10; + case GHASTTRAP_ACTIVE: + case REACTOR_ACTIVE: + return 15; + default: + return 0; + } } @Override - public TileEntity createTileEntity(World world, int metadata) - { - if (metadata == META_BUILDER_ACTIVE) - { - return new TileEntityTFTowerBuilder(); + public boolean hasTileEntity(IBlockState state) { + switch (state.getValue(VARIANT)) { + case BUILDER_ACTIVE: + case ANTIBUILDER: + case GHASTTRAP_INACTIVE: + case GHASTTRAP_ACTIVE: + case REACTOR_ACTIVE: + return true; + default: + return false; } - else if (metadata == META_ANTIBUILDER) - { - return new TileEntityTFReverter(); - } - else if (metadata == META_GHASTTRAP_INACTIVE) - { - return new TileEntityTFGhastTrapInactive(); - } - else if (metadata == META_GHASTTRAP_ACTIVE) - { - return new TileEntityTFGhastTrapActive(); + } + + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + switch (state.getValue(VARIANT)) { + case BUILDER_ACTIVE: + return new TileEntityTFTowerBuilder(); + case ANTIBUILDER: + return new TileEntityTFAntibuilder(); + case GHASTTRAP_INACTIVE: + return new TileEntityTFGhastTrapInactive(); + case GHASTTRAP_ACTIVE: + return new TileEntityTFGhastTrapActive(); + case REACTOR_ACTIVE: + return new TileEntityTFCReactorActive(); + default: + return null; } - else if (metadata == META_REACTOR_ACTIVE) - { - return new TileEntityTFCReactorActive(); + } + + @Override + public Item getItemDropped(IBlockState state, Random random, int fortune) { + switch (state.getValue(VARIANT)) { + case ANTIBUILDER: + return Items.AIR; + default: + return Item.getItemFromBlock(this); } - else - { - return null; + } + + @Override + @Deprecated + protected boolean canSilkHarvest() { + return false; + } + + @Override + public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + return false; + } + + @Override + public int damageDropped(IBlockState state) { + switch (state.getValue(VARIANT)) { + case REAPPEARING_ACTIVE: + state = state.withProperty(VARIANT, TowerDeviceVariant.REAPPEARING_INACTIVE); + break; + case BUILDER_ACTIVE: + case BUILDER_TIMEOUT: + state = state.withProperty(VARIANT, TowerDeviceVariant.BUILDER_INACTIVE); + break; + case VANISH_ACTIVE: + state = state.withProperty(VARIANT, TowerDeviceVariant.VANISH_INACTIVE); + break; + case GHASTTRAP_ACTIVE: + state = state.withProperty(VARIANT, TowerDeviceVariant.GHASTTRAP_INACTIVE); + break; + case REACTOR_ACTIVE: + state = state.withProperty(VARIANT, TowerDeviceVariant.REACTOR_INACTIVE); + break; + default: + break; } + + return getMetaFromState(state); } - - - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int meta, Random par2Random, int par3) - { - switch (meta) - { - case META_ANTIBUILDER : - return null; - default : - return Item.getItemFromBlock(this); - } - } - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) - { - switch (meta) - { - case META_REAPPEARING_ACTIVE : - return META_REAPPEARING_INACTIVE; - case META_BUILDER_ACTIVE : - case META_BUILDER_TIMEOUT : - return META_BUILDER_INACTIVE; - case META_VANISH_ACTIVE : - return META_VANISH_INACTIVE; - case META_GHASTTRAP_ACTIVE : - return META_GHASTTRAP_INACTIVE; - case META_REACTOR_ACTIVE : - return META_REACTOR_INACTIVE; - default : - return meta; - } - } - -// @Override -// public void breakBlock(World par1World, int x, int y, int z, int par5, int meta) { -// super.breakBlock(par1World, x, y, z, par5, meta); -// -// //System.out.println("broke block, meta = " + meta); -// -// if (meta == META_BUILDER_ACTIVE) -// { -// // activate all adjacent inactive vanish blocks -// checkAndActivateVanishBlock(par1World, x - 1, y, z); -// checkAndActivateVanishBlock(par1World, x + 1, y, z); -// checkAndActivateVanishBlock(par1World, x, y + 1, z); -// checkAndActivateVanishBlock(par1World, x, y - 1, z); -// checkAndActivateVanishBlock(par1World, x, y, z + 1); -// checkAndActivateVanishBlock(par1World, x, y, z - 1); -// } -// } - - + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } + @Override + @SideOnly(Side.CLIENT) + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } } diff --git a/src/main/java/twilightforest/block/BlockTFTowerTranslucent.java b/src/main/java/twilightforest/block/BlockTFTowerTranslucent.java index 51ffba403f..691995107b 100644 --- a/src/main/java/twilightforest/block/BlockTFTowerTranslucent.java +++ b/src/main/java/twilightforest/block/BlockTFTowerTranslucent.java @@ -1,264 +1,197 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.init.Blocks; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.TowerDeviceVariant; +import twilightforest.enums.TowerTranslucentVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import java.util.Random; + +public class BlockTFTowerTranslucent extends Block implements ModelRegisterCallback { -public class BlockTFTowerTranslucent extends Block -{ + public static final IProperty VARIANT = PropertyEnum.create("variant", TowerTranslucentVariant.class); + private static final AxisAlignedBB REAPPEARING_BB = new AxisAlignedBB(0.375F, 0.375F, 0.375F, 0.625F, 0.625F, 0.625F); - public static final int META_REAPPEARING_INACTIVE = 0; - public static final int META_REAPPEARING_ACTIVE = 1; - public static final int META_BUILT_INACTIVE = 2; - public static final int META_BUILT_ACTIVE = 3; - public static final int META_REVERTER_REPLACEMENT = 4; - public static final int META_REACTOR_DEBRIS = 5; - public static final int META_FAKE_GOLD = 6; - public static final int META_FAKE_DIAMOND = 7; - - public static IIcon TEX_REAPPEARING_INACTIVE; - public static IIcon TEX_REAPPEARING_ACTIVE; - public static IIcon TEX_BUILT_INACTIVE; - public static IIcon TEX_BUILT_ACTIVE; - public static IIcon TEX_REVERTER_REPLACEMENT; - - private static Random sideRNG = new Random(); - - public BlockTFTowerTranslucent() - { - super(Material.glass); - this.setHardness(50.0F); - this.setResistance(2000.0F); - this.setStepSound(Block.soundTypeMetal); + public BlockTFTowerTranslucent() { + super(Material.GLASS); + this.setHardness(50.0F); + this.setResistance(2000.0F); + this.setSoundType(SoundType.METAL); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, TowerTranslucentVariant.REAPPEARING_INACTIVE)); + } - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return false; - } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } - /** - * How many world ticks before ticking - */ - public int tickRate() - { - return 15; - } - - /** - * Returns the ID of the items to drop on destruction. - */ @Override - public Item getItemDropped(int par1, Random par2Random, int par3) { - return null; + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); } - - /** - * Return true if a player with Silk Touch can harvest this block directly, and not its normal drops. - */ - @Override - protected boolean canSilkHarvest() - { - return false; - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ + @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) - { - int meta = par1World.getBlockMetadata(par2, par3, par4) & 7; + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, TowerTranslucentVariant.values()[meta]); + } - if (meta == META_REAPPEARING_INACTIVE || meta == META_REAPPEARING_ACTIVE) - { - return null; - } - else - { - this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); - return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); - } + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; } + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - @Override - public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) - { - int meta = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + @Override + public int tickRate(World world) { + return 15; + } - if (meta == META_REAPPEARING_INACTIVE || meta == META_REAPPEARING_ACTIVE) - { - this.setBlockBounds(0.375F, 0.375F, 0.375F, 0.625F, 0.625F, 0.625F); - } - if (meta == META_REACTOR_DEBRIS) - { - this.setBlockBounds(sideRNG.nextFloat() * 0.4F, sideRNG.nextFloat() * 0.4F, sideRNG.nextFloat() * 0.4F, - 1.0F - sideRNG.nextFloat() * 0.4F, 1.0F - sideRNG.nextFloat() * 0.4F, 1.0F - sideRNG.nextFloat() * 0.4F); - } - else - { - this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - } - } - - /** - * Returns the block hardness at a location. Args: world, x, y, z - */ - @Override - public float getBlockHardness(World world, int x, int y, int z) - { - // reverter replacement is like glass - int meta = world.getBlockMetadata(x, y, z); - - if (meta == META_REVERTER_REPLACEMENT || meta == META_REACTOR_DEBRIS) - { - return 0.3F; - } - else - { - return super.getBlockHardness(world, x, y, z); - } - } - + @Override + public Item getItemDropped(IBlockState state, Random random, int fortune) { + return Items.AIR; + } + @Override + public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + return false; + } + @Override + @Deprecated + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + switch (state.getValue(VARIANT)) { + case REAPPEARING_INACTIVE: + case REAPPEARING_ACTIVE: + return NULL_AABB; + default: + return super.getCollisionBoundingBox(state, world, pos); + } + } - @Override - public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) - { - int meta = par1IBlockAccess.getBlockMetadata(par2, par3, par4); + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + switch (state.getValue(VARIANT)) { + case REAPPEARING_INACTIVE: + case REAPPEARING_ACTIVE: + return REAPPEARING_BB; + default: + return FULL_BLOCK_AABB; + } + } - switch (meta) - { - case META_REAPPEARING_INACTIVE: - case META_REAPPEARING_ACTIVE: - default: - return false; - case META_BUILT_INACTIVE: - case META_BUILT_ACTIVE: - case META_REVERTER_REPLACEMENT: - case META_REACTOR_DEBRIS: - return true; - } - } + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + switch (state.getValue(VARIANT)) { + case REAPPEARING_INACTIVE: + case REAPPEARING_ACTIVE: + return BlockFaceShape.UNDEFINED; + default: + return super.getBlockFaceShape(worldIn, state, pos, face); + } + } + @Override + @Deprecated + public float getBlockHardness(IBlockState state, World world, BlockPos pos) { + // reverter replacement is like glass + switch (state.getValue(VARIANT)) { + case REVERTER_REPLACEMENT: + case REACTOR_DEBRIS: + return 0.3F; + default: + return super.getBlockHardness(state, world, pos); + } + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ @Override - public IIcon getIcon(int side, int meta) { - switch (meta) - { - case META_REAPPEARING_INACTIVE: - default: - return TEX_REAPPEARING_INACTIVE; - case META_REAPPEARING_ACTIVE: - return TEX_REAPPEARING_ACTIVE; - case META_BUILT_INACTIVE: - return TEX_BUILT_INACTIVE; - case META_BUILT_ACTIVE: - return TEX_BUILT_ACTIVE; - case META_REVERTER_REPLACEMENT: - return TEX_REVERTER_REPLACEMENT; - case META_REACTOR_DEBRIS: - Block toMimic = sideRNG.nextBoolean() ? (sideRNG.nextBoolean() ? Blocks.portal : Blocks.netherrack) : (sideRNG.nextBoolean() ? Blocks.bedrock : Blocks.obsidian); - return toMimic.getIcon(side, meta); - case META_FAKE_GOLD: - return Blocks.gold_block.getIcon(side, meta); - case META_FAKE_DIAMOND: - return Blocks.diamond_block.getIcon(side, meta); + public boolean isPassable(IBlockAccess world, BlockPos pos) { + switch (world.getBlockState(pos).getValue(VARIANT)) { + case REAPPEARING_INACTIVE: + case REAPPEARING_ACTIVE: + return true; + default: + return false; } } - - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFTowerTranslucent.TEX_REAPPEARING_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_reappearing_trace_off"); - BlockTFTowerTranslucent.TEX_REAPPEARING_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_reappearing_trace_on"); - BlockTFTowerTranslucent.TEX_BUILT_INACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_built_off"); - BlockTFTowerTranslucent.TEX_BUILT_ACTIVE = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_built_on"); - BlockTFTowerTranslucent.TEX_REVERTER_REPLACEMENT = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerdev_antibuilt"); - } - - /** - * Ticks the block if it's been scheduled - */ - @Override - public void updateTick(World par1World, int x, int y, int z, Random par5Random) - { - if (!par1World.isRemote) - { - int meta = par1World.getBlockMetadata(x, y, z); - if (meta == META_BUILT_ACTIVE) - { - par1World.setBlock(x, y, z, Blocks.air, 0, 3); - par1World.notifyBlocksOfNeighborChange(x, y, z, this); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.pop", 0.3F, 0.5F); - //par1World.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - - // activate all adjacent inactive vanish blocks - BlockTFTowerDevice.checkAndActivateVanishBlock(par1World, x - 1, y, z); - BlockTFTowerDevice.checkAndActivateVanishBlock(par1World, x + 1, y, z); - BlockTFTowerDevice.checkAndActivateVanishBlock(par1World, x, y + 1, z); - BlockTFTowerDevice.checkAndActivateVanishBlock(par1World, x, y - 1, z); - BlockTFTowerDevice.checkAndActivateVanishBlock(par1World, x, y, z + 1); - BlockTFTowerDevice.checkAndActivateVanishBlock(par1World, x, y, z - 1); + // todo 1.10 smart model for REACTOR_DEBRIS that randomly chooses sides from portal/netherrack/bedrock/obsidian + + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random random) { + + if (world.isRemote) return; + + TowerTranslucentVariant variant = state.getValue(VARIANT); - } - if (meta == META_REAPPEARING_ACTIVE) - { - par1World.setBlock(x, y, z, TFBlocks.towerDevice, BlockTFTowerDevice.META_REAPPEARING_INACTIVE, 3); - par1World.notifyBlocksOfNeighborChange(x, y, z, this); - par1World.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "random.click", 0.3F, 0.5F); - //par1World.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - } - else if (meta == META_REAPPEARING_INACTIVE) - { - BlockTFTowerDevice.changeToActiveVanishBlock(par1World, x, y, z, META_REAPPEARING_ACTIVE); - } + if (variant == TowerTranslucentVariant.BUILT_ACTIVE) { + world.setBlockToAir(pos); + world.notifyNeighborsRespectDebug(pos, this, false); + world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 0.3F, 0.5F); + //world.markBlockRangeForRenderUpdate(x, y, z, x, y, z); - } - } + // activate all adjacent inactive vanish blocks + for (EnumFacing e : EnumFacing.VALUES) { + BlockTFTowerDevice.checkAndActivateVanishBlock(world, pos.offset(e)); + } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - // none! - } + } else if (variant == TowerTranslucentVariant.REAPPEARING_ACTIVE) { + world.setBlockState(pos, TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.REAPPEARING_INACTIVE)); + world.notifyNeighborsRespectDebug(pos, this, false); + world.playSound(null, pos, SoundEvents.BLOCK_WOOD_BUTTON_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.5F); + //world.markBlockRangeForRenderUpdate(x, y, z, x, y, z); + } else if (variant == TowerTranslucentVariant.REAPPEARING_INACTIVE) { + BlockTFTowerDevice.changeToActiveVanishBlock(world, pos, TowerTranslucentVariant.REAPPEARING_ACTIVE); + } + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) {} + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } } diff --git a/src/main/java/twilightforest/block/BlockTFTowerWood.java b/src/main/java/twilightforest/block/BlockTFTowerWood.java index de6b188234..1fdbb2a18f 100644 --- a/src/main/java/twilightforest/block/BlockTFTowerWood.java +++ b/src/main/java/twilightforest/block/BlockTFTowerWood.java @@ -1,226 +1,126 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.TowerWoodVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.entity.EntityTFTowerTermite; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import java.util.Random; /** - * * Tower wood is a type of plank block that forms the walls of Dark Towers - * - * @author Ben * + * @author Ben */ -public class BlockTFTowerWood extends Block { - - private static IIcon TEX_PLAIN; - private static IIcon TEX_ENCASED; - private static IIcon TEX_CRACKED; - private static IIcon TEX_MOSSY; - private static IIcon TEX_INFESTED; - - public static final int META_INFESTED = 4; - - - public BlockTFTowerWood() - { - super(Material.wood); - this.setHardness(40F); - this.setResistance(10F); - this.setStepSound(Block.soundTypeWood); +public class BlockTFTowerWood extends Block implements ModelRegisterCallback { + + public static final IProperty VARIANT = PropertyEnum.create("variant", TowerWoodVariant.class); + + public BlockTFTowerWood() { + super(Material.WOOD, MapColor.ADOBE); + this.setHardness(40F); + this.setResistance(10F); + this.setSoundType(SoundType.WOOD); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(blockState.getBaseState().withProperty(VARIANT, TowerWoodVariant.PLAIN)); + } + + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } - } - - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @Override - public int colorMultiplier(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int meta = par1IBlockAccess.getBlockMetadata(x, y, z); - - if (meta == 0 || meta == 2 || meta == 3 || meta == META_INFESTED) - { - // stripes! - int value = x * 31 + y * 15 + z * 33; - if ((value & 256) != 0) - { - value = 255 - (value & 255); - } - value &= 255; - value = value >> 1; - value |= 128; - - return value << 16 | value << 8 | value; - } - else - { - return 16777215; - } - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ @Override - public IIcon getIcon(int side, int meta) { - switch (meta) - { - case 0: - default: - return TEX_PLAIN; - case 1: - return TEX_ENCASED; - case 2: - return TEX_CRACKED; - case 3: - return TEX_MOSSY; - case META_INFESTED: - return TEX_INFESTED; + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); + } + + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, TowerWoodVariant.values()[meta]); + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return state.getValue(VARIANT) == TowerWoodVariant.ENCASED ? MapColor.SAND : super.getMapColor(state, world, pos); + } + + @Override + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + for (TowerWoodVariant variant : TowerWoodVariant.values()) { + list.add(new ItemStack(this, 1, variant.ordinal())); } } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - BlockTFTowerWood.TEX_PLAIN = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerwood_planks"); - BlockTFTowerWood.TEX_ENCASED = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerwood_encased"); - BlockTFTowerWood.TEX_CRACKED = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerwood_cracked"); - BlockTFTowerWood.TEX_MOSSY = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerwood_mossy"); - BlockTFTowerWood.TEX_INFESTED = par1IconRegister.registerIcon(TwilightForestMod.ID + ":towerwood_infested"); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - par3List.add(new ItemStack(par1, 1, 3)); - par3List.add(new ItemStack(par1, 1, META_INFESTED)); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return meta; + + @Override + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } + + @Override + public int quantityDropped(IBlockState state, int fortune, Random random) { + if (state.getValue(VARIANT) == TowerWoodVariant.INFESTED) { + return 0; + } else { + return super.quantityDropped(state, fortune, random); + } + } + + @Override + @Deprecated + public float getBlockHardness(IBlockState state, World world, BlockPos pos) { + if (state.getValue(VARIANT) == TowerWoodVariant.INFESTED) { + return 0.75F; + } else { + return super.getBlockHardness(state, world, pos); + } + } + + @Override + public void dropBlockAsItemWithChance(World world, BlockPos pos, IBlockState state, float chance, int fortune) { + if (!world.isRemote && state.getValue(VARIANT) == TowerWoodVariant.INFESTED) { + EntityTFTowerTermite termite = new EntityTFTowerTermite(world); + termite.setLocationAndAngles(pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D, 0.0F, 0.0F); + world.spawnEntity(termite); + termite.spawnExplosionParticle(); + } + + super.dropBlockAsItemWithChance(world, pos, state, chance, fortune); } - - /** - * Metadata and fortune sensitive version, this replaces the old (int meta, Random rand) - * version in 1.1. - * - * @param meta Blocks Metadata - * @param fortune Current item fortune level - * @param random Random number generator - * @return The number of items to drop - */ - @Override - public int quantityDropped(int meta, int fortune, Random random) - { - if (meta == META_INFESTED) - { - return 0; - } - else - { - return super.quantityDropped(meta, fortune, random); - } - } - - /** - * Returns the block hardness at a location. Args: world, x, y, z - */ - @Override - public float getBlockHardness(World world, int x, int y, int z) - { - // infested block is not very hard - int meta = world.getBlockMetadata(x, y, z); - - if (meta == META_INFESTED) - { - return 0.75F; - } - else - { - return super.getBlockHardness(world, x, y, z); - } - } - - /** - * Called right before the block is destroyed by a player. Args: world, x, y, z, metaData - */ - @Override - public void dropBlockAsItemWithChance(World par1World, int x, int y, int z, int meta, float chance, int something) - { - if (!par1World.isRemote && meta == META_INFESTED) - { - EntityTFTowerTermite termite = new EntityTFTowerTermite(par1World); - termite.setLocationAndAngles(x + 0.5D, y, z + 0.5D, 0.0F, 0.0F); - par1World.spawnEntityInWorld(termite); - termite.spawnExplosionParticle(); - } - - super.dropBlockAsItemWithChance(par1World, x, y, z, meta, chance, something); - } - - /** - * Chance that fire will spread and consume this block. - * 300 being a 100% chance, 0, being a 0% chance. - * - * @param world The current world - * @param x The blocks X position - * @param y The blocks Y position - * @param z The blocks Z position - * @param metadata The blocks current metadata - * @param face The face that the fire is coming from - * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire - */ - @Override - public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { - return 1; - } - - /** - * Called when fire is updating on a neighbor block. - * The higher the number returned, the faster fire will spread around this block. - * - * @param world The current world - * @param x The blocks X position - * @param y The blocks Y position - * @param z The blocks Z position - * @param metadata The blocks current metadata - * @param face The face that the fire is coming from - * @return A number that is used to determine the speed of fire growth around the block - */ + @Override - public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + public int getFlammability(IBlockAccess world, BlockPos pos, EnumFacing side) { + return 1; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing side) { return 0; } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); + } + } diff --git a/src/main/java/twilightforest/block/BlockTFTrapDoor.java b/src/main/java/twilightforest/block/BlockTFTrapDoor.java new file mode 100644 index 0000000000..bd3687c461 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFTrapDoor.java @@ -0,0 +1,37 @@ +package twilightforest.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockTrapDoor; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.pathfinding.PathNodeType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import twilightforest.client.ModelRegisterCallback; + +public class BlockTFTrapDoor extends BlockTrapDoor implements ModelRegisterCallback { + + private final MapColor mapColor; + + protected BlockTFTrapDoor(Material material, MapColor mapColor) { + super(material); + this.mapColor = mapColor; + } + + @Override + public Block setSoundType(SoundType sound) { + return super.setSoundType(sound); + } + + @Override + public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { + return mapColor; + } + + @Override + public PathNodeType getAiPathNodeType(IBlockState state, IBlockAccess world, BlockPos pos) { + return PathNodeType.TRAPDOOR; + } +} diff --git a/src/main/java/twilightforest/block/BlockTFTrollLjos.java b/src/main/java/twilightforest/block/BlockTFTrollLjos.java index 39dc5572d0..f789d0de8e 100644 --- a/src/main/java/twilightforest/block/BlockTFTrollLjos.java +++ b/src/main/java/twilightforest/block/BlockTFTrollLjos.java @@ -1,31 +1,19 @@ package twilightforest.block; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import twilightforest.item.TFItems; import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.init.Blocks; +import twilightforest.item.TFItems; public class BlockTFTrollLjos extends Block { - + protected BlockTFTrollLjos() { - super(Material.rock); + super(Material.ROCK); - this.setHardness(2F); - this.setResistance(15F); - this.setStepSound(Block.soundTypeStone); + this.setHardness(2F); + this.setResistance(15F); + this.setSoundType(SoundType.STONE); this.setCreativeTab(TFItems.creativeTab); - - this.setLightLevel(1.0F); - - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.blockIcon = Blocks.lit_redstone_lamp.getIcon(0, 0); + this.setLightLevel(1.0F); } } diff --git a/src/main/java/twilightforest/block/BlockTFTrollRoot.java b/src/main/java/twilightforest/block/BlockTFTrollRoot.java index ea4e2a9130..f29eab0801 100644 --- a/src/main/java/twilightforest/block/BlockTFTrollRoot.java +++ b/src/main/java/twilightforest/block/BlockTFTrollRoot.java @@ -1,142 +1,130 @@ package twilightforest.block; -import java.util.ArrayList; -import java.util.Random; - -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.init.Blocks; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.IShearable; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +import java.util.List; +import java.util.Random; -public class BlockTFTrollRoot extends Block implements IShearable { +public class BlockTFTrollRoot extends Block implements IShearable, ModelRegisterCallback { + + protected static final AxisAlignedBB AABB = new AxisAlignedBB(0.1, 0.0, 0.1, 0.9, 1.0, 0.9); protected BlockTFTrollRoot() { - super(Material.plants); - this.setTickRandomly(true); + super(Material.PLANTS); + this.setTickRandomly(true); this.setCreativeTab(TFItems.creativeTab); - this.setStepSound(soundTypeGrass); - - this.setBlockTextureName(TwilightForestMod.ID + ":troll_root"); - + this.setSoundType(SoundType.PLANT); } @Override - public boolean isShearable(ItemStack item, IBlockAccess world, int x, int y, int z) { + public boolean isShearable(ItemStack item, IBlockAccess world, BlockPos pos) { return true; } @Override - public ArrayList onSheared(ItemStack item, IBlockAccess world, int x, int y, int z, int fortune) { - ArrayList ret = new ArrayList(); - ret.add(new ItemStack(this)); - return ret; - } - - - - /** - * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. - */ - @Override - public boolean canBlockStay(World world, int x, int y, int z) { - return canPlaceRootBelow(world, x, y + 1, z); - } - - public static boolean canPlaceRootBelow(World world, int x, int y, int z) { - Block blockAbove = world.getBlock(x, y, z); - - return blockAbove.getMaterial() == Material.rock || blockAbove == TFBlocks.trollVidr || blockAbove == TFBlocks.trollBer || blockAbove == TFBlocks.unripeTrollBer; - } - - /** - * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z - */ - public boolean canPlaceBlockAt(World world, int x, int y, int z) { - return super.canPlaceBlockAt(world, x, y, z) && this.canBlockStay(world, x, y, z); - } - - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int x, int y, int z) { - return null; - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() { - return false; - } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - @Override - public boolean renderAsNormalBlock() { - return false; - } - - /** - * The type of render function that is called for this block - */ + public List onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) { + NonNullList ret = NonNullList.create(); + ret.add(new ItemStack(this)); + return ret; + } + + private boolean canBlockStay(World world, BlockPos pos) { + return canPlaceRootBelow(world, pos.up()); + } + + public static boolean canPlaceRootBelow(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + Block blockAbove = state.getBlock(); + + return state.getMaterial() == Material.ROCK || blockAbove == TFBlocks.trollvidr || blockAbove == TFBlocks.trollber || blockAbove == TFBlocks.unripe_trollber; + } + + @Override + public boolean canPlaceBlockAt(World world, BlockPos pos) { + return super.canPlaceBlockAt(world, pos) && this.canBlockStay(world, pos); + } + + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return AABB; + } + + @Override + @Deprecated + public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return NULL_AABB; + } + + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face) { + return BlockFaceShape.UNDEFINED; + } + + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } + @Override - public int getRenderType() { - return 1; + public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { + this.checkAndDropBlock(world, pos); } - - /** - * Ticks the block if it's been scheduled - */ + @Override - public void updateTick(World world, int x, int y, int z, Random rand) { - this.checkAndDropBlock(world, x, y, z); - } - - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor Block - */ - public void onNeighborBlockChange(World world, int x, int y, int z, Block block) { - this.checkAndDropBlock(world, x, y, z); - } - - /** - * checks if the block can stay, if not drop as item - */ - protected void checkAndDropBlock(World world, int x, int y, int z) { - if (!this.canBlockStay(world, x, y, z)) { - this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); - world.setBlockToAir(x, y, z); - } - } - - /** - * Metadata and fortune sensitive version, this replaces the old (int meta, Random rand) - * version in 1.1. - * - * @param meta Blocks Metadata - * @param fortune Current item fortune level - * @param random Random number generator - * @return The number of items to drop - */ - public int quantityDropped(int meta, int fortune, Random random) { - return 0; - } + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) { + this.checkAndDropBlock(world, pos); + } + + private void checkAndDropBlock(World world, BlockPos pos) { + if (!this.canBlockStay(world, pos)) { + world.destroyBlock(pos, true); + } + } + + @Override + public int quantityDropped(IBlockState state, int fortune, Random random) { + return 0; + } + + @SideOnly(Side.CLIENT) + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.CUTOUT; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, new ModelResourceLocation(getRegistryName(), "inventory")); + } } diff --git a/src/main/java/twilightforest/block/BlockTFTrollSteinn.java b/src/main/java/twilightforest/block/BlockTFTrollSteinn.java index 54e04f2086..377d456075 100644 --- a/src/main/java/twilightforest/block/BlockTFTrollSteinn.java +++ b/src/main/java/twilightforest/block/BlockTFTrollSteinn.java @@ -1,143 +1,129 @@ package twilightforest.block; -import java.util.Random; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.init.Blocks; -import net.minecraft.util.IIcon; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; -public class BlockTFTrollSteinn extends Block { +import java.util.Random; + +public class BlockTFTrollSteinn extends Block implements ModelRegisterCallback { + + static final IProperty DOWN_LIT = PropertyBool.create("down"); + static final IProperty UP_LIT = PropertyBool.create("up"); + static final IProperty NORTH_LIT = PropertyBool.create("north"); + static final IProperty SOUTH_LIT = PropertyBool.create("south"); + static final IProperty WEST_LIT = PropertyBool.create("west"); + static final IProperty EAST_LIT = PropertyBool.create("east"); private static final int LIGHT_THRESHHOLD = 7; - private IIcon blockIconLight; - protected BlockTFTrollSteinn() { - super(Material.rock); + BlockTFTrollSteinn() { + super(Material.ROCK); - this.setHardness(2F); - this.setResistance(15F); - this.setStepSound(Block.soundTypeStone); + this.setHardness(2F); + this.setResistance(15F); + this.setSoundType(SoundType.STONE); this.setCreativeTab(TFItems.creativeTab); - this.setBlockTextureName(TwilightForestMod.ID + ":trollsteinn"); + this.setDefaultState(blockState.getBaseState() + .withProperty(DOWN_LIT, false).withProperty(UP_LIT, false) + .withProperty(NORTH_LIT, false).withProperty(SOUTH_LIT, false) + .withProperty(WEST_LIT, false).withProperty(EAST_LIT, false)); } - - /** - * A randomly called display update to be able to add particles or other items for display - */ - @SideOnly(Side.CLIENT) - public void randomDisplayTick(World world, int x, int y, int z, Random rand) { - if (rand.nextInt(2) == 0) { - this.sparkle(world, x, y, z, rand); - } - } - - private void sparkle(World world, int x, int y, int z, Random rand) { - Random random = rand; - double pixel = 0.0625D; - int threshhold = LIGHT_THRESHHOLD; - - for (int side = 0; side < 6; ++side) - { - double rx = (double)((float)x + random.nextFloat()); - double ry = (double)((float)y + random.nextFloat()); - double rz = (double)((float)z + random.nextFloat()); - - if (side == 0 && !world.getBlock(x, y - 1, z).isOpaqueCube() && world.getBlockLightValue(x, y - 1, z) <= threshhold) - { - ry = (double)(y + 0) - pixel; - } - - if (side == 1 && !world.getBlock(x, y + 1, z).isOpaqueCube() && world.getBlockLightValue(x, y + 1, z) <= threshhold) - { - ry = (double)(y + 1) + pixel; - } - - if (side == 2 && !world.getBlock(x, y, z + 1).isOpaqueCube() && world.getBlockLightValue(x, y, z + 1) <= threshhold) - { - rz = (double)(z + 1) + pixel; - } - - if (side == 3 && !world.getBlock(x, y, z - 1).isOpaqueCube() && world.getBlockLightValue(x, y, z - 1) <= threshhold) - { - rz = (double)(z + 0) - pixel; - } - - if (side == 4 && !world.getBlock(x + 1, y, z).isOpaqueCube() && world.getBlockLightValue(x + 1, y, z) <= threshhold) - { - rx = (double)(x + 1) + pixel; - } - - if (side == 5 && !world.getBlock(x - 1, y, z).isOpaqueCube() && world.getBlockLightValue(x - 1, y, z) <= threshhold) - { - rx = (double)(x + 0) - pixel; - } - - if (rx < (double)x || rx > (double)(x + 1) || ry < 0.0D || ry > (double)(y + 1) || rz < (double)z || rz > (double)(z + 1)) - { - world.spawnParticle("reddust", rx, ry, rz, 0.25D, -1.0D, 0.5D); - } - } - } - - @SideOnly(Side.CLIENT) - public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { - - // check brightness for the side - if (side == 0 && isBlockLit(world, x, y - 1, z)) { - return this.blockIconLight; - } - - if (side == 1 && isBlockLit(world, x, y + 1, z)) { - return this.blockIconLight; - } - - if (side == 2 && isBlockLit(world, x, y, z - 1)) { - return this.blockIconLight; - } - - if (side == 3 && isBlockLit(world, x, y, z + 1)) { - return this.blockIconLight; - } - - if (side == 4 && isBlockLit(world, x - 1, y, z)) { - return this.blockIconLight; - } - - if (side == 5 && isBlockLit(world, x + 1, y, z)) { - return this.blockIconLight; - } - - return this.getIcon(side, world.getBlockMetadata(x, y, z)); - } - - private boolean isBlockLit(IBlockAccess world, int x, int y, int z) { - int threshhold = LIGHT_THRESHHOLD << 4; - - if (world.getBlock(x, y, z).isOpaqueCube()) { - return false; - } else { - int light = world.getLightBrightnessForSkyBlocks(x, y, z, 0); - int sky = light % 65536; - int block = light / 65536; - - return sky > threshhold || block > threshhold; - } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, DOWN_LIT, UP_LIT, NORTH_LIT, SOUTH_LIT, WEST_LIT, EAST_LIT); } + @Override + public int getMetaFromState(IBlockState state) { + return 0; + } @Override + @Deprecated + public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) { + if (!(world instanceof World)) return this.getDefaultState(); + + for (SideProps side : SideProps.values()) + state = state.withProperty(side.prop, ((World) world).getLight(pos.offset(side.facing)) > LIGHT_THRESHHOLD); + + return state; + } + @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) { - this.blockIcon = par1IconRegister.registerIcon(this.getTextureName()); - this.blockIconLight = par1IconRegister.registerIcon(this.getTextureName() + "_light"); - } + @Override + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random rand) { + if (rand.nextInt(2) == 0) this.sparkle(world, pos); + } + + // [VanillaCopy] Based on BlockRedstoneOre.spawnParticles + private void sparkle(World world, BlockPos pos) { + Random random = world.rand; + int threshhold = LIGHT_THRESHHOLD; + + for (EnumFacing side : EnumFacing.VALUES) { + double rx = (double) ((float) pos.getX() + random.nextFloat()); + double ry = (double) ((float) pos.getY() + random.nextFloat()); + double rz = (double) ((float) pos.getZ() + random.nextFloat()); + + if (side == EnumFacing.DOWN && !world.getBlockState(pos.down()).isOpaqueCube() && world.getLight(pos.down()) <= threshhold) { + ry = (double)pos.getY() - 0.0625D; + } + + if (side == EnumFacing.UP && !world.getBlockState(pos.up()).isOpaqueCube() && world.getLight(pos.up()) <= threshhold) { + ry = (double)pos.getY() + 0.0625D + 1.0D; + } + + if (side == EnumFacing.NORTH && !world.getBlockState(pos.north()).isOpaqueCube() && world.getLight(pos.north()) <= threshhold) { + rz = (double)pos.getZ() - 0.0625D; + } + + if (side == EnumFacing.SOUTH && !world.getBlockState(pos.south()).isOpaqueCube() && world.getLight(pos.south()) <= threshhold) { + rz = (double)pos.getZ() + 0.0625D + 1.0D; + } + + if (side == EnumFacing.WEST && !world.getBlockState(pos.west()).isOpaqueCube() && world.getLight(pos.west()) <= threshhold) { + rx = (double)pos.getX() - 0.0625D; + } + + if (side == EnumFacing.EAST && !world.getBlockState(pos.east()).isOpaqueCube() && world.getLight(pos.east()) <= threshhold) { + rx = (double)pos.getX() + 0.0625D + 1.0D; + } + + if (rx < (double) pos.getX() || rx > (double) (pos.getX() + 1) || ry < 0.0D || ry > (double) (pos.getY() + 1) || rz < (double) pos.getZ() || rz > (double) (pos.getZ() + 1)) { + world.spawnParticle(EnumParticleTypes.REDSTONE, rx, ry, rz, 0.25D, -1.0D, 0.5D); + } + } + } + + private enum SideProps { + UP(UP_LIT, EnumFacing.UP), + DOWN(DOWN_LIT, EnumFacing.DOWN), + NORTH(NORTH_LIT, EnumFacing.NORTH), + SOUTH(SOUTH_LIT, EnumFacing.SOUTH), + WEST(WEST_LIT, EnumFacing.WEST), + EAST(EAST_LIT, EnumFacing.EAST); + + private final IProperty prop; + private final EnumFacing facing; + + SideProps(IProperty prop, EnumFacing faceing) { + this.prop = prop; + this.facing = faceing; + } + } } diff --git a/src/main/java/twilightforest/block/BlockTFTrophy.java b/src/main/java/twilightforest/block/BlockTFTrophy.java index 00517da5c6..55ecddfb19 100644 --- a/src/main/java/twilightforest/block/BlockTFTrophy.java +++ b/src/main/java/twilightforest/block/BlockTFTrophy.java @@ -1,259 +1,179 @@ package twilightforest.block; -import java.util.ArrayList; -import java.util.Random; - -import net.minecraft.block.BlockContainer; -import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.block.BlockSkull; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.statemap.StateMap; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntitySkull; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.common.Optional; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import thaumcraft.api.crafting.IInfusionStabiliser; +import twilightforest.TFSounds; +import twilightforest.enums.BossVariant; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; import twilightforest.tileentity.TileEntityTFTrophy; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -/** - * Head trophy similar to (and based partially on) BlockSkull - * - */ -public class BlockTFTrophy extends BlockContainer -{ - - public BlockTFTrophy() - { - super(Material.circuits); - this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); - } - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return -1; - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return false; - } - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - @Override - public boolean renderAsNormalBlock() - { - return false; - } - - /** - * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been - * cleared to be reused) - */ - @Override - public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) - { - this.setBlockBoundsBasedOnState(par1World, par2, par3, par4); - return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4); - } - - - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - @Override - public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int meta = par1IBlockAccess.getBlockMetadata(x, y, z) & 7; - TileEntityTFTrophy trophy = (TileEntityTFTrophy)par1IBlockAccess.getTileEntity(x, y, z); - - if (trophy != null && trophy.func_145904_a() == 0) - { - // hydra bounds - switch (meta) - { - case 1: - default: - this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); - break; - case 2: - case 3: - this.setBlockBounds(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 1.0F); - break; - case 4: - case 5: - this.setBlockBounds(0.0F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); - break; - } - } - else if (trophy != null && trophy.func_145904_a() == 3) - { - // urghast bounds - this.setBlockBounds(0.25F, 0.5F, 0.25F, 0.75F, 1F, 0.75F); - } - else - { - // normal skull bounds - switch (meta) - { - case 1: - default: - this.setBlockBounds(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); - break; - case 2: - this.setBlockBounds(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F); - break; - case 3: - this.setBlockBounds(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F); - break; - case 4: - this.setBlockBounds(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); - break; - case 5: - this.setBlockBounds(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F); - } - } - } +import java.util.List; +import java.util.Random; - /** - * Called when the block is placed in the world. - */ - @Override - public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLiving, ItemStack itemStack) - { - int rotation = MathHelper.floor_double(par5EntityLiving.rotationYaw * 4.0F / 360.0F + 2.5D) & 3; - par1World.setBlockMetadataWithNotify(par2, par3, par4, rotation, 2); - } +@Optional.Interface(modid = "thaumcraft", iface = "thaumcraft.api.crafting.IInfusionStabiliser") +public class BlockTFTrophy extends BlockSkull implements ModelRegisterCallback, IInfusionStabiliser { + private static final AxisAlignedBB HYDRA_Y_BB = new AxisAlignedBB(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); + private static final AxisAlignedBB HYDRA_EAST_BB = new AxisAlignedBB(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F); + private static final AxisAlignedBB HYDRA_WEST_BB = new AxisAlignedBB(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); + private static final AxisAlignedBB HYDRA_SOUTH_BB = new AxisAlignedBB(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F); + private static final AxisAlignedBB HYDRA_NORTH_BB = new AxisAlignedBB(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F); + private static final AxisAlignedBB URGHAST_BB = new AxisAlignedBB(0.25F, 0.5F, 0.25F, 0.75F, 1F, 0.75F); - /** - * Returns a new instance of a block's tile entity class. Called on placing the block. - */ - @Override - public TileEntity createNewTileEntity(World var1, int var2) { - return new TileEntityTFTrophy(); + public BlockTFTrophy() { + setDefaultState(blockState.getBaseState().withProperty(BlockSkull.NODROP, false).withProperty(BlockSkull.FACING, EnumFacing.UP)); } - @SideOnly(Side.CLIENT) - - /** - * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) - */ - public Item idPicked(World par1World, int par2, int par3, int par4) - { - return TFItems.trophy; - } - - /** - * Get the block's damage value (for use with pick block). - */ - @Override - public int getDamageValue(World par1World, int par2, int par3, int par4) - { - TileEntity var5 = par1World.getTileEntity(par2, par3, par4); - return var5 != null && var5 instanceof TileEntitySkull ? ((TileEntitySkull)var5).func_145904_a() : super.getDamageValue(par1World, par2, par3, par4); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int par1) - { - return par1; - } + @Override + public EnumBlockRenderType getRenderType(IBlockState state) { + return EnumBlockRenderType.ENTITYBLOCK_ANIMATED; + } - /** - * Called when the block is attempted to be harvested - */ - @Override - public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer) - { - if (par6EntityPlayer.capabilities.isCreativeMode) - { - par5 |= 8; - par1World.setBlockMetadataWithNotify(par2, par3, par4, par5, 2); - } + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess access, BlockPos pos) { + TileEntity te = access.getTileEntity(pos); + if (te instanceof TileEntityTFTrophy) { + switch (BossVariant.getVariant(((TileEntityTFTrophy) te).getSkullType())) { + case HYDRA: + // hydra bounds TODO: actually use non-default bounds here + switch (state.getValue(BlockSkull.FACING)) { + case UP: + default: + return HYDRA_Y_BB; + case NORTH: + return HYDRA_NORTH_BB; + case SOUTH: + return HYDRA_SOUTH_BB; + case WEST: + return HYDRA_WEST_BB; + case EAST: + return HYDRA_EAST_BB; + } + case UR_GHAST: + return URGHAST_BB; + // TODO: also add case for Questing Ram? + } + } + return super.getBoundingBox(state, access, pos); + } - dropBlockAsItem(par1World, par2, par3, par4, par5, 0); + @Override + public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + TileEntity te = worldIn.getTileEntity(pos); + if (te instanceof TileEntityTFTrophy) { + SoundEvent sound = null; + float volume = 1.0F; + switch (BossVariant.getVariant(((TileEntityTFTrophy) te).getSkullType())) { + case NAGA: + sound = TFSounds.NAGA_RATTLE; + volume = 1.25F; + break; + case LICH: + sound = SoundEvents.ENTITY_BLAZE_AMBIENT; + volume = 0.35F; + break; + case HYDRA: + sound = TFSounds.HYDRA_GROWL; + break; + case UR_GHAST: + sound = SoundEvents.ENTITY_GHAST_AMBIENT; + break; + case SNOW_QUEEN: + sound = TFSounds.ICE_AMBIENT; + break; + case KNIGHT_PHANTOM: + sound = TFSounds.WRAITH; + break; + case MINOSHROOM: + sound = SoundEvents.ENTITY_COW_AMBIENT; + volume = 0.5F; + break; + case QUEST_RAM: + sound = SoundEvents.ENTITY_SHEEP_AMBIENT; + break; + } + if (sound != null) + worldIn.playSound(playerIn, pos, sound, SoundCategory.BLOCKS, volume, 16.0F); + } + return true; + } - super.onBlockHarvested(par1World, par2, par3, par4, par5, par6EntityPlayer); - } + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + return new TileEntityTFTrophy(); + } -// /** -// * ejects contained items into the world, and notifies neighbours of an update, as appropriate -// */ -// public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) -// { -// super.breakBlock(par1World, par2, par3, par4, par5, par6); -// } + @Override + public ItemStack getItem(World world, BlockPos pos, IBlockState state) { + TileEntity te = world.getTileEntity(pos); + if (te instanceof TileEntityTFTrophy) { + return new ItemStack(TFItems.trophy, 1, ((TileEntityTFTrophy) te).getSkullType()); + } + return ItemStack.EMPTY; + } - @Override - public ArrayList getDrops(World world, int x, int y, int z, int metadata, int fortune) - { - ArrayList drops = new ArrayList(); - if ((metadata & 8) == 0) - { - ItemStack var7 = new ItemStack(TFItems.trophy, 1, this.getDamageValue(world, x, y, z)); - TileEntityTFTrophy var8 = (TileEntityTFTrophy)world.getTileEntity(x, y, z); + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return TFItems.trophy; + } - if (var8 == null) - { - return drops; - } -// if (var8.func_145904_a() == 3 && var8.func_145907_c() != null && var8.func_145907_c().length() > 0) -// { -// var7.setTagCompound(new NBTTagCompound()); -// var7.getTagCompound().setString("SkullOwner", var8.func_145907_c()); -// } - drops.add(var7); - } - return drops; - } + // [VanillaCopy] of superclass, relevant edits indicated + @Override + public List getDrops(IBlockAccess worldIn, BlockPos pos, IBlockState state, int fortune) { + java.util.List ret = new java.util.ArrayList(); + { + if (!((Boolean) state.getValue(NODROP)).booleanValue()) { + TileEntity tileentity = worldIn.getTileEntity(pos); + + if (tileentity instanceof TileEntitySkull) { + TileEntitySkull tileentityskull = (TileEntitySkull) tileentity; + ItemStack itemstack = new ItemStack(TFItems.trophy, 1, tileentityskull.getSkullType()); // TF - use our item + + /*if (tileentityskull.getSkullType() == 3 && tileentityskull.getPlayerProfile() != null) + { + itemstack.setTagCompound(new NBTTagCompound()); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + NBTUtil.writeGameProfile(nbttagcompound, tileentityskull.getPlayerProfile()); + itemstack.getTagCompound().setTag("SkullOwner", nbttagcompound); + }*/// TF - don't set player skins + + ret.add(itemstack); + } + } + } + return ret; + } - /** - * Returns the ID of the items to drop on destruction. - */ - @Override - public Item getItemDropped(int par1, Random par2Random, int par3) - { - return TFItems.trophy; - } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - @SideOnly(Side.CLIENT) - public IIcon getIcon(int side, int meta) - { - return Blocks.soul_sand.getIcon(side, meta); - } - - @Override @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - ; // don't load anything - } - + @Override + public void registerModel() { + ModelLoader.setCustomStateMapper(this, new StateMap.Builder().ignore(NODROP).ignore(FACING).build()); + } + @Override + public boolean canStabaliseInfusion(World world, BlockPos blockPos) { + return true; + } } diff --git a/src/main/java/twilightforest/block/BlockTFTrophyPedestal.java b/src/main/java/twilightforest/block/BlockTFTrophyPedestal.java index d618bc8625..5948e82840 100644 --- a/src/main/java/twilightforest/block/BlockTFTrophyPedestal.java +++ b/src/main/java/twilightforest/block/BlockTFTrophyPedestal.java @@ -1,387 +1,198 @@ package twilightforest.block; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.entity.EntityClientPlayerMP; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.stats.StatFileWriter; -import net.minecraft.stats.StatisticsFile; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.Optional; +import thaumcraft.api.crafting.IInfusionStabiliser; import twilightforest.TwilightForestMod; +import twilightforest.advancements.TFAdvancements; +import twilightforest.client.ModelRegisterCallbackCTM; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.world.TFWorld; + +@Optional.Interface(modid = "thaumcraft", iface = "thaumcraft.api.crafting.IInfusionStabiliser") +public class BlockTFTrophyPedestal extends Block implements ModelRegisterCallbackCTM, IInfusionStabiliser { -public class BlockTFTrophyPedestal extends Block { - - private IIcon sprTopActive; - private IIcon sprTop; - private IIcon sprBottom; - private IIcon sprNagaActive; - private IIcon sprNaga; - private IIcon sprLichActive; - private IIcon sprLich; - private IIcon sprHydraActive; - private IIcon sprHydra; - private IIcon sprUrghastActive; - private IIcon sprUrghast; + public static final IProperty FACING = PropertyDirection.create("facing", EnumFacing.Plane.HORIZONTAL); + public static final IProperty LATENT = PropertyBool.create("latent"); + + private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); public BlockTFTrophyPedestal() { - super(Material.rock); + super(Material.ROCK); this.setHardness(2.0F); this.setResistance(2000.0F); - this.setStepSound(Block.soundTypeStone); - + this.setSoundType(SoundType.STONE); this.setCreativeTab(TFItems.creativeTab); + this.setDefaultState(getDefaultState().withProperty(LATENT, true).withProperty(FACING, EnumFacing.NORTH)); } - - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - - if (side == 1) - { - return meta > 7 ? sprTopActive : sprTop; - } - else if (side >= 2 && side <= 5) - { - // determine rotated side to show - int rotate = meta & 3; - int rotatedSide = ((side - 2) + rotate) % 4; - - switch (rotatedSide) - { - case 0: - return meta > 7 ? sprNagaActive : sprNaga; - case 1: - return meta > 7 ? sprLichActive : sprLich; - case 2: - return meta > 7 ? sprHydraActive : sprHydra; - case 3: - return meta > 7 ? sprUrghastActive : sprUrghast; - } - - } -// if (side == 2) -// { -// return meta > 7 ? sprNagaActive : sprNaga; -// } -// if (side == 3) -// { -// return meta > 7 ? sprLichActive : sprLich; -// } -// if (side == 4) -// { -// return meta > 7 ? sprHydraActive : sprHydra; -// } -// if (side == 5) -// { -// return meta > 7 ? sprUrghastActive : sprUrghast; -// } - - return sprTop; - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - this.sprTopActive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_top_active"); - this.sprTop = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_top"); - this.sprBottom = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_top"); - this.sprNagaActive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_naga_active"); - this.sprNaga = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_naga"); - this.sprLichActive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_lich_active"); - this.sprLich = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_lich"); - this.sprHydraActive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_hydra_active"); - this.sprHydra = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_hydra"); - this.sprUrghastActive = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_urghast_active"); - this.sprUrghast = par1IconRegister.registerIcon(TwilightForestMod.ID + ":pedestal_urghast"); - } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 15)); - } - - - /** - * Updates the blocks bounds based on its current state. Args: world, x, y, z - */ - @Override - public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { - this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); - } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - @Override - public boolean renderAsNormalBlock() - { - return false; - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - @Override - public boolean isOpaqueCube() - { - return false; - } - - - /** - * The type of render function that is called for this block - */ - @Override - public int getRenderType() - { - return TwilightForestMod.proxy.getPedestalBlockRenderID(); - } - - /** - * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given - * coordinates. Args: blockAccess, x, y, z, side - */ - @Override - @SideOnly(Side.CLIENT) - public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) - { - return true; - } - - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor blockID - */ - @Override - public void onNeighborBlockChange(World par1World, int x, int y, int z, Block myBlockID) - { - int meta = par1World.getBlockMetadata(x, y, z); + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING, LATENT); + } - if (!par1World.isRemote && meta > 0) - { - // something has changed, is there a trophy on top of us? - if (isTrophyOnTop(par1World, x, y, z)) - { - par1World.scheduleBlockUpdate(x, y, z, this, 1); - } - } - - } - - /** - * Called when the block is placed in the world. - */ - @Override - public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack) - { - int facing = MathHelper.floor_double(par5EntityLivingBase.rotationYaw * 4.0F / 360.0F + 0.5D) & 3; - - int latent = par6ItemStack.getItemDamage() & 8; + @Override + public int getMetaFromState(IBlockState state) { + int meta = state.getValue(FACING).getHorizontalIndex(); + if (state.getValue(LATENT)) { + meta |= 1 << 2; + } + return meta; + } - if (facing == 0) - { - par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | latent, 2); - } + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + IBlockState ret = getDefaultState(); + ret = ret.withProperty(FACING, EnumFacing.byHorizontalIndex(meta & 0b11)); + if ((meta & 0b100) > 0) { + ret = ret.withProperty(LATENT, true); + } + return ret; + } - if (facing == 1) - { - par1World.setBlockMetadataWithNotify(par2, par3, par4, 1 | latent, 2); - } + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return AABB; + } - if (facing == 2) - { - par1World.setBlockMetadataWithNotify(par2, par3, par4, 3 | latent, 2); - } + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } - if (facing == 3) - { - par1World.setBlockMetadataWithNotify(par2, par3, par4, 2 | latent, 2); - } - } - - /** - * Just checks if there is a trophy above the position indicated. Perhaps in the future we can accept different kinds of trophies. - */ - private boolean isTrophyOnTop(World world, int x, int y, int z) { - return world.getBlock(x, y + 1, z) == TFBlocks.trophy; + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; } - /** - * Ticks the block if it's been scheduled - */ @Override - public void updateTick(World world, int x, int y, int z, Random par5Random) - { - if (!world.isRemote) { - int meta = world.getBlockMetadata(x, y, z); + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) { - if (this.isTrophyOnTop(world, x, y, z)) { - // is the pedestal still "latent"? - if (meta > 7) { - // check enforced progression - if (world.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE)) { - if (this.areNearbyPlayersEligible(world, x, y, z)) { - doPedestalEffect(world, x, y, z, meta); - } - // warn players whether it works or not - warnIneligiblePlayers(world, x, y, z); - } else { - // just do it if enforced progression is turned off - doPedestalEffect(world, x, y, z, meta); - } - } + if (world.isRemote || !state.getValue(LATENT) || !isTrophyOnTop(world, pos)) return; - rewardNearbyPlayers(world, x, y, z); + if (TFWorld.isProgressionEnforced(world)) { + if (areNearbyPlayersEligible(world, pos)) { + doPedestalEffect(world, pos, state); } - } - } + warnIneligiblePlayers(world, pos); + } else { + doPedestalEffect(world, pos, state); + } + + rewardNearbyPlayers(world, pos); + } - private void warnIneligiblePlayers(World world, int x, int y, int z) { - // scan for players nearby to give the achievement - List nearbyPlayers = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1).expand(16.0D, 16.0D, 16.0D)); - - for (EntityPlayer player : nearbyPlayers) { + private boolean isTrophyOnTop(World world, BlockPos pos) { + return world.getBlockState(pos.up()).getBlock() == TFBlocks.trophy; + } + + private void warnIneligiblePlayers(World world, BlockPos pos) { + for (EntityPlayer player : world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB(pos).grow(16.0D))) { if (!isPlayerEligible(player)) { - player.addChatMessage(new ChatComponentText("You are unworthy.")); + player.sendStatusMessage(new TextComponentTranslation(TwilightForestMod.ID + ".trophy_pedestal.ineligible"), true); } } } - private boolean areNearbyPlayersEligible(World world, int x, int y, int z) { - boolean isEligible = false; - // scan for players nearby to give the achievement - List nearbyPlayers = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1).expand(16.0D, 16.0D, 16.0D)); - - for (EntityPlayer player : nearbyPlayers) { - isEligible |= isPlayerEligible(player); + private boolean areNearbyPlayersEligible(World world, BlockPos pos) { + for (EntityPlayer player : world.getEntitiesWithinAABB(EntityPlayer.class, new AxisAlignedBB(pos).grow(16.0D))) { + if (isPlayerEligible(player)) return true; } - - return isEligible; + return false; } private boolean isPlayerEligible(EntityPlayer player) { - if (player instanceof EntityPlayerMP && ((EntityPlayerMP)player).func_147099_x() != null) { - StatisticsFile stats = ((EntityPlayerMP)player).func_147099_x(); - - return stats.hasAchievementUnlocked(TFAchievementPage.twilightProgressTrophyPedestal.parentAchievement); - } else if (player instanceof EntityClientPlayerMP && ((EntityClientPlayerMP)player).getStatFileWriter() != null) { - StatFileWriter stats = ((EntityClientPlayerMP)player).getStatFileWriter(); - - return stats.hasAchievementUnlocked(TFAchievementPage.twilightProgressTrophyPedestal.parentAchievement); - } - // uh, not a player? - return false; + return TwilightForestMod.proxy.doesPlayerHaveAdvancement(player, TwilightForestMod.prefix("progress_lich")); } - private void doPedestalEffect(World world, int x, int y, int z, int meta) { - // if we're a latent pedestal, change to a non-latent! - // remove shield blocks - removeNearbyShields(world, x, y, z); - - // change this block meta to be non-latent - world.setBlockMetadataWithNotify(x, y, z, meta & 7, 2); - - // sound - world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "mob.zombie.infect", 4.0F, 0.1F); + private void doPedestalEffect(World world, BlockPos pos, IBlockState state) { + world.setBlockState(pos, state.withProperty(LATENT, false)); + removeNearbyShields(world, pos); + world.playSound(null, pos, SoundEvents.ENTITY_ZOMBIE_INFECT, SoundCategory.BLOCKS, 4.0F, 0.1F); } - @SuppressWarnings("unchecked") - private void rewardNearbyPlayers(World world, int x, int y, int z) { - // scan for players nearby to give the achievement - List nearbyPlayers = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 1, z + 1).expand(16.0D, 16.0D, 16.0D)); - - for (EntityPlayer player : nearbyPlayers) { - player.triggerAchievement(TFAchievementPage.twilightProgressTrophyPedestal); + private void rewardNearbyPlayers(World world, BlockPos pos) { + for (EntityPlayerMP player : world.getEntitiesWithinAABB(EntityPlayerMP.class, new AxisAlignedBB(pos).grow(16.0D))) { + TFAdvancements.PLACED_TROPHY_ON_PEDESTAL.trigger(player); } } - /** - * Remove shield blocks near the specified coordinates - */ - protected void removeNearbyShields(World world, int x, int y, int z) { + private void removeNearbyShields(World world, BlockPos pos) { for (int sx = -5; sx <= 5; sx++) - { for (int sy = -5; sy <= 5; sy++) - { for (int sz = -5; sz <= 5; sz++) - { - Block blockAt = world.getBlock(x + sx, y + sy, z + sz); - int metaAt = world.getBlockMetadata(x + sx, y + sy, z + sz); - - if (blockAt == TFBlocks.shield && metaAt == 15) - { - world.setBlock(x + sx, y + sy, z + sz, Blocks.air, 0, 2); - - // effect - world.playAuxSFX(2001, x + sx, y + sy, z + sz, Block.getIdFromBlock(blockAt) + (metaAt << 12)); - } - } - } - } + if (world.getBlockState(pos.add(sx, sy, sz)).getBlock() == TFBlocks.stronghold_shield) { + world.destroyBlock(pos.add(sx, sy, sz), false); + } } - - /** - * How many world ticks before ticking - */ - @Override - public int tickRate(World world) - { - return 10; - } - - /** - * Gets the hardness of block at the given coordinates in the given world, relative to the ability of the given - * EntityPlayer. - */ - @Override - public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World world, int x, int y, int z) - { - // not breakable if meta > 0 - int meta = world.getBlockMetadata(x, y, z); - - if (meta > 0) - { - return -1; - } - else - { - return super.getPlayerRelativeBlockHardness(par1EntityPlayer, world, x, y, z); - } - } + @Override + @Deprecated + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); + } + // todo ambiguous in 1.7, what was this supposed to be? + @Override + @Deprecated + public float getPlayerRelativeBlockHardness(IBlockState state, EntityPlayer player, World world, BlockPos pos) { + return state.getValue(LATENT) ? -1 : super.getPlayerRelativeBlockHardness(state, player, world, pos); + } + @Override + protected boolean canSilkHarvest() { + return false; + } + + @Override + public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + return false; + } + + @Override + public int damageDropped(IBlockState state) { + return 0; + } + + @Override + public boolean canStabaliseInfusion(World world, BlockPos blockPos) { + return true; + } + + @Override + public void registerItemModel() { + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, Loader.isModLoaded("ctm") ? new ModelResourceLocation(this.getRegistryName() + "_ctm", "latent=false") : new ModelResourceLocation(this.getRegistryName(), "latent=false")); + } + + @Override + public IProperty[] getIgnoredProperties() { + return new IProperty[] { FACING }; + } } diff --git a/src/main/java/twilightforest/block/BlockTFUberousSoil.java b/src/main/java/twilightforest/block/BlockTFUberousSoil.java index 4dfd5624cb..26ad9a191e 100644 --- a/src/main/java/twilightforest/block/BlockTFUberousSoil.java +++ b/src/main/java/twilightforest/block/BlockTFUberousSoil.java @@ -1,166 +1,142 @@ package twilightforest.block; -import java.util.Random; - -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; import net.minecraft.block.Block; +import net.minecraft.block.BlockFarmland; import net.minecraft.block.IGrowable; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemDye; import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.EnumPlantType; import net.minecraftforge.common.IPlantable; -import net.minecraftforge.common.util.ForgeDirection; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +import java.util.Random; -public class BlockTFUberousSoil extends Block implements IGrowable { +public class BlockTFUberousSoil extends Block implements IGrowable, ModelRegisterCallback { + private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); protected BlockTFUberousSoil() { - super(Material.ground); - this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); - this.setLightOpacity(255); - this.setHardness(0.6F); - this.setStepSound(soundTypeGravel); - this.setTickRandomly(true); - - this.setBlockTextureName(TwilightForestMod.ID + ":uberous_soil"); - + super(Material.GROUND); + this.setLightOpacity(255); + this.setHardness(0.6F); + this.setSoundType(SoundType.GROUND); + this.setTickRandomly(true); + this.useNeighborBrightness = true; + this.setCreativeTab(TFItems.creativeTab); - } - - /** - * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two - * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. - */ - public boolean isOpaqueCube() - { - return false; - } - - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - public boolean renderAsNormalBlock() - { - return false; - } - - public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) - { - return Blocks.dirt.getItemDropped(0, p_149650_2_, p_149650_3_); - } - - /** - * Ticks the block if it's been scheduled - */ - public void updateTick(World world, int x, int y, int z, Random rand) { - Material aboveMaterial = world.getBlock(x, y + 1, z).getMaterial(); - if (aboveMaterial.isSolid()) { - world.setBlock(x, y, z, Blocks.dirt); - } - } - - /** - * Determines if this block can support the passed in plant, allowing it to be planted and grow. - * Some examples: - * Reeds check if its a reed, or if its sand/dirt/grass and adjacent to water - * Cacti checks if its a cacti, or if its sand - * Nether types check for soul sand - * Crops check for tilled soil - * Caves check if it's a solid surface - * Plains check if its grass or dirt - * Water check if its still water - * - * @param world The current world - * @param x X Position - * @param y Y Position - * @param z Z position - * @param direction The direction relative to the given position the plant wants to be, typically its UP - * @param plantable The plant that wants to check - * @return True to allow the plant to be planted/stay. - */ - public boolean canSustainPlant(IBlockAccess world, int x, int y, int z, ForgeDirection direction, IPlantable plantable) - { - //Block plant = plantable.getPlant(world, x, y + 1, z); - EnumPlantType plantType = plantable.getPlantType(world, x, y + 1, z); - - return plantType == EnumPlantType.Crop || plantType == EnumPlantType.Plains || plantType == EnumPlantType.Cave; - } - - /** - * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are - * their own) Args: x, y, z, neighbor Block - */ - public void onNeighborBlockChange(World world, int x, int y, int z, Block neighbor) { - Block above = world.getBlock(x, y + 1, z); - Material aboveMaterial = above.getMaterial(); - - if (aboveMaterial.isSolid()) - { - world.setBlock(x, y, z, Blocks.dirt); - } - - if (above instanceof IPlantable) { - IPlantable plant = (IPlantable)above; - // revert to farmland or grass - if (plant.getPlantType(world, x, y + 1, z) == EnumPlantType.Crop) { - world.setBlock(x, y, z, Blocks.farmland, 2, 2); - } else if (plant.getPlantType(world, x, y + 1, z) == EnumPlantType.Plains) { - world.setBlock(x, y, z, Blocks.grass); - } else { - world.setBlock(x, y, z, Blocks.dirt); - } - // apply bonemeal - ItemDye.applyBonemeal(new ItemStack(Items.dye), world, x, y + 1, z, null); - ItemDye.applyBonemeal(new ItemStack(Items.dye), world, x, y + 1, z, null); - ItemDye.applyBonemeal(new ItemStack(Items.dye), world, x, y + 1, z, null); - ItemDye.applyBonemeal(new ItemStack(Items.dye), world, x, y + 1, z, null); - // green sparkles - if (!world.isRemote) { - world.playAuxSFX(2005, x, y + 1, z, 0); - } - } - } - - /** - * Is is possible for us to grow? - */ + } + + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return AABB; + } + + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) { + return face == EnumFacing.DOWN ? BlockFaceShape.SOLID : BlockFaceShape.UNDEFINED; + } + @Override - public boolean func_149851_a(World world, int x, int y, int z, boolean var5) { + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.TRANSLUCENT; + } + + @Override + public Item getItemDropped(IBlockState state, Random rand, int fortune) { + return Item.getItemFromBlock(Blocks.DIRT); + } + + @Override + public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { + Material aboveMaterial = world.getBlockState(pos.up()).getMaterial(); + if (aboveMaterial.isSolid()) { + world.setBlockState(pos, Blocks.DIRT.getDefaultState()); + } + } + + @Override + public boolean canSustainPlant(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing direction, IPlantable plantable) { + if (direction != EnumFacing.UP) + return false; + EnumPlantType plantType = plantable.getPlantType(world, pos.offset(direction)); + return plantType == EnumPlantType.Crop || plantType == EnumPlantType.Plains || plantType == EnumPlantType.Cave; + } + + @Override + @Deprecated + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block neighbor, BlockPos fromPos) { + IBlockState above = world.getBlockState(pos.up()); + Material aboveMaterial = above.getMaterial(); + + if (aboveMaterial.isSolid()) { + world.setBlockState(pos, Blocks.DIRT.getDefaultState()); + } + + // todo should probably use IGrowable and loop until it can't grow anymore + if (above.getBlock() instanceof IPlantable) { + IPlantable plant = (IPlantable) above.getBlock(); + // revert to farmland or grass + if (plant.getPlantType(world, pos.up()) == EnumPlantType.Crop) { + world.setBlockState(pos, Blocks.FARMLAND.getDefaultState().withProperty(BlockFarmland.MOISTURE, 2)); + } else if (plant.getPlantType(world, pos.up()) == EnumPlantType.Plains) { + world.setBlockState(pos, Blocks.GRASS.getDefaultState()); + } else { + world.setBlockState(pos, Blocks.DIRT.getDefaultState()); + } + // apply bonemeal + ItemDye.applyBonemeal(new ItemStack(Items.DYE), world, pos.up()); + ItemDye.applyBonemeal(new ItemStack(Items.DYE), world, pos.up()); + ItemDye.applyBonemeal(new ItemStack(Items.DYE), world, pos.up()); + ItemDye.applyBonemeal(new ItemStack(Items.DYE), world, pos.up()); + // green sparkles + world.playEvent(2005, pos.up(), 0); + } + } + + @Override + public boolean canGrow(World world, BlockPos pos, IBlockState state, boolean isClient) { return true; } - /** - * Have we randomly decided it's okay to grow? - */ @Override - public boolean func_149852_a(World world, Random rand, int x, int y, int z) { + public boolean canUseBonemeal(World world, Random rand, BlockPos pos, IBlockState state) { return true; } - /** - * Do the growth! - */ @Override - public void func_149853_b(World world, Random rand, int x, int y, int z) { - int gx = x; - int gy = y; - int gz = z; - - if (rand.nextBoolean()) { - gx += (rand.nextBoolean() ? 1 : -1); - } else { - gz += (rand.nextBoolean() ? 1 : -1); - } + public void grow(World world, Random rand, BlockPos pos, IBlockState state) { + pos = pos.offset(EnumFacing.HORIZONTALS[rand.nextInt(EnumFacing.HORIZONTALS.length)]); - Block blockAt = world.getBlock(gx, gy, gz); - if (world.isAirBlock(gx, gy + 1, gz) && (blockAt == Blocks.dirt || blockAt == Blocks.grass || blockAt == Blocks.farmland)) { - world.setBlock(gx, gy, gz, this); + Block blockAt = world.getBlockState(pos).getBlock(); + if (world.isAirBlock(pos.up()) && (blockAt == Blocks.DIRT || blockAt == Blocks.GRASS || blockAt == Blocks.FARMLAND)) { + world.setBlockState(pos, this.getDefaultState()); } } } diff --git a/src/main/java/twilightforest/block/BlockTFUncraftingTable.java b/src/main/java/twilightforest/block/BlockTFUncraftingTable.java index 686c4e8a5e..69143689d9 100644 --- a/src/main/java/twilightforest/block/BlockTFUncraftingTable.java +++ b/src/main/java/twilightforest/block/BlockTFUncraftingTable.java @@ -1,68 +1,48 @@ package twilightforest.block; -import java.util.List; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.stats.StatList; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFUncraftingTable extends Block { - - public static IIcon tinkerTop; - public static IIcon tinkerSide; - +public class BlockTFUncraftingTable extends Block implements ModelRegisterCallback { + protected BlockTFUncraftingTable() { - super(Material.wood); + super(Material.WOOD); this.setHardness(2.5F); - this.setStepSound(Block.soundTypeWood); + this.setSoundType(SoundType.WOOD); this.setCreativeTab(TFItems.creativeTab); } + @Override + public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + if (world.isRemote) return true; - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ - @Override - public IIcon getIcon(int side, int meta) - { - return side == 1 ? tinkerTop : tinkerSide; - } - - @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { - tinkerTop = par1IconRegister.registerIcon(TwilightForestMod.ID + ":uncrafting_top"); - tinkerSide = par1IconRegister.registerIcon(TwilightForestMod.ID + ":uncrafting_side"); - } - - /** - * Called when the block is clicked by a player. Args: x, y, z, entityPlayer - */ - @Override - public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int par6, float par7, float par8, float par9) { - player.openGui(TwilightForestMod.instance, 1, world, x, y, z); - return true; + player.openGui(TwilightForestMod.instance, 1, world, pos.getX(), pos.getY(), pos.getZ()); + player.addStat(StatList.CRAFTING_TABLE_INTERACTION); + return true; } - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - } - - + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelResourceLocation mrl = new ModelResourceLocation(this.getRegistryName(), Loader.isModLoaded("ctm") ? "ctm" : "normal"); + ModelLoader.setCustomStateMapper(this, new SingleStateMapper(mrl)); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), 0, mrl); + } } diff --git a/src/main/java/twilightforest/block/BlockTFUnderBrick.java b/src/main/java/twilightforest/block/BlockTFUnderBrick.java index 8566c63366..f824dd6d96 100644 --- a/src/main/java/twilightforest/block/BlockTFUnderBrick.java +++ b/src/main/java/twilightforest/block/BlockTFUnderBrick.java @@ -1,114 +1,67 @@ package twilightforest.block; -import java.util.List; - import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.IBlockAccess; -import twilightforest.TwilightForestMod; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.enums.UnderBrickVariant; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class BlockTFUnderBrick extends Block { - - private static IIcon[] iconSide = new IIcon[4]; -// private static IIcon[] iconFloor = new IIcon[4]; +public class BlockTFUnderBrick extends Block implements ModelRegisterCallback { + public static final IProperty VARIANT = PropertyEnum.create("variant", UnderBrickVariant.class); public BlockTFUnderBrick() { - super(Material.rock); + super(Material.ROCK, MapColor.WOOD); this.setHardness(1.5F); this.setResistance(10.0F); - this.setStepSound(Block.soundTypeStone); - + this.setSoundType(SoundType.STONE); + setDefaultState(blockState.getBaseState().withProperty(VARIANT, UnderBrickVariant.NORMAL)); this.setCreativeTab(TFItems.creativeTab); - } + @Override + public BlockStateContainer createBlockState() { + return new BlockStateContainer(this, VARIANT); + } @Override - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister par1IconRegister) - { -// for (int i = 0; i < this.iconSide.length; i++) -// { -// this.iconFloor[i] = Blocks.stonebrick.getIcon(0, i); -// } - - BlockTFUnderBrick.iconSide[0] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":knightbrick"); - BlockTFUnderBrick.iconSide[1] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":knightbrick_mossy"); - BlockTFUnderBrick.iconSide[2] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":knightbrick_cracked"); - -// this.iconFloor[0] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":knightbrick_floor"); -// this.iconFloor[1] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":knightbrick_floor"); -// this.iconFloor[2] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":knightbrick_floor"); + public int getMetaFromState(IBlockState state) { + return state.getValue(VARIANT).ordinal(); } + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(VARIANT, UnderBrickVariant.values()[meta]); + } - /** - * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata - */ @Override - public IIcon getIcon(int side, int meta) { - if (meta < BlockTFUnderBrick.iconSide.length) - { - if (side == 0 || side == 1) - { - return BlockTFUnderBrick.iconSide[meta]; - } - else - { - return BlockTFUnderBrick.iconSide[meta]; - } - } - else - { - if (side == 0 || side == 1) - { - return BlockTFUnderBrick.iconSide[0]; - } - else - { - return BlockTFUnderBrick.iconSide[0]; - } + public void getSubBlocks(CreativeTabs creativeTab, NonNullList list) { + for (UnderBrickVariant variant : UnderBrickVariant.values()) { + list.add(new ItemStack(this, 1, variant.ordinal())); } } - - /** - * Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called - * when first determining what to render. - */ - @Override - public int colorMultiplier(IBlockAccess par1IBlockAccess, int x, int y, int z) - { - int meta = par1IBlockAccess.getBlockMetadata(x, y, z); - return 0xFFFFFF; - } + @Override + public int damageDropped(IBlockState state) { + return getMetaFromState(state); + } - - /** - * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks) - */ - @Override - public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - par3List.add(new ItemStack(par1, 1, 0)); - par3List.add(new ItemStack(par1, 1, 1)); - par3List.add(new ItemStack(par1, 1, 2)); - } - - /** - * Determines the damage on the item the block drops. Used in cloth and wood. - */ - @Override - public int damageDropped(int meta) { - return meta; + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelUtils.registerToStateSingleVariant(this, VARIANT); } } diff --git a/src/main/java/twilightforest/block/BlockTFUnripeTorchCluster.java b/src/main/java/twilightforest/block/BlockTFUnripeTorchCluster.java index 550c366b60..dd152437eb 100644 --- a/src/main/java/twilightforest/block/BlockTFUnripeTorchCluster.java +++ b/src/main/java/twilightforest/block/BlockTFUnripeTorchCluster.java @@ -1,35 +1,21 @@ package twilightforest.block; -import java.util.Random; - -import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; + +import java.util.Random; public class BlockTFUnripeTorchCluster extends BlockTFTrollRoot { - private static final int RIPEN_THRESHHOLD = 6; - - protected BlockTFUnripeTorchCluster() { - super(); - - this.setBlockTextureName(TwilightForestMod.ID + ":unripe_torch_cluster"); - - } - - - /** - * Ticks the block if it's been scheduled - */ @Override - public void updateTick(World world, int x, int y, int z, Random rand) { - super.updateTick(world, x, y, z, rand); + public void updateTick(World world, BlockPos pos, IBlockState state, Random rand) { + super.updateTick(world, pos, state, rand); - if (world.getBlockLightValue(x, y, z) >= RIPEN_THRESHHOLD) { - // ripen! - world.setBlock(x, y, z, TFBlocks.trollBer); - } - } + if (world.getLight(pos) >= RIPEN_THRESHHOLD) { + // ripen! + world.setBlockState(pos, TFBlocks.trollber.getDefaultState()); + } + } } diff --git a/src/main/java/twilightforest/block/BlockTFWallPillar.java b/src/main/java/twilightforest/block/BlockTFWallPillar.java new file mode 100644 index 0000000000..92a6f97c03 --- /dev/null +++ b/src/main/java/twilightforest/block/BlockTFWallPillar.java @@ -0,0 +1,71 @@ +package twilightforest.block; + +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallbackCTM; +import twilightforest.client.ModelUtils; + +public class BlockTFWallPillar extends BlockTFConnectableRotatedPillar implements ModelRegisterCallbackCTM { + + protected static final PropertyBool UP = PropertyBool.create("up"); + protected static final PropertyBool DOWN = PropertyBool.create("down"); + + BlockTFWallPillar(Material material, double width, double height) { + super(material, width, height); + + this.setDefaultState(this.getDefaultState().withProperty(UP, false).withProperty(DOWN, false)); + } + + @Override + protected IProperty[] getAdditionalProperties() { + return new IProperty[]{ UP, DOWN }; + } + + @Override + protected boolean canConnectTo(IBlockState state, IBlockState otherState, IBlockAccess world, BlockPos pos, EnumFacing connectTo) { + return otherState.getBlock() == this && state.getValue(AXIS) == otherState.getValue(AXIS); + } + + @Override + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { + return /*(!state.getValue(UP)) || (!state.getValue(DOWN)) ? FULL_BLOCK_AABB :*/ super.getBoundingBox(state, world, pos); + } + + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) { + EnumFacing.Axis axis = state.getValue(AXIS); + return super.getActualState(state.withProperty(UP, canConnectTo(state, world.getBlockState(pos.offset(getFacingFromPropertyWithAxis(UP, axis))), world, pos, EnumFacing.UP)).withProperty(DOWN, canConnectTo(state, world.getBlockState(pos.offset(getFacingFromPropertyWithAxis(DOWN, axis))), world, pos, EnumFacing.DOWN)), world, pos); + } + + private static EnumFacing getFacingFromPropertyWithAxis(PropertyBool property, EnumFacing.Axis axis) { + switch (axis) { + case X: + if (property == DOWN) return EnumFacing.WEST; + if (property == UP ) return EnumFacing.EAST; + break; + case Y: + if (property == DOWN) return EnumFacing.DOWN; + if (property == UP ) return EnumFacing.UP; + break; + case Z: + if (property == DOWN) return EnumFacing.SOUTH; + if (property == UP ) return EnumFacing.NORTH; + break; + } + + TwilightForestMod.LOGGER.warn("BlockTFWallPillar helper (getFacingFromPropertyWithAxis) had a problem? (property '{}' with axis '{}')", property.getName(), axis.getName()); + return BlockTFConnectableRotatedPillar.PairHelper.getFacingFromPropertyWithAxis(property, axis); + } + + @Override + public void registerModel() { + ModelUtils.registerToState(this, 0, this.getDefaultState()); + } +} diff --git a/src/main/java/twilightforest/block/BlockTFWispyCloud.java b/src/main/java/twilightforest/block/BlockTFWispyCloud.java index 2516357aea..c98f3d92ff 100644 --- a/src/main/java/twilightforest/block/BlockTFWispyCloud.java +++ b/src/main/java/twilightforest/block/BlockTFWispyCloud.java @@ -1,65 +1,40 @@ package twilightforest.block; -import java.util.Random; - -import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.BlockBreakable; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +import java.util.Random; -public class BlockTFWispyCloud extends BlockBreakable { +public class BlockTFWispyCloud extends BlockBreakable implements ModelRegisterCallback { protected BlockTFWispyCloud() { - super("", Material.craftedSnow, false); - this.setStepSound(soundTypeCloth); + super(new Material(MapColor.SNOW), false); + this.setSoundType(SoundType.CLOTH); this.setCreativeTab(TFItems.creativeTab); - this.setHardness(0.3F); - this.setBlockTextureName(TwilightForestMod.ID + ":wispy_cloud"); - } - @SideOnly(Side.CLIENT) - public void registerBlockIcons(IIconRegister p_149651_1_) - { - this.blockIcon = p_149651_1_.registerIcon(this.getTextureName()); - } - - /** - * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha - */ - @SideOnly(Side.CLIENT) - public int getRenderBlockPass() - { - return 1; - } - + @Override + public BlockRenderLayer getRenderLayer() { + return BlockRenderLayer.TRANSLUCENT; + } - /** - * Return true if a player with Silk Touch can harvest this block directly, and not its normal drops. - */ - protected boolean canSilkHarvest() - { - return true; - } - - /** - * Returns the quantity of items to drop on block destruction. - */ - public int quantityDropped(Random p_149745_1_) - { - return 0; - } - + @Override + public boolean canSilkHarvest(World world, BlockPos pos, IBlockState state, EntityPlayer player) { + return true; + } - /** - * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) - */ - public boolean renderAsNormalBlock() - { - return false; - } + @Override + public int quantityDropped(Random random) { + return 0; + } } diff --git a/src/main/java/twilightforest/block/GiantBlockIcon.java b/src/main/java/twilightforest/block/GiantBlockIcon.java deleted file mode 100644 index 8e1eda04d1..0000000000 --- a/src/main/java/twilightforest/block/GiantBlockIcon.java +++ /dev/null @@ -1,67 +0,0 @@ -package twilightforest.block; - -import net.minecraft.util.IIcon; - -public class GiantBlockIcon implements IIcon { - - private IIcon baseIcon; - private int myX; - private int myY; - - public GiantBlockIcon(IIcon blockIcon, int x, int y) { - this.baseIcon = blockIcon; - this.myX = x; - this.myY = y; - } - - @Override - public int getIconWidth() { - return this.baseIcon.getIconWidth() / 4; - } - - @Override - public int getIconHeight() { - return this.baseIcon.getIconHeight() / 4; - } - - @Override - public float getMinU() { - float f = this.baseIcon.getMaxU() - this.baseIcon.getMinU(); - return this.baseIcon.getMinU() + (f * 0.25F * myX); - } - - @Override - public float getMaxU() { - float f = this.baseIcon.getMaxU() - this.baseIcon.getMinU(); - return this.baseIcon.getMaxU() - (f * 0.25F * (3 - myX)); - } - - @Override - public float getInterpolatedU(double par1) { - float f = this.getMaxU() - this.getMinU(); - return this.getMinU() + f * (float)par1 / 16.0F; - } - - @Override - public float getMinV() { - float f = this.baseIcon.getMaxV() - this.baseIcon.getMinV(); - return this.baseIcon.getMinV() + (f * 0.25F * myY); - } - - @Override - public float getMaxV() { - float f = this.baseIcon.getMaxV() - this.baseIcon.getMinV(); - return this.baseIcon.getMaxV() - (f * 0.25F * (3 - myY)); - } - - @Override - public float getInterpolatedV(double par1) { - float f = this.getMaxV() - this.getMinV(); - return this.getMinV() + f * ((float)par1 / 16.0F); - } - - @Override - public String getIconName() { - return this.baseIcon.getIconName(); - } -} diff --git a/src/main/java/twilightforest/block/RegisterBlockEvent.java b/src/main/java/twilightforest/block/RegisterBlockEvent.java new file mode 100644 index 0000000000..fbbf4ed9ae --- /dev/null +++ b/src/main/java/twilightforest/block/RegisterBlockEvent.java @@ -0,0 +1,242 @@ +package twilightforest.block; + +import net.minecraft.block.*; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.properties.PropertyEnum; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.registries.IForgeRegistry; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.ModelUtils; +import twilightforest.enums.CastleBrickVariant; +import twilightforest.enums.MagicWoodVariant; +import twilightforest.enums.WoodVariant; +import twilightforest.item.TFItems; +import twilightforest.util.IMapColorSupplier; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public final class RegisterBlockEvent { + @SubscribeEvent + public static void onRegisterBlocks(RegistryEvent.Register event) { + BlockRegistryHelper blocks = new BlockRegistryHelper(event.getRegistry()); + + blocks.register("twilight_log", "Log", new BlockTFLog()); + blocks.register("root", "Roots", new BlockTFRoots()); + blocks.register("twilight_leaves", "Leaves", new BlockTFLeaves()); + blocks.register("firefly", "Firefly", new BlockTFFirefly()); + blocks.register("cicada", "Cicada", new BlockTFCicada()); + blocks.register("twilight_portal", "Portal", new BlockTFPortal()); + blocks.register("maze_stone", "Mazestone", new BlockTFMazestone()); + blocks.register("hedge", "Hedge", new BlockTFHedge()); + blocks.register("boss_spawner", "BossSpawner", new BlockTFBossSpawner().setBlockUnbreakable()); + blocks.register("firefly_jar", "FireflyJar", new BlockTFFireflyJar()); + blocks.register("twilight_plant", "Plant", new BlockTFPlant()); + blocks.register("uncrafting_table", "UncraftingTable", new BlockTFUncraftingTable()); + blocks.register("fire_jet", "FireJet", new BlockTFFireJet()); + blocks.register("naga_stone", "Nagastone", new BlockTFNagastone()); + blocks.register("twilight_sapling", "Sapling", new BlockTFSapling()); + blocks.register("moonworm", "Moonworm", new BlockTFMoonworm()); + blocks.register("magic_log", "MagicLog", new BlockTFMagicLog()); + blocks.register("magic_leaves", "MagicLeaves", new BlockTFMagicLeaves()); + blocks.register("magic_log_core", "MagicLogSpecial", new BlockTFMagicLogSpecial()); + blocks.register("tower_wood", "TowerStone", new BlockTFTowerWood()); + blocks.register("tower_device", "TowerDevice", new BlockTFTowerDevice()); + blocks.register("tower_translucent", "TowerTranslucent", new BlockTFTowerTranslucent()); + blocks.register("trophy", "Trophy", new BlockTFTrophy()); + blocks.register("stronghold_shield", "Shield", new BlockTFShield()); + blocks.register("trophy_pedestal", "TrophyPedestal", new BlockTFTrophyPedestal()); + blocks.register("aurora_block", "AuroraBrick", new BlockTFAuroraBrick()); + blocks.register("underbrick", "UnderBrick", new BlockTFUnderBrick()); + blocks.register("thorns", "Thorns", new BlockTFThorns()); + blocks.register("burnt_thorns", "BurntThorns", new BlockTFBurntThorns()); + blocks.register("thorn_rose", "ThornRose", new BlockTFThornRose()); + blocks.register("twilight_leaves_3", "Leaves3", new BlockTFLeaves3()); + blocks.register("deadrock", "Deadrock", new BlockTFDeadrock()); + blocks.register("dark_leaves", "DarkLeaves", new BlockTFDarkLeaves()); + blocks.register("aurora_pillar", "AuroraPillar", new BlockTFPillar(Material.PACKED_ICE).setHardness(2.0F).setResistance(10.0F)); + blocks.register("aurora_slab", "AuroraSlab", new BlockTFAuroraSlab(false)); + blocks.register("double_aurora_slab", "AuroraDoubleSlab", new BlockTFAuroraSlab(true)); + blocks.register("trollsteinn", "TrollSteinn", new BlockTFTrollSteinn()); + blocks.register("wispy_cloud", "WispyCloud", new BlockTFWispyCloud()); + blocks.register("fluffy_cloud", "FluffyCloud", new BlockTFFluffyCloud()); + blocks.register("giant_cobblestone", "GiantCobble", new BlockTFGiantCobble()); + blocks.register("giant_log", "GiantLog", new BlockTFGiantLog()); + blocks.register("giant_leaves", "GiantLeaves", new BlockTFGiantLeaves()); + blocks.register("giant_obsidian", "GiantObsidian", new BlockTFGiantObsidian()); + blocks.register("uberous_soil", "UberousSoil", new BlockTFUberousSoil()); + blocks.register("huge_stalk", "HugeStalk", new BlockTFHugeStalk()); + blocks.register("huge_mushgloom", "HugeGloomBlock", new BlockTFHugeGloomBlock()); + blocks.register("trollvidr", "TrollVidr", new BlockTFTrollRoot()); + blocks.register("unripe_trollber", "UnripeTrollBer", new BlockTFUnripeTorchCluster()); + blocks.register("trollber", "TrollBer", new BlockTFRipeTorchCluster()); + blocks.register("knightmetal_block", "KnightmetalBlock", new BlockTFKnightmetalBlock()); + blocks.register("huge_lilypad", "HugeLilyPad", new BlockTFHugeLilyPad()); + blocks.register("huge_waterlily", "HugeWaterLily", new BlockTFHugeWaterLily()); + blocks.register("slider", "Slider", new BlockTFSlider()); + Block castleBrick = new BlockTFCastleBlock(); + IBlockState castleState = castleBrick.getDefaultState(); + blocks.register("castle_brick", "CastleBrick", castleBrick); + blocks.register("castle_stairs_brick", "CastleStairsBrick", new BlockTFStairs(castleState)); + blocks.register("castle_stairs_worn", "CastleStairsWorn", new BlockTFStairs(castleState.withProperty(BlockTFCastleBlock.VARIANT, CastleBrickVariant.WORN))); + blocks.register("castle_stairs_cracked", "CastleStairsCracked", new BlockTFStairs(castleState.withProperty(BlockTFCastleBlock.VARIANT, CastleBrickVariant.CRACKED))); + blocks.register("castle_stairs_mossy", "CastleStairsMossy", new BlockTFStairs(castleState.withProperty(BlockTFCastleBlock.VARIANT, CastleBrickVariant.MOSSY))); + Block castlePillar = new BlockTFCastlePillar(); + blocks.register("castle_pillar", "CastlePillar", castlePillar); + blocks.register("castle_stairs", "CastleStairs", new BlockTFCastleStairs(castlePillar.getDefaultState())); + blocks.register("castle_rune_brick", "CastleMagic", new BlockTFCastleMagic()); + blocks.register("force_field", "ForceField", new BlockTFForceField()); + blocks.register("cinder_furnace", "CinderFurnaceIdle", new BlockTFCinderFurnace(false)); + blocks.register("cinder_furnace_lit", "CinderFurnaceLit", new BlockTFCinderFurnace(true)); + blocks.register("cinder_log", "CinderLog", new BlockTFCinderLog()); + blocks.register("castle_door", "CastleDoor", new BlockTFCastleDoor(false)); + blocks.register("castle_door_vanished", "CastleDoorVanished", new BlockTFCastleDoor(true)); + blocks.register("castle_unlock", "CastleUnlock", new BlockTFCastleUnlock()); + blocks.register("experiment_115", "experiment115", new BlockTFExperiment115().setHardness(0.5F)); + blocks.register("miniature_structure", "MiniatureStructure", new BlockTFMiniatureStructure().setHardness(0.75F)); + blocks.register("block_storage", "BlockOfStorage", new BlockTFCompressed()); + blocks.register("lapis_block", "BlockOfLapisTF", new BlockTFLapisBlock()); + blocks.register("spiral_bricks", "SpiralBricks", new BlockTFSpiralBrick()); + Block etchedNagastone = new BlockTFNagastoneEtched().setHardness(1.5F).setResistance(10.0F); + blocks.register("etched_nagastone", "EtchedNagastone", etchedNagastone); + blocks.register("nagastone_stairs", "NagastoneStairs", new BlockTFNagastoneStairs(etchedNagastone.getDefaultState()).setHardness(1.5F).setResistance(10.0F)); + blocks.register("nagastone_pillar", "NagastonePillar", new BlockTFNagastonePillar().setHardness(1.5F).setResistance(10.0F)); + Block etchedNagastoneMossy = new BlockTFNagastoneEtched().setHardness(1.5F).setResistance(10.0F); + blocks.register("etched_nagastone_mossy", "EtchedNagastoneMossy", etchedNagastoneMossy); + blocks.register("nagastone_stairs_mossy", "NagastoneStairsMossy", new BlockTFNagastoneStairs(etchedNagastoneMossy.getDefaultState()).setHardness(1.5F).setResistance(10.0F)); + blocks.register("nagastone_pillar_mossy", "NagastonePillarMossy", new BlockTFNagastonePillar().setHardness(1.5F).setResistance(10.0F)); + Block etchedNagastoneWeathered = new BlockTFNagastoneEtched().setHardness(1.5F).setResistance(10.0F); + blocks.register("etched_nagastone_weathered", "EtchedNagastoneWeathered", etchedNagastoneWeathered); + blocks.register("nagastone_stairs_weathered", "NagastoneStairsWeathered", new BlockTFNagastoneStairs(etchedNagastoneWeathered.getDefaultState()).setHardness(1.5F).setResistance(10.0F)); + blocks.register("nagastone_pillar_weathered", "NagastonePillarWeathered", new BlockTFNagastonePillar().setHardness(1.5F).setResistance(10.0F)); + blocks.register("auroralized_glass", "AuroralizedGlass", new BlockTFAuroralizedGlass()); + blocks.register("iron_ladder", "IronLadder", new BlockTFLadderBars().setSoundType(SoundType.METAL).setHardness(5.0F).setResistance(10.0F)); + + registerWoodVariants(blocks, BlockTFLog.VARIANT, WoodVariant.values()); + registerWoodVariants(blocks, BlockTFMagicLog.VARIANT, MagicWoodVariant.values()); + + blocks.register("terrorcotta_circle", "TerrorCottaCircle", new BlockTFHorizontal(Material.ROCK, MapColor.SAND).setSoundType(SoundType.STONE).setHardness(1.7F)); + blocks.register("terrorcotta_diagonal", "TerrorCottaDiagonal", new BlockTFDiagonal(Material.ROCK, MapColor.SAND).setSoundType(SoundType.STONE).setHardness(1.7F)); + blocks.register("stone_twist", "StonePillar", new BlockTFPillar(Material.ROCK).setHardness(1.5F).setResistance(10.0F)); + blocks.register("stone_twist_thin", "StonePillarThin", new BlockTFWallPillar(Material.ROCK, 12, 16).setHardness(1.5F).setResistance(10.0F)); + + registerFluidBlock(blocks, moltenFiery); + registerFluidBlock(blocks, moltenKnightmetal); + registerFluidBlock("fiery_essence", blocks, essenceFiery); + } + + private static & IStringSerializable & IMapColorSupplier> void registerWoodVariants(BlockRegistryHelper blocks, final IProperty key, final T[] types) { + for (T woodType : types) { + String woodName = woodType.getName(); + String woodNameCapitalized; + + if ("oak".equals(woodName)) { // Not really going to rename that enum entry just yet + woodName = "twilight_oak"; + woodNameCapitalized = "TwilightOak"; + } else { + woodNameCapitalized = woodName.substring(0, 1).toUpperCase() + woodName.substring(1); + } + + // Not going to initialize these two over 60 times + final String inventory = "inventory"; + final IProperty[] noProperty = new IProperty[0]; + + // Make special property key that allows ONLY one value because slabs are special level of stupid + final PropertyEnum restrictedKey = PropertyEnum.create("variant", key.getValueClass(), input -> input == woodType); + + Block planks = blocks.register(woodName + "_planks", woodNameCapitalized + "Planks", new BlockTF(Material.WOOD, woodType.supplyMapColor()) { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, noProperty); }}).setSoundType(SoundType.WOOD).setHardness(2.0F).setResistance(5.0F); + blocks.register(woodName + "_stairs" , woodNameCapitalized + "Stairs" , new BlockTFStairs(planks.getDefaultState()) { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, noProperty); }}); // No hardness/soundType, that's derived from IBlockState in + Block singleSlab = blocks.register(woodName + "_slab", woodNameCapitalized + "Slab", new BlockTFSlab(Material.WOOD, woodType.supplyMapColor(), woodType) { @Override public boolean isDouble() { return false; } @Override protected Block getSingle() { return this; } @Override public IProperty getVariantProperty() { return restrictedKey; } @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, restrictedKey); }}).setSoundType(SoundType.WOOD).setHardness(2.0F).setResistance(5.0F); + blocks.register(woodName + "_doubleslab", woodNameCapitalized + "Slab" , new BlockTFSlab(Material.WOOD, woodType.supplyMapColor(), woodType) { @Override public boolean isDouble() { return true; } @Override protected Block getSingle() { return singleSlab; } @Override public IProperty getVariantProperty() { return restrictedKey; } @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, restrictedKey); }}).setSoundType(SoundType.WOOD).setHardness(2.0F).setResistance(5.0F); + blocks.register(woodName + "_button" , woodNameCapitalized + "Button" , new BlockTFButtonWood() { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, noProperty); }}).setSoundType(SoundType.WOOD).setHardness(0.5F); + blocks.register(woodName + "_door" , woodNameCapitalized + "Door" , new BlockTFDoor(Material.WOOD, woodType.supplyMapColor(), new ResourceLocation(TwilightForestMod.ID, woodName + "_door")) { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, BlockTFDoor.POWERED); } { setSoundType(SoundType.WOOD); }}).setHardness(3.0F); + blocks.register(woodName + "_trapdoor" , woodNameCapitalized + "TrapDoor", new BlockTFTrapDoor(Material.WOOD, woodType.supplyMapColor()) { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, noProperty); }}).setSoundType(SoundType.WOOD).setHardness(3.0F); + blocks.register(woodName + "_fence" , woodNameCapitalized + "Fence" , new BlockTFFence(Material.WOOD, woodType.supplyMapColor()) { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, noProperty); }}).setSoundType(SoundType.WOOD).setHardness(2.0F).setResistance(5.0F); + blocks.register(woodName + "_gate" , woodNameCapitalized + "Gate" , new BlockTFFenceGate(woodType.supplyPlankColor()) { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, BlockFenceGate.POWERED); }}).setSoundType(SoundType.WOOD).setHardness(2.0F).setResistance(5.0F); + blocks.register(woodName + "_plate" , woodNameCapitalized + "Plate" , new BlockTFPressurePlate(Material.WOOD, woodType.supplyMapColor(), BlockPressurePlate.Sensitivity.EVERYTHING) { @SideOnly(Side.CLIENT) @Override public void registerModel() { ModelUtils.registerIncludingItemModels(this, inventory, noProperty); }}).setSoundType(SoundType.WOOD).setHardness(0.5F); + + // TODO chests? boats? + } + } + + public static List getBlockModels() { + return Collections.unmodifiableList(BlockRegistryHelper.blockModels); + } + + private static class BlockRegistryHelper { + + static final List blockModels = new ArrayList<>(); + + private final IForgeRegistry registry; + + BlockRegistryHelper(IForgeRegistry registry) { + this.registry = registry; + } + + T register(String registryName, String translationKey, T block) { + block.setTranslationKey(TwilightForestMod.ID + "." + translationKey); + register(registryName, block); + return block; + } + + T register(String registryName, T block) { + block.setRegistryName(TwilightForestMod.ID, registryName); + if (block instanceof ModelRegisterCallback) { + blockModels.add((ModelRegisterCallback) block); + } + block.setCreativeTab(TFItems.creativeTab); + registry.register(block); + return block; + } + } + + // our internal fluid instances + public static final Fluid moltenFiery; + public static final Fluid moltenKnightmetal; + public static final Fluid essenceFiery; + + public static final ResourceLocation moltenFieryStill = TwilightForestMod.prefix("blocks/molten_fiery_still"); + public static final ResourceLocation moltenFieryFlow = TwilightForestMod.prefix("blocks/molten_fiery_flow"); + + public static final ResourceLocation moltenKnightmetalStill = TwilightForestMod.prefix("blocks/molten_knightmetal_still"); + public static final ResourceLocation moltenKnightmetalFlow = TwilightForestMod.prefix("blocks/molten_knightmetal_flow"); + + public static final ResourceLocation essenceFieryStill = TwilightForestMod.prefix("blocks/fluid_fiery_still"); + public static final ResourceLocation essenceFieryFlow = TwilightForestMod.prefix("blocks/fluid_fiery_flow"); + + static { + moltenFiery = registerFluid(new Fluid("fierymetal" , moltenFieryStill, moltenFieryFlow).setTemperature(1000).setLuminosity(15)); + moltenKnightmetal = registerFluid(new Fluid("knightmetal", moltenKnightmetalStill, moltenKnightmetalFlow).setTemperature(1000).setLuminosity(15)); + essenceFiery = registerFluid(new Fluid("fiery_essence", essenceFieryStill, essenceFieryFlow).setTemperature(1000)); + } + + private static Fluid registerFluid(Fluid fluid) { + fluid.setUnlocalizedName(fluid.getName()); + FluidRegistry.registerFluid(fluid); + FluidRegistry.addBucketForFluid(fluid); + return fluid; + } + + private static void registerFluidBlock(BlockRegistryHelper blocks, Fluid fluid) { + registerFluidBlock("molten_" + fluid.getName(), blocks, fluid); + } + + private static void registerFluidBlock(String registryName, BlockRegistryHelper blocks, Fluid fluid) { + Block block = new BlockTFFluid(fluid, Material.LAVA).setTranslationKey(TwilightForestMod.ID + "." + fluid.getName()).setLightLevel(1.0F); + blocks.register(registryName, block); + } +} diff --git a/src/main/java/twilightforest/block/StepSoundTFInsect.java b/src/main/java/twilightforest/block/StepSoundTFInsect.java deleted file mode 100644 index 2f79bab25a..0000000000 --- a/src/main/java/twilightforest/block/StepSoundTFInsect.java +++ /dev/null @@ -1,37 +0,0 @@ -package twilightforest.block; - -import net.minecraft.block.Block; - - -public class StepSoundTFInsect extends Block.SoundType { - - public StepSoundTFInsect(String par1Str, float par2, float par3) { - super(par1Str, par2, par3); - } - - /** - * Used when a block breaks, EXA: Player break, Shep eating grass, etc.. - */ - @Override - public String getBreakSound() - { - return "mob.slime.big"; - } - - /** - * Used when a entity walks over, or otherwise interacts with the block. - */ - public String getStepSound() - { - return "mob.slime.big"; - } - - /** - * Used when a player places a block. - */ - public String getPlaceSound() - { - return "mob.slime.big"; - } - -} diff --git a/src/main/java/twilightforest/block/TFBlocks.java b/src/main/java/twilightforest/block/TFBlocks.java index 565068cbf8..12869abeab 100644 --- a/src/main/java/twilightforest/block/TFBlocks.java +++ b/src/main/java/twilightforest/block/TFBlocks.java @@ -1,232 +1,173 @@ package twilightforest.block; import net.minecraft.block.Block; -import net.minecraft.block.BlockCompressed; +import net.minecraft.block.BlockBush; +import net.minecraft.block.BlockLeaves; import net.minecraft.block.BlockSlab; -import net.minecraft.block.material.MapColor; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemBlock; import twilightforest.TwilightForestMod; -import twilightforest.item.ItemBlockTFMeta; -import cpw.mods.fml.common.registry.GameRegistry; -public class TFBlocks { - - public static Block log; - public static Block leaves; - public static Block firefly; - public static Block portal; - public static Block mazestone; - public static Block hedge; - public static Block bossSpawner; - public static Block fireflyJar; - public static Block plant; - public static Block cicada; - public static Block root; - public static Block uncraftingTable; - public static Block fireJet; - public static Block nagastone; - public static Block sapling; - public static Block magicLog; - public static Block magicLogSpecial; - public static Block magicLeaves; - public static Block moonworm; - public static Block towerWood; - public static Block towerDevice; - //public static Block towerAntenna; - public static Block towerTranslucent; - public static Block trophy; - public static Block shield; - public static Block trophyPedestal; - public static Block auroraBlock; - public static Block underBrick; - public static Block thorns; - public static Block burntThorns; - public static Block thornRose; - public static Block leaves3; - public static Block deadrock; - public static Block darkleaves; - public static Block auroraPillar; - public static BlockSlab auroraSlab; - public static BlockSlab auroraDoubleSlab; - public static Block trollSteinn; - public static Block wispyCloud; - public static Block fluffyCloud; - public static Block giantCobble; - public static Block giantLog; - public static Block giantLeaves; - public static Block giantObsidian; - public static Block uberousSoil; - public static Block hugeStalk; - public static Block hugeGloomBlock; - public static Block trollVidr; - public static Block unripeTrollBer; - public static Block trollBer; - public static Block knightmetalStorage; - public static Block hugeLilyPad; - public static Block hugeWaterLily; - public static Block slider; - public static Block castleBlock; - public static Block castleMagic; - public static Block forceField; - public static Block cinderFurnace; - public static Block cinderFurnaceLit; - public static Block cinderLog; - public static Block castleDoor; - public static Block castleDoorVanished; - public static Block castleUnlock; - - public static void registerBlocks() { - - log = (new BlockTFLog()).setBlockName("TFLog"); - leaves = (new BlockTFLeaves()).setBlockName("TFLeaves").setBlockTextureName("leaves_oak"); - firefly = (new BlockTFFirefly()).setBlockName("TFFirefly"); - cicada = (new BlockTFCicada()).setBlockName("TFCicada"); - portal = (new BlockTFPortal()).setBlockName("TFPortal"); - mazestone = (new BlockTFMazestone()).setBlockName("TFMazestone"); - hedge = (new BlockTFHedge()).setBlockName("TFHedge"); - bossSpawner = (new BlockTFBossSpawner()).setBlockName("TFBossSpawner"); - fireflyJar = (new BlockTFFireflyJar()).setBlockName("TFFireflyJar"); - plant = (new BlockTFPlant()).setBlockName("TFPlant"); - root = (new BlockTFRoots()).setBlockName("TFRoots"); - uncraftingTable = (new BlockTFUncraftingTable()).setBlockName("TFUncraftingTable"); - fireJet = (new BlockTFFireJet()).setBlockName("TFFireJet"); - nagastone = (new BlockTFNagastone()).setBlockName("TFNagastone"); - sapling = (new BlockTFSapling()).setBlockName("TFSapling"); - magicLog = (new BlockTFMagicLog()).setBlockName("TFMagicLog"); - magicLogSpecial = (new BlockTFMagicLogSpecial()).setBlockName("TFMagicLogSpecial"); - magicLeaves = (new BlockTFMagicLeaves()).setBlockName("TFMagicLeaves"); - moonworm = (new BlockTFMoonworm()).setBlockName("TFMoonworm"); - towerWood = (new BlockTFTowerWood()).setBlockName("TFTowerStone"); - towerDevice = (new BlockTFTowerDevice()).setBlockName("TFTowerDevice"); - towerTranslucent = (new BlockTFTowerTranslucent()).setBlockName("TFTowerTranslucent"); - trophy = (new BlockTFTrophy()).setBlockName("TFTrophy"); - shield = (new BlockTFShield()).setBlockName("TFShield"); - trophyPedestal = (new BlockTFTrophyPedestal()).setBlockName("TFTrophyPedestal"); - auroraBlock = (new BlockTFAuroraBrick()).setBlockName("TFAuroraBrick"); - underBrick = (new BlockTFUnderBrick()).setBlockName("TFUnderBrick"); - thorns = (new BlockTFThorns()).setBlockName("TFThorns"); - burntThorns = (new BlockTFBurntThorns()).setBlockName("TFBurntThorns"); - thornRose = (new BlockTFThornRose()).setBlockName("TFThornRose").setBlockTextureName(TwilightForestMod.ID + ":thornRose"); - leaves3 = (new BlockTFLeaves3()).setBlockName("TFLeaves3").setBlockTextureName("leaves_oak"); - deadrock = (new BlockTFDeadrock()).setBlockName("TFDeadrock"); - darkleaves = (new BlockTFDarkLeaves()).setBlockName("DarkLeaves"); - auroraPillar = (new BlockTFAuroraPillar()).setBlockName("AuroraPillar"); - auroraSlab = (BlockSlab) (new BlockTFAuroraSlab(false)).setBlockName("AuroraSlab"); - auroraDoubleSlab = (BlockSlab) (new BlockTFAuroraSlab(true)).setBlockName("AuroraDoubleSlab"); - trollSteinn = (new BlockTFTrollSteinn()).setBlockName("TrollSteinn"); - wispyCloud = (new BlockTFWispyCloud()).setBlockName("WispyCloud"); - fluffyCloud = (new BlockTFFluffyCloud()).setBlockName("FluffyCloud"); - giantCobble = (new BlockTFGiantCobble()).setBlockName("GiantCobble"); - giantLog = (new BlockTFGiantLog()).setBlockName("GiantLog"); - giantLeaves = (new BlockTFGiantLeaves()).setBlockName("GiantLeaves"); - giantObsidian = (new BlockTFGiantObsidian()).setBlockName("GiantObsidian"); - uberousSoil = (new BlockTFUberousSoil()).setBlockName("UberousSoil"); - hugeStalk = (new BlockTFHugeStalk()).setBlockName("HugeStalk"); - hugeGloomBlock = (new BlockTFHugeGloomBlock()).setBlockName("HugeGloomBlock"); - trollVidr = (new BlockTFTrollRoot()).setBlockName("TrollVidr"); - unripeTrollBer = (new BlockTFUnripeTorchCluster()).setBlockName("UnripeTrollBer"); - trollBer = (new BlockTFRipeTorchCluster()).setBlockName("TrollBer"); - knightmetalStorage = (new BlockTFKnightmetalBlock()).setBlockName("KnightmetalBlock"); - hugeLilyPad = (new BlockTFHugeLilyPad()).setBlockName("HugeLilyPad"); - hugeWaterLily = (new BlockTFHugeWaterLily()).setBlockName("HugeWaterLily").setBlockTextureName(TwilightForestMod.ID + ":huge_waterlily"); - slider = (new BlockTFSlider()).setBlockName("Slider"); - castleBlock = (new BlockTFCastleBlock()).setBlockName("CastleBrick"); - castleMagic = (new BlockTFCastleMagic()).setBlockName("CastleMagic"); - forceField = (new BlockTFForceField()).setBlockName("ForceField"); - cinderFurnace = (new BlockTFCinderFurnace(false)).setBlockName("CinderFurnaceIdle"); - cinderFurnaceLit = (new BlockTFCinderFurnace(true)).setBlockName("CinderFurnaceLit"); - cinderLog = (new BlockTFCinderLog()).setBlockName("CinderLog"); - castleDoor = (new BlockTFCastleDoor(false)).setBlockName("CastleDoor"); - castleDoorVanished = (new BlockTFCastleDoor(true)).setBlockName("CastleDoorVanished"); - castleUnlock = (new BlockTFCastleUnlock()).setBlockName("CastleUnlock"); - - // register blocks with their pickup values - registerMyBlock(log); - registerMyBlock(root); - registerMyBlock(leaves); - registerMyBlock(firefly, ItemBlock.class); - registerMyBlock(cicada, ItemBlock.class); - registerMyBlock(portal, ItemBlock.class); - registerMyBlock(mazestone); - registerMyBlock(hedge); - registerMyBlock(bossSpawner); - registerMyBlock(fireflyJar, ItemBlock.class); - registerMyBlock(plant, twilightforest.item.ItemBlockTFPlant.class); - registerMyBlock(uncraftingTable, ItemBlock.class); - registerMyBlock(fireJet); - registerMyBlock(nagastone); - registerMyBlock(sapling); - registerMyBlock(moonworm, ItemBlock.class); - registerMyBlock(magicLog); - registerMyBlock(magicLeaves); - registerMyBlock(magicLogSpecial); - registerMyBlock(towerWood); - registerMyBlock(towerDevice); - registerMyBlock(towerTranslucent); - registerMyBlock(trophy); - registerMyBlock(shield); - registerMyBlock(trophyPedestal); - registerMyBlock(auroraBlock, ItemBlock.class); - registerMyBlock(underBrick); - registerMyBlock(thorns, twilightforest.item.ItemBlockTFThorns.class, thorns, ((BlockTFThorns) thorns).getNames()); - registerMyBlock(burntThorns, ItemBlock.class); - registerMyBlock(thornRose, ItemBlock.class); - registerMyBlock(leaves3); - registerMyBlock(deadrock, twilightforest.item.ItemBlockTFDeadrock.class, deadrock, BlockTFDeadrock.names); - registerMyBlock(darkleaves, ItemBlock.class); - registerMyBlock(auroraPillar, ItemBlock.class); - registerMyBlock(auroraSlab, twilightforest.item.ItemBlockTFAuroraSlab.class, ((BlockSlab) auroraSlab), ((BlockSlab) auroraDoubleSlab), false); - registerMyBlock(auroraDoubleSlab, twilightforest.item.ItemBlockTFAuroraSlab.class, ((BlockSlab) auroraSlab), ((BlockSlab) auroraDoubleSlab), true); - registerMyBlock(trollSteinn, ItemBlock.class); - registerMyBlock(wispyCloud, ItemBlock.class); - registerMyBlock(fluffyCloud, ItemBlock.class); - registerMyBlock(giantCobble, ItemBlock.class); - registerMyBlock(giantLog, ItemBlock.class); - registerMyBlock(giantLeaves, ItemBlock.class); - registerMyBlock(giantObsidian, ItemBlock.class); - registerMyBlock(uberousSoil, ItemBlock.class); - registerMyBlock(hugeStalk, ItemBlock.class); - registerMyBlock(hugeGloomBlock, ItemBlock.class); - registerMyBlock(trollVidr, ItemBlock.class); - registerMyBlock(unripeTrollBer, ItemBlock.class); - registerMyBlock(trollBer, ItemBlock.class); - registerMyBlock(knightmetalStorage, ItemBlock.class); - registerMyBlock(hugeLilyPad, twilightforest.item.ItemBlockTFHugeLilyPad.class); - registerMyBlock(hugeWaterLily, twilightforest.item.ItemBlockTFHugeWaterLily.class); - registerMyBlock(slider); - registerMyBlock(castleBlock); - registerMyBlock(castleMagic); - registerMyBlock(forceField); - registerMyBlock(cinderFurnace, ItemBlock.class); - registerMyBlock(cinderFurnaceLit, ItemBlock.class); - registerMyBlock(cinderLog); - registerMyBlock(castleDoor); - registerMyBlock(castleDoorVanished); - - // fire info - Blocks.fire.setFireInfo(log, 5, 5); - Blocks.fire.setFireInfo(leaves, 30, 60); - Blocks.fire.setFireInfo(leaves3, 30, 60); - } +import javax.annotation.Nonnull; - private static void registerMyBlock(Block block, Class pickup, BlockSlab singleSlab, BlockSlab doubleSlab, boolean isDouble) { - GameRegistry.registerBlock(block, pickup, block.getUnlocalizedName(), singleSlab, doubleSlab, isDouble); +import static net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; - } +@SuppressWarnings({"WeakerAccess", "ConstantConditions"}) +@ObjectHolder(TwilightForestMod.ID) +@Nonnull +public class TFBlocks { + public static final Block twilight_log = iCantBelieveItsNotNull(); + public static final BlockLeaves twilight_leaves = iCantBelieveItsNotNull(); + public static final Block firefly = iCantBelieveItsNotNull(); + public static final BlockTFPortal twilight_portal = iCantBelieveItsNotNull(); + public static final Block maze_stone = iCantBelieveItsNotNull(); + public static final Block hedge = iCantBelieveItsNotNull(); + public static final Block boss_spawner = iCantBelieveItsNotNull(); + public static final Block firefly_jar = iCantBelieveItsNotNull(); + public static final Block twilight_plant = iCantBelieveItsNotNull(); + public static final Block cicada = iCantBelieveItsNotNull(); + public static final Block root = iCantBelieveItsNotNull(); + public static final Block uncrafting_table = iCantBelieveItsNotNull(); + public static final Block fire_jet = iCantBelieveItsNotNull(); + public static final Block naga_stone = iCantBelieveItsNotNull(); + public static final BlockBush twilight_sapling = iCantBelieveItsNotNull(); + public static final Block magic_log = iCantBelieveItsNotNull(); + public static final Block magic_log_core = iCantBelieveItsNotNull(); + public static final BlockLeaves magic_leaves = iCantBelieveItsNotNull(); + public static final Block moonworm = iCantBelieveItsNotNull(); + public static final Block tower_wood = iCantBelieveItsNotNull(); + public static final BlockTFTowerDevice tower_device = iCantBelieveItsNotNull(); + //public static Block towerAntenna = null; // Not you + public static final Block tower_translucent = iCantBelieveItsNotNull(); + public static final Block trophy = iCantBelieveItsNotNull(); + public static final Block stronghold_shield = iCantBelieveItsNotNull(); + public static final Block trophy_pedestal = iCantBelieveItsNotNull(); + public static final Block aurora_block = iCantBelieveItsNotNull(); + public static final Block underbrick = iCantBelieveItsNotNull(); + public static final Block thorns = iCantBelieveItsNotNull(); + public static final Block burnt_thorns = iCantBelieveItsNotNull(); + public static final Block thorn_rose = iCantBelieveItsNotNull(); + public static final BlockLeaves twilight_leaves_3 = iCantBelieveItsNotNull(); + public static final Block deadrock = iCantBelieveItsNotNull(); + public static final Block dark_leaves = iCantBelieveItsNotNull(); + public static final Block aurora_pillar = iCantBelieveItsNotNull(); + public static final BlockSlab aurora_slab = iCantBelieveItsNotNull(); + public static final BlockSlab double_aurora_slab = iCantBelieveItsNotNull(); + public static final Block trollsteinn = iCantBelieveItsNotNull(); + public static final Block wispy_cloud = iCantBelieveItsNotNull(); + public static final Block fluffy_cloud = iCantBelieveItsNotNull(); + public static final Block giant_cobblestone = iCantBelieveItsNotNull(); + public static final Block giant_log = iCantBelieveItsNotNull(); + public static final Block giant_leaves = iCantBelieveItsNotNull(); + public static final Block giant_obsidian = iCantBelieveItsNotNull(); + public static final Block uberous_soil = iCantBelieveItsNotNull(); + public static final Block huge_stalk = iCantBelieveItsNotNull(); + public static final Block huge_mushgloom = iCantBelieveItsNotNull(); + public static final Block trollvidr = iCantBelieveItsNotNull(); + public static final Block unripe_trollber = iCantBelieveItsNotNull(); + public static final Block trollber = iCantBelieveItsNotNull(); + public static final Block knightmetal_block = iCantBelieveItsNotNull(); + public static final Block huge_lilypad = iCantBelieveItsNotNull(); + public static final Block huge_waterlily = iCantBelieveItsNotNull(); + public static final Block slider = iCantBelieveItsNotNull(); + public static final Block castle_brick = iCantBelieveItsNotNull(); + public static final Block castle_stairs = iCantBelieveItsNotNull(); + public static final Block castle_pillar = iCantBelieveItsNotNull(); + public static final Block castle_rune_brick = iCantBelieveItsNotNull(); + public static final Block force_field = iCantBelieveItsNotNull(); + public static final Block cinder_furnace = iCantBelieveItsNotNull(); + public static final Block cinder_furnace_lit = iCantBelieveItsNotNull(); + public static final Block cinder_log = iCantBelieveItsNotNull(); + public static final Block castle_door = iCantBelieveItsNotNull(); + public static final Block castle_door_vanished = iCantBelieveItsNotNull(); + public static final Block experiment_115 = iCantBelieveItsNotNull(); + public static final Block miniature_structure = iCantBelieveItsNotNull(); + public static final Block block_storage = iCantBelieveItsNotNull(); + public static final Block spiral_bricks = iCantBelieveItsNotNull(); + public static final Block etched_nagastone = iCantBelieveItsNotNull(); + public static final Block nagastone_pillar = iCantBelieveItsNotNull(); + public static final Block nagastone_stairs = iCantBelieveItsNotNull(); + public static final Block etched_nagastone_mossy = iCantBelieveItsNotNull(); + public static final Block nagastone_pillar_mossy = iCantBelieveItsNotNull(); + public static final Block nagastone_stairs_mossy = iCantBelieveItsNotNull(); + public static final Block etched_nagastone_weathered = iCantBelieveItsNotNull(); + public static final Block nagastone_pillar_weathered = iCantBelieveItsNotNull(); + public static final Block nagastone_stairs_weathered = iCantBelieveItsNotNull(); + public static final Block auroralized_glass = iCantBelieveItsNotNull(); + public static final Block castle_stairs_brick = iCantBelieveItsNotNull(); + public static final Block castle_stairs_cracked = iCantBelieveItsNotNull(); + public static final Block castle_stairs_worn = iCantBelieveItsNotNull(); + public static final Block castle_stairs_mossy = iCantBelieveItsNotNull(); + public static final BlockTFLadderBars iron_ladder = iCantBelieveItsNotNull(); + public static final Block terrorcotta_circle = iCantBelieveItsNotNull(); + public static final Block terrorcotta_diagonal = iCantBelieveItsNotNull(); + public static final Block stone_twist = iCantBelieveItsNotNull(); + public static final Block stone_twist_thin = iCantBelieveItsNotNull(); - private static void registerMyBlock(Block block, Class pickup, Block blockAgain, String[] names) { - GameRegistry.registerBlock(block, pickup, block.getUnlocalizedName(), blockAgain, names); - } + public static final BlockTF twilight_oak_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs twilight_oak_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab twilight_oak_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab twilight_oak_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood twilight_oak_button = iCantBelieveItsNotNull(); + public static final BlockTFFence twilight_oak_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate twilight_oak_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate twilight_oak_plate = iCantBelieveItsNotNull(); + public static final BlockTF canopy_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs canopy_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab canopy_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab canopy_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood canopy_button = iCantBelieveItsNotNull(); + public static final BlockTFFence canopy_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate canopy_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate canopy_plate = iCantBelieveItsNotNull(); + public static final BlockTF mangrove_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs mangrove_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab mangrove_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab mangrove_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood mangrove_button = iCantBelieveItsNotNull(); + public static final BlockTFFence mangrove_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate mangrove_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate mangrove_plate = iCantBelieveItsNotNull(); + public static final BlockTF dark_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs dark_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab dark_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab dark_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood dark_button = iCantBelieveItsNotNull(); + public static final BlockTFFence dark_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate dark_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate dark_plate = iCantBelieveItsNotNull(); + public static final BlockTF time_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs time_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab time_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab time_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood time_button = iCantBelieveItsNotNull(); + public static final BlockTFFence time_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate time_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate time_plate = iCantBelieveItsNotNull(); + public static final BlockTF trans_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs trans_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab trans_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab trans_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood trans_button = iCantBelieveItsNotNull(); + public static final BlockTFFence trans_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate trans_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate trans_plate = iCantBelieveItsNotNull(); + public static final BlockTF mine_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs mine_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab mine_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab mine_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood mine_button = iCantBelieveItsNotNull(); + public static final BlockTFFence mine_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate mine_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate mine_plate = iCantBelieveItsNotNull(); + public static final BlockTF sort_planks = iCantBelieveItsNotNull(); + public static final BlockTFStairs sort_stairs = iCantBelieveItsNotNull(); + public static final BlockTFSlab sort_doubleslab = iCantBelieveItsNotNull(); + public static final BlockTFSlab sort_slab = iCantBelieveItsNotNull(); + public static final BlockTFButtonWood sort_button = iCantBelieveItsNotNull(); + public static final BlockTFFence sort_fence = iCantBelieveItsNotNull(); + public static final BlockTFFenceGate sort_gate = iCantBelieveItsNotNull(); + public static final BlockTFPressurePlate sort_plate = iCantBelieveItsNotNull(); - private static void registerMyBlock(Block block, Class pickup) - { - GameRegistry.registerBlock(block, pickup, block.getUnlocalizedName()); + private static T iCantBelieveItsNotNull() { + return null; } - - private static void registerMyBlock(Block block) - { - GameRegistry.registerBlock(block, ItemBlockTFMeta.class, block.getUnlocalizedName()); - } - } diff --git a/src/main/java/twilightforest/block/package-info.java b/src/main/java/twilightforest/block/package-info.java new file mode 100644 index 0000000000..3c43355f09 --- /dev/null +++ b/src/main/java/twilightforest/block/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.block; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/capabilities/CapabilityList.java b/src/main/java/twilightforest/capabilities/CapabilityList.java new file mode 100644 index 0000000000..99f34a3f45 --- /dev/null +++ b/src/main/java/twilightforest/capabilities/CapabilityList.java @@ -0,0 +1,68 @@ +package twilightforest.capabilities; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityInject; +import net.minecraftforge.common.capabilities.CapabilityManager; +import net.minecraftforge.common.capabilities.ICapabilitySerializable; +import net.minecraftforge.event.AttachCapabilitiesEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import twilightforest.capabilities.shield.IShieldCapability; +import twilightforest.capabilities.shield.ShieldCapabilityHandler; +import twilightforest.capabilities.shield.ShieldCapabilityStorage; + +import javax.annotation.Nonnull; + +public class CapabilityList { + + @CapabilityInject(IShieldCapability.class) + public static final Capability SHIELDS; + + static { + SHIELDS = null; + } + + public static void registerCapabilities() { + CapabilityManager.INSTANCE.register(IShieldCapability.class, new ShieldCapabilityStorage(), ShieldCapabilityHandler::new); + MinecraftForge.EVENT_BUS.register(CapabilityList.class); + } + + @SubscribeEvent + public static void attachEntityCapability(AttachCapabilitiesEvent e) { + if (e.getObject() instanceof EntityLivingBase) { + e.addCapability(IShieldCapability.ID, new ICapabilitySerializable() { + + IShieldCapability inst = SHIELDS.getDefaultInstance(); + + { + inst.setEntity((EntityLivingBase) e.getObject()); + } + + @Override + public boolean hasCapability(@Nonnull Capability capability, EnumFacing facing) { + return capability == SHIELDS; + } + + @Override + public T getCapability(@Nonnull Capability capability, EnumFacing facing) { + return capability == SHIELDS ? SHIELDS.cast(inst) : null; + } + + @Override + public NBTTagCompound serializeNBT() { + return (NBTTagCompound) SHIELDS.getStorage().writeNBT(SHIELDS, inst, null); + } + + @Override + public void deserializeNBT(NBTTagCompound nbt) { + SHIELDS.getStorage().readNBT(SHIELDS, inst, null, nbt); + } + + }); + } + } +} diff --git a/src/main/java/twilightforest/capabilities/shield/IShieldCapability.java b/src/main/java/twilightforest/capabilities/shield/IShieldCapability.java new file mode 100644 index 0000000000..e40d50bf0f --- /dev/null +++ b/src/main/java/twilightforest/capabilities/shield/IShieldCapability.java @@ -0,0 +1,28 @@ +package twilightforest.capabilities.shield; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +public interface IShieldCapability { + + ResourceLocation ID = TwilightForestMod.prefix("cap_shield"); + + void setEntity(EntityLivingBase entity); + + void update(); + + int shieldsLeft(); + + int temporaryShieldsLeft(); + + int permanentShieldsLeft(); + + void breakShield(); + + void replenishShields(); + + void setShields(int amount, boolean temp); + + void addShields(int amount, boolean temp); +} diff --git a/src/main/java/twilightforest/capabilities/shield/ShieldCapabilityHandler.java b/src/main/java/twilightforest/capabilities/shield/ShieldCapabilityHandler.java new file mode 100644 index 0000000000..1cfa60b7f6 --- /dev/null +++ b/src/main/java/twilightforest/capabilities/shield/ShieldCapabilityHandler.java @@ -0,0 +1,110 @@ +package twilightforest.capabilities.shield; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.SoundCategory; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import twilightforest.network.PacketUpdateShield; +import twilightforest.network.TFPacketHandler; + +public class ShieldCapabilityHandler implements IShieldCapability { + + private int temporaryShields; + private int permanentShields; + private EntityLivingBase host; + private int timer; + + @Override + public void setEntity(EntityLivingBase entity) { + host = entity; + } + + @Override + public void update() { + if (!host.world.isRemote && shieldsLeft() > 0 && timer-- <= 0 && (!(host instanceof EntityPlayer) || !((EntityPlayer) host).isCreative())) + breakShield(); + } + + @Override + public int shieldsLeft() { + return temporaryShields + permanentShields; + } + + @Override + public int temporaryShieldsLeft() { + return temporaryShields; + } + + @Override + public int permanentShieldsLeft() { + return permanentShields; + } + + @Override + public void breakShield() { + // Temp shields should break first before permanent ones. Reset time each time a temp shield is busted. + if (temporaryShields > 0) { + temporaryShields--; + resetTimer(); + } else if (permanentShields > 0) { + permanentShields--; + } + + host.world.playSound(null, host.getPosition(), SoundEvents.ENTITY_ITEM_BREAK, SoundCategory.PLAYERS, 1.0F, ((host.getRNG().nextFloat() - host.getRNG().nextFloat()) * 0.7F + 1.0F) * 2.0F); + sendUpdatePacket(); + } + + @Override + public void replenishShields() { + setShields(5, true); + host.world.playSound(null, host.getPosition(), SoundEvents.ENTITY_CHICKEN_EGG, SoundCategory.PLAYERS, 1.0F, (host.getRNG().nextFloat() - host.getRNG().nextFloat()) * 0.2F + 1.0F); + } + + @Override + public void setShields(int amount, boolean temp) { + if (temp) { + temporaryShields = Math.max(amount, 0); + resetTimer(); + } else { + permanentShields = Math.max(amount, 0); + } + + sendUpdatePacket(); + } + + @Override + public void addShields(int amount, boolean temp) { + if (temp) { + if (temporaryShields <= 0) + resetTimer(); // Since we add new shields to the stack instead of setting them, no timer reset is needed, unless they start from 0 shields. + temporaryShields = Math.max(temporaryShields + amount, 0); + } else { + permanentShields = Math.max(permanentShields + amount, 0); + } + + sendUpdatePacket(); + } + + void initShields(int temporary, int permanent) { + temporaryShields = Math.max(temporary, 0); + permanentShields = Math.max(permanent, 0); + resetTimer(); + } + + private void resetTimer() { + timer = 240; + } + + private void sendUpdatePacket() { + if (!host.world.isRemote) { + IMessage message = new PacketUpdateShield(host, this); + TFPacketHandler.CHANNEL.sendToAllTracking(message, host); + // sendToAllTracking doesn't send to your own client so we need to send that as well. + if (host instanceof EntityPlayerMP) { + TFPacketHandler.CHANNEL.sendTo(message, (EntityPlayerMP) host); + } + } + } +} diff --git a/src/main/java/twilightforest/capabilities/shield/ShieldCapabilityStorage.java b/src/main/java/twilightforest/capabilities/shield/ShieldCapabilityStorage.java new file mode 100644 index 0000000000..eb6de04bc8 --- /dev/null +++ b/src/main/java/twilightforest/capabilities/shield/ShieldCapabilityStorage.java @@ -0,0 +1,28 @@ +package twilightforest.capabilities.shield; + +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.capabilities.Capability; + +public class ShieldCapabilityStorage implements Capability.IStorage { + + @Override + public NBTTagCompound writeNBT(Capability capability, IShieldCapability instance, EnumFacing side) { + NBTTagCompound tag = new NBTTagCompound(); + tag.setInteger("tempshields", instance.temporaryShieldsLeft()); + tag.setInteger("permshields", instance.permanentShieldsLeft()); + return tag; + } + + @Override + public void readNBT(Capability capability, IShieldCapability instance, EnumFacing side, NBTBase nbt) { + if (nbt instanceof NBTTagCompound && instance instanceof ShieldCapabilityHandler) { + NBTTagCompound tag = (NBTTagCompound) nbt; + ((ShieldCapabilityHandler) instance).initShields( + tag.getInteger("tempshields"), + tag.getInteger("permshields") + ); + } + } +} diff --git a/src/main/java/twilightforest/client/BugModelAnimationHelper.java b/src/main/java/twilightforest/client/BugModelAnimationHelper.java new file mode 100644 index 0000000000..30819bf7af --- /dev/null +++ b/src/main/java/twilightforest/client/BugModelAnimationHelper.java @@ -0,0 +1,95 @@ +package twilightforest.client; + +import java.util.Random; + +public class BugModelAnimationHelper { + + private static final Random rand = new Random(); + + private static int yawDelay; + public static int currentYaw; + private static int desiredYaw; + + public static int yawWriggleDelay; + public static int currentRotation = -1; + public static int desiredRotation; + + public static float glowIntensity; + private static boolean glowing; + private static int glowDelay; + + static void animate() { + tickYaw(); + tickGlow(); + tickRotation(); + } + + private static void tickYaw() { + if (yawDelay > 0) { + yawDelay--; + return; + } + + if (currentYaw == 0 && desiredYaw == 0) { + // make it rotate! + yawDelay = 200 + rand.nextInt(200); + desiredYaw = rand.nextInt(15) - rand.nextInt(15); + } + + if (currentYaw < desiredYaw) { + currentYaw++; + } else if (currentYaw > desiredYaw) { + currentYaw--; + } else if (currentYaw == desiredYaw) { + desiredYaw = 0; + } + } + + private static void tickGlow() { + if (glowDelay > 0) { + glowDelay--; + return; + } + + if (glowing && glowIntensity >= 1f) { + glowing = false; + } + if (glowing && glowIntensity < 1f) { + glowIntensity += 0.05f; + } + if (!glowing && glowIntensity > 0f) { + glowIntensity -= 0.05f; + } + if (!glowing && glowIntensity <= 0f) { + glowing = true; + glowDelay = rand.nextInt(50); + } + } + + private static void tickRotation() { + if (yawWriggleDelay > 0) { + yawWriggleDelay--; + return; + } + + if (currentRotation == -1) { + currentRotation = rand.nextInt(4) * 90; + } + + if (desiredRotation == 0) { + // make it rotate! + yawWriggleDelay = 200 + rand.nextInt(200); + desiredRotation = rand.nextInt(4) * 90; + } + + currentRotation++; + + if (currentRotation > 360) { + currentRotation = 0; + } + + if (currentRotation == desiredRotation) { + desiredRotation = 0; + } + } +} diff --git a/src/main/java/twilightforest/client/ColorHandler.java b/src/main/java/twilightforest/client/ColorHandler.java new file mode 100644 index 0000000000..9952b1dc4b --- /dev/null +++ b/src/main/java/twilightforest/client/ColorHandler.java @@ -0,0 +1,318 @@ +package twilightforest.client; + +import net.minecraft.client.renderer.color.BlockColors; +import net.minecraft.client.renderer.color.ItemColors; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemBlock; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.ColorizerFoliage; +import net.minecraft.world.ColorizerGrass; +import net.minecraft.world.biome.BiomeColorHelper; +import net.minecraftforge.client.event.ColorHandlerEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.relauncher.Side; +import twilightforest.TwilightForestMod; +import twilightforest.block.*; +import twilightforest.compat.TFCompat; +import twilightforest.compat.ie.ItemTFShaderGrabbag; +import twilightforest.enums.Leaves3Variant; +import twilightforest.enums.LeavesVariant; +import twilightforest.enums.MagicWoodVariant; +import twilightforest.enums.TowerWoodVariant; +import twilightforest.item.ItemTFArcticArmor; +import twilightforest.item.TFItems; + +import java.awt.Color; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID, value = Side.CLIENT) +public final class ColorHandler { + + @SubscribeEvent + public static void registerBlockColors(ColorHandlerEvent.Block event) { + + BlockColors blockColors = event.getBlockColors(); + + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> tintIndex > 15 ? 0xFFFFFF : Color.HSBtoRGB(worldIn == null ? 0.45F : BlockTFAuroraBrick.rippleFractialNoise(2, 128.0f, pos != null ? pos.up(128) : new BlockPos(0, 0, 0), 0.37f, 0.67f, 1.5f), 1.0f, 1.0f), TFBlocks.aurora_block); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + int normalColor = blockColors.colorMultiplier(TFBlocks.aurora_block.getDefaultState(), worldIn, pos, tintIndex); + + int red = (normalColor >> 16) & 255; + int blue = normalColor & 255; + int green = (normalColor >> 8) & 255; + + float[] hsb = Color.RGBtoHSB(red, blue, green, null); + + return Color.HSBtoRGB(hsb[0], hsb[1] * 0.5F, Math.min(hsb[2] + 0.4F, 0.9F)); + }, TFBlocks.aurora_pillar, TFBlocks.aurora_slab, TFBlocks.double_aurora_slab, TFBlocks.auroralized_glass); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + if (worldIn == null || pos == null) { + return ColorizerFoliage.getFoliageColorBasic(); + } + + int red = 0; + int grn = 0; + int blu = 0; + + for (int dz = -1; dz <= 1; ++dz) { + for (int dx = -1; dx <= 1; ++dx) { + int i2 = worldIn.getBiome(pos.add(dx, 0, dz)).getFoliageColorAtPos(pos.add(dx, 0, dz)); + red += (i2 & 16711680) >> 16; + grn += (i2 & 65280) >> 8; + blu += i2 & 255; + } + } + + return (red / 9 & 255) << 16 | (grn / 9 & 255) << 8 | blu / 9 & 255; + }, TFBlocks.dark_leaves, TFBlocks.giant_leaves); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> tintIndex > 15 ? 0xFFFFFF : state.getValue(BlockTFFireJet.VARIANT).hasGrassColor ? blockColors.colorMultiplier(Blocks.GRASS.getDefaultState(), worldIn, pos, tintIndex) : 0xFFFFFF, TFBlocks.fire_jet); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> worldIn != null && pos != null ? 2129968 : 7455580, TFBlocks.huge_lilypad); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + if (worldIn == null || pos == null) { + switch (state.getValue(BlockTFMagicLog.VARIANT)) { + case TIME: + return 106 << 16 | 156 << 8 | 23; + case TRANS: + return 108 << 16 | 204 << 8 | 234; + case MINE: + return 252 << 16 | 241 << 8 | 68; + case SORT: + return 54 << 16 | 76 << 8 | 3; + default: + return -1; + } + } else { + int red = -1, green = -1, blue = -1; + MagicWoodVariant leafType = state.getValue(BlockTFMagicLog.VARIANT); + + if (leafType == MagicWoodVariant.TIME) { + int fade = pos.getX() * 16 + pos.getY() * 16 + pos.getZ() * 16; + if ((fade & 256) != 0) { + fade = 255 - (fade & 255); + } + fade &= 255; + + float spring = (255 - fade) / 255F; + float fall = fade / 255F; + + red = (int) (spring * 106 + fall * 251); + green = (int) (spring * 156 + fall * 108); + blue = (int) (spring * 23 + fall * 27); + } else if (leafType == MagicWoodVariant.MINE) { + int fade = pos.getX() * 31 + pos.getY() * 33 + pos.getZ() * 32; + if ((fade & 256) != 0) { + fade = 255 - (fade & 255); + } + fade &= 255; + + float spring = (255 - fade) / 255F; + float fall = fade / 255F; + + red = (int) (spring * 252 + fall * 237); + green = (int) (spring * 241 + fall * 172); + blue = (int) (spring * 68 + fall * 9); + } else if (leafType == MagicWoodVariant.TRANS) { + int fade = pos.getX() * 27 + pos.getY() * 63 + pos.getZ() * 39; + if ((fade & 256) != 0) { + fade = 255 - (fade & 255); + } + fade &= 255; + + float spring = (255 - fade) / 255F; + float fall = fade / 255F; + + red = (int) (spring * 108 + fall * 96); + green = (int) (spring * 204 + fall * 107); + blue = (int) (spring * 234 + fall * 121); + } else if (leafType == MagicWoodVariant.SORT) { + int fade = pos.getX() * 63 + pos.getY() * 63 + pos.getZ() * 63; + if ((fade & 256) != 0) { + fade = 255 - (fade & 255); + } + fade &= 255; + + float spring = (255 - fade) / 255F; + float fall = fade / 255F; + + red = (int) (spring * 54 + fall * 168); + green = (int) (spring * 76 + fall * 199); + blue = (int) (spring * 3 + fall * 43); + } + + return red << 16 | green << 8 | blue; + } + }, TFBlocks.magic_leaves); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + if (worldIn == null || pos == null || state.getValue(BlockTFTowerWood.VARIANT) == TowerWoodVariant.ENCASED) { + return -1; + } else { + float f = BlockTFAuroraBrick.rippleFractialNoise(2, 32.0f, pos, 0.4f, 1.0f, 2f); + return Color.HSBtoRGB(0.1f, 1f - f, (f + 2f) / 3f); + } + }, TFBlocks.tower_wood); + blockColors.registerBlockColorHandler((state, world, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + if (world == null || pos == null) { + switch (state.getValue(BlockTFLeaves.VARIANT)) { + case CANOPY: + return 0x609860; + case MANGROVE: + return 0x80A755; + default: + case OAK: + return 0x48B518; + } + } else { + int red = 0; + int green = 0; + int blue = 0; + + for (int dz = -1; dz <= 1; ++dz) { + for (int dx = -1; dx <= 1; ++dx) { + int color = world.getBiome(pos.add(dx, 0, dz)).getFoliageColorAtPos(pos); + red += (color & 16711680) >> 16; + green += (color & 65280) >> 8; + blue += color & 255; + } + } + + int normalColor = (red / 9 & 0xFF) << 16 | (green / 9 & 0xFF) << 8 | blue / 9 & 0xFF; + + if (state.getValue(BlockTFLeaves.VARIANT) == LeavesVariant.CANOPY) { + // canopy colorizer + return ((normalColor & 0xFEFEFE) + 0x469A66) / 2; + //return ((normalColor & 0xFEFEFE) + 0x009822) / 2; + } else if (state.getValue(BlockTFLeaves.VARIANT) == LeavesVariant.MANGROVE) { + // mangrove colors + return ((normalColor & 0xFEFEFE) + 0xC0E694) / 2; + } else if (state.getValue(BlockTFLeaves.VARIANT) == LeavesVariant.RAINBOAK) { + // RAINBOW! + red = pos.getX() * 32 + pos.getY() * 16; + if ((red & 256) != 0) { + red = 255 - (red & 255); + } + red &= 255; + + blue = pos.getY() * 32 + pos.getZ() * 16; + if ((blue & 256) != 0) { + blue = 255 - (blue & 255); + } + blue ^= 255; + + green = pos.getX() * 16 + pos.getZ() * 32; + if ((green & 256) != 0) { + green = 255 - (green & 255); + } + green &= 255; + + + return red << 16 | blue << 8 | green; + } else { + return normalColor; + } + } + }, TFBlocks.twilight_leaves); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + Leaves3Variant variant = state.getValue(BlockTFLeaves3.VARIANT); + return variant == Leaves3Variant.THORN ? ColorizerFoliage.getFoliageColorPine() + : variant == Leaves3Variant.BEANSTALK ? ColorizerFoliage.getFoliageColorBirch() + : -1; + }, TFBlocks.twilight_leaves_3); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> tintIndex != 0 ? 0xFFFFFF : state.getValue(BlockTFPlant.VARIANT).isColored ? worldIn != null && pos != null ? state.getValue(BlockTFPlant.VARIANT).isLeaves ? BiomeColorHelper.getFoliageColorAtPos(worldIn, pos) : BiomeColorHelper.getGrassColorAtPos(worldIn, pos) : ColorizerGrass.getGrassColor(0.5D, 1.0D) : 0xFFFFFF, TFBlocks.twilight_plant); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> ColorizerGrass.getGrassColor(0.5D, 1.0D), TFBlocks.miniature_structure); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + switch (state.getValue(BlockTFCastleMagic.COLOR)) { + case PINK: + return 0xFF00FF; + case BLUE: + return 0x00FFFF; + case YELLOW: + return 0xFFFF00; + case PURPLE: + return 0x4B0082; + default: + TwilightForestMod.LOGGER.warn("Magic happened. Got {} for Castle Rune", state.getValue(BlockTFCastleMagic.COLOR).getName()); + return state.getValue(BlockTFCastleMagic.COLOR).getColorValue(); + } + }, TFBlocks.castle_rune_brick); + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + switch (state.getValue(BlockTFCastleDoor.LOCK_INDEX)) { + case 0: // YELLOW + return 0xFFFF00; + case 1: // PURPLE + return 0x4B0082; + case 2: // PINK + return 0xFF00FF; + case 3: // BLUE + return 0x00FFFF; + default: + return 0; + } + }, TFBlocks.castle_door, TFBlocks.castle_door_vanished); + + blockColors.registerBlockColorHandler((state, worldIn, pos, tintIndex) -> { + if (tintIndex > 15) return 0xFFFFFF; + + switch (state.getValue(BlockTFForceField.COLOR)) { + case PURPLE: + return 0x5C1074; + case PINK: + return 0xFA057E; + case ORANGE: + return 0xFF5B02; + case GREEN: + return 0x89E701; + case BLUE: + return 0x0DDEFF; + default: + TwilightForestMod.LOGGER.warn("Magic happened. Got {} for Forcefield", state.getValue(BlockTFForceField.COLOR).getName()); + return state.getValue(BlockTFForceField.COLOR).getColorValue(); + } + }, TFBlocks.force_field); + } + + @SubscribeEvent + public static void registerItemColors(ColorHandlerEvent.Item event) { + ItemColors itemColors = event.getItemColors(); + BlockColors blockColors = event.getBlockColors(); + + // Atomic: This is one place where getStateFromMeta is still commonly used + itemColors.registerItemColorHandler((stack, tintIndex) -> blockColors.colorMultiplier(((ItemBlock)stack.getItem()).getBlock().getStateFromMeta(stack.getMetadata()), null, null, tintIndex), + TFBlocks.aurora_block, TFBlocks.aurora_pillar, TFBlocks.aurora_slab, TFBlocks.auroralized_glass, TFBlocks.dark_leaves, TFBlocks.giant_leaves, TFBlocks.fire_jet, TFBlocks.magic_leaves, TFBlocks.twilight_leaves, TFBlocks.twilight_leaves_3, TFBlocks.twilight_plant, TFBlocks.castle_rune_brick, TFBlocks.castle_door, TFBlocks.miniature_structure, TFBlocks.force_field, TFBlocks.huge_lilypad); + // Honestly I'd say it makes sense in this context. -Drullkus + + itemColors.registerItemColorHandler((stack, tintIndex) -> + stack.getItem() instanceof ItemTFArcticArmor + ? ((ItemTFArcticArmor) stack.getItem()).getColor(stack, tintIndex) + : 0xFFFFFF, + TFItems.arctic_helmet, TFItems.arctic_chestplate, TFItems.arctic_leggings, TFItems.arctic_boots); + + if (TFCompat.IMMERSIVEENGINEERING.isActivated()) { + itemColors.registerItemColorHandler(twilightforest.compat.ie.ItemTFShader::getShaderColors, twilightforest.compat.ie.ItemTFShader.shader); + itemColors.registerItemColorHandler((stack, tintIndex) -> { + int c = blusunrize.immersiveengineering.client.ClientUtils.getFormattingColour(ItemTFShaderGrabbag.shader_bag.getRarity(stack).color); + + float d = tintIndex + 1; + + return (int) ((c >> 16 & 0xFF) / d) << 16 + | (int) ((c >> 8 & 0xFF) / d) << 8 + | (int) ((c & 0xFF) / d); + }, twilightforest.compat.ie.ItemTFShaderGrabbag.shader_bag); + } + } + + private ColorHandler() {} +} diff --git a/src/main/java/twilightforest/client/FogHandler.java b/src/main/java/twilightforest/client/FogHandler.java new file mode 100644 index 0000000000..9054bbdf3a --- /dev/null +++ b/src/main/java/twilightforest/client/FogHandler.java @@ -0,0 +1,78 @@ +package twilightforest.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.client.event.EntityViewRenderEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.relauncher.Side; +import org.lwjgl.opengl.GLContext; +import twilightforest.TwilightForestMod; +import twilightforest.biomes.TFBiomes; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID, value = Side.CLIENT) +public class FogHandler { + + private static final float[] spoopColors = new float[3]; + private static float spoopColor = 0F; + private static float spoopFog = 1F; + + @SubscribeEvent + public static void fogColors(EntityViewRenderEvent.FogColors event) { + boolean flag = isSpooky(); + if (flag || spoopColor > 0F) { + final float[] realColors = {event.getRed(), event.getGreen(), event.getBlue()}; + final float[] lerpColors = {106F / 255F, 60F / 255F, 153F / 255F}; + for (int i = 0; i < 3; i++) { + final float real = realColors[i]; + final float spoop = lerpColors[i]; + final boolean inverse = real > spoop; + spoopColors[i] = real == spoop ? spoop : (float) MathHelper.clampedLerp(inverse ? spoop : real, inverse ? real : spoop, spoopColor); + } + float shift = (float) (0.01F * event.getRenderPartialTicks()); + if (flag) + spoopColor += shift; + else + spoopColor -= shift; + spoopColor = MathHelper.clamp(spoopColor, 0F, 1F); + event.setRed(spoopColors[0]); + event.setGreen(spoopColors[1]); + event.setBlue(spoopColors[2]); + } + } + + @SubscribeEvent + public static void fog(EntityViewRenderEvent.RenderFogEvent event) { + boolean flag = isSpooky(); + if (flag || spoopFog < 1F) { + float f = 48F; + f = f >= event.getFarPlaneDistance() ? event.getFarPlaneDistance() : (float) MathHelper.clampedLerp(f, event.getFarPlaneDistance(), spoopFog); + float shift = (float) (0.001F * event.getRenderPartialTicks()); + if (flag) + spoopFog -= shift; + else + spoopFog += shift; + spoopFog = MathHelper.clamp(spoopFog, 0F, 1F); + + GlStateManager.setFog(GlStateManager.FogMode.LINEAR); + + if (event.getFogMode() == -1) { + GlStateManager.setFogStart(0.0F); + GlStateManager.setFogEnd(f); + } else { + GlStateManager.setFogStart(f * 0.75F); + GlStateManager.setFogEnd(f); + } + + if (GLContext.getCapabilities().GL_NV_fog_distance) { + GlStateManager.glFogi(0x855a, 0x855b); + } + } + } + + private static boolean isSpooky() { + return Minecraft.getMinecraft().world != null && Minecraft.getMinecraft().player != null && Minecraft.getMinecraft().world.getBiome(Minecraft.getMinecraft().player.getPosition()) == TFBiomes.spookyForest; + } + +} diff --git a/src/main/java/twilightforest/client/GuiTFCinderFurnace.java b/src/main/java/twilightforest/client/GuiTFCinderFurnace.java deleted file mode 100644 index 7a297d6068..0000000000 --- a/src/main/java/twilightforest/client/GuiTFCinderFurnace.java +++ /dev/null @@ -1,61 +0,0 @@ -package twilightforest.client; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.inventory.ContainerFurnace; -import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; - -import org.lwjgl.opengl.GL11; - -import twilightforest.inventory.ContainerTFCinderFurnace; -import twilightforest.tileentity.TileEntityTFCinderFurnace; - -@SideOnly(Side.CLIENT) -public class GuiTFCinderFurnace extends GuiContainer -{ - private static final ResourceLocation furnaceGuiTextures = new ResourceLocation("textures/gui/container/furnace.png"); - private TileEntityTFCinderFurnace tileFurnace; - - public GuiTFCinderFurnace(InventoryPlayer inventory, TileEntityTFCinderFurnace furnace) - { - super(new ContainerTFCinderFurnace(inventory, furnace)); - this.tileFurnace = furnace; - } - - public GuiTFCinderFurnace(InventoryPlayer inventory, World world, int x, - int y, int z) { - this(inventory, (TileEntityTFCinderFurnace)world.getTileEntity(x, y, z)); - } - - /** - * Draw the foreground layer for the GuiContainer (everything in front of the items) - */ - protected void drawGuiContainerForegroundLayer(int p_146979_1_, int p_146979_2_) - { - String s = this.tileFurnace.hasCustomInventoryName() ? this.tileFurnace.getInventoryName() : I18n.format(this.tileFurnace.getInventoryName(), new Object[0]); - this.fontRendererObj.drawString(s, this.xSize / 2 - this.fontRendererObj.getStringWidth(s) / 2, 6, 4210752); - this.fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, this.ySize - 96 + 2, 4210752); - } - - protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) - { - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - this.mc.getTextureManager().bindTexture(furnaceGuiTextures); - int k = (this.width - this.xSize) / 2; - int l = (this.height - this.ySize) / 2; - this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize); - - if (this.tileFurnace.isBurning()) - { - int i1 = this.tileFurnace.getBurnTimeRemainingScaled(13); - this.drawTexturedModalRect(k + 56, l + 36 + 12 - i1, 176, 12 - i1, 14, i1 + 1); - i1 = this.tileFurnace.getCookProgressScaled(24); - this.drawTexturedModalRect(k + 79, l + 34, 176, 14, i1 + 1, 16); - } - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/GuiTFGoblinCrafting.java b/src/main/java/twilightforest/client/GuiTFGoblinCrafting.java index add8f1443d..eb828cd1c7 100644 --- a/src/main/java/twilightforest/client/GuiTFGoblinCrafting.java +++ b/src/main/java/twilightforest/client/GuiTFGoblinCrafting.java @@ -1,137 +1,302 @@ package twilightforest.client; - +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.StatCollector; import net.minecraft.world.World; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; +import twilightforest.block.TFBlocks; import twilightforest.inventory.ContainerTFUncrafting; +import twilightforest.network.PacketUncraftingGui; +import twilightforest.network.TFPacketHandler; + +import java.io.IOException; public class GuiTFGoblinCrafting extends GuiContainer { - - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.GUI_DIR + "guigoblintinkering.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getGuiTexture("guigoblintinkering.png"); public GuiTFGoblinCrafting(InventoryPlayer inventory, World world, int x, int y, int z) { super(new ContainerTFUncrafting(inventory, world, x, y, z)); } - /** - * Draw the foreground layer for the GuiContainer (everythin in front of the items) - */ @Override - protected void drawGuiContainerForegroundLayer(int var1, int var2) - { - this.fontRendererObj.drawString("Uncrafting Table", 8, 6, 4210752); - this.fontRendererObj.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); - } + public void initGui() { + super.initGui(); + + int id = 0; + + this.buttonList.add(new CycleButton(++id, guiLeft + 40, guiTop + 22, true, false)); + this.buttonList.add(new CycleButton(++id, guiLeft + 40, guiTop + 55, false, false)); + + //this.buttonList.add(new ModeButton(++id, guiLeft + 7, guiTop + 57)); + + this.buttonList.add(new CycleButtonMini(++id, guiLeft + 27, guiTop + 56, true)); + this.buttonList.add(new CycleButtonMini(++id, guiLeft + 27, guiTop + 63, false)); + + //this.buttonList.add(new RefreshButton(++id, guiLeft + 26, guiTop + 57)); + + this.buttonList.add(new CycleButton(++id, guiLeft + 121, guiTop + 22, true, true)); + this.buttonList.add(new CycleButton(++id, guiLeft + 121, guiTop + 55, false, true)); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + super.drawScreen(mouseX, mouseY, partialTicks); + renderHoveredToolTip(mouseX, mouseY); + } + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + this.fontRenderer.drawString(I18n.format(TFBlocks.uncrafting_table.getTranslationKey() + ".name"), 8, 6, 4210752); + this.fontRenderer.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752); + } - /** - * Draw the background layer for the GuiContainer (everything behind the items) - */ @Override - protected void drawGuiContainerBackgroundLayer(float var1, int var2, int var3) { - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - this.mc.getTextureManager().bindTexture(textureLoc); - int frameX = (this.width - this.xSize) / 2; - int frameY = (this.height - this.ySize) / 2; - this.drawTexturedModalRect(frameX, frameY, 0, 0, this.xSize, this.ySize); - - ContainerTFUncrafting tfContainer = (ContainerTFUncrafting)this.inventorySlots; - - // show uncrafting ingredients as background - RenderHelper.enableGUIStandardItemLighting(); - GL11.glPushMatrix(); - GL11.glTranslatef((float)this.guiLeft, (float)this.guiTop, 0.0F); - - for (int i = 0; i < 9; i++) { - Slot uncrafting = tfContainer.getSlot(2 + i); - Slot assembly = tfContainer.getSlot(11 + i); - - if (uncrafting.getStack() != null) - { - drawSlotAsBackground(uncrafting, assembly); - } - } - GL11.glPopMatrix(); - - // show the costs if there are any - FontRenderer fontRendererObj = this.mc.fontRenderer; - RenderHelper.disableStandardItemLighting(); - - int costVal = tfContainer.getUncraftingCost(); - if (costVal > 0) { - if (this.mc.thePlayer.experienceLevel < costVal && !this.mc.thePlayer.capabilities.isCreativeMode) { - int color = 0xA00000; - String cost = "" + costVal; - fontRendererObj.drawStringWithShadow(cost, frameX + 48 - fontRendererObj.getStringWidth(cost), frameY + 38, color); - } - else { - int color = 0x80FF20; - String cost = "" + costVal; - fontRendererObj.drawStringWithShadow(cost, frameX + 48 - fontRendererObj.getStringWidth(cost), frameY + 38, color); - } - } - - costVal = tfContainer.getRecraftingCost(); - if (costVal > 0) { - if (this.mc.thePlayer.experienceLevel < costVal && !this.mc.thePlayer.capabilities.isCreativeMode) { - int color = 0xA00000; - String cost = "" + costVal; - fontRendererObj.drawStringWithShadow(cost, frameX + 130 - fontRendererObj.getStringWidth(cost), frameY + 38, color); - } - else { - int color = 0x80FF20; - String cost = "" + costVal; - fontRendererObj.drawStringWithShadow(cost, frameX + 130 - fontRendererObj.getStringWidth(cost), frameY + 38, color); - } - } - + protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { + GlStateManager.color(1, 1, 1, 1); + this.mc.getTextureManager().bindTexture(textureLoc); + int frameX = (this.width - this.xSize) / 2; + int frameY = (this.height - this.ySize) / 2; + this.drawTexturedModalRect(frameX, frameY, 0, 0, this.xSize, this.ySize); + + ContainerTFUncrafting tfContainer = (ContainerTFUncrafting) this.inventorySlots; + + // show uncrafting ingredients as background + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft, guiTop, 0); + + for (int i = 0; i < 9; i++) { + Slot uncrafting = tfContainer.getSlot(2 + i); + Slot assembly = tfContainer.getSlot(11 + i); + + if (uncrafting.getHasStack()) { + drawSlotAsBackground(uncrafting, assembly); + } + } + GlStateManager.popMatrix(); + + // show the costs if there are any + FontRenderer fontRendererObj = this.mc.fontRenderer; + RenderHelper.disableStandardItemLighting(); + + int costVal = tfContainer.getUncraftingCost(); + if (costVal > 0) { + if (this.mc.player.experienceLevel < costVal && !this.mc.player.capabilities.isCreativeMode) { + int color = 0xA00000; + String cost = "" + costVal; + fontRendererObj.drawStringWithShadow(cost, frameX + 48 - fontRendererObj.getStringWidth(cost), frameY + 38, color); + } else { + int color = 0x80FF20; + String cost = "" + costVal; + fontRendererObj.drawStringWithShadow(cost, frameX + 48 - fontRendererObj.getStringWidth(cost), frameY + 38, color); + } + } + + costVal = tfContainer.getRecraftingCost(); + if (costVal > 0) { + if (this.mc.player.experienceLevel < costVal && !this.mc.player.capabilities.isCreativeMode) { + int color = 0xA00000; + String cost = "" + costVal; + fontRendererObj.drawStringWithShadow(cost, frameX + 130 - fontRendererObj.getStringWidth(cost), frameY + 38, color); + } else { + int color = 0x80FF20; + String cost = "" + costVal; + fontRendererObj.drawStringWithShadow(cost, frameX + 130 - fontRendererObj.getStringWidth(cost), frameY + 38, color); + } + } + + } + + private void drawSlotAsBackground(Slot backgroundSlot, Slot appearSlot) { + + int screenX = appearSlot.xPos; + int screenY = appearSlot.yPos; + ItemStack itemStackToRender = backgroundSlot.getStack(); + this.zLevel = 50.0F; + itemRender.zLevel = 50.0F; + + itemRender.renderItemIntoGUI(itemStackToRender, screenX, screenY); + itemRender.renderItemOverlayIntoGUI(this.fontRenderer, itemStackToRender, screenX, screenY, ""); + + boolean itemBroken = ContainerTFUncrafting.isMarked(itemStackToRender); + + // draw 50% gray rectangle over the item + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + Gui.drawRect(screenX, screenY, screenX + 16, screenY + 16, itemBroken ? 0x80FF8b8b : 0x9f8b8b8b); + GlStateManager.enableLighting(); + GlStateManager.enableDepth(); + + itemRender.zLevel = 0.0F; + this.zLevel = 0.0F; } + @Override + protected void actionPerformed(GuiButton button) throws IOException { + super.actionPerformed(button); + + if (this.inventorySlots instanceof ContainerTFUncrafting) { + ContainerTFUncrafting uncrafting = (ContainerTFUncrafting) this.inventorySlots; + + if (button instanceof CycleButton) { + CycleButton cycleButton = (CycleButton) button; + + if (cycleButton.constructive) { + TFPacketHandler.CHANNEL.sendToServer(new PacketUncraftingGui(cycleButton.up ? 4 : 5)); + + if (((CycleButton) button).up) { + uncrafting.recipeInCycle++; + } else { + uncrafting.recipeInCycle--; + } + + uncrafting.onCraftMatrixChanged(uncrafting.assemblyMatrix); + } else { + TFPacketHandler.CHANNEL.sendToServer(new PacketUncraftingGui(cycleButton.up ? 0 : 1)); + + if (((CycleButton) button).up) { + uncrafting.unrecipeInCycle++; + } else { + uncrafting.unrecipeInCycle--; + } + + uncrafting.onCraftMatrixChanged(uncrafting.tinkerInput); + } + } + + //if (button instanceof ModeButton) { + // TFPacketHandler.CHANNEL.sendToServer(new PacketUncraftingGui(2)); + + // uncrafting.ingredientMode = !uncrafting.ingredientMode; + //} + + if (button instanceof CycleButtonMini) { + TFPacketHandler.CHANNEL.sendToServer(new PacketUncraftingGui(((CycleButtonMini) button).up ? 2 : 3)); + + if (((CycleButtonMini) button).up) { + uncrafting.ingredientsInCycle++; + } else { + uncrafting.ingredientsInCycle--; + } + + uncrafting.onCraftMatrixChanged(uncrafting.tinkerInput); + } + + this.buttonList.clear(); + this.initGui(); + this.updateScreen(); + } + } + + private static class CycleButton extends GuiButton { + private final boolean up; + private final boolean constructive; + + CycleButton(int buttonId, int x, int y, boolean up, boolean constructive) { + super(buttonId, x, y, 14, 9, ""); + this.up = up; + this.constructive = constructive; + } + + @Override + public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { + if (this.visible) { + mc.getTextureManager().bindTexture(GuiTFGoblinCrafting.textureLoc); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; + + int textureX = 176; + int textureY = 0; + + if (this.hovered) textureX += this.width; + + // what's up + if (!this.up) textureY += this.height; + + this.drawTexturedModalRect(this.x, this.y, textureX, textureY, this.width, this.height); + } + } + } + +// private static class ModeButton extends GuiButton { +// ModeButton(int buttonId, int x, int y) { +// super(buttonId, x, y, 18, 12, ""); +// } + +// public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { +// if (this.visible) { +// mc.getTextureManager().bindTexture(GuiTFGoblinCrafting.textureLoc); +// GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); +// this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; + +// int textureX = 176; +// int textureY = 18; + +// if (this.hovered) textureX += this.width; + +// this.drawTexturedModalRect(this.x, this.y, textureX, textureY, this.width, this.height); +// } +// } +// } + + private class CycleButtonMini extends GuiButton { + private final boolean up; + + CycleButtonMini(int buttonId, int x, int y, boolean up) { + super(buttonId, x, y, 8, 6, ""); + this.up = up; + } + + @Override + public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { + if (this.visible) { + mc.getTextureManager().bindTexture(GuiTFGoblinCrafting.textureLoc); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; + + int textureX = 176; + int textureY = 41; + + if (this.hovered) textureX += this.width; + + // what's up + if (!this.up) textureY += this.height; + + this.drawTexturedModalRect(this.x, this.y, textureX, textureY, this.width, this.height); + } + } + } + +// static class RefreshButton extends GuiButton { +// RefreshButton(int buttonId, int x, int y) { +// super(buttonId, x, y, 8, 6, ""); +// } + +// public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { +// if (this.visible) { +// mc.getTextureManager().bindTexture(GuiTFGoblinCrafting.textureLoc); +// GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); +// this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; + +// int textureX = 176; +// int textureY = 30; + +// if (this.hovered) textureX += this.width; - - /** - * Draws an inventory slot - */ - private void drawSlotAsBackground(Slot backgroundSlot, Slot appearSlot) - { - int screenX = appearSlot.xDisplayPosition; - int screenY = appearSlot.yDisplayPosition; - ItemStack itemStackToRender = backgroundSlot.getStack(); - this.zLevel = 50.0F; - itemRender.zLevel = 50.0F; - - itemRender.renderItemIntoGUI(this.fontRendererObj, this.mc.renderEngine, itemStackToRender, screenX, screenY); - itemRender.renderItemOverlayIntoGUI(this.fontRendererObj, this.mc.renderEngine, itemStackToRender, screenX, screenY); - - boolean itemBroken = false; - - if (backgroundSlot.getHasStack() && backgroundSlot.getStack().stackSize == 0) { - itemBroken = true; - } - - - // draw 50% gray rectangle over the item - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glDisable(GL11.GL_DEPTH_TEST); - Gui.drawRect(screenX, screenY, screenX + 16, screenY + 16, itemBroken ? 0x80FF8b8b : 0x9f8b8b8b); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glEnable(GL11.GL_DEPTH_TEST); - - - itemRender.zLevel = 0.0F; - this.zLevel = 0.0F; - } +// this.drawTexturedModalRect(this.x, this.y, textureX, textureY, this.width, this.height); +// } +// } +// } } diff --git a/src/main/java/twilightforest/client/GuiTwilightForestLoading.java b/src/main/java/twilightforest/client/GuiTwilightForestLoading.java new file mode 100644 index 0000000000..fb8d81c51c --- /dev/null +++ b/src/main/java/twilightforest/client/GuiTwilightForestLoading.java @@ -0,0 +1,476 @@ +package twilightforest.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.translation.I18n; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.lwjgl.opengl.GL11; +import twilightforest.TFConfig; +import twilightforest.TwilightForestMod; + +import java.util.Random; + +@SideOnly(Side.CLIENT) +public class GuiTwilightForestLoading extends GuiScreen { + + private boolean isEntering; + private boolean contentNeedsAssignment = false; + private long lastWorldUpdateTick = 0L; + private long seed; + private BackgroundThemes backgroundTheme; + private ItemStack item; + + private static final Random random = new Random(); + private static final float backgroundScale = 32.0F; + + GuiTwilightForestLoading() { + + } + + void setEntering(boolean isEntering) { + this.isEntering = isEntering; + } + + @Override + public void initGui() { + this.buttonList.clear(); + this.assignContent(); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) {} + + @Override + public boolean doesGuiPauseGame() { + return false; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + if (this.contentNeedsAssignment) { + this.assignContent(); + this.contentNeedsAssignment = false; + } + + if (mc.world != null && TFConfig.loadingScreen.cycleLoadingScreenFrequency != 0) { + if (lastWorldUpdateTick != mc.world.getTotalWorldTime() % 240000) { + + lastWorldUpdateTick = mc.world.getTotalWorldTime() % 240000; + + if (lastWorldUpdateTick % TFConfig.loadingScreen.cycleLoadingScreenFrequency == 0) { + assignContent(); + } + } + } + + FontRenderer fontRenderer = mc.fontRenderer; + ScaledResolution resolution = new ScaledResolution(mc); + + drawBackground(resolution.getScaledWidth(), resolution.getScaledHeight()); + + drawBouncingWobblyItem(partialTicks, resolution.getScaledWidth(), resolution.getScaledHeight()); + + String loadTitle = I18n.translateToLocal(TwilightForestMod.ID + ".loading.title." + (isEntering ? "enter" : "leave")); + GlStateManager.pushMatrix(); + GlStateManager.translate( + (resolution.getScaledWidth() / 2f) - (fontRenderer.getStringWidth(loadTitle) / 4f), + (resolution.getScaledHeight() / 3f), + 0f + ); + GlStateManager.translate(-(fontRenderer.getStringWidth(loadTitle) / 4f), 0f, 0f); + fontRenderer.drawStringWithShadow(loadTitle, 0, 0, 0xEEEEEE); //eeeeeeeeeeeeeeeeee + GlStateManager.popMatrix(); + GlStateManager.color(1F, 1F, 1F, 1F); + } + + private void assignContent() { + backgroundTheme = BackgroundThemes.values()[random.nextInt(BackgroundThemes.values().length)]; + item = TFConfig.loadingScreen.getLoadingScreenIcons().get(random.nextInt(TFConfig.loadingScreen.getLoadingScreenIcons().size())); + seed = random.nextLong(); + } + + private void drawBackground(float width, float height) { + random.setSeed(seed); + + backgroundTheme.renderBackground(width, height); + backgroundTheme.postRenderBackground(width, height); + } + + private void drawBouncingWobblyItem(float partialTicks, float width, float height) { + float sineTicker = (TFClientEvents.sineTicker + partialTicks) * TFConfig.loadingScreen.frequency; + float sineTicker2 = (TFClientEvents.sineTicker + 314f + partialTicks) * TFConfig.loadingScreen.frequency; + GlStateManager.pushMatrix(); + + // Shove it! + GlStateManager.translate(width - ((width / 30f) * TFConfig.loadingScreen.scale), height - (height / 10f), 0f); // Bottom right Corner + + if (TFConfig.loadingScreen.enable) { + // Wobble it! + GlStateManager.rotate(MathHelper.sin(sineTicker / TFConfig.loadingScreen.tiltRange) * TFConfig.loadingScreen.tiltConstant, 0f, 0f, 1f); + + // Bounce it! + GlStateManager.scale(((MathHelper.sin(((sineTicker2 + 180F) / TFConfig.loadingScreen.tiltRange) * 2F) / TFConfig.loadingScreen.scaleDeviation) + 2F) * (TFConfig.loadingScreen.scale / 2F), ((MathHelper.sin(((sineTicker + 180F) / TFConfig.loadingScreen.tiltRange) * 2F) / TFConfig.loadingScreen.scaleDeviation) + 2F) * (TFConfig.loadingScreen.scale / 2F), 1F); + } + + // Shift it! + GlStateManager.translate(-8f, -16.5f, 0f); + + RenderHelper.enableGUIStandardItemLighting(); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 0x20, 0x20); + // Draw it! + mc.getRenderItem().renderItemAndEffectIntoGUI(item, 0, 0); + RenderHelper.disableStandardItemLighting(); + + // Pop it! + GlStateManager.popMatrix(); + // Bop it! + } + + public enum BackgroundThemes { + LABYRINTH( + TwilightForestMod.prefix("textures/blocks/mazestone_brick.png"), + TwilightForestMod.prefix("textures/blocks/mazestone_brick.png"), + //TwilightForestMod.prefix("textures/blocks/mazestone_mossy.png" ), + TwilightForestMod.prefix("textures/blocks/mazestone_cracked.png") + ) { + private final ResourceLocation mazestoneDecor = TwilightForestMod.prefix("textures/blocks/mazestone_decorative.png"); + + @Override + void postRenderBackground(float width, float height) { + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + Minecraft.getMinecraft().getTextureManager().bindTexture(mazestoneDecor); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(0, 24F, 0F) + .tex(0F, 0.75F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(width, 24F, 0F) + .tex(width / backgroundScale, 0.75F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(width, 8F, 0F) + .tex(width / backgroundScale, 0.25F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(0, 8F, 0) + .tex(0F, 0.25F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + tessellator.draw(); + + float halfScale = backgroundScale / 2F; + float bottomGrid = height - (height % halfScale); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(0, bottomGrid, 0F) + .tex(0F, 0.75F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(width, bottomGrid, 0F) + .tex(width / backgroundScale, 0.75F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(width, bottomGrid - halfScale, 0F) + .tex(width / backgroundScale, 0.25F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(0, bottomGrid - halfScale, 0) + .tex(0F, 0.25F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + tessellator.draw(); + } + }, + STRONGHOLD( + TwilightForestMod.prefix("textures/blocks/knightbrick.png"), + TwilightForestMod.prefix("textures/blocks/knightbrick_mossy.png"), + TwilightForestMod.prefix("textures/blocks/knightbrick_cracked.png") + ), + DARKTOWER( + TwilightForestMod.prefix("textures/blocks/towerwood_planks.png"), + TwilightForestMod.prefix("textures/blocks/towerwood_planks.png"), + TwilightForestMod.prefix("textures/blocks/towerwood_mossy.png"), + TwilightForestMod.prefix("textures/blocks/towerwood_cracked.png"), + //TwilightForestMod.prefix("textures/blocks/towerwood_infested.png" ), + TwilightForestMod.prefix("textures/blocks/towerwood_alt.png") + ) { + private final ResourceLocation towerwoodEncased = TwilightForestMod.prefix("textures/blocks/towerwood_encased.png"); + + private final float stretch = 0.985F; + private final float offset = 0.4F; + private final float depth = 1.15F; + + @Override + void renderBackground(float width, float height) { + final float headerDepthHeight = (backgroundScale / stretch) * depth; + final float footerDepthHeight = height - headerDepthHeight; + + GlStateManager.disableLighting(); + GlStateManager.disableFog(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + GlStateManager.color(0.9F, 0.9F, 0.9F, 1.0F); + + for (float x = backgroundScale; x < width + backgroundScale; x += backgroundScale) { + for (float y = backgroundScale + headerDepthHeight; y < footerDepthHeight + backgroundScale; y += backgroundScale) { + Minecraft.getMinecraft().getTextureManager().bindTexture(this.getBackgroundMaterials()[random.nextInt(this.getBackgroundMaterials().length)]); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(x - backgroundScale, y, 0) + .tex(0, 1) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + buffer.pos(x, y, 0) + .tex(1, 1) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + buffer.pos(x, y - backgroundScale, 0) + .tex(1, 0) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + buffer.pos(x - backgroundScale, y - backgroundScale, 0) + .tex(0, 0) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + tessellator.draw(); + } + } + } + + @Override + void postRenderBackground(float width, float height) { + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + Minecraft.getMinecraft().getTextureManager().bindTexture(towerwoodEncased); + + final float textureHeaderXMin = stretch * offset; + final float textureHeaderXMax = ((width / backgroundScale) * stretch) + offset; + + final float headerBottom = backgroundScale / stretch; + final float headerDepthHeight = headerBottom * depth; + + final float footerTop = height - headerBottom; + final float footerDepthHeight = height - headerDepthHeight; + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + // BOTTOM VERTEXES + buffer.pos(0F, headerBottom, 0F) + .tex(textureHeaderXMin, 1F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(width, headerBottom, 0F) + .tex(textureHeaderXMax, 1F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + // TOP VERTEXES + buffer.pos(width, 0F, 0F) + .tex(textureHeaderXMax, 0F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(0F, 0F, 0F) + .tex(textureHeaderXMin, 0F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + tessellator.draw(); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + // BOTTOM VERTEXES + buffer.pos(0F, headerDepthHeight, 0F) + .tex(0F, 1F) + .color(0.25F, 0.25F, 0.25F, 1F) + .endVertex(); + buffer.pos(width, headerDepthHeight, 0F) + .tex((width / backgroundScale), 1F) + .color(0.25F, 0.25F, 0.25F, 1F) + .endVertex(); + // TOP VERTEXES + buffer.pos(width, headerBottom, 0F) + .tex(textureHeaderXMax, 0F) + .color(0.25F, 0.25F, 0.25F, 1F) + .endVertex(); + buffer.pos(0F, headerBottom, 0F) + .tex(textureHeaderXMin, 0F) + .color(0.25F, 0.25F, 0.25F, 1F) + .endVertex(); + tessellator.draw(); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + // BOTTOM VERTEXES + buffer.pos(0F, height, 0F) + .tex(textureHeaderXMin, 1F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(width, height, 0F) + .tex(textureHeaderXMax, 1F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + // TOP VERTEXES + buffer.pos(width, footerTop, 0F) + .tex(textureHeaderXMax, 0F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + buffer.pos(0F, footerTop, 0F) + .tex(textureHeaderXMin, 0F) + .color(0.5F, 0.5F, 0.5F, 1F) + .endVertex(); + tessellator.draw(); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + // BOTTOM VERTEXES + buffer.pos(0F, footerTop, 0F) + .tex(textureHeaderXMin, 1F) + .color(0.75F, 0.75F, 0.75F, 1F) + .endVertex(); + buffer.pos(width, footerTop, 0F) + .tex(textureHeaderXMax, 1F) + .color(0.75F, 0.75F, 0.75F, 1F) + .endVertex(); + // TOP VERTEXES + buffer.pos(width, footerDepthHeight, 0F) + .tex(width / backgroundScale, 0F) + .color(0.75F, 0.75F, 0.75F, 1F) + .endVertex(); + buffer.pos(0F, footerDepthHeight, 0F) + .tex(0F, 0F) + .color(0.75F, 0.75F, 0.75F, 1F) + .endVertex(); + tessellator.draw(); + } + }, + FINALCASTLE( + TwilightForestMod.prefix("textures/blocks/castleblock_brick.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_brick.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_brick.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_brick.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_brick.png"), + //TwilightForestMod.prefix("textures/blocks/castleblock_mossy.png" ), // Jeez this one does not fit at ALL. Out! + TwilightForestMod.prefix("textures/blocks/castleblock_cracked.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_faded.png") + ) { + private final ResourceLocation[] magic = new ResourceLocation[]{ + TwilightForestMod.prefix("textures/blocks/castleblock_magic_0.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_magic_1.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_magic_2.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_magic_3.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_magic_4.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_magic_5.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_magic_6.png"), + TwilightForestMod.prefix("textures/blocks/castleblock_magic_7.png") + }; + + private final int[] colors = new int[]{0xFF00FF, 0x00FFFF, 0xFFFF00, 0x4B0082}; + + @Override + void postRenderBackground(float width, float height) { + GlStateManager.disableLighting(); + GlStateManager.disableFog(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + + int color = this.colors[random.nextInt(this.colors.length)]; + + int r = color >> 16 & 255; + int g = color >> 8 & 255; + int b = color & 255; + + for (float x = backgroundScale; x < width + backgroundScale; x += backgroundScale) { + Minecraft.getMinecraft().getTextureManager().bindTexture(this.magic[random.nextInt(this.magic.length)]); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(x - backgroundScale, backgroundScale + (backgroundScale / 2), 0) + .tex(0, 1) + .color(r, g, b, 255) + .endVertex(); + buffer.pos(x, backgroundScale + (backgroundScale / 2), 0) + .tex(1, 1) + .color(r, g, b, 255) + .endVertex(); + buffer.pos(x, backgroundScale / 2, 0) + .tex(1, 0) + .color(r, g, b, 255) + .endVertex(); + buffer.pos(x - backgroundScale, backgroundScale / 2, 0) + .tex(0, 0) + .color(r, g, b, 255) + .endVertex(); + tessellator.draw(); + } + + for (float x = backgroundScale; x < width + backgroundScale; x += backgroundScale) { + Minecraft.getMinecraft().getTextureManager().bindTexture(this.magic[random.nextInt(this.magic.length)]); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(x - backgroundScale, height - (backgroundScale / 2), 0) + .tex(0, 1) + .color(r, g, b, 255) + .endVertex(); + buffer.pos(x, height - (backgroundScale / 2), 0) + .tex(1, 1) + .color(r, g, b, 255) + .endVertex(); + buffer.pos(x, height - backgroundScale - (backgroundScale / 2), 0) + .tex(1, 0) + .color(r, g, b, 255) + .endVertex(); + buffer.pos(x - backgroundScale, height - backgroundScale - (backgroundScale / 2), 0) + .tex(0, 0) + .color(r, g, b, 255) + .endVertex(); + tessellator.draw(); + } + } + }; + + private final ResourceLocation[] backgroundMaterials; + + BackgroundThemes(ResourceLocation... backgroundMaterials) { + this.backgroundMaterials = backgroundMaterials; + } + + ResourceLocation[] getBackgroundMaterials() { + return backgroundMaterials; + } + + void renderBackground(float width, float height) { + GlStateManager.disableLighting(); + GlStateManager.disableFog(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + GlStateManager.color(0.9F, 0.9F, 0.9F, 1.0F); + + for (float x = backgroundScale; x < width + backgroundScale; x += backgroundScale) { + for (float y = backgroundScale; y < height + backgroundScale; y += backgroundScale) { + Minecraft.getMinecraft().getTextureManager().bindTexture(this.getBackgroundMaterials()[random.nextInt(this.getBackgroundMaterials().length)]); + buffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(x - backgroundScale, y, 0) + .tex(0, 1) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + buffer.pos(x, y, 0) + .tex(1, 1) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + buffer.pos(x, y - backgroundScale, 0) + .tex(1, 0) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + buffer.pos(x - backgroundScale, y - backgroundScale, 0) + .tex(0, 0) + .color(0.5f, 0.5f, 0.5f, 1f) + .endVertex(); + tessellator.draw(); + } + } + } + + void postRenderBackground(float width, float height) { + } + } +} diff --git a/src/main/java/twilightforest/client/GuiUtils.java b/src/main/java/twilightforest/client/GuiUtils.java new file mode 100644 index 0000000000..eae5b562d2 --- /dev/null +++ b/src/main/java/twilightforest/client/GuiUtils.java @@ -0,0 +1,22 @@ +package twilightforest.client; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; + +public class GuiUtils { + + // [VanillaCopy] of Gui.drawModalRectWithCustomSizedTexture, but accepting a z-level parameter + public static void drawModalRectWithCustomSizedTexture(int x, int y, float z, float u, float v, int width, int height, float textureWidth, float textureHeight) { + float f = 1.0F / textureWidth; + float f1 = 1.0F / textureHeight; + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX); + bufferbuilder.pos((double)x, (double)(y + height), (double)z).tex((double)(u * f), (double)((v + (float)height) * f1)).endVertex(); + bufferbuilder.pos((double)(x + width), (double)(y + height), (double)z).tex((double)((u + (float)width) * f), (double)((v + (float)height) * f1)).endVertex(); + bufferbuilder.pos((double)(x + width), (double)y, (double)z).tex((double)((u + (float)width) * f), (double)(v * f1)).endVertex(); + bufferbuilder.pos((double)x, (double)y, (double)z).tex((double)(u * f), (double)(v * f1)).endVertex(); + tessellator.draw(); + } +} diff --git a/src/main/java/twilightforest/client/LoadingScreenListener.java b/src/main/java/twilightforest/client/LoadingScreenListener.java new file mode 100644 index 0000000000..c2cf003274 --- /dev/null +++ b/src/main/java/twilightforest/client/LoadingScreenListener.java @@ -0,0 +1,36 @@ +package twilightforest.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiDownloadTerrain; +import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; + +@SideOnly(Side.CLIENT) +public class LoadingScreenListener { + + private final Minecraft client = Minecraft.getMinecraft(); + private int lastDimension = 0; + + @SubscribeEvent + public void onPlayerTick(TickEvent.PlayerTickEvent event) { + if (event.phase == TickEvent.Phase.END && event.player == client.player) { + lastDimension = event.player.dimension; + } + } + + @SubscribeEvent + public void onOpenGui(GuiOpenEvent event) { + if (event.getGui() instanceof GuiDownloadTerrain && client.player != null) { + int tfDimension = TFConfig.dimension.dimensionID; + if (client.player.dimension == tfDimension || lastDimension == tfDimension) { + GuiTwilightForestLoading guiLoading = new GuiTwilightForestLoading(); + guiLoading.setEntering(client.player.dimension == tfDimension); + event.setGui(guiLoading); + } + } + } +} diff --git a/src/main/java/twilightforest/client/ModelRegisterCallback.java b/src/main/java/twilightforest/client/ModelRegisterCallback.java new file mode 100644 index 0000000000..1f47123128 --- /dev/null +++ b/src/main/java/twilightforest/client/ModelRegisterCallback.java @@ -0,0 +1,39 @@ +package twilightforest.client; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.block.statemap.StateMapperBase; +import net.minecraft.item.Item; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public interface ModelRegisterCallback { + + /** + * Do whatever is necessary to register your models. (Statemappers, custom meshers, etc.) + */ + @SideOnly(Side.CLIENT) + default void registerModel() { + if (this instanceof Item) { + ModelLoader.setCustomModelResourceLocation((Item) this, 0, new ModelResourceLocation(((Item) this).getRegistryName(), "inventory")); + } else if (this instanceof Block) { + ModelUtils.registerToState((Block) this, 0, ((Block) this).getDefaultState()); + } + } + + class SingleStateMapper extends StateMapperBase { + + private final ModelResourceLocation location; + + public SingleStateMapper(ModelResourceLocation location) { + this.location = location; + } + + @Override + protected ModelResourceLocation getModelResourceLocation(IBlockState state) { + return location; + } + } +} diff --git a/src/main/java/twilightforest/client/ModelRegisterCallbackCTM.java b/src/main/java/twilightforest/client/ModelRegisterCallbackCTM.java new file mode 100644 index 0000000000..43a5c18384 --- /dev/null +++ b/src/main/java/twilightforest/client/ModelRegisterCallbackCTM.java @@ -0,0 +1,64 @@ +package twilightforest.client; + +import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.block.statemap.StateMapperBase; +import net.minecraft.item.Item; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.HashMap; + +public interface ModelRegisterCallbackCTM extends ModelRegisterCallback { + /** + * Should ONLY be implemented on Block or its children. + */ + @Override + @SideOnly(Side.CLIENT) + default void registerModel() { + ModelLoader.setCustomStateMapper((Block) this, new CTMOptionalStateMapper(this.getIgnoredProperties())); + + this.registerItemModel(); + } + + @SideOnly(Side.CLIENT) + default void registerItemModel() { + Block block = (Block) this; + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory")); + } + + @SideOnly(Side.CLIENT) + default IProperty[] getIgnoredProperties() { + return new IProperty[0]; + } + + @SideOnly(Side.CLIENT) + class CTMOptionalStateMapper extends StateMapperBase { + private final IProperty[] IGNORED_PROPERTIES; + + public CTMOptionalStateMapper(IProperty... ignoredProperties) { + this.IGNORED_PROPERTIES = ignoredProperties; + } + + @Override + protected ModelResourceLocation getModelResourceLocation(IBlockState state) { + HashMap, Comparable> properties = new HashMap<>(state.getProperties()); + + for (IProperty ignored : IGNORED_PROPERTIES) + properties.remove(ignored); + + boolean ctm = Loader.isModLoaded("ctm"); + + // If there's no additional properties, then let's cheese it and just fold it into a single blockstate json + // Otherwise, split to two blockstate jsons + if (properties.isEmpty()) + return new ModelResourceLocation(Block.REGISTRY.getNameForObject(state.getBlock()), ctm ? "ctm" : "normal"); + else + return new ModelResourceLocation(ctm ? Block.REGISTRY.getNameForObject(state.getBlock()) + "_ctm" : Block.REGISTRY.getNameForObject(state.getBlock()).toString(), this.getPropertyString(properties)); + } + } +} diff --git a/src/main/java/twilightforest/client/ModelRegistrationHandler.java b/src/main/java/twilightforest/client/ModelRegistrationHandler.java new file mode 100644 index 0000000000..537849c5a2 --- /dev/null +++ b/src/main/java/twilightforest/client/ModelRegistrationHandler.java @@ -0,0 +1,19 @@ +package twilightforest.client; + +import net.minecraftforge.client.event.ModelRegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.relauncher.Side; +import twilightforest.TwilightForestMod; +import twilightforest.block.RegisterBlockEvent; +import twilightforest.item.RegisterItemEvent; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID, value = Side.CLIENT) +public class ModelRegistrationHandler { + + @SubscribeEvent + public static void onModelRegistryReady(ModelRegistryEvent event) { + RegisterBlockEvent.getBlockModels().forEach(ModelRegisterCallback::registerModel); + RegisterItemEvent.getItemModels().forEach(ModelRegisterCallback::registerModel); + } +} diff --git a/src/main/java/twilightforest/client/ModelUtils.java b/src/main/java/twilightforest/client/ModelUtils.java new file mode 100644 index 0000000000..0b6edc8916 --- /dev/null +++ b/src/main/java/twilightforest/client/ModelUtils.java @@ -0,0 +1,89 @@ +package twilightforest.client; + +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableSet; +import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.block.statemap.DefaultStateMapper; +import net.minecraft.client.renderer.block.statemap.IStateMapper; +import net.minecraft.client.renderer.block.statemap.StateMap; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.model.ModelLoader; + +import java.util.*; + +public class ModelUtils { + + public static void registerToState(Block b, int itemMeta, IBlockState state) { + registerToState(b, itemMeta, state, new DefaultStateMapper()); + } + + public static void registerToState(Block b, int itemMeta, IBlockState state, IStateMapper stateMapper) { + ModelResourceLocation mrl = stateMapper.putStateModelLocations(state.getBlock()).get(state); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(b), itemMeta, mrl); + } + + public static > void registerToStateSingleVariant(Block b, IProperty variant) { + registerToStateSingleVariant(b, variant, new DefaultStateMapper()); + } + + public static > void registerToStateSingleVariant(Block b, IProperty variant, IStateMapper stateMapper) { + List variants = new ArrayList<>(variant.getAllowedValues()); + for (int i = 0; i < variants.size(); i++) { + registerToState(b, i, b.getDefaultState().withProperty(variant, variants.get(i)), stateMapper); + } + } + + public static void registerIncludingItemModels(Block b, String inventoryPrefix, IProperty... blockIgnorables) { + registerIncludingItemModels(b, inventoryPrefix, blockIgnorables, new IProperty[0]); + } + + public static void registerIncludingItemModels(Block b, String inventoryPrefix, IProperty[] blockIgnorables, IProperty[] itemIgnorables) { + Set> properties = new HashSet<>(b.getBlockState().getProperties()); + final Item item = Item.getItemFromBlock(b); + + ModelLoader.setCustomStateMapper(b, new StateMap.Builder().ignore(blockIgnorables).build()); + + if (item != Items.AIR) { + if (itemIgnorables.length > 0) { + for (IProperty ignore : itemIgnorables) properties.remove(ignore); + + Set states = new HashSet<>(); + final IBlockState defaultState = b.getDefaultState(); + states.add(defaultState); + + for (IProperty prop : properties) { + ImmutableSet.Builder statesIn = ImmutableSet.builder(); + statesIn.addAll(states); + swizzleStatesWithPropertyKey(defaultState, states, statesIn.build(), prop); + } + + ResourceLocation rl = item.getRegistryName(); + + if (rl != null) { + for (IBlockState state : states) { + int meta = b.getMetaFromState(state); + ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(rl, inventoryPrefix + "_" + meta)); + } + } + } else { + ResourceLocation rl = item.getRegistryName(); + if (rl != null) ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(rl, inventoryPrefix)); + } + } + } + + private static > void swizzleStatesWithPropertyKey(IBlockState defaultState, Collection target, ImmutableCollection statesIn, IProperty property) { + Set values = new HashSet<>(property.getAllowedValues()); + + values.remove(defaultState.getValue(property)); + + for (T value : values) + for (IBlockState state : statesIn) + target.add(state.withProperty(property, value)); + } +} diff --git a/src/main/java/twilightforest/client/RenderEffect.java b/src/main/java/twilightforest/client/RenderEffect.java new file mode 100644 index 0000000000..139b43cf20 --- /dev/null +++ b/src/main/java/twilightforest/client/RenderEffect.java @@ -0,0 +1,102 @@ +package twilightforest.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderLivingBase; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.init.Blocks; +import org.lwjgl.opengl.GL11; +import twilightforest.capabilities.CapabilityList; +import twilightforest.capabilities.shield.IShieldCapability; +import twilightforest.client.renderer.entity.LayerShields; +import twilightforest.entity.boss.EntityTFLich; +import twilightforest.potions.PotionFrosted; + +import java.util.Random; + +public enum RenderEffect { + + ICE { + + private final Random random = new Random(); + + @Override + public boolean shouldRender(EntityLivingBase entity, boolean firstPerson) { + return !firstPerson && entity.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).getModifier(PotionFrosted.MODIFIER_UUID) != null; + } + + @Override + public void render(EntityLivingBase entity, RenderLivingBase renderer, + double x, double y, double z, float partialTicks, boolean firstPerson) { + + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + + random.setSeed(entity.getEntityId() * entity.getEntityId() * 3121 + entity.getEntityId() * 45238971); + + // number of cubes + int numCubes = (int) (entity.height / 0.4F); + + // make cubes + for (int i = 0; i < numCubes; i++) { + GlStateManager.pushMatrix(); + float dx = (float) (x + random.nextGaussian() * 0.2F * entity.width); + float dy = (float) (y + random.nextGaussian() * 0.2F * entity.height) + entity.height / 2F; + float dz = (float) (z + random.nextGaussian() * 0.2F * entity.width); + GlStateManager.translate(dx, dy, dz); + GlStateManager.scale(0.5F, 0.5F, 0.5F); + GlStateManager.rotate(random.nextFloat() * 360F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(random.nextFloat() * 360F, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(random.nextFloat() * 360F, 0.0F, 0.0F, 1.0F); + + Minecraft.getMinecraft().getBlockRendererDispatcher().renderBlockBrightness(Blocks.ICE.getDefaultState(), 1); + GlStateManager.popMatrix(); + } + + GlStateManager.disableBlend(); + } + + }, SHIELDS { + private final LayerRenderer layer = new LayerShields(); + + @Override + public boolean shouldRender(EntityLivingBase entity, boolean firstPerson) { + if (entity instanceof EntityTFLich) return false; + IShieldCapability cap = entity.getCapability(CapabilityList.SHIELDS, null); + return cap != null && cap.shieldsLeft() > 0; + } + + @Override + public void render(EntityLivingBase entity, RenderLivingBase renderer, + double x, double y, double z, float partialTicks, boolean firstPerson) { + + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); + GlStateManager.rotate(180, 1, 0, 0); + GlStateManager.translate(0, 0.5F - entity.getEyeHeight(), 0); + GlStateManager.enableBlend(); + GlStateManager.disableCull(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + layer.doRenderLayer(entity, 0, 0, partialTicks, 0, 0, 0, 0.0625F); + GlStateManager.enableCull(); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + }; + + static final RenderEffect[] VALUES = values(); + + public boolean shouldRender(EntityLivingBase entity, boolean firstPerson) { + return false; + } + + public void render(EntityLivingBase entity, RenderLivingBase renderer, + double x, double y, double z, float partialTicks, boolean firstPerson) { + + } +} diff --git a/src/main/java/twilightforest/client/TFClientEvents.java b/src/main/java/twilightforest/client/TFClientEvents.java index 747bb64760..6ce3346035 100644 --- a/src/main/java/twilightforest/client/TFClientEvents.java +++ b/src/main/java/twilightforest/client/TFClientEvents.java @@ -1,107 +1,216 @@ package twilightforest.client; -import java.util.Random; - import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderLivingBase; import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.settings.GameSettings; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.Blocks; -import net.minecraft.potion.Potion; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.client.event.RenderLivingEvent; - -import org.lwjgl.opengl.GL11; - +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; +import twilightforest.TFEventListener; import twilightforest.TwilightForestMod; -import twilightforest.item.ItemTFBowBase; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; - +import twilightforest.block.RegisterBlockEvent; +import twilightforest.block.TFBlocks; +import twilightforest.client.renderer.TFWeatherRenderer; +import twilightforest.client.texture.GradientMappedTexture; +import twilightforest.client.texture.GradientNode; +import twilightforest.client.texture.MoltenFieryTexture; +import twilightforest.compat.TFCompat; +import twilightforest.compat.ie.IEShaderRegister; +import twilightforest.world.TFWorld; + +@SideOnly(Side.CLIENT) +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID, value = Side.CLIENT) public class TFClientEvents { - private Random random; - - public TFClientEvents() { - this.random = new Random(); + @SubscribeEvent + public static void texStitch(TextureStitchEvent.Pre evt) { + TextureMap map = evt.getMap(); + + map.registerSprite(new ResourceLocation(TwilightForestMod.ID, "particles/snow_0")); + map.registerSprite(new ResourceLocation(TwilightForestMod.ID, "particles/snow_1")); + map.registerSprite(new ResourceLocation(TwilightForestMod.ID, "particles/snow_2")); + map.registerSprite(new ResourceLocation(TwilightForestMod.ID, "particles/snow_3")); + map.registerSprite(new ResourceLocation(TwilightForestMod.ID, "particles/annihilate_particle")); + map.registerSprite(new ResourceLocation(TwilightForestMod.ID, "particles/firefly")); + map.registerSprite(new ResourceLocation(TwilightForestMod.ID, "particles/fallen_leaf")); + + map.setTextureEntry( new MoltenFieryTexture ( new ResourceLocation( "minecraft", "blocks/lava_still" ), RegisterBlockEvent.moltenFieryStill )); + map.setTextureEntry( new MoltenFieryTexture ( new ResourceLocation( "minecraft", "blocks/lava_flow" ), RegisterBlockEvent.moltenFieryFlow )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "minecraft", "blocks/lava_still" ), RegisterBlockEvent.moltenKnightmetalStill, true, KNIGHTMETAL_GRADIENT_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "minecraft", "blocks/lava_flow" ), RegisterBlockEvent.moltenKnightmetalFlow , true, KNIGHTMETAL_GRADIENT_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "minecraft", "blocks/water_still" ), RegisterBlockEvent.essenceFieryStill , true, FIERY_ESSENCE_GRADIENT_MAP)); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "minecraft", "blocks/water_flow" ), RegisterBlockEvent.essenceFieryFlow , true, FIERY_ESSENCE_GRADIENT_MAP)); + + if (TFCompat.IMMERSIVEENGINEERING.isActivated()) { + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "revolvers/shaders/revolver_grip" ), IEShaderRegister.PROCESSED_REVOLVER_GRIP_LAYER, true, EASY_GRAYSCALING_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "revolvers/shaders/revolver_0" ), IEShaderRegister.PROCESSED_REVOLVER_LAYER , true, EASY_GRAYSCALING_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "items/shaders/chemthrower_0" ), IEShaderRegister.PROCESSED_CHEMTHROW_LAYER , true, EASY_GRAYSCALING_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "items/shaders/drill_diesel_0" ), IEShaderRegister.PROCESSED_DRILL_LAYER , true, EASY_GRAYSCALING_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "items/shaders/railgun_0" ), IEShaderRegister.PROCESSED_RAILGUN_LAYER , true, EASY_GRAYSCALING_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "items/shaders/shield_0" ), IEShaderRegister.PROCESSED_SHIELD_LAYER , true, EASY_GRAYSCALING_MAP )); + // map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "" ), IEShaderRegister.PROCESSED_MINECART_LAYER , true, EASY_GRAYSCALING_MAP )); + map.setTextureEntry( new GradientMappedTexture( new ResourceLocation( "immersiveengineering", "blocks/shaders/balloon_0" ), IEShaderRegister.PROCESSED_BALLOON_LAYER , true, EASY_GRAYSCALING_MAP )); + + final String[] types = new String[]{ "1_0", "1_2", "1_4", "1_5", "1_6" }; + + for (IEShaderRegister.CaseType caseType : IEShaderRegister.CaseType.everythingButMinecart()) { + for (String type : types) { + map.setTextureEntry(new GradientMappedTexture( + IEShaderRegister.ModType.IMMERSIVE_ENGINEERING.provideTex(caseType, type), + IEShaderRegister.ModType.TWILIGHT_FOREST.provideTex(caseType, type), + true, EASY_GRAYSCALING_MAP + )); + } + } + } } + public static final GradientNode[] KNIGHTMETAL_GRADIENT_MAP = { + new GradientNode(0.0f , 0xFF_33_32_32), + new GradientNode(0.1f , 0xFF_6A_73_5E), + new GradientNode(0.15f, 0xFF_80_8C_72), + new GradientNode(0.3f , 0xFF_A3_B3_91), + new GradientNode(0.6f , 0xFF_C4_D6_AE), + new GradientNode(1.0f , 0xFF_E7_FC_CD) + }; + + public static final GradientNode[] FIERY_ESSENCE_GRADIENT_MAP = { + new GradientNode(0.2f, 0xFF_3D_17_17), + new GradientNode(0.8f, 0xFF_5C_0B_0B) + }; + + public static final GradientNode[] EASY_GRAYSCALING_MAP = { + new GradientNode(0.0f, 0xFF_80_80_80), + new GradientNode(0.5f, 0xFF_AA_AA_AA), // AAAAAAaaaaaaaaaaa + new GradientNode(1.0f, 0xFF_FF_FF_FF) + }; - /** - * Do ice effect on slowed monsters + /** + * Stop the game from rendering the mount health for unfriendly creatures */ @SubscribeEvent - public void renderLivingPost(RenderLivingEvent.Post event) { - if (event.entity.getDataWatcher().getWatchableObjectInt(7) == Potion.potionTypes[Potion.moveSlowdown.getId()].getLiquidColor() && event.entity.getDataWatcher().getWatchableObjectByte(8) > 0) { - - - //System.out.println("Rendering slowed entity"); - this.renderIcedEntity(event.entity, event.renderer, event.x, event.y, event.z); + public static boolean preOverlay(RenderGameOverlayEvent.Pre event) { + if (event.getType() == RenderGameOverlayEvent.ElementType.HEALTHMOUNT) { + if (TFEventListener.isRidingUnfriendly(Minecraft.getMinecraft().player)) { + event.setCanceled(true); + return false; + } } + return true; + } + + //FIXME shove onto an external player layer, like armor + //@SubscribeEvent + //public static void renderLivingPre(RenderLivingEvent.Pre event) { + // // Shields + // if (event.getEntity().hasCapability(CapabilityList.SHIELDS, null)) { + // ShaderManager.useShader(ShaderManager.shieldShader, ShaderManager.TIME); + // } + //} + /** + * Render various effects such as an iced entity + */ + @SubscribeEvent + public static void renderLivingPost(RenderLivingEvent.Post event) { + for (RenderEffect effect : RenderEffect.VALUES) { + if (effect.shouldRender(event.getEntity(), false)) { + effect.render(event.getEntity(), event.getRenderer(), event.getX(), event.getY(), event.getZ(), event.getPartialRenderTick(), false); + } + } } - /** - * Alter FOV for our bows + /** + * Render effects in first-person perspective */ @SubscribeEvent - public void fovUpdate(FOVUpdateEvent event) { - if (event.entity.isUsingItem() && (event.entity.getItemInUse().getItem() instanceof ItemTFBowBase)) - { - int i = event.entity.getItemInUseDuration(); - float f1 = (float)i / 20.0F; - - if (f1 > 1.0F) - { - f1 = 1.0F; - } - else - { - f1 *= f1; - } - - event.newfov *= 1.0F - f1 * 0.15F; - } + public static void renderWorldLast(RenderWorldLastEvent event) { + + if (!TFConfig.firstPersonEffects) return; + + GameSettings settings = Minecraft.getMinecraft().gameSettings; + if (settings.thirdPersonView != 0 || settings.hideGUI) return; + + Entity entity = Minecraft.getMinecraft().getRenderViewEntity(); + if (entity instanceof EntityLivingBase) { + Render renderer = Minecraft.getMinecraft().getRenderManager().getEntityRenderObject(entity); + if (renderer instanceof RenderLivingBase) { + for (RenderEffect effect : RenderEffect.VALUES) { + if (effect.shouldRender((EntityLivingBase) entity, true)) { + effect.render((EntityLivingBase) entity, (RenderLivingBase) renderer, 0.0, 0.0, 0.0, event.getPartialTicks(), true); + } + } + } + } } /** - * Render an entity with the ice effect. - * This just displays a bunch of ice cubes around on their model + * On the tick, we kill the vignette */ - private void renderIcedEntity(EntityLivingBase entity, RendererLivingEntity renderer, double x, double y, double z) { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - RenderManager.instance.renderEngine.bindTexture(TextureMap.locationBlocksTexture); - - this.random.setSeed(entity.getEntityId() * entity.getEntityId() * 3121 + entity.getEntityId() * 45238971); - - // number of cubes - int numCubes = (int) (entity.height / 0.4F); - - // make cubes - for (int i = 0; i < numCubes; i++) { - GL11.glPushMatrix(); - float dx = (float)(x + random.nextGaussian() * 0.2F * entity.width); - float dy = (float)(y + random.nextGaussian() * 0.2F * entity.height) + entity.height / 2F; - float dz = (float)(z + random.nextGaussian() * 0.2F * entity.width); - GL11.glTranslatef(dx, dy, dz); - GL11.glScalef(0.5F, 0.5F, 0.5F); - GL11.glRotatef(random.nextFloat() * 360F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(random.nextFloat() * 360F, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(random.nextFloat() * 360F, 0.0F, 0.0F, 1.0F); - - RenderBlocks.getInstance().renderBlockAsItem(Blocks.ice, 0, 1.0F); - GL11.glPopMatrix(); + @SubscribeEvent + public static void renderTick(TickEvent.RenderTickEvent event) { + if (event.phase == TickEvent.Phase.START) { + Minecraft minecraft = Minecraft.getMinecraft(); + + boolean fancyGraphics = minecraft.gameSettings.fancyGraphics; + TFBlocks.twilight_leaves.setGraphicsLevel(fancyGraphics); + TFBlocks.twilight_leaves_3.setGraphicsLevel(fancyGraphics); + TFBlocks.magic_leaves.setGraphicsLevel(fancyGraphics); + + // only fire if we're in the twilight forest + if (minecraft.world != null && TFWorld.isTwilightForest(minecraft.world)) { + // vignette + if (minecraft.ingameGUI != null) { + minecraft.ingameGUI.prevVignetteBrightness = 0.0F; + } + }//*/ + + if (minecraft.player != null && TFEventListener.isRidingUnfriendly(minecraft.player)) { + if (minecraft.ingameGUI != null) { + minecraft.ingameGUI.setOverlayMessage("", false); + } + } } + } + + @SubscribeEvent + public static void clientTick(TickEvent.ClientTickEvent event) { + if (event.phase != TickEvent.Phase.END) return; + time++; - GL11.glDisable(GL11.GL_BLEND); + Minecraft mc = Minecraft.getMinecraft(); + float partial = mc.getRenderPartialTicks(); + + rotationTickerI = (rotationTickerI >= 359 ? 0 : rotationTickerI + 1); + sineTickerI = (sineTickerI >= SINE_TICKER_BOUND ? 0 : sineTickerI + 1); + + rotationTicker = rotationTickerI + partial; + sineTicker = sineTicker + partial; + + BugModelAnimationHelper.animate(); + + if (!mc.isGamePaused() && mc.world != null && mc.world.provider.getWeatherRenderer() instanceof TFWeatherRenderer) { + ((TFWeatherRenderer) mc.world.provider.getWeatherRenderer()).tick(); + } } - + + public static int time = 0; + private static int rotationTickerI = 0; + private static int sineTickerI = 0; + public static float rotationTicker = 0; + public static float sineTicker = 0; + public static final float PI = (float) Math.PI; + private static final int SINE_TICKER_BOUND = (int) ((PI * 200.0F) - 1.0F); } diff --git a/src/main/java/twilightforest/client/TFClientProxy.java b/src/main/java/twilightforest/client/TFClientProxy.java index 8b13ea5b7a..6a470d748d 100644 --- a/src/main/java/twilightforest/client/TFClientProxy.java +++ b/src/main/java/twilightforest/client/TFClientProxy.java @@ -1,574 +1,278 @@ package twilightforest.client; +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementProgress; import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.MusicTicker; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelPig; import net.minecraft.client.model.ModelSilverfish; -import net.minecraft.client.model.ModelSlime; -import net.minecraft.client.model.ModelWolf; -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.particle.EntitySmokeFX; +import net.minecraft.client.multiplayer.ClientAdvancementManager; +import net.minecraft.client.particle.Particle; import net.minecraft.client.renderer.entity.RenderSnowball; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; -import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.client.EnumHelperClient; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.client.registry.ClientRegistry; +import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.registry.GameRegistry; import twilightforest.TFCommonProxy; -import twilightforest.TFGenericPacketHandler; -import twilightforest.TwilightForestMod; -import twilightforest.block.TFBlocks; -import twilightforest.client.model.ModelTFAdherent; -import twilightforest.client.model.ModelTFArcticArmor; -import twilightforest.client.model.ModelTFBighorn; -import twilightforest.client.model.ModelTFBighornFur; -import twilightforest.client.model.ModelTFBlockGoblin; -import twilightforest.client.model.ModelTFBoar; -import twilightforest.client.model.ModelTFBunny; -import twilightforest.client.model.ModelTFDeathTome; -import twilightforest.client.model.ModelTFDeer; -import twilightforest.client.model.ModelTFFieryArmor; -import twilightforest.client.model.ModelTFFireBeetle; -import twilightforest.client.model.ModelTFGhast; -import twilightforest.client.model.ModelTFGoblinChain; -import twilightforest.client.model.ModelTFGoblinKnightLower; -import twilightforest.client.model.ModelTFGoblinKnightUpper; -import twilightforest.client.model.ModelTFHelmetCrab; -import twilightforest.client.model.ModelTFHydra; -import twilightforest.client.model.ModelTFHydraHead; -import twilightforest.client.model.ModelTFHydraNeck; -import twilightforest.client.model.ModelTFKnightPhantom2; -import twilightforest.client.model.ModelTFKnightlyArmor; -import twilightforest.client.model.ModelTFKobold; -import twilightforest.client.model.ModelTFLich; -import twilightforest.client.model.ModelTFLichMinion; -import twilightforest.client.model.ModelTFLoyalZombie; -import twilightforest.client.model.ModelTFMinoshroom; -import twilightforest.client.model.ModelTFMinotaur; -import twilightforest.client.model.ModelTFMosquitoSwarm; -import twilightforest.client.model.ModelTFNaga; -import twilightforest.client.model.ModelTFPenguin; -import twilightforest.client.model.ModelTFPhantomArmor; -import twilightforest.client.model.ModelTFPinchBeetle; -import twilightforest.client.model.ModelTFRaven; -import twilightforest.client.model.ModelTFRedcap; -import twilightforest.client.model.ModelTFSkeletonDruid; -import twilightforest.client.model.ModelTFSlimeBeetle; -import twilightforest.client.model.ModelTFSpikeBlock; -import twilightforest.client.model.ModelTFSquirrel; -import twilightforest.client.model.ModelTFTinyBird; -import twilightforest.client.model.ModelTFTowerBoss; -import twilightforest.client.model.ModelTFTowerGolem; -import twilightforest.client.model.ModelTFTroll; -import twilightforest.client.model.ModelTFWraith; -import twilightforest.client.model.ModelTFYeti; -import twilightforest.client.model.ModelTFYetiAlpha; -import twilightforest.client.model.ModelTFYetiArmor; -import twilightforest.client.particle.EntityTFAnnihilateFX; -import twilightforest.client.particle.EntityTFBossTearFX; -import twilightforest.client.particle.EntityTFGhastTrapFX; -import twilightforest.client.particle.EntityTFIceBeamFX; -import twilightforest.client.particle.EntityTFLargeFlameFX; -import twilightforest.client.particle.EntityTFLeafRuneFX; -import twilightforest.client.particle.EntityTFProtectionFX; -import twilightforest.client.particle.EntityTFSnowFX; -import twilightforest.client.particle.EntityTFSnowGuardianFX; -import twilightforest.client.particle.EntityTFSnowWarningFX; -import twilightforest.client.renderer.TFFieryItemRenderer; -import twilightforest.client.renderer.TFGiantBlockRenderer; -import twilightforest.client.renderer.TFGiantItemRenderer; -import twilightforest.client.renderer.TFIceItemRenderer; -import twilightforest.client.renderer.TFMagicMapRenderer; -import twilightforest.client.renderer.TFMazeMapRenderer; -import twilightforest.client.renderer.TileEntityTFCicadaRenderer; -import twilightforest.client.renderer.TileEntityTFFireflyRenderer; -import twilightforest.client.renderer.TileEntityTFMoonwormRenderer; -import twilightforest.client.renderer.TileEntityTFTrophyRenderer; -import twilightforest.client.renderer.blocks.RenderBlockTFCastleMagic; -import twilightforest.client.renderer.blocks.RenderBlockTFCritters; -import twilightforest.client.renderer.blocks.RenderBlockTFFireflyJar; -import twilightforest.client.renderer.blocks.RenderBlockTFHugeLilyPad; -import twilightforest.client.renderer.blocks.RenderBlockTFKnightMetal; -import twilightforest.client.renderer.blocks.RenderBlockTFMagicLeaves; -import twilightforest.client.renderer.blocks.RenderBlockTFNagastone; -import twilightforest.client.renderer.blocks.RenderBlockTFPedestal; -import twilightforest.client.renderer.blocks.RenderBlockTFPlants; -import twilightforest.client.renderer.blocks.RenderBlockTFThorns; -import twilightforest.client.renderer.entity.RenderTFAdherent; -import twilightforest.client.renderer.entity.RenderTFHarbingerCube; -import twilightforest.client.renderer.entity.RenderTFBighorn; -import twilightforest.client.renderer.entity.RenderTFBiped; -import twilightforest.client.renderer.entity.RenderTFBird; -import twilightforest.client.renderer.entity.RenderTFBlockGoblin; -import twilightforest.client.renderer.entity.RenderTFBoar; -import twilightforest.client.renderer.entity.RenderTFBunny; -import twilightforest.client.renderer.entity.RenderTFChainBlock; -import twilightforest.client.renderer.entity.RenderTFCharm; -import twilightforest.client.renderer.entity.RenderTFCubeOfAnnihilation; -import twilightforest.client.renderer.entity.RenderTFDeer; -import twilightforest.client.renderer.entity.RenderTFFallingIce; -import twilightforest.client.renderer.entity.RenderTFGenericLiving; -import twilightforest.client.renderer.entity.RenderTFGiant; -import twilightforest.client.renderer.entity.RenderTFGoblinKnightUpper; -import twilightforest.client.renderer.entity.RenderTFHedgeSpider; -import twilightforest.client.renderer.entity.RenderTFHydra; -import twilightforest.client.renderer.entity.RenderTFHydraHead; -import twilightforest.client.renderer.entity.RenderTFHydraMortar; -import twilightforest.client.renderer.entity.RenderTFIceExploder; -import twilightforest.client.renderer.entity.RenderTFIceShooter; -import twilightforest.client.renderer.entity.RenderTFIceCrystal; -import twilightforest.client.renderer.entity.RenderTFKingSpider; -import twilightforest.client.renderer.entity.RenderTFKnightPhantom; -import twilightforest.client.renderer.entity.RenderTFKobold; -import twilightforest.client.renderer.entity.RenderTFLich; -import twilightforest.client.renderer.entity.RenderTFMazeSlime; -import twilightforest.client.renderer.entity.RenderTFMiniGhast; -import twilightforest.client.renderer.entity.RenderTFMinoshroom; -import twilightforest.client.renderer.entity.RenderTFMistWolf; -import twilightforest.client.renderer.entity.RenderTFMoonwormShot; -import twilightforest.client.renderer.entity.RenderTFNaga; -import twilightforest.client.renderer.entity.RenderTFNagaSegment; -import twilightforest.client.renderer.entity.RenderTFProtectionBox; -import twilightforest.client.renderer.entity.RenderTFQuestRam; -import twilightforest.client.renderer.entity.RenderTFRovingCube; -import twilightforest.client.renderer.entity.RenderTFSlideBlock; -import twilightforest.client.renderer.entity.RenderTFSlimeBeetle; -import twilightforest.client.renderer.entity.RenderTFSnowGuardian; -import twilightforest.client.renderer.entity.RenderTFSnowQueen; -import twilightforest.client.renderer.entity.RenderTFSnowQueenIceShield; -import twilightforest.client.renderer.entity.RenderTFSpikeBlock; -import twilightforest.client.renderer.entity.RenderTFSwarmSpider; -import twilightforest.client.renderer.entity.RenderTFThrownAxe; -import twilightforest.client.renderer.entity.RenderTFThrownIce; -import twilightforest.client.renderer.entity.RenderTFTinyBird; -import twilightforest.client.renderer.entity.RenderTFTinyFirefly; -import twilightforest.client.renderer.entity.RenderTFTowerBroodling; -import twilightforest.client.renderer.entity.RenderTFTowerGhast; -import twilightforest.client.renderer.entity.RenderTFTowerGolem; -import twilightforest.client.renderer.entity.RenderTFUrGhast; -import twilightforest.client.renderer.entity.RenderTFWinterWolf; -import twilightforest.client.renderer.entity.RenderTFWraith; -import twilightforest.client.renderer.entity.RenderTFYeti; -import twilightforest.entity.EntityTFCubeOfAnnihilation; -import twilightforest.item.TFItems; -import twilightforest.tileentity.TileEntityTFCicada; -import twilightforest.tileentity.TileEntityTFFirefly; -import twilightforest.tileentity.TileEntityTFMoonworm; +import twilightforest.TFSounds; +import twilightforest.client.model.armor.*; +import twilightforest.client.model.entity.*; +import twilightforest.client.model.entity.finalcastle.ModelTFCastleGuardian; +import twilightforest.client.particle.TFParticleFactory; +import twilightforest.client.particle.TFParticleType; +import twilightforest.client.renderer.entity.*; +import twilightforest.client.renderer.tileentity.*; +import twilightforest.client.shader.ShaderManager; +import twilightforest.compat.TFCompat; +import twilightforest.entity.*; +import twilightforest.entity.boss.*; +import twilightforest.entity.finalcastle.EntityTFCastleGuardian; +import twilightforest.entity.passive.*; import twilightforest.tileentity.TileEntityTFTrophy; -import cpw.mods.fml.client.FMLClientHandler; -import cpw.mods.fml.client.registry.ClientRegistry; -import cpw.mods.fml.client.registry.RenderingRegistry; -import cpw.mods.fml.common.FMLCommonHandler; +import twilightforest.tileentity.critters.*; + +import java.util.EnumMap; +import java.util.Map; public class TFClientProxy extends TFCommonProxy { - int critterRenderID; - int plantRenderID; - int blockComplexRenderID; - int nagastoneRenderID; - int magicLeavesRenderID; - int pedestalRenderID; - int thornsRenderID; - int knightmetalBlockRenderID; - int hugeLilyPadBlockRenderID; - int castleMagicBlockRenderID; - - ModelBiped[] knightlyArmorModel; - ModelBiped[] phantomArmorModel; - ModelBiped[] yetiArmorModel; - ModelBiped[] arcticArmorModel; - ModelBiped[] fieryArmorModel; - - TFClientTicker clientTicker; - TFClientEvents clientEvents; - - boolean isDangerOverlayShown; - /** - * Called during mod pre-load. We need to register our sound thing here so that it can catch the SoundLoadEvent during loading. - */ - @Override - public void doPreLoadRegistration() { - // sounds - //MinecraftForge.EVENT_BUS.register(new TFSounds()); + private final Map knightlyArmorModel = new EnumMap<>(EntityEquipmentSlot.class); + private final Map phantomArmorModel = new EnumMap<>(EntityEquipmentSlot.class); + private final Map yetiArmorModel = new EnumMap<>(EntityEquipmentSlot.class); + private final Map arcticArmorModel = new EnumMap<>(EntityEquipmentSlot.class); + private final Map fieryArmorModel = new EnumMap<>(EntityEquipmentSlot.class); - } + private boolean isDangerOverlayShown; + + public static MusicTicker.MusicType TFMUSICTYPE; - /** - * Called during mod loading. Registers renderers and stuff - */ @Override - public void doOnLoadRegistration() { - Minecraft mc = FMLClientHandler.instance().getClient(); - - // client tick listener - clientTicker = new TFClientTicker(); - FMLCommonHandler.instance().bus().register(clientTicker); - - // client events - clientEvents = new TFClientEvents(); - MinecraftForge.EVENT_BUS.register(clientEvents); - - // packet listener - TFGenericPacketHandler genericPacketHandler = new TFGenericPacketHandler(); - TwilightForestMod.genericChannel.register(genericPacketHandler); - - // entity renderers - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFBoar.class, new RenderTFBoar(new ModelTFBoar(), new ModelPig(0.5F), 0.7F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFBighorn.class, new RenderTFBighorn(new ModelTFBighorn(), new ModelTFBighornFur(), 0.7F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFDeer.class, new RenderTFDeer(new ModelTFDeer(), 0.7F)); - - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFRedcap.class, new RenderTFBiped(new ModelTFRedcap(), 0.625F, "redcap.png")); -// RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFNagaOld.class, new RenderTFNaga(new ModelTFNaga(), 0.625F)); -// RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFNagaSegmentOld.class, new RenderTFNaga(new ModelTFNaga(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFTinyFirefly.class, new RenderTFTinyFirefly()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFSkeletonDruid.class, new RenderTFBiped(new ModelTFSkeletonDruid(), 0.5F, "skeletondruid.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFWraith.class, new RenderTFWraith(new ModelTFWraith(), 0.5F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFHydra.class, new RenderTFHydra(new ModelTFHydra(), 1.0F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFLich.class, new RenderTFLich(new ModelTFLich(), 1.0F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFPenguin.class, new RenderTFBird(new ModelTFPenguin(), 1.0F, "penguin.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFLichMinion.class, new RenderTFBiped(new ModelTFLichMinion(), 1.0F, "textures/entity/zombie/zombie.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFLoyalZombie.class, new RenderTFBiped(new ModelTFLoyalZombie(), 1.0F, "textures/entity/zombie/zombie.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFTinyBird.class, new RenderTFTinyBird(new ModelTFTinyBird(), 1.0F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFSquirrel.class, new RenderTFGenericLiving(new ModelTFSquirrel(), 1.0F, "squirrel2.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFBunny.class, new RenderTFBunny(new ModelTFBunny(), 1.0F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFRaven.class, new RenderTFBird(new ModelTFRaven(), 1.0F, "raven.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFQuestRam.class, new RenderTFQuestRam()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFKobold.class, new RenderTFKobold(new ModelTFKobold(), 0.625F, "kobold.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFBoggard.class, new RenderTFBiped(new ModelTFLoyalZombie(), 0.625F, "kobold.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFMosquitoSwarm.class, new RenderTFGenericLiving(new ModelTFMosquitoSwarm(), 0.625F, "mosquitoswarm.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFDeathTome.class, new RenderTFGenericLiving(new ModelTFDeathTome(), 0.625F, "textures/entity/enchanting_table_book.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFMinotaur.class, new RenderTFBiped(new ModelTFMinotaur(), 0.625F, "minotaur.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFMinoshroom.class, new RenderTFMinoshroom(new ModelTFMinoshroom(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFFireBeetle.class, new RenderTFGenericLiving(new ModelTFFireBeetle(), 0.625F, "firebeetle.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFSlimeBeetle.class, new RenderTFSlimeBeetle(new ModelTFSlimeBeetle(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFPinchBeetle.class, new RenderTFGenericLiving(new ModelTFPinchBeetle(), 0.625F, "pinchbeetle.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFMistWolf.class, new RenderTFMistWolf(new ModelWolf(), new ModelWolf(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.passive.EntityTFMobileFirefly.class, new RenderTFTinyFirefly()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFMiniGhast.class, new RenderTFMiniGhast(new ModelTFGhast(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFTowerGolem.class, new RenderTFTowerGolem(new ModelTFTowerGolem(), 0.5F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFTowerTermite.class, new RenderTFGenericLiving(new ModelSilverfish(), 0.3F, "towertermite.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFTowerGhast.class, new RenderTFTowerGhast(new ModelTFGhast(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFUrGhast.class, new RenderTFUrGhast(new ModelTFTowerBoss(), 0.625F, 24F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFBlockGoblin.class, new RenderTFBlockGoblin(new ModelTFBlockGoblin(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFGoblinChain.class, new RenderTFSpikeBlock(new ModelTFGoblinChain(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFSpikeBlock.class, new RenderTFSpikeBlock(new ModelTFSpikeBlock(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFGoblinKnightUpper.class, new RenderTFGoblinKnightUpper(new ModelTFGoblinKnightUpper(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFGoblinKnightLower.class, new RenderTFBiped(new ModelTFGoblinKnightLower(), 0.625F, "doublegoblin.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFHelmetCrab.class, new RenderTFGenericLiving(new ModelTFHelmetCrab(), 0.625F, "helmetcrab.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFKnightPhantom.class, new RenderTFKnightPhantom(new ModelTFKnightPhantom2(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFNaga.class, new RenderTFNaga(new ModelTFNaga(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFNagaSegment.class, new RenderTFNagaSegment(new ModelTFNaga(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFSwarmSpider.class, new RenderTFSwarmSpider()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFKingSpider.class, new RenderTFKingSpider()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFTowerBroodling.class, new RenderTFTowerBroodling()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFHedgeSpider.class, new RenderTFHedgeSpider()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFRedcapSapper.class, new RenderTFBiped(new ModelTFRedcap(), 0.625F, "redcapsapper.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFMazeSlime.class, new RenderTFMazeSlime(new ModelSlime(16), new ModelSlime(0), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFYeti.class, new RenderTFYeti(new ModelTFYeti(), 0.625F, "yeti2.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFProtectionBox.class, new RenderTFProtectionBox()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFYetiAlpha.class, new RenderTFYeti(new ModelTFYetiAlpha(), 0.625F, "yetialpha.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFWinterWolf.class, new RenderTFWinterWolf(new ModelWolf(), new ModelWolf(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFSnowGuardian.class, new RenderTFSnowGuardian()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFIceShooter.class, new RenderTFIceShooter()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFIceExploder.class, new RenderTFIceExploder()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFSnowQueen.class, new RenderTFSnowQueen()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFSnowQueenIceShield.class, new RenderTFSnowQueenIceShield()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFTroll.class, new RenderTFBiped(new ModelTFTroll(), 0.625F, "troll.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFGiantMiner.class, new RenderTFGiant()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFIceCrystal.class, new RenderTFIceCrystal()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFChainBlock.class, new RenderTFChainBlock(new ModelTFSpikeBlock(), 0.625F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFCubeOfAnnihilation.class, new RenderTFCubeOfAnnihilation()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFHarbingerCube.class, new RenderTFHarbingerCube()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFAdherent.class, new RenderTFAdherent(new ModelTFAdherent(), 0.625F, "adherent.png")); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFRovingCube.class, new RenderTFRovingCube()); + public void preInit() { + RenderingRegistry.registerEntityRenderingHandler(EntityTFBoar.class, m -> new RenderTFBoar(m, new ModelTFBoar())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFBighorn.class, m -> new RenderTFBighorn(m, new ModelTFBighorn(), new ModelTFBighornFur(), 0.7F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFDeer.class, m -> new RenderTFDeer(m, new ModelTFDeer(), 0.7F)); + + RenderingRegistry.registerEntityRenderingHandler(EntityTFRedcap.class, m -> new RenderTFBiped<>(m, new ModelTFRedcap(), 0.4F, "redcap.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSkeletonDruid.class, m -> new RenderTFBiped<>(m, new ModelTFSkeletonDruid(), 0.5F, "skeletondruid.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFWraith.class, m -> new RenderTFWraith(m, new ModelTFWraith(), 0.5F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFHydra.class, m -> new RenderTFHydra(m, new ModelTFHydra(), 4.0F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFLich.class, m -> new RenderTFLich(m, new ModelTFLich(), 0.6F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFPenguin.class, m -> new RenderTFBird(m, new ModelTFPenguin(), 0.375F, "penguin.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFLichMinion.class, m -> new RenderTFBiped<>(m, new ModelTFLichMinion(), 0.5F, "textures/entity/zombie/zombie.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFLoyalZombie.class, m -> new RenderTFBiped<>(m, new ModelTFLoyalZombie(), 0.5F, "textures/entity/zombie/zombie.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTinyBird.class, m -> new RenderTFTinyBird(m, new ModelTFTinyBird(), 1.0F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSquirrel.class, m -> new RenderTFGenericLiving<>(m, new ModelTFSquirrel(), 1.0F, "squirrel2.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFBunny.class, m -> new RenderTFBunny(m, new ModelTFBunny(), 1.0F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFRaven.class, m -> new RenderTFBird(m, new ModelTFRaven(), 1.0F, "raven.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFQuestRam.class, RenderTFQuestRam::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFKobold.class, m -> new RenderTFKobold(m, new ModelTFKobold(), 0.4F, "kobold.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFBoggard.class, m -> new RenderTFBiped<>(m, new ModelTFLoyalZombie(), 0.625F, "kobold.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMosquitoSwarm.class, m -> new RenderTFGenericLiving<>(m, new ModelTFMosquitoSwarm(), 0.0F, "mosquitoswarm.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFDeathTome.class, m -> new RenderTFGenericLiving<>(m, new ModelTFDeathTome(), 0.3F, "textures/entity/enchanting_table_book.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMinotaur.class, m -> new RenderTFBiped<>(m, new ModelTFMinotaur(), 0.625F, "minotaur.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMinoshroom.class, m -> new RenderTFMinoshroom(m, new ModelTFMinoshroom(), 0.625F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFFireBeetle.class, m -> new RenderTFGenericLiving<>(m, new ModelTFFireBeetle(), 0.8F, "firebeetle.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSlimeBeetle.class, m -> new RenderTFSlimeBeetle(m, new ModelTFSlimeBeetle(), 0.6F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFPinchBeetle.class, m -> new RenderTFGenericLiving<>(m, new ModelTFPinchBeetle(), 0.6F, "pinchbeetle.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMistWolf.class, RenderTFMistWolf::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMobileFirefly.class, RenderTFMobileFirefly::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMiniGhast.class, m -> new RenderTFGhast<>(m, new ModelTFGhast(), 0.625F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTowerGolem.class, m -> new RenderTFTowerGolem(m, new ModelTFTowerGolem(), 0.75F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTowerTermite.class, m -> new RenderTFGenericLiving<>(m, new ModelSilverfish(), 0.3F, "towertermite.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTowerGhast.class, m -> new RenderTFTowerGhast(m, new ModelTFGhast(), 3.0F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFUrGhast.class, m -> new RenderTFUrGhast(m, new ModelTFTowerBoss(), 8.0F, 24F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFBlockGoblin.class, m -> new RenderTFBlockGoblin(m, new ModelTFBlockGoblin(), 0.4F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFGoblinChain.class, m -> new RenderTFSpikeBlock(m, new ModelTFGoblinChain())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSpikeBlock.class, m -> new RenderTFSpikeBlock(m, new ModelTFSpikeBlock())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFGoblinKnightUpper.class, m -> new RenderTFGoblinKnightUpper(m, new ModelTFGoblinKnightUpper(), 0.625F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFGoblinKnightLower.class, m -> new RenderTFBiped<>(m, new ModelTFGoblinKnightLower(), 0.625F, "doublegoblin.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFHelmetCrab.class, m -> new RenderTFGenericLiving<>(m, new ModelTFHelmetCrab(), 0.625F, "helmetcrab.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFKnightPhantom.class, m -> new RenderTFKnightPhantom(m, new ModelTFKnightPhantom2(), 0.625F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFNaga.class, m -> new RenderTFNaga(m, new ModelTFNaga(), 1.45F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFNagaSegment.class, m -> new RenderTFNagaSegment(m, new ModelTFNaga())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSwarmSpider.class, RenderTFSwarmSpider::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFKingSpider.class, RenderTFKingSpider::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTowerBroodling.class, RenderTFTowerBroodling::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFHedgeSpider.class, RenderTFHedgeSpider::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFRedcapSapper.class, m -> new RenderTFBiped<>(m, new ModelTFRedcap(), 0.4F, "redcapsapper.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMazeSlime.class, m -> new RenderTFMazeSlime(m, 0.625F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFYeti.class, m -> new RenderTFYeti(m, new ModelTFYeti(), 0.625F, "yeti2.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFProtectionBox.class, RenderTFProtectionBox::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFYetiAlpha.class, m -> new RenderTFYeti(m, new ModelTFYetiAlpha(), 1.75F, "yetialpha.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFWinterWolf.class, RenderTFWinterWolf::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSnowGuardian.class, RenderTFSnowGuardian::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFIceShooter.class, RenderTFIceShooter::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFIceExploder.class, RenderTFIceExploder::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSnowQueen.class, RenderTFSnowQueen::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSnowQueenIceShield.class, RenderTFSnowQueenIceShield::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTroll.class, m -> new RenderTFBiped<>(m, new ModelTFTroll(), 0.625F, "troll.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFGiantMiner.class, RenderTFGiant::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFIceCrystal.class, RenderTFIceCrystal::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFChainBlock.class, m -> new RenderTFChainBlock(m, new ModelTFSpikeBlock())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFCubeOfAnnihilation.class, RenderTFCubeOfAnnihilation::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFHarbingerCube.class, RenderTFHarbingerCube::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFAdherent.class, m -> new RenderTFAdherent(m, new ModelTFAdherent(), 0.625F, "adherent.png")); + RenderingRegistry.registerEntityRenderingHandler(EntityTFRovingCube.class, RenderTFRovingCube::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFRisingZombie.class, m -> new RenderTFBiped<>(m, new ModelTFRisingZombie(), 0.5F, "textures/entity/zombie/zombie.png")); + + RenderingRegistry.registerEntityRenderingHandler(EntityTFCastleGuardian.class, m -> new RenderTFCastleGuardian(m, new ModelTFCastleGuardian(), 2.0F, "finalcastle/castle_guardian.png")); // projectiles - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFNatureBolt.class, new RenderSnowball(Items.wheat_seeds)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFLichBolt.class, new RenderSnowball(Items.ender_pearl)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFTwilightWandBolt.class, new RenderSnowball(Items.ender_pearl)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFTomeBolt.class, new RenderSnowball(Items.paper)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFHydraMortar.class, new RenderTFHydraMortar()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFSlimeProjectile.class, new RenderSnowball(Items.slime_ball)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFMoonwormShot.class, new RenderTFMoonwormShot()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFCharmEffect.class, new RenderTFCharm(TFItems.charmOfLife1.getIconFromDamage(0))); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFLichBomb.class, new RenderSnowball(Items.magma_cream)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFThrownAxe.class, new RenderTFThrownAxe(TFItems.knightlyAxe)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFThrownPick.class, new RenderTFThrownAxe(TFItems.knightlyPick)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFFallingIce.class, new RenderTFFallingIce()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFIceBomb.class, new RenderTFThrownIce()); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFIceSnowball.class, new RenderSnowball(Items.snowball)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.EntityTFSlideBlock.class, new RenderTFSlideBlock()); - + RenderingRegistry.registerEntityRenderingHandler(EntityTFNatureBolt.class, m -> new RenderSnowball<>(m, Items.WHEAT_SEEDS, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFLichBolt.class, m -> new RenderSnowball<>(m, Items.ENDER_PEARL, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTwilightWandBolt.class, m -> new RenderSnowball<>(m, Items.ENDER_PEARL, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFTomeBolt.class, m -> new RenderSnowball<>(m, Items.PAPER, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFHydraMortar.class, RenderTFHydraMortar::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSlimeProjectile.class, m -> new RenderSnowball<>(m, Items.SLIME_BALL, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFMoonwormShot.class, RenderTFMoonwormShot::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFCharmEffect.class, m -> new RenderTFCharm(m, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFLichBomb.class, m -> new RenderSnowball<>(m, Items.MAGMA_CREAM, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFThrownWep.class, RenderTFThrownWep::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFFallingIce.class, RenderTFFallingIce::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFIceBomb.class, RenderTFThrownIce::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTFIceSnowball.class, m -> new RenderSnowball<>(m, Items.SNOWBALL, Minecraft.getMinecraft().getRenderItem())); + RenderingRegistry.registerEntityRenderingHandler(EntityTFSlideBlock.class, RenderTFSlideBlock::new); + RenderingRegistry.registerEntityRenderingHandler(EntitySeekerArrow.class, RenderDefaultArrow::new); + RenderingRegistry.registerEntityRenderingHandler(EntityIceArrow.class, RenderDefaultArrow::new); + // I guess the hydra gets its own section - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFHydraHead.class, new RenderTFHydraHead(new ModelTFHydraHead(), 1.0F)); - RenderingRegistry.registerEntityRenderingHandler(twilightforest.entity.boss.EntityTFHydraNeck.class, new RenderTFGenericLiving(new ModelTFHydraNeck(), 1.0F, "hydra4.png")); - - // animated textures -// TextureFXManager.instance().addAnimation(new TextureTFMagicLeavesFX(mc, BlockTFMagicLeaves.SPR_TIMELEAVES, BlockTFMagicLeaves.SPR_TIMEFX)); -// TextureFXManager.instance().addAnimation(new TextureTFMagicLeavesFX(mc, BlockTFMagicLeaves.SPR_TRANSLEAVES, BlockTFMagicLeaves.SPR_TRANSFX)); -// TextureFXManager.instance().addAnimation(new TextureTFMagicLeavesFX(mc, BlockTFMagicLeaves.SPR_SORTLEAVES, BlockTFMagicLeaves.SPR_SORTFX)); - + RenderingRegistry.registerEntityRenderingHandler(EntityTFHydraHead.class, m -> new RenderTFHydraHead(m, new ModelTFHydraHead(), 1.0F)); + RenderingRegistry.registerEntityRenderingHandler(EntityTFHydraNeck.class, m -> new RenderTFGenericLiving<>(m, new ModelTFHydraNeck(), 1.0F, "hydra4.png")); + } + + @Override + public void init() { + + MinecraftForge.EVENT_BUS.register(new LoadingScreenListener()); + // tile entities - ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFFirefly.class, new TileEntityTFFireflyRenderer()); - ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFCicada.class, new TileEntityTFCicadaRenderer()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFFireflyTicking.class, new TileEntityTFFireflyRenderer()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFCicadaTicking.class, new TileEntityTFCicadaRenderer()); // ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFNagaSpawner.class, new TileEntityMobSpawnerRenderer()); // ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFLichSpawner.class, new TileEntityMobSpawnerRenderer()); // ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFHydraSpawner.class, new TileEntityMobSpawnerRenderer()); - ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFMoonworm.class, new TileEntityTFMoonwormRenderer()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFMoonwormTicking.class, new TileEntityTFMoonwormRenderer()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFTrophy.class, new TileEntityTFTrophyRenderer()); - - // map item renderer - MinecraftForgeClient.registerItemRenderer(TFItems.magicMap, new TFMagicMapRenderer(mc.gameSettings, mc.getTextureManager())); - TFMazeMapRenderer mazeRenderer = new TFMazeMapRenderer(mc.gameSettings, mc.getTextureManager()); - MinecraftForgeClient.registerItemRenderer(TFItems.mazeMap, mazeRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.oreMap, mazeRenderer); - - // giant item renderers - TFGiantItemRenderer giantRenderer = new TFGiantItemRenderer(mc.gameSettings, mc.getTextureManager()); - MinecraftForgeClient.registerItemRenderer(TFItems.giantPick, giantRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.giantSword, giantRenderer); - - TFGiantBlockRenderer giantBlockRenderer = new TFGiantBlockRenderer(mc.gameSettings, mc.getTextureManager()); - MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(TFBlocks.giantLeaves), giantBlockRenderer); - MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(TFBlocks.giantCobble), giantBlockRenderer); - MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(TFBlocks.giantLog), giantBlockRenderer); - MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(TFBlocks.giantObsidian), giantBlockRenderer); - - // fiery item render - TFFieryItemRenderer fieryRenderer = new TFFieryItemRenderer(mc.gameSettings, mc.getTextureManager()); - MinecraftForgeClient.registerItemRenderer(TFItems.fieryPick, fieryRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.fierySword, fieryRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.fieryIngot, fieryRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.fieryHelm, fieryRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.fieryPlate, fieryRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.fieryLegs, fieryRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.fieryBoots, fieryRenderer); - - // ice item renderers - TFIceItemRenderer iceRenderer = new TFIceItemRenderer(mc.gameSettings, mc.getTextureManager()); - MinecraftForgeClient.registerItemRenderer(TFItems.iceSword, iceRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.glassSword, iceRenderer); - MinecraftForgeClient.registerItemRenderer(TFItems.iceBow, iceRenderer); - - - // block render ids - blockComplexRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFFireflyJar(blockComplexRenderID)); - - plantRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFPlants(plantRenderID)); - - critterRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFCritters(critterRenderID)); - - nagastoneRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFNagastone(nagastoneRenderID)); - - magicLeavesRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFMagicLeaves(magicLeavesRenderID)); - - pedestalRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFPedestal(pedestalRenderID)); - - thornsRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFThorns(thornsRenderID)); - - knightmetalBlockRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFKnightMetal(knightmetalBlockRenderID)); - - hugeLilyPadBlockRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFHugeLilyPad(hugeLilyPadBlockRenderID)); - - castleMagicBlockRenderID = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(new RenderBlockTFCastleMagic(castleMagicBlockRenderID)); - - // armor model - knightlyArmorModel = new ModelBiped[4]; - knightlyArmorModel[0] = new ModelTFKnightlyArmor(0, 0.5F); - knightlyArmorModel[1] = new ModelTFKnightlyArmor(1, 1.0F); - knightlyArmorModel[2] = new ModelTFKnightlyArmor(2, 0.5F); - knightlyArmorModel[3] = new ModelTFKnightlyArmor(3, 0.5F); - - phantomArmorModel = new ModelBiped[2]; - phantomArmorModel[0] = new ModelTFPhantomArmor(0, 0.5F); - phantomArmorModel[1] = new ModelTFPhantomArmor(1, 1.0F); - - yetiArmorModel = new ModelBiped[4]; - yetiArmorModel[0] = new ModelTFYetiArmor(0, 0.6F); - yetiArmorModel[1] = new ModelTFYetiArmor(1, 1.0F); - yetiArmorModel[2] = new ModelTFYetiArmor(2, 0.4F); - yetiArmorModel[3] = new ModelTFYetiArmor(3, 0.55F); - - arcticArmorModel = new ModelBiped[4]; - arcticArmorModel[0] = new ModelTFArcticArmor(0, 0.6F); - arcticArmorModel[1] = new ModelTFArcticArmor(1, 1.0F); - arcticArmorModel[2] = new ModelTFArcticArmor(2, 0.4F); - arcticArmorModel[3] = new ModelTFArcticArmor(3, 0.55F); - - fieryArmorModel = new ModelBiped[4]; - fieryArmorModel[0] = new ModelTFFieryArmor(0, 0.5F); - fieryArmorModel[1] = new ModelTFFieryArmor(1, 1.0F); - fieryArmorModel[2] = new ModelTFFieryArmor(2, 0.5F); - fieryArmorModel[3] = new ModelTFFieryArmor(3, 0.5F); + knightlyArmorModel.put(EntityEquipmentSlot.HEAD, new ModelTFKnightlyArmor(0.5F)); + knightlyArmorModel.put(EntityEquipmentSlot.CHEST, new ModelTFKnightlyArmor(1.0F)); + knightlyArmorModel.put(EntityEquipmentSlot.LEGS, new ModelTFKnightlyArmor(0.5F)); + knightlyArmorModel.put(EntityEquipmentSlot.FEET, new ModelTFKnightlyArmor(0.5F)); + phantomArmorModel.put(EntityEquipmentSlot.HEAD, new ModelTFPhantomArmor(EntityEquipmentSlot.HEAD, 0.5F)); + phantomArmorModel.put(EntityEquipmentSlot.CHEST, new ModelTFPhantomArmor(EntityEquipmentSlot.CHEST, 0.5F)); - } - - public int getCritterBlockRenderID() { - return critterRenderID; - } + yetiArmorModel.put(EntityEquipmentSlot.HEAD, new ModelTFYetiArmor(EntityEquipmentSlot.HEAD, 0.6F)); + yetiArmorModel.put(EntityEquipmentSlot.CHEST, new ModelTFYetiArmor(EntityEquipmentSlot.CHEST, 1.0F)); + yetiArmorModel.put(EntityEquipmentSlot.LEGS, new ModelTFYetiArmor(EntityEquipmentSlot.LEGS, 0.4F)); + yetiArmorModel.put(EntityEquipmentSlot.FEET, new ModelTFYetiArmor(EntityEquipmentSlot.FEET, 0.55F)); - public int getPlantBlockRenderID() { - return plantRenderID; - } + arcticArmorModel.put(EntityEquipmentSlot.HEAD, new ModelTFArcticArmor(0.6F)); + arcticArmorModel.put(EntityEquipmentSlot.CHEST, new ModelTFArcticArmor(1.0F)); + arcticArmorModel.put(EntityEquipmentSlot.LEGS, new ModelTFArcticArmor(0.4F)); + arcticArmorModel.put(EntityEquipmentSlot.FEET, new ModelTFArcticArmor(0.55F)); - public int getComplexBlockRenderID() { - return blockComplexRenderID; - } - - public int getNagastoneBlockRenderID() { - return nagastoneRenderID; - } - - public int getMagicLeavesBlockRenderID() { - return magicLeavesRenderID; - } - - public int getPedestalBlockRenderID() { - return pedestalRenderID; - } - - public int getThornsBlockRenderID() { - return thornsRenderID; - } - - public int getKnightmetalBlockRenderID() { - return knightmetalBlockRenderID; - } - - public int getHugeLilyPadBlockRenderID() { - return hugeLilyPadBlockRenderID; - } - - public int getCastleMagicBlockRenderID() { - return castleMagicBlockRenderID; - } - - /** - * The prefix is not actually used, but we do need a render ID - */ - public int registerArmorRenderID(String prefix) { - return RenderingRegistry.addNewArmourRendererPrefix(prefix); + fieryArmorModel.put(EntityEquipmentSlot.HEAD, new ModelTFFieryArmor(0.5F)); + fieryArmorModel.put(EntityEquipmentSlot.CHEST, new ModelTFFieryArmor(1.0F)); + fieryArmorModel.put(EntityEquipmentSlot.LEGS, new ModelTFFieryArmor(0.5F)); + fieryArmorModel.put(EntityEquipmentSlot.FEET, new ModelTFFieryArmor(0.5F)); + + TFMUSICTYPE = EnumHelperClient.addMusicType("TFMUSIC", TFSounds.MUSIC, 1200, 12000); + + ShaderManager.initShaders(); + + ClientCommandHandler.instance.registerCommand(new CommandBase() { + @Override + public String getName() { + return "tfreload"; + } + + @Override + public String getUsage(ICommandSender sender) { + return "commands.tffeature.reload"; + } + + @Override + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + if(FMLCommonHandler.instance().getEffectiveSide().isClient()) { + Minecraft.getMinecraft().player.sendMessage(new TextComponentString("Reloading Twilight Forest Shaders!")); + twilightforest.client.shader.ShaderManager.getShaderReloadListener().onResourceManagerReload(net.minecraft.client.Minecraft.getMinecraft().getResourceManager()); + if (TFCompat.IMMERSIVEENGINEERING.isActivated()) + twilightforest.compat.ie.IEShaderRegister.initShaders(); + } + } + }); } + // [VanillaCopy] adapted from RenderGlobal.spawnParticle @Override - public World getClientWorld() { - return FMLClientHandler.instance().getClient().theWorld; - } - - - /** - * Spawns a particle. This is my copy of RenderGlobal.spawnParticle where I implement custom particles. - */ - public void spawnParticle(World world, String particleType, double x, double y, double z, double velX, double velY, double velZ) - { - Minecraft mc = FMLClientHandler.instance().getClient(); - if (mc != null && mc.renderViewEntity != null && mc.effectRenderer != null && mc.theWorld == world) - { - // TODO: check render settings? - double distX = mc.renderViewEntity.posX - x; - double distY = mc.renderViewEntity.posY - y; - double distZ = mc.renderViewEntity.posZ - z; - - EntityFX particle = null; - - double maxDist = 64.0D; // normally 16.0D - - // check for particle max distance - if (distX * distX + distY * distY + distZ * distZ < maxDist * maxDist) - { - - if (particleType.equals("largeflame")) - { - particle = new EntityTFLargeFlameFX(world, x, y, z, velX, velY, velZ); - } - else if (particleType.equals("hugesmoke")) - { - particle = new EntitySmokeFX(world, x, y, z, velX, velY, velZ, 8.0f); - } - else if (particleType.equals("leafrune")) - { - particle = new EntityTFLeafRuneFX(world, x, y, z, velX, velY, velZ); - } - else if (particleType.equals("bosstear")) - { - particle = new EntityTFBossTearFX(world, x, y, z, velX, velY, velZ, Items.ghast_tear); - } - else if (particleType.equals("ghasttrap")) - { - particle = new EntityTFGhastTrapFX(world, x, y, z, velX, velY, velZ); - } - else if (particleType.equals("protection")) - { - particle = new EntityTFProtectionFX(world, x, y, z, velX, velY, velZ); - } - else if (particleType.equals("snowstuff")) - { - particle = new EntityTFSnowFX(world, x, y, z, velX, velY, velZ); - } - else if (particleType.equals("snowwarning")) - { - particle = new EntityTFSnowWarningFX(world, x, y, z, velX, velY, velZ, 1F); - } - else if (particleType.equals("snowguardian")) - { - particle = new EntityTFSnowGuardianFX(world, x, y, z, velX, velY, velZ, 0.75F); - } - else if (particleType.equals("icebeam")) - { - particle = new EntityTFIceBeamFX(world, x, y, z, velX, velY, velZ, 0.75F); - } - else if (particleType.equals("annihilate")) - { - particle = new EntityTFAnnihilateFX(world, x, y, z, velX, velY, velZ, 0.75F); - } + public void spawnParticle(TFParticleType particleType, double x, double y, double z, double vx, double vy, double vz) { - // if we made a partcle, go ahead and add it - if (particle != null) - { - particle.prevPosX = particle.posX; - particle.prevPosY = particle.posY; - particle.prevPosZ = particle.posZ; - - // we keep having a non-threadsafe crash adding particles directly here, so let's pass them to a buffer - //clientTicker.addParticle(particle); - mc.effectRenderer.addEffect(particle); // maybe it's fixed? - } + Minecraft mc = Minecraft.getMinecraft(); + Entity entity = mc.getRenderViewEntity(); + World world = mc.world; + + if (entity != null && mc.effectRenderer != null) { + + int i = mc.gameSettings.particleSetting; + + if (i == 1 && world.rand.nextInt(3) == 0) { + i = 2; + } + + if (i > 1) return; + + double dx = entity.posX - x; + double dy = entity.posY - y; + double dz = entity.posZ - z; + + if (dx * dx + dy * dy + dz * dz > 1024.0D) return; + + Particle particle = TFParticleFactory.createParticle(particleType, world, x, y, z, vx, vy, vz); + if (particle != null) { + mc.effectRenderer.addEffect(particle); } } } - - public ModelBiped getKnightlyArmorModel(int armorSlot) { - return knightlyArmorModel[armorSlot]; + @Override + public ModelBiped getKnightlyArmorModel(EntityEquipmentSlot armorSlot) { + return knightlyArmorModel.get(armorSlot); } - - public ModelBiped getPhantomArmorModel(int armorSlot) { - return phantomArmorModel[armorSlot]; + + @Override + public ModelBiped getPhantomArmorModel(EntityEquipmentSlot armorSlot) { + return phantomArmorModel.get(armorSlot); } - - public ModelBiped getYetiArmorModel(int armorSlot) { - return yetiArmorModel[armorSlot]; + + @Override + public ModelBiped getYetiArmorModel(EntityEquipmentSlot armorSlot) { + return yetiArmorModel.get(armorSlot); } - public ModelBiped getArcticArmorModel(int armorSlot) { - return arcticArmorModel[armorSlot]; + @Override + public ModelBiped getArcticArmorModel(EntityEquipmentSlot armorSlot) { + return arcticArmorModel.get(armorSlot); } - - - public ModelBiped getFieryArmorModel(int armorSlot) { - return this.fieryArmorModel[armorSlot]; + + @Override + public ModelBiped getFieryArmorModel(EntityEquipmentSlot armorSlot) { + return this.fieryArmorModel.get(armorSlot); } public boolean isDangerOverlayShown() { @@ -577,49 +281,40 @@ public boolean isDangerOverlayShown() { public void setDangerOverlayShown(boolean isDangerOverlayShown) { this.isDangerOverlayShown = isDangerOverlayShown; - } - - public void doBlockAnnihilateEffect(World worldObj, int blockX, int blockY, int blockZ) { - // particles from the block? -// for (int i = 0; i < 10; i++) { -// -// double d0 = worldObj.rand.nextGaussian() * 0.02D; -// double d1 = worldObj.rand.nextGaussian() * 0.02D; -// double d2 = worldObj.rand.nextGaussian() * 0.02D; -// -// float dx = blockX + 0.5F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.4F; -// float dy = blockY + 0.5F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.4F; -// float dz = blockZ + 0.5F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.4F; -// -// TwilightForestMod.proxy.spawnParticle(worldObj, "annihilate", dx, dy, dz, d0, d1, d2); -// -// } - - - byte four = 4; - - for (int dx = 0; dx < four; ++dx) - { - for (int dy = 0; dy < four; ++dy) - { - for (int dz = 0; dz < four; ++dz) - { - double d0 = (double)blockX + ((double)dx + 0.5D) / (double)four; - double d1 = (double)blockY + ((double)dy + 0.5D) / (double)four; - double d2 = (double)blockZ + ((double)dz + 0.5D) / (double)four; - - double gx = worldObj.rand.nextGaussian() * 0.2D; - double gy = worldObj.rand.nextGaussian() * 0.2D; - double gz = worldObj.rand.nextGaussian() * 0.2D; - - TwilightForestMod.proxy.spawnParticle(worldObj, "annihilate", d0, d1, d2, gx, gy, gz); - - - //this.addEffect((new EntityDiggingFX(this.worldObj, d0, d1, d2, d0 - (double)p_147215_1_ - 0.5D, d1 - (double)p_147215_2_ - 0.5D, d2 - (double)p_147215_3_ - 0.5D, p_147215_4_, p_147215_5_)).applyColourMultiplier(p_147215_1_, p_147215_2_, p_147215_3_)); - } - } - } + + @Override + public boolean doesPlayerHaveAdvancement(EntityPlayer player, ResourceLocation advId) { + if (player instanceof EntityPlayerSP) { + ClientAdvancementManager manager = ((EntityPlayerSP) player).connection.getAdvancementManager(); + Advancement adv = manager.getAdvancementList().getAdvancement(advId); + if (adv == null) return false; + AdvancementProgress progress = manager.advancementToProgress.get(adv); + return progress != null && progress.isDone(); + } + + return super.doesPlayerHaveAdvancement(player, advId); + } + + @Override + public TileEntityTFCicada getNewCicadaTE() { + return new TileEntityTFCicadaTicking(); + } + + @Override + public TileEntityTFFirefly getNewFireflyTE() { + return new TileEntityTFFireflyTicking(); } + @Override + public TileEntityTFMoonworm getNewMoonwormTE() { + return new TileEntityTFMoonwormTicking(); + } + + @Override + public void registerCritterTileEntities() { + GameRegistry.registerTileEntity(TileEntityTFFireflyTicking.class, prefix("firefly" )); + GameRegistry.registerTileEntity(TileEntityTFCicadaTicking.class, prefix("cicada" )); + GameRegistry.registerTileEntity(TileEntityTFMoonwormTicking.class, prefix("moonworm")); + } } diff --git a/src/main/java/twilightforest/client/TFClientTicker.java b/src/main/java/twilightforest/client/TFClientTicker.java deleted file mode 100644 index c9ccf814d7..0000000000 --- a/src/main/java/twilightforest/client/TFClientTicker.java +++ /dev/null @@ -1,32 +0,0 @@ -package twilightforest.client; - -import net.minecraft.client.Minecraft; -import net.minecraft.world.World; -import twilightforest.world.WorldProviderTwilightForest; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent; - -public class TFClientTicker { - - - /** - * On the tick, we kill the vignette - */ - @SubscribeEvent - public void clientTick(ClientTickEvent event) { - Minecraft mc = Minecraft.getMinecraft(); - World world = mc.theWorld; - - - // only fire if we're in the twilight forest - if (world != null && (world.provider instanceof WorldProviderTwilightForest)) - { - // vignette - if (mc.ingameGUI != null) - { - mc.ingameGUI.prevVignetteBrightness = 0.0F; - } - - } - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/model/ModelTFAdherent.java b/src/main/java/twilightforest/client/model/ModelTFAdherent.java deleted file mode 100644 index a2472c2b38..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFAdherent.java +++ /dev/null @@ -1,91 +0,0 @@ -package twilightforest.client.model; - -import org.lwjgl.opengl.GL11; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - -public class ModelTFAdherent extends ModelBiped { - - ModelRenderer leftSleeve; - ModelRenderer rightSleeve; - - public ModelTFAdherent() { - - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - this.bipedLeftLeg = new ModelRenderer(this, 0, 0); - this.bipedRightLeg = new ModelRenderer(this, 0, 0); - - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8); - this.bipedHead.setRotationPoint(0F, 0F, 0F); - - this.bipedBody = new ModelRenderer(this, 32, 0); - this.bipedBody.addBox(-4F, 0F, -2F, 8, 24, 4); - this.bipedBody.setRotationPoint(0F, 0F, 0F); - - this.bipedRightArm = new ModelRenderer(this, 0, 16); - this.bipedRightArm.addBox(-3F, -2F, -2F, 4, 12, 4); - this.bipedRightArm.setRotationPoint(-5F, 2F, 0F); - - this.bipedLeftArm = new ModelRenderer(this, 0, 16); - this.bipedLeftArm.addBox(-1F, -2F, -2F, 4, 12, 4); - this.bipedLeftArm.setRotationPoint(5F, 2F, 0F); - - this.leftSleeve = new ModelRenderer(this, 16, 16); - this.leftSleeve.addBox(-1F, -2F, 2F, 4, 12, 4); - this.leftSleeve.setRotationPoint(0F, 0F, 0F); - - this.bipedLeftArm.addChild(this.leftSleeve); - - this.rightSleeve = new ModelRenderer(this, 16, 16); - this.rightSleeve.addBox(-3F, -2F, 2F, 4, 12, 4); - this.rightSleeve.setRotationPoint(0F, 0F, 0F); - - this.bipedRightArm.addChild(this.rightSleeve); - - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - - @Override - public void setRotationAngles(float f, float f1, float f2, float yaw, float pitch, float time, Entity entity) - { - //super.setRotationAngles(f, f1, f2, yaw, pitch, time, entity); - - // rotate head normally - this.bipedHead.rotateAngleY = yaw / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = pitch / (180F / (float)Math.PI); - - // wave arms more - this.bipedRightArm.rotateAngleX = 0.0F;//MathHelper.cos(f * 0.6662F + (float)Math.PI) * 2.0F * f1 * 0.5F; - this.bipedLeftArm.rotateAngleX = 0.0F;//MathHelper.cos(f * 0.6662F) * 2.0F * f1 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - - - this.bipedRightArm.rotateAngleZ += MathHelper.cos((f2 + 10F) * 0.133F) * 0.3F + 0.3F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos((f2 + 10F) * 0.133F) * 0.3F + 0.3F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(f2 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(f2 * 0.067F) * 0.05F; - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float partialTick) { - float bounce = par1EntityLiving.ticksExisted + partialTick; - - // this is where we add the floating - GL11.glTranslatef(0F, -0.125F - MathHelper.sin((bounce) * 0.133F) * 0.1F, 0F); - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFArcticArmor.java b/src/main/java/twilightforest/client/model/ModelTFArcticArmor.java deleted file mode 100644 index db107ac571..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFArcticArmor.java +++ /dev/null @@ -1,92 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; - -public class ModelTFArcticArmor extends ModelBiped { - - public ModelTFArcticArmor(int part, float expand) { - super(expand); - - ModelRenderer rightHood = new ModelRenderer(this, 0, 0); - rightHood.addBox(-1.0F, -2.0F, -1.0F, 1, 4, 1, expand); - rightHood.setRotationPoint(-2.5F, -3.0F, -5.0F); - this.bipedHead.addChild(rightHood); - - ModelRenderer leftHood = new ModelRenderer(this, 0, 0); - leftHood.addBox(0.0F, -2.0F, -1.0F, 1, 4, 1, expand); - leftHood.setRotationPoint(2.5F, -3.0F, -5.0F); - this.bipedHead.addChild(leftHood); - - ModelRenderer topHood = new ModelRenderer(this, 24, 0); - topHood.addBox(-2.0F, -1.0F, -1.0F, 4, 1, 1, expand); - topHood.setRotationPoint(0.0F, -5.5F, -5.0F); - this.bipedHead.addChild(topHood); - - ModelRenderer bottomHood = new ModelRenderer(this, 24, 0); - bottomHood.addBox(-2.0F, -1.0F, -1.0F, 4, 1, 1, expand); - bottomHood.setRotationPoint(0.0F, 0.5F, -5.0F); - this.bipedHead.addChild(bottomHood); - - - switch (part) { - case 0: // helmet - this.bipedHead.showModel = true; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 1: // chest - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = true; - this.bipedRightArm.showModel = true; - this.bipedLeftArm.showModel = true; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 2: // pants - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = true; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - break; - case 3: // boots - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - break; - } - - } - - /** - * Sets the models various rotation angles then renders the model. - */ - @Override - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { - - if (par1Entity != null) { - this.isSneak = par1Entity.isSneaking(); - } - - if (par1Entity != null && par1Entity instanceof EntityLivingBase) { - this.heldItemRight = ((EntityLivingBase)par1Entity).getHeldItem() != null ? 1 : 0; - } - - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFBighorn.java b/src/main/java/twilightforest/client/model/ModelTFBighorn.java deleted file mode 100644 index eb8df5509c..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFBighorn.java +++ /dev/null @@ -1,52 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.client.model.ModelSheep1; - - -public class ModelTFBighorn extends ModelSheep1 -{ - - public ModelTFBighorn() - { - super(); - head = new ModelRenderer(this, 0, 0); - head.addBox(-3F, -4F, -6F, 6, 6, 7, 0F); - head.setRotationPoint(0F, 6F, -8F); - - body = new ModelRenderer(this, 36, 10); - body.addBox(-4F, -9F, -7F, 8, 15, 6, 0F); - body.setRotationPoint(0F, 5F, 2F); - - leg1 = new ModelRenderer(this, 0, 16); - leg1.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); - leg1.setRotationPoint(-3F, 12F, 7F); - - leg2 = new ModelRenderer(this, 0, 16); - leg2.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); - leg2.setRotationPoint(3F, 12F, 7F); - - leg3 = new ModelRenderer(this, 0, 16); - leg3.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); - leg3.setRotationPoint(-3F, 12F, -5F); - - leg4 = new ModelRenderer(this, 0, 16); - leg4.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); - leg4.setRotationPoint(3F, 12F, -5F); - - // curly horn 1 - head.setTextureOffset(28, 16).addBox(-5F, -4F, -4F, 2, 2, 2, 0F); - head.setTextureOffset(16, 13).addBox(-6F, -5F, -3F, 2, 2, 4, 0F); - head.setTextureOffset(16, 19).addBox(-7F, -4F, 0F, 2, 5, 2, 0F); - head.setTextureOffset(18, 27).addBox(-8F, 0F, -2F, 2, 2, 3, 0F); - head.setTextureOffset(28, 27).addBox(-9F, -1F, -3F, 2, 2, 1, 0F); - - // curly horn 2 - head.setTextureOffset(28, 16).addBox(3F, -4F, -4F, 2, 2, 2, 0F); - head.setTextureOffset(16, 13).addBox(4F, -5F, -3F, 2, 2, 4, 0F); - head.setTextureOffset(16, 19).addBox(5F, -4F, 0F, 2, 5, 2, 0F); - head.setTextureOffset(18, 27).addBox(6F, 0F, -2F, 2, 2, 3, 0F); - head.setTextureOffset(28, 27).addBox(7F, -1F, -3F, 2, 2, 1, 0F); - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFBighornFur.java b/src/main/java/twilightforest/client/model/ModelTFBighornFur.java deleted file mode 100644 index b5e3134e51..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFBighornFur.java +++ /dev/null @@ -1,33 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.client.model.ModelSheep2; - - -public class ModelTFBighornFur extends ModelSheep2 -{ - - public ModelTFBighornFur() - { - super(); - head = new ModelRenderer(this, 0, 0); - head.addBox(-3F, -4F, -4F, 6, 6, 6, 0.6F); - head.setRotationPoint(0.0F, 6F, -8F); - body = new ModelRenderer(this, 28, 8); - body.addBox(-4F, -9F, -7F, 8, 15, 6, 0.5F); - body.setRotationPoint(0.0F, 5F, 2.0F); - float f = 0.4F; - leg1 = new ModelRenderer(this, 0, 16); - leg1.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); - leg1.setRotationPoint(-3F, 12F, 7F); - leg2 = new ModelRenderer(this, 0, 16); - leg2.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); - leg2.setRotationPoint(3F, 12F, 7F); - leg3 = new ModelRenderer(this, 0, 16); - leg3.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); - leg3.setRotationPoint(-3F, 12F, -5F); - leg4 = new ModelRenderer(this, 0, 16); - leg4.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); - leg4.setRotationPoint(3F, 12F, -5F); - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFBlockGoblin.java b/src/main/java/twilightforest/client/model/ModelTFBlockGoblin.java deleted file mode 100644 index 9ccc95c91d..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFBlockGoblin.java +++ /dev/null @@ -1,206 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; - - -public class ModelTFBlockGoblin extends ModelBiped -{ - public ModelRenderer helmet; - - ModelRenderer block; - ModelRenderer[] spikes = new ModelRenderer[27]; - - public ModelTFBlockGoblin() - { - bipedHead = new ModelRenderer(this, 0, 0); - bipedHead.addBox(0F, 0F, 0F, 0, 0, 0, 0F); - bipedHead.setRotationPoint(0F, 11F, 0F); - - bipedHeadwear = new ModelRenderer(this, 0, 0); - bipedHeadwear.addBox(0F, 0F, 0F, 0, 0, 0, 0.5F); - bipedHeadwear.setRotationPoint(0F, 11F, 0F); - - this.helmet = new ModelRenderer(this, 24, 0); - this.helmet.addBox(-2.5F, -9.0F, -2.5F, 5, 9, 5); - this.helmet.rotateAngleY = 45F / (180F / (float)Math.PI); - - this.bipedHeadwear.addChild(helmet); - - bipedBody = new ModelRenderer(this, 0, 21); - bipedBody.addBox(-3.5F, 0F, -2F, 7, 7, 4, 0F); - bipedBody.setRotationPoint(0F, 11F, 0F); - - bipedRightArm = new ModelRenderer(this, 52, 0); - bipedRightArm.addBox(-3F, -1F, -2F, 3, 12, 3, 0F); - bipedRightArm.setRotationPoint(-3.5F, 12F, 0F); - - bipedLeftArm = new ModelRenderer(this, 52, 0); - bipedLeftArm.addBox(0F, -1F, -1.5F, 3, 12, 3, 0F); - bipedLeftArm.setRotationPoint(3.5F, 12F, 0F); - - bipedRightLeg = new ModelRenderer(this, 0, 12); - bipedRightLeg.addBox(-1.5F, 0F, -1.5F, 3, 6, 3, 0F); - bipedRightLeg.setRotationPoint(-2F, 18F, 0F); - - bipedLeftLeg = new ModelRenderer(this, 0, 12); - bipedLeftLeg.addBox(-1.5F, 0F, -1.5F, 3, 6, 3, 0F); - bipedLeftLeg.setRotationPoint(2F, 18F, 0F); - - block = new ModelRenderer(this, 32, 16); - block.addBox(-4F, -8F, -4F, 8, 8, 8, 0F); - block.setRotationPoint(6F, 0F, 0F); - - for (int i = 0; i < spikes.length; i++) - { - spikes[i] = new ModelRenderer(this, 56, 16); - spikes[i].addBox(-1F, -1F, -1F, 2, 2, 2, 0F); - block.addChild(spikes[i]); - } - - // X - spikes[2].rotationPointX = 4; - spikes[3].rotationPointX = 4; - spikes[4].rotationPointX = 4; - spikes[11].rotationPointX = 4; - spikes[12].rotationPointX = 5; - spikes[13].rotationPointX = 4; - spikes[20].rotationPointX = 4; - spikes[21].rotationPointX = 4; - spikes[22].rotationPointX = 4; - - spikes[6].rotationPointX = -4; - spikes[7].rotationPointX = -4; - spikes[8].rotationPointX = -4; - spikes[15].rotationPointX = -4; - spikes[16].rotationPointX = -5; - spikes[17].rotationPointX = -4; - spikes[24].rotationPointX = -4; - spikes[25].rotationPointX = -4; - spikes[26].rotationPointX = -4; - - // Y - spikes[0].rotationPointY = -9; - spikes[1].rotationPointY = -8; - spikes[2].rotationPointY = -8; - spikes[3].rotationPointY = -8; - spikes[4].rotationPointY = -8; - spikes[5].rotationPointY = -8; - spikes[6].rotationPointY = -8; - spikes[7].rotationPointY = -8; - spikes[8].rotationPointY = -8; - - spikes[9].rotationPointY = -4; // this spike is not really there - spikes[10].rotationPointY = -4; - spikes[11].rotationPointY = -4; - spikes[12].rotationPointY = -4; - spikes[13].rotationPointY = -4; - spikes[14].rotationPointY = -4; - spikes[15].rotationPointY = -4; - spikes[16].rotationPointY = -4; - spikes[17].rotationPointY = -4; - - spikes[18].rotationPointY = 1; - - // Z - spikes[1].rotationPointZ = 4; - spikes[2].rotationPointZ = 4; - spikes[8].rotationPointZ = 4; - spikes[10].rotationPointZ = 4; - spikes[11].rotationPointZ = 5; - spikes[17].rotationPointZ = 4; - spikes[19].rotationPointZ = 4; - spikes[20].rotationPointZ = 4; - spikes[26].rotationPointZ = 4; - - spikes[4].rotationPointZ = -4; - spikes[5].rotationPointZ = -4; - spikes[6].rotationPointZ = -4; - spikes[13].rotationPointZ = -4; - spikes[14].rotationPointZ = -5; - spikes[15].rotationPointZ = -4; - spikes[22].rotationPointZ = -4; - spikes[23].rotationPointZ = -4; - spikes[24].rotationPointZ = -4; - - // rotation - float fourtyFive = (float) (Math.PI / 4F); - - spikes[1].rotateAngleX = fourtyFive; - spikes[5].rotateAngleX = fourtyFive; - spikes[19].rotateAngleX = fourtyFive; - spikes[23].rotateAngleX = fourtyFive; - - spikes[11].rotateAngleY = fourtyFive; - spikes[13].rotateAngleY = fourtyFive; - spikes[15].rotateAngleY = fourtyFive; - spikes[17].rotateAngleY = fourtyFive; - - spikes[3].rotateAngleZ = fourtyFive; - spikes[7].rotateAngleZ = fourtyFive; - spikes[21].rotateAngleZ = fourtyFive; - spikes[25].rotateAngleZ = fourtyFive; - - spikes[2].rotateAngleX = -55F / (180F / (float)Math.PI); - spikes[2].rotateAngleY = fourtyFive; - spikes[24].rotateAngleX = -55F / (180F / (float)Math.PI); - spikes[24].rotateAngleY = fourtyFive; - - spikes[4].rotateAngleX = -35F / (180F / (float)Math.PI); - spikes[4].rotateAngleY = -fourtyFive; - spikes[26].rotateAngleX = -35F / (180F / (float)Math.PI); - spikes[26].rotateAngleY = -fourtyFive; - - spikes[6].rotateAngleY = fourtyFive; - spikes[6].rotateAngleX = -35F / (180F / (float)Math.PI); - spikes[20].rotateAngleY = fourtyFive; - spikes[20].rotateAngleX = -35F / (180F / (float)Math.PI); - - spikes[8].rotateAngleX = -55F / (180F / (float)Math.PI); - spikes[8].rotateAngleY = -fourtyFive; - spikes[22].rotateAngleX = -55F / (180F / (float)Math.PI); - spikes[22].rotateAngleY = -fourtyFive; - - } - - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { - super.render(entity, f, f1, f2, f3, f4, f5); - - //block.render(f5); - } - - @Override - public void setRotationAngles(float f, float f1, float f2, float yaw, float pitch, float time, Entity entity) - { - aimedBow = false; - super.setRotationAngles(f, f1, f2, yaw, pitch, time, entity); - - bipedHead.rotationPointY = 11.0F; - bipedHeadwear.rotationPointY = 11.0F; - bipedBody.rotationPointY = 11F; - - bipedRightLeg.rotationPointY = 18F; - bipedLeftLeg.rotationPointY = 18F; - - bipedRightArm.setRotationPoint(-3.5F, 12F, 0F); - - bipedRightArm.rotateAngleX += Math.PI; - - bipedLeftArm.setRotationPoint(3.5F, 12F, 0F); - - - bipedLeftArm.rotateAngleX += Math.PI; - - float angle = f2 / 4F; - float length = 0;//16F; - - block.rotationPointX = (float) Math.sin(angle) * length; - block.rotationPointZ = (float) -Math.cos(angle) * length; - - - block.rotateAngleY = -angle; - - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFBunny.java b/src/main/java/twilightforest/client/model/ModelTFBunny.java deleted file mode 100644 index 7a08a2951b..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFBunny.java +++ /dev/null @@ -1,113 +0,0 @@ -// Date: 4/28/2012 9:36:32 AM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - - -public class ModelTFBunny extends ModelBase -{ - //fields - ModelRenderer tail; - ModelRenderer body; - ModelRenderer leg1; - ModelRenderer leg2; - ModelRenderer leg3; - ModelRenderer leg4; - ModelRenderer head; - - public ModelTFBunny() - { - textureWidth = 32; - textureHeight = 32; - setTextureOffset("head.head", 0, 0); - setTextureOffset("head.ear2", 16, 0); - setTextureOffset("head.ear1", 16, 0); - - tail = new ModelRenderer(this, 0, 18); - tail.addBox(-1F, -1F, 0F, 2, 2, 2); - tail.setRotationPoint(0F, 20F, 3F); - tail.setTextureSize(32, 32); - tail.mirror = true; - setRotation(tail, 0F, 0F, 0F); - body = new ModelRenderer(this, 0, 8); - body.addBox(-2F, -1F, -2F, 4, 3, 5); - body.setRotationPoint(0F, 21F, 0F); - body.setTextureSize(32, 32); - body.mirror = true; - setRotation(body, 0F, 0F, 0F); - leg1 = new ModelRenderer(this, 0, 16); - leg1.addBox(0F, 0F, 0F, 1, 1, 1); - leg1.setRotationPoint(-2F, 23F, 2F); - leg1.setTextureSize(32, 32); - leg1.mirror = true; - setRotation(leg1, 0F, 0F, 0F); - leg2 = new ModelRenderer(this, 0, 16); - leg2.addBox(0F, 0F, 0F, 1, 1, 1); - leg2.setRotationPoint(1F, 23F, 2F); - leg2.setTextureSize(32, 32); - leg2.mirror = true; - setRotation(leg2, 0F, 0F, 0F); - leg3 = new ModelRenderer(this, 0, 16); - leg3.addBox(0F, 0F, 0F, 1, 1, 1); - leg3.setRotationPoint(-2F, 23F, -2F); - leg3.setTextureSize(32, 32); - leg3.mirror = true; - setRotation(leg3, 0F, 0F, 0F); - leg4 = new ModelRenderer(this, 0, 16); - leg4.addBox(0F, 0F, 0F, 1, 1, 1); - leg4.setRotationPoint(1F, 23F, -2F); - leg4.setTextureSize(32, 32); - leg4.mirror = true; - setRotation(leg4, 0F, 0F, 0F); - head = new ModelRenderer(this, "head"); - head.setRotationPoint(0F, 22F, -1F); - setRotation(head, 0F, 0F, 0F); - head.mirror = true; - head.addBox("head", -2F, -4F, -3F, 4, 4, 4); - head.addBox("ear2", -2.5F, -8F, -0.5F, 2, 4, 1); - head.addBox("ear1", 0.5F, -8F, -0.5F, 2, 4, 1); - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5); - tail.render(f5); - body.render(f5); - leg1.render(f5); - leg2.render(f5); - leg3.render(f5); - leg4.render(f5); - head.render(f5); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6) - { - this.head.rotateAngleX = par5 / (180F / (float)Math.PI); - this.head.rotateAngleY = par4 / (180F / (float)Math.PI); - this.leg1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.leg2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.leg3.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.leg4.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFCubeOfAnnihilation.java b/src/main/java/twilightforest/client/model/ModelTFCubeOfAnnihilation.java deleted file mode 100644 index 5a2fb5197b..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFCubeOfAnnihilation.java +++ /dev/null @@ -1,56 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; - -public class ModelTFCubeOfAnnihilation extends ModelBase -{ - - public ModelRenderer box; - public ModelRenderer boxX; - public ModelRenderer boxY; - public ModelRenderer boxZ; - - public ModelTFCubeOfAnnihilation() - { - textureWidth = 64; - textureHeight = 64; - box = new ModelRenderer(this, 0, 0); - box.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); - box.setRotationPoint(0F, 0F, 0F); - - boxX = new ModelRenderer(this, 0, 32); - boxX.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); - boxX.setRotationPoint(0F, 0F, 0F); - - boxY = new ModelRenderer(this, 0, 32); - boxY.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); - boxY.setRotationPoint(0F, 0F, 0F); - - boxZ = new ModelRenderer(this, 0, 32); - boxZ.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); - boxZ.setRotationPoint(0F, 0F, 0F); - } - - - public void render(Entity p_78088_1_, float p_78088_2_, float p_78088_3_, float p_78088_4_, float p_78088_5_, float p_78088_6_, float p_78088_7_) { - - this.setRotationAngles(p_78088_2_, p_78088_3_, p_78088_4_, p_78088_5_, p_78088_6_, p_78088_7_, p_78088_1_); - - box.render(p_78088_7_); - boxX.render(p_78088_7_); - boxY.render(p_78088_7_); - boxZ.render(p_78088_7_); - } - - @Override - public void setRotationAngles(float f, float f1, float f2, float f3, float time, float f5, Entity entity) { - - boxX.rotateAngleX = (float) Math.sin((entity.ticksExisted + time)) / 5F; - boxY.rotateAngleY = (float) Math.sin((entity.ticksExisted + time)) / 5F; - boxZ.rotateAngleZ = (float) Math.sin((entity.ticksExisted + time)) / 5F; - - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFDeathTome.java b/src/main/java/twilightforest/client/model/ModelTFDeathTome.java deleted file mode 100644 index eec3367d99..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFDeathTome.java +++ /dev/null @@ -1,121 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBook; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - -import org.lwjgl.opengl.GL11; - -public class ModelTFDeathTome extends ModelBook { - - ModelRenderer everything; - ModelRenderer book; - - ModelRenderer loosePage1; - ModelRenderer loosePage2; - ModelRenderer loosePage3; - ModelRenderer loosePage4; - - - public ModelTFDeathTome() - { - super(); - - everything = (new ModelRenderer(this)).setTextureOffset(0, 0).addBox(0.0F, 0.0F, 0.0F, 0, 0, 0); - - book = (new ModelRenderer(this)).setTextureOffset(0, 0).addBox(0.0F, 0.0F, 0.0F, 0, 0, 0); - - book.addChild(coverRight); - book.addChild(coverLeft); - book.addChild(bookSpine); - book.addChild(pagesRight); - book.addChild(pagesLeft); - book.addChild(flippingPageRight); - book.addChild(flippingPageLeft); - - loosePage1 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, -8F, 5, 8, 0); - loosePage2 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, 9F, 5, 8, 0); - loosePage3 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, 11F, 5, 8, 0); - loosePage4 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, 7F, 5, 8, 0); - - everything.addChild(book); - everything.addChild(loosePage1); - everything.addChild(loosePage2); - everything.addChild(loosePage3); - everything.addChild(loosePage4); - - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float scale) - { - //this.everything.rotateAngleX = par6 / (180F / (float)Math.PI); - GL11.glEnable(GL11.GL_CULL_FACE); - this.setRotationAngles(par1Entity.ticksExisted, 0.4F, 0.6F, 0.9F, par6, 0.0625F); - this.everything.render(scale); - GL11.glDisable(GL11.GL_CULL_FACE); - - } - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float bounce, float flipRight, float flipLeft, float open, float rotate, float scale) - { - book.rotateAngleZ = -0.8726646259971647F; - this.everything.rotateAngleY = rotate / (180F / (float)Math.PI) + (float)Math.PI / 2.0F; - - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float partialTick) { - float bounce = par1EntityLiving.ticksExisted + partialTick; - float open = 0.9f; - float flipRight = 0.4f; - float flipLeft = 0.6f; - - // hoveriness - book.setRotationPoint(0, 4 + MathHelper.sin((bounce) * 0.3F) * 2.0F, 0); - - // book openness - float openAngle = (MathHelper.sin(bounce * 0.4F) * 0.3F + 1.25F) * open; - this.coverRight.rotateAngleY = (float)Math.PI + openAngle; - this.coverLeft.rotateAngleY = -openAngle; - this.pagesRight.rotateAngleY = openAngle; - this.pagesLeft.rotateAngleY = -openAngle; - this.flippingPageRight.rotateAngleY = openAngle - openAngle * 2.0F * flipRight; - this.flippingPageLeft.rotateAngleY = openAngle - openAngle * 2.0F * flipLeft; - this.pagesRight.rotationPointX = MathHelper.sin(openAngle); - this.pagesLeft.rotationPointX = MathHelper.sin(openAngle); - this.flippingPageRight.rotationPointX = MathHelper.sin(openAngle); - this.flippingPageLeft.rotationPointX = MathHelper.sin(openAngle); - - - // page rotations - loosePage1.rotateAngleY = (bounce) / 4.0F; - loosePage1.rotateAngleX = MathHelper.sin((bounce) / 5.0F) / 3.0F; - loosePage1.rotateAngleZ = MathHelper.cos((bounce) / 5.0F) / 5.0F; - - loosePage2.rotateAngleY = (bounce) / 3.0F; - loosePage2.rotateAngleX = MathHelper.sin((bounce) / 5.0F) / 3.0F; - loosePage2.rotateAngleZ = MathHelper.cos((bounce) / 5.0F) / 4.0F + 2; - - loosePage3.rotateAngleY = (bounce) / 4.0F; - loosePage3.rotateAngleX = -MathHelper.sin((bounce) / 5.0F) / 3.0F; - loosePage3.rotateAngleZ = MathHelper.cos((bounce) / 5.0F) / 5.0F - 1.0F; - - loosePage4.rotateAngleY = (bounce) / 4.0F; - loosePage4.rotateAngleX = -MathHelper.sin((bounce) / 2.0F) / 4.0F; - loosePage4.rotateAngleZ = MathHelper.cos((bounce) / 7.0F) / 5.0F; - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFFieryArmor.java b/src/main/java/twilightforest/client/model/ModelTFFieryArmor.java deleted file mode 100644 index 7d000ba672..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFFieryArmor.java +++ /dev/null @@ -1,83 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.model.ModelBiped; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; - -public class ModelTFFieryArmor extends ModelBiped { - - public ModelTFFieryArmor(int part, float expand) - { - super(expand); - - - switch (part) - { - case 0: // helmet - this.bipedHead.showModel = true; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 1: // chest - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = true; - this.bipedRightArm.showModel = true; - this.bipedLeftArm.showModel = true; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 2: // pants - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = true; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - break; - case 3: // boots - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - break; - - } - } - - - /** - * Sets the models various rotation angles then renders the model. - */ - @Override - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { - - if (par1Entity != null) { - this.isSneak = par1Entity.isSneaking(); - } - - if (par1Entity != null && par1Entity instanceof EntityLivingBase) { - this.heldItemRight = ((EntityLivingBase)par1Entity).getHeldItem() != null ? 1 : 0; - } - - // FULL BRIGHT - Minecraft.getMinecraft().entityRenderer.disableLightmap(0); - - - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - - - Minecraft.getMinecraft().entityRenderer.enableLightmap(0); - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFFireBeetle.java b/src/main/java/twilightforest/client/model/ModelTFFireBeetle.java deleted file mode 100644 index 5f127945b0..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFFireBeetle.java +++ /dev/null @@ -1,226 +0,0 @@ -// Date: 11/5/2012 7:35:56 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -public class ModelTFFireBeetle extends ModelBase -{ - //fields - ModelRenderer thorax; - ModelRenderer head; - ModelRenderer connector2; - ModelRenderer RearEnd; - ModelRenderer Leg6; - ModelRenderer Leg4; - ModelRenderer Leg2; - ModelRenderer Leg5; - ModelRenderer Leg3; - ModelRenderer Leg1; - ModelRenderer connector1; - ModelRenderer jaw1a; - ModelRenderer jaw1b; - ModelRenderer jaw2a; - ModelRenderer jaw2b; - ModelRenderer antenna1; - ModelRenderer antenna2; - ModelRenderer eye1; - ModelRenderer eye2; - - public ModelTFFireBeetle() - { - textureWidth = 64; - textureHeight = 32; - - thorax = new ModelRenderer(this, 0, 22); - thorax.addBox(-4.5F, -4F, 0F, 9, 8, 2); - thorax.setRotationPoint(0F, 18F, -4.5F); - - connector1 = new ModelRenderer(this, 0, 12); - connector1.addBox(-3F, -3F, 0F, 6, 6, 1); - connector1.setRotationPoint(0F, 18F, -3F); - - connector2 = new ModelRenderer(this, 0, 12); - connector2.addBox(-3F, -3F, -1F, 6, 6, 1); - connector2.setRotationPoint(0F, 18F, -4F); - - RearEnd = new ModelRenderer(this, 22, 9); - RearEnd.addBox(-6F, -9F, -4F, 12, 14, 9); - RearEnd.setRotationPoint(0F, 18F, 7F); - setRotation(RearEnd, 1.570796F, 0F, 0F); - - Leg6 = new ModelRenderer(this, 40, 0); - Leg6.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg6.setRotationPoint(4F, 21F, -4F); - setRotation(Leg6, 0F, 0.2792527F, 0.3490659F); - - Leg5 = new ModelRenderer(this, 40, 0); - Leg5.mirror = true; - Leg5.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg5.setRotationPoint(-4F, 21F, -4F); - setRotation(Leg5, 0F, -0.2792527F, -0.3490659F); - - Leg4 = new ModelRenderer(this, 40, 0); - Leg4.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg4.setRotationPoint(4F, 21F, -1F); - setRotation(Leg4, 0F, -0.2792527F, 0.3490659F); - - Leg2 = new ModelRenderer(this, 40, 0); - Leg2.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg2.setRotationPoint(4F, 21F, 4F); - setRotation(Leg2, 0F, -0.6981317F, 0.3490659F); - - Leg3 = new ModelRenderer(this, 40, 0); - Leg3.mirror = true; - Leg3.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg3.setRotationPoint(-4F, 21F, -1F); - setRotation(Leg3, 0F, 0.2792527F, -0.3490659F); - - Leg1 = new ModelRenderer(this, 40, 0); - Leg1.mirror = true; - Leg1.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg1.setRotationPoint(-4F, 21F, 4F); - Leg1.setTextureSize(64, 32); - setRotation(Leg1, 0F, 0.6981317F, -0.3490659F); - - head = new ModelRenderer(this, 0, 0); - head.addBox(-4F, -4F, -6F, 8, 6, 6); - head.setRotationPoint(0F, 19F, -5F); - - jaw1a = new ModelRenderer(this, 0, 0); - jaw1a.addBox(0F, 0F, -2F, 1, 1, 2); - jaw1a.setRotationPoint(-3F, 0F, -6F); - setRotation(jaw1a, 0.3490659F, 0F, 0F); - - jaw1b = new ModelRenderer(this, 0, 0); - jaw1b.addBox(0F, 0F, 0F, 1, 1, 2); - jaw1b.setRotationPoint(0F, 0F, -2F); - setRotation(jaw1b, 0F, 1.570796F, 0F); - - jaw2a = new ModelRenderer(this, 0, 0); - jaw2a.addBox(-1F, 0F, -2F, 1, 1, 2); - jaw2a.setRotationPoint(3F, 0F, -6F); - setRotation(jaw2a, 0.3490659F, 0F, 0F); - - jaw2b = new ModelRenderer(this, 0, 0); - jaw2b.addBox(0F, 0F, -2F, 1, 1, 2); - jaw2b.setRotationPoint(0F, 0F, -2F); - setRotation(jaw2b, 0F, 1.570796F, 0F); - - antenna1 = new ModelRenderer(this, 42, 4); - antenna1.addBox(0F, -0.5F, -0.5F, 10, 1, 1); - antenna1.setRotationPoint(1F, -3F, -5F); - setRotation(antenna1, 0F, 1.047198F, -0.296706F); - - antenna2 = new ModelRenderer(this, 42, 4); - antenna2.addBox(0F, -0.5F, -0.5F, 10, 1, 1); - antenna2.setRotationPoint(-1F, -3F, -5F); - setRotation(antenna2, 0F, 2.094395F, 0.296706F); - - eye1 = new ModelRenderer(this, 15, 12); - eye1.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - eye1.setRotationPoint(-3F, -2F, -5F); - - eye2 = new ModelRenderer(this, 15, 12); - eye2.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - eye2.setRotationPoint(3F, -2F, -5F); - - - - head.addChild(jaw1a); - jaw1a.addChild(jaw1b); - head.addChild(jaw2a); - jaw2a.addChild(jaw2b); - head.addChild(antenna1); - head.addChild(antenna2); - head.addChild(eye1); - head.addChild(eye2); - - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - thorax.render(f5); - head.render(f5); - connector2.render(f5); - RearEnd.render(f5); - Leg6.render(f5); - Leg4.render(f5); - Leg2.render(f5); - Leg5.render(f5); - Leg3.render(f5); - Leg1.render(f5); - connector1.render(f5); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - this.head.rotateAngleY = par4 / (180F / (float)Math.PI); - this.head.rotateAngleX = par5 / (180F / (float)Math.PI); - - float legZ = ((float)Math.PI / 11F); - this.Leg1.rotateAngleZ = -legZ; - this.Leg2.rotateAngleZ = legZ; - this.Leg3.rotateAngleZ = -legZ * 0.74F; - this.Leg4.rotateAngleZ = legZ * 0.74F; - this.Leg5.rotateAngleZ = -legZ; - this.Leg6.rotateAngleZ = legZ; - - float var9 = -0.0F; - float var10 = 0.3926991F; - this.Leg1.rotateAngleY = var10 * 2.0F + var9; - this.Leg2.rotateAngleY = -var10 * 2.0F - var9; - this.Leg3.rotateAngleY = var10 * 1.0F + var9; - this.Leg4.rotateAngleY = -var10 * 1.0F - var9; - this.Leg5.rotateAngleY = -var10 * 2.0F + var9; - this.Leg6.rotateAngleY = var10 * 2.0F - var9; - - float var11 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + 0.0F) * 0.4F) * par2; - float var12 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + (float)Math.PI) * 0.4F) * par2; - float var14 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - - float var15 = Math.abs(MathHelper.sin(par1 * 0.6662F + 0.0F) * 0.4F) * par2; - float var16 = Math.abs(MathHelper.sin(par1 * 0.6662F + (float)Math.PI) * 0.4F) * par2; - float var18 = Math.abs(MathHelper.sin(par1 * 0.6662F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - - this.Leg1.rotateAngleY += var11; - this.Leg2.rotateAngleY += -var11; - this.Leg3.rotateAngleY += var12; - this.Leg4.rotateAngleY += -var12; - this.Leg5.rotateAngleY += var14; - this.Leg6.rotateAngleY += -var14; - - this.Leg1.rotateAngleZ += var15; - this.Leg2.rotateAngleZ += -var15; - - this.Leg3.rotateAngleZ += var16; - this.Leg4.rotateAngleZ += -var16; - - this.Leg5.rotateAngleZ += var18; - this.Leg6.rotateAngleZ += -var18; - - - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFGhast.java b/src/main/java/twilightforest/client/model/ModelTFGhast.java deleted file mode 100644 index 39379ef3eb..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFGhast.java +++ /dev/null @@ -1,73 +0,0 @@ -package twilightforest.client.model; - -import java.util.Random; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ModelTFGhast extends ModelBase -{ - ModelRenderer body; - protected ModelRenderer[] tentacles = new ModelRenderer[9]; - - - public ModelTFGhast() - { - byte yOffset = -16; - this.body = new ModelRenderer(this, 0, 0); - this.body.addBox(-8.0F, -8.0F, -8.0F, 16, 16, 16); - this.body.rotationPointY += (float)(24 + yOffset); - Random rand = new Random(1660L); - - for (int i = 0; i < this.tentacles.length; ++i) - { - makeTentacle(yOffset, rand, i); - } - } - - protected void makeTentacle(byte yOffset, Random random, int i) { - this.tentacles[i] = new ModelRenderer(this, 0, 0); - float xPoint = (((float)(i % 3) - (float)(i / 3 % 2) * 0.5F + 0.25F) / 2.0F * 2.0F - 1.0F) * 5.0F; - float zPoint = ((float)(i / 3) / 2.0F * 2.0F - 1.0F) * 5.0F; - int length = random.nextInt(7) + 8; - this.tentacles[i].addBox(-1.0F, 0.0F, -1.0F, 2, length, 2); - this.tentacles[i].rotationPointX = xPoint; - this.tentacles[i].rotationPointZ = zPoint; - this.tentacles[i].rotationPointY = (float)(23 + yOffset); - - this.body.addChild(this.tentacles[i]); - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float yaw, float pitch, float par6, Entity par7Entity) - { - // wave tentacles - for (int i = 0; i < this.tentacles.length; ++i) - { - this.tentacles[i].rotateAngleX = 0.2F * MathHelper.sin(par3 * 0.3F + (float)i) + 0.4F; - } - - // make body face what we're looking at - this.body.rotateAngleX = pitch / (180F / (float)Math.PI); - this.body.rotateAngleY = yaw / (180F / (float)Math.PI); - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float yaw, float pitch, float time) - { - this.setRotationAngles(par2, par3, par4, yaw, pitch, time, par1Entity); - - this.body.render(time); - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFGoblinChain.java b/src/main/java/twilightforest/client/model/ModelTFGoblinChain.java deleted file mode 100644 index ad6f0f4d9b..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFGoblinChain.java +++ /dev/null @@ -1,26 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; - - -public class ModelTFGoblinChain extends ModelBase -{ - ModelRenderer chain; - - public ModelTFGoblinChain() - { - - chain = new ModelRenderer(this, 56, 16); - chain.addBox(-1F, -1F, -1F, 2, 2, 2, 0F); - chain.setRotationPoint(0F, 0F, 0F); - - } - - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { - chain.render(f5); - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFGoblinKnightLower.java b/src/main/java/twilightforest/client/model/ModelTFGoblinKnightLower.java deleted file mode 100644 index 4e187195af..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFGoblinKnightLower.java +++ /dev/null @@ -1,130 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import twilightforest.entity.EntityTFGoblinKnightLower; - -public class ModelTFGoblinKnightLower extends ModelBiped { - - public ModelRenderer tunic; - - public ModelTFGoblinKnightLower() - { - this.heldItemLeft = 0; - this.heldItemRight = 0; - this.isSneak = false; - this.aimedBow = false; - this.textureWidth = 128; - this.textureHeight = 64; - - this.bipedCloak = new ModelRenderer(this, 0, 0); - this.bipedCloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1); - this.bipedEars = new ModelRenderer(this, 24, 0); - this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1); - - this.bipedHead = new ModelRenderer(this, 0, 32); - this.bipedHead.addBox(-2.5F, -5.0F, -3.5F, 5, 5, 5); - this.bipedHead.setRotationPoint(0.0F, 10.0F, 1.0F); - - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - this.bipedHeadwear.addBox(0, 0, 0, 0, 0, 0); - - this.bipedBody = new ModelRenderer(this, 16, 48); - this.bipedBody.addBox(-3.5F, 0.0F, -2.0F, 7, 8, 4); - this.bipedBody.setRotationPoint(0.0F, 8.0F, 0.0F); - - this.bipedRightArm = new ModelRenderer(this, 40, 48); - this.bipedRightArm.addBox(-2.0F, -2.0F, -1.5F, 2, 8, 3); - this.bipedRightArm.setRotationPoint(-3.5F, 10.0F, 0.0F); - - this.bipedLeftArm = new ModelRenderer(this, 40, 48); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(0.0F, -2.0F, -1.5F, 2, 8, 3); - this.bipedLeftArm.setRotationPoint(3.5F, 10.0F, 0.0F); - - this.bipedRightLeg = new ModelRenderer(this, 0, 48); - this.bipedRightLeg.addBox(-3.0F, 0.0F, -2.0F, 4, 8, 4); - this.bipedRightLeg.setRotationPoint(-2.5F, 16.0F, 0.0F); - - this.bipedLeftLeg = new ModelRenderer(this, 0, 48); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-1.0F, 0.0F, -2.0F, 4, 8, 4); - this.bipedLeftLeg.setRotationPoint(2.5F, 16.0F, 0.0F); - - this.tunic = new ModelRenderer(this, 64, 19); - this.tunic.addBox(-6.0F, 0.0F, -3.0F, 12, 9, 6); - this.tunic.setRotationPoint(0F, 7.5F, 0.0F); - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - - if (((EntityTFGoblinKnightLower)par1Entity).hasArmor()) - { - this.renderTunic(par7); - } - } - - /** - * Renders the tunic, if we're wearing armor - */ - public void renderTunic(float par1) - { - this.tunic.render(par1); - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; - this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.bipedRightLeg.rotateAngleY = 0.0F; - this.bipedLeftLeg.rotateAngleY = 0.0F; - - if (par7Entity.riddenByEntity != null) - { - this.bipedHead.rotateAngleY = 0; - this.bipedHead.rotateAngleX = 0; - this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; - this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; - } - - if (this.heldItemLeft != 0) - { - this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemLeft; - } - - if (this.heldItemRight != 0) - { - this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemRight; - } - - this.bipedRightArm.rotateAngleY = 0.0F; - this.bipedLeftArm.rotateAngleY = 0.0F; - - - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFGoblinKnightUpper.java b/src/main/java/twilightforest/client/model/ModelTFGoblinKnightUpper.java deleted file mode 100644 index 31edf6e181..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFGoblinKnightUpper.java +++ /dev/null @@ -1,263 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import twilightforest.entity.EntityTFGoblinKnightUpper; - -public class ModelTFGoblinKnightUpper extends ModelBiped { - - public ModelRenderer breastplate; - public ModelRenderer helmet; - public ModelRenderer righthorn1; - public ModelRenderer righthorn2; - public ModelRenderer lefthorn1; - public ModelRenderer lefthorn2; - - public ModelRenderer shield; - public ModelRenderer spear; - - - public ModelTFGoblinKnightUpper() - { - this.heldItemLeft = 0; - this.heldItemRight = 0; - this.isSneak = false; - this.aimedBow = false; - this.textureWidth = 128; - this.textureHeight = 64; - - this.bipedCloak = new ModelRenderer(this, 0, 0); - this.bipedCloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1); - this.bipedEars = new ModelRenderer(this, 24, 0); - this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1); - - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(0, 0, 0, 0, 0, 0); - this.bipedHead.setRotationPoint(0.0F, 12.0F, 0.0F); - - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - this.bipedHeadwear.addBox(0, 0, 0, 0, 0, 0); - this.bipedHeadwear.setRotationPoint(0.0F, 12.0F, 0.0F); - - this.helmet = new ModelRenderer(this, 0, 0); - this.helmet.addBox(-3.5F, -11.0F, -3.5F, 7, 11, 7); - this.helmet.rotateAngleY = 45F / (180F / (float)Math.PI); - - this.righthorn1 = new ModelRenderer(this, 28, 0); - this.righthorn1.addBox(-6F, -1.5F, -1.5F, 7, 3, 3); - this.righthorn1.setRotationPoint(-3.5F, -9F, 0.0F); - this.righthorn1.rotateAngleY = 15F / (180F / (float)Math.PI); - this.righthorn1.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn2 = new ModelRenderer(this, 28, 6); - this.righthorn2.addBox(-3.0F, -1.0F, -1.0F, 3, 2, 2); - this.righthorn2.setRotationPoint(-5.5F, 0.0F, 0.0F); - this.righthorn2.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn1.addChild(righthorn2); - - this.lefthorn1 = new ModelRenderer(this, 28, 0); - this.lefthorn1.mirror = true; - this.lefthorn1.addBox(-1F, -1.5F, -1.5F, 7, 3, 3); - this.lefthorn1.setRotationPoint(3.5F, -9F, 0.0F); - this.lefthorn1.rotateAngleY = -15F / (180F / (float)Math.PI); - this.lefthorn1.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn2 = new ModelRenderer(this, 28, 6); - this.lefthorn2.addBox(0.0F, -1.0F, -1.0F, 3, 2, 2); - this.lefthorn2.setRotationPoint(5.5F, 0.0F, 0.0F); - this.lefthorn2.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn1.addChild(lefthorn2); - - this.bipedHeadwear.addChild(helmet); - this.bipedHeadwear.addChild(righthorn1); - this.bipedHeadwear.addChild(lefthorn1); - - this.bipedBody = new ModelRenderer(this, 0, 18); - this.bipedBody.setRotationPoint(0.0F, 12.0F, 0.0F); - this.bipedBody.addBox(-5.5F, 0.0F, -2.0F, 11, 8, 4); - this.bipedBody.setTextureOffset(30, 24).addBox(-6.5F, 0F, -2F, 1, 4, 4); // right shoulder - this.bipedBody.setTextureOffset(30, 24).addBox(5.5F, 0F, -2F, 1, 4, 4); // left shoulder - - this.bipedRightArm = new ModelRenderer(this, 44, 16); - this.bipedRightArm.addBox(-4.0F, -2.0F, -2.0F, 4, 12, 4); - this.bipedRightArm.setRotationPoint(-6.5F, 14.0F, 0.0F); - - this.bipedLeftArm = new ModelRenderer(this, 44, 16); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(0.0F, -2.0F, -2.0F, 4, 12, 4); - this.bipedLeftArm.setRotationPoint(6.5F, 14.0F, 0.0F); - - this.bipedRightLeg = new ModelRenderer(this, 30, 16); - this.bipedRightLeg.addBox(-1.5F, 0.0F, -2.0F, 3, 4, 4); - this.bipedRightLeg.setRotationPoint(-4F, 20.0F, 0.0F); - - this.bipedLeftLeg = new ModelRenderer(this, 30, 16); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-1.5F, 0.0F, -2.0F, 3, 4, 4); - this.bipedLeftLeg.setRotationPoint(4F, 20.0F, 0.0F); - - this.shield = new ModelRenderer(this, 63, 36); - this.shield.addBox(-6.0F, -6.0F, -2.0F, 12, 20, 2); - this.shield.setRotationPoint(0F, 12F, 0.0F); - this.shield.rotateAngleX = 90F / (180F / (float)Math.PI); - - this.bipedLeftArm.addChild(shield); - - this.spear = new ModelRenderer(this, 108, 0); - this.spear.addBox(-1.0F, -19.0F, -1.0F, 2, 40, 2); - this.spear.setRotationPoint(-2F, 8.5F, 0.0F); - this.spear.rotateAngleX = 90F / (180F / (float)Math.PI); - - this.bipedRightArm.addChild(spear); - - - this.breastplate = new ModelRenderer(this, 64, 0); - this.breastplate.addBox(-6.5F, 0.0F, -3.0F, 13, 12, 6); - this.breastplate.setRotationPoint(0F, 11.5F, 0.0F); - - - - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - this.shield.isHidden = !((EntityTFGoblinKnightUpper)par1Entity).hasShield(); - - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - - if (((EntityTFGoblinKnightUpper)par1Entity).hasArmor()) - { - this.renderBreastplate(par7); - } - - } - - /** - * Renders the breastplate, if we're wearing armor - */ - public void renderBreastplate(float par1) - { - this.breastplate.render(par1); - } - - - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - EntityTFGoblinKnightUpper upperKnight = ((EntityTFGoblinKnightUpper)par7Entity); - - boolean hasShield = upperKnight.hasShield(); - - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleZ = 0; - this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; - this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; - this.bipedHeadwear.rotateAngleZ = this.bipedHead.rotateAngleZ; - - - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - - float leftConstraint = hasShield ? 0.2F : par2; - - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * leftConstraint * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - - - this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.bipedRightLeg.rotateAngleY = 0.0F; - this.bipedLeftLeg.rotateAngleY = 0.0F; - - if (this.isRiding) - { - this.bipedRightArm.rotateAngleX += -((float)Math.PI / 5F); - this.bipedLeftArm.rotateAngleX += -((float)Math.PI / 5F); - this.bipedRightLeg.rotateAngleX = 0; - this.bipedLeftLeg.rotateAngleX = 0; -// this.bipedRightLeg.rotateAngleY = ((float)Math.PI / 10F); -// this.bipedLeftLeg.rotateAngleY = -((float)Math.PI / 10F); - } - - if (this.heldItemLeft != 0) - { - this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemLeft; - } - - this.heldItemRight = 1; - - if (this.heldItemRight != 0) - { - this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemRight; - } - - bipedRightArm.rotateAngleX -= (Math.PI * 0.66); - - // during swing move arm forward - if (upperKnight.heavySpearTimer > 0) - { - bipedRightArm.rotateAngleX -= this.getArmRotationDuringSwing(60 - upperKnight.heavySpearTimer + par6) / (180F / (float)Math.PI); - } - - this.bipedRightArm.rotateAngleY = 0.0F; - this.bipedLeftArm.rotateAngleY = 0.0F; - - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - - // shield arm points somewhat inward - this.bipedLeftArm.rotateAngleZ = -this.bipedLeftArm.rotateAngleZ; - - // fix shield so that it's always perpendicular to the floor - this.shield.rotateAngleX = (float) ( Math.PI * 2 - this.bipedLeftArm.rotateAngleX); - } - - /** - * - */ - private float getArmRotationDuringSwing(float attackTime) - { - if (attackTime <= 10) - { - // rock back - return attackTime * 1.0F; - } - if (attackTime > 10 && attackTime <= 30) - { - // hang back - return 10F; - } - if (attackTime > 30 && attackTime <= 33) - { - // slam forward - return (attackTime - 30) * -8F + 10F; - } - if (attackTime > 33 && attackTime <= 50) - { - // stay forward - return -15F; - } - if (attackTime > 50 && attackTime <= 60) - { - // back to normal - return (10 - (attackTime - 50)) * -1.5F; - } - - return 0; - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFHelmetCrab.java b/src/main/java/twilightforest/client/model/ModelTFHelmetCrab.java deleted file mode 100644 index 836dcf2f02..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFHelmetCrab.java +++ /dev/null @@ -1,245 +0,0 @@ -// Date: 4/14/2013 12:59:03 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -/** - * Helmet crab model, based partially on some of the spider code - */ -public class ModelTFHelmetCrab extends ModelBase -{ - //fields - ModelRenderer body; - ModelRenderer helmetBase; - ModelRenderer Leg8; - ModelRenderer Leg6; - ModelRenderer Leg4; - ModelRenderer rightArm; - ModelRenderer Leg5; - ModelRenderer Leg3; - ModelRenderer clawbase; - ModelRenderer clawtop; - ModelRenderer clawbottom; - ModelRenderer righteye; - ModelRenderer lefteye; - - public ModelRenderer helmet; - public ModelRenderer righthorn1; - public ModelRenderer righthorn2; - public ModelRenderer lefthorn1; - public ModelRenderer lefthorn2; - - - public ModelTFHelmetCrab() - { - textureWidth = 64; - textureHeight = 32; - - body = new ModelRenderer(this, 32, 4); - body.addBox(-2.5F, -2.5F, -5F, 5, 5, 5); - body.setRotationPoint(0F, 19F, 0F); - - helmetBase = new ModelRenderer(this, 0, 0); - helmetBase.addBox(0, 0, 0, 0, 0, 0); - helmetBase.setRotationPoint(0F, 18F, 0F); - this.helmetBase.rotateAngleX = -100F / (180F / (float)Math.PI); - this.helmetBase.rotateAngleY = -30F / (180F / (float)Math.PI); - - this.helmet = new ModelRenderer(this, 0, 14); - this.helmet.addBox(-3.5F, -11.0F, -3.5F, 7, 11, 7); - this.helmet.rotateAngleY = 45F / (180F / (float)Math.PI); - - this.righthorn1 = new ModelRenderer(this, 28, 14); - this.righthorn1.addBox(-6F, -1.5F, -1.5F, 7, 3, 3); - this.righthorn1.setRotationPoint(-3.5F, -9F, 0.0F); - this.righthorn1.rotateAngleY = -15F / (180F / (float)Math.PI); - this.righthorn1.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn2 = new ModelRenderer(this, 28, 20); - this.righthorn2.addBox(-3.0F, -1.0F, -1.0F, 3, 2, 2); - this.righthorn2.setRotationPoint(-5.5F, 0.0F, 0.0F); - this.righthorn2.rotateAngleY = -15F / (180F / (float)Math.PI); - this.righthorn2.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn1.addChild(righthorn2); - - this.lefthorn1 = new ModelRenderer(this, 28, 14); - this.lefthorn1.mirror = true; - this.lefthorn1.addBox(-1F, -1.5F, -1.5F, 7, 3, 3); - this.lefthorn1.setRotationPoint(3.5F, -9F, 0.0F); - this.lefthorn1.rotateAngleY = 15F / (180F / (float)Math.PI); - this.lefthorn1.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn2 = new ModelRenderer(this, 28, 20); - this.lefthorn2.addBox(0.0F, -1.0F, -1.0F, 3, 2, 2); - this.lefthorn2.setRotationPoint(5.5F, 0.0F, 0.0F); - this.lefthorn2.rotateAngleY = 15F / (180F / (float)Math.PI); - this.lefthorn2.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn1.addChild(lefthorn2); - - this.helmetBase.addChild(helmet); - this.helmetBase.addChild(righthorn1); - this.helmetBase.addChild(lefthorn1); - - Leg8 = new ModelRenderer(this, 18, 0); - Leg8.addBox(-1F, -1F, -1F, 8, 2, 2); - Leg8.setRotationPoint(3F, 20F, -3F); - setRotation(Leg8, 0F, 0.5759587F, 0.1919862F); - - Leg6 = new ModelRenderer(this, 18, 0); - Leg6.addBox(-1F, -1F, -1F, 8, 2, 2); - Leg6.setRotationPoint(3F, 20F, -2F); - setRotation(Leg6, 0F, 0.2792527F, 0.1919862F); - - Leg4 = new ModelRenderer(this, 18, 0); - Leg4.addBox(-1F, -1F, -1F, 8, 2, 2); - Leg4.setRotationPoint(3F, 20F, -1F); - setRotation(Leg4, 0F, -0.2792527F, 0.1919862F); - - rightArm = new ModelRenderer(this, 38, 0); - rightArm.addBox(-7F, -1F, -1F, 8, 2, 2); - rightArm.setRotationPoint(-3F, 20F, -3F); - setRotation(rightArm, 0F, -1.319531F, -0.1919862F); - - Leg5 = new ModelRenderer(this, 18, 0); - Leg5.addBox(-7F, -1F, -1F, 8, 2, 2); - Leg5.setRotationPoint(-3F, 20F, -2F); - setRotation(Leg5, 0F, -0.2792527F, -0.1919862F); - - Leg3 = new ModelRenderer(this, 18, 0); - Leg3.addBox(-7F, -1F, -1F, 8, 2, 2); - Leg3.setRotationPoint(-3F, 20F, -1F); - setRotation(Leg3, 0F, 0.2792527F, -0.1919862F); - - clawbase = new ModelRenderer(this, 0, 0); - clawbase.addBox(0F, -1.5F, -1F, 3, 3, 2); - clawbase.setRotationPoint(-6F, 0F, -0.5F); - setRotation(clawbase, 0.0F, (float)(Math.PI / 2.0F), 0); - - clawtop = new ModelRenderer(this, 0, 5); - clawtop.addBox(0F, -0.5F, -1F, 3, 1, 2); - clawtop.setRotationPoint(3F, -1F, 0F); - setRotation(clawtop, 0F, 0F, -0.1858931F); - - clawbottom = new ModelRenderer(this, 0, 8); - clawbottom.addBox(0F, -0.5F, -1F, 3, 2, 2); - clawbottom.setRotationPoint(3F, 0F, 0F); - setRotation(clawbottom, 0F, 0F, 0.2602503F); - - this.clawbase.addChild(clawtop); - this.clawbase.addChild(clawbottom); - - this.rightArm.addChild(clawbase); - - righteye = new ModelRenderer(this, 10, 0); - righteye.addBox(-1F, -3F, -1F, 2, 3, 2); - righteye.setRotationPoint(-1F, -1F, -4F); - setRotation(righteye, (float)(Math.PI / 4.0F), 0.0F, -(float)(Math.PI / 4.0F)); - - lefteye = new ModelRenderer(this, 10, 0); - lefteye.addBox(-1F, -3F, -1F, 2, 3, 2); - lefteye.setRotationPoint(1F, -1F, -4F); - setRotation(lefteye, (float)(Math.PI / 4.0F), 0.0F, (float)(Math.PI / 4.0F)); - - this.body.addChild(righteye); - this.body.addChild(lefteye); - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); - body.render(par7); - helmetBase.render(par7); - Leg8.render(par7); - Leg6.render(par7); - Leg4.render(par7); - rightArm.render(par7); - Leg5.render(par7); - Leg3.render(par7); -// clawbase.render(par7); -// clawtop.render(par7); -// clawbottom.render(par7); -// righteye.render(par7); -// lefteye.render(par7); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); - - this.body.rotateAngleY = par4 / (180F / (float)Math.PI); - this.body.rotateAngleX = par5 / (180F / (float)Math.PI); - float f6 = ((float)Math.PI / 4F); - //this.Leg1.rotateAngleZ = -f6; - //this.Leg2.rotateAngleZ = f6; - this.Leg3.rotateAngleZ = -f6 * 0.74F; - this.Leg4.rotateAngleZ = f6 * 0.74F; - this.Leg5.rotateAngleZ = -f6 * 0.74F; - this.Leg6.rotateAngleZ = f6 * 0.74F; - //this.Leg7.rotateAngleZ = -f6; - this.Leg8.rotateAngleZ = f6; - float f7 = -0.0F; - float f8 = 0.3926991F; - //this.Leg1.rotateAngleY = f8 * 2.0F + f7; - //this.Leg2.rotateAngleY = -f8 * 2.0F - f7; - this.Leg3.rotateAngleY = f8 * 1.0F + f7; - this.Leg4.rotateAngleY = -f8 * 1.0F - f7; - this.Leg5.rotateAngleY = -f8 * 1.0F + f7; - this.Leg6.rotateAngleY = f8 * 1.0F - f7; - //this.Leg7.rotateAngleY = -f8 * 2.0F + f7; - this.Leg8.rotateAngleY = f8 * 2.0F - f7; - float f10 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + (float)Math.PI) * 0.4F) * par2; - float f11 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + ((float)Math.PI / 2F)) * 0.4F) * par2; - float f12 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - float f14 = Math.abs(MathHelper.sin(par1 * 0.6662F + (float)Math.PI) * 0.4F) * par2; - float f15 = Math.abs(MathHelper.sin(par1 * 0.6662F + ((float)Math.PI / 2F)) * 0.4F) * par2; - float f16 = Math.abs(MathHelper.sin(par1 * 0.6662F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - //this.Leg1.rotateAngleY += f9; - //this.Leg2.rotateAngleY += -f9; - this.Leg3.rotateAngleY += f10; - this.Leg4.rotateAngleY += -f10; - this.Leg5.rotateAngleY += f11; - this.Leg6.rotateAngleY += -f11; - //this.Leg7.rotateAngleY += f12; - this.Leg8.rotateAngleY += -f12; - //this.Leg1.rotateAngleZ += f13; - //this.Leg2.rotateAngleZ += -f13; - this.Leg3.rotateAngleZ += f14; - this.Leg4.rotateAngleZ += -f14; - this.Leg5.rotateAngleZ += f15; - this.Leg6.rotateAngleZ += -f15; - //this.Leg7.rotateAngleZ += f16; - this.Leg8.rotateAngleZ += -f16; - - // swing right arm as if it were an arm, not a leg - this.rightArm.rotateAngleY = -1.319531F; - this.rightArm.rotateAngleY += MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - - - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFHydra.java b/src/main/java/twilightforest/client/model/ModelTFHydra.java deleted file mode 100644 index 70aea681e0..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFHydra.java +++ /dev/null @@ -1,326 +0,0 @@ -// Date: 2/5/2012 10:11:18 AM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import twilightforest.entity.boss.EntityTFHydra; -import twilightforest.entity.boss.EntityTFHydraPart; - - -public class ModelTFHydra extends ModelBase -{ - //fields - ModelRenderer body; - ModelRenderer leg1; - ModelRenderer leg2; - ModelRenderer tail1; - ModelRenderer tail2; - ModelRenderer tail3; - ModelRenderer tail4; - ModelRenderer neck1a; - ModelRenderer neck1b; - ModelRenderer neck1c; - ModelRenderer neck1d; - ModelRenderer head1; - ModelRenderer jaw1; - ModelRenderer frill1; - ModelRenderer neck2a; - ModelRenderer neck2b; - ModelRenderer neck2c; - ModelRenderer neck2d; - ModelRenderer head2; - ModelRenderer jaw2; - ModelRenderer frill2; - ModelRenderer neck3a; - ModelRenderer neck3b; - ModelRenderer neck3c; - ModelRenderer neck3d; - ModelRenderer head3; - ModelRenderer jaw3; - ModelRenderer frill3; - - public ModelTFHydra() - { - textureWidth = 512; - textureHeight = 256; - - setTextureOffset("body.body", 0, 0); - setTextureOffset("leg.main", 0, 136); - setTextureOffset("leg.toe", 184, 200); - setTextureOffset("tail.box", 128, 136); - setTextureOffset("tail.fin", 128, 200); - setTextureOffset("neck.box", 128, 136); - setTextureOffset("neck.fin", 128, 200); - setTextureOffset("head.box", 272, 0); - setTextureOffset("head.upperlip", 272, 56); - setTextureOffset("head.fin", 128, 200); - setTextureOffset("jaw.jaw", 272, 92); - setTextureOffset("frill.frill", 272, 200); - - body = new ModelRenderer(this, "body"); - body.setRotationPoint(0F, -12F, 0F); - body.addBox("body", -48F, 0F, 0F, 96, 96, 40); - setRotation(body, 1.22173F, 0F, 0F); - - leg1 = new ModelRenderer(this, "leg"); - leg1.setRotationPoint(48F, -24F, 0F); - leg1.addBox("main", -16F, 0F, -16F, 32, 48, 32); - leg1.addBox("toe", -20F, 40F, -20F, 8, 8, 8); - leg1.addBox("toe", -4F, 40F, -22F, 8, 8, 8); - leg1.addBox("toe", 12F, 40F, -20F, 8, 8, 8); - - leg2 = new ModelRenderer(this, "leg"); - leg2.setRotationPoint(-48F, -24F, 0F); - leg2.mirror = true; - leg2.addBox("main", -16F, 0F, -16F, 32, 48, 32); - leg2.addBox("toe", -20F, 40F, -20F, 8, 8, 8); - leg2.addBox("toe", -4F, 40F, -22F, 8, 8, 8); - leg2.addBox("toe", 12F, 40F, -20F, 8, 8, 8); - - - tail1 = new ModelRenderer(this, "tail"); - tail1.setRotationPoint(0F, 6F, 108F); - tail1.addBox("box", -16F, -16F, -16F, 32, 32, 32); - tail1.addBox("fin", -2F, -28F, -11F, 4, 24, 24); - - tail2 = new ModelRenderer(this, "tail"); - tail2.addBox("box", -16F, -16F, -16F, 32, 32, 32); - tail2.addBox("fin", -2F, -28F, -11F, 4, 24, 24); - tail2.setRotationPoint(0F, 7F, 142F); - - tail3 = new ModelRenderer(this, "tail"); - tail3.addBox("box", -16F, -16F, -16F, 32, 32, 32); - tail3.addBox("fin", -2F, -28F, -11F, 4, 24, 24); - tail3.setRotationPoint(0F, 8F, 176F); - - tail4 = new ModelRenderer(this, "tail"); - tail4.addBox("box", -16F, -16F, -16F, 32, 32, 32); - tail4.addBox("fin", -2F, -28F, -11F, 4, 24, 24); - tail4.setRotationPoint(0F, 8F, 210F); - - neck1a = new ModelRenderer(this, "neck"); - neck1a.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck1a.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck1a.setRotationPoint(0F, -48F, 16F); - - neck1b = new ModelRenderer(this, "neck"); - neck1b.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck1b.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck1b.setRotationPoint(0F, -68F, 0F); - - neck1c = new ModelRenderer(this, "neck"); - neck1c.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck1c.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck1c.setRotationPoint(0F, -93F, -14F); - - neck1d = new ModelRenderer(this, "neck"); - neck1d.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck1d.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck1d.setRotationPoint(0F, -116F, -37F); - - - head1 = new ModelRenderer(this, "head"); - head1.addBox("box", -16F, -14F, -32F, 32, 24, 32); - head1.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); - head1.addBox("fin", -2F, -30F, -12F, 4, 24, 24); - head1.setRotationPoint(0F, -128F, -53F); - - jaw1 = new ModelRenderer(this, "jaw"); - jaw1.setRotationPoint(0F, 10F, -4F); - jaw1.addBox("jaw", -15F, 0F, -48F, 30, 8, 48); - setRotation(jaw1, 0F, 0F, 0F); - head1.addChild(jaw1); - - frill1 = new ModelRenderer(this, "frill"); - frill1.setRotationPoint(0F, 0F, -10F); - frill1.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); - setRotation(frill1, -0.5235988F, 0F, 0F); - head1.addChild(frill1); - - neck2a = new ModelRenderer(this, "neck"); - neck2a.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck2a.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck2a.setRotationPoint(48F, -48F, 16F); - - neck2b = new ModelRenderer(this, "neck"); - neck2b.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck2b.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck2b.setRotationPoint(71F, -68F, 0F); - - neck2c = new ModelRenderer(this, "neck"); - neck2c.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck2c.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck2c.setRotationPoint(96F, -93F, -14F); - - neck2d = new ModelRenderer(this, "neck"); - neck2d.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck2d.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck2d.setRotationPoint(108F, -116F, -37F); - - head2 = new ModelRenderer(this, "head"); - head2.addBox("box", -16F, -14F, -32F, 32, 24, 32); - head2.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); - head2.addBox("fin", -2F, -30F, -12F, 4, 24, 24); - head2.setRotationPoint(108F, -128F, -53F); - - jaw2 = new ModelRenderer(this, "jaw"); - jaw2.setRotationPoint(0F, 10F, -4F); - jaw2.addBox("jaw", -15F, 0F, -48F, 30, 8, 48); - setRotation(jaw2, 0F, 0F, 0F); - head2.addChild(jaw2); - - frill2 = new ModelRenderer(this, "frill"); - frill2.setRotationPoint(0F, 0F, -10F); - frill2.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); - setRotation(frill2, -0.5235988F, 0F, 0F); - head2.addChild(frill2); - - - neck3a = new ModelRenderer(this, "neck"); - neck3a.addBox("box", -16F, -16F, -16F, 32, 32, 31); - neck3a.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck3a.setRotationPoint(-48F, -48F, 16F); - - neck3b = new ModelRenderer(this, "neck"); - neck3b.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck3b.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck3b.setRotationPoint(-71F, -43F, 0F); - - neck3c = new ModelRenderer(this, "neck"); - neck3c.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck3c.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck3c.setRotationPoint(-96F, -33F, -14F); - - neck3d = new ModelRenderer(this, "neck"); - neck3d.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck3d.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck3d.setRotationPoint(-108F, -24F, -37F); - - - head3 = new ModelRenderer(this, "head"); - head3.addBox("box", -16F, -14F, -32F, 32, 24, 32); - head3.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); - head3.addBox("fin", -2F, -30F, -12F, 4, 24, 24); - head3.setRotationPoint(-108F, -24F, -53F); - - jaw3 = new ModelRenderer(this, "jaw"); - jaw3.setRotationPoint(0F, 10F, -4F); - jaw3.addBox("jaw", -15F, 0F, -48F, 30, 8, 48); - setRotation(jaw3, 0.125F, 0F, 0F); - head3.addChild(jaw3); - - frill3 = new ModelRenderer(this, "frill"); - frill3.setRotationPoint(0F, 0F, -10F); - frill3.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); - setRotation(frill3, -0.5235988F, 0F, 0F); - head3.addChild(frill3); - - } - - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - body.render(f5); - leg1.render(f5); - leg2.render(f5); - tail1.render(f5); - tail2.render(f5); - tail3.render(f5); - tail4.render(f5); -// neck1a.render(f5); -// neck1b.render(f5); -// neck1c.render(f5); -// neck1d.render(f5); -// head1.render(f5); -// neck2a.render(f5); -// neck2b.render(f5); -// neck2c.render(f5); -// neck2d.render(f5); -// head2.render(f5); -// neck3a.render(f5); -// neck3b.render(f5); -// neck3c.render(f5); -// neck3d.render(f5); -// head3.render(f5); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) - { - super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); - - leg1.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1; - leg2.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1; - - leg1.rotateAngleY = 0.0F; - leg2.rotateAngleY = 0.0F; - - } - - - -// @Override -// public void setLivingAnimations(EntityLiving entityliving, float f, float f1, float time) { -// EntityTFHydra hydra = (EntityTFHydra)entityliving; -// -// // position the heads -// Vec3 vec; -// -// vec = Vec3.getVec3Pool().getVecFromPool(0, 0, 7*-16); -// vec.rotateAroundX((60 * 3.141593F) / 180F); -// vec.rotateAroundY((0 * 3.141593F) / 180F); -// head1.setRotationPoint((float)vec.xCoord, (float)vec.yCoord - 48, (float)vec.zCoord); -// -// vec = Vec3.getVec3Pool().getVecFromPool(0, 0, 9*-16); -// vec.rotateAroundX((45 * 3.141593F) / 180F); -// vec.rotateAroundY((-60 * 3.141593F) / 180F); -// head2.setRotationPoint((float)vec.xCoord, (float)vec.yCoord - 48, (float)vec.zCoord); -// -// vec = Vec3.getVec3Pool().getVecFromPool(0, 0, 9*-16); -// vec.rotateAroundX((-10 * 3.141593F) / 180F); -// vec.rotateAroundY((60 * 3.141593F) / 180F); -// head3.setRotationPoint((float)vec.xCoord, (float)vec.yCoord - 48, (float)vec.zCoord); -// -// // rotate the heads -// if (hydra.head1 != null) -// { -// head1.rotateAngleY = getRotationY(hydra, hydra.head1, time); -// head1.rotateAngleX = getRotationX(hydra, hydra.head1, time); -// -// head2.rotateAngleY = getRotationY(hydra, hydra.head3, time); -// head2.rotateAngleX = getRotationX(hydra, hydra.head3, time); -// -// head3.rotateAngleY = getRotationY(hydra, hydra.head2, time); -// head3.rotateAngleX = getRotationX(hydra, hydra.head2, time) - 0.015F; -// } -// } - - public float getRotationY(EntityTFHydra hydra, EntityTFHydraPart whichHead, float time) { - - float yawOffset = hydra.prevRenderYawOffset + (hydra.renderYawOffset - hydra.prevRenderYawOffset) * time; - float yaw = whichHead.prevRotationYaw + (whichHead.rotationYaw - whichHead.prevRotationYaw) * time; - - return (yaw - yawOffset) / 57.29578F; - } - - public float getRotationX(EntityTFHydra hydra, EntityTFHydraPart whichHead, float time) { - - return (whichHead.prevRotationPitch + (whichHead.rotationPitch - whichHead.prevRotationPitch) * time) / 57.29578F; - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFHydraHead.java b/src/main/java/twilightforest/client/model/ModelTFHydraHead.java deleted file mode 100644 index 6c2d6039a9..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFHydraHead.java +++ /dev/null @@ -1,133 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import twilightforest.entity.boss.EntityTFHydraHead; -import twilightforest.entity.boss.EntityTFHydraPart; - - -public class ModelTFHydraHead extends ModelBase { - - ModelRenderer head; - ModelRenderer jaw; - ModelRenderer frill; - - public ModelTFHydraHead() - { - textureWidth = 512; - textureHeight = 256; - - setTextureOffset("head.box", 272, 0); - setTextureOffset("head.upperlip", 272, 56); - setTextureOffset("head.rearjaw", 272, 132); - setTextureOffset("head.fin", 128, 200); - setTextureOffset("head.fang1", 272, 156); - setTextureOffset("head.fang2", 272, 156); - setTextureOffset("head.teeth", 280, 156); - setTextureOffset("head.teeth2", 280, 160); - setTextureOffset("head.teeth3", 280, 160); - setTextureOffset("jaw.jaw", 272, 92); - setTextureOffset("jaw.fang1", 272, 156); - setTextureOffset("jaw.fang2", 272, 156); - setTextureOffset("jaw.teeth", 280, 156); - setTextureOffset("jaw.teeth2", 280, 160); - setTextureOffset("jaw.teeth3", 280, 160); - setTextureOffset("frill.frill", 272, 200); - - - head = new ModelRenderer(this, "head"); - head.addBox("box", -16F, -14F, -32F, 32, 24, 32); - head.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); - head.addBox("rearjaw", -15F, 10F, -20F, 30, 8, 16); - head.addBox("fin", -2F, -30F, -12F, 4, 24, 24); - head.addBox("fang1", -12F, 10, -49F, 2, 5, 2); - head.addBox("fang2", 10F, 10, -49F, 2, 5, 2); - head.addBox("teeth", -8F, 9, -49F, 16, 2, 2); - head.addBox("teeth2", -10F, 9, -45F, 2, 2, 16); - head.addBox("teeth3", 8F, 9, -45F, 2, 2, 16); - head.setRotationPoint(0F, 0F, 0F); - - jaw = new ModelRenderer(this, "jaw"); - jaw.setRotationPoint(0F, 10F, -20F); - jaw.addBox("jaw", -15F, 0F, -32F, 30, 8, 32); - jaw.addBox("fang1", -10F, -5, -29F, 2, 5, 2); - jaw.addBox("fang2", 8F, -5, -29F, 2, 5, 2); - jaw.addBox("teeth", -8F, -1, -29F, 16, 2, 2); - jaw.addBox("teeth2", -10F, -1, -25F, 2, 2, 16); - jaw.addBox("teeth3", 8F, -1, -25F, 2, 2, 16); - setRotation(jaw, 0F, 0F, 0F); - head.addChild(jaw); - - frill = new ModelRenderer(this, "frill"); - frill.setRotationPoint(0F, 0F, -14F); - frill.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); - setRotation(frill, -0.5235988F, 0F, 0F); - head.addChild(frill); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - head.render(f5); - } - - public void render(float f5) - { - head.render(f5); - } - - @Override - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity par7Entity) - { - //System.out.println("Setting head rotation to " + f3 + ", " + f4); - -// head.rotateAngleY = f3 / (180F / (float)Math.PI); -// head.rotateAngleX = f4 / (180F / (float)Math.PI); - } - - @Override - public void setLivingAnimations(EntityLivingBase entityliving, float f, float f1, float time) { - EntityTFHydraHead whichHead = (EntityTFHydraHead)entityliving; - - head.rotateAngleY = getRotationY(whichHead, time); - head.rotateAngleX = getRotationX(whichHead, time); - - float mouthOpen = whichHead.getMouthOpen(); - head.rotateAngleX -= (float) (mouthOpen * (Math.PI / 12.0)); - jaw.rotateAngleX = (float) (mouthOpen * (Math.PI / 3.0)); - } - - public void openMouthForTrophy(float mouthOpen) { - head.rotateAngleY = 0; - head.rotateAngleX = 0; - - head.rotateAngleX -= (float) (mouthOpen * (Math.PI / 12.0)); - jaw.rotateAngleX = (float) (mouthOpen * (Math.PI / 3.0)); - - } - - public float getRotationY(EntityTFHydraPart whichHead, float time) { - - //float yawOffset = hydra.prevRenderYawOffset + (hydra.renderYawOffset - hydra.prevRenderYawOffset) * time; - float yaw = whichHead.prevRotationYaw + (whichHead.rotationYaw - whichHead.prevRotationYaw) * time; - - return yaw / 57.29578F; - } - - public float getRotationX(EntityTFHydraPart whichHead, float time) { - - return (whichHead.prevRotationPitch + (whichHead.rotationPitch - whichHead.prevRotationPitch) * time) / 57.29578F; - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFHydraMortar.java b/src/main/java/twilightforest/client/model/ModelTFHydraMortar.java deleted file mode 100644 index 0426c72f96..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFHydraMortar.java +++ /dev/null @@ -1,24 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; - -public class ModelTFHydraMortar extends ModelBase -{ - - public ModelRenderer box; - - public ModelTFHydraMortar() - { - textureWidth = 32; - textureHeight = 32; - box = new ModelRenderer(this, 0, 0); - box.addBox(-4F, 0F, -4F, 8, 8, 8, 0F); - box.setRotationPoint(0F, 0F, 0F); - } - - public void render(float f5) - { - box.render(f5); - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFHydraNeck.java b/src/main/java/twilightforest/client/model/ModelTFHydraNeck.java deleted file mode 100644 index d80a7f8253..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFHydraNeck.java +++ /dev/null @@ -1,42 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; - - -public class ModelTFHydraNeck extends ModelBase { - - ModelRenderer neck; - - public ModelTFHydraNeck() - { - textureWidth = 512; - textureHeight = 256; - - setTextureOffset("neck.box", 128, 136); - setTextureOffset("neck.fin", 128, 200); - neck = new ModelRenderer(this, "neck"); - neck.addBox("box", -16F, -16F, -16F, 32, 32, 32); - neck.addBox("fin", -2F, -23F, 0F, 4, 24, 24); - neck.setRotationPoint(0F, 0F, 0F); - - } - - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - neck.render(f5); - } - - @Override - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) - { - neck.rotateAngleY = f3 / 57.29578F; - neck.rotateAngleX = f4 / 57.29578F; - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFIceCrystal.java b/src/main/java/twilightforest/client/model/ModelTFIceCrystal.java deleted file mode 100644 index ae4d2fd0ad..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFIceCrystal.java +++ /dev/null @@ -1,96 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - -import org.lwjgl.opengl.GL11; - -public class ModelTFIceCrystal extends ModelBase { - - public ModelRenderer[] spikes = new ModelRenderer[16]; - - - public ModelTFIceCrystal() { - this.textureWidth = 32; - this.textureHeight = 32; - - float par1 = 0F; - float par2 = 0F; - - // spikes - for (int i = 0; i < spikes.length; i++) { - this.spikes[i] = new ModelRenderer(this, 0, 16); - - int spikeLength = i % 2 == 0 ? 6 : 8; - - this.spikes[i].addBox(-1.0F, -1.0F, -1.0F, 2, spikeLength, 2, par1); - this.spikes[i].setRotationPoint(0.0F, 0.0F + par2, 0.0F); - - ModelRenderer cube = new ModelRenderer(this, 8, 16); - cube.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - cube.setRotationPoint(0.0F, spikeLength, 0.0F); - - cube.rotateAngleZ = (float) (Math.PI / 4F); - - this.spikes[i].addChild(cube); - - } - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - //this.bipedHead.render(f5); - - for (int i = 0; i < spikes.length; i++) { - - if (entity.isEntityAlive()) { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - GL11.glColor4f(1F, 1F, 1F, 0.6F); - } - - this.spikes[i].render(f5); - - GL11.glDisable(GL11.GL_BLEND); - - } - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float time) - { - for (int i = 0; i < spikes.length; i++) { - // rotate the spikes - this.spikes[i].rotateAngleX = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - this.spikes[i].rotateAngleY = (par1EntityLiving.ticksExisted + time) / 5.0F; - this.spikes[i].rotateAngleZ = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - - this.spikes[i].rotateAngleX += i * (Math.PI / 8F); - - if (i % 4 == 0) { - this.spikes[i].rotateAngleY += 1; - } else if (i % 4 == 2) { - this.spikes[i].rotateAngleY -= 1; - } - - //this.spikes[i].rotateAngleY += i * (Math.PI / 8F); - //this.spikes[i].rotateAngleZ += i * (Math.PI / 8F); - - -// this.spikes[i].rotationPointX = MathHelper.cos((par1EntityLiving.ticksExisted + time) / (float)i) * 3F; -// this.spikes[i].rotationPointY = 5F + MathHelper.sin((par1EntityLiving.ticksExisted + time) / (float)i) * 3F; -// this.spikes[i].rotationPointZ = MathHelper.sin((par1EntityLiving.ticksExisted + time) / (float)i) * 3F; - - //((ModelRenderer)this.spikes[i].childModels.get(0)).rotationPointY = 10 + MathHelper.sin((i + par1EntityLiving.ticksExisted + time) / i) * 3F; - - } - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFIceExploder.java b/src/main/java/twilightforest/client/model/ModelTFIceExploder.java deleted file mode 100644 index 175a565d36..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFIceExploder.java +++ /dev/null @@ -1,100 +0,0 @@ -package twilightforest.client.model; - -import org.lwjgl.opengl.GL11; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - -public class ModelTFIceExploder extends ModelBiped { - - public ModelRenderer[] spikes = new ModelRenderer[16]; - - - public ModelTFIceExploder() { - this.textureWidth = 32; - this.textureHeight = 32; - - float par1 = 0F; - float par2 = 0F; - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(-4.0F, 0.0F, -4.0F, 8, 8, 8, par1); - this.bipedHead.setRotationPoint(0.0F, 0.0F + par2, 0.0F); - - // delete all other body parts - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - this.bipedBody = new ModelRenderer(this, 0, 0); - this.bipedRightArm = new ModelRenderer(this, 0, 0); - this.bipedLeftArm = new ModelRenderer(this, 0, 0); - this.bipedRightLeg = new ModelRenderer(this, 0, 0); - this.bipedLeftLeg = new ModelRenderer(this, 0, 0); - - // spikes - - for (int i = 0; i < spikes.length; i++) { - this.spikes[i] = new ModelRenderer(this, 0, 16); - - int spikeLength = i % 2 == 0 ? 6 : 8; - - this.spikes[i].addBox(-1.0F, 6.0F, -1.0F, 2, spikeLength, 2, par1); - this.spikes[i].setRotationPoint(0.0F, 4.0F + par2, 0.0F); - - ModelRenderer cube = new ModelRenderer(this, 8, 16); - cube.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - cube.setRotationPoint(0.0F, 8F, 0.0F); - - cube.rotateAngleZ = (float) (Math.PI / 4F); - - this.spikes[i].addChild(cube); - - } - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - this.bipedHead.render(f5); - - for (int i = 0; i < spikes.length; i++) { - - if (entity.isEntityAlive()) { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - GL11.glColor4f(1F, 1F, 1F, 0.6F); - } - - this.spikes[i].render(f5); - - GL11.glDisable(GL11.GL_BLEND); - - } - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float time) - { - for (int i = 0; i < spikes.length; i++) { - // rotate the spikes - this.spikes[i].rotateAngleY = (par1EntityLiving.ticksExisted + time) / 5.0F; - this.spikes[i].rotateAngleX = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - this.spikes[i].rotateAngleZ = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - - this.spikes[i].rotateAngleX += i * 5; - this.spikes[i].rotateAngleY += i * 2.5f; - this.spikes[i].rotateAngleZ += i * 3; - - this.spikes[i].rotationPointX = MathHelper.cos((par1EntityLiving.ticksExisted + time) / (float)i) * 3F; - this.spikes[i].rotationPointY = 5F + MathHelper.sin((par1EntityLiving.ticksExisted + time) / (float)i) * 3F; - this.spikes[i].rotationPointZ = MathHelper.sin((par1EntityLiving.ticksExisted + time) / (float)i) * 3F; - - ((ModelRenderer)this.spikes[i].childModels.get(0)).rotationPointY = 10 + MathHelper.sin((i + par1EntityLiving.ticksExisted + time) / i) * 3F; - - } - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFIceShooter.java b/src/main/java/twilightforest/client/model/ModelTFIceShooter.java deleted file mode 100644 index 4687773526..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFIceShooter.java +++ /dev/null @@ -1,33 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - -public class ModelTFIceShooter extends ModelTFIceExploder { - - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float time) - { - for (int i = 0; i < spikes.length; i++) { - // rotate the spikes - this.spikes[i].rotateAngleY = (3.14159F / 2F) + (MathHelper.sin((par1EntityLiving.ticksExisted + time) / 5.0F) * 0.5F); - this.spikes[i].rotateAngleX = (par1EntityLiving.ticksExisted + time) / 5.0F; - this.spikes[i].rotateAngleZ = MathHelper.cos(i / 5.0F) / 4.0F; - - this.spikes[i].rotateAngleX += i * (Math.PI / 8F); - //this.spikes[i].rotateAngleY += i * 2.5f; - //this.spikes[i].rotateAngleZ += i * 3; - - ((ModelRenderer)this.spikes[i].childModels.get(0)).rotationPointY = 9.5F + MathHelper.sin((i + par1EntityLiving.ticksExisted + time) / 3F) * 3F; - - - //((ModelBox)this.spikes[i].cubeList.get(0)). = 6 + MathHelper.sin((par1EntityLiving.ticksExisted + time) / (float)i) * 3F; - - } - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFKnightPhantom.java b/src/main/java/twilightforest/client/model/ModelTFKnightPhantom.java deleted file mode 100644 index ac46259be0..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFKnightPhantom.java +++ /dev/null @@ -1,168 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -public class ModelTFKnightPhantom extends ModelBiped { - - public ModelRenderer helmet; - public ModelRenderer righthorn1; - public ModelRenderer righthorn2; - public ModelRenderer lefthorn1; - public ModelRenderer lefthorn2; - - - public ModelTFKnightPhantom() - { - this.heldItemLeft = 0; - this.heldItemRight = 0; - this.isSneak = false; - this.aimedBow = false; - this.textureWidth = 128; - this.textureHeight = 64; - - this.bipedCloak = new ModelRenderer(this, 0, 0); - this.bipedCloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1); - this.bipedEars = new ModelRenderer(this, 24, 0); - this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1); - - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(0, 0, 0, 0, 0, 0); - this.bipedHead.setRotationPoint(0.0F, -10.0F, 0.0F); - - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - this.bipedHeadwear.addBox(0, 0, 0, 0, 0, 0); - this.bipedHeadwear.setRotationPoint(0.0F, -10.0F, 0.0F); - - this.helmet = new ModelRenderer(this, 0, 0); - this.helmet.addBox(-4.0F, -11.0F, -4.0F, 8, 11, 8); - this.helmet.rotateAngleY = 45F / (180F / (float)Math.PI); - - this.righthorn1 = new ModelRenderer(this, 28, 0); - this.righthorn1.addBox(-6F, -1.5F, -1.5F, 7, 3, 3); - this.righthorn1.setRotationPoint(-3.5F, -9F, 0.0F); - this.righthorn1.rotateAngleY = 15F / (180F / (float)Math.PI); - this.righthorn1.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn2 = new ModelRenderer(this, 28, 6); - this.righthorn2.addBox(-3.0F, -1.0F, -1.0F, 3, 2, 2); - this.righthorn2.setRotationPoint(-5.5F, 0.0F, 0.0F); - this.righthorn2.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn1.addChild(righthorn2); - - this.lefthorn1 = new ModelRenderer(this, 28, 0); - this.lefthorn1.mirror = true; - this.lefthorn1.addBox(-1F, -1.5F, -1.5F, 7, 3, 3); - this.lefthorn1.setRotationPoint(3.5F, -9F, 0.0F); - this.lefthorn1.rotateAngleY = -15F / (180F / (float)Math.PI); - this.lefthorn1.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn2 = new ModelRenderer(this, 28, 6); - this.lefthorn2.addBox(0.0F, -1.0F, -1.0F, 3, 2, 2); - this.lefthorn2.setRotationPoint(5.5F, 0.0F, 0.0F); - this.lefthorn2.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn1.addChild(lefthorn2); - - this.bipedHeadwear.addChild(helmet); - this.bipedHeadwear.addChild(righthorn1); - this.bipedHeadwear.addChild(lefthorn1); - - this.bipedBody = new ModelRenderer(this, 0, 18); - this.bipedBody.setRotationPoint(0.0F, 2.0F, 0.0F); - this.bipedBody.addBox(-7.0F, -12.0F, -3.5F, 14, 12, 7); - this.bipedBody.setTextureOffset(30, 24).addBox(-6.0F, 0F, -3F, 12, 8, 6); // torso - - this.bipedRightArm = new ModelRenderer(this, 44, 16); - this.bipedRightArm.addBox(-5.0F, -2.0F, -3.0F, 6, 7, 6); - this.bipedRightArm.setRotationPoint(-8.0F, -8.0F, 0.0F); - - this.bipedLeftArm = new ModelRenderer(this, 44, 16); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(-1.0F, -2.0F, -3.0F, 6, 7, 6); - this.bipedLeftArm.setRotationPoint(8.0F, -8.0F, 0.0F); - - this.bipedRightLeg = new ModelRenderer(this, 0, 0); - this.bipedRightLeg.addBox(0, 0, 0, 0, 0, 0); - this.bipedRightLeg.setRotationPoint(0.0F, 12.0F, 0.0F); - - this.bipedLeftLeg = new ModelRenderer(this, 0, 0); - this.bipedLeftLeg.addBox(0, 0, 0, 0, 0, 0); - this.bipedLeftLeg.setRotationPoint(0.0F, 12.0F, 0.0F); - - - - } - - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleZ = 0; - this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; - this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; - this.bipedHeadwear.rotateAngleZ = this.bipedHead.rotateAngleZ; - - - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - - -// this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; -// this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; -// this.bipedRightLeg.rotateAngleY = 0.0F; -// this.bipedLeftLeg.rotateAngleY = 0.0F; -// -// if (this.isRiding) -// { -// this.bipedRightArm.rotateAngleX += -((float)Math.PI / 5F); -// this.bipedLeftArm.rotateAngleX += -((float)Math.PI / 5F); -// this.bipedRightLeg.rotateAngleX = 0; -// this.bipedLeftLeg.rotateAngleX = 0; -//// this.bipedRightLeg.rotateAngleY = ((float)Math.PI / 10F); -//// this.bipedLeftLeg.rotateAngleY = -((float)Math.PI / 10F); -// } - - if (this.heldItemLeft != 0) - { - this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemLeft; - } - - this.heldItemRight = 1; - - if (this.heldItemRight != 0) - { - this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemRight; - } -// -// bipedRightArm.rotateAngleX -= (Math.PI * 0.66); -// -// // during swing move arm forward -// if (upperKnight.heavySpearTimer > 0) -// { -// bipedRightArm.rotateAngleX -= this.getArmRotationDuringSwing(60 - upperKnight.heavySpearTimer + par6) / (180F / (float)Math.PI); -// } - -// this.bipedRightArm.rotateAngleY = 0.0F; -// this.bipedLeftArm.rotateAngleY = 0.0F; - - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFKnightPhantom2.java b/src/main/java/twilightforest/client/model/ModelTFKnightPhantom2.java deleted file mode 100644 index f721c7273c..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFKnightPhantom2.java +++ /dev/null @@ -1,72 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import twilightforest.entity.boss.EntityTFKnightPhantom; - -public class ModelTFKnightPhantom2 extends ModelBiped { - - public ModelTFKnightPhantom2() - { - this(0.0F); - } - - public ModelTFKnightPhantom2(float par1) - { - super(par1, 0.0F, 64, 32); - this.bipedRightArm = new ModelRenderer(this, 40, 16); - this.bipedRightArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1); - this.bipedRightArm.setRotationPoint(-5.0F, 2.0F, 0.0F); - this.bipedLeftArm = new ModelRenderer(this, 40, 16); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1); - this.bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); - this.bipedRightLeg = new ModelRenderer(this, 0, 16); - this.bipedRightLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1); - this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F, 0.0F); - this.bipedLeftLeg = new ModelRenderer(this, 0, 16); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1); - this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F, 0.0F); - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); - - if (((EntityTFKnightPhantom)par1Entity).isChargingAtPlayer()) - { - // render full skeleton - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - } - } - - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); - this.bipedLeftLeg.rotateAngleX = 0; - this.bipedLeftLeg.rotateAngleY = 0; - this.bipedLeftLeg.rotateAngleZ = 0; - - this.bipedRightLeg.rotateAngleX = 0; - this.bipedRightLeg.rotateAngleY = 0; - this.bipedRightLeg.rotateAngleZ = 0; - - this.bipedRightLeg.rotateAngleX = 0.2F * MathHelper.sin(par3 * 0.3F) + 0.4F; - this.bipedLeftLeg.rotateAngleX = 0.2F * MathHelper.sin(par3 * 0.3F) + 0.4F; - - - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFKnightlyArmor.java b/src/main/java/twilightforest/client/model/ModelTFKnightlyArmor.java deleted file mode 100644 index 568b0c7cba..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFKnightlyArmor.java +++ /dev/null @@ -1,152 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; - -public class ModelTFKnightlyArmor extends ModelBiped { - - public ModelRenderer righthorn1; - public ModelRenderer righthorn2; - public ModelRenderer lefthorn1; - public ModelRenderer lefthorn2; - - public ModelRenderer shoulderSpike1; - public ModelRenderer shoulderSpike2; - - public ModelRenderer shoeSpike1; - public ModelRenderer shoeSpike2; - - - public ModelTFKnightlyArmor(int part, float expand) - { - super(expand); - - this.righthorn1 = new ModelRenderer(this, 32, 0); - this.righthorn1.addBox(-5.5F, -1.5F, -1.5F, 5, 3, 3); - this.righthorn1.setRotationPoint(-4.0F, -6.5F, 0.0F); - this.righthorn1.rotateAngleY = -15F / (180F / (float)Math.PI); - this.righthorn1.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn2 = new ModelRenderer(this, 32, 6); - this.righthorn2.addBox(-3.5F, -1.0F, -1.0F, 3, 2, 2); - this.righthorn2.setRotationPoint(-4.5F, 0.0F, 0.0F); - this.righthorn2.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn1.addChild(righthorn2); - - this.lefthorn1 = new ModelRenderer(this, 32, 0); - this.lefthorn1.mirror = true; - this.lefthorn1.addBox(0.5F, -1.5F, -1.5F, 5, 3, 3); - this.lefthorn1.setRotationPoint(4.0F, -6.5F, 0.0F); - this.lefthorn1.rotateAngleY = 15F / (180F / (float)Math.PI); - this.lefthorn1.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn2 = new ModelRenderer(this, 32, 6); - this.lefthorn2.addBox(0.5F, -1.0F, -1.0F, 3, 2, 2); - this.lefthorn2.setRotationPoint(4.5F, 0.0F, 0.0F); - this.lefthorn2.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn1.addChild(lefthorn2); - - this.bipedHead.addChild(righthorn1); - this.bipedHead.addChild(lefthorn1); - - - this.shoulderSpike1 = new ModelRenderer(this, 32, 10); - this.shoulderSpike1.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); - this.shoulderSpike1.setRotationPoint(-3.75F, -2.5F, 0.0F); - this.shoulderSpike1.rotateAngleX = 45F / (180F / (float)Math.PI); - this.shoulderSpike1.rotateAngleY = 10F / (180F / (float)Math.PI); - this.shoulderSpike1.rotateAngleZ = 35F / (180F / (float)Math.PI); - - this.bipedRightArm.addChild(shoulderSpike1); - - this.shoulderSpike2 = new ModelRenderer(this, 32, 10); - this.shoulderSpike2.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); - this.shoulderSpike2.setRotationPoint(3.75F, -2.5F, 0.0F); - this.shoulderSpike2.rotateAngleX = -45F / (180F / (float)Math.PI); - this.shoulderSpike2.rotateAngleY = -10F / (180F / (float)Math.PI); - this.shoulderSpike2.rotateAngleZ = 55F / (180F / (float)Math.PI); - - this.bipedLeftArm.addChild(shoulderSpike2); - - this.shoeSpike1 = new ModelRenderer(this, 32, 10); - this.shoeSpike1.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); - this.shoeSpike1.setRotationPoint(-2.5F, 11F, 2.0F); - this.shoeSpike1.rotateAngleY = -45F / (180F / (float)Math.PI); - - this.bipedRightLeg.addChild(shoeSpike1); - - this.shoeSpike2 = new ModelRenderer(this, 32, 10); - this.shoeSpike2.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); - this.shoeSpike2.setRotationPoint(2.5F, 11F, 2.0F); - this.shoeSpike2.rotateAngleY = 45F / (180F / (float)Math.PI); - - this.bipedLeftLeg.addChild(shoeSpike2); - - - - switch (part) - { - case 0: // helmet - this.bipedHead.showModel = true; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 1: // chest - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = true; - this.bipedRightArm.showModel = true; - this.bipedLeftArm.showModel = true; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 2: // pants - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = true; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - break; - case 3: // boots - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - break; - - } - } - - - /** - * Sets the models various rotation angles then renders the model. - */ - @Override - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { - - if (par1Entity != null) { - this.isSneak = par1Entity.isSneaking(); - } - - if (par1Entity != null && par1Entity instanceof EntityLivingBase) { - this.heldItemRight = ((EntityLivingBase)par1Entity).getHeldItem() != null ? 1 : 0; - } - - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFKobold.java b/src/main/java/twilightforest/client/model/ModelTFKobold.java deleted file mode 100644 index 7716ba651c..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFKobold.java +++ /dev/null @@ -1,150 +0,0 @@ -// Date: 6/11/2012 3:12:45 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - -public class ModelTFKobold extends ModelBiped -{ - //fields - - ModelRenderer rightear; - ModelRenderer leftear; - ModelRenderer snout; - ModelRenderer jaw; - - boolean isJumping; - - public ModelTFKobold() - { - isJumping = false; - - textureWidth = 64; - textureHeight = 32; - - bipedHead = new ModelRenderer(this, 0, 0); - bipedHead.addBox(-3.5F, -7F, -3F, 7, 6, 6); - bipedHead.setRotationPoint(0F, 13F, 0F); - - bipedBody = new ModelRenderer(this, 12, 19); - bipedBody.addBox(0F, 0F, 0F, 7, 7, 4); - bipedBody.setRotationPoint(-3.5F, 12F, -2F); - - bipedRightArm = new ModelRenderer(this, 36, 17); - bipedRightArm.addBox(-3F, -1F, -1.5F, 3, 7, 3); - bipedRightArm.setRotationPoint(-3.5F, 12F, 0F); - - bipedLeftArm.mirror = true; - bipedLeftArm = new ModelRenderer(this, 36, 17); - bipedLeftArm.addBox(0F, -1F, -1.5F, 3, 7, 3); - bipedLeftArm.setRotationPoint(3.5F, 12F, 0F); - - bipedLeftArm.mirror = false; - bipedRightLeg = new ModelRenderer(this, 0, 20); - bipedRightLeg.addBox(-1.5F, 0F, -1.5F, 3, 5, 3); - bipedRightLeg.setRotationPoint(-2F, 19F, 0F); - - bipedLeftLeg = new ModelRenderer(this, 0, 20); - bipedLeftLeg.addBox(-1.5F, 0F, -1.5F, 3, 5, 3); - bipedLeftLeg.setRotationPoint(2F, 19F, 0F); - - rightear = new ModelRenderer(this, 48, 20); - rightear.addBox(0F, -4F, 0F, 4, 4, 1); - rightear.setRotationPoint(3.5F, -3F, -1F); - rightear.rotateAngleY = 0.2617994F; - rightear.rotateAngleZ = -0.3490659F; - - bipedHead.addChild(rightear); - - leftear = new ModelRenderer(this, 48, 25); - leftear.addBox(-4F, -4F, 0F, 4, 4, 1); - leftear.setRotationPoint(-3.5F, -3F, -1F); - leftear.rotateAngleY = -0.2617994F; - leftear.rotateAngleZ = 0.3490659F; - - bipedHead.addChild(leftear); - - - snout = new ModelRenderer(this, 28, 0); - snout.addBox(-1.5F, -2F, -2F, 3, 2, 3); - snout.setRotationPoint(0F, -2F, -3F); - - bipedHead.addChild(snout); - - jaw = new ModelRenderer(this, 28, 5); - jaw.addBox(-1.5F, 0F, -2F, 3, 1, 3); - jaw.setRotationPoint(0F, -2F, -3F); - jaw.rotateAngleX = 0.20944F; - - bipedHead.addChild(jaw); -} - - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6) - { - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - - this.bipedRightArm.rotateAngleX = -((float)Math.PI * .15F); - this.bipedLeftArm.rotateAngleX = -((float)Math.PI * .15F); - - - this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.bipedRightLeg.rotateAngleY = 0.0F; - this.bipedLeftLeg.rotateAngleY = 0.0F; - - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.19F) * 0.15F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.19F) * 0.15F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.267F) * 0.25F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.267F) * 0.25F; - - if (this.isJumping) { - // open jaw - this.jaw.rotateAngleX = 1.44F; - } - else { - this.jaw.rotateAngleX = 0.20944F; - } - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float partialTick) { - // check if entity is jumping - this.isJumping = par1EntityLiving.motionY > 0; - } - - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - setRotationAngles(f, f1, f2, f3, f4, f5); - bipedHead.render(f5); - bipedBody.render(f5); - bipedRightArm.render(f5); - bipedLeftArm.render(f5); - bipedRightLeg.render(f5); - bipedLeftLeg.render(f5); - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFLich.java b/src/main/java/twilightforest/client/model/ModelTFLich.java deleted file mode 100644 index f551ff2a97..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFLich.java +++ /dev/null @@ -1,191 +0,0 @@ -package twilightforest.client.model; - - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; -import twilightforest.entity.boss.EntityTFLich; - - - -public class ModelTFLich extends ModelBiped { - - - ModelRenderer collar; - ModelRenderer cloak; - ModelRenderer shieldBelt; - - boolean renderPass = false; - - public ModelTFLich() { - this.renderPass = false; - - textureWidth = 64; - textureHeight = 64; - - - bipedBody = new ModelRenderer(this, 8, 16); - bipedBody.addBox(-4F, 0.0F, -2F, 8, 24, 4); - bipedBody.setRotationPoint(0.0F, -4.0F, 0.0F); - bipedBody.setTextureSize(64, 64); - - bipedRightArm = new ModelRenderer(this, 0, 16); - bipedRightArm.addBox(-2F, -2F, -1F, 2, 12, 2); - bipedRightArm.setTextureSize(64, 64); - bipedRightArm.setRotationPoint(-5F, -2.0F, 0.0F); - - bipedLeftArm = new ModelRenderer(this, 0, 16); - bipedLeftArm.mirror = true; - bipedLeftArm.addBox(-2F, -2F, -1F, 2, 12, 2); - bipedLeftArm.setRotationPoint(5F, -2.0F, 0.0F); - bipedLeftArm.setTextureSize(64, 64); - - bipedHeadwear = new ModelRenderer(this, 32, 0); - bipedHeadwear.addBox(-4F, -12F, -4F, 8, 8, 8, 0.5F); - bipedHeadwear.setRotationPoint(0.0F, -4.0F, 0.0F); - bipedHeadwear.setTextureSize(64, 64); - - bipedHead = new ModelRenderer(this, 0, 0); - bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8); - bipedHead.setRotationPoint(0F, -4F, 0F); - bipedHead.setTextureSize(64, 64); - - bipedRightLeg = new ModelRenderer(this, 0, 16); - bipedRightLeg.addBox(-1F, 0F, -1F, 2, 12, 2); - bipedRightLeg.setRotationPoint(-2F, 9.5F, 0F); - bipedRightLeg.setTextureSize(64, 64); - - bipedLeftLeg = new ModelRenderer(this, 0, 16); - bipedLeftLeg.addBox(-1F, 0F, -1F, 2, 12, 2); - bipedLeftLeg.setRotationPoint(2F, 9.5F, 0F); - bipedLeftLeg.setTextureSize(64, 64); - bipedLeftLeg.mirror = true; - - collar = new ModelRenderer(this, 32, 16); - collar.addBox(-6F, 0F, 0F, 12, 12, 1); - collar.setRotationPoint(0F, -3F, -1F); - collar.setTextureSize(64, 64); - setRotation(collar, 2.164208F, 0F, 0F); - - - cloak = new ModelRenderer(this, 0, 44); - cloak.addBox(-6F, 0F, 0F, 12, 19, 1); - cloak.setRotationPoint(0F, -4F, 2.5F); - cloak.setTextureSize(64, 64); - setRotation(cloak, 0F, 0F, 0F); - - shieldBelt = new ModelRenderer(this); - shieldBelt.setRotationPoint(0F, 0F, 0F); - - } - - public ModelTFLich(boolean specialRenderModel) { - this(); - this.renderPass = specialRenderModel; - } - - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - EntityTFLich lich = (EntityTFLich)entity; - - // on regular pass, render everything about the master lich except the shield - if (!renderPass) { - if (!lich.isShadowClone()) { - super.render(entity, f, f1, f2, f3, f4, f5 * 1.125F); - collar.render(f5 * 1.125F); - cloak.render(f5 * 1.125F); - } - } - else { - // on the special render pass, render the shadow clone and the shield - if (lich.isShadowClone()) { -// GL11.glDisable(GL11.GL_DEPTH_TEST); - - super.render(entity, f, f1, f2, f3, f4, f5 * 1.125F); -// GL11.glEnable(GL11.GL_DEPTH_TEST); - - } else { - if (lich.getShieldStrength() > 0) { - shieldBelt.render(f5 * 1.125F); - } - } - } - - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float time) - { - EntityTFLich lich = (EntityTFLich)par1EntityLiving; - // make the shield belt - int shields = lich.getShieldStrength(); - if (!lich.isShadowClone() && shields > 0) { - if (shieldBelt.childModels == null || shieldBelt.childModels.size() != shields) { - // clear shields if we have the wrong number - if (shieldBelt.childModels != null) { - shieldBelt.childModels.clear(); - } - // make or remake a belt of shields around the lich - Vec3 vec; - for (int i = 0; i < shields; i++) { - vec = Vec3.createVectorHelper(11, 0, 0); - float rotateY = ((i * (360F / shields)) * 3.141593F) / 180F; - vec.rotateAroundY(rotateY); - ModelRenderer shield = new ModelRenderer(this, 26, 40); - shield.addBox(0.5F, -6F, -6F, 1, 12, 12); - shield.setRotationPoint((float)vec.xCoord, (float)vec.yCoord, (float)vec.zCoord); - shield.setTextureSize(64, 64); - shield.rotateAngleY = rotateY; - shieldBelt.addChild(shield); - } - } - - // rotate the belt - shieldBelt.rotateAngleY = (lich.ticksExisted + time) / 5.0F; - shieldBelt.rotateAngleX = MathHelper.sin((lich.ticksExisted + time) / 5.0F) / 4.0F; - shieldBelt.rotateAngleZ = MathHelper.cos((lich.ticksExisted + time) / 5.0F) / 4.0F; - } - } - - @Override - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) - { - aimedBow = false; - super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); - float ogSin = MathHelper.sin(onGround * 3.141593F); - float otherSin = MathHelper.sin((1.0F - (1.0F - onGround) * (1.0F - onGround)) * 3.141593F); - bipedRightArm.rotateAngleZ = 0.0F; - bipedLeftArm.rotateAngleZ = 0.5F; - bipedRightArm.rotateAngleY = -(0.1F - ogSin * 0.6F); - bipedLeftArm.rotateAngleY = 0.1F - ogSin * 0.6F; - bipedRightArm.rotateAngleX = -1.570796F; - bipedLeftArm.rotateAngleX = -3.141593F; - bipedRightArm.rotateAngleX -= ogSin * 1.2F - otherSin * 0.4F; - bipedLeftArm.rotateAngleX -= ogSin * 1.2F - otherSin * 0.4F; - bipedRightArm.rotateAngleZ += MathHelper.cos(f2 * 0.26F) * 0.15F + 0.05F; - bipedLeftArm.rotateAngleZ -= MathHelper.cos(f2 * 0.26F) * 0.15F + 0.05F; - bipedRightArm.rotateAngleX += MathHelper.sin(f2 * 0.167F) * 0.15F; - bipedLeftArm.rotateAngleX -= MathHelper.sin(f2 * 0.167F) * 0.15F; - - bipedHead.rotationPointY = -4.0F; - bipedHeadwear.rotationPointY = -4.0F; - bipedRightLeg.rotationPointY = 9.5F; - bipedLeftLeg.rotationPointY = 9.5F; - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFLichMinion.java b/src/main/java/twilightforest/client/model/ModelTFLichMinion.java deleted file mode 100644 index a125b1a833..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFLichMinion.java +++ /dev/null @@ -1,46 +0,0 @@ -package twilightforest.client.model; - - -import net.minecraft.client.model.ModelZombie; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.potion.Potion; - -import org.lwjgl.opengl.GL11; - -import twilightforest.entity.boss.EntityTFLichMinion; - - - - -public class ModelTFLichMinion extends ModelZombie { - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float time) - { - EntityTFLichMinion minion = (EntityTFLichMinion)par1EntityLiving; - // make minions greener - if (minion.getActivePotionEffect(Potion.damageBoost) != null) { - GL11.glColor3f(0.25F, 2.0F, 0.25F); - } - else { - GL11.glColor3f(0.5F, 1.0F, 0.5F); - } - } - - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - EntityTFLichMinion minion = (EntityTFLichMinion)par1Entity; - // make strong minions bigger - if (minion.getActivePotionEffect(Potion.damageBoost) != null) { - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - } - else { - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - } - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFLoyalZombie.java b/src/main/java/twilightforest/client/model/ModelTFLoyalZombie.java deleted file mode 100644 index e5b9c918a7..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFLoyalZombie.java +++ /dev/null @@ -1,21 +0,0 @@ -package twilightforest.client.model; - - -import net.minecraft.client.model.ModelZombie; -import net.minecraft.entity.EntityLivingBase; - -import org.lwjgl.opengl.GL11; - -public class ModelTFLoyalZombie extends ModelZombie { - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float time) - { - // GREEEEN - GL11.glColor3f(0.25F, 2.0F, 0.25F); - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFMinoshroom.java b/src/main/java/twilightforest/client/model/ModelTFMinoshroom.java deleted file mode 100644 index dd01d0f14e..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFMinoshroom.java +++ /dev/null @@ -1,207 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -public class ModelTFMinoshroom extends ModelBiped { - - ModelRenderer body; - ModelRenderer leg1; - ModelRenderer leg2; - ModelRenderer leg3; - ModelRenderer leg4; - ModelRenderer udders; - - ModelRenderer snout; - - public ModelRenderer righthorn1; - public ModelRenderer righthorn2; - public ModelRenderer lefthorn1; - public ModelRenderer lefthorn2; - - public ModelTFMinoshroom() - { - textureWidth = 128; - textureHeight = 32; - - bipedHead = new ModelRenderer(this, 96, 16); - bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8); - bipedHead.setRotationPoint(0F, -6F, -9F); - - body = new ModelRenderer(this, 18, 4); - body.addBox(-6F, -10F, -7F, 12, 18, 10); - body.setRotationPoint(0F, 5F, 2F); - setRotation(body, 1.570796F, 0F, 0F); - - leg1 = new ModelRenderer(this, 0, 16); - leg1.addBox(-3F, 0F, -2F, 4, 12, 4); - leg1.setRotationPoint(-3F, 12F, 7F); - - leg2 = new ModelRenderer(this, 0, 16); - leg2.addBox(-1F, 0F, -2F, 4, 12, 4); - leg2.setRotationPoint(3F, 12F, 7F); - - leg3 = new ModelRenderer(this, 0, 16); - leg3.addBox(-3F, 0F, -3F, 4, 12, 4); - leg3.setRotationPoint(-3F, 12F, -5F); - - leg4 = new ModelRenderer(this, 0, 16); - leg4.addBox(-1F, 0F, -3F, 4, 12, 4); - leg4.setRotationPoint(3F, 12F, -5F); - - udders = new ModelRenderer(this, 52, 0); - udders.addBox(-2F, -3F, 0F, 4, 6, 2); - udders.setRotationPoint(0F, 14F, 6F); - setRotation(udders, 1.570796F, 0F, 0F); - - bipedBody = new ModelRenderer(this, 64, 0); - bipedBody.addBox(-4F, 0F, -2.5F, 8, 12, 5); - bipedBody.setRotationPoint(0F, -6F, -9F); - - this.bipedLeftArm = new ModelRenderer(this, 90, 0); - this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4); - this.bipedLeftArm.setRotationPoint(5F, -4F, -9F); - this.bipedLeftArm.mirror = true; - - this.bipedRightArm = new ModelRenderer(this, 90, 0); - this.bipedRightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4); - this.bipedRightArm.setRotationPoint(-5F, -4F, -9F); - - // horns - this.righthorn1 = new ModelRenderer(this, 0, 0); - this.righthorn1.addBox(-5.5F, -1.5F, -1.5F, 5, 3, 3); - this.righthorn1.setRotationPoint(-2.5F, -6.5F, 0.0F); - this.righthorn1.rotateAngleY = -25F / (180F / (float)Math.PI); - this.righthorn1.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn2 = new ModelRenderer(this, 16, 0); - this.righthorn2.addBox(-3.5F, -1.0F, -1.0F, 3, 2, 2); - this.righthorn2.setRotationPoint(-4.5F, 0.0F, 0.0F); - this.righthorn2.rotateAngleY = -15F / (180F / (float)Math.PI); - this.righthorn2.rotateAngleZ = 45F / (180F / (float)Math.PI); - - this.righthorn1.addChild(righthorn2); - - this.lefthorn1 = new ModelRenderer(this, 0, 0); - this.lefthorn1.mirror = true; - this.lefthorn1.addBox(0.5F, -1.5F, -1.5F, 5, 3, 3); - this.lefthorn1.setRotationPoint(2.5F, -6.5F, 0.0F); - this.lefthorn1.rotateAngleY = 25F / (180F / (float)Math.PI); - this.lefthorn1.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn2 = new ModelRenderer(this, 16, 0); - this.lefthorn2.addBox(0.5F, -1.0F, -1.0F, 3, 2, 2); - this.lefthorn2.setRotationPoint(4.5F, 0.0F, 0.0F); - this.lefthorn2.rotateAngleY = 15F / (180F / (float)Math.PI); - this.lefthorn2.rotateAngleZ = -45F / (180F / (float)Math.PI); - - this.lefthorn1.addChild(lefthorn2); - - this.bipedHead.addChild(righthorn1); - this.bipedHead.addChild(lefthorn1); - - snout = new ModelRenderer(this, 105, 28); - snout.addBox(-2, -1, -1, 4, 3, 1); - snout.setRotationPoint(0F, -2.0F, -4F); - - this.bipedHead.addChild(snout); - - // kill off headwear box - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - //super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - bipedHead.render(f5); - body.render(f5); - leg1.render(f5); - leg2.render(f5); - leg3.render(f5); - leg4.render(f5); - udders.render(f5); - - bipedBody.render(f5); - bipedLeftArm.render(f5); - bipedRightArm.render(f5); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - @Override - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity entity) - { - // copied from ModelBiped - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; - this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; - - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - - this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.bipedRightLeg.rotateAngleY = 0.0F; - this.bipedLeftLeg.rotateAngleY = 0.0F; - - if (this.heldItemLeft != 0) - { - this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemLeft; - } - - if (this.heldItemRight != 0) - { - this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemRight; - } - - - - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - - if (this.aimedBow) - { - float var7 = 0.0F; - float var8 = 0.0F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightArm.rotateAngleY = -(0.1F - var7 * 0.6F) + this.bipedHead.rotateAngleY; - this.bipedLeftArm.rotateAngleY = 0.1F - var7 * 0.6F + this.bipedHead.rotateAngleY + 0.4F; - this.bipedRightArm.rotateAngleX = -((float)Math.PI / 2F) + this.bipedHead.rotateAngleX; - this.bipedLeftArm.rotateAngleX = -((float)Math.PI / 2F) + this.bipedHead.rotateAngleX; - this.bipedRightArm.rotateAngleX -= var7 * 1.2F - var8 * 0.4F; - this.bipedLeftArm.rotateAngleX -= var7 * 1.2F - var8 * 0.4F; - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - } - - // copied from ModelQuadruped - this.body.rotateAngleX = ((float)Math.PI / 2F); - this.leg1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.leg2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.leg3.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.leg4.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFMinotaur.java b/src/main/java/twilightforest/client/model/ModelTFMinotaur.java deleted file mode 100644 index 20ed93fa67..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFMinotaur.java +++ /dev/null @@ -1,61 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; - -public class ModelTFMinotaur extends ModelBiped { - - public ModelRenderer righthorn1; - public ModelRenderer righthorn2; - public ModelRenderer lefthorn1; - public ModelRenderer lefthorn2; - - ModelRenderer snout; - - public ModelTFMinotaur() - { - - this.righthorn1 = new ModelRenderer(this, 24, 0); - this.righthorn1.addBox(-5.5F, -1.5F, -1.5F, 5, 3, 3); - this.righthorn1.setRotationPoint(-2.5F, -6.5F, 0.0F); - this.righthorn1.rotateAngleY = -25F / (180F / (float)Math.PI); - this.righthorn1.rotateAngleZ = 10F / (180F / (float)Math.PI); - - this.righthorn2 = new ModelRenderer(this, 40, 0); - this.righthorn2.addBox(-3.5F, -1.0F, -1.0F, 3, 2, 2); - this.righthorn2.setRotationPoint(-4.5F, 0.0F, 0.0F); - this.righthorn2.rotateAngleY = -15F / (180F / (float)Math.PI); - this.righthorn2.rotateAngleZ = 45F / (180F / (float)Math.PI); - - this.righthorn1.addChild(righthorn2); - - this.lefthorn1 = new ModelRenderer(this, 24, 0); - this.lefthorn1.mirror = true; - this.lefthorn1.addBox(0.5F, -1.5F, -1.5F, 5, 3, 3); - this.lefthorn1.setRotationPoint(2.5F, -6.5F, 0.0F); - this.lefthorn1.rotateAngleY = 25F / (180F / (float)Math.PI); - this.lefthorn1.rotateAngleZ = -10F / (180F / (float)Math.PI); - - this.lefthorn2 = new ModelRenderer(this, 40, 0); - this.lefthorn2.addBox(0.5F, -1.0F, -1.0F, 3, 2, 2); - this.lefthorn2.setRotationPoint(4.5F, 0.0F, 0.0F); - this.lefthorn2.rotateAngleY = 15F / (180F / (float)Math.PI); - this.lefthorn2.rotateAngleZ = -45F / (180F / (float)Math.PI); - - this.lefthorn1.addChild(lefthorn2); - - this.bipedHead.addChild(righthorn1); - this.bipedHead.addChild(lefthorn1); - - snout = new ModelRenderer(this, 9, 12); - snout.addBox(-2, -1, -1, 4, 3, 1); - snout.setRotationPoint(0F, -2.0F, -4F); - - this.bipedHead.addChild(snout); - - // kill off headwear box - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFMoonworm.java b/src/main/java/twilightforest/client/model/ModelTFMoonworm.java deleted file mode 100644 index d2c3fead5c..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFMoonworm.java +++ /dev/null @@ -1,94 +0,0 @@ -// Date: 11/8/2012 9:54:59 AM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - - - - - - -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import twilightforest.tileentity.TileEntityTFMoonworm; - -public class ModelTFMoonworm extends ModelBase -{ - //fields - ModelRenderer Shape1; - ModelRenderer Shape2; - ModelRenderer Shape3; - ModelRenderer head; - - public ModelTFMoonworm() - { - textureWidth = 32; - textureHeight = 32; - - Shape1 = new ModelRenderer(this, 0, 4); - Shape1.addBox(-1F, -1F, -1F, 4, 2, 2); - Shape1.setRotationPoint(-1F, 7F, 3F); - - Shape2 = new ModelRenderer(this, 0, 8); - Shape2.addBox(-1F, -1F, -1F, 2, 2, 4); - Shape2.setRotationPoint(3F, 7F, 0F); - - Shape3 = new ModelRenderer(this, 0, 14); - Shape3.addBox(-1F, -1F, -1F, 2, 2, 2); - Shape3.setRotationPoint(2F, 7F, -2F); - - head = new ModelRenderer(this, 0, 0); - head.addBox(-1F, -1F, -1F, 2, 2, 2); - head.setRotationPoint(-3F, 7F, 2F); - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - Shape1.render(f5); - Shape2.render(f5); - Shape3.render(f5); - head.render(f5); - } - - public void render(float f5) - { - Shape1.render(f5); - Shape2.render(f5); - Shape3.render(f5); - head.render(f5); - } - - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) - { - super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); - } - - public void setLivingAnimations(TileEntityTFMoonworm moonworm, float partialTime) { - - head.rotationPointY = 7F; - Shape1.rotationPointY = 7F; - Shape2.rotationPointY = 7F; - Shape3.rotationPointY = 7F; - - if (moonworm.yawDelay == 0) - { - float time = (moonworm.desiredYaw - moonworm.currentYaw) - partialTime; - - // moving - head.rotationPointY += Math.min(0, MathHelper.sin(time / 2)); - Shape1.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 1)); - Shape2.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 2)); - Shape3.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 3)); - - } - - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFMosquitoSwarm.java b/src/main/java/twilightforest/client/model/ModelTFMosquitoSwarm.java deleted file mode 100644 index bbf9adb08f..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFMosquitoSwarm.java +++ /dev/null @@ -1,135 +0,0 @@ -package twilightforest.client.model; - -import java.util.Random; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; - -public class ModelTFMosquitoSwarm extends ModelBase -{ - - ModelRenderer core; - ModelRenderer node1; - ModelRenderer node2; - ModelRenderer node3; - ModelRenderer node4; - ModelRenderer node5; - ModelRenderer node6; - - Random rand = new Random(); - - public ModelTFMosquitoSwarm() - { - core = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - core.addBox(-4F, 0.0F, -2F, 1, 1, 1); - core.setRotationPoint(0.0F, -4.0F, 0.0F); - - node1 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - node1.addBox(-5.5F, -5F, -13F, 1, 1, 1); - node1.setRotationPoint(2F, -1F, -6F); - core.addChild(node1); - - node2 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - node2.addBox(-5.5F, -13F, -5F, 1, 1, 1); - node2.setRotationPoint(0F, -7F, -1F); - core.addChild(node2); - - node3 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - node3.addBox(-13F, -5F, -5F, 1, 1, 1); - node3.setRotationPoint(5F, -2F, -1F); - core.addChild(node3); - - node4 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - node4.addBox(-5.5F, -5F, -13F, 1, 1, 1); - node4.setRotationPoint(2F, -1F, -6F); - core.addChild(node4); - - node5 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - node5.addBox(-5.5F, -13F, -5F, 1, 1, 1); - node5.setRotationPoint(0F, -7F, -1F); - core.addChild(node5); - - node6 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - node6.addBox(-13F, -5F, -5F, 1, 1, 1); - node6.setRotationPoint(5F, -2F, -1F); - core.addChild(node6); - - addBugsToNodes(node1); - addBugsToNodes(node2); - addBugsToNodes(node3); - addBugsToNodes(node4); - addBugsToNodes(node5); - addBugsToNodes(node6); - } - - @Override - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { - core.render(par7 / 2.0F); -// node1.render(par7); -// node2.render(par7); -// node3.render(par7); - } - - /** - * Add the proper number of mosquitoes to the nodes - */ - public void addBugsToNodes(ModelRenderer node) - { - int bugs = 16; - - for (int i = 0; i < bugs; i++) { - Vec3 vec = Vec3.createVectorHelper(11, 0, 0); - float rotateY = ((i * (360F / bugs)) * 3.141593F) / 180F; - vec.rotateAroundY(rotateY); - ModelRenderer bug = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); - - float bugX = (rand.nextFloat() - rand.nextFloat()) * 4.0f; - float bugY = (rand.nextFloat() - rand.nextFloat()) * 4.0f; - float bugZ = (rand.nextFloat() - rand.nextFloat()) * 4.0f; - - bug.addBox(bugX, bugY, bugZ, 1, 1, 1); - - bug.setRotationPoint((float)vec.xCoord, (float)vec.yCoord, (float)vec.zCoord); - bug.rotateAngleY = rotateY; - node.addChild(bug); - } - } - - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float time) { - core.rotateAngleY = (par1EntityLiving.ticksExisted + time) / 5.0F; - core.rotateAngleX = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - core.rotateAngleZ = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - - node1.rotateAngleY = (par1EntityLiving.ticksExisted + time) / 2.0F; - node1.rotateAngleX = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 6.0F) / 2.0F; - node1.rotateAngleZ = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - - node2.rotateAngleY = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 2.0F) / 3.0F; - node2.rotateAngleX = (par1EntityLiving.ticksExisted + time) / 5.0F; - node2.rotateAngleZ = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - - node3.rotateAngleY = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 7.0F) / 3.0F; - node3.rotateAngleX = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 4.0F) / 2.0F; - node3.rotateAngleZ = (par1EntityLiving.ticksExisted + time) / 5.0F; - - node4.rotateAngleX = (par1EntityLiving.ticksExisted + time) / 2.0F; - node4.rotateAngleZ = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 6.0F) / 2.0F; - node4.rotateAngleY = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - - node5.rotateAngleZ = MathHelper.sin((par1EntityLiving.ticksExisted + time) / 2.0F) / 3.0F; - node5.rotateAngleY = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - node5.rotateAngleX = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 5.0F) / 4.0F; - - node6.rotateAngleZ = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 7.0F) / 3.0F; - node6.rotateAngleX = MathHelper.cos((par1EntityLiving.ticksExisted + time) / 4.0F) / 2.0F; - node6.rotateAngleY = (par1EntityLiving.ticksExisted + time) / 5.0F; - - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFNaga.java b/src/main/java/twilightforest/client/model/ModelTFNaga.java deleted file mode 100644 index b169cdca32..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFNaga.java +++ /dev/null @@ -1,43 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import twilightforest.entity.boss.EntityTFNaga; -import twilightforest.entity.boss.EntityTFNagaSegment; - - -public class ModelTFNaga extends ModelBase -{ - public ModelTFNaga() - { - head = new ModelRenderer(this, 0, 0); - head.addBox(-8F, -12F, -8F, 16, 16, 16, 0F); - head.setRotationPoint(0F, 0F, 0F); - - body = new ModelRenderer(this, 0, 0); - body.addBox(-8F, -16F, -8F, 16, 16, 16, 0F); - body.setRotationPoint(0F, 0F, 0F); - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - - if (entity instanceof EntityTFNaga) { - head.render(f5 * 2); - } - else if (entity instanceof EntityTFNagaSegment) { - body.render(f5 * 2); - } - else { - head.render(f5 * 2); - } - - } - - //fields - public ModelRenderer head; - public ModelRenderer body; -} diff --git a/src/main/java/twilightforest/client/model/ModelTFPenguin.java b/src/main/java/twilightforest/client/model/ModelTFPenguin.java deleted file mode 100644 index 8e4b256b35..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFPenguin.java +++ /dev/null @@ -1,126 +0,0 @@ -// Date: 3/3/2012 11:56:45 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - - - - - - -package twilightforest.client.model; - - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -import org.lwjgl.opengl.GL11; - -public class ModelTFPenguin extends ModelBase -{ - //fields - ModelRenderer body; - ModelRenderer rightarm; - ModelRenderer leftarm; - ModelRenderer rightleg; - ModelRenderer leftleg; - ModelRenderer head; - ModelRenderer beak; - - public ModelTFPenguin() - { - textureWidth = 64; - textureHeight = 32; - - body = new ModelRenderer(this, 32, 0); - body.addBox(-4F, 0F, -4F, 8, 9, 8); - body.setRotationPoint(0F, 14F, 0F); - - rightarm = new ModelRenderer(this, 34, 18); - rightarm.addBox(-1F, -1F, -2F, 1, 8, 4); - rightarm.setRotationPoint(-4F, 15F, 0F); - - leftarm = new ModelRenderer(this, 24, 18); - leftarm.addBox(0F, -1F, -2F, 1, 8, 4); - leftarm.setRotationPoint(4F, 15F, 0F); - - leftarm.mirror = true; - - - rightleg = new ModelRenderer(this, 0, 16); - rightleg.addBox(-2F, 0F, -5F, 4, 1, 8); - rightleg.setRotationPoint(-2F, 23F, 0F); - rightleg.setTextureSize(64, 32); - - leftleg = new ModelRenderer(this, 0, 16); - leftleg.addBox(-2F, 0F, -5F, 4, 1, 8); - leftleg.setRotationPoint(2F, 23F, 0F); - - - head = new ModelRenderer(this, 0, 0); - head.addBox(-3.5F, -4F, -3.5F, 7, 5, 7); - head.setRotationPoint(0F, 13F, 0F); - - beak = new ModelRenderer(this, 0, 13); - beak.addBox(-1F, 0F, -1F, 2, 1, 2); - beak.setRotationPoint(0F, -1F, -4F); - - head.addChild(beak); - - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - setRotationAngles(par2, par3, par4, par5, par6, par7); - - if (isChild) - { - float f = 2.0F; - GL11.glPushMatrix(); - GL11.glTranslatef(0.0F, 5F * par7, 0.75F * par7); - head.render(par7); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - GL11.glScalef(1.0F / f, 1.0F / f, 1.0F / f); - GL11.glTranslatef(0.0F, 24F * par7, 0.0F); - body.render(par7); - rightleg.render(par7); - leftleg.render(par7); - rightarm.render(par7); - leftarm.render(par7); - GL11.glPopMatrix(); - } - else - { - head.render(par7); - body.render(par7); - rightleg.render(par7); - leftleg.render(par7); - rightarm.render(par7); - leftarm.render(par7); - } - } - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6) - { - head.rotateAngleX = par5 / (180F / (float)Math.PI); - head.rotateAngleY = par4 / (180F / (float)Math.PI); - - rightleg.rotateAngleX = MathHelper.cos(par1) * 0.7F * par2; - leftleg.rotateAngleX = MathHelper.cos(par1 + (float)Math.PI) * 0.7F * par2; - - rightarm.rotateAngleZ = par3; - leftarm.rotateAngleZ = -par3; - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFPhantomArmor.java b/src/main/java/twilightforest/client/model/ModelTFPhantomArmor.java deleted file mode 100644 index 9873726229..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFPhantomArmor.java +++ /dev/null @@ -1,23 +0,0 @@ -package twilightforest.client.model; - - -public class ModelTFPhantomArmor extends ModelTFKnightlyArmor { - - public ModelTFPhantomArmor(int part, float expand) - { - super(part, expand); - - this.righthorn1.rotateAngleY = -25F / (180F / (float)Math.PI); - this.righthorn1.rotateAngleZ = 45F / (180F / (float)Math.PI); - - this.righthorn2.rotateAngleY = -15F / (180F / (float)Math.PI); - this.righthorn2.rotateAngleZ = 45F / (180F / (float)Math.PI); - - this.lefthorn1.rotateAngleY = 25F / (180F / (float)Math.PI); - this.lefthorn1.rotateAngleZ = -45F / (180F / (float)Math.PI); - - this.lefthorn2.rotateAngleY = 15F / (180F / (float)Math.PI); - this.lefthorn2.rotateAngleZ = -45F / (180F / (float)Math.PI); - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFPinchBeetle.java b/src/main/java/twilightforest/client/model/ModelTFPinchBeetle.java deleted file mode 100644 index abde43a095..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFPinchBeetle.java +++ /dev/null @@ -1,288 +0,0 @@ -// Date: 11/5/2012 7:35:56 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; -import twilightforest.entity.EntityTFPinchBeetle; - -public class ModelTFPinchBeetle extends ModelBase -{ - //fields - ModelRenderer thorax; - ModelRenderer head; - ModelRenderer connector2; - ModelRenderer RearEnd; - ModelRenderer Leg6; - ModelRenderer Leg4; - ModelRenderer Leg2; - ModelRenderer Leg5; - ModelRenderer Leg3; - ModelRenderer Leg1; - ModelRenderer connector1; - ModelRenderer jaw1a; - ModelRenderer jaw1b; - ModelRenderer jaw2a; - ModelRenderer jaw2b; - ModelRenderer antenna1; - ModelRenderer antenna2; - ModelRenderer eye1; - ModelRenderer eye2; - ModelRenderer tooth1a; - ModelRenderer tooth1b; - ModelRenderer tooth1c; - ModelRenderer tooth2a; - ModelRenderer tooth2b; - ModelRenderer tooth2c; - - public ModelTFPinchBeetle() - { - textureWidth = 64; - textureHeight = 32; - - thorax = new ModelRenderer(this, 0, 22); - thorax.addBox(-4.5F, -4F, 0F, 9, 8, 2); - thorax.setRotationPoint(0F, 18F, -4.5F); - - connector1 = new ModelRenderer(this, 0, 12); - connector1.addBox(-3F, -3F, 0F, 6, 6, 1); - connector1.setRotationPoint(0F, 18F, -3F); - - connector2 = new ModelRenderer(this, 0, 12); - connector2.addBox(-3F, -3F, -1F, 6, 6, 1); - connector2.setRotationPoint(0F, 18F, -4F); - - RearEnd = new ModelRenderer(this, 28, 14); - RearEnd.addBox(-5F, -9F, -4F, 10, 10, 8); - RearEnd.setRotationPoint(0F, 18F, 7F); - setRotation(RearEnd, 1.570796F, 0F, 0F); - - Leg6 = new ModelRenderer(this, 40, 0); - Leg6.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg6.setRotationPoint(4F, 21F, -4F); - setRotation(Leg6, 0F, 0.2792527F, 0.3490659F); - - Leg5 = new ModelRenderer(this, 40, 0); - Leg5.mirror = true; - Leg5.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg5.setRotationPoint(-4F, 21F, -4F); - setRotation(Leg5, 0F, -0.2792527F, -0.3490659F); - - Leg4 = new ModelRenderer(this, 40, 0); - Leg4.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg4.setRotationPoint(4F, 21F, -1F); - setRotation(Leg4, 0F, -0.2792527F, 0.3490659F); - - Leg2 = new ModelRenderer(this, 40, 0); - Leg2.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg2.setRotationPoint(4F, 21F, 4F); - setRotation(Leg2, 0F, -0.6981317F, 0.3490659F); - - Leg3 = new ModelRenderer(this, 40, 0); - Leg3.mirror = true; - Leg3.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg3.setRotationPoint(-4F, 21F, -1F); - setRotation(Leg3, 0F, 0.2792527F, -0.3490659F); - - Leg1 = new ModelRenderer(this, 40, 0); - Leg1.mirror = true; - Leg1.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg1.setRotationPoint(-4F, 21F, 4F); - Leg1.setTextureSize(64, 32); - setRotation(Leg1, 0F, 0.6981317F, -0.3490659F); - - head = new ModelRenderer(this, 0, 0); - head.addBox(-4F, -4F, -6F, 8, 6, 6); - head.setRotationPoint(0F, 19F, -5F); - - jaw1a = new ModelRenderer(this, 40, 6); - jaw1a.addBox(-1F, -1F, -1.5F, 8, 2, 3); - jaw1a.setRotationPoint(-3F, 1F, -6F); - setRotation(jaw1a, 0F, 2.6354471F, 0F); - - jaw1b = new ModelRenderer(this, 40, 10); - jaw1b.addBox(-1F, -1F, -1F, 10, 2, 2); - jaw1b.setRotationPoint(7F, 0F, 0F); - setRotation(jaw1b, 0F, -1.047197F, 0F); - - jaw2a = new ModelRenderer(this, 40, 6); - jaw2a.addBox(-1F, -1F, -1.5F, 8, 2, 3); - jaw2a.setRotationPoint(3F, 1F, -6F); - setRotation(jaw2a, 0F, 0.5410520F, 0F); - - jaw2b = new ModelRenderer(this, 40, 10); - jaw2b.addBox(-1F, -1F, -1F, 10, 2, 2); - jaw2b.setRotationPoint(7F, 0F, 0F); - setRotation(jaw2b, 0F, 1.047197F, 0F); - - antenna1 = new ModelRenderer(this, 42, 4); - antenna1.addBox(0F, -0.5F, -0.5F, 10, 1, 1); - antenna1.setRotationPoint(1F, -3F, -5F); - setRotation(antenna1, 0F, 1.047198F, -0.296706F); - - antenna2 = new ModelRenderer(this, 42, 4); - antenna2.addBox(0F, -0.5F, -0.5F, 10, 1, 1); - antenna2.setRotationPoint(-1F, -3F, -5F); - setRotation(antenna2, 0F, 2.094395F, 0.296706F); - - eye1 = new ModelRenderer(this, 15, 12); - eye1.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - eye1.setRotationPoint(-3F, -2F, -5F); - - eye2 = new ModelRenderer(this, 15, 12); - eye2.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - eye2.setRotationPoint(3F, -2F, -5F); - - tooth1a = new ModelRenderer(this, 0, 0); - tooth1a.addBox(0F, -0.5F, -0F, 2, 1, 1); - tooth1a.setRotationPoint(9F, 0F, 0F); - setRotation(tooth1a, 0F, -0.5235987F, 0); - - tooth1b = new ModelRenderer(this, 0, 0); - tooth1b.addBox(-2.5F, -0.5F, -0F, 2, 1, 1); - tooth1b.setRotationPoint(6F, 0F, 0F); - setRotation(tooth1b, 0F, 1.5707963F, 0); - - tooth1c = new ModelRenderer(this, 0, 0); - tooth1c.addBox(-2.5F, -0.5F, -0F, 2, 1, 1); - tooth1c.setRotationPoint(3F, 0F, 0F); - setRotation(tooth1c, 0F, 1.5707963F, 0); - - tooth2a = new ModelRenderer(this, 0, 0); - tooth2a.addBox(0F, -0.5F, -1F, 2, 1, 1); - tooth2a.setRotationPoint(9F, 0F, 0F); - setRotation(tooth2a, 0F, 0.5235987F, 0); - - tooth2b = new ModelRenderer(this, 0, 0); - tooth2b.addBox(-2.5F, -0.5F, -1F, 2, 1, 1); - tooth2b.setRotationPoint(6F, 0F, 0F); - setRotation(tooth2b, 0F, -1.5707963F, 0); - - tooth2c = new ModelRenderer(this, 0, 0); - tooth2c.addBox(-2.5F, -0.5F, -1F, 2, 1, 1); - tooth2c.setRotationPoint(3F, 0F, 0F); - setRotation(tooth2c, 0F, -1.5707963F, 0); - - head.addChild(jaw1a); - jaw1a.addChild(jaw1b); - jaw1b.addChild(tooth1a); - jaw1b.addChild(tooth1b); - jaw1b.addChild(tooth1c); - jaw2b.addChild(tooth2a); - jaw2b.addChild(tooth2b); - jaw2b.addChild(tooth2c); - head.addChild(jaw2a); - jaw2a.addChild(jaw2b); - head.addChild(antenna1); - head.addChild(antenna2); - head.addChild(eye1); - head.addChild(eye2); - - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - thorax.render(f5); - head.render(f5); - connector2.render(f5); - RearEnd.render(f5); - Leg6.render(f5); - Leg4.render(f5); - Leg2.render(f5); - Leg5.render(f5); - Leg3.render(f5); - Leg1.render(f5); - connector1.render(f5); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - this.head.rotateAngleY = par4 / (180F / (float)Math.PI); - this.head.rotateAngleX = par5 / (180F / (float)Math.PI); - - float legZ = ((float)Math.PI / 11F); - this.Leg1.rotateAngleZ = -legZ; - this.Leg2.rotateAngleZ = legZ; - this.Leg3.rotateAngleZ = -legZ * 0.74F; - this.Leg4.rotateAngleZ = legZ * 0.74F; - this.Leg5.rotateAngleZ = -legZ; - this.Leg6.rotateAngleZ = legZ; - - float var9 = -0.0F; - float var10 = 0.3926991F; - this.Leg1.rotateAngleY = var10 * 2.0F + var9; - this.Leg2.rotateAngleY = -var10 * 2.0F - var9; - this.Leg3.rotateAngleY = var10 * 1.0F + var9; - this.Leg4.rotateAngleY = -var10 * 1.0F - var9; - this.Leg5.rotateAngleY = -var10 * 2.0F + var9; - this.Leg6.rotateAngleY = var10 * 2.0F - var9; - - float var11 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + 0.0F) * 0.4F) * par2; - float var12 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + (float)Math.PI) * 0.4F) * par2; - float var14 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - - float var15 = Math.abs(MathHelper.sin(par1 * 0.6662F + 0.0F) * 0.4F) * par2; - float var16 = Math.abs(MathHelper.sin(par1 * 0.6662F + (float)Math.PI) * 0.4F) * par2; - float var18 = Math.abs(MathHelper.sin(par1 * 0.6662F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - - this.Leg1.rotateAngleY += var11; - this.Leg2.rotateAngleY += -var11; - this.Leg3.rotateAngleY += var12; - this.Leg4.rotateAngleY += -var12; - this.Leg5.rotateAngleY += var14; - this.Leg6.rotateAngleY += -var14; - - this.Leg1.rotateAngleZ += var15; - this.Leg2.rotateAngleZ += -var15; - - this.Leg3.rotateAngleZ += var16; - this.Leg4.rotateAngleZ += -var16; - - this.Leg5.rotateAngleZ += var18; - this.Leg6.rotateAngleZ += -var18; - - - } - - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float partialTick) - { - EntityTFPinchBeetle beetle = (EntityTFPinchBeetle)par1EntityLiving; - - if (beetle.riddenByEntity == null) - { - // open jaws - this.jaw1a.rotateAngleY = 2.96705972839036F; - this.jaw2a.rotateAngleY = 0.3490658503988659F; - } - else - { - // close jaws - this.jaw1a.rotateAngleY = 2.356194490192345F; - this.jaw2a.rotateAngleY = 0.7853981633974483F; - } - } - - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFProtectionBox.java b/src/main/java/twilightforest/client/model/ModelTFProtectionBox.java deleted file mode 100644 index 692014c228..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFProtectionBox.java +++ /dev/null @@ -1,57 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import twilightforest.entity.EntityTFProtectionBox; - -public class ModelTFProtectionBox extends ModelBase -{ - - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) { - } - - public ModelRenderer box; - private int lastPixelsX; - private int lastPixelsY; - private int lastPixelsZ; - - public ModelTFProtectionBox() - { - textureWidth = 16; - textureHeight = 16; - box = new ModelRenderer(this, 0, 0); - box.addBox(0F, 0F, 0F, 16, 16, 16, 0F); - box.setRotationPoint(0F, 0F, 0F); - } - - @Override - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { - - EntityTFProtectionBox boxEntity = (EntityTFProtectionBox) par1Entity; - - int pixelsX = boxEntity.sizeX * 16 + 2; - int pixelsY = boxEntity.sizeY * 16 + 2; - int pixelsZ = boxEntity.sizeZ * 16 + 2; - - if (pixelsX != this.lastPixelsX || pixelsY != this.lastPixelsY || pixelsZ != this.lastPixelsZ) { - resizeBoxElement(pixelsX, pixelsY, pixelsZ); - } - - box.render(par7); - } - - private void resizeBoxElement(int pixelsX, int pixelsY, int pixelsZ) { - box = new ModelRenderer(this, 0, 0); - box.addBox(-1F, -1F, -1F, pixelsX, pixelsY, pixelsZ, 0F); - box.setRotationPoint(0F, 0F, 0F); - - this.lastPixelsX = pixelsX; - this.lastPixelsY = pixelsY; - this.lastPixelsZ = pixelsZ; - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFQuestRam.java b/src/main/java/twilightforest/client/model/ModelTFQuestRam.java deleted file mode 100644 index 08220a7c15..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFQuestRam.java +++ /dev/null @@ -1,239 +0,0 @@ -// Date: 5/18/2012 11:45:03 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - -package twilightforest.client.model; - - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.passive.EntitySheep; -import net.minecraft.util.MathHelper; - -import org.lwjgl.opengl.GL11; - -import twilightforest.entity.passive.EntityTFQuestRam; - - - -public class ModelTFQuestRam extends ModelBase -{ - //fields - ModelRenderer frontbody; - ModelRenderer rearbody; - ModelRenderer leg1; - ModelRenderer haunch1; - ModelRenderer leg2; - ModelRenderer haunch2; - ModelRenderer leg3; - ModelRenderer haunch3; - ModelRenderer leg4; - ModelRenderer haunch4; - ModelRenderer neck; - ModelRenderer nose; - ModelRenderer head; - - ModelRenderer[] segments; - boolean[] segmentEnabled; - - int[] colorOrder = new int[] {0, 8, 7, 15, 14, 1, 4, 5, 13, 3, 9, 11, 10, 2, 6, 12}; - - public ModelTFQuestRam() - { - textureWidth = 128; - textureHeight = 128; - setTextureOffset("head.head", 0, 70); - setTextureOffset("head.horn1a", 0, 94); - setTextureOffset("head.horn1b", 20, 96); - setTextureOffset("head.horn1c", 34, 95); - setTextureOffset("head.horn1d", 46, 98); - setTextureOffset("head.horn1e", 58, 95); - setTextureOffset("head.horn1f", 76, 95); - setTextureOffset("head.horn1g", 88, 97); - setTextureOffset("head.horn1a", 0, 94); - setTextureOffset("head.horn1b", 20, 96); - setTextureOffset("head.horn1c", 34, 95); - setTextureOffset("head.horn1d", 46, 98); - setTextureOffset("head.horn1e", 58, 95); - setTextureOffset("head.horn1f", 76, 95); - setTextureOffset("head.horn1g", 88, 97); - - frontbody = new ModelRenderer(this, 0, 0); - frontbody.addBox(-9F, -7.5F, -15F, 18, 15, 15); - frontbody.setRotationPoint(0F, -1F, 2F); - - rearbody = new ModelRenderer(this, 0, 30); - rearbody.addBox(-9F, -7.5F, 0F, 18, 15, 15); - rearbody.setRotationPoint(0F, -1F, 4F); - - - leg1 = new ModelRenderer(this, 66, 0); - leg1.addBox(-3F, 10F, -3F, 6, 12, 6); - leg1.setRotationPoint(-6F, 2F, 13F); - - haunch1 = new ModelRenderer(this, 90, 0); - haunch1.addBox(-3.5F, 0F, -6F, 7, 10, 10); - haunch1.setRotationPoint(-6F, 2F, 13F); - - leg2 = new ModelRenderer(this, 66, 0); - leg2.addBox(-3F, 10F, -3F, 6, 12, 6); - leg2.setRotationPoint(6F, 2F, 13F); - - haunch2 = new ModelRenderer(this, 90, 0); - haunch2.addBox(-3.5F, 0F, -6F, 7, 10, 10); - haunch2.setRotationPoint(6F, 2F, 13F); - - leg3 = new ModelRenderer(this, 66, 18); - leg3.addBox(-3F, 10F, -3F, 6, 13, 6); - leg3.setRotationPoint(-6F, 1F, -8F); - - haunch3 = new ModelRenderer(this, 90, 20); - haunch3.addBox(-3.5F, 0F, -4F, 7, 10, 7); - haunch3.setRotationPoint(-6F, 1F, -8F); - - leg4 = new ModelRenderer(this, 66, 18); - leg4.addBox(-3F, 10F, -3F, 6, 13, 6); - leg4.setRotationPoint(6F, 1F, -8F); - - haunch4 = new ModelRenderer(this, 90, 20); - haunch4.addBox(-3.5F, 0F, -4F, 7, 10, 7); - haunch4.setRotationPoint(6F, 1F, -8F); - - neck = new ModelRenderer(this, 66, 37); - neck.addBox(-5.5F, -8F, -8F, 11, 14, 12); - neck.setRotationPoint(0F, -8F, -7F); - - setRotation(neck, 0.2617994F, 0F, 0F); - - head = new ModelRenderer(this, "head"); - head.setRotationPoint(0F, -13F, -5F); - - head.addBox("head", -6F, -4.5F, -15F, 12, 9, 15); - head.addBox("horn1a", 5F, -9F, -7F, 4, 4, 6); - head.addBox("horn1b", 7F, -8F, -2F, 3, 4, 4); - head.addBox("horn1c", 8F, -6F, 0F, 3, 6, 3); - head.addBox("horn1d", 9.5F, -2F, -2F, 3, 3, 3); - head.addBox("horn1e", 11F, 0F, -7F, 3, 3, 6); - head.addBox("horn1f", 12F, -4F, -9F, 3, 6, 3); - head.addBox("horn1g", 13F, -6F, -7F, 3, 3, 4); - head.addBox("horn1a", -9F, -9F, -7F, 4, 4, 6); - head.addBox("horn1b", -10F, -8F, -2F, 3, 4, 4); - head.addBox("horn1c", -11F, -6F, 0F, 3, 6, 3); - head.addBox("horn1d", -12.5F, -2F, -2F, 3, 3, 3); - head.addBox("horn1e", -14F, 0F, -7F, 3, 3, 6); - head.addBox("horn1f", -15F, -4F, -9F, 3, 6, 3); - head.addBox("horn1g", -16F, -6F, -7F, 3, 3, 4); - - nose = new ModelRenderer(this, 54, 73); - nose.addBox(-5.5F, -5F, -13F, 11, 9, 12); - nose.setRotationPoint(0F, -7F, -1F); - nose.setTextureSize(128, 128); - setRotation(nose, 0.5235988F, 0F, 0F); - head.addChild(nose); - - segments = new ModelRenderer[16]; - segmentEnabled = new boolean[16]; - for (int i = 0; i < 16; i++) { - segments[i] = new ModelRenderer(this, 0, 104); - segments[i].addBox(-9F, -7.5F, 0F, 18, 15, 2); - segments[i].setRotationPoint(0F, -1F, 2F); - - segmentEnabled[i] = false; - } - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5); - frontbody.render(f5); - rearbody.render(f5); - leg1.render(f5); - haunch1.render(f5); - leg2.render(f5); - haunch2.render(f5); - leg3.render(f5); - haunch3.render(f5); - leg4.render(f5); - haunch4.render(f5); - neck.render(f5); - //nose.render(f5); - head.render(f5); - - for (int i = 0; i < 16; i++) { - if (segmentEnabled[i]) { - float var4 = 1.0F; - GL11.glColor3f(var4 * EntitySheep.fleeceColorTable[i][0], var4 * EntitySheep.fleeceColorTable[i][1], var4 * EntitySheep.fleeceColorTable[i][2]); - segments[i].render(f5); - - } - } - GL11.glColor3f(1.0F, 1.0F, 1.0F); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6) - { - this.head.rotateAngleX = par5 / (180F / (float)Math.PI); - this.head.rotateAngleY = par4 / (180F / (float)Math.PI); - - this.neck.rotateAngleY = this.head.rotateAngleY; - - this.leg1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2 * 0.5F; - this.leg2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2 * 0.5F; - this.leg3.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2 * 0.5F; - this.leg4.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2 * 0.5F; - this.haunch1.rotateAngleX = this.leg1.rotateAngleX; - this.haunch2.rotateAngleX = this.leg2.rotateAngleX; - this.haunch3.rotateAngleX = this.leg3.rotateAngleX; - this.haunch4.rotateAngleX = this.leg4.rotateAngleX; - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float partialTick) { - EntityTFQuestRam ram = (EntityTFQuestRam)par1EntityLiving; - - // how many colors should we display? - int count = ram.countColorsSet(); - - this.rearbody.rotationPointZ = 2 + 2 * count; - this.leg1.rotationPointZ = 11 + 2 * count; - this.leg2.rotationPointZ = 11 + 2 * count; - this.haunch1.rotationPointZ = 11 + 2 * count; - this.haunch2.rotationPointZ = 11 + 2 * count; - - // set up the colors displayed in color order - int segmentOffset = 2; - for (int color : colorOrder) { - if (ram.isColorPresent(color)) { - segmentEnabled[color] = true; - segments[color].rotationPointZ = segmentOffset; - - segmentOffset += 2; - } - else { - segmentEnabled[color] = false; - } - } - } - - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFRaven.java b/src/main/java/twilightforest/client/model/ModelTFRaven.java deleted file mode 100644 index 8c9e1d66cf..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFRaven.java +++ /dev/null @@ -1,153 +0,0 @@ -// Date: 4/28/2012 9:46:20 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import twilightforest.entity.passive.EntityTFBird; - - -public class ModelTFRaven extends ModelBase -{ - //fields - ModelRenderer head; - ModelRenderer beak1; - ModelRenderer beak2; - ModelRenderer body; - ModelRenderer rightarm; - ModelRenderer leftarm; - ModelRenderer rightleg; - ModelRenderer leftleg; - ModelRenderer rightfoot; - ModelRenderer leftfoot; - ModelRenderer tail; - - public ModelTFRaven() - { - textureWidth = 32; - textureHeight = 32; - - head = new ModelRenderer(this, 0, 0); - head.addBox(-1.5F, -1.5F, -3F, 3, 3, 3); - head.setRotationPoint(0F, 18F, 0F); - head.setTextureSize(32, 32); - head.mirror = true; - setRotation(head, 0F, 0F, 0F); - - beak1 = new ModelRenderer(this, 12, 0); - beak1.addBox(-0.5F, -1F, -2F, 1, 1, 2); - beak1.setRotationPoint(0F, 0F, -2.5F); - beak1.rotateAngleX = 0.2617994F; - head.addChild(beak1); - - beak2 = new ModelRenderer(this, 12, 0); - beak2.addBox(-0.5F, 0F, -2F, 1, 1, 2); - beak2.setRotationPoint(0F, 0F, -2.5F); - beak2.rotateAngleX = -0.2617994F; - head.addChild(beak2); - - body = new ModelRenderer(this, 0, 6); - body.addBox(-1.5F, 0F, -1F, 3, 4, 6); - body.setRotationPoint(0F, 17F, 1F); - body.setTextureSize(32, 32); - setRotation(body, -0.5235988F, 0F, 0F); - - rightarm = new ModelRenderer(this, 0, 16); - rightarm.addBox(-1F, 0F, -1.5F, 1, 3, 6); - rightarm.setRotationPoint(-1.5F, 18F, 1F); - rightarm.setTextureSize(32, 32); - - leftarm = new ModelRenderer(this, 0, 16); - leftarm.addBox(0F, 0F, -1.5F, 1, 3, 6); - leftarm.setRotationPoint(1.5F, 18F, 1F); - leftarm.setTextureSize(32, 32); - - rightleg = new ModelRenderer(this, 14, 16); - rightleg.addBox(0F, 0F, 0F, 1, 2, 1); - rightleg.setRotationPoint(-1.5F, 21F, 1F); - rightleg.setTextureSize(32, 32); - - rightfoot = new ModelRenderer(this, 14, 20); - rightfoot.addBox(0F, -1F, -2F, 1, 1, 2); - rightfoot.setRotationPoint(0F, 2F, 1F); - rightfoot.setTextureSize(32, 32); - setRotation(rightfoot, 0.5235988F, 0F, 0F); - rightleg.addChild(rightfoot); - - leftleg = new ModelRenderer(this, 14, 16); - leftleg.addBox(0F, 0F, 0F, 1, 2, 1); - leftleg.setRotationPoint(0.5F, 21F, 1F); - leftleg.setTextureSize(32, 32); - - leftfoot = new ModelRenderer(this, 14, 20); - leftfoot.addBox(0F, -1F, -2F, 1, 1, 2); - leftfoot.setRotationPoint(0F, 2F, 1F); - leftfoot.setTextureSize(32, 32); - setRotation(leftfoot, 0.5235988F, 0F, 0F); - leftleg.addChild(leftfoot); - - tail = new ModelRenderer(this, 0, 25); - tail.addBox(-1.5F, -0.5F, 0F, 3, 1, 3); - tail.setRotationPoint(0F, 21F, 4F); - tail.setTextureSize(32, 32); - setRotation(tail, -0.5235988F, 0F, 0F); - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - head.render(f5); - body.render(f5); - rightarm.render(f5); - leftarm.render(f5); - rightleg.render(f5); - leftleg.render(f5); - - tail.render(f5); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - head.rotateAngleX = par5 / (180F / (float)Math.PI); - head.rotateAngleY = par4 / (180F / (float)Math.PI); - head.rotateAngleZ = par4 > 5 ? -0.2617994F : 0; - - rightleg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - leftleg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - - rightarm.rotateAngleZ = par3; - leftarm.rotateAngleZ = -par3; - - if (((EntityTFBird)par7Entity).isBirdLanded()) - { - rightleg.rotationPointY = 21; - leftleg.rotationPointY = 21; - } - else - { - rightleg.rotationPointY = 20F; - leftleg.rotationPointY = 20F; - } - } - - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFRedcap.java b/src/main/java/twilightforest/client/model/ModelTFRedcap.java deleted file mode 100644 index ef9ec28754..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFRedcap.java +++ /dev/null @@ -1,78 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; - - -public class ModelTFRedcap extends ModelBiped -{ - public ModelTFRedcap() - { - bipedHead = new ModelRenderer(this, 0, 0); - bipedHead.addBox(-3.4F, 1F, -4F, 7, 7, 7, 0F); - bipedHead.setRotationPoint(0F, 0F, 0F); - - bipedHeadwear = new ModelRenderer(this, 32, 0); - bipedHeadwear.addBox(-2F, 0F, -3F, 4, 5, 7, 0F); - bipedHeadwear.setRotationPoint(0F, 0F, 0F); - - bipedBody = new ModelRenderer(this, 12, 19); - bipedBody.addBox(-4F, 6F, -2F, 8, 9, 4, 0F); - bipedBody.setRotationPoint(0F, 0F, 0F); - - bipedRightArm = new ModelRenderer(this, 36, 17); - bipedRightArm.addBox(-2F, -2F, -2F, 3, 12, 3, 0F); - bipedRightArm.setRotationPoint(-5F, 8F, 0F); - - bipedLeftArm = new ModelRenderer(this, 36, 17); - bipedLeftArm.addBox(-1F, -2F, -2F, 3, 12, 3, 0F); - bipedLeftArm.setRotationPoint(5F, 8F, 0F); - - bipedRightLeg = new ModelRenderer(this, 0, 20); - bipedRightLeg.addBox(-2F, 2F, -1F, 3, 9, 3, 0F); - bipedRightLeg.setRotationPoint(-2F, 12F, 0F); - - bipedLeftLeg = new ModelRenderer(this, 0, 20); - bipedLeftLeg.addBox(-1F, 3F, -1F, 3, 9, 3, 0F); - bipedLeftLeg.setRotationPoint(2F, 12F, 0F); - - goblinRightEar = new ModelRenderer(this, 48, 20); - goblinRightEar.addBox(3F, -2F, -1F, 2, 3, 1, 0F); - goblinRightEar.setRotationPoint(0F, 3F, 0F); - - goblinLeftEar = new ModelRenderer(this, 48, 24); - goblinLeftEar.addBox(-5F, -2F, -1F, 2, 3, 1, 0F); - goblinLeftEar.setRotationPoint(0F, 3F, 0F); - - goblinLeftEar.mirror = true; -} - - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) - { - super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); - - goblinRightEar.rotateAngleX = bipedHead.rotateAngleX; - goblinRightEar.rotateAngleY = bipedHead.rotateAngleY; - goblinRightEar.rotateAngleZ = bipedHead.rotateAngleZ; - - goblinLeftEar.rotateAngleX = bipedHead.rotateAngleX; - goblinLeftEar.rotateAngleY = bipedHead.rotateAngleY; - goblinLeftEar.rotateAngleZ = bipedHead.rotateAngleZ; - } - - - - @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { - super.render(entity, f, f1, f2, f3, f4, f5); - - goblinRightEar.render(f5); - goblinLeftEar.render(f5); - } - - - - ModelRenderer goblinRightEar; - ModelRenderer goblinLeftEar; -} diff --git a/src/main/java/twilightforest/client/model/ModelTFSkeletonDruid.java b/src/main/java/twilightforest/client/model/ModelTFSkeletonDruid.java deleted file mode 100644 index fb9e19f452..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFSkeletonDruid.java +++ /dev/null @@ -1,48 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; - - -public class ModelTFSkeletonDruid extends ModelBiped { - - public ModelTFSkeletonDruid() { - float f = 0.0F; - - bipedBody = new ModelRenderer(this, 8, 16); - bipedBody.addBox(-4F, 0.0F, -2F, 8, 12, 4, f); - bipedBody.setRotationPoint(0.0F, 0.0F + f, 0.0F); - - bipedRightArm = new ModelRenderer(this, 0, 16); - bipedRightArm.addBox(-1F, -2F, -1F, 2, 12, 2, f); - bipedRightArm.setRotationPoint(-5F, 2.0F, 0.0F); - bipedLeftArm = new ModelRenderer(this, 0, 16); - bipedLeftArm.mirror = true; - bipedLeftArm.addBox(-1F, -2F, -1F, 2, 12, 2, f); - bipedLeftArm.setRotationPoint(5F, 2.0F, 0.0F); - - this.bipedRightLeg = new ModelRenderer(this, 0, 16); - this.bipedRightLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2); - this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F, 0.0F); - this.bipedLeftLeg = new ModelRenderer(this, 0, 16); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2); - this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F, 0.0F); - - - dress = new ModelRenderer(this, 32, 16); - dress.addBox(-4F, 12.0F, -2F, 8, 12, 4, f); - dress.setRotationPoint(0.0F, 0.0F, 0.0F); - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - - dress.render(f5); - } - - public ModelRenderer dress; - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFSlimeBeetle.java b/src/main/java/twilightforest/client/model/ModelTFSlimeBeetle.java deleted file mode 100644 index 81005388b3..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFSlimeBeetle.java +++ /dev/null @@ -1,253 +0,0 @@ -// Date: 11/5/2012 7:35:56 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -public class ModelTFSlimeBeetle extends ModelBase -{ - //fields - ModelRenderer head; - ModelRenderer RearEnd; - ModelRenderer Leg6; - ModelRenderer Leg4; - ModelRenderer Leg2; - ModelRenderer Leg5; - ModelRenderer Leg3; - ModelRenderer Leg1; - ModelRenderer connector1; - ModelRenderer antenna1; - ModelRenderer antenna2; - ModelRenderer eye1; - ModelRenderer eye2; - - ModelRenderer slimeCube; - ModelRenderer tail1; - ModelRenderer tail2; - ModelRenderer mouth; - ModelRenderer slimeCenter; - - boolean renderPassModel = false; - - - public ModelTFSlimeBeetle() - { - this(false); - } - - public ModelTFSlimeBeetle(boolean renderpass) - { - this.renderPassModel = renderpass; - - textureWidth = 64; - textureHeight = 64; - - connector1 = new ModelRenderer(this, 0, 12); - connector1.addBox(-3F, -3F, -1F, 6, 6, 1); - connector1.setRotationPoint(0F, 19F, -4F); - - RearEnd = new ModelRenderer(this, 31, 6); - RearEnd.addBox(-4F, -11F, -4F, 8, 10, 8); - RearEnd.setRotationPoint(0F, 18F, 7F); - setRotation(RearEnd, 1.570796F, 0F, 0F); - - Leg6 = new ModelRenderer(this, 40, 0); - Leg6.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg6.setRotationPoint(2F, 21F, -4F); - setRotation(Leg6, 0F, 0.2792527F, 0.3490659F); - - Leg5 = new ModelRenderer(this, 40, 0); - Leg5.mirror = true; - Leg5.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg5.setRotationPoint(-2F, 21F, -4F); - setRotation(Leg5, 0F, -0.2792527F, -0.3490659F); - - Leg4 = new ModelRenderer(this, 40, 0); - Leg4.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg4.setRotationPoint(2F, 21F, -1F); - setRotation(Leg4, 0F, -0.2792527F, 0.3490659F); - - Leg2 = new ModelRenderer(this, 40, 0); - Leg2.addBox(-1F, -1F, -1F, 10, 2, 2); - Leg2.setRotationPoint(2F, 21F, 4F); - setRotation(Leg2, 0F, -0.6981317F, 0.3490659F); - - Leg3 = new ModelRenderer(this, 40, 0); - Leg3.mirror = true; - Leg3.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg3.setRotationPoint(-2F, 21F, -1F); - setRotation(Leg3, 0F, 0.2792527F, -0.3490659F); - - Leg1 = new ModelRenderer(this, 40, 0); - Leg1.mirror = true; - Leg1.addBox(-9F, -1F, -1F, 10, 2, 2); - Leg1.setRotationPoint(-2F, 21F, 4F); - Leg1.setTextureSize(64, 32); - setRotation(Leg1, 0F, 0.6981317F, -0.3490659F); - - head = new ModelRenderer(this, 0, 0); - head.addBox(-4F, -4F, -6F, 8, 6, 6); - head.setRotationPoint(0F, 19F, -5F); - - antenna1 = new ModelRenderer(this, 38, 4); - antenna1.addBox(0F, -0.5F, -0.5F, 12, 1, 1); - antenna1.setRotationPoint(1F, -3F, -5F); - setRotation(antenna1, 0F, 1.047198F, -0.296706F); - - antenna2 = new ModelRenderer(this, 38, 4); - antenna2.addBox(0F, -0.5F, -0.5F, 12, 1, 1); - antenna2.setRotationPoint(-1F, -3F, -5F); - setRotation(antenna2, 0F, 2.094395F, 0.296706F); - - eye1 = new ModelRenderer(this, 15, 12); - eye1.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - eye1.setRotationPoint(-3F, -2F, -5F); - - eye2 = new ModelRenderer(this, 15, 12); - eye2.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - eye2.setRotationPoint(3F, -2F, -5F); - - - mouth = new ModelRenderer(this, 17, 12); - mouth.addBox(-1F, -1F, -1F, 2, 2, 1); - mouth.setRotationPoint(0F, 1, -6F); - - - head.addChild(antenna1); - head.addChild(antenna2); - head.addChild(eye1); - head.addChild(eye2); - head.addChild(mouth); - - - tail1 = new ModelRenderer(this, 0, 20); - tail1.addBox(-3F, -3F, -3F, 6, 6, 6); - tail1.setRotationPoint(0F, 19F, 9F); - - tail2 = new ModelRenderer(this, 0, 20); - tail2.addBox(-3F, -6F, -3F, 6, 6, 6); - tail2.setRotationPoint(0F, -3F, 2F); - - slimeCube = new ModelRenderer(this, 0, 40); - slimeCube.addBox(-6F, -12F, -9F, 12, 12, 12); - slimeCube.setRotationPoint(0F, -6, 0); - - slimeCenter = new ModelRenderer(this, 32, 24); - slimeCenter.addBox(-4F, -10F, -7F, 8, 8, 8); - slimeCenter.setRotationPoint(0F, -6, 0); - - tail1.addChild(tail2); - - if (renderPassModel) - { - tail2.addChild(slimeCube); - } - else - { - tail2.addChild(slimeCenter); - } - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - - tail1.render(f5); - - if (renderPassModel) - { - } - else - { - head.render(f5); - RearEnd.render(f5); - Leg6.render(f5); - Leg4.render(f5); - Leg2.render(f5); - Leg5.render(f5); - Leg3.render(f5); - Leg1.render(f5); - connector1.render(f5); - //tail1.render(f5); -// tail2.render(f5); -// slimeCenter.render(f5); - } - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - this.head.rotateAngleY = par4 / (180F / (float)Math.PI); - this.head.rotateAngleX = par5 / (180F / (float)Math.PI); - - // legs! - float legZ = ((float)Math.PI / 11F); - this.Leg1.rotateAngleZ = -legZ; - this.Leg2.rotateAngleZ = legZ; - this.Leg3.rotateAngleZ = -legZ * 0.74F; - this.Leg4.rotateAngleZ = legZ * 0.74F; - this.Leg5.rotateAngleZ = -legZ; - this.Leg6.rotateAngleZ = legZ; - - float var9 = -0.0F; - float var10 = 0.3926991F; - this.Leg1.rotateAngleY = var10 * 2.0F + var9; - this.Leg2.rotateAngleY = -var10 * 2.0F - var9; - this.Leg3.rotateAngleY = var10 * 1.0F + var9; - this.Leg4.rotateAngleY = -var10 * 1.0F - var9; - this.Leg5.rotateAngleY = -var10 * 2.0F + var9; - this.Leg6.rotateAngleY = var10 * 2.0F - var9; - - float var11 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + 0.0F) * 0.4F) * par2; - float var12 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + (float)Math.PI) * 0.4F) * par2; - float var14 = -(MathHelper.cos(par1 * 0.6662F * 2.0F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - - float var15 = Math.abs(MathHelper.sin(par1 * 0.6662F + 0.0F) * 0.4F) * par2; - float var16 = Math.abs(MathHelper.sin(par1 * 0.6662F + (float)Math.PI) * 0.4F) * par2; - float var18 = Math.abs(MathHelper.sin(par1 * 0.6662F + ((float)Math.PI * 3F / 2F)) * 0.4F) * par2; - - this.Leg1.rotateAngleY += var11; - this.Leg2.rotateAngleY += -var11; - this.Leg3.rotateAngleY += var12; - this.Leg4.rotateAngleY += -var12; - this.Leg5.rotateAngleY += var14; - this.Leg6.rotateAngleY += -var14; - - this.Leg1.rotateAngleZ += var15; - this.Leg2.rotateAngleZ += -var15; - - this.Leg3.rotateAngleZ += var16; - this.Leg4.rotateAngleZ += -var16; - - this.Leg5.rotateAngleZ += var18; - this.Leg6.rotateAngleZ += -var18; - - - - // tail wiggle - this.tail1.rotateAngleX = MathHelper.cos(par3 * 0.3335F) * 0.15F; - this.tail2.rotateAngleX = MathHelper.cos(par3 * 0.4445F) * 0.20F; - this.slimeCube.rotateAngleX = MathHelper.cos(par3 * 0.5555F) * 0.25F; - this.slimeCenter.rotateAngleX = MathHelper.cos(par3 * 0.5555F + 0.25F) * 0.25F; - - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFSnowGuardian.java b/src/main/java/twilightforest/client/model/ModelTFSnowGuardian.java deleted file mode 100644 index 3a79528c72..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFSnowGuardian.java +++ /dev/null @@ -1,28 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; - -public class ModelTFSnowGuardian extends ModelBiped { - - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); - - } - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float partialTick) { - //float bounce = par1EntityLiving.ticksExisted + partialTick; - //par1EntityLiving.yOffset = 0.5F + MathHelper.sin((bounce) * 0.3F) * 0.5F; - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFSnowQueen.java b/src/main/java/twilightforest/client/model/ModelTFSnowQueen.java deleted file mode 100644 index 3bb6c4aeea..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFSnowQueen.java +++ /dev/null @@ -1,145 +0,0 @@ -package twilightforest.client.model; - -import twilightforest.entity.boss.EntityTFSnowQueen; -import twilightforest.entity.boss.EntityTFSnowQueen.Phase; -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -public class ModelTFSnowQueen extends ModelBiped { - - public ModelTFSnowQueen() { - - float par1 = 0; - float par2 = 0; - - - // crown - this.bipedHeadwear = new ModelRenderer(this, 0, 0); - - this.bipedHeadwear.addChild(makeFrontCrown(-1, -4, 10F)); - this.bipedHeadwear.addChild(makeFrontCrown(0, 4, -10F)); - this.bipedHeadwear.addChild(makeSideCrown(-1, -4, 10F)); - this.bipedHeadwear.addChild(makeSideCrown(0, 4, -10F)); - - // copy to back - - - - // dress - this.bipedBody = new ModelRenderer(this, 32, 0); - this.bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 23, 4, par1); - this.bipedBody.setRotationPoint(0.0F, 0.0F + par2, 0.0F); - - // shrink - this.bipedRightArm = new ModelRenderer(this, 16, 16); - this.bipedRightArm.addBox(-2.0F, -2.0F, -1.5F, 3, 12, 3, par1); - this.bipedRightArm.setRotationPoint(-5.0F, 2.0F + par2, 0.0F); - this.bipedLeftArm = new ModelRenderer(this, 16, 16); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.3F, 3, 12, 3, par1); - this.bipedLeftArm.setRotationPoint(5.0F, 2.0F + par2, 0.0F); - this.bipedRightLeg = new ModelRenderer(this, 0, 16); - this.bipedRightLeg.addBox(-1.5F, 0.0F, -1.5F, 3, 12, 3, par1); - this.bipedRightLeg.setRotationPoint(-1.9F, 12.0F + par2, 0.0F); - this.bipedLeftLeg = new ModelRenderer(this, 0, 16); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-1.5F, 0.0F, -1.5F, 3, 12, 3, par1); - this.bipedLeftLeg.setRotationPoint(1.9F, 12.0F + par2, 0.0F); - - } - - private ModelRenderer makeSideCrown(float spikeDepth, float crownX, float angle) { - ModelRenderer crownSide = new ModelRenderer(this, 28, 28); - crownSide.addBox(-3.5F, -0.5F, -0.5F, 7, 1, 1); - crownSide.setRotationPoint(crownX, -6.0F, 0.0F); - crownSide.rotateAngleY = 3.14159F / 2.0F; - - ModelRenderer spike4 = new ModelRenderer(this, 48, 27); - spike4.addBox(-0.5F, -3.5F, spikeDepth, 1, 4, 1); - spike4.rotateAngleX = angle * 1.5F / 180F * 3.14159F; - - ModelRenderer spike3l = new ModelRenderer(this, 52, 28); - spike3l.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); - spike3l.setRotationPoint(-2.5F, 0.0F, 0.0F); - spike3l.rotateAngleX = angle / 180F * 3.14159F; - spike3l.rotateAngleZ = -10F / 180F * 3.14159F; - - ModelRenderer spike3r = new ModelRenderer(this, 52, 28); - spike3r.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); - spike3r.setRotationPoint(2.5F, 0.0F, 0.0F); - spike3r.rotateAngleX = angle / 180F * 3.14159F; - spike3r.rotateAngleZ = 10F / 180F * 3.14159F; - - - crownSide.addChild(spike4); - crownSide.addChild(spike3l); - crownSide.addChild(spike3r); - return crownSide; - } - - private ModelRenderer makeFrontCrown(float spikeDepth, float crownZ, float angle) { - ModelRenderer crownFront = new ModelRenderer(this, 28, 30); - crownFront.addBox(-4.5F, -0.5F, -0.5F, 9, 1, 1); - crownFront.setRotationPoint(0.0F, -6.0F, crownZ); - - ModelRenderer spike4 = new ModelRenderer(this, 48, 27); - spike4.addBox(-0.5F, -3.5F, spikeDepth, 1, 4, 1); - spike4.rotateAngleX = angle * 1.5F / 180F * 3.14159F; - - ModelRenderer spike3l = new ModelRenderer(this, 52, 28); - spike3l.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); - spike3l.setRotationPoint(-2.5F, 0.0F, 0.0F); - spike3l.rotateAngleX = angle / 180F * 3.14159F; - spike3l.rotateAngleZ = -10F / 180F * 3.14159F; - - ModelRenderer spike3r = new ModelRenderer(this, 52, 28); - spike3r.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); - spike3r.setRotationPoint(2.5F, 0.0F, 0.0F); - spike3r.rotateAngleX = angle / 180F * 3.14159F; - spike3r.rotateAngleZ = 10F / 180F * 3.14159F; - - crownFront.addChild(spike4); - crownFront.addChild(spike3l); - crownFront.addChild(spike3r); - return crownFront; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); - - EntityTFSnowQueen queen = (EntityTFSnowQueen)par7Entity; - - // in beam phase, arms forwards - if (queen.getCurrentPhase() == Phase.BEAM) { - if (queen.isBreathing()) { - float f6 = MathHelper.sin(this.onGround * (float)Math.PI); - float f7 = MathHelper.sin((1.0F - (1.0F - this.onGround) * (1.0F - this.onGround)) * (float)Math.PI); - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightArm.rotateAngleY = -(0.1F - f6 * 0.6F); - this.bipedLeftArm.rotateAngleY = 0.1F - f6 * 0.6F; - this.bipedRightArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedLeftArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedRightArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; - this.bipedLeftArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - } else { - // arms up - this.bipedRightArm.rotateAngleX += Math.PI; - this.bipedLeftArm.rotateAngleX += Math.PI; - } - } - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFSquirrel.java b/src/main/java/twilightforest/client/model/ModelTFSquirrel.java deleted file mode 100644 index dcd1da5280..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFSquirrel.java +++ /dev/null @@ -1,159 +0,0 @@ -// Date: 4/27/2012 9:49:06 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - - -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - - -public class ModelTFSquirrel extends ModelBase -{ - //fields - ModelRenderer body; - ModelRenderer leg1; - ModelRenderer leg2; - ModelRenderer leg3; - ModelRenderer leg4; - ModelRenderer head; - ModelRenderer tail; - ModelRenderer fluff1; - ModelRenderer fluff2; - ModelRenderer fluff3; - - public ModelTFSquirrel() - { - textureWidth = 32; - textureHeight = 32; - setTextureOffset("head.head", 0, 0); - setTextureOffset("head.ear2", 16, 0); - setTextureOffset("head.ear1", 16, 0); - setTextureOffset("tail.fluff1", 0, 20); - setTextureOffset("tail.base", 0, 18); - setTextureOffset("tail.fluff2", 0, 20); - setTextureOffset("tail.fluff3", 0, 26); - - body = new ModelRenderer(this, 0, 8); - body.addBox(-2F, -1F, -2F, 4, 3, 5); - body.setRotationPoint(0F, 21F, 0F); - body.setTextureSize(32, 32); - body.mirror = true; - setRotation(body, 0F, 0F, 0F); - leg1 = new ModelRenderer(this, 0, 16); - leg1.addBox(0F, 0F, 0F, 1, 1, 1); - leg1.setRotationPoint(-2F, 23F, 2F); - leg1.setTextureSize(32, 32); - leg1.mirror = true; - setRotation(leg1, 0F, 0F, 0F); - leg2 = new ModelRenderer(this, 0, 16); - leg2.addBox(0F, 0F, 0F, 1, 1, 1); - leg2.setRotationPoint(1F, 23F, 2F); - leg2.setTextureSize(32, 32); - leg2.mirror = true; - setRotation(leg2, 0F, 0F, 0F); - leg3 = new ModelRenderer(this, 0, 16); - leg3.addBox(0F, 0F, 0F, 1, 1, 1); - leg3.setRotationPoint(-2F, 23F, -2F); - leg3.setTextureSize(32, 32); - - setRotation(leg3, 0F, 0F, 0F); - leg4 = new ModelRenderer(this, 0, 16); - leg4.addBox(0F, 0F, 0F, 1, 1, 1); - leg4.setRotationPoint(1F, 23F, -2F); - leg4.setTextureSize(32, 32); - - setRotation(leg4, 0F, 0F, 0F); - head = new ModelRenderer(this, "head"); - head.setRotationPoint(0F, 22F, -2F); - setRotation(head, 0F, 0F, 0F); - - head.addBox("head", -2F, -5F, -3F, 4, 4, 4); - head.addBox("ear2", -2F, -6F, -0.5F, 1, 1, 1); - head.addBox("ear1", 1F, -6F, -0.5F, 1, 1, 1); - - tail = new ModelRenderer(this, "tail"); - tail.setRotationPoint(0F, 21F, 2F); - - tail.addBox("base", -0.5F, -1.5F, 0.5F, 1, 1, 1); - - fluff1 = new ModelRenderer(this, 0, 20); - fluff1.addBox(-1.5F, -4F, 1F, 3, 3, 3); - tail.addChild(fluff1); - - fluff2 = new ModelRenderer(this, 0, 20); - fluff2.addBox(0F, -3F, -1.5F, 3, 3, 3); - fluff2.setRotationPoint(-1.5F, -4F, 2.5F); - fluff1.addChild(fluff2); - - fluff3 = new ModelRenderer(this, 0, 26); - fluff3.addBox(1.5F, -3F, -1.5F, 3, 3, 3); - fluff3.setRotationPoint(-1.5F, -3F, 0F); - fluff2.addChild(fluff3); - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5); - body.render(f5); - leg1.render(f5); - leg2.render(f5); - leg3.render(f5); - leg4.render(f5); - head.render(f5); - tail.render(f5); - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float par4) - { - //EntityTFSquirrel squirrel = (EntityTFSquirrel)par1EntityLiving; - - - } - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6) - { - this.head.rotateAngleX = par5 / (180F / (float)Math.PI); - this.head.rotateAngleY = par4 / (180F / (float)Math.PI); - this.leg1.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.leg2.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.leg3.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.leg4.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - - if (par2 > 0.2) { - float wiggle = Math.min(par2, 0.6F); - this.tail.rotateAngleX = (MathHelper.cos(par3 * 0.6662F) * 1.0F - (float)Math.PI / 3) * wiggle; - this.fluff2.rotateAngleX = MathHelper.cos(par3 * 0.7774F) * 1.2F * wiggle; - this.fluff3.rotateAngleX = MathHelper.cos(par3 * 0.8886F + (float)Math.PI / 2) * 1.4F * wiggle; - } - else { - this.tail.rotateAngleX = 0.2F + MathHelper.cos(par3 * 0.3335F) * 0.15F; - this.fluff2.rotateAngleX = 0.1F + MathHelper.cos(par3 * 0.4445F) * 0.20F; - this.fluff3.rotateAngleX = 0.1F + MathHelper.cos(par3 * 0.5555F) * 0.25F; - } - - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFSwarmSpider.java b/src/main/java/twilightforest/client/model/ModelTFSwarmSpider.java deleted file mode 100644 index 373f8294fc..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFSwarmSpider.java +++ /dev/null @@ -1,13 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelSpider; -import net.minecraft.entity.Entity; - - -public class ModelTFSwarmSpider extends ModelSpider { - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - super.render(entity, f, f1, f2, f3, f4, f5 * 0.5f); - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFTinyBird.java b/src/main/java/twilightforest/client/model/ModelTFTinyBird.java deleted file mode 100644 index bd9a0cc388..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFTinyBird.java +++ /dev/null @@ -1,159 +0,0 @@ -// Date: 4/25/2012 10:28:13 PM -// Template version 1.1 -// Java generated by Techne -// Keep in mind that you still need to fill in some blanks -// - ZeuX - -package twilightforest.client.model; - - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -import org.lwjgl.opengl.GL11; - -import twilightforest.entity.passive.EntityTFBird; - -public class ModelTFTinyBird extends ModelBase -{ - //fields - ModelRenderer beak; - ModelRenderer head; - ModelRenderer body; - ModelRenderer rightarm; - ModelRenderer leftarm; - ModelRenderer rightleg; - ModelRenderer leftleg; - ModelRenderer tail; - - public ModelTFTinyBird() - { - textureWidth = 32; - textureHeight = 32; - - head = new ModelRenderer(this, 0, 0); - head.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); - head.setRotationPoint(0F, 20.5F, -0.5F); - head.setTextureSize(32, 32); - head.mirror = true; - setRotation(head, 0F, 0F, 0F); - - beak = new ModelRenderer(this, 12, 0); - beak.addBox(-0.5F, -0.5F, -0.5F, 1, 1, 1); - beak.setRotationPoint(0F, 0.5F, -2F); - - head.addChild(beak); - - - body = new ModelRenderer(this, 0, 6); - body.addBox(-1.5F, 0F, -1F, 3, 3, 3); - body.setRotationPoint(0F, 20F, 0F); - body.setTextureSize(32, 32); - body.mirror = true; - setRotation(body, 0F, 0F, 0F); - rightarm = new ModelRenderer(this, 12, 2); - rightarm.addBox(-1F, 0F, -1.5F, 1, 2, 3); - rightarm.setRotationPoint(-1.5F, 20.5F, 1F); - rightarm.setTextureSize(32, 32); - rightarm.mirror = true; - setRotation(rightarm, 0F, 0F, 0F); - leftarm = new ModelRenderer(this, 12, 2); - leftarm.addBox(0F, 0F, -1.5F, 1, 2, 3); - leftarm.setRotationPoint(1.5F, 20.5F, 1F); - leftarm.setTextureSize(32, 32); - leftarm.mirror = true; - setRotation(leftarm, 0F, 0F, 0F); - rightleg = new ModelRenderer(this, 0, 12); - rightleg.addBox(0F, 0F, 0F, 1, 1, 1); - rightleg.setRotationPoint(-1.5F, 23F, 0F); - rightleg.setTextureSize(32, 32); - rightleg.mirror = true; - setRotation(rightleg, 0F, 0F, 0F); - leftleg = new ModelRenderer(this, 0, 12); - leftleg.addBox(0.5F, 0F, 0F, 1, 1, 1); - leftleg.setRotationPoint(0F, 23F, 0F); - leftleg.setTextureSize(32, 32); - leftleg.mirror = true; - setRotation(leftleg, 0F, 0F, 0F); - tail = new ModelRenderer(this, 0, 14); - tail.addBox(-1.5F, -0.5F, 0F, 3, 1, 2); - tail.setRotationPoint(0F, 22F, 2F); - tail.setTextureSize(32, 32); - tail.mirror = true; - setRotation(tail, 0F, 0F, 0F); - } - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); - - if (isChild) - { - float f = 2.0F; - GL11.glPushMatrix(); - GL11.glTranslatef(0.0F, 5F * par7, 0.75F * par7); - head.render(par7); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - GL11.glScalef(1.0F / f, 1.0F / f, 1.0F / f); - GL11.glTranslatef(0.0F, 24F * par7, 0.0F); - body.render(par7); - rightleg.render(par7); - leftleg.render(par7); - rightarm.render(par7); - leftarm.render(par7); - GL11.glPopMatrix(); - } - else - { - head.render(par7); - body.render(par7); - rightleg.render(par7); - leftleg.render(par7); - rightarm.render(par7); - leftarm.render(par7); - tail.render(par7); -// beak.render(par7); - } - } - - private void setRotation(ModelRenderer model, float x, float y, float z) - { - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - - /** - * Sets the models various rotation angles. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - head.rotateAngleX = par5 / (180F / (float)Math.PI); - head.rotateAngleY = par4 / (180F / (float)Math.PI); - - rightleg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - leftleg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - - rightarm.rotateAngleZ = par3; - leftarm.rotateAngleZ = -par3; - - if (((EntityTFBird)par7Entity).isBirdLanded()) - { - rightleg.rotationPointY = 23; - leftleg.rotationPointY = 23; - } - else - { - rightleg.rotationPointY = 22.5F; - leftleg.rotationPointY = 22.5F; - } - - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFTinyFirefly.java b/src/main/java/twilightforest/client/model/ModelTFTinyFirefly.java deleted file mode 100644 index b73a37512f..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFTinyFirefly.java +++ /dev/null @@ -1,29 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; - - -public class ModelTFTinyFirefly extends ModelBase -{ - public ModelTFTinyFirefly() - { - glow1 = new ModelRenderer(this, 20, 0); - glow1.addBox(-5F, -5F, 0F, 10, 10, 0, 0F); - - } - - public void render(float f, float f1, float f2, float f3, float f4, float f5) - { - glow1.render(f5); - } - - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) - { - //super.setRotationAngles(f, f1, f2, f3, f4, f5); - } - - //fields - public ModelRenderer glow1; - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFTowerBoss.java b/src/main/java/twilightforest/client/model/ModelTFTowerBoss.java deleted file mode 100644 index 76c7182123..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFTowerBoss.java +++ /dev/null @@ -1,176 +0,0 @@ -package twilightforest.client.model; - -import java.util.Random; - -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -public class ModelTFTowerBoss extends ModelTFGhast { - - protected ModelRenderer[][] subTentacles; - protected ModelRenderer[][] smallTentacles; - - public ModelTFTowerBoss() - { - super(); - - this.smallTentacles = new ModelRenderer[2][3]; - for (int i = 0; i < this.smallTentacles.length; ++i) - { - makeSmallTentacle(i); - } - } - - protected void makeTentacle(byte yOffset, Random random, int num) { - this.tentacles[num] = new ModelRenderer(this, num % 3, 0); - - int length = 5; - - this.tentacles[num].addBox(-1.5F, 0.0F, -1.5F, 3, length, 3); - - - if (num == 0) - { - this.tentacles[num].rotationPointX = 4.5F; - this.tentacles[num].rotationPointZ = 4.5F; - this.tentacles[num].rotationPointY = (float)(23 + yOffset); - } - if (num == 1) - { - this.tentacles[num].rotationPointX = -4.5F; - this.tentacles[num].rotationPointZ = 4.5F; - this.tentacles[num].rotationPointY = (float)(23 + yOffset); - } - if (num == 2) - { - this.tentacles[num].rotationPointX = 0F; - this.tentacles[num].rotationPointZ = 0F; - this.tentacles[num].rotationPointY = (float)(23 + yOffset); - } - if (num == 3) - { - this.tentacles[num].rotationPointX = 5.5F; - this.tentacles[num].rotationPointZ = -4.5F; - this.tentacles[num].rotationPointY = (float)(23 + yOffset); - } - if (num == 4) - { - this.tentacles[num].rotationPointX = -5.5F; - this.tentacles[num].rotationPointZ = -4.5F; - this.tentacles[num].rotationPointY = (float)(23 + yOffset); - } - else if (num == 5) - { - this.tentacles[num].rotationPointX = -7.5F; - this.tentacles[num].rotationPointY = 3.5F; - this.tentacles[num].rotationPointZ = -1F; - - this.tentacles[num].rotateAngleZ = (float)Math.PI / 4.0F; - } - else if (num == 6) - { - this.tentacles[num].rotationPointX = -7.5F; - this.tentacles[num].rotationPointY = -1.5F; - this.tentacles[num].rotationPointZ = 3.5F; - - this.tentacles[num].rotateAngleZ = (float)Math.PI / 3.0F; - } - else if (num == 7) - { - this.tentacles[num].rotationPointX = 7.5F; - this.tentacles[num].rotationPointY = 3.5F; - this.tentacles[num].rotationPointZ = -1F; - - this.tentacles[num].rotateAngleZ = -(float)Math.PI / 4.0F; - } - else if (num == 8) - { - this.tentacles[num].rotationPointX = 7.5F; - this.tentacles[num].rotationPointY = -1.5F; - this.tentacles[num].rotationPointZ = 3.5F; - - this.tentacles[num].rotateAngleZ = -(float)Math.PI / 3.0F; - } - - // goofy mid-method initializer - if (this.subTentacles == null) - { - this.subTentacles = new ModelRenderer[tentacles.length][3]; - } - - for (int i = 0; i < 3; i++) - { - length = 4; - - this.subTentacles[num][i] = new ModelRenderer(this, num % 4, (i * 5) - 1); - - this.subTentacles[num][i].addBox(-1.5F, -0.5F, -1.5F, 3, length, 3); - this.subTentacles[num][i].rotationPointX = 0; - this.subTentacles[num][i].rotationPointZ = 0; - this.subTentacles[num][i].rotationPointY = length; - - if (i == 0) - { - this.tentacles[num].addChild(this.subTentacles[num][i]); - } - else - { - this.subTentacles[num][i - 1].addChild(this.subTentacles[num][i]); - } - } - - this.body.addChild(this.tentacles[num]); - - } - - - /** - * Make one of the small tentacles - * @param i - */ - protected void makeSmallTentacle(int num) - { - ; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float timeAlive, float yaw, float pitch, float par6, Entity par7Entity) - { - super.setRotationAngles(par1, par2, timeAlive, yaw, pitch, par6, par7Entity); - - // wave tentacles - for (int i = 0; i < this.subTentacles.length; ++i) - { -// for (int j = 0; j < this.subTentacles[i].length; ++j) -// { -// this.subTentacles[i][j].rotateAngleX = 0.8F * MathHelper.sin(i * 2.3F) + 0.3F * MathHelper.sin(j) + 0.2F; -// -// } - - float wiggle = Math.min(par2, 0.6F); - - float time = (timeAlive + (i * 9)) / 2.0F; - - this.subTentacles[i][0].rotateAngleX = (MathHelper.cos(time * 0.6662F) * 1.0F - (float)Math.PI / 3.0F) * wiggle; - this.subTentacles[i][1].rotateAngleX = MathHelper.cos(time * 0.7774F) * 1.2F * wiggle; - this.subTentacles[i][2].rotateAngleX = MathHelper.cos(time * 0.8886F + (float)Math.PI / 2.0F) * 1.4F * wiggle; - - this.subTentacles[i][0].rotateAngleX = 0.2F + MathHelper.cos(time * 0.3335F) * 0.15F; - this.subTentacles[i][1].rotateAngleX = 0.1F + MathHelper.cos(time * 0.4445F) * 0.20F; - this.subTentacles[i][2].rotateAngleX = 0.1F + MathHelper.cos(time * 0.5555F) * 0.25F; - - - - float yTwist = 0.4F; - - this.tentacles[i].rotateAngleY = yTwist * MathHelper.sin(time * 0.3F); - - } - } - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFTowerGolem.java b/src/main/java/twilightforest/client/model/ModelTFTowerGolem.java deleted file mode 100644 index 7a5c2f6fd0..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFTowerGolem.java +++ /dev/null @@ -1,158 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; -import twilightforest.entity.EntityTFTowerGolem; - -//Date: 3/9/2013 10:55:38 AM -//Template version 1.1 -//Java generated by Techne -//Keep in mind that you still need to fill in some blanks -//- ZeuX - - -public class ModelTFTowerGolem extends ModelBase -{ - //fields - ModelRenderer head; - ModelRenderer jaw; - ModelRenderer body; - ModelRenderer rightarm; - ModelRenderer leftarm; - ModelRenderer leftleg; - ModelRenderer leftfoot; - ModelRenderer ribs; - ModelRenderer hips; - ModelRenderer rightfoot; - ModelRenderer rightleg; - ModelRenderer spine; - - public ModelTFTowerGolem() - { - textureWidth = 128; - textureHeight = 64; - - head = new ModelRenderer(this, 0, 0); - head.setRotationPoint(0F, -11F, -2F); - head.setTextureOffset(0, 0).addBox(-3.5F, -10F, -3F, 7, 8, 6); // head - head.setTextureOffset(0, 14).addBox(-4F, -6F, -3.5F, 8, 4, 6); // jaw - - body = new ModelRenderer(this, 0, 26); - body.addBox(-8F, 0F, -5F, 16, 10, 10); - body.setRotationPoint(0F, -13F, 0F); - - ribs = new ModelRenderer(this, 0, 46); - ribs.addBox(-5F, 0F, -3F, 10, 6, 6); - ribs.setRotationPoint(0F, -3F, 0F); - - rightarm = new ModelRenderer(this, 52, 0); - rightarm.setRotationPoint(-8F, -12F, 0F); - rightarm.setTextureOffset(52, 0).addBox(-5F, -2F, -1.5F, 3, 14, 3); // arm - rightarm.setTextureOffset(52, 17).addBox(-7F, 12F, -3F, 6, 12, 6); // fist - rightarm.setTextureOffset(52, 36).addBox(-7F, -3F, -3.5F, 7, 2, 7); // shoulder top - rightarm.setTextureOffset(52, 45).addBox(-7F, -1F, -3.5F, 7, 5, 2); // shoulder front - rightarm.setTextureOffset(52, 45).addBox(-7F, -1F, 1.5F, 7, 5, 2); // shoulder back - rightarm.setTextureOffset(52, 54).addBox(-2F, -1F, -2F, 2, 5, 3); // shoulder inner - - leftarm = new ModelRenderer(this, 52, 0); - leftarm.mirror = true; - leftarm.setRotationPoint(8F, -12F, 0F); - leftarm.setTextureOffset(52, 0).addBox(2F, -2F, -1.5F, 3, 14, 3); // arm - leftarm.setTextureOffset(52, 17).addBox(1F, 12F, -3F, 6, 12, 6); // fist - leftarm.setTextureOffset(52, 36).addBox(0F, -3F, -3.5F, 7, 2, 7); // shoulder top - leftarm.setTextureOffset(52, 45).addBox(0F, -1F, -3.5F, 7, 5, 2); // shoulder front - leftarm.setTextureOffset(52, 45).addBox(0F, -1F, 1.5F, 7, 5, 2); // shoulder back - leftarm.setTextureOffset(52, 54).addBox(0F, -1F, -2F, 2, 5, 3); // shoulder inner - - hips = new ModelRenderer(this, 84, 25); - hips.addBox(-5F, 0F, -2F, 10, 3, 4); - hips.setRotationPoint(0F, 1F, 0F); - - spine = new ModelRenderer(this, 84, 18); - spine.addBox(-1.5F, 0F, -1.5F, 3, 4, 3); - spine.setRotationPoint(0F, -3F, 0F); - - leftleg = new ModelRenderer(this, 84, 32); - leftleg.mirror = true; - leftleg.setRotationPoint(1F, 2F, 0F); - leftleg.setTextureOffset(84, 32).addBox(0F, 0F, -1.5F, 3, 8, 3); - leftleg.setTextureOffset(84, 43).addBox(-0.5F, 8F, -4F, 6, 14, 7); - - rightleg = new ModelRenderer(this, 84, 32); - rightleg.setRotationPoint(-1F, 2F, 0F); - rightleg.setTextureOffset(84, 32).addBox(-3F, 0F, -1.5F, 3, 8, 3); - rightleg.setTextureOffset(84, 43).addBox(-5.5F, 8F, -4F, 6, 14, 7); - - } - - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - //super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - head.render(f5); - body.render(f5); - rightarm.render(f5); - leftarm.render(f5); - rightleg.render(f5); - leftleg.render(f5); - ribs.render(f5); - hips.render(f5); - spine.render(f5); - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - this.head.rotateAngleY = par4 / (180F / (float)Math.PI); - this.head.rotateAngleX = par5 / (180F / (float)Math.PI); - this.leftleg.rotateAngleX = -1.5F * this.func_78172_a(par1, 13.0F) * par2; - this.rightleg.rotateAngleX = 1.5F * this.func_78172_a(par1, 13.0F) * par2; - this.leftleg.rotateAngleY = 0.0F; - this.rightleg.rotateAngleY = 0.0F; - -// this.leftleg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; // biped leg movement -// this.rightleg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - - - this.rightarm.rotateAngleZ = MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.leftarm.rotateAngleZ = -MathHelper.cos(par3 * 0.09F) * 0.05F - 0.05F; - - } - - - - - /** - * Used for easily adding entity-dependent animations. The second and third float params here are the same second - * and third as in the setRotationAngles method. - */ - public void setLivingAnimations(EntityLivingBase par1EntityLiving, float par2, float par3, float par4) - { - EntityTFTowerGolem var5 = (EntityTFTowerGolem)par1EntityLiving; - int var6 = var5.getAttackTimer(); - - if (var6 > 0) - { - this.rightarm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float)var6 - par4, 10.0F); - this.leftarm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float)var6 - par4, 10.0F); - } - else - { - this.rightarm.rotateAngleX = (-0.2F + 1.5F * this.func_78172_a(par2, 25.0F)) * par3; - this.leftarm.rotateAngleX = (-0.2F - 1.5F * this.func_78172_a(par2, 25.0F)) * par3; - } - } - - private float func_78172_a(float par1, float par2) - { - return (Math.abs(par1 % par2 - par2 * 0.5F) - par2 * 0.25F) / (par2 * 0.25F); - } -} diff --git a/src/main/java/twilightforest/client/model/ModelTFTroll.java b/src/main/java/twilightforest/client/model/ModelTFTroll.java deleted file mode 100644 index 7738d53392..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFTroll.java +++ /dev/null @@ -1,129 +0,0 @@ -package twilightforest.client.model; - -import twilightforest.entity.EntityTFTroll; -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; - -public class ModelTFTroll extends ModelBiped { - - public ModelRenderer nose; - - - public ModelTFTroll() - { - super(); - - this.textureWidth = 128; - this.textureHeight = 64; - - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(-5.0F, -8.0F, -3.0F, 10, 10, 10); - this.bipedHead.setRotationPoint(0.0F, -9.0F, -6.0F); - - this.bipedHeadwear = new ModelRenderer(this, 32, 0); - this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); - - this.bipedBody = new ModelRenderer(this, 40, 0); - this.bipedBody.addBox(-8.0F, 0.0F, -5.0F, 16, 26, 10); - this.bipedBody.setRotationPoint(0.0F, -14.0F, 0.0F); - - - this.nose = new ModelRenderer(this, 0, 21); - this.nose.addBox(-2.0F, -2.0F, -2.0F, 4, 8, 4); - this.nose.setRotationPoint(0.0F, -2.0F, -4.0F); - this.bipedHead.addChild(nose); - - this.bipedRightArm = new ModelRenderer(this, 32, 36); - this.bipedRightArm.addBox(-5.0F, -2.0F, -3.0F, 6, 22, 6); - this.bipedRightArm.setRotationPoint(-9.0F, -9.0F, 0.0F); - - this.bipedLeftArm = new ModelRenderer(this, 32, 36); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(-1.0F, -2.0F, -3.0F, 6, 22, 6); - this.bipedLeftArm.setRotationPoint(9.0F, -9.0F, 0.0F); - - - this.bipedRightLeg = new ModelRenderer(this, 0, 44); - this.bipedRightLeg.addBox(-3.0F, 0.0F, -4.0F, 6, 12, 8); - this.bipedRightLeg.setRotationPoint(-5.0F, 12.0F, 0.0F); - - this.bipedLeftLeg = new ModelRenderer(this, 0, 44); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-3.0F, 0.0F, -4.0F, 6, 12, 8); - this.bipedLeftLeg.setRotationPoint(5.0F, 12.0F, 0.0F); - } - - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - EntityTFTroll troll = (EntityTFTroll)par7Entity; - - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; - this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.bipedRightLeg.rotateAngleY = 0.0F; - this.bipedLeftLeg.rotateAngleY = 0.0F; - - if (par7Entity.riddenByEntity != null) - { - // arms up! - this.bipedRightArm.rotateAngleX += Math.PI; - this.bipedLeftArm.rotateAngleX += Math.PI; - - } - - if (this.heldItemLeft != 0 || this.heldItemRight != 0) { - this.bipedRightArm.rotateAngleX += Math.PI; - this.bipedLeftArm.rotateAngleX += Math.PI; - } - - if (this.onGround > 0F) { - float swing = 1.0F - this.onGround; - - this.bipedRightArm.rotateAngleX -= (Math.PI * swing); - this.bipedLeftArm.rotateAngleX -= (Math.PI * swing); - } - - this.bipedRightArm.rotateAngleY = 0.0F; - this.bipedLeftArm.rotateAngleY = 0.0F; - - - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - - } - - /** - * Change eye color if yeti is angry - */ - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) { - EntityTFTroll troll = (EntityTFTroll)par1EntityLivingBase; - - if (troll.getAttackTarget() != null) { - this.bipedRightArm.rotateAngleX += Math.PI; - this.bipedLeftArm.rotateAngleX += Math.PI; - } - - } - - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFWraith.java b/src/main/java/twilightforest/client/model/ModelTFWraith.java deleted file mode 100644 index a3563168b1..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFWraith.java +++ /dev/null @@ -1,61 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - - -public class ModelTFWraith extends ModelBiped { - - public ModelRenderer dress; - - public ModelTFWraith() { - float f = 0.0F; - dress = new ModelRenderer(this, 40, 16); - dress.addBox(-4F, 12.0F, -2F, 8, 12, 4, f); - dress.setRotationPoint(0.0F, 0.0F, 0.0F); - - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) - { - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - bipedHead.render(f5); - bipedBody.render(f5); - bipedRightArm.render(f5); - bipedLeftArm.render(f5); - - dress.render(f5); - - //bipedRightLeg.render(f5); - //bipedLeftLeg.render(f5); - bipedHeadwear.render(f5); - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); - float var8 = MathHelper.sin(this.onGround * (float)Math.PI); - float var9 = MathHelper.sin((1.0F - (1.0F - this.onGround) * (1.0F - this.onGround)) * (float)Math.PI); - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightArm.rotateAngleY = -(0.1F - var8 * 0.6F); - this.bipedLeftArm.rotateAngleY = 0.1F - var8 * 0.6F; - this.bipedRightArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedLeftArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; - this.bipedLeftArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFYeti.java b/src/main/java/twilightforest/client/model/ModelTFYeti.java deleted file mode 100644 index 6fe806a4fb..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFYeti.java +++ /dev/null @@ -1,171 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; -import twilightforest.entity.EntityTFYeti; - -public class ModelTFYeti extends ModelBiped { - - public ModelRenderer mouth; - public ModelRenderer leftEye; - public ModelRenderer rightEye; - public ModelRenderer angryLeftEye; - public ModelRenderer angryRightEye; - - - public ModelTFYeti() - { - super(); - - this.textureWidth = 128; - this.textureHeight = 64; - - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); - this.bipedHeadwear = new ModelRenderer(this, 32, 0); - this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); - - this.bipedBody = new ModelRenderer(this, 32, 0); - this.bipedBody.addBox(-10.0F, 0.0F, -6.0F, 20, 26, 12); - this.bipedBody.setRotationPoint(0.0F, -14.0F, 0.0F); - - - this.mouth = new ModelRenderer(this, 96, 6); - this.mouth.addBox(-7.0F, -5.0F, -0.5F, 14, 10, 1); - this.mouth.setRotationPoint(0.0F, 12.0F, -6.0F); - this.bipedBody.addChild(mouth); - - this.rightEye = new ModelRenderer(this, 96, 0); - this.rightEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); - this.rightEye.setRotationPoint(-5.5F, 4.5F, -6.0F); - this.bipedBody.addChild(rightEye); - - this.leftEye = new ModelRenderer(this, 96, 0); - this.leftEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); - this.leftEye.setRotationPoint(5.5F, 4.5F, -6.0F); - this.bipedBody.addChild(leftEye); - - this.angryRightEye = new ModelRenderer(this, 109, 0); - this.angryRightEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); - this.angryRightEye.setRotationPoint(5.5F, 4.5F, -6.0F); - this.bipedBody.addChild(angryRightEye); - - this.angryLeftEye = new ModelRenderer(this, 109, 0); - this.angryLeftEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); - this.angryLeftEye.setRotationPoint(-5.5F, 4.5F, -6.0F); - this.bipedBody.addChild(angryLeftEye); - - this.bipedRightArm = new ModelRenderer(this, 0, 0); - this.bipedRightArm.addBox(-5.0F, -2.0F, -3.0F, 6, 16, 6); - this.bipedRightArm.setRotationPoint(-11.0F, -4.0F, 0.0F); - this.bipedLeftArm = new ModelRenderer(this, 0, 0); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(-1.0F, -2.0F, -3.0F, 6, 16, 6); - this.bipedLeftArm.setRotationPoint(11.0F, -4.0F, 0.0F); - this.bipedRightLeg = new ModelRenderer(this, 0, 22); - this.bipedRightLeg.addBox(-4.0F, 0.0F, -4.0F, 8, 12, 8); - this.bipedRightLeg.setRotationPoint(-6.0F, 12.0F, 0.0F); - this.bipedLeftLeg = new ModelRenderer(this, 0, 22); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-4.0F, 0.0F, -4.0F, 8, 12, 8); - this.bipedLeftLeg.setRotationPoint(6.0F, 12.0F, 0.0F); - } - - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - EntityTFYeti yeti = (EntityTFYeti)par7Entity; - - - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; - this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.bipedRightLeg.rotateAngleY = 0.0F; - this.bipedLeftLeg.rotateAngleY = 0.0F; - - if (par7Entity.riddenByEntity != null) - { - // arms up! - this.bipedRightArm.rotateAngleX += Math.PI; - this.bipedLeftArm.rotateAngleX += Math.PI; - - } - - if (this.heldItemLeft != 0) - { - this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemLeft; - } - - if (this.heldItemRight != 0) - { - this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemRight; - } - - this.bipedRightArm.rotateAngleY = 0.0F; - this.bipedLeftArm.rotateAngleY = 0.0F; - - - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - - - // if yeti is angry, hold arms forwards like a zombie - if (yeti.isAngry()) - { - float f6 = MathHelper.sin(this.onGround * (float)Math.PI); - float f7 = MathHelper.sin((1.0F - (1.0F - this.onGround) * (1.0F - this.onGround)) * (float)Math.PI); - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightArm.rotateAngleY = -(0.1F - f6 * 0.6F); - this.bipedLeftArm.rotateAngleY = 0.1F - f6 * 0.6F; - this.bipedRightArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedLeftArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedRightArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; - this.bipedLeftArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - } - } - - /** - * Change eye color if yeti is angry - */ - @Override - public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) { - EntityTFYeti yeti = (EntityTFYeti)par1EntityLivingBase; - - if (yeti.isAngry()) { - this.rightEye.isHidden = true; - this.leftEye.isHidden = true; - this.angryRightEye.isHidden = false; - this.angryLeftEye.isHidden = false; - } else { - this.rightEye.isHidden = false; - this.leftEye.isHidden = false; - this.angryRightEye.isHidden = true; - this.angryLeftEye.isHidden = true; - } - } - - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFYetiAlpha.java b/src/main/java/twilightforest/client/model/ModelTFYetiAlpha.java deleted file mode 100644 index cad170e6d2..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFYetiAlpha.java +++ /dev/null @@ -1,223 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import twilightforest.entity.boss.EntityTFYetiAlpha; - -public class ModelTFYetiAlpha extends ModelBiped { - - public ModelRenderer mouth; - public ModelRenderer leftEye; - public ModelRenderer rightEye; - - - - public ModelTFYetiAlpha() - { - super(); - - this.textureWidth = 256; - this.textureHeight = 128; - - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); - - this.bipedHeadwear = new ModelRenderer(this, 32, 0); - this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); - - this.bipedBody = new ModelRenderer(this, 80, 0); - this.bipedBody.addBox(-24.0F, -60.0F, -18.0F, 48, 72, 36); - this.bipedBody.setRotationPoint(0.0F, -6.0F, 0.0F); - - this.mouth = new ModelRenderer(this, 121, 50); - this.mouth.addBox(-17.0F, -7.0F, -1.5F, 34, 29, 2); - this.mouth.setRotationPoint(0.0F, -37.0F, -18.0F); - this.bipedBody.addChild(mouth); - - this.rightEye = new ModelRenderer(this, 64, 0); - this.rightEye.addBox(-6.0F, -6.0F, -1.5F, 12, 12, 2); - this.rightEye.setRotationPoint(-14.0F, -50.0F, -18.0F); - this.bipedBody.addChild(rightEye); - - this.leftEye = new ModelRenderer(this, 64, 0); - this.leftEye.addBox(-6.0F, -6.0F, -1.5F, 12, 12, 2); - this.leftEye.setRotationPoint(14.0F, -50.0F, -18.0F); - this.bipedBody.addChild(leftEye); - - this.bipedRightArm = new ModelRenderer(this, 0, 0); - this.bipedRightArm.addBox(-15.0F, -6.0F, -8.0F, 16, 48, 16); - this.bipedRightArm.setRotationPoint(-25.0F, -26.0F, 0.0F); - - this.bipedBody.addChild(this.bipedRightArm); - - this.bipedLeftArm = new ModelRenderer(this, 0, 0); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(-1.0F, -6.0F, -8.0F, 16, 48, 16); - this.bipedLeftArm.setRotationPoint(25.0F, -26.0F, 0.0F); - - this.bipedBody.addChild(this.bipedLeftArm); - - - this.bipedRightLeg = new ModelRenderer(this, 0, 66); - this.bipedRightLeg.addBox(-10.0F, 0.0F, -10.0F, 20, 20, 20); - this.bipedRightLeg.setRotationPoint(-13.5F, 4.0F, 0.0F); - - this.bipedLeftLeg = new ModelRenderer(this, 0, 66); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-10.0F, 0.0F, -10.0F, 20, 20, 20); - this.bipedLeftLeg.setRotationPoint(13.5F, 4.0F, 0.0F); - - addPairHorns(-58.0F, 35F); - addPairHorns(-46.0F, 15F); - addPairHorns(-36.0F, -5F); - - - } - - - /** - * Add a pair of horns - */ - private void addPairHorns(float height, float zangle) { - ModelRenderer horn1a; - ModelRenderer horn1b; - - horn1a = new ModelRenderer(this, 0, 108); - horn1a.addBox(-9.0F, -5.0F, -5.0F, 10, 10, 10); - horn1a.setRotationPoint(-24.0F, height, -8.0F); - horn1a.rotateAngleY = -30F / (180F / (float)Math.PI); - horn1a.rotateAngleZ = zangle / (180F / (float)Math.PI); - this.bipedBody.addChild(horn1a); - - horn1b = new ModelRenderer(this, 40, 108); - horn1b.addBox(-14.0F, -4.0F, -4.0F, 18, 8, 8); - horn1b.setRotationPoint(-8.0F, 0.0F, 0.0F); - horn1b.rotateAngleY = -20F / (180F / (float)Math.PI); - horn1b.rotateAngleZ = zangle / (180F / (float)Math.PI); - horn1a.addChild(horn1b); - - ModelRenderer horn2a; - ModelRenderer horn2b; - - horn2a = new ModelRenderer(this, 0, 108); - horn2a.addBox(-1.0F, -5.0F, -5.0F, 10, 10, 10); - horn2a.setRotationPoint(24.0F, height, 0.0F); - horn2a.rotateAngleY = 30F / (180F / (float)Math.PI); - horn2a.rotateAngleZ = -zangle / (180F / (float)Math.PI); - this.bipedBody.addChild(horn2a); - - horn2b = new ModelRenderer(this, 40, 108); - horn2b.addBox(-2.0F, -4.0F, -4.0F, 18, 8, 8); - horn2b.setRotationPoint(8.0F, 0.0F, 0.0F); - horn2b.rotateAngleY = 20F / (180F / (float)Math.PI); - horn2b.rotateAngleZ = -zangle / (180F / (float)Math.PI); - horn2a.addChild(horn2b); - } - - - /** - * Sets the models various rotation angles then renders the model. - */ - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) - { - this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); - - this.bipedBody.render(par7); - this.bipedRightLeg.render(par7); - this.bipedLeftLeg.render(par7); - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) - { - EntityTFYetiAlpha yeti = (EntityTFYetiAlpha)par7Entity; - - - this.bipedHead.rotateAngleY = par4 / (180F / (float)Math.PI); - this.bipedHead.rotateAngleX = par5 / (180F / (float)Math.PI); - - this.bipedBody.rotateAngleX = par5 / (180F / (float)Math.PI); - - - this.bipedRightLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; - this.bipedLeftLeg.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - this.bipedRightLeg.rotateAngleY = 0.0F; - this.bipedLeftLeg.rotateAngleY = 0.0F; - - float f6 = MathHelper.sin(this.onGround * (float)Math.PI); - float f7 = MathHelper.sin((1.0F - (1.0F - this.onGround) * (1.0F - this.onGround)) * (float)Math.PI); - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - this.bipedRightArm.rotateAngleY = -(0.1F - f6 * 0.6F); - this.bipedLeftArm.rotateAngleY = 0.1F - f6 * 0.6F; - this.bipedRightArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedLeftArm.rotateAngleX = -((float)Math.PI / 2F); - this.bipedRightArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; - this.bipedLeftArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; - this.bipedRightArm.rotateAngleZ += MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(par3 * 0.09F) * 0.05F + 0.05F; - this.bipedRightArm.rotateAngleX += MathHelper.sin(par3 * 0.067F) * 0.05F; - this.bipedLeftArm.rotateAngleX -= MathHelper.sin(par3 * 0.067F) * 0.05F; - - this.bipedBody.rotationPointY = -6F; - this.bipedRightLeg.rotationPointY = 4F; - this.bipedLeftLeg.rotationPointY = 4F; - - - if (yeti.isTired()) { - // arms down - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 2.0F * par2 * 0.5F; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - - // legs out - this.bipedRightArm.rotateAngleX += -((float)Math.PI / 5F); - this.bipedLeftArm.rotateAngleX += -((float)Math.PI / 5F); - this.bipedRightLeg.rotateAngleX = -((float)Math.PI * 2F / 5F); - this.bipedLeftLeg.rotateAngleX = -((float)Math.PI * 2F / 5F); - this.bipedRightLeg.rotateAngleY = ((float)Math.PI / 10F); - this.bipedLeftLeg.rotateAngleY = -((float)Math.PI / 10F); - - //body down - this.bipedBody.rotationPointY = 6F; - this.bipedRightLeg.rotationPointY = 12F; - this.bipedLeftLeg.rotationPointY = 12F; - } - - if (yeti.isRampaging()) { - // arms up - this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.66F + (float)Math.PI) * 2.0F * par2 * 0.5F; - this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.66F) * 2.0F * par2 * 0.5F; - -// this.bipedRightArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F) * 1.4F * par2; -// this.bipedLeftArm.rotateAngleX = MathHelper.cos(par1 * 0.6662F + (float)Math.PI) * 1.4F * par2; - - this.bipedRightArm.rotateAngleY += MathHelper.cos(par1 * 0.25F) * 0.5F + 0.5F; - this.bipedLeftArm.rotateAngleY -= MathHelper.cos(par1 * 0.25F) * 0.5F + 0.5F; - - this.bipedRightArm.rotateAngleX += Math.PI * 1.25; - this.bipedLeftArm.rotateAngleX += Math.PI * 1.25; - this.bipedRightArm.rotateAngleZ = 0.0F; - this.bipedLeftArm.rotateAngleZ = 0.0F; - } - - if (par7Entity.riddenByEntity != null) - { - // arms up! - this.bipedRightArm.rotateAngleX += Math.PI; - this.bipedLeftArm.rotateAngleX += Math.PI; - - } - - - } - - -} diff --git a/src/main/java/twilightforest/client/model/ModelTFYetiArmor.java b/src/main/java/twilightforest/client/model/ModelTFYetiArmor.java deleted file mode 100644 index 0d4b3e6591..0000000000 --- a/src/main/java/twilightforest/client/model/ModelTFYetiArmor.java +++ /dev/null @@ -1,202 +0,0 @@ -package twilightforest.client.model; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; - -public class ModelTFYetiArmor extends ModelBiped { - - private ModelRenderer bipedLegBody; - private ModelRenderer rightRuff; - private ModelRenderer leftRuff; - private ModelRenderer rightToe; - private ModelRenderer leftToe; - - - - public ModelTFYetiArmor(int part, float expand) - { - super(expand); - - //bigger head - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(-4.5F, -7.5F, -4.0F, 9, 8, 8, expand); - this.bipedHead.setRotationPoint(0.0F, 0.0F + expand, 0.0F); - - // add horns - addPairHorns(-8.0F, 35F); - addPairHorns(-6.0F, 15F); - addPairHorns(-4.0F, -5F); - - - // change leg texture - this.bipedRightLeg = new ModelRenderer(this, 40, 0); - this.bipedRightLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, expand); - this.bipedRightLeg.setRotationPoint(-1.9F, 12.0F + 0.0F, 0.0F); - - this.bipedLeftLeg = new ModelRenderer(this, 40, 0); - this.bipedLeftLeg.mirror = true; - this.bipedLeftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, expand); - this.bipedLeftLeg.setRotationPoint(1.9F, 12.0F + 0.0F, 0.0F); - - rightRuff = new ModelRenderer(this, 40, 22); - rightRuff.addBox(-2.5F, 0.0F, -2.5F, 5, 2, 5, expand); - rightRuff.setRotationPoint(0.0F, 6.0F, 0.0F); - this.bipedRightLeg.addChild(rightRuff); - - leftRuff = new ModelRenderer(this, 40, 22); - leftRuff.addBox(-2.5F, 0.0F, -2.5F, 5, 2, 5, expand); - leftRuff.setRotationPoint(0.0F, 6.0F, 0.0F); - this.bipedLeftLeg.addChild(leftRuff); - - rightToe = new ModelRenderer(this, 40, 17); - rightToe.addBox(-2.0F, 0.0F, -1.0F, 4, 2, 1, expand); - rightToe.setRotationPoint(0.0F, 10.0F, -2.0F); - this.bipedRightLeg.addChild(rightToe); - - leftToe = new ModelRenderer(this, 40, 17); - leftToe.addBox(-2.0F, 0.0F, -1.0F, 4, 2, 1, expand); - leftToe.setRotationPoint(0.0F, 10.0F, -2.0F); - this.bipedLeftLeg.addChild(leftToe); - - // stuff for chest and legs - this.bipedBody = new ModelRenderer(this, 0, 0); - this.bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 11, 4, expand); - this.bipedBody.setRotationPoint(0.0F, 0.0F + 0.0f, 0.0F); - - this.bipedLegBody = new ModelRenderer(this, 40, 16); - this.bipedLegBody.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, expand); - this.bipedLegBody.setRotationPoint(0.0F, 0.0F + 0.0f, 0.0F); - - this.bipedRightArm = new ModelRenderer(this, 0, 16); - this.bipedRightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 10, 4, expand); - this.bipedRightArm.setRotationPoint(-5.0F, 2.0F + 0.0f, 0.0F); - - this.bipedLeftArm = new ModelRenderer(this, 0, 16); - this.bipedLeftArm.mirror = true; - this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 10, 4, expand); - this.bipedLeftArm.setRotationPoint(5.0F, 2.0F + 0.0f, 0.0F); - - - switch (part) - { - case 0: // helmet - this.bipedHead.showModel = true; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedLegBody.showModel = false; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 1: // chest - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = true; - this.bipedRightArm.showModel = true; - this.bipedLeftArm.showModel = true; - this.bipedLegBody.showModel = false; - this.bipedRightLeg.showModel = false; - this.bipedLeftLeg.showModel = false; - break; - case 2: // pants - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedLegBody.showModel = true; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - this.leftRuff.showModel = false; - this.leftToe.showModel = false; - this.rightRuff.showModel = false; - this.rightToe.showModel = false; - break; - case 3: // boots - this.bipedHead.showModel = false; - this.bipedHeadwear.showModel = false; - this.bipedBody.showModel = false; - this.bipedRightArm.showModel = false; - this.bipedLeftArm.showModel = false; - this.bipedLegBody.showModel = false; - this.bipedRightLeg.showModel = true; - this.bipedLeftLeg.showModel = true; - this.leftRuff.showModel = true; - this.leftToe.showModel = true; - this.rightRuff.showModel = true; - this.rightToe.showModel = true; - break; - - } - } - - /** - * Add a pair of horns - */ - private void addPairHorns(float height, float zangle) { - ModelRenderer horn1a; - ModelRenderer horn1b; - - horn1a = new ModelRenderer(this, 0, 19); - horn1a.addBox(-3.0F, -1.5F, -1.5F, 3, 3, 3); - horn1a.setRotationPoint(-4.5F, height, -1.0F); - horn1a.rotateAngleY = -30F / (180F / (float)Math.PI); - horn1a.rotateAngleZ = zangle / (180F / (float)Math.PI); - this.bipedHead.addChild(horn1a); - - horn1b = new ModelRenderer(this, 0, 26); - horn1b.addBox(-4.0F, -1.0F, -1.0F, 5, 2, 2); - horn1b.setRotationPoint(-3.0F, 0.0F, 0.0F); - horn1b.rotateAngleY = -20F / (180F / (float)Math.PI); - horn1b.rotateAngleZ = zangle / (180F / (float)Math.PI); - horn1a.addChild(horn1b); - - ModelRenderer horn2a; - ModelRenderer horn2b; - - horn2a = new ModelRenderer(this, 0, 19); - horn2a.addBox(0.0F, -1.5F, -1.5F, 3, 3, 3); - horn2a.setRotationPoint(4.5F, height, -1.0F); - horn2a.rotateAngleY = 30F / (180F / (float)Math.PI); - horn2a.rotateAngleZ = -zangle / (180F / (float)Math.PI); - this.bipedHead.addChild(horn2a); - - horn2b = new ModelRenderer(this, 0, 26); - horn2b.addBox(-1.0F, -1.0F, -1.0F, 5, 2, 2); - horn2b.setRotationPoint(3.0F, 0.0F, 0.0F); - horn2b.rotateAngleY = 20F / (180F / (float)Math.PI); - horn2b.rotateAngleZ = -zangle / (180F / (float)Math.PI); - horn2a.addChild(horn2b); - } - - - /** - * Sets the models various rotation angles then renders the model. - */ - @Override - public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) { - - if (par1Entity != null) - { - this.isSneak = par1Entity.isSneaking(); - } - - if (par1Entity != null && par1Entity instanceof EntityLivingBase) - { - this.heldItemRight = ((EntityLivingBase)par1Entity).getHeldItem() != null ? 1 : 0; - - //System.out.println("Held right = " + ((EntityLivingBase)par1Entity).getHeldItem()); - } else { - //System.out.println("Entity = " + par1Entity); - } - - super.render(par1Entity, par2, par3, par4, par5, par6, par7); - - this.bipedLegBody.render(par7); - } - - -} diff --git a/src/main/java/twilightforest/client/model/armor/ModelTFArcticArmor.java b/src/main/java/twilightforest/client/model/armor/ModelTFArcticArmor.java new file mode 100644 index 0000000000..8bf6f6f8d3 --- /dev/null +++ b/src/main/java/twilightforest/client/model/armor/ModelTFArcticArmor.java @@ -0,0 +1,30 @@ +package twilightforest.client.model.armor; + +import net.minecraft.client.model.ModelRenderer; + +public class ModelTFArcticArmor extends ModelTFArmor { + + public ModelTFArcticArmor(float expand) { + super(expand); + + ModelRenderer rightHood = new ModelRenderer(this, 0, 0); + rightHood.addBox(-1.0F, -2.0F, -1.0F, 1, 4, 1, expand); + rightHood.setRotationPoint(-2.5F, -3.0F, -5.0F); + this.bipedHead.addChild(rightHood); + + ModelRenderer leftHood = new ModelRenderer(this, 0, 0); + leftHood.addBox(0.0F, -2.0F, -1.0F, 1, 4, 1, expand); + leftHood.setRotationPoint(2.5F, -3.0F, -5.0F); + this.bipedHead.addChild(leftHood); + + ModelRenderer topHood = new ModelRenderer(this, 24, 0); + topHood.addBox(-2.0F, -1.0F, -1.0F, 4, 1, 1, expand); + topHood.setRotationPoint(0.0F, -5.5F, -5.0F); + this.bipedHead.addChild(topHood); + + ModelRenderer bottomHood = new ModelRenderer(this, 24, 0); + bottomHood.addBox(-2.0F, -1.0F, -1.0F, 4, 1, 1, expand); + bottomHood.setRotationPoint(0.0F, 0.5F, -5.0F); + this.bipedHead.addChild(bottomHood); + } +} diff --git a/src/main/java/twilightforest/client/model/armor/ModelTFArmor.java b/src/main/java/twilightforest/client/model/armor/ModelTFArmor.java new file mode 100644 index 0000000000..d6af9dbfe2 --- /dev/null +++ b/src/main/java/twilightforest/client/model/armor/ModelTFArmor.java @@ -0,0 +1,45 @@ +package twilightforest.client.model.armor; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityArmorStand; + +public class ModelTFArmor extends ModelBiped { + + public ModelTFArmor(float modelSize) { + super(modelSize, 0.0F, 64, 32); + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn) { + // [VanillaCopy] ModelArmorStandArmor + // this prevents helmets from always facing south, and the armor "breathing" on the stand + if (entityIn instanceof EntityArmorStand) { + EntityArmorStand entityarmorstand = (EntityArmorStand) entityIn; + this.bipedHead.rotateAngleX = 0.017453292F * entityarmorstand.getHeadRotation().getX(); + this.bipedHead.rotateAngleY = 0.017453292F * entityarmorstand.getHeadRotation().getY(); + this.bipedHead.rotateAngleZ = 0.017453292F * entityarmorstand.getHeadRotation().getZ(); + this.bipedHead.setRotationPoint(0.0F, 1.0F, 0.0F); + this.bipedBody.rotateAngleX = 0.017453292F * entityarmorstand.getBodyRotation().getX(); + this.bipedBody.rotateAngleY = 0.017453292F * entityarmorstand.getBodyRotation().getY(); + this.bipedBody.rotateAngleZ = 0.017453292F * entityarmorstand.getBodyRotation().getZ(); + this.bipedLeftArm.rotateAngleX = 0.017453292F * entityarmorstand.getLeftArmRotation().getX(); + this.bipedLeftArm.rotateAngleY = 0.017453292F * entityarmorstand.getLeftArmRotation().getY(); + this.bipedLeftArm.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftArmRotation().getZ(); + this.bipedRightArm.rotateAngleX = 0.017453292F * entityarmorstand.getRightArmRotation().getX(); + this.bipedRightArm.rotateAngleY = 0.017453292F * entityarmorstand.getRightArmRotation().getY(); + this.bipedRightArm.rotateAngleZ = 0.017453292F * entityarmorstand.getRightArmRotation().getZ(); + this.bipedLeftLeg.rotateAngleX = 0.017453292F * entityarmorstand.getLeftLegRotation().getX(); + this.bipedLeftLeg.rotateAngleY = 0.017453292F * entityarmorstand.getLeftLegRotation().getY(); + this.bipedLeftLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftLegRotation().getZ(); + this.bipedLeftLeg.setRotationPoint(1.9F, 11.0F, 0.0F); + this.bipedRightLeg.rotateAngleX = 0.017453292F * entityarmorstand.getRightLegRotation().getX(); + this.bipedRightLeg.rotateAngleY = 0.017453292F * entityarmorstand.getRightLegRotation().getY(); + this.bipedRightLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getRightLegRotation().getZ(); + this.bipedRightLeg.setRotationPoint(-1.9F, 11.0F, 0.0F); + copyModelAngles(this.bipedHead, this.bipedHeadwear); + } else super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entityIn); + // TF - Defer to super otherwise + } + +} diff --git a/src/main/java/twilightforest/client/model/armor/ModelTFFieryArmor.java b/src/main/java/twilightforest/client/model/armor/ModelTFFieryArmor.java new file mode 100644 index 0000000000..8f8471856e --- /dev/null +++ b/src/main/java/twilightforest/client/model/armor/ModelTFFieryArmor.java @@ -0,0 +1,26 @@ +package twilightforest.client.model.armor; + +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.Entity; +import org.lwjgl.opengl.GL11; + +public class ModelTFFieryArmor extends ModelTFArmor { + + public ModelTFFieryArmor(float expand) { + super(expand); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + // FULL BRIGHT + float prevX = OpenGlHelper.lastBrightnessX, prevY = OpenGlHelper.lastBrightnessY; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(1f, 1f, 1f, 1f)); + + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + + GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(0f, 0f, 0f, 1f)); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, prevX, prevY); + } +} diff --git a/src/main/java/twilightforest/client/model/armor/ModelTFKnightlyArmor.java b/src/main/java/twilightforest/client/model/armor/ModelTFKnightlyArmor.java new file mode 100644 index 0000000000..87c080589d --- /dev/null +++ b/src/main/java/twilightforest/client/model/armor/ModelTFKnightlyArmor.java @@ -0,0 +1,83 @@ +package twilightforest.client.model.armor; + +import net.minecraft.client.model.ModelRenderer; + +public class ModelTFKnightlyArmor extends ModelTFArmor { + + public ModelRenderer righthorn1; + public ModelRenderer righthorn2; + public ModelRenderer lefthorn1; + public ModelRenderer lefthorn2; + + public ModelRenderer shoulderSpike1; + public ModelRenderer shoulderSpike2; + + public ModelRenderer shoeSpike1; + public ModelRenderer shoeSpike2; + + + public ModelTFKnightlyArmor(float expand) { + super(expand); + + this.righthorn1 = new ModelRenderer(this, 24, 0); + this.righthorn1.addBox(-5.5F, -1.5F, -1.5F, 5, 3, 3); + this.righthorn1.setRotationPoint(-4.0F, -6.5F, 0.0F); + this.righthorn1.rotateAngleY = -15F / (180F / (float) Math.PI); + this.righthorn1.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn2 = new ModelRenderer(this, 54, 16); + this.righthorn2.addBox(-3.5F, -1.0F, -1.0F, 3, 2, 2); + this.righthorn2.setRotationPoint(-4.5F, 0.0F, 0.0F); + this.righthorn2.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.bipedHead.addChild(righthorn1); + this.righthorn1.addChild(righthorn2); + + this.lefthorn1 = new ModelRenderer(this, 24, 0); + this.lefthorn1.mirror = true; + this.lefthorn1.addBox(0.5F, -1.5F, -1.5F, 5, 3, 3); + this.lefthorn1.setRotationPoint(4.0F, -6.5F, 0.0F); + this.lefthorn1.rotateAngleY = 15F / (180F / (float) Math.PI); + this.lefthorn1.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn2 = new ModelRenderer(this, 54, 16); + this.lefthorn2.addBox(0.5F, -1.0F, -1.0F, 3, 2, 2); + this.lefthorn2.setRotationPoint(4.5F, 0.0F, 0.0F); + this.lefthorn2.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.bipedHead.addChild(lefthorn1); + this.lefthorn1.addChild(lefthorn2); + + this.shoulderSpike1 = new ModelRenderer(this, 0, 0); + this.shoulderSpike1.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); + this.shoulderSpike1.setRotationPoint(-3.75F, -2.5F, 0.0F); + this.shoulderSpike1.rotateAngleX = 45F / (180F / (float) Math.PI); + this.shoulderSpike1.rotateAngleY = 10F / (180F / (float) Math.PI); + this.shoulderSpike1.rotateAngleZ = 35F / (180F / (float) Math.PI); + + this.bipedRightArm.addChild(shoulderSpike1); + + this.shoulderSpike2 = new ModelRenderer(this, 0, 0); + this.shoulderSpike2.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); + this.shoulderSpike2.setRotationPoint(3.75F, -2.5F, 0.0F); + this.shoulderSpike2.rotateAngleX = -45F / (180F / (float) Math.PI); + this.shoulderSpike2.rotateAngleY = -10F / (180F / (float) Math.PI); + this.shoulderSpike2.rotateAngleZ = 55F / (180F / (float) Math.PI); + + this.bipedLeftArm.addChild(shoulderSpike2); + + this.shoeSpike1 = new ModelRenderer(this, 0, 0); + this.shoeSpike1.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); + this.shoeSpike1.setRotationPoint(-2.5F, 11F, 2.0F); + this.shoeSpike1.rotateAngleY = -45F / (180F / (float) Math.PI); + + this.bipedRightLeg.addChild(shoeSpike1); + + this.shoeSpike2 = new ModelRenderer(this, 0, 0); + this.shoeSpike2.addBox(-1.0F, -1.0F, -1.0F, 2, 2, 2, 0.5F); + this.shoeSpike2.setRotationPoint(2.5F, 11F, 2.0F); + this.shoeSpike2.rotateAngleY = 45F / (180F / (float) Math.PI); + + this.bipedLeftLeg.addChild(shoeSpike2); + } +} diff --git a/src/main/java/twilightforest/client/model/armor/ModelTFPhantomArmor.java b/src/main/java/twilightforest/client/model/armor/ModelTFPhantomArmor.java new file mode 100644 index 0000000000..8fa78b5dc5 --- /dev/null +++ b/src/main/java/twilightforest/client/model/armor/ModelTFPhantomArmor.java @@ -0,0 +1,25 @@ +package twilightforest.client.model.armor; + + +import net.minecraft.inventory.EntityEquipmentSlot; +import twilightforest.client.model.armor.ModelTFKnightlyArmor; + +public class ModelTFPhantomArmor extends ModelTFKnightlyArmor { + + public ModelTFPhantomArmor(EntityEquipmentSlot part, float expand) { + super(expand); + + this.righthorn1.rotateAngleY = -25F / (180F / (float) Math.PI); + this.righthorn1.rotateAngleZ = 45F / (180F / (float) Math.PI); + + this.righthorn2.rotateAngleY = -15F / (180F / (float) Math.PI); + this.righthorn2.rotateAngleZ = 45F / (180F / (float) Math.PI); + + this.lefthorn1.rotateAngleY = 25F / (180F / (float) Math.PI); + this.lefthorn1.rotateAngleZ = -45F / (180F / (float) Math.PI); + + this.lefthorn2.rotateAngleY = 15F / (180F / (float) Math.PI); + this.lefthorn2.rotateAngleZ = -45F / (180F / (float) Math.PI); + } + +} diff --git a/src/main/java/twilightforest/client/model/armor/ModelTFYetiArmor.java b/src/main/java/twilightforest/client/model/armor/ModelTFYetiArmor.java new file mode 100644 index 0000000000..ee719bbec3 --- /dev/null +++ b/src/main/java/twilightforest/client/model/armor/ModelTFYetiArmor.java @@ -0,0 +1,181 @@ +package twilightforest.client.model.armor; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.inventory.EntityEquipmentSlot; + +public class ModelTFYetiArmor extends ModelTFArmor { + + private final EntityEquipmentSlot slot; + + private ModelRenderer bipedLegBody; + private ModelRenderer rightRuff; + private ModelRenderer leftRuff; + private ModelRenderer rightToe; + private ModelRenderer leftToe; + + public ModelTFYetiArmor(EntityEquipmentSlot slot, float expand) { + super(expand); + this.slot = slot; + + //bigger head + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.5F, -7.5F, -4.0F, 9, 8, 8, expand); + this.bipedHead.setRotationPoint(0.0F, 0.0F + expand, 0.0F); + + // add horns + addPairHorns(-8.0F, 35F); + addPairHorns(-6.0F, 15F); + addPairHorns(-4.0F, -5F); + + + // change leg texture + this.bipedRightLeg = new ModelRenderer(this, 40, 0); + this.bipedRightLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, expand); + this.bipedRightLeg.setRotationPoint(-1.9F, 12.0F + 0.0F, 0.0F); + + this.bipedLeftLeg = new ModelRenderer(this, 40, 0); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, expand); + this.bipedLeftLeg.setRotationPoint(1.9F, 12.0F + 0.0F, 0.0F); + + this.rightRuff = new ModelRenderer(this, 40, 22); + this.rightRuff.addBox(-2.5F, 0.0F, -2.5F, 5, 2, 5, expand); + this.rightRuff.setRotationPoint(0.0F, 6.0F, 0.0F); + this.bipedRightLeg.addChild(rightRuff); + + this.leftRuff = new ModelRenderer(this, 40, 22); + this.leftRuff.addBox(-2.5F, 0.0F, -2.5F, 5, 2, 5, expand); + this.leftRuff.setRotationPoint(0.0F, 6.0F, 0.0F); + this.bipedLeftLeg.addChild(leftRuff); + + this.rightToe = new ModelRenderer(this, 40, 17); + this.rightToe.addBox(-2.0F, 0.0F, -1.0F, 4, 2, 1, expand); + this.rightToe.setRotationPoint(0.0F, 10.0F, -2.0F); + this.bipedRightLeg.addChild(rightToe); + + this.leftToe = new ModelRenderer(this, 40, 17); + this.leftToe.addBox(-2.0F, 0.0F, -1.0F, 4, 2, 1, expand); + this.leftToe.setRotationPoint(0.0F, 10.0F, -2.0F); + this.bipedLeftLeg.addChild(leftToe); + + // stuff for chest and legs + this.bipedBody = new ModelRenderer(this, 0, 0); + this.bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 11, 4, expand); + this.bipedBody.setRotationPoint(0.0F, 0.0F + 0.0f, 0.0F); + + this.bipedLegBody = new ModelRenderer(this, 40, 16); + this.bipedLegBody.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, expand); + this.bipedLegBody.setRotationPoint(0.0F, 0.0F + 0.0f, 0.0F); + + this.bipedRightArm = new ModelRenderer(this, 0, 16); + this.bipedRightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 10, 4, expand); + this.bipedRightArm.setRotationPoint(-5.0F, 2.0F + 0.0f, 0.0F); + + this.bipedLeftArm = new ModelRenderer(this, 0, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 10, 4, expand); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F + 0.0f, 0.0F); + + } + + private void addPairHorns(float height, float zangle) { + ModelRenderer horn1a; + ModelRenderer horn1b; + + horn1a = new ModelRenderer(this, 0, 19); + horn1a.addBox(-3.0F, -1.5F, -1.5F, 3, 3, 3); + horn1a.setRotationPoint(-4.5F, height, -1.0F); + horn1a.rotateAngleY = -30F / (180F / (float) Math.PI); + horn1a.rotateAngleZ = zangle / (180F / (float) Math.PI); + this.bipedHead.addChild(horn1a); + + horn1b = new ModelRenderer(this, 0, 26); + horn1b.addBox(-4.0F, -1.0F, -1.0F, 5, 2, 2); + horn1b.setRotationPoint(-3.0F, 0.0F, 0.0F); + horn1b.rotateAngleY = -20F / (180F / (float) Math.PI); + horn1b.rotateAngleZ = zangle / (180F / (float) Math.PI); + horn1a.addChild(horn1b); + + ModelRenderer horn2a; + ModelRenderer horn2b; + + horn2a = new ModelRenderer(this, 0, 19); + horn2a.addBox(0.0F, -1.5F, -1.5F, 3, 3, 3); + horn2a.setRotationPoint(4.5F, height, -1.0F); + horn2a.rotateAngleY = 30F / (180F / (float) Math.PI); + horn2a.rotateAngleZ = -zangle / (180F / (float) Math.PI); + this.bipedHead.addChild(horn2a); + + horn2b = new ModelRenderer(this, 0, 26); + horn2b.addBox(-1.0F, -1.0F, -1.0F, 5, 2, 2); + horn2b.setRotationPoint(3.0F, 0.0F, 0.0F); + horn2b.rotateAngleY = 20F / (180F / (float) Math.PI); + horn2b.rotateAngleZ = -zangle / (180F / (float) Math.PI); + horn2a.addChild(horn2b); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + bipedLegBody.showModel = visible; + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + switch (slot) { + case HEAD: + this.bipedHead.showModel = true; + this.bipedHeadwear.showModel = false; + this.bipedBody.showModel = false; + this.bipedRightArm.showModel = false; + this.bipedLeftArm.showModel = false; + this.bipedLegBody.showModel = false; + this.bipedRightLeg.showModel = false; + this.bipedLeftLeg.showModel = false; + break; + case CHEST: + this.bipedHead.showModel = false; + this.bipedHeadwear.showModel = false; + this.bipedBody.showModel = true; + this.bipedRightArm.showModel = true; + this.bipedLeftArm.showModel = true; + this.bipedLegBody.showModel = false; + this.bipedRightLeg.showModel = false; + this.bipedLeftLeg.showModel = false; + break; + case LEGS: + this.bipedHead.showModel = false; + this.bipedHeadwear.showModel = false; + this.bipedBody.showModel = false; + this.bipedRightArm.showModel = false; + this.bipedLeftArm.showModel = false; + this.bipedLegBody.showModel = true; + this.bipedRightLeg.showModel = true; + this.bipedLeftLeg.showModel = true; + this.leftRuff.showModel = false; + this.leftToe.showModel = false; + this.rightRuff.showModel = false; + this.rightToe.showModel = false; + break; + case FEET: + this.bipedHead.showModel = false; + this.bipedHeadwear.showModel = false; + this.bipedBody.showModel = false; + this.bipedRightArm.showModel = false; + this.bipedLeftArm.showModel = false; + this.bipedLegBody.showModel = false; + this.bipedRightLeg.showModel = true; + this.bipedLeftLeg.showModel = true; + this.leftRuff.showModel = true; + this.leftToe.showModel = true; + this.rightRuff.showModel = true; + this.rightToe.showModel = true; + break; + default: + break; + } + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + this.bipedLegBody.render(scale); + } +} diff --git a/src/main/java/twilightforest/client/model/baked/BakedMossModel.java b/src/main/java/twilightforest/client/model/baked/BakedMossModel.java new file mode 100644 index 0000000000..e799f14d3c --- /dev/null +++ b/src/main/java/twilightforest/client/model/baked/BakedMossModel.java @@ -0,0 +1,107 @@ +package twilightforest.client.model.baked; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.*; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.EnumFacing; +import org.lwjgl.util.vector.Vector3f; +import twilightforest.TwilightForestMod; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +public class BakedMossModel implements IBakedModel { + private static final FaceBakery bakery = new FaceBakery(); + private static final String spriteString = TwilightForestMod.ID + ":blocks/mosspatch"; + private static final TextureAtlasSprite mossTex = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(spriteString); + + @Override + public List getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) { + List quads = new ArrayList<>(); + + List ups = new ArrayList<>(); + List norths = new ArrayList<>(); + List souths = new ArrayList<>(); + List wests = new ArrayList<>(); + List easts = new ArrayList<>(); + + int xMin = (int) (rand & 0b11L) + 1; + int xMax = (int) (rand >> 2 & 0b11L) + 1; + int zMin = (int) (rand >> 4 & 0b11L) + 1; + int zMax = (int) (rand >> 6 & 0b11L) + 1; + + //UnpackedBakedQuad.Builder mainTop = new UnpackedBakedQuad.Builder(DefaultVertexFormats.ITEM); + //mainTop.setQuadOrientation(EnumFacing.UP); + //mainTop.setTexture(mossTex); + + // Main piece + BakedQuad mainUp = makeMossQuad(8 - xMin, 8 - zMin, 8 + xMax, 8 + zMax, EnumFacing.UP , quads, ups ); + BakedQuad mainNorth = makeMossQuad(8 - xMin, 8 - zMin, 8 + xMax, 8 + zMax, EnumFacing.NORTH, quads, norths); + BakedQuad mainSouth = makeMossQuad(8 - xMin, 8 - zMin, 8 + xMax, 8 + zMax, EnumFacing.SOUTH, quads, souths); + BakedQuad mainWest = makeMossQuad(8 - xMin, 8 - zMin, 8 + xMax, 8 + zMax, EnumFacing.WEST , quads, wests ); + BakedQuad mainEast = makeMossQuad(8 - xMin, 8 - zMin, 8 + xMax, 8 + zMax, EnumFacing.EAST , quads, easts ); + + int num4 = (int) (rand >> 7 & 0b1L); + int num5 = (int) (rand >> 9 & 0b11L) + 1; + int num6 = (int) (rand >> 11 & 0b11L) + 1; + + int num7 = (int) (rand >> 12 & 0b1L); + int num8 = (int) (rand >> 14 & 0b11L) + 1; + int num9 = (int) (rand >> 16 & 0b11L) + 1; + + int num10 = (int) (rand >> 17 & 0b1L); + int num11 = (int) (rand >> 19 & 0b11L) + 1; + int num12 = (int) (rand >> 21 & 0b11L) + 1; + + int num13 = (int) (rand >> 22 & 0b1L); + int num14 = (int) (rand >> 24 & 0b11L) + 1; + int num15 = (int) (rand >> 26 & 0b11L) + 1; + + return null; + } + + private static BakedQuad makeMossQuad(int xMin, int zMin, int xMax, int zMax, EnumFacing facing, List generalQuads, List faceQuads) { + BakedQuad toReturn = bakery.makeBakedQuad( + new Vector3f(xMin, 0.0f, zMin), + new Vector3f(xMax, 1.0f, zMax), + new BlockPartFace(null, -1, spriteString, new BlockFaceUV(new float[]{ 8 - xMin, 8 - zMin, 8 + xMax, 8 + zMax }, 0)), + mossTex, + facing, + ModelRotation.X0_Y0, + null, + true, + false); + + generalQuads.add(toReturn); + faceQuads.add(toReturn); + + return toReturn; + } + + @Override + public boolean isAmbientOcclusion() { + return false; + } + + @Override + public boolean isGui3d() { + return false; + } + + @Override + public boolean isBuiltInRenderer() { + return false; + } + + @Override + public TextureAtlasSprite getParticleTexture() { + return null; + } + + @Override + public ItemOverrideList getOverrides() { + return null; + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFAdherent.java b/src/main/java/twilightforest/client/model/entity/ModelTFAdherent.java new file mode 100644 index 0000000000..e3a3913f4b --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFAdherent.java @@ -0,0 +1,88 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; + +public class ModelTFAdherent extends ModelBiped { + + ModelRenderer leftSleeve; + ModelRenderer rightSleeve; + + public ModelTFAdherent() { + + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + this.bipedLeftLeg = new ModelRenderer(this, 0, 0); + this.bipedRightLeg = new ModelRenderer(this, 0, 0); + + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8); + this.bipedHead.setRotationPoint(0F, 0F, 0F); + + this.bipedBody = new ModelRenderer(this, 32, 0); + this.bipedBody.addBox(-4F, 0F, -2F, 8, 24, 4); + this.bipedBody.setRotationPoint(0F, 0F, 0F); + + this.bipedRightArm = new ModelRenderer(this, 0, 16); + this.bipedRightArm.addBox(-3F, -2F, -2F, 4, 12, 4); + this.bipedRightArm.setRotationPoint(-5F, 2F, 0F); + + this.bipedLeftArm = new ModelRenderer(this, 0, 16); + this.bipedLeftArm.addBox(-1F, -2F, -2F, 4, 12, 4); + this.bipedLeftArm.setRotationPoint(5F, 2F, 0F); + + this.leftSleeve = new ModelRenderer(this, 16, 16); + this.leftSleeve.addBox(-1F, -2F, 2F, 4, 12, 4); + this.leftSleeve.setRotationPoint(0F, 0F, 0F); + + this.bipedLeftArm.addChild(this.leftSleeve); + + this.rightSleeve = new ModelRenderer(this, 16, 16); + this.rightSleeve.addBox(-3F, -2F, 2F, 4, 12, 4); + this.rightSleeve.setRotationPoint(0F, 0F, 0F); + + this.bipedRightArm.addChild(this.rightSleeve); + + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + //super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + // rotate head normally + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + + // wave arms more + this.bipedRightArm.rotateAngleX = 0.0F;//MathHelper.cos(limbSwing * 0.6662F + (float)Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = 0.0F;//MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + + + this.bipedRightArm.rotateAngleZ += MathHelper.cos((ageInTicks + 10F) * 0.133F) * 0.3F + 0.3F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos((ageInTicks + 10F) * 0.133F) * 0.3F + 0.3F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + float bounce = entity.ticksExisted + partialTicks; + + // this is where we add the floating + GlStateManager.translate(0F, -0.125F - MathHelper.sin((bounce) * 0.133F) * 0.1F, 0F); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFApocalypseCube.java b/src/main/java/twilightforest/client/model/entity/ModelTFApocalypseCube.java new file mode 100644 index 0000000000..49aab59f73 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFApocalypseCube.java @@ -0,0 +1,57 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelQuadruped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + +public class ModelTFApocalypseCube extends ModelQuadruped { + + public ModelTFApocalypseCube() { + this(0.0F); + } + + public ModelTFApocalypseCube(float fNumber) { + super(6, fNumber); + + this.textureWidth = 128; + this.textureHeight = 64; + + this.head = new ModelRenderer(this, 0, 0); + + body = new ModelRenderer(this, 0, 0); + body.addBox(-16F, -16F, -16F, 32, 32, 32); + body.setRotationPoint(0F, 0F, -2F); + + leg1 = new ModelRenderer(this, 0, 0); + leg1.addBox(-4F, 0F, -4F, 8, 8, 8); + leg1.setRotationPoint(-6F, 16F, 9F); + + leg2 = new ModelRenderer(this, 0, 0); + leg2.addBox(-4F, 0F, -4F, 8, 8, 8); + leg2.setRotationPoint(6F, 16F, 9F); + + leg3 = new ModelRenderer(this, 0, 0); + leg3.addBox(-4F, 0F, -4F, 8, 8, 8); + leg3.setRotationPoint(-9F, 16F, -14F); + + leg4 = new ModelRenderer(this, 0, 0); + leg4.addBox(-4F, 0F, -4F, 8, 8, 8); + leg4.setRotationPoint(9F, 16F, -14F); + + + this.childYOffset = 4.0F; + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + this.body.rotateAngleX = 0F; + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFBighorn.java b/src/main/java/twilightforest/client/model/entity/ModelTFBighorn.java new file mode 100644 index 0000000000..768223c62a --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFBighorn.java @@ -0,0 +1,50 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.model.ModelSheep1; + + +public class ModelTFBighorn extends ModelSheep1 { + + public ModelTFBighorn() { + super(); + head = new ModelRenderer(this, 0, 0); + head.addBox(-3F, -4F, -6F, 6, 6, 7, 0F); + head.setRotationPoint(0F, 6F, -8F); + + body = new ModelRenderer(this, 36, 10); + body.addBox(-4F, -9F, -7F, 8, 15, 6, 0F); + body.setRotationPoint(0F, 5F, 2F); + + leg1 = new ModelRenderer(this, 0, 16); + leg1.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); + leg1.setRotationPoint(-3F, 12F, 7F); + + leg2 = new ModelRenderer(this, 0, 16); + leg2.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); + leg2.setRotationPoint(3F, 12F, 7F); + + leg3 = new ModelRenderer(this, 0, 16); + leg3.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); + leg3.setRotationPoint(-3F, 12F, -5F); + + leg4 = new ModelRenderer(this, 0, 16); + leg4.addBox(-2F, 0.0F, -2F, 4, 12, 4, 0F); + leg4.setRotationPoint(3F, 12F, -5F); + + // curly horn 1 + head.setTextureOffset(28, 16).addBox(-5F, -4F, -4F, 2, 2, 2, 0F); + head.setTextureOffset(16, 13).addBox(-6F, -5F, -3F, 2, 2, 4, 0F); + head.setTextureOffset(16, 19).addBox(-7F, -4F, 0F, 2, 5, 2, 0F); + head.setTextureOffset(18, 27).addBox(-8F, 0F, -2F, 2, 2, 3, 0F); + head.setTextureOffset(28, 27).addBox(-9F, -1F, -3F, 2, 2, 1, 0F); + + // curly horn 2 + head.setTextureOffset(28, 16).addBox(3F, -4F, -4F, 2, 2, 2, 0F); + head.setTextureOffset(16, 13).addBox(4F, -5F, -3F, 2, 2, 4, 0F); + head.setTextureOffset(16, 19).addBox(5F, -4F, 0F, 2, 5, 2, 0F); + head.setTextureOffset(18, 27).addBox(6F, 0F, -2F, 2, 2, 3, 0F); + head.setTextureOffset(28, 27).addBox(7F, -1F, -3F, 2, 2, 1, 0F); + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFBighornFur.java b/src/main/java/twilightforest/client/model/entity/ModelTFBighornFur.java new file mode 100644 index 0000000000..f94453b682 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFBighornFur.java @@ -0,0 +1,31 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.model.ModelSheep2; + + +public class ModelTFBighornFur extends ModelSheep2 { + + public ModelTFBighornFur() { + super(); + head = new ModelRenderer(this, 0, 0); + head.addBox(-3F, -4F, -4F, 6, 6, 6, 0.6F); + head.setRotationPoint(0.0F, 6F, -8F); + body = new ModelRenderer(this, 28, 8); + body.addBox(-4F, -9F, -7F, 8, 15, 6, 0.5F); + body.setRotationPoint(0.0F, 5F, 2.0F); + float f = 0.4F; + leg1 = new ModelRenderer(this, 0, 16); + leg1.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg1.setRotationPoint(-3F, 12F, 7F); + leg2 = new ModelRenderer(this, 0, 16); + leg2.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg2.setRotationPoint(3F, 12F, 7F); + leg3 = new ModelRenderer(this, 0, 16); + leg3.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg3.setRotationPoint(-3F, 12F, -5F); + leg4 = new ModelRenderer(this, 0, 16); + leg4.addBox(-2F, 0.0F, -2F, 4, 6, 4, f); + leg4.setRotationPoint(3F, 12F, -5F); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFBlockGoblin.java b/src/main/java/twilightforest/client/model/entity/ModelTFBlockGoblin.java new file mode 100644 index 0000000000..3602e5262a --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFBlockGoblin.java @@ -0,0 +1,201 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + + +public class ModelTFBlockGoblin extends ModelBiped { + public ModelRenderer helmet; + + ModelRenderer block; + ModelRenderer[] spikes = new ModelRenderer[27]; + + public ModelTFBlockGoblin() { + bipedHead = new ModelRenderer(this, 0, 0); + bipedHead.addBox(0F, 0F, 0F, 0, 0, 0, 0F); + bipedHead.setRotationPoint(0F, 11F, 0F); + + bipedHeadwear = new ModelRenderer(this, 0, 0); + bipedHeadwear.addBox(0F, 0F, 0F, 0, 0, 0, 0.5F); + bipedHeadwear.setRotationPoint(0F, 11F, 0F); + + this.helmet = new ModelRenderer(this, 24, 0); + this.helmet.addBox(-2.5F, -9.0F, -2.5F, 5, 9, 5); + this.helmet.rotateAngleY = 45F / (180F / (float) Math.PI); + + this.bipedHeadwear.addChild(helmet); + + bipedBody = new ModelRenderer(this, 0, 21); + bipedBody.addBox(-3.5F, 0F, -2F, 7, 7, 4, 0F); + bipedBody.setRotationPoint(0F, 11F, 0F); + + bipedRightArm = new ModelRenderer(this, 52, 0); + bipedRightArm.addBox(-3F, -1F, -2F, 3, 12, 3, 0F); + bipedRightArm.setRotationPoint(-3.5F, 12F, 0F); + + bipedLeftArm = new ModelRenderer(this, 52, 0); + bipedLeftArm.addBox(0F, -1F, -1.5F, 3, 12, 3, 0F); + bipedLeftArm.setRotationPoint(3.5F, 12F, 0F); + + bipedRightLeg = new ModelRenderer(this, 0, 12); + bipedRightLeg.addBox(-1.5F, 0F, -1.5F, 3, 6, 3, 0F); + bipedRightLeg.setRotationPoint(-2F, 18F, 0F); + + bipedLeftLeg = new ModelRenderer(this, 0, 12); + bipedLeftLeg.addBox(-1.5F, 0F, -1.5F, 3, 6, 3, 0F); + bipedLeftLeg.setRotationPoint(2F, 18F, 0F); + + block = new ModelRenderer(this, 32, 16); + block.addBox(-4F, -8F, -4F, 8, 8, 8, 0F); + block.setRotationPoint(6F, 0F, 0F); + + for (int i = 0; i < spikes.length; i++) { + spikes[i] = new ModelRenderer(this, 56, 16); + spikes[i].addBox(-1F, -1F, -1F, 2, 2, 2, 0F); + block.addChild(spikes[i]); + } + + // X + spikes[2].rotationPointX = 4; + spikes[3].rotationPointX = 4; + spikes[4].rotationPointX = 4; + spikes[11].rotationPointX = 4; + spikes[12].rotationPointX = 5; + spikes[13].rotationPointX = 4; + spikes[20].rotationPointX = 4; + spikes[21].rotationPointX = 4; + spikes[22].rotationPointX = 4; + + spikes[6].rotationPointX = -4; + spikes[7].rotationPointX = -4; + spikes[8].rotationPointX = -4; + spikes[15].rotationPointX = -4; + spikes[16].rotationPointX = -5; + spikes[17].rotationPointX = -4; + spikes[24].rotationPointX = -4; + spikes[25].rotationPointX = -4; + spikes[26].rotationPointX = -4; + + // Y + spikes[0].rotationPointY = -9; + spikes[1].rotationPointY = -8; + spikes[2].rotationPointY = -8; + spikes[3].rotationPointY = -8; + spikes[4].rotationPointY = -8; + spikes[5].rotationPointY = -8; + spikes[6].rotationPointY = -8; + spikes[7].rotationPointY = -8; + spikes[8].rotationPointY = -8; + + spikes[9].rotationPointY = -4; // this spike is not really there + spikes[10].rotationPointY = -4; + spikes[11].rotationPointY = -4; + spikes[12].rotationPointY = -4; + spikes[13].rotationPointY = -4; + spikes[14].rotationPointY = -4; + spikes[15].rotationPointY = -4; + spikes[16].rotationPointY = -4; + spikes[17].rotationPointY = -4; + + spikes[18].rotationPointY = 1; + + // Z + spikes[1].rotationPointZ = 4; + spikes[2].rotationPointZ = 4; + spikes[8].rotationPointZ = 4; + spikes[10].rotationPointZ = 4; + spikes[11].rotationPointZ = 5; + spikes[17].rotationPointZ = 4; + spikes[19].rotationPointZ = 4; + spikes[20].rotationPointZ = 4; + spikes[26].rotationPointZ = 4; + + spikes[4].rotationPointZ = -4; + spikes[5].rotationPointZ = -4; + spikes[6].rotationPointZ = -4; + spikes[13].rotationPointZ = -4; + spikes[14].rotationPointZ = -5; + spikes[15].rotationPointZ = -4; + spikes[22].rotationPointZ = -4; + spikes[23].rotationPointZ = -4; + spikes[24].rotationPointZ = -4; + + // rotation + float fourtyFive = (float) (Math.PI / 4F); + + spikes[1].rotateAngleX = fourtyFive; + spikes[5].rotateAngleX = fourtyFive; + spikes[19].rotateAngleX = fourtyFive; + spikes[23].rotateAngleX = fourtyFive; + + spikes[11].rotateAngleY = fourtyFive; + spikes[13].rotateAngleY = fourtyFive; + spikes[15].rotateAngleY = fourtyFive; + spikes[17].rotateAngleY = fourtyFive; + + spikes[3].rotateAngleZ = fourtyFive; + spikes[7].rotateAngleZ = fourtyFive; + spikes[21].rotateAngleZ = fourtyFive; + spikes[25].rotateAngleZ = fourtyFive; + + spikes[2].rotateAngleX = -55F / (180F / (float) Math.PI); + spikes[2].rotateAngleY = fourtyFive; + spikes[24].rotateAngleX = -55F / (180F / (float) Math.PI); + spikes[24].rotateAngleY = fourtyFive; + + spikes[4].rotateAngleX = -35F / (180F / (float) Math.PI); + spikes[4].rotateAngleY = -fourtyFive; + spikes[26].rotateAngleX = -35F / (180F / (float) Math.PI); + spikes[26].rotateAngleY = -fourtyFive; + + spikes[6].rotateAngleY = fourtyFive; + spikes[6].rotateAngleX = -35F / (180F / (float) Math.PI); + spikes[20].rotateAngleY = fourtyFive; + spikes[20].rotateAngleX = -35F / (180F / (float) Math.PI); + + spikes[8].rotateAngleX = -55F / (180F / (float) Math.PI); + spikes[8].rotateAngleY = -fourtyFive; + spikes[22].rotateAngleX = -55F / (180F / (float) Math.PI); + spikes[22].rotateAngleY = -fourtyFive; + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + + //block.render(scale); + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + bipedHead.rotationPointY = 11.0F; + bipedHeadwear.rotationPointY = 11.0F; + bipedBody.rotationPointY = 11F; + + bipedRightLeg.rotationPointY = 18F; + bipedLeftLeg.rotationPointY = 18F; + + bipedRightArm.setRotationPoint(-3.5F, 12F, 0F); + + bipedRightArm.rotateAngleX += Math.PI; + + bipedLeftArm.setRotationPoint(3.5F, 12F, 0F); + + + bipedLeftArm.rotateAngleX += Math.PI; + + float angle = ageInTicks / 4F; + float length = 0;//16F; + + block.rotationPointX = (float) Math.sin(angle) * length; + block.rotationPointZ = (float) -Math.cos(angle) * length; + + + block.rotateAngleY = -angle; + + } +} diff --git a/src/main/java/twilightforest/client/model/ModelTFBoar.java b/src/main/java/twilightforest/client/model/entity/ModelTFBoar.java similarity index 87% rename from src/main/java/twilightforest/client/model/ModelTFBoar.java rename to src/main/java/twilightforest/client/model/entity/ModelTFBoar.java index 150f7d80f1..9eec675c85 100644 --- a/src/main/java/twilightforest/client/model/ModelTFBoar.java +++ b/src/main/java/twilightforest/client/model/entity/ModelTFBoar.java @@ -1,46 +1,44 @@ -package twilightforest.client.model; +package twilightforest.client.model.entity; import net.minecraft.client.model.ModelQuadruped; import net.minecraft.client.model.ModelRenderer; -public class ModelTFBoar extends ModelQuadruped -{ - public ModelTFBoar() - { +public class ModelTFBoar extends ModelQuadruped { + public ModelTFBoar() { super(6, 0.0F); - + // head height for baby - field_78145_g = 4F; - + childYOffset = 4F; + head = new ModelRenderer(this, 0, 0); head.addBox(-4F, -2F, -6F, 8, 7, 6, 0F); head.setRotationPoint(0F, 12F, -6F); - + body = new ModelRenderer(this, 28, 10); body.addBox(-5F, -8F, -7F, 10, 14, 8, 0F); body.setRotationPoint(0F, 11F, 2F); - + body.rotateAngleX = 1.570796F; - + leg1 = new ModelRenderer(this, 0, 16); leg1.addBox(-2F, 0F, -2F, 4, 6, 4, 0F); leg1.setRotationPoint(-3F, 18F, 7F); - + leg2 = new ModelRenderer(this, 0, 16); leg2.addBox(-2F, 0F, -2F, 4, 6, 4, 0F); leg2.setRotationPoint(3F, 18F, 7F); - + leg3 = new ModelRenderer(this, 0, 16); leg3.addBox(-2F, 0F, -2F, 4, 6, 4, 0F); leg3.setRotationPoint(-3F, 18F, -5F); - + leg4 = new ModelRenderer(this, 0, 16); leg4.addBox(-2F, 0F, -2F, 4, 6, 4, 0F); leg4.setRotationPoint(3F, 18F, -5F); - + head.setTextureOffset(28, 0).addBox(-3F, 1F, -9F, 6, 4, 3, 0F); // snout - + head.setTextureOffset(17, 17).addBox(3F, 2F, -9F, 1, 2, 1, 0F); // tusk1 head.setTextureOffset(17, 17).addBox(-4F, 2F, -9F, 1, 2, 1, 0F); // tusk2 } diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFBunny.java b/src/main/java/twilightforest/client/model/entity/ModelTFBunny.java new file mode 100644 index 0000000000..0b94ebde85 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFBunny.java @@ -0,0 +1,110 @@ +// Date: 4/28/2012 9:36:32 AM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + + +public class ModelTFBunny extends ModelBase { + //fields + ModelRenderer tail; + ModelRenderer body; + ModelRenderer leg1; + ModelRenderer leg2; + ModelRenderer leg3; + ModelRenderer leg4; + ModelRenderer head; + + public ModelTFBunny() { + textureWidth = 32; + textureHeight = 32; + setTextureOffset("head.head", 0, 0); + setTextureOffset("head.ear2", 16, 0); + setTextureOffset("head.ear1", 16, 0); + + tail = new ModelRenderer(this, 0, 18); + tail.addBox(-1F, -1F, 0F, 2, 2, 2); + tail.setRotationPoint(0F, 20F, 3F); + tail.setTextureSize(32, 32); + tail.mirror = true; + setRotation(tail, 0F, 0F, 0F); + body = new ModelRenderer(this, 0, 8); + body.addBox(-2F, -1F, -2F, 4, 3, 5); + body.setRotationPoint(0F, 21F, 0F); + body.setTextureSize(32, 32); + body.mirror = true; + setRotation(body, 0F, 0F, 0F); + leg1 = new ModelRenderer(this, 0, 16); + leg1.addBox(0F, 0F, 0F, 1, 1, 1); + leg1.setRotationPoint(-2F, 23F, 2F); + leg1.setTextureSize(32, 32); + leg1.mirror = true; + setRotation(leg1, 0F, 0F, 0F); + leg2 = new ModelRenderer(this, 0, 16); + leg2.addBox(0F, 0F, 0F, 1, 1, 1); + leg2.setRotationPoint(1F, 23F, 2F); + leg2.setTextureSize(32, 32); + leg2.mirror = true; + setRotation(leg2, 0F, 0F, 0F); + leg3 = new ModelRenderer(this, 0, 16); + leg3.addBox(0F, 0F, 0F, 1, 1, 1); + leg3.setRotationPoint(-2F, 23F, -2F); + leg3.setTextureSize(32, 32); + leg3.mirror = true; + setRotation(leg3, 0F, 0F, 0F); + leg4 = new ModelRenderer(this, 0, 16); + leg4.addBox(0F, 0F, 0F, 1, 1, 1); + leg4.setRotationPoint(1F, 23F, -2F); + leg4.setTextureSize(32, 32); + leg4.mirror = true; + setRotation(leg4, 0F, 0F, 0F); + head = new ModelRenderer(this, "head"); + head.setRotationPoint(0F, 22F, -1F); + setRotation(head, 0F, 0F, 0F); + head.mirror = true; + head.addBox("head", -2F, -4F, -3F, 4, 4, 4); + head.addBox("ear2", -2.5F, -8F, -0.5F, 2, 4, 1); + head.addBox("ear1", 0.5F, -8F, -0.5F, 2, 4, 1); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + tail.render(scale); + body.render(scale); + leg1.render(scale); + leg2.render(scale); + leg3.render(scale); + leg4.render(scale); + head.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + /** + * Sets the models various rotation angles. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.head.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.leg1.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.leg2.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.leg3.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.leg4.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + + } + +} diff --git a/src/main/java/twilightforest/client/model/ModelTFCicada.java b/src/main/java/twilightforest/client/model/entity/ModelTFCicada.java similarity index 87% rename from src/main/java/twilightforest/client/model/ModelTFCicada.java rename to src/main/java/twilightforest/client/model/entity/ModelTFCicada.java index d2fc2f640b..42b85d6bc5 100644 --- a/src/main/java/twilightforest/client/model/ModelTFCicada.java +++ b/src/main/java/twilightforest/client/model/entity/ModelTFCicada.java @@ -1,41 +1,38 @@ -package twilightforest.client.model; +package twilightforest.client.model.entity; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; -public class ModelTFCicada extends ModelBase -{ - public ModelTFCicada() - { +public class ModelTFCicada extends ModelBase { + public ModelTFCicada() { legs = new ModelRenderer(this, 0, 21); legs.addBox(-4F, 7.9F, -5F, 8, 1, 9, 0F); //legs.setRotationPoint(0F, 16F, 0F); - + fatbody = new ModelRenderer(this, 0, 11); fatbody.addBox(-2F, 6F, -4F, 4, 2, 6, 0F); //fatbody.setRotationPoint(0F, 16F, 0F); - + skinnybody = new ModelRenderer(this, 0, 0); skinnybody.addBox(-1F, 7F, -5F, 2, 1, 8, 0F); //skinnybody.setRotationPoint(0F, 16F, 0F); - - + + eye1 = new ModelRenderer(this, 20, 15); eye1.addBox(1F, 5F, 2F, 2, 2, 2, 0F); //eye1.setRotationPoint(0F, 16F, 0F); - + eye2 = new ModelRenderer(this, 20, 15); eye2.addBox(-3F, 5F, 2F, 2, 2, 2, 0F); //eye2.setRotationPoint(0F, 16F, 0F); - + wings = new ModelRenderer(this, 20, 0); wings.addBox(-4F, 5F, -7F, 8, 1, 8, 0F); //wings.setRotationPoint(0F, 16F, 0F); } - public void render(float f5) - { + public void render(float f5) { // super.render(f, f1, f2, f3, f4, f5); // setRotationAngles(f, f1, f2, f3, f4, f5); legs.render(f5); @@ -44,11 +41,10 @@ public void render(float f5) eye1.render(f5); eye2.render(f5); wings.render(f5); - + } - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) - { + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) { // super.setRotationAngles(f, f1, f2, f3, f4, f5); } @@ -59,5 +55,5 @@ public void setRotationAngles(float f, float f1, float f2, float f3, float f4, f public ModelRenderer eye1; public ModelRenderer eye2; public ModelRenderer wings; - + } diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFCubeOfAnnihilation.java b/src/main/java/twilightforest/client/model/entity/ModelTFCubeOfAnnihilation.java new file mode 100644 index 0000000000..f202bee159 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFCubeOfAnnihilation.java @@ -0,0 +1,55 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + +public class ModelTFCubeOfAnnihilation extends ModelBase { + + public ModelRenderer box; + public ModelRenderer boxX; + public ModelRenderer boxY; + public ModelRenderer boxZ; + + public ModelTFCubeOfAnnihilation() { + textureWidth = 64; + textureHeight = 64; + box = new ModelRenderer(this, 0, 0); + box.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); + box.setRotationPoint(0F, 0F, 0F); + + boxX = new ModelRenderer(this, 0, 32); + boxX.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); + boxX.setRotationPoint(0F, 0F, 0F); + + boxY = new ModelRenderer(this, 0, 32); + boxY.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); + boxY.setRotationPoint(0F, 0F, 0F); + + boxZ = new ModelRenderer(this, 0, 32); + boxZ.addBox(-8F, -8F, -8F, 16, 16, 16, 0F); + boxZ.setRotationPoint(0F, 0F, 0F); + } + + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + box.render(scale); + boxX.render(scale); + boxY.render(scale); + boxZ.render(scale); + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + + boxX.rotateAngleX = (float) Math.sin((entity.ticksExisted + headPitch)) / 5F; + boxY.rotateAngleY = (float) Math.sin((entity.ticksExisted + headPitch)) / 5F; + boxZ.rotateAngleZ = (float) Math.sin((entity.ticksExisted + headPitch)) / 5F; + + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFDeathTome.java b/src/main/java/twilightforest/client/model/entity/ModelTFDeathTome.java new file mode 100644 index 0000000000..fdf6114270 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFDeathTome.java @@ -0,0 +1,101 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBook; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; + +public class ModelTFDeathTome extends ModelBook { + private ModelRenderer everything; + + private ModelRenderer book; + private ModelRenderer loosePage1; + private ModelRenderer loosePage2; + private ModelRenderer loosePage3; + private ModelRenderer loosePage4; + + public ModelTFDeathTome() { + everything = (new ModelRenderer(this)).setTextureOffset(0, 0).addBox(0.0F, 0.0F, 0.0F, 0, 0, 0); + + book = (new ModelRenderer(this)).setTextureOffset(0, 0).addBox(0.0F, 0.0F, 0.0F, 0, 0, 0); + + book.addChild(coverRight); + book.addChild(coverLeft); + book.addChild(bookSpine); + book.addChild(pagesRight); + book.addChild(pagesLeft); + book.addChild(flippingPageRight); + book.addChild(flippingPageLeft); + + loosePage1 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, -8F, 5, 8, 0); + loosePage2 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, 9F, 5, 8, 0); + loosePage3 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, 11F, 5, 8, 0); + loosePage4 = (new ModelRenderer(this)).setTextureOffset(24, 10).addBox(0F, -4F, 7F, 5, 8, 0); + + everything.addChild(book); + everything.addChild(loosePage1); + everything.addChild(loosePage2); + everything.addChild(loosePage3); + everything.addChild(loosePage4); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + GlStateManager.enableCull(); + this.setRotationAngles(entity.ticksExisted, 0.4F, 0.6F, 0.9F, headPitch, 0.0625F, entity); + this.everything.render(scale); + GlStateManager.disableCull(); + + } + + @Override + public void setRotationAngles(float bounce, float flipRight, float flipLeft, float open, float rotate, float scale, Entity entity) { + book.rotateAngleZ = -0.8726646259971647F; + this.everything.rotateAngleY = rotate / (180F / (float) Math.PI) + (float) Math.PI / 2.0F; + } + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + float bounce = entity.ticksExisted + partialTicks; + float open = 0.9f; + float flipRight = 0.4f; + float flipLeft = 0.6f; + + // hoveriness + book.setRotationPoint(0, 4 + MathHelper.sin((bounce) * 0.3F) * 2.0F, 0); + + // book openness + float openAngle = (MathHelper.sin(bounce * 0.4F) * 0.3F + 1.25F) * open; + this.coverRight.rotateAngleY = (float) Math.PI + openAngle; + this.coverLeft.rotateAngleY = -openAngle; + this.pagesRight.rotateAngleY = openAngle; + this.pagesLeft.rotateAngleY = -openAngle; + this.flippingPageRight.rotateAngleY = openAngle - openAngle * 2.0F * flipRight; + this.flippingPageLeft.rotateAngleY = openAngle - openAngle * 2.0F * flipLeft; + this.pagesRight.rotationPointX = MathHelper.sin(openAngle); + this.pagesLeft.rotationPointX = MathHelper.sin(openAngle); + this.flippingPageRight.rotationPointX = MathHelper.sin(openAngle); + this.flippingPageLeft.rotationPointX = MathHelper.sin(openAngle); + + + // page rotations + loosePage1.rotateAngleY = (bounce) / 4.0F; + loosePage1.rotateAngleX = MathHelper.sin((bounce) / 5.0F) / 3.0F; + loosePage1.rotateAngleZ = MathHelper.cos((bounce) / 5.0F) / 5.0F; + + loosePage2.rotateAngleY = (bounce) / 3.0F; + loosePage2.rotateAngleX = MathHelper.sin((bounce) / 5.0F) / 3.0F; + loosePage2.rotateAngleZ = MathHelper.cos((bounce) / 5.0F) / 4.0F + 2; + + loosePage3.rotateAngleY = (bounce) / 4.0F; + loosePage3.rotateAngleX = -MathHelper.sin((bounce) / 5.0F) / 3.0F; + loosePage3.rotateAngleZ = MathHelper.cos((bounce) / 5.0F) / 5.0F - 1.0F; + + loosePage4.rotateAngleY = (bounce) / 4.0F; + loosePage4.rotateAngleX = -MathHelper.sin((bounce) / 2.0F) / 4.0F; + loosePage4.rotateAngleZ = MathHelper.cos((bounce) / 7.0F) / 5.0F; + } +} diff --git a/src/main/java/twilightforest/client/model/ModelTFDeer.java b/src/main/java/twilightforest/client/model/entity/ModelTFDeer.java similarity index 93% rename from src/main/java/twilightforest/client/model/ModelTFDeer.java rename to src/main/java/twilightforest/client/model/entity/ModelTFDeer.java index 4502962762..88de1e9620 100644 --- a/src/main/java/twilightforest/client/model/ModelTFDeer.java +++ b/src/main/java/twilightforest/client/model/entity/ModelTFDeer.java @@ -1,18 +1,16 @@ -package twilightforest.client.model; +package twilightforest.client.model.entity; import net.minecraft.client.model.ModelQuadruped; import net.minecraft.client.model.ModelRenderer; -public class ModelTFDeer extends ModelQuadruped -{ - public ModelTFDeer() - { +public class ModelTFDeer extends ModelQuadruped { + public ModelTFDeer() { super(12, 0.0F); // head height for baby - field_78145_g = 10F; - + childYOffset = 10F; + head = new ModelRenderer(this, 0, 5); head.addBox(-2F, -8F, -6F, 4, 6, 6, 0F); head.setRotationPoint(0F, 4F, -7F); @@ -44,12 +42,12 @@ public ModelTFDeer() // neck.setRotationPoint(1F, 5F, 2F); neck.rotateAngleX = 4.974188f; - + body.addChild(neck); // nose head.setTextureOffset(52, 0).addBox(-1.5F, -5F, -9F, 3, 3, 3, 0F); - + // antler 1 head.setTextureOffset(20, 0); head.addBox(-3F, -10F, -2F, 2, 2, 2, 0F); @@ -64,7 +62,7 @@ public ModelTFDeer() head.addBox(-6F, -16F, -9F, 1, 1, 4, 0F); head.addBox(-7F, -18F, -1F, 1, 5, 1, 0F); head.addBox(-6F, -19F, -6F, 1, 5, 1, 0F); - + // antler 2 head.addBox(1F, -10F, -2F, 2, 2, 2, 0F); head.addBox(3F, -10F, -1F, 1, 1, 3, 0F); diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFFireBeetle.java b/src/main/java/twilightforest/client/model/entity/ModelTFFireBeetle.java new file mode 100644 index 0000000000..b1cfee0f4c --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFFireBeetle.java @@ -0,0 +1,222 @@ +// Date: 11/5/2012 7:35:56 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + +public class ModelTFFireBeetle extends ModelBase { + //fields + ModelRenderer thorax; + ModelRenderer head; + ModelRenderer connector2; + ModelRenderer RearEnd; + ModelRenderer Leg6; + ModelRenderer Leg4; + ModelRenderer Leg2; + ModelRenderer Leg5; + ModelRenderer Leg3; + ModelRenderer Leg1; + ModelRenderer connector1; + ModelRenderer jaw1a; + ModelRenderer jaw1b; + ModelRenderer jaw2a; + ModelRenderer jaw2b; + ModelRenderer antenna1; + ModelRenderer antenna2; + ModelRenderer eye1; + ModelRenderer eye2; + + public ModelTFFireBeetle() { + textureWidth = 64; + textureHeight = 32; + + thorax = new ModelRenderer(this, 0, 22); + thorax.addBox(-4.5F, -4F, 0F, 9, 8, 2); + thorax.setRotationPoint(0F, 18F, -4.5F); + + connector1 = new ModelRenderer(this, 0, 12); + connector1.addBox(-3F, -3F, 0F, 6, 6, 1); + connector1.setRotationPoint(0F, 18F, -3F); + + connector2 = new ModelRenderer(this, 0, 12); + connector2.addBox(-3F, -3F, -1F, 6, 6, 1); + connector2.setRotationPoint(0F, 18F, -4F); + + RearEnd = new ModelRenderer(this, 22, 9); + RearEnd.addBox(-6F, -9F, -4F, 12, 14, 9); + RearEnd.setRotationPoint(0F, 18F, 7F); + setRotation(RearEnd, 1.570796F, 0F, 0F); + + Leg6 = new ModelRenderer(this, 40, 0); + Leg6.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg6.setRotationPoint(4F, 21F, -4F); + setRotation(Leg6, 0F, 0.2792527F, 0.3490659F); + + Leg5 = new ModelRenderer(this, 40, 0); + Leg5.mirror = true; + Leg5.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg5.setRotationPoint(-4F, 21F, -4F); + setRotation(Leg5, 0F, -0.2792527F, -0.3490659F); + + Leg4 = new ModelRenderer(this, 40, 0); + Leg4.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg4.setRotationPoint(4F, 21F, -1F); + setRotation(Leg4, 0F, -0.2792527F, 0.3490659F); + + Leg2 = new ModelRenderer(this, 40, 0); + Leg2.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg2.setRotationPoint(4F, 21F, 4F); + setRotation(Leg2, 0F, -0.6981317F, 0.3490659F); + + Leg3 = new ModelRenderer(this, 40, 0); + Leg3.mirror = true; + Leg3.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg3.setRotationPoint(-4F, 21F, -1F); + setRotation(Leg3, 0F, 0.2792527F, -0.3490659F); + + Leg1 = new ModelRenderer(this, 40, 0); + Leg1.mirror = true; + Leg1.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg1.setRotationPoint(-4F, 21F, 4F); + Leg1.setTextureSize(64, 32); + setRotation(Leg1, 0F, 0.6981317F, -0.3490659F); + + head = new ModelRenderer(this, 0, 0); + head.addBox(-4F, -4F, -6F, 8, 6, 6); + head.setRotationPoint(0F, 19F, -5F); + + jaw1a = new ModelRenderer(this, 0, 0); + jaw1a.addBox(0F, 0F, -2F, 1, 1, 2); + jaw1a.setRotationPoint(-3F, 0F, -6F); + setRotation(jaw1a, 0.3490659F, 0F, 0F); + + jaw1b = new ModelRenderer(this, 0, 0); + jaw1b.addBox(0F, 0F, 0F, 1, 1, 2); + jaw1b.setRotationPoint(0F, 0F, -2F); + setRotation(jaw1b, 0F, 1.570796F, 0F); + + jaw2a = new ModelRenderer(this, 0, 0); + jaw2a.addBox(-1F, 0F, -2F, 1, 1, 2); + jaw2a.setRotationPoint(3F, 0F, -6F); + setRotation(jaw2a, 0.3490659F, 0F, 0F); + + jaw2b = new ModelRenderer(this, 0, 0); + jaw2b.addBox(0F, 0F, -2F, 1, 1, 2); + jaw2b.setRotationPoint(0F, 0F, -2F); + setRotation(jaw2b, 0F, 1.570796F, 0F); + + antenna1 = new ModelRenderer(this, 42, 4); + antenna1.addBox(0F, -0.5F, -0.5F, 10, 1, 1); + antenna1.setRotationPoint(1F, -3F, -5F); + setRotation(antenna1, 0F, 1.047198F, -0.296706F); + + antenna2 = new ModelRenderer(this, 42, 4); + antenna2.addBox(0F, -0.5F, -0.5F, 10, 1, 1); + antenna2.setRotationPoint(-1F, -3F, -5F); + setRotation(antenna2, 0F, 2.094395F, 0.296706F); + + eye1 = new ModelRenderer(this, 15, 12); + eye1.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + eye1.setRotationPoint(-3F, -2F, -5F); + + eye2 = new ModelRenderer(this, 15, 12); + eye2.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + eye2.setRotationPoint(3F, -2F, -5F); + + + head.addChild(jaw1a); + jaw1a.addChild(jaw1b); + head.addChild(jaw2a); + jaw2a.addChild(jaw2b); + head.addChild(antenna1); + head.addChild(antenna2); + head.addChild(eye1); + head.addChild(eye2); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + thorax.render(scale); + head.render(scale); + connector2.render(scale); + RearEnd.render(scale); + Leg6.render(scale); + Leg4.render(scale); + Leg2.render(scale); + Leg5.render(scale); + Leg3.render(scale); + Leg1.render(scale); + connector1.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.head.rotateAngleX = headPitch / (180F / (float) Math.PI); + + float legZ = ((float) Math.PI / 11F); + this.Leg1.rotateAngleZ = -legZ; + this.Leg2.rotateAngleZ = legZ; + this.Leg3.rotateAngleZ = -legZ * 0.74F; + this.Leg4.rotateAngleZ = legZ * 0.74F; + this.Leg5.rotateAngleZ = -legZ; + this.Leg6.rotateAngleZ = legZ; + + float var9 = -0.0F; + float var10 = 0.3926991F; + this.Leg1.rotateAngleY = var10 * 2.0F + var9; + this.Leg2.rotateAngleY = -var10 * 2.0F - var9; + this.Leg3.rotateAngleY = var10 * 1.0F + var9; + this.Leg4.rotateAngleY = -var10 * 1.0F - var9; + this.Leg5.rotateAngleY = -var10 * 2.0F + var9; + this.Leg6.rotateAngleY = var10 * 2.0F - var9; + + float var11 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + 0.0F) * 0.4F) * limbSwingAmount; + float var12 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float var14 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + + float var15 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + 0.0F) * 0.4F) * limbSwingAmount; + float var16 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float var18 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + + this.Leg1.rotateAngleY += var11; + this.Leg2.rotateAngleY += -var11; + this.Leg3.rotateAngleY += var12; + this.Leg4.rotateAngleY += -var12; + this.Leg5.rotateAngleY += var14; + this.Leg6.rotateAngleY += -var14; + + this.Leg1.rotateAngleZ += var15; + this.Leg2.rotateAngleZ += -var15; + + this.Leg3.rotateAngleZ += var16; + this.Leg4.rotateAngleZ += -var16; + + this.Leg5.rotateAngleZ += var18; + this.Leg6.rotateAngleZ += -var18; + + + } + + +} diff --git a/src/main/java/twilightforest/client/model/ModelTFFirefly.java b/src/main/java/twilightforest/client/model/entity/ModelTFFirefly.java similarity index 85% rename from src/main/java/twilightforest/client/model/ModelTFFirefly.java rename to src/main/java/twilightforest/client/model/entity/ModelTFFirefly.java index a3c6f697fb..33ff43c0ea 100644 --- a/src/main/java/twilightforest/client/model/ModelTFFirefly.java +++ b/src/main/java/twilightforest/client/model/entity/ModelTFFirefly.java @@ -1,13 +1,11 @@ -package twilightforest.client.model; +package twilightforest.client.model.entity; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; -public class ModelTFFirefly extends ModelBase -{ - public ModelTFFirefly() - { +public class ModelTFFirefly extends ModelBase { + public ModelTFFirefly() { legs = new ModelRenderer(this, 0, 21); legs.addBox(-4F, 7.9F, -5F, 8, 1, 10, 0F); //legs.setRotationPoint(0F, 16F, 0F); @@ -26,19 +24,17 @@ public ModelTFFirefly() } - public void render(float f5) - { + public void render(float f5) { //super.render(f, f1, f2, f3, f4, f5); //setRotationAngles(f, f1, f2, f3, f4, f5); legs.render(f5); fatbody.render(f5); skinnybody.render(f5); // glow.render(f5); - + } - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) - { + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) { //super.setRotationAngles(f, f1, f2, f3, f4, f5); } @@ -47,5 +43,5 @@ public void setRotationAngles(float f, float f1, float f2, float f3, float f4, f public ModelRenderer fatbody; public ModelRenderer skinnybody; public ModelRenderer glow; - + } diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFGhast.java b/src/main/java/twilightforest/client/model/entity/ModelTFGhast.java new file mode 100644 index 0000000000..66d23c4b61 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFGhast.java @@ -0,0 +1,69 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.Random; + +@SideOnly(Side.CLIENT) +public class ModelTFGhast extends ModelBase { + ModelRenderer body; + protected ModelRenderer[] tentacles = new ModelRenderer[9]; + + + public ModelTFGhast() { + byte yOffset = -16; + this.body = new ModelRenderer(this, 0, 0); + this.body.addBox(-8.0F, -8.0F, -8.0F, 16, 16, 16); + this.body.rotationPointY += (float) (24 + yOffset); + Random rand = new Random(1660L); + + for (int i = 0; i < this.tentacles.length; ++i) { + makeTentacle(yOffset, rand, i); + } + } + + protected void makeTentacle(byte yOffset, Random random, int i) { + this.tentacles[i] = new ModelRenderer(this, 0, 0); + float xPoint = (((float) (i % 3) - (float) (i / 3 % 2) * 0.5F + 0.25F) / 2.0F * 2.0F - 1.0F) * 5.0F; + float zPoint = ((float) (i / 3) / 2.0F * 2.0F - 1.0F) * 5.0F; + int length = random.nextInt(7) + 8; + this.tentacles[i].addBox(-1.0F, 0.0F, -1.0F, 2, length, 2); + this.tentacles[i].rotationPointX = xPoint; + this.tentacles[i].rotationPointZ = zPoint; + this.tentacles[i].rotationPointY = (float) (23 + yOffset); + + this.body.addChild(this.tentacles[i]); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + // wave tentacles + for (int i = 0; i < this.tentacles.length; ++i) { + this.tentacles[i].rotateAngleX = 0.2F * MathHelper.sin(ageInTicks * 0.3F + (float) i) + 0.4F; + } + + // make body face what we're looking at + this.body.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.body.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + this.body.render(scale); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFGoblinChain.java b/src/main/java/twilightforest/client/model/entity/ModelTFGoblinChain.java new file mode 100644 index 0000000000..0259c6b93f --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFGoblinChain.java @@ -0,0 +1,24 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + + +public class ModelTFGoblinChain extends ModelBase { + ModelRenderer chain; + + public ModelTFGoblinChain() { + + chain = new ModelRenderer(this, 56, 16); + chain.addBox(-1F, -1F, -1F, 2, 2, 2, 0F); + chain.setRotationPoint(0F, 0F, 0F); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + chain.render(scale); + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFGoblinKnightLower.java b/src/main/java/twilightforest/client/model/entity/ModelTFGoblinKnightLower.java new file mode 100644 index 0000000000..f83bdc19ac --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFGoblinKnightLower.java @@ -0,0 +1,127 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.EntityTFGoblinKnightLower; + +public class ModelTFGoblinKnightLower extends ModelBiped { + + public ModelRenderer tunic; + + public ModelTFGoblinKnightLower() { + this.isSneak = false; + this.textureWidth = 128; + this.textureHeight = 64; + +//FIXME: AtomicBlom: Replace with something like LayerCape +/* + this.bipedCloak = new ModelRenderer(this, 0, 0); + this.bipedCloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1); +*/ +//FIXME: AtomicBlom replace with some variant of LayerDeadmau5Head +/* + this.bipedEars = new ModelRenderer(this, 24, 0); + this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1); +*/ + + this.bipedHead = new ModelRenderer(this, 0, 32); + this.bipedHead.addBox(-2.5F, -5.0F, -3.5F, 5, 5, 5); + this.bipedHead.setRotationPoint(0.0F, 10.0F, 1.0F); + + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + this.bipedHeadwear.addBox(0, 0, 0, 0, 0, 0); + + this.bipedBody = new ModelRenderer(this, 16, 48); + this.bipedBody.addBox(-3.5F, 0.0F, -2.0F, 7, 8, 4); + this.bipedBody.setRotationPoint(0.0F, 8.0F, 0.0F); + + this.bipedRightArm = new ModelRenderer(this, 40, 48); + this.bipedRightArm.addBox(-2.0F, -2.0F, -1.5F, 2, 8, 3); + this.bipedRightArm.setRotationPoint(-3.5F, 10.0F, 0.0F); + + this.bipedLeftArm = new ModelRenderer(this, 40, 48); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(0.0F, -2.0F, -1.5F, 2, 8, 3); + this.bipedLeftArm.setRotationPoint(3.5F, 10.0F, 0.0F); + + this.bipedRightLeg = new ModelRenderer(this, 0, 48); + this.bipedRightLeg.addBox(-3.0F, 0.0F, -2.0F, 4, 8, 4); + this.bipedRightLeg.setRotationPoint(-2.5F, 16.0F, 0.0F); + + this.bipedLeftLeg = new ModelRenderer(this, 0, 48); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.0F, 0.0F, -2.0F, 4, 8, 4); + this.bipedLeftLeg.setRotationPoint(2.5F, 16.0F, 0.0F); + + this.tunic = new ModelRenderer(this, 64, 19); + this.tunic.addBox(-6.0F, 0.0F, -3.0F, 12, 9, 6); + this.tunic.setRotationPoint(0F, 7.5F, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + + if (((EntityTFGoblinKnightLower) entity).hasArmor()) { + this.renderTunic(scale); + } + } + + /** + * Renders the tunic, if we're wearing armor + */ + public void renderTunic(float scale) { + this.tunic.render(scale); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + if (entity.isBeingRidden()) { + this.bipedHead.rotateAngleY = 0; + this.bipedHead.rotateAngleX = 0; + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + } + + if (this.leftArmPose != ArmPose.EMPTY) { + this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + if (this.rightArmPose != ArmPose.EMPTY) { + this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + this.bipedRightArm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFGoblinKnightUpper.java b/src/main/java/twilightforest/client/model/entity/ModelTFGoblinKnightUpper.java new file mode 100644 index 0000000000..ab4542d715 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFGoblinKnightUpper.java @@ -0,0 +1,251 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.EntityTFGoblinKnightUpper; + +public class ModelTFGoblinKnightUpper extends ModelBiped { + + public ModelRenderer breastplate; + public ModelRenderer helmet; + public ModelRenderer righthorn1; + public ModelRenderer righthorn2; + public ModelRenderer lefthorn1; + public ModelRenderer lefthorn2; + + public ModelRenderer shield; + public ModelRenderer spear; + + + public ModelTFGoblinKnightUpper() { + this.isSneak = false; + this.textureWidth = 128; + this.textureHeight = 64; + +//FIXME: AtomicBlom: Replace with something like LayerCape +/* + this.bipedCloak = new ModelRenderer(this, 0, 0); + this.bipedCloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1); +*/ +//FIXME: AtomicBlom replace with some variant of LayerDeadmau5Head +/* + this.bipedEars = new ModelRenderer(this, 24, 0); + this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1); +*/ + + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(0, 0, 0, 0, 0, 0); + this.bipedHead.setRotationPoint(0.0F, 12.0F, 0.0F); + + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + this.bipedHeadwear.addBox(0, 0, 0, 0, 0, 0); + this.bipedHeadwear.setRotationPoint(0.0F, 12.0F, 0.0F); + + this.helmet = new ModelRenderer(this, 0, 0); + this.helmet.addBox(-3.5F, -11.0F, -3.5F, 7, 11, 7); + this.helmet.rotateAngleY = 45F / (180F / (float) Math.PI); + + this.righthorn1 = new ModelRenderer(this, 28, 0); + this.righthorn1.addBox(-6F, -1.5F, -1.5F, 7, 3, 3); + this.righthorn1.setRotationPoint(-3.5F, -9F, 0.0F); + this.righthorn1.rotateAngleY = 15F / (180F / (float) Math.PI); + this.righthorn1.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn2 = new ModelRenderer(this, 28, 6); + this.righthorn2.addBox(-3.0F, -1.0F, -1.0F, 3, 2, 2); + this.righthorn2.setRotationPoint(-5.5F, 0.0F, 0.0F); + this.righthorn2.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn1.addChild(righthorn2); + + this.lefthorn1 = new ModelRenderer(this, 28, 0); + this.lefthorn1.mirror = true; + this.lefthorn1.addBox(-1F, -1.5F, -1.5F, 7, 3, 3); + this.lefthorn1.setRotationPoint(3.5F, -9F, 0.0F); + this.lefthorn1.rotateAngleY = -15F / (180F / (float) Math.PI); + this.lefthorn1.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn2 = new ModelRenderer(this, 28, 6); + this.lefthorn2.addBox(0.0F, -1.0F, -1.0F, 3, 2, 2); + this.lefthorn2.setRotationPoint(5.5F, 0.0F, 0.0F); + this.lefthorn2.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn1.addChild(lefthorn2); + + this.bipedHeadwear.addChild(helmet); + this.bipedHeadwear.addChild(righthorn1); + this.bipedHeadwear.addChild(lefthorn1); + + this.bipedBody = new ModelRenderer(this, 0, 18); + this.bipedBody.setRotationPoint(0.0F, 12.0F, 0.0F); + this.bipedBody.addBox(-5.5F, 0.0F, -2.0F, 11, 8, 4); + this.bipedBody.setTextureOffset(30, 24).addBox(-6.5F, 0F, -2F, 1, 4, 4); // right shoulder + this.bipedBody.setTextureOffset(30, 24).addBox(5.5F, 0F, -2F, 1, 4, 4); // left shoulder + + this.bipedRightArm = new ModelRenderer(this, 44, 16); + this.bipedRightArm.addBox(-4.0F, -2.0F, -2.0F, 4, 12, 4); + this.bipedRightArm.setRotationPoint(-6.5F, 14.0F, 0.0F); + + this.bipedLeftArm = new ModelRenderer(this, 44, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(0.0F, -2.0F, -2.0F, 4, 12, 4); + this.bipedLeftArm.setRotationPoint(6.5F, 14.0F, 0.0F); + + this.bipedRightLeg = new ModelRenderer(this, 30, 16); + this.bipedRightLeg.addBox(-1.5F, 0.0F, -2.0F, 3, 4, 4); + this.bipedRightLeg.setRotationPoint(-4F, 20.0F, 0.0F); + + this.bipedLeftLeg = new ModelRenderer(this, 30, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.5F, 0.0F, -2.0F, 3, 4, 4); + this.bipedLeftLeg.setRotationPoint(4F, 20.0F, 0.0F); + + this.shield = new ModelRenderer(this, 63, 36); + this.shield.addBox(-6.0F, -6.0F, -2.0F, 12, 20, 2); + this.shield.setRotationPoint(0F, 12F, 0.0F); + this.shield.rotateAngleX = 90F / (180F / (float) Math.PI); + + this.bipedLeftArm.addChild(shield); + + this.spear = new ModelRenderer(this, 108, 0); + this.spear.addBox(-1.0F, -19.0F, -1.0F, 2, 40, 2); + this.spear.setRotationPoint(-2F, 8.5F, 0.0F); + this.spear.rotateAngleX = 90F / (180F / (float) Math.PI); + + this.bipedRightArm.addChild(spear); + + + this.breastplate = new ModelRenderer(this, 64, 0); + this.breastplate.addBox(-6.5F, 0.0F, -3.0F, 13, 12, 6); + this.breastplate.setRotationPoint(0F, 11.5F, 0.0F); + + + } + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.shield.isHidden = !((EntityTFGoblinKnightUpper) entity).hasShield(); + + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + + if (((EntityTFGoblinKnightUpper) entity).hasArmor()) { + this.renderBreastplate(scale); + } + + } + + /** + * Renders the breastplate, if we're wearing armor + */ + public void renderBreastplate(float scale) { + this.breastplate.render(scale); + } + + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + EntityTFGoblinKnightUpper upperKnight = ((EntityTFGoblinKnightUpper) entity); + + boolean hasShield = upperKnight.hasShield(); + + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.bipedHead.rotateAngleZ = 0; + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedHeadwear.rotateAngleZ = this.bipedHead.rotateAngleZ; + + + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + + float leftConstraint = hasShield ? 0.2F : limbSwingAmount; + + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * leftConstraint * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + + + this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + if (this.isRiding) { + this.bipedRightArm.rotateAngleX += -((float) Math.PI / 5F); + this.bipedLeftArm.rotateAngleX += -((float) Math.PI / 5F); + this.bipedRightLeg.rotateAngleX = 0; + this.bipedLeftLeg.rotateAngleX = 0; +// this.bipedRightLeg.rotateAngleY = ((float)Math.PI / 10F); +// this.bipedLeftLeg.rotateAngleY = -((float)Math.PI / 10F); + } + + if (this.leftArmPose != ArmPose.EMPTY) { + this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + this.rightArmPose = ArmPose.ITEM; + + if (this.rightArmPose != ArmPose.EMPTY) { + this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + bipedRightArm.rotateAngleX -= (Math.PI * 0.66); + + // during swing move arm forward + if (upperKnight.heavySpearTimer > 0) { + bipedRightArm.rotateAngleX -= this.getArmRotationDuringSwing(60 - upperKnight.heavySpearTimer + scaleFactor) / (180F / (float) Math.PI); + } + + this.bipedRightArm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + + // shield arm points somewhat inward + this.bipedLeftArm.rotateAngleZ = -this.bipedLeftArm.rotateAngleZ; + + // fix shield so that it's always perpendicular to the floor + this.shield.rotateAngleX = (float) (Math.PI * 2 - this.bipedLeftArm.rotateAngleX); + } + + /** + * + */ + private float getArmRotationDuringSwing(float attackTime) { + if (attackTime <= 10) { + // rock back + return attackTime * 1.0F; + } + if (attackTime > 10 && attackTime <= 30) { + // hang back + return 10F; + } + if (attackTime > 30 && attackTime <= 33) { + // slam forward + return (attackTime - 30) * -8F + 10F; + } + if (attackTime > 33 && attackTime <= 50) { + // stay forward + return -15F; + } + if (attackTime > 50 && attackTime <= 60) { + // back to normal + return (10 - (attackTime - 50)) * -1.5F; + } + + return 0; + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFHelmetCrab.java b/src/main/java/twilightforest/client/model/entity/ModelTFHelmetCrab.java new file mode 100644 index 0000000000..42e01e0ded --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFHelmetCrab.java @@ -0,0 +1,242 @@ +// Date: 4/14/2013 12:59:03 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + +/** + * Helmet crab model, based partially on some of the spider code + */ +public class ModelTFHelmetCrab extends ModelBase { + //fields + ModelRenderer body; + ModelRenderer helmetBase; + ModelRenderer Leg8; + ModelRenderer Leg6; + ModelRenderer Leg4; + ModelRenderer rightArm; + ModelRenderer Leg5; + ModelRenderer Leg3; + ModelRenderer clawbase; + ModelRenderer clawtop; + ModelRenderer clawbottom; + ModelRenderer righteye; + ModelRenderer lefteye; + + public ModelRenderer helmet; + public ModelRenderer righthorn1; + public ModelRenderer righthorn2; + public ModelRenderer lefthorn1; + public ModelRenderer lefthorn2; + + + public ModelTFHelmetCrab() { + textureWidth = 64; + textureHeight = 32; + + body = new ModelRenderer(this, 32, 4); + body.addBox(-2.5F, -2.5F, -5F, 5, 5, 5); + body.setRotationPoint(0F, 19F, 0F); + + helmetBase = new ModelRenderer(this, 0, 0); + helmetBase.addBox(0, 0, 0, 0, 0, 0); + helmetBase.setRotationPoint(0F, 18F, 0F); + this.helmetBase.rotateAngleX = -100F / (180F / (float) Math.PI); + this.helmetBase.rotateAngleY = -30F / (180F / (float) Math.PI); + + this.helmet = new ModelRenderer(this, 0, 14); + this.helmet.addBox(-3.5F, -11.0F, -3.5F, 7, 11, 7); + this.helmet.rotateAngleY = 45F / (180F / (float) Math.PI); + + this.righthorn1 = new ModelRenderer(this, 28, 14); + this.righthorn1.addBox(-6F, -1.5F, -1.5F, 7, 3, 3); + this.righthorn1.setRotationPoint(-3.5F, -9F, 0.0F); + this.righthorn1.rotateAngleY = -15F / (180F / (float) Math.PI); + this.righthorn1.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn2 = new ModelRenderer(this, 28, 20); + this.righthorn2.addBox(-3.0F, -1.0F, -1.0F, 3, 2, 2); + this.righthorn2.setRotationPoint(-5.5F, 0.0F, 0.0F); + this.righthorn2.rotateAngleY = -15F / (180F / (float) Math.PI); + this.righthorn2.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn1.addChild(righthorn2); + + this.lefthorn1 = new ModelRenderer(this, 28, 14); + this.lefthorn1.mirror = true; + this.lefthorn1.addBox(-1F, -1.5F, -1.5F, 7, 3, 3); + this.lefthorn1.setRotationPoint(3.5F, -9F, 0.0F); + this.lefthorn1.rotateAngleY = 15F / (180F / (float) Math.PI); + this.lefthorn1.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn2 = new ModelRenderer(this, 28, 20); + this.lefthorn2.addBox(0.0F, -1.0F, -1.0F, 3, 2, 2); + this.lefthorn2.setRotationPoint(5.5F, 0.0F, 0.0F); + this.lefthorn2.rotateAngleY = 15F / (180F / (float) Math.PI); + this.lefthorn2.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn1.addChild(lefthorn2); + + this.helmetBase.addChild(helmet); + this.helmetBase.addChild(righthorn1); + this.helmetBase.addChild(lefthorn1); + + Leg8 = new ModelRenderer(this, 18, 0); + Leg8.addBox(-1F, -1F, -1F, 8, 2, 2); + Leg8.setRotationPoint(3F, 20F, -3F); + setRotation(Leg8, 0F, 0.5759587F, 0.1919862F); + + Leg6 = new ModelRenderer(this, 18, 0); + Leg6.addBox(-1F, -1F, -1F, 8, 2, 2); + Leg6.setRotationPoint(3F, 20F, -2F); + setRotation(Leg6, 0F, 0.2792527F, 0.1919862F); + + Leg4 = new ModelRenderer(this, 18, 0); + Leg4.addBox(-1F, -1F, -1F, 8, 2, 2); + Leg4.setRotationPoint(3F, 20F, -1F); + setRotation(Leg4, 0F, -0.2792527F, 0.1919862F); + + rightArm = new ModelRenderer(this, 38, 0); + rightArm.addBox(-7F, -1F, -1F, 8, 2, 2); + rightArm.setRotationPoint(-3F, 20F, -3F); + setRotation(rightArm, 0F, -1.319531F, -0.1919862F); + + Leg5 = new ModelRenderer(this, 18, 0); + Leg5.addBox(-7F, -1F, -1F, 8, 2, 2); + Leg5.setRotationPoint(-3F, 20F, -2F); + setRotation(Leg5, 0F, -0.2792527F, -0.1919862F); + + Leg3 = new ModelRenderer(this, 18, 0); + Leg3.addBox(-7F, -1F, -1F, 8, 2, 2); + Leg3.setRotationPoint(-3F, 20F, -1F); + setRotation(Leg3, 0F, 0.2792527F, -0.1919862F); + + clawbase = new ModelRenderer(this, 0, 0); + clawbase.addBox(0F, -1.5F, -1F, 3, 3, 2); + clawbase.setRotationPoint(-6F, 0F, -0.5F); + setRotation(clawbase, 0.0F, (float) (Math.PI / 2.0F), 0); + + clawtop = new ModelRenderer(this, 0, 5); + clawtop.addBox(0F, -0.5F, -1F, 3, 1, 2); + clawtop.setRotationPoint(3F, -1F, 0F); + setRotation(clawtop, 0F, 0F, -0.1858931F); + + clawbottom = new ModelRenderer(this, 0, 8); + clawbottom.addBox(0F, -0.5F, -1F, 3, 2, 2); + clawbottom.setRotationPoint(3F, 0F, 0F); + setRotation(clawbottom, 0F, 0F, 0.2602503F); + + this.clawbase.addChild(clawtop); + this.clawbase.addChild(clawbottom); + + this.rightArm.addChild(clawbase); + + righteye = new ModelRenderer(this, 10, 0); + righteye.addBox(-1F, -3F, -1F, 2, 3, 2); + righteye.setRotationPoint(-1F, -1F, -4F); + setRotation(righteye, (float) (Math.PI / 4.0F), 0.0F, -(float) (Math.PI / 4.0F)); + + lefteye = new ModelRenderer(this, 10, 0); + lefteye.addBox(-1F, -3F, -1F, 2, 3, 2); + lefteye.setRotationPoint(1F, -1F, -4F); + setRotation(lefteye, (float) (Math.PI / 4.0F), 0.0F, (float) (Math.PI / 4.0F)); + + this.body.addChild(righteye); + this.body.addChild(lefteye); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + body.render(scale); + helmetBase.render(scale); + Leg8.render(scale); + Leg6.render(scale); + Leg4.render(scale); + rightArm.render(scale); + Leg5.render(scale); + Leg3.render(scale); +// clawbase.render(scale); +// clawtop.render(scale); +// clawbottom.render(scale); +// righteye.render(scale); +// lefteye.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + this.body.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.body.rotateAngleX = headPitch / (180F / (float) Math.PI); + float f6 = ((float) Math.PI / 4F); + //this.Leg1.rotateAngleZ = -f6; + //this.Leg2.rotateAngleZ = f6; + this.Leg3.rotateAngleZ = -f6 * 0.74F; + this.Leg4.rotateAngleZ = f6 * 0.74F; + this.Leg5.rotateAngleZ = -f6 * 0.74F; + this.Leg6.rotateAngleZ = f6 * 0.74F; + //this.Leg7.rotateAngleZ = -f6; + this.Leg8.rotateAngleZ = f6; + float f7 = -0.0F; + float f8 = 0.3926991F; + //this.Leg1.rotateAngleY = f8 * 2.0F + f7; + //this.Leg2.rotateAngleY = -f8 * 2.0F - f7; + this.Leg3.rotateAngleY = f8 * 1.0F + f7; + this.Leg4.rotateAngleY = -f8 * 1.0F - f7; + this.Leg5.rotateAngleY = -f8 * 1.0F + f7; + this.Leg6.rotateAngleY = f8 * 1.0F - f7; + //this.Leg7.rotateAngleY = -f8 * 2.0F + f7; + this.Leg8.rotateAngleY = f8 * 2.0F - f7; + float f10 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float f11 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + ((float) Math.PI / 2F)) * 0.4F) * limbSwingAmount; + float f12 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + float f14 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float f15 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + ((float) Math.PI / 2F)) * 0.4F) * limbSwingAmount; + float f16 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + //this.Leg1.rotateAngleY += f9; + //this.Leg2.rotateAngleY += -f9; + this.Leg3.rotateAngleY += f10; + this.Leg4.rotateAngleY += -f10; + this.Leg5.rotateAngleY += f11; + this.Leg6.rotateAngleY += -f11; + //this.Leg7.rotateAngleY += f12; + this.Leg8.rotateAngleY += -f12; + //this.Leg1.rotateAngleZ += f13; + //this.Leg2.rotateAngleZ += -f13; + this.Leg3.rotateAngleZ += f14; + this.Leg4.rotateAngleZ += -f14; + this.Leg5.rotateAngleZ += f15; + this.Leg6.rotateAngleZ += -f15; + //this.Leg7.rotateAngleZ += f16; + this.Leg8.rotateAngleZ += -f16; + + // swing right arm as if it were an arm, not a leg + this.rightArm.rotateAngleY = -1.319531F; + this.rightArm.rotateAngleY += MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + + + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFHydra.java b/src/main/java/twilightforest/client/model/entity/ModelTFHydra.java new file mode 100644 index 0000000000..6e405dafaf --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFHydra.java @@ -0,0 +1,321 @@ +// Date: 2/5/2012 10:11:18 AM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.boss.EntityTFHydra; +import twilightforest.entity.boss.EntityTFHydraPart; + + +public class ModelTFHydra extends ModelBase { + //fields + ModelRenderer body; + ModelRenderer leg1; + ModelRenderer leg2; + ModelRenderer tail1; + ModelRenderer tail2; + ModelRenderer tail3; + ModelRenderer tail4; + ModelRenderer neck1a; + ModelRenderer neck1b; + ModelRenderer neck1c; + ModelRenderer neck1d; + ModelRenderer head1; + ModelRenderer jaw1; + ModelRenderer frill1; + ModelRenderer neck2a; + ModelRenderer neck2b; + ModelRenderer neck2c; + ModelRenderer neck2d; + ModelRenderer head2; + ModelRenderer jaw2; + ModelRenderer frill2; + ModelRenderer neck3a; + ModelRenderer neck3b; + ModelRenderer neck3c; + ModelRenderer neck3d; + ModelRenderer head3; + ModelRenderer jaw3; + ModelRenderer frill3; + + public ModelTFHydra() { + textureWidth = 512; + textureHeight = 256; + + setTextureOffset("body.body", 0, 0); + setTextureOffset("leg.main", 0, 136); + setTextureOffset("leg.toe", 184, 200); + setTextureOffset("tail.box", 128, 136); + setTextureOffset("tail.fin", 128, 200); + setTextureOffset("neck.box", 128, 136); + setTextureOffset("neck.fin", 128, 200); + setTextureOffset("head.box", 272, 0); + setTextureOffset("head.upperlip", 272, 56); + setTextureOffset("head.fin", 128, 200); + setTextureOffset("jaw.jaw", 272, 92); + setTextureOffset("frill.frill", 272, 200); + + body = new ModelRenderer(this, "body"); + body.setRotationPoint(0F, -12F, 0F); + body.addBox("body", -48F, 0F, 0F, 96, 96, 40); + setRotation(body, 1.22173F, 0F, 0F); + + leg1 = new ModelRenderer(this, "leg"); + leg1.setRotationPoint(48F, -24F, 0F); + leg1.addBox("main", -16F, 0F, -16F, 32, 48, 32); + leg1.addBox("toe", -20F, 40F, -20F, 8, 8, 8); + leg1.addBox("toe", -4F, 40F, -22F, 8, 8, 8); + leg1.addBox("toe", 12F, 40F, -20F, 8, 8, 8); + + leg2 = new ModelRenderer(this, "leg"); + leg2.setRotationPoint(-48F, -24F, 0F); + leg2.mirror = true; + leg2.addBox("main", -16F, 0F, -16F, 32, 48, 32); + leg2.addBox("toe", -20F, 40F, -20F, 8, 8, 8); + leg2.addBox("toe", -4F, 40F, -22F, 8, 8, 8); + leg2.addBox("toe", 12F, 40F, -20F, 8, 8, 8); + + + tail1 = new ModelRenderer(this, "tail"); + tail1.setRotationPoint(0F, 6F, 108F); + tail1.addBox("box", -16F, -16F, -16F, 32, 32, 32); + tail1.addBox("fin", -2F, -28F, -11F, 4, 24, 24); + + tail2 = new ModelRenderer(this, "tail"); + tail2.addBox("box", -16F, -16F, -16F, 32, 32, 32); + tail2.addBox("fin", -2F, -28F, -11F, 4, 24, 24); + tail2.setRotationPoint(0F, 7F, 142F); + + tail3 = new ModelRenderer(this, "tail"); + tail3.addBox("box", -16F, -16F, -16F, 32, 32, 32); + tail3.addBox("fin", -2F, -28F, -11F, 4, 24, 24); + tail3.setRotationPoint(0F, 8F, 176F); + + tail4 = new ModelRenderer(this, "tail"); + tail4.addBox("box", -16F, -16F, -16F, 32, 32, 32); + tail4.addBox("fin", -2F, -28F, -11F, 4, 24, 24); + tail4.setRotationPoint(0F, 8F, 210F); + + neck1a = new ModelRenderer(this, "neck"); + neck1a.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck1a.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck1a.setRotationPoint(0F, -48F, 16F); + + neck1b = new ModelRenderer(this, "neck"); + neck1b.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck1b.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck1b.setRotationPoint(0F, -68F, 0F); + + neck1c = new ModelRenderer(this, "neck"); + neck1c.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck1c.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck1c.setRotationPoint(0F, -93F, -14F); + + neck1d = new ModelRenderer(this, "neck"); + neck1d.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck1d.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck1d.setRotationPoint(0F, -116F, -37F); + + + head1 = new ModelRenderer(this, "head"); + head1.addBox("box", -16F, -14F, -32F, 32, 24, 32); + head1.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); + head1.addBox("fin", -2F, -30F, -12F, 4, 24, 24); + head1.setRotationPoint(0F, -128F, -53F); + + jaw1 = new ModelRenderer(this, "jaw"); + jaw1.setRotationPoint(0F, 10F, -4F); + jaw1.addBox("jaw", -15F, 0F, -48F, 30, 8, 48); + setRotation(jaw1, 0F, 0F, 0F); + head1.addChild(jaw1); + + frill1 = new ModelRenderer(this, "frill"); + frill1.setRotationPoint(0F, 0F, -10F); + frill1.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); + setRotation(frill1, -0.5235988F, 0F, 0F); + head1.addChild(frill1); + + neck2a = new ModelRenderer(this, "neck"); + neck2a.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck2a.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck2a.setRotationPoint(48F, -48F, 16F); + + neck2b = new ModelRenderer(this, "neck"); + neck2b.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck2b.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck2b.setRotationPoint(71F, -68F, 0F); + + neck2c = new ModelRenderer(this, "neck"); + neck2c.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck2c.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck2c.setRotationPoint(96F, -93F, -14F); + + neck2d = new ModelRenderer(this, "neck"); + neck2d.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck2d.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck2d.setRotationPoint(108F, -116F, -37F); + + head2 = new ModelRenderer(this, "head"); + head2.addBox("box", -16F, -14F, -32F, 32, 24, 32); + head2.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); + head2.addBox("fin", -2F, -30F, -12F, 4, 24, 24); + head2.setRotationPoint(108F, -128F, -53F); + + jaw2 = new ModelRenderer(this, "jaw"); + jaw2.setRotationPoint(0F, 10F, -4F); + jaw2.addBox("jaw", -15F, 0F, -48F, 30, 8, 48); + setRotation(jaw2, 0F, 0F, 0F); + head2.addChild(jaw2); + + frill2 = new ModelRenderer(this, "frill"); + frill2.setRotationPoint(0F, 0F, -10F); + frill2.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); + setRotation(frill2, -0.5235988F, 0F, 0F); + head2.addChild(frill2); + + + neck3a = new ModelRenderer(this, "neck"); + neck3a.addBox("box", -16F, -16F, -16F, 32, 32, 31); + neck3a.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck3a.setRotationPoint(-48F, -48F, 16F); + + neck3b = new ModelRenderer(this, "neck"); + neck3b.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck3b.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck3b.setRotationPoint(-71F, -43F, 0F); + + neck3c = new ModelRenderer(this, "neck"); + neck3c.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck3c.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck3c.setRotationPoint(-96F, -33F, -14F); + + neck3d = new ModelRenderer(this, "neck"); + neck3d.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck3d.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck3d.setRotationPoint(-108F, -24F, -37F); + + + head3 = new ModelRenderer(this, "head"); + head3.addBox("box", -16F, -14F, -32F, 32, 24, 32); + head3.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); + head3.addBox("fin", -2F, -30F, -12F, 4, 24, 24); + head3.setRotationPoint(-108F, -24F, -53F); + + jaw3 = new ModelRenderer(this, "jaw"); + jaw3.setRotationPoint(0F, 10F, -4F); + jaw3.addBox("jaw", -15F, 0F, -48F, 30, 8, 48); + setRotation(jaw3, 0.125F, 0F, 0F); + head3.addChild(jaw3); + + frill3 = new ModelRenderer(this, "frill"); + frill3.setRotationPoint(0F, 0F, -10F); + frill3.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); + setRotation(frill3, -0.5235988F, 0F, 0F); + head3.addChild(frill3); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + body.render(scale); + leg1.render(scale); + leg2.render(scale); + tail1.render(scale); + tail2.render(scale); + tail3.render(scale); + tail4.render(scale); +// neck1a.render(scale); +// neck1b.render(scale); +// neck1c.render(scale); +// neck1d.render(scale); +// head1.render(scale); +// neck2a.render(scale); +// neck2b.render(scale); +// neck2c.render(scale); +// neck2d.render(scale); +// head2.render(scale); +// neck3a.render(scale); +// neck3b.render(scale); +// neck3c.render(scale); +// neck3d.render(scale); +// head3.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + leg1.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + leg2.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + 3.141593F) * 1.4F * limbSwingAmount; + + leg1.rotateAngleY = 0.0F; + leg2.rotateAngleY = 0.0F; + + } + + +// @Override +// public void setLivingAnimations(EntityLiving entityliving, float f, float f1, float time) { +// EntityTFHydra hydra = (EntityTFHydra)entityliving; +// +// // position the heads +// Vec3 vec; +// +// vec = Vec3.getVec3Pool().getVecFromPool(0, 0, 7*-16); +// vec.rotateAroundX((60 * 3.141593F) / 180F); +// vec.rotateAroundY((0 * 3.141593F) / 180F); +// head1.setRotationPoint((float)vec.x, (float)vec.y - 48, (float)vec.z); +// +// vec = Vec3.getVec3Pool().getVecFromPool(0, 0, 9*-16); +// vec.rotateAroundX((45 * 3.141593F) / 180F); +// vec.rotateAroundY((-60 * 3.141593F) / 180F); +// head2.setRotationPoint((float)vec.x, (float)vec.y - 48, (float)vec.z); +// +// vec = Vec3.getVec3Pool().getVecFromPool(0, 0, 9*-16); +// vec.rotateAroundX((-10 * 3.141593F) / 180F); +// vec.rotateAroundY((60 * 3.141593F) / 180F); +// head3.setRotationPoint((float)vec.x, (float)vec.y - 48, (float)vec.z); +// +// // rotate the heads +// if (hydra.head1 != null) +// { +// head1.rotateAngleY = getRotationY(hydra, hydra.head1, time); +// head1.rotateAngleX = getRotationX(hydra, hydra.head1, time); +// +// head2.rotateAngleY = getRotationY(hydra, hydra.head3, time); +// head2.rotateAngleX = getRotationX(hydra, hydra.head3, time); +// +// head3.rotateAngleY = getRotationY(hydra, hydra.head2, time); +// head3.rotateAngleX = getRotationX(hydra, hydra.head2, time) - 0.015F; +// } +// } + + public float getRotationY(EntityTFHydra hydra, EntityTFHydraPart whichHead, float time) { + + float yawOffset = hydra.prevRenderYawOffset + (hydra.renderYawOffset - hydra.prevRenderYawOffset) * time; + float yaw = whichHead.prevRotationYaw + (whichHead.rotationYaw - whichHead.prevRotationYaw) * time; + + return (yaw - yawOffset) / 57.29578F; + } + + public float getRotationX(EntityTFHydra hydra, EntityTFHydraPart whichHead, float time) { + + return (whichHead.prevRotationPitch + (whichHead.rotationPitch - whichHead.prevRotationPitch) * time) / 57.29578F; + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFHydraHead.java b/src/main/java/twilightforest/client/model/entity/ModelTFHydraHead.java new file mode 100644 index 0000000000..2209a23abf --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFHydraHead.java @@ -0,0 +1,126 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import twilightforest.entity.boss.EntityTFHydraHead; +import twilightforest.entity.boss.EntityTFHydraPart; + + +public class ModelTFHydraHead extends ModelBase { + + ModelRenderer head; + ModelRenderer jaw; + ModelRenderer frill; + + public ModelTFHydraHead() { + textureWidth = 512; + textureHeight = 256; + + setTextureOffset("head.box", 272, 0); + setTextureOffset("head.upperlip", 272, 56); + setTextureOffset("head.rearjaw", 272, 132); + setTextureOffset("head.fin", 128, 200); + setTextureOffset("head.fang1", 272, 156); + setTextureOffset("head.fang2", 272, 156); + setTextureOffset("head.teeth", 280, 156); + setTextureOffset("head.teeth2", 280, 160); + setTextureOffset("head.teeth3", 280, 160); + setTextureOffset("jaw.jaw", 272, 92); + setTextureOffset("jaw.fang1", 272, 156); + setTextureOffset("jaw.fang2", 272, 156); + setTextureOffset("jaw.teeth", 280, 156); + setTextureOffset("jaw.teeth2", 280, 160); + setTextureOffset("jaw.teeth3", 280, 160); + setTextureOffset("frill.frill", 272, 200); + + + head = new ModelRenderer(this, "head"); + head.addBox("box", -16F, -14F, -32F, 32, 24, 32); + head.addBox("upperlip", -15F, -2F, -56F, 30, 12, 24); + head.addBox("rearjaw", -15F, 10F, -20F, 30, 8, 16); + head.addBox("fin", -2F, -30F, -12F, 4, 24, 24); + head.addBox("fang1", -12F, 10, -49F, 2, 5, 2); + head.addBox("fang2", 10F, 10, -49F, 2, 5, 2); + head.addBox("teeth", -8F, 9, -49F, 16, 2, 2); + head.addBox("teeth2", -10F, 9, -45F, 2, 2, 16); + head.addBox("teeth3", 8F, 9, -45F, 2, 2, 16); + head.setRotationPoint(0F, 0F, 0F); + + jaw = new ModelRenderer(this, "jaw"); + jaw.setRotationPoint(0F, 10F, -20F); + jaw.addBox("jaw", -15F, 0F, -32F, 30, 8, 32); + jaw.addBox("fang1", -10F, -5, -29F, 2, 5, 2); + jaw.addBox("fang2", 8F, -5, -29F, 2, 5, 2); + jaw.addBox("teeth", -8F, -1, -29F, 16, 2, 2); + jaw.addBox("teeth2", -10F, -1, -25F, 2, 2, 16); + jaw.addBox("teeth3", 8F, -1, -25F, 2, 2, 16); + setRotation(jaw, 0F, 0F, 0F); + head.addChild(jaw); + + frill = new ModelRenderer(this, "frill"); + frill.setRotationPoint(0F, 0F, -14F); + frill.addBox("frill", -24F, -40.0F, 0F, 48, 48, 4); + setRotation(frill, -0.5235988F, 0F, 0F); + head.addChild(frill); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + head.render(scale); + } + + public void render(float f5) { + head.render(f5); + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { +// head.rotateAngleY = netHeadYaw / (180F / (float)Math.PI); +// head.rotateAngleX = headPitch / (180F / (float)Math.PI); + } + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + EntityTFHydraHead whichHead = (EntityTFHydraHead) entity; + + head.rotateAngleY = getRotationY(whichHead, partialTicks); + head.rotateAngleX = getRotationX(whichHead, partialTicks); + + float mouthOpen = whichHead.getMouthOpen(); + head.rotateAngleX -= (float) (mouthOpen * (Math.PI / 12.0)); + jaw.rotateAngleX = (float) (mouthOpen * (Math.PI / 3.0)); + } + + public void openMouthForTrophy(float mouthOpen) { + head.rotateAngleY = 0; + head.rotateAngleX = 0; + + head.rotateAngleX -= (float) (mouthOpen * (Math.PI / 12.0)); + jaw.rotateAngleX = (float) (mouthOpen * (Math.PI / 3.0)); + + } + + public float getRotationY(EntityTFHydraPart whichHead, float time) { + + //float yawOffset = hydra.prevRenderYawOffset + (hydra.renderYawOffset - hydra.prevRenderYawOffset) * time; + float yaw = whichHead.prevRotationYaw + (whichHead.rotationYaw - whichHead.prevRotationYaw) * time; + + return yaw / 57.29578F; + } + + public float getRotationX(EntityTFHydraPart whichHead, float time) { + + return (whichHead.prevRotationPitch + (whichHead.rotationPitch - whichHead.prevRotationPitch) * time) / 57.29578F; + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFHydraMortar.java b/src/main/java/twilightforest/client/model/entity/ModelTFHydraMortar.java new file mode 100644 index 0000000000..b0f3620a25 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFHydraMortar.java @@ -0,0 +1,21 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; + +public class ModelTFHydraMortar extends ModelBase { + + public ModelRenderer box; + + public ModelTFHydraMortar() { + textureWidth = 32; + textureHeight = 32; + box = new ModelRenderer(this, 0, 0); + box.addBox(-4F, 0F, -4F, 8, 8, 8, 0F); + box.setRotationPoint(0F, 0F, 0F); + } + + public void render(float f5) { + box.render(f5); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFHydraNeck.java b/src/main/java/twilightforest/client/model/entity/ModelTFHydraNeck.java new file mode 100644 index 0000000000..76f932cfb8 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFHydraNeck.java @@ -0,0 +1,39 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + + +public class ModelTFHydraNeck extends ModelBase { + + ModelRenderer neck; + + public ModelTFHydraNeck() { + textureWidth = 512; + textureHeight = 256; + + setTextureOffset("neck.box", 128, 136); + setTextureOffset("neck.fin", 128, 200); + neck = new ModelRenderer(this, "neck"); + neck.addBox("box", -16F, -16F, -16F, 32, 32, 32); + neck.addBox("fin", -2F, -23F, 0F, 4, 24, 24); + neck.setRotationPoint(0F, 0F, 0F); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + neck.render(scale); + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + neck.rotateAngleY = netHeadYaw / 57.29578F; + neck.rotateAngleX = headPitch / 57.29578F; + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFIceCrystal.java b/src/main/java/twilightforest/client/model/entity/ModelTFIceCrystal.java new file mode 100644 index 0000000000..e4c35aa09c --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFIceCrystal.java @@ -0,0 +1,95 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; +import org.lwjgl.opengl.GL11; + +public class ModelTFIceCrystal extends ModelBase { + + public ModelRenderer[] spikes = new ModelRenderer[16]; + + + public ModelTFIceCrystal() { + this.textureWidth = 32; + this.textureHeight = 32; + + float par1 = 0F; + float par2 = 0F; + + // spikes + for (int i = 0; i < spikes.length; i++) { + this.spikes[i] = new ModelRenderer(this, 0, 16); + + int spikeLength = i % 2 == 0 ? 6 : 8; + + this.spikes[i].addBox(-1.0F, -1.0F, -1.0F, 2, spikeLength, 2, par1); + this.spikes[i].setRotationPoint(0.0F, 0.0F + par2, 0.0F); + + ModelRenderer cube = new ModelRenderer(this, 8, 16); + cube.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + cube.setRotationPoint(0.0F, spikeLength, 0.0F); + + cube.rotateAngleZ = (float) (Math.PI / 4F); + + this.spikes[i].addChild(cube); + + } + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + //this.bipedHead.render(scale); + + for (int i = 0; i < spikes.length; i++) { + + if (entity.isEntityAlive()) { + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + GlStateManager.color(1F, 1F, 1F, 0.6F); + } + + this.spikes[i].render(scale); + + GlStateManager.disableBlend(); + } + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + for (int i = 0; i < spikes.length; i++) { + // rotate the spikes + this.spikes[i].rotateAngleX = MathHelper.sin((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + this.spikes[i].rotateAngleY = (entity.ticksExisted + partialTicks) / 5.0F; + this.spikes[i].rotateAngleZ = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + this.spikes[i].rotateAngleX += i * (Math.PI / 8F); + + if (i % 4 == 0) { + this.spikes[i].rotateAngleY += 1; + } else if (i % 4 == 2) { + this.spikes[i].rotateAngleY -= 1; + } + + //this.spikes[i].rotateAngleY += i * (Math.PI / 8F); + //this.spikes[i].rotateAngleZ += i * (Math.PI / 8F); + + +// this.spikes[i].rotationPointX = MathHelper.cos((entity.ticksExisted + partialTicks) / (float)i) * 3F; +// this.spikes[i].rotationPointY = 5F + MathHelper.sin((entity.ticksExisted + partialTicks) / (float)i) * 3F; +// this.spikes[i].rotationPointZ = MathHelper.sin((entity.ticksExisted + partialTicks) / (float)i) * 3F; + + //((ModelRenderer)this.spikes[i].childModels.get(0)).rotationPointY = 10 + MathHelper.sin((i + entity.ticksExisted + partialTicks) / i) * 3F; + + } + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFIceExploder.java b/src/main/java/twilightforest/client/model/entity/ModelTFIceExploder.java new file mode 100644 index 0000000000..b40ec33989 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFIceExploder.java @@ -0,0 +1,99 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; +import org.lwjgl.opengl.GL11; + +public class ModelTFIceExploder extends ModelBiped { + + public ModelRenderer[] spikes = new ModelRenderer[16]; + + + public ModelTFIceExploder() { + this.textureWidth = 32; + this.textureHeight = 32; + + float par1 = 0F; + float par2 = 0F; + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.0F, 0.0F, -4.0F, 8, 8, 8, par1); + this.bipedHead.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + + // delete all other body parts + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + this.bipedBody = new ModelRenderer(this, 0, 0); + this.bipedRightArm = new ModelRenderer(this, 0, 0); + this.bipedLeftArm = new ModelRenderer(this, 0, 0); + this.bipedRightLeg = new ModelRenderer(this, 0, 0); + this.bipedLeftLeg = new ModelRenderer(this, 0, 0); + + // spikes + + for (int i = 0; i < spikes.length; i++) { + this.spikes[i] = new ModelRenderer(this, 0, 16); + + int spikeLength = i % 2 == 0 ? 6 : 8; + + this.spikes[i].addBox(-1.0F, 6.0F, -1.0F, 2, spikeLength, 2, par1); + this.spikes[i].setRotationPoint(0.0F, 4.0F + par2, 0.0F); + + ModelRenderer cube = new ModelRenderer(this, 8, 16); + cube.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + cube.setRotationPoint(0.0F, 8F, 0.0F); + + cube.rotateAngleZ = (float) (Math.PI / 4F); + + this.spikes[i].addChild(cube); + + } + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + this.bipedHead.render(scale); + + for (int i = 0; i < spikes.length; i++) { + + if (entity.isEntityAlive()) { + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + GlStateManager.color(1F, 1F, 1F, 0.6F); + } + + this.spikes[i].render(scale); + + GlStateManager.disableBlend(); + } + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + for (int i = 0; i < spikes.length; i++) { + // rotate the spikes + this.spikes[i].rotateAngleY = (entity.ticksExisted + partialTicks) / 5.0F; + this.spikes[i].rotateAngleX = MathHelper.sin((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + this.spikes[i].rotateAngleZ = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + this.spikes[i].rotateAngleX += i * 5; + this.spikes[i].rotateAngleY += i * 2.5f; + this.spikes[i].rotateAngleZ += i * 3; + + this.spikes[i].rotationPointX = MathHelper.cos((entity.ticksExisted + partialTicks) / (float) i) * 3F; + this.spikes[i].rotationPointY = 5F + MathHelper.sin((entity.ticksExisted + partialTicks) / (float) i) * 3F; + this.spikes[i].rotationPointZ = MathHelper.sin((entity.ticksExisted + partialTicks) / (float) i) * 3F; + + ((ModelRenderer) this.spikes[i].childModels.get(0)).rotationPointY = 10 + MathHelper.sin((i + entity.ticksExisted + partialTicks) / i) * 3F; + + } + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFIceShooter.java b/src/main/java/twilightforest/client/model/entity/ModelTFIceShooter.java new file mode 100644 index 0000000000..10329f4c71 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFIceShooter.java @@ -0,0 +1,33 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; + +public class ModelTFIceShooter extends ModelTFIceExploder { + + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + for (int i = 0; i < spikes.length; i++) { + // rotate the spikes + this.spikes[i].rotateAngleY = (3.14159F / 2F) + (MathHelper.sin((entity.ticksExisted + partialTicks) / 5.0F) * 0.5F); + this.spikes[i].rotateAngleX = (entity.ticksExisted + partialTicks) / 5.0F; + this.spikes[i].rotateAngleZ = MathHelper.cos(i / 5.0F) / 4.0F; + + this.spikes[i].rotateAngleX += i * (Math.PI / 8F); + //this.spikes[i].rotateAngleY += i * 2.5f; + //this.spikes[i].rotateAngleZ += i * 3; + + ((ModelRenderer) this.spikes[i].childModels.get(0)).rotationPointY = 9.5F + MathHelper.sin((i + entity.ticksExisted + partialTicks) / 3F) * 3F; + + + //((ModelBox)this.spikes[i].cubeList.get(0)). = 6 + MathHelper.sin((entity.ticksExisted + partialTicks) / (float)i) * 3F; + + } + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFKnightPhantom.java b/src/main/java/twilightforest/client/model/entity/ModelTFKnightPhantom.java new file mode 100644 index 0000000000..13bd530bdd --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFKnightPhantom.java @@ -0,0 +1,168 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + +@Deprecated +public class ModelTFKnightPhantom extends ModelBiped { + + public ModelRenderer helmet; + public ModelRenderer righthorn1; + public ModelRenderer righthorn2; + public ModelRenderer lefthorn1; + public ModelRenderer lefthorn2; + + @Deprecated + public ModelTFKnightPhantom() { + this.isSneak = false; + this.textureWidth = 128; + this.textureHeight = 64; + +//FIXME: AtomicBlom: Replace with something like LayerCape +/* + this.bipedCloak = new ModelRenderer(this, 0, 0); + this.bipedCloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1); +*/ +//FIXME: AtomicBlom replace with some variant of LayerDeadmau5Head +/* + this.bipedEars = new ModelRenderer(this, 24, 0); + this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1); +*/ + + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(0, 0, 0, 0, 0, 0); + this.bipedHead.setRotationPoint(0.0F, -10.0F, 0.0F); + + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + this.bipedHeadwear.addBox(0, 0, 0, 0, 0, 0); + this.bipedHeadwear.setRotationPoint(0.0F, -10.0F, 0.0F); + + this.helmet = new ModelRenderer(this, 0, 0); + this.helmet.addBox(-4.0F, -11.0F, -4.0F, 8, 11, 8); + this.helmet.rotateAngleY = 45F / (180F / (float) Math.PI); + + this.righthorn1 = new ModelRenderer(this, 28, 0); + this.righthorn1.addBox(-6F, -1.5F, -1.5F, 7, 3, 3); + this.righthorn1.setRotationPoint(-3.5F, -9F, 0.0F); + this.righthorn1.rotateAngleY = 15F / (180F / (float) Math.PI); + this.righthorn1.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn2 = new ModelRenderer(this, 28, 6); + this.righthorn2.addBox(-3.0F, -1.0F, -1.0F, 3, 2, 2); + this.righthorn2.setRotationPoint(-5.5F, 0.0F, 0.0F); + this.righthorn2.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn1.addChild(righthorn2); + + this.lefthorn1 = new ModelRenderer(this, 28, 0); + this.lefthorn1.mirror = true; + this.lefthorn1.addBox(-1F, -1.5F, -1.5F, 7, 3, 3); + this.lefthorn1.setRotationPoint(3.5F, -9F, 0.0F); + this.lefthorn1.rotateAngleY = -15F / (180F / (float) Math.PI); + this.lefthorn1.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn2 = new ModelRenderer(this, 28, 6); + this.lefthorn2.addBox(0.0F, -1.0F, -1.0F, 3, 2, 2); + this.lefthorn2.setRotationPoint(5.5F, 0.0F, 0.0F); + this.lefthorn2.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn1.addChild(lefthorn2); + + this.bipedHeadwear.addChild(helmet); + this.bipedHeadwear.addChild(righthorn1); + this.bipedHeadwear.addChild(lefthorn1); + + this.bipedBody = new ModelRenderer(this, 0, 18); + this.bipedBody.setRotationPoint(0.0F, 2.0F, 0.0F); + this.bipedBody.addBox(-7.0F, -12.0F, -3.5F, 14, 12, 7); + this.bipedBody.setTextureOffset(30, 24).addBox(-6.0F, 0F, -3F, 12, 8, 6); // torso + + this.bipedRightArm = new ModelRenderer(this, 44, 16); + this.bipedRightArm.addBox(-5.0F, -2.0F, -3.0F, 6, 7, 6); + this.bipedRightArm.setRotationPoint(-8.0F, -8.0F, 0.0F); + + this.bipedLeftArm = new ModelRenderer(this, 44, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -3.0F, 6, 7, 6); + this.bipedLeftArm.setRotationPoint(8.0F, -8.0F, 0.0F); + + this.bipedRightLeg = new ModelRenderer(this, 0, 0); + this.bipedRightLeg.addBox(0, 0, 0, 0, 0, 0); + this.bipedRightLeg.setRotationPoint(0.0F, 12.0F, 0.0F); + + this.bipedLeftLeg = new ModelRenderer(this, 0, 0); + this.bipedLeftLeg.addBox(0, 0, 0, 0, 0, 0); + this.bipedLeftLeg.setRotationPoint(0.0F, 12.0F, 0.0F); + + + } + + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.bipedHead.rotateAngleZ = 0; + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedHeadwear.rotateAngleZ = this.bipedHead.rotateAngleZ; + + + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + + +// this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; +// this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float)Math.PI) * 1.4F * limbSwingAmount; +// this.bipedRightLeg.rotateAngleY = 0.0F; +// this.bipedLeftLeg.rotateAngleY = 0.0F; +// +// if (this.isRiding) +// { +// this.bipedRightArm.rotateAngleX += -((float)Math.PI / 5F); +// this.bipedLeftArm.rotateAngleX += -((float)Math.PI / 5F); +// this.bipedRightLeg.rotateAngleX = 0; +// this.bipedLeftLeg.rotateAngleX = 0; +//// this.bipedRightLeg.rotateAngleY = ((float)Math.PI / 10F); +//// this.bipedLeftLeg.rotateAngleY = -((float)Math.PI / 10F); +// } + + if (this.leftArmPose != ArmPose.EMPTY) { + this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + this.rightArmPose = ArmPose.ITEM; + + if (this.rightArmPose != ArmPose.EMPTY) { + this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } +// +// bipedRightArm.rotateAngleX -= (Math.PI * 0.66); +// +// // during swing move arm forward +// if (upperKnight.heavySpearTimer > 0) +// { +// bipedRightArm.rotateAngleX -= this.getArmRotationDuringSwing(60 - upperKnight.heavySpearTimer + scaleFactor) / (180F / (float)Math.PI); +// } + +// this.bipedRightArm.rotateAngleY = 0.0F; +// this.bipedLeftArm.rotateAngleY = 0.0F; + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFKnightPhantom2.java b/src/main/java/twilightforest/client/model/entity/ModelTFKnightPhantom2.java new file mode 100644 index 0000000000..5d3f500c77 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFKnightPhantom2.java @@ -0,0 +1,69 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.boss.EntityTFKnightPhantom; + +public class ModelTFKnightPhantom2 extends ModelBiped { + + public ModelTFKnightPhantom2() { + this(0.0F); + } + + public ModelTFKnightPhantom2(float scale) { + super(scale, 0.0F, 64, 32); + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, scale); + this.bipedRightArm.setRotationPoint(-5.0F, 2.0F, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 40, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, scale); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + this.bipedRightLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, scale); + this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, scale); + this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + if (((EntityTFKnightPhantom) entity).isChargingAtPlayer()) { + // render full skeleton + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + } + } + + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + this.bipedLeftLeg.rotateAngleX = 0; + this.bipedLeftLeg.rotateAngleY = 0; + this.bipedLeftLeg.rotateAngleZ = 0; + + this.bipedRightLeg.rotateAngleX = 0; + this.bipedRightLeg.rotateAngleY = 0; + this.bipedRightLeg.rotateAngleZ = 0; + + this.bipedRightLeg.rotateAngleX = 0.2F * MathHelper.sin(ageInTicks * 0.3F) + 0.4F; + this.bipedLeftLeg.rotateAngleX = 0.2F * MathHelper.sin(ageInTicks * 0.3F) + 0.4F; + + + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFKobold.java b/src/main/java/twilightforest/client/model/entity/ModelTFKobold.java new file mode 100644 index 0000000000..0a6cadce79 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFKobold.java @@ -0,0 +1,137 @@ +// Date: 6/11/2012 3:12:45 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; + +public class ModelTFKobold extends ModelBiped { + //fields + + ModelRenderer rightear; + ModelRenderer leftear; + ModelRenderer snout; + ModelRenderer jaw; + + boolean isJumping; + + public ModelTFKobold() { + isJumping = false; + + textureWidth = 64; + textureHeight = 32; + + bipedHead = new ModelRenderer(this, 0, 0); + bipedHead.addBox(-3.5F, -7F, -3F, 7, 6, 6); + bipedHead.setRotationPoint(0F, 13F, 0F); + + bipedBody = new ModelRenderer(this, 12, 19); + bipedBody.addBox(0F, 0F, 0F, 7, 7, 4); + bipedBody.setRotationPoint(-3.5F, 12F, -2F); + + bipedRightArm = new ModelRenderer(this, 36, 17); + bipedRightArm.addBox(-3F, -1F, -1.5F, 3, 7, 3); + bipedRightArm.setRotationPoint(-3.5F, 12F, 0F); + + bipedLeftArm.mirror = true; + bipedLeftArm = new ModelRenderer(this, 36, 17); + bipedLeftArm.addBox(0F, -1F, -1.5F, 3, 7, 3); + bipedLeftArm.setRotationPoint(3.5F, 12F, 0F); + + bipedLeftArm.mirror = false; + bipedRightLeg = new ModelRenderer(this, 0, 20); + bipedRightLeg.addBox(-1.5F, 0F, -1.5F, 3, 5, 3); + bipedRightLeg.setRotationPoint(-2F, 19F, 0F); + + bipedLeftLeg = new ModelRenderer(this, 0, 20); + bipedLeftLeg.addBox(-1.5F, 0F, -1.5F, 3, 5, 3); + bipedLeftLeg.setRotationPoint(2F, 19F, 0F); + + rightear = new ModelRenderer(this, 48, 20); + rightear.addBox(0F, -4F, 0F, 4, 4, 1); + rightear.setRotationPoint(3.5F, -3F, -1F); + rightear.rotateAngleY = 0.2617994F; + rightear.rotateAngleZ = -0.3490659F; + + bipedHead.addChild(rightear); + + leftear = new ModelRenderer(this, 48, 25); + leftear.addBox(-4F, -4F, 0F, 4, 4, 1); + leftear.setRotationPoint(-3.5F, -3F, -1F); + leftear.rotateAngleY = -0.2617994F; + leftear.rotateAngleZ = 0.3490659F; + + bipedHead.addChild(leftear); + + + snout = new ModelRenderer(this, 28, 0); + snout.addBox(-1.5F, -2F, -2F, 3, 2, 3); + snout.setRotationPoint(0F, -2F, -3F); + + bipedHead.addChild(snout); + + jaw = new ModelRenderer(this, 28, 5); + jaw.addBox(-1.5F, 0F, -2F, 3, 1, 3); + jaw.setRotationPoint(0F, -2F, -3F); + jaw.rotateAngleX = 0.20944F; + + bipedHead.addChild(jaw); + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + + this.bipedRightArm.rotateAngleX = -((float) Math.PI * .15F); + this.bipedLeftArm.rotateAngleX = -((float) Math.PI * .15F); + + + this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.19F) * 0.15F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.19F) * 0.15F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.267F) * 0.25F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.267F) * 0.25F; + + if (this.isJumping) { + // open jaw + this.jaw.rotateAngleX = 1.44F; + } else { + this.jaw.rotateAngleX = 0.20944F; + } + } + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + // check if entity is jumping + this.isJumping = entity.motionY > 0; + } + + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + bipedHead.render(scale); + bipedBody.render(scale); + bipedRightArm.render(scale); + bipedLeftArm.render(scale); + bipedRightLeg.render(scale); + bipedLeftLeg.render(scale); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFLich.java b/src/main/java/twilightforest/client/model/entity/ModelTFLich.java new file mode 100644 index 0000000000..531b778a86 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFLich.java @@ -0,0 +1,118 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import org.lwjgl.opengl.GL11; +import twilightforest.entity.boss.EntityTFLich; + +import javax.annotation.Nonnull; + +public class ModelTFLich extends ModelBiped { + private final ModelRenderer collar; + private final ModelRenderer cloak; + + public ModelTFLich() { + textureWidth = 64; + textureHeight = 64; + + + bipedBody = new ModelRenderer(this, 8, 16); + bipedBody.addBox(-4F, 0.0F, -2F, 8, 24, 4); + bipedBody.setRotationPoint(0.0F, -4.0F, 0.0F); + bipedBody.setTextureSize(64, 64); + + bipedRightArm = new ModelRenderer(this, 0, 16); + bipedRightArm.addBox(-2F, -2F, -1F, 2, 12, 2); + bipedRightArm.setTextureSize(64, 64); + bipedRightArm.setRotationPoint(-5F, -2.0F, 0.0F); + + bipedLeftArm = new ModelRenderer(this, 0, 16); + bipedLeftArm.mirror = true; + bipedLeftArm.addBox(-2F, -2F, -1F, 2, 12, 2); + bipedLeftArm.setRotationPoint(5F, -2.0F, 0.0F); + bipedLeftArm.setTextureSize(64, 64); + + bipedHeadwear = new ModelRenderer(this, 32, 0); + bipedHeadwear.addBox(-4F, -12F, -4F, 8, 8, 8, 0.5F); + bipedHeadwear.setRotationPoint(0.0F, -4.0F, 0.0F); + bipedHeadwear.setTextureSize(64, 64); + + bipedHead = new ModelRenderer(this, 0, 0); + bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8); + bipedHead.setRotationPoint(0F, -4F, 0F); + bipedHead.setTextureSize(64, 64); + + bipedRightLeg = new ModelRenderer(this, 0, 16); + bipedRightLeg.addBox(-1F, 0F, -1F, 2, 12, 2); + bipedRightLeg.setRotationPoint(-2F, 9.5F, 0F); + bipedRightLeg.setTextureSize(64, 64); + + bipedLeftLeg = new ModelRenderer(this, 0, 16); + bipedLeftLeg.addBox(-1F, 0F, -1F, 2, 12, 2); + bipedLeftLeg.setRotationPoint(2F, 9.5F, 0F); + bipedLeftLeg.setTextureSize(64, 64); + bipedLeftLeg.mirror = true; + + collar = new ModelRenderer(this, 32, 16); + collar.addBox(-6F, 0F, 0F, 12, 12, 1); + collar.setRotationPoint(0F, -3F, -1F); + collar.setTextureSize(64, 64); + setRotation(collar, 2.164208F, 0F, 0F); + + + cloak = new ModelRenderer(this, 0, 44); + cloak.addBox(-6F, 0F, 0F, 12, 19, 1); + cloak.setRotationPoint(0F, -4F, 2.5F); + cloak.setTextureSize(64, 64); + setRotation(cloak, 0F, 0F, 0F); + } + + @Override + public void render(@Nonnull Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + if (!((EntityTFLich) entity).isShadowClone()) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + collar.render(scale * 1.125F); + cloak.render(scale * 1.125F); + } else { + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + float shadow = 0.33f; + GlStateManager.color(shadow, shadow, shadow, 0.8F); + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + GlStateManager.disableBlend(); + } + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + float ogSin = MathHelper.sin(swingProgress * 3.141593F); + float otherSin = MathHelper.sin((1.0F - (1.0F - swingProgress) * (1.0F - swingProgress)) * 3.141593F); + bipedRightArm.rotateAngleZ = 0.0F; + bipedLeftArm.rotateAngleZ = 0.5F; + bipedRightArm.rotateAngleY = -(0.1F - ogSin * 0.6F); + bipedLeftArm.rotateAngleY = 0.1F - ogSin * 0.6F; + bipedRightArm.rotateAngleX = -1.570796F; + bipedLeftArm.rotateAngleX = -3.141593F; + bipedRightArm.rotateAngleX -= ogSin * 1.2F - otherSin * 0.4F; + bipedLeftArm.rotateAngleX -= ogSin * 1.2F - otherSin * 0.4F; + bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.26F) * 0.15F + 0.05F; + bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.26F) * 0.15F + 0.05F; + bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.167F) * 0.15F; + bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.167F) * 0.15F; + + bipedHead.rotationPointY = -4.0F; + bipedHeadwear.rotationPointY = -4.0F; + bipedRightLeg.rotationPointY = 9.5F; + bipedLeftLeg.rotationPointY = 9.5F; + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFLichMinion.java b/src/main/java/twilightforest/client/model/entity/ModelTFLichMinion.java new file mode 100644 index 0000000000..7b8b8eb5a7 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFLichMinion.java @@ -0,0 +1,36 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelZombie; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import twilightforest.entity.boss.EntityTFLichMinion; + +public class ModelTFLichMinion extends ModelZombie { + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + EntityTFLichMinion minion = (EntityTFLichMinion) entity; + // make strong minions greener + if (minion.isStrong()) { + GlStateManager.color(0.25F, 2.0F, 0.25F); + } else { + GlStateManager.color(0.5F, 1.0F, 0.5F); + } + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + EntityTFLichMinion minion = (EntityTFLichMinion) entity; + // make strong minions bigger FIXME: actually do this? + if (minion.isStrong()) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + } else { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + } + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFLoyalZombie.java b/src/main/java/twilightforest/client/model/entity/ModelTFLoyalZombie.java new file mode 100644 index 0000000000..967fe2957a --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFLoyalZombie.java @@ -0,0 +1,15 @@ +package twilightforest.client.model.entity; + + +import net.minecraft.client.model.ModelZombie; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; + +public class ModelTFLoyalZombie extends ModelZombie { + @Override + public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + // GREEEEN + GlStateManager.color(0.25F, 2.0F, 0.25F); + super.render(entityIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFMinoshroom.java b/src/main/java/twilightforest/client/model/entity/ModelTFMinoshroom.java new file mode 100644 index 0000000000..6279eabfcb --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFMinoshroom.java @@ -0,0 +1,234 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumHandSide; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.boss.EntityTFMinoshroom; + +public class ModelTFMinoshroom extends ModelBiped { + + ModelRenderer body; + ModelRenderer leg1; + ModelRenderer leg2; + ModelRenderer leg3; + ModelRenderer leg4; + ModelRenderer udders; + + ModelRenderer snout; + + public ModelRenderer righthorn1; + public ModelRenderer righthorn2; + public ModelRenderer lefthorn1; + public ModelRenderer lefthorn2; + + public ModelTFMinoshroom() { + textureWidth = 128; + textureHeight = 32; + + bipedHead = new ModelRenderer(this, 96, 16); + bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8); + bipedHead.setRotationPoint(0F, -6F, -9F); + + body = new ModelRenderer(this, 18, 4); + body.addBox(-6F, -10F, -7F, 12, 18, 10); + body.setRotationPoint(0F, 5F, 2F); + setRotation(body, 1.570796F, 0F, 0F); + + leg1 = new ModelRenderer(this, 0, 16); + leg1.addBox(-3F, 0F, -2F, 4, 12, 4); + leg1.setRotationPoint(-3F, 12F, 7F); + + leg2 = new ModelRenderer(this, 0, 16); + leg2.addBox(-1F, 0F, -2F, 4, 12, 4); + leg2.setRotationPoint(3F, 12F, 7F); + + leg3 = new ModelRenderer(this, 0, 16); + leg3.addBox(-3F, 0F, -3F, 4, 12, 4); + leg3.setRotationPoint(-3F, 12F, -5F); + + leg4 = new ModelRenderer(this, 0, 16); + leg4.addBox(-1F, 0F, -3F, 4, 12, 4); + leg4.setRotationPoint(3F, 12F, -5F); + + udders = new ModelRenderer(this, 52, 0); + udders.addBox(-2F, -3F, 0F, 4, 6, 2); + udders.setRotationPoint(0F, 14F, 6F); + setRotation(udders, 1.570796F, 0F, 0F); + + bipedBody = new ModelRenderer(this, 64, 0); + bipedBody.addBox(-4F, 0F, -2.5F, 8, 12, 5); + bipedBody.setRotationPoint(0F, -6F, -9F); + + this.bipedLeftArm = new ModelRenderer(this, 90, 0); + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4); + this.bipedLeftArm.setRotationPoint(5F, -4F, -9F); + this.bipedLeftArm.mirror = true; + + this.bipedRightArm = new ModelRenderer(this, 90, 0); + this.bipedRightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4); + this.bipedRightArm.setRotationPoint(-5F, -4F, -9F); + + // horns + this.righthorn1 = new ModelRenderer(this, 0, 0); + this.righthorn1.addBox(-5.5F, -1.5F, -1.5F, 5, 3, 3); + this.righthorn1.setRotationPoint(-2.5F, -6.5F, 0.0F); + this.righthorn1.rotateAngleY = -25F / (180F / (float) Math.PI); + this.righthorn1.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn2 = new ModelRenderer(this, 16, 0); + this.righthorn2.addBox(-3.5F, -1.0F, -1.0F, 3, 2, 2); + this.righthorn2.setRotationPoint(-4.5F, 0.0F, 0.0F); + this.righthorn2.rotateAngleY = -15F / (180F / (float) Math.PI); + this.righthorn2.rotateAngleZ = 45F / (180F / (float) Math.PI); + + this.righthorn1.addChild(righthorn2); + + this.lefthorn1 = new ModelRenderer(this, 0, 0); + this.lefthorn1.mirror = true; + this.lefthorn1.addBox(0.5F, -1.5F, -1.5F, 5, 3, 3); + this.lefthorn1.setRotationPoint(2.5F, -6.5F, 0.0F); + this.lefthorn1.rotateAngleY = 25F / (180F / (float) Math.PI); + this.lefthorn1.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn2 = new ModelRenderer(this, 16, 0); + this.lefthorn2.addBox(0.5F, -1.0F, -1.0F, 3, 2, 2); + this.lefthorn2.setRotationPoint(4.5F, 0.0F, 0.0F); + this.lefthorn2.rotateAngleY = 15F / (180F / (float) Math.PI); + this.lefthorn2.rotateAngleZ = -45F / (180F / (float) Math.PI); + + this.lefthorn1.addChild(lefthorn2); + + this.bipedHead.addChild(righthorn1); + this.bipedHead.addChild(lefthorn1); + + snout = new ModelRenderer(this, 105, 28); + snout.addBox(-2, -1, -1, 4, 3, 1); + snout.setRotationPoint(0F, -2.0F, -4F); + + this.bipedHead.addChild(snout); + + // kill off headwear box + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + //super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + bipedHead.render(scale); + body.render(scale); + leg1.render(scale); + leg2.render(scale); + leg3.render(scale); + leg4.render(scale); + udders.render(scale); + + bipedBody.render(scale); + bipedLeftArm.render(scale); + bipedRightArm.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + // copied from ModelBiped + + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + + this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + if (this.leftArmPose != ArmPose.EMPTY) { + this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + if (this.rightArmPose != ArmPose.EMPTY) { + this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + + float var7 = 0.0F; + float var8 = 0.0F; + + if (this.leftArmPose == ArmPose.BOW_AND_ARROW) { + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.1F - var7 * 0.6F + this.bipedHead.rotateAngleY + 0.4F; + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F) + this.bipedHead.rotateAngleX; + this.bipedLeftArm.rotateAngleX -= var7 * 1.2F - var8 * 0.4F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + } + + if (this.rightArmPose == ArmPose.BOW_AND_ARROW) { + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - var7 * 0.6F) + this.bipedHead.rotateAngleY; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F) + this.bipedHead.rotateAngleX; + this.bipedRightArm.rotateAngleX -= var7 * 1.2F - var8 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + } + + // copied from ModelQuadruped + this.body.rotateAngleX = ((float) Math.PI / 2F); + this.leg1.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.leg2.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.leg3.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.leg4.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + + float f = ageInTicks - (float) entity.ticksExisted; + float f1 = ((EntityTFMinoshroom) entity).getChargeAnimationScale(f); + f1 = f1 * f1; + float f2 = 1.0F - f1; + if (f1 > 0) { + + if (((EntityLivingBase)entity).getPrimaryHand() == EnumHandSide.RIGHT) + { + this.bipedRightArm.rotateAngleX = f1 * -1.8F; + this.bipedLeftArm.rotateAngleX = 0.0F; + this.bipedRightArm.rotateAngleZ = -0.2F; + } else { + this.bipedRightArm.rotateAngleX = 0.0F; + this.bipedLeftArm.rotateAngleX = f1 * -1.8F; + this.bipedLeftArm.rotateAngleZ = 0.2F; + } + this.body.rotateAngleX = ((float) Math.PI / 2F) - f1 * (float) Math.PI * 0.2F; + this.leg3.rotationPointY = 12.0F + (-5.8F * f1); + this.leg3.rotationPointZ = -4.0F + (-5.8F * f1); + this.leg3.rotateAngleX -= f1 * (float) Math.PI * 0.3F; + + this.leg4.rotationPointY = this.leg3.rotationPointY; + this.leg4.rotationPointZ = this.leg3.rotationPointZ; + this.leg4.rotateAngleX -= f1 * (float) Math.PI * 0.3F; + this.bipedBody.rotationPointY = -6F + -3.0F * f1; + } + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFMinotaur.java b/src/main/java/twilightforest/client/model/entity/ModelTFMinotaur.java new file mode 100644 index 0000000000..56464cda79 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFMinotaur.java @@ -0,0 +1,60 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; + +public class ModelTFMinotaur extends ModelBiped { + + public ModelRenderer righthorn1; + public ModelRenderer righthorn2; + public ModelRenderer lefthorn1; + public ModelRenderer lefthorn2; + + ModelRenderer snout; + + public ModelTFMinotaur() { + + this.righthorn1 = new ModelRenderer(this, 24, 0); + this.righthorn1.addBox(-5.5F, -1.5F, -1.5F, 5, 3, 3); + this.righthorn1.setRotationPoint(-2.5F, -6.5F, 0.0F); + this.righthorn1.rotateAngleY = -25F / (180F / (float) Math.PI); + this.righthorn1.rotateAngleZ = 10F / (180F / (float) Math.PI); + + this.righthorn2 = new ModelRenderer(this, 40, 0); + this.righthorn2.addBox(-3.5F, -1.0F, -1.0F, 3, 2, 2); + this.righthorn2.setRotationPoint(-4.5F, 0.0F, 0.0F); + this.righthorn2.rotateAngleY = -15F / (180F / (float) Math.PI); + this.righthorn2.rotateAngleZ = 45F / (180F / (float) Math.PI); + + this.righthorn1.addChild(righthorn2); + + this.lefthorn1 = new ModelRenderer(this, 24, 0); + this.lefthorn1.mirror = true; + this.lefthorn1.addBox(0.5F, -1.5F, -1.5F, 5, 3, 3); + this.lefthorn1.setRotationPoint(2.5F, -6.5F, 0.0F); + this.lefthorn1.rotateAngleY = 25F / (180F / (float) Math.PI); + this.lefthorn1.rotateAngleZ = -10F / (180F / (float) Math.PI); + + this.lefthorn2 = new ModelRenderer(this, 40, 0); + this.lefthorn2.addBox(0.5F, -1.0F, -1.0F, 3, 2, 2); + this.lefthorn2.setRotationPoint(4.5F, 0.0F, 0.0F); + this.lefthorn2.rotateAngleY = 15F / (180F / (float) Math.PI); + this.lefthorn2.rotateAngleZ = -45F / (180F / (float) Math.PI); + + this.lefthorn1.addChild(lefthorn2); + + this.bipedHead.addChild(righthorn1); + this.bipedHead.addChild(lefthorn1); + + snout = new ModelRenderer(this, 9, 12); + snout.addBox(-2, -1, -1, 4, 3, 1); + snout.setRotationPoint(0F, -2.0F, -4F); + + this.bipedHead.addChild(snout); + + // kill off headwear box + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFMoonworm.java b/src/main/java/twilightforest/client/model/entity/ModelTFMoonworm.java new file mode 100644 index 0000000000..fa1097fef3 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFMoonworm.java @@ -0,0 +1,94 @@ +// Date: 11/8/2012 9:54:59 AM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.client.BugModelAnimationHelper; +import twilightforest.tileentity.critters.TileEntityTFMoonwormTicking; + +import javax.annotation.Nullable; + +public class ModelTFMoonworm extends ModelBase { + //fields + ModelRenderer Shape1; + ModelRenderer Shape2; + ModelRenderer Shape3; + ModelRenderer head; + + public ModelTFMoonworm() { + textureWidth = 32; + textureHeight = 32; + + Shape1 = new ModelRenderer(this, 0, 4); + Shape1.addBox(-1F, -1F, -1F, 4, 2, 2); + Shape1.setRotationPoint(-1F, 7F, 3F); + + Shape2 = new ModelRenderer(this, 0, 8); + Shape2.addBox(-1F, -1F, -1F, 2, 2, 4); + Shape2.setRotationPoint(3F, 7F, 0F); + + Shape3 = new ModelRenderer(this, 0, 14); + Shape3.addBox(-1F, -1F, -1F, 2, 2, 2); + Shape3.setRotationPoint(2F, 7F, -2F); + + head = new ModelRenderer(this, 0, 0); + head.addBox(-1F, -1F, -1F, 2, 2, 2); + head.setRotationPoint(-3F, 7F, 2F); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + Shape1.render(scale); + Shape2.render(scale); + Shape3.render(scale); + head.render(scale); + } + + public void render(float scale) { + Shape1.render(scale); + Shape2.render(scale); + Shape3.render(scale); + head.render(scale); + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + } + + public void setLivingAnimations(@Nullable TileEntityTFMoonwormTicking moonworm, float partialTime) { + + head.rotationPointY = 7F; + Shape1.rotationPointY = 7F; + Shape2.rotationPointY = 7F; + Shape3.rotationPointY = 7F; + + if (moonworm != null && moonworm.yawDelay == 0) { + float time = (moonworm.desiredYaw - moonworm.currentYaw) - partialTime; + + // moving + head.rotationPointY += Math.min(0, MathHelper.sin(time / 2)); + Shape1.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 1)); + Shape2.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 2)); + Shape3.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 3)); + } else if (moonworm == null && BugModelAnimationHelper.yawWriggleDelay == 0) { + float time = (BugModelAnimationHelper.desiredRotation - BugModelAnimationHelper.currentRotation) - partialTime; + + // moving + head.rotationPointY += Math.min(0, MathHelper.sin(time / 2)); + Shape1.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 1)); + Shape2.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 2)); + Shape3.rotationPointY += Math.min(0, MathHelper.sin(time / 2 + 3)); + } + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFMosquitoSwarm.java b/src/main/java/twilightforest/client/model/entity/ModelTFMosquitoSwarm.java new file mode 100644 index 0000000000..c4ab4fac6c --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFMosquitoSwarm.java @@ -0,0 +1,132 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +import java.util.Random; + +public class ModelTFMosquitoSwarm extends ModelBase { + + ModelRenderer core; + ModelRenderer node1; + ModelRenderer node2; + ModelRenderer node3; + ModelRenderer node4; + ModelRenderer node5; + ModelRenderer node6; + + Random rand = new Random(); + + public ModelTFMosquitoSwarm() { + core = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + core.addBox(-4F, 0.0F, -2F, 1, 1, 1); + core.setRotationPoint(0.0F, -4.0F, 0.0F); + + node1 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + node1.addBox(-5.5F, -5F, -13F, 1, 1, 1); + node1.setRotationPoint(2F, -1F, -6F); + core.addChild(node1); + + node2 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + node2.addBox(-5.5F, -13F, -5F, 1, 1, 1); + node2.setRotationPoint(0F, -7F, -1F); + core.addChild(node2); + + node3 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + node3.addBox(-13F, -5F, -5F, 1, 1, 1); + node3.setRotationPoint(5F, -2F, -1F); + core.addChild(node3); + + node4 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + node4.addBox(-5.5F, -5F, -13F, 1, 1, 1); + node4.setRotationPoint(2F, -1F, -6F); + core.addChild(node4); + + node5 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + node5.addBox(-5.5F, -13F, -5F, 1, 1, 1); + node5.setRotationPoint(0F, -7F, -1F); + core.addChild(node5); + + node6 = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + node6.addBox(-13F, -5F, -5F, 1, 1, 1); + node6.setRotationPoint(5F, -2F, -1F); + core.addChild(node6); + + addBugsToNodes(node1); + addBugsToNodes(node2); + addBugsToNodes(node3); + addBugsToNodes(node4); + addBugsToNodes(node5); + addBugsToNodes(node6); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + core.render(scale / 2.0F); +// node1.render(scale); +// node2.render(scale); +// node3.render(scale); + } + + /** + * Add the proper number of mosquitoes to the nodes + */ + public void addBugsToNodes(ModelRenderer node) { + int bugs = 16; + + for (int i = 0; i < bugs; i++) { + Vec3d vec = new Vec3d(11, 0, 0); + float rotateY = ((i * (360F / bugs)) * 3.141593F) / 180F; + vec.rotateYaw(rotateY); + ModelRenderer bug = new ModelRenderer(this, rand.nextInt(28), rand.nextInt(28)); + + float bugX = (rand.nextFloat() - rand.nextFloat()) * 4.0f; + float bugY = (rand.nextFloat() - rand.nextFloat()) * 4.0f; + float bugZ = (rand.nextFloat() - rand.nextFloat()) * 4.0f; + + bug.addBox(bugX, bugY, bugZ, 1, 1, 1); + + bug.setRotationPoint((float) vec.x, (float) vec.y, (float) vec.z); + bug.rotateAngleY = rotateY; + node.addChild(bug); + } + } + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + core.rotateAngleY = (entity.ticksExisted + partialTicks) / 5.0F; + core.rotateAngleX = MathHelper.sin((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + core.rotateAngleZ = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + node1.rotateAngleY = (entity.ticksExisted + partialTicks) / 2.0F; + node1.rotateAngleX = MathHelper.sin((entity.ticksExisted + partialTicks) / 6.0F) / 2.0F; + node1.rotateAngleZ = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + node2.rotateAngleY = MathHelper.sin((entity.ticksExisted + partialTicks) / 2.0F) / 3.0F; + node2.rotateAngleX = (entity.ticksExisted + partialTicks) / 5.0F; + node2.rotateAngleZ = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + node3.rotateAngleY = MathHelper.sin((entity.ticksExisted + partialTicks) / 7.0F) / 3.0F; + node3.rotateAngleX = MathHelper.cos((entity.ticksExisted + partialTicks) / 4.0F) / 2.0F; + node3.rotateAngleZ = (entity.ticksExisted + partialTicks) / 5.0F; + + node4.rotateAngleX = (entity.ticksExisted + partialTicks) / 2.0F; + node4.rotateAngleZ = MathHelper.sin((entity.ticksExisted + partialTicks) / 6.0F) / 2.0F; + node4.rotateAngleY = MathHelper.sin((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + node5.rotateAngleZ = MathHelper.sin((entity.ticksExisted + partialTicks) / 2.0F) / 3.0F; + node5.rotateAngleY = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + node5.rotateAngleX = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + node6.rotateAngleZ = MathHelper.cos((entity.ticksExisted + partialTicks) / 7.0F) / 3.0F; + node6.rotateAngleX = MathHelper.cos((entity.ticksExisted + partialTicks) / 4.0F) / 2.0F; + node6.rotateAngleY = (entity.ticksExisted + partialTicks) / 5.0F; + + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFNaga.java b/src/main/java/twilightforest/client/model/entity/ModelTFNaga.java new file mode 100644 index 0000000000..74a8bdb242 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFNaga.java @@ -0,0 +1,39 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import twilightforest.entity.boss.EntityTFNaga; +import twilightforest.entity.boss.EntityTFNagaSegment; + + +public class ModelTFNaga extends ModelBase { + public ModelTFNaga() { + head = new ModelRenderer(this, 0, 0); + head.addBox(-8F, -12F, -8F, 16, 16, 16, 0F); + head.setRotationPoint(0F, 0F, 0F); + + body = new ModelRenderer(this, 0, 0); + body.addBox(-8F, -16F, -8F, 16, 16, 16, 0F); + body.setRotationPoint(0F, 0F, 0F); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + if (entity instanceof EntityTFNaga) { + head.render(scale * 2); + } else if (entity instanceof EntityTFNagaSegment) { + body.render(scale * 2); + } else { + head.render(scale * 2); + } + + } + + //fields + public ModelRenderer head; + public ModelRenderer body; +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFPenguin.java b/src/main/java/twilightforest/client/model/entity/ModelTFPenguin.java new file mode 100644 index 0000000000..5e62ec4768 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFPenguin.java @@ -0,0 +1,114 @@ +// Date: 3/3/2012 11:56:45 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + +public class ModelTFPenguin extends ModelBase { + //fields + ModelRenderer body; + ModelRenderer rightarm; + ModelRenderer leftarm; + ModelRenderer rightleg; + ModelRenderer leftleg; + ModelRenderer head; + ModelRenderer beak; + + public ModelTFPenguin() { + textureWidth = 64; + textureHeight = 32; + + body = new ModelRenderer(this, 32, 0); + body.addBox(-4F, 0F, -4F, 8, 9, 8); + body.setRotationPoint(0F, 14F, 0F); + + rightarm = new ModelRenderer(this, 34, 18); + rightarm.addBox(-1F, -1F, -2F, 1, 8, 4); + rightarm.setRotationPoint(-4F, 15F, 0F); + + leftarm = new ModelRenderer(this, 24, 18); + leftarm.addBox(0F, -1F, -2F, 1, 8, 4); + leftarm.setRotationPoint(4F, 15F, 0F); + + leftarm.mirror = true; + + + rightleg = new ModelRenderer(this, 0, 16); + rightleg.addBox(-2F, 0F, -5F, 4, 1, 8); + rightleg.setRotationPoint(-2F, 23F, 0F); + rightleg.setTextureSize(64, 32); + + leftleg = new ModelRenderer(this, 0, 16); + leftleg.addBox(-2F, 0F, -5F, 4, 1, 8); + leftleg.setRotationPoint(2F, 23F, 0F); + + + head = new ModelRenderer(this, 0, 0); + head.addBox(-3.5F, -4F, -3.5F, 7, 5, 7); + head.setRotationPoint(0F, 13F, 0F); + + beak = new ModelRenderer(this, 0, 13); + beak.addBox(-1F, 0F, -1F, 2, 1, 2); + beak.setRotationPoint(0F, -1F, -4F); + + head.addChild(beak); + + } + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + if (isChild) { + float f = 2.0F; + GlStateManager.pushMatrix(); + GlStateManager.translate(0.0F, 5F * scale, 0.75F * scale); + head.render(scale); + GlStateManager.popMatrix(); + GlStateManager.pushMatrix(); + GlStateManager.scale(1.0F / f, 1.0F / f, 1.0F / f); + GlStateManager.translate(0.0F, 24F * scale, 0.0F); + body.render(scale); + rightleg.render(scale); + leftleg.render(scale); + rightarm.render(scale); + leftarm.render(scale); + GlStateManager.popMatrix(); + } else { + head.render(scale); + body.render(scale); + rightleg.render(scale); + leftleg.render(scale); + rightarm.render(scale); + leftarm.render(scale); + } + } + + /** + * Sets the models various rotation angles. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + head.rotateAngleX = headPitch / (180F / (float) Math.PI); + head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + + rightleg.rotateAngleX = MathHelper.cos(limbSwing) * 0.7F * limbSwingAmount; + leftleg.rotateAngleX = MathHelper.cos(limbSwing + (float) Math.PI) * 0.7F * limbSwingAmount; + + rightarm.rotateAngleZ = ageInTicks; + leftarm.rotateAngleZ = -ageInTicks; + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFPinchBeetle.java b/src/main/java/twilightforest/client/model/entity/ModelTFPinchBeetle.java new file mode 100644 index 0000000000..87f4c36120 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFPinchBeetle.java @@ -0,0 +1,280 @@ +// Date: 11/5/2012 7:35:56 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.EntityTFPinchBeetle; + +public class ModelTFPinchBeetle extends ModelBase { + //fields + ModelRenderer thorax; + ModelRenderer head; + ModelRenderer connector2; + ModelRenderer RearEnd; + ModelRenderer Leg6; + ModelRenderer Leg4; + ModelRenderer Leg2; + ModelRenderer Leg5; + ModelRenderer Leg3; + ModelRenderer Leg1; + ModelRenderer connector1; + ModelRenderer jaw1a; + ModelRenderer jaw1b; + ModelRenderer jaw2a; + ModelRenderer jaw2b; + ModelRenderer antenna1; + ModelRenderer antenna2; + ModelRenderer eye1; + ModelRenderer eye2; + ModelRenderer tooth1a; + ModelRenderer tooth1b; + ModelRenderer tooth1c; + ModelRenderer tooth2a; + ModelRenderer tooth2b; + ModelRenderer tooth2c; + + public ModelTFPinchBeetle() { + textureWidth = 64; + textureHeight = 32; + + thorax = new ModelRenderer(this, 0, 22); + thorax.addBox(-4.5F, -4F, 0F, 9, 8, 2); + thorax.setRotationPoint(0F, 18F, -4.5F); + + connector1 = new ModelRenderer(this, 0, 12); + connector1.addBox(-3F, -3F, 0F, 6, 6, 1); + connector1.setRotationPoint(0F, 18F, -3F); + + connector2 = new ModelRenderer(this, 0, 12); + connector2.addBox(-3F, -3F, -1F, 6, 6, 1); + connector2.setRotationPoint(0F, 18F, -4F); + + RearEnd = new ModelRenderer(this, 28, 14); + RearEnd.addBox(-5F, -9F, -4F, 10, 10, 8); + RearEnd.setRotationPoint(0F, 18F, 7F); + setRotation(RearEnd, 1.570796F, 0F, 0F); + + Leg6 = new ModelRenderer(this, 40, 0); + Leg6.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg6.setRotationPoint(4F, 21F, -4F); + setRotation(Leg6, 0F, 0.2792527F, 0.3490659F); + + Leg5 = new ModelRenderer(this, 40, 0); + Leg5.mirror = true; + Leg5.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg5.setRotationPoint(-4F, 21F, -4F); + setRotation(Leg5, 0F, -0.2792527F, -0.3490659F); + + Leg4 = new ModelRenderer(this, 40, 0); + Leg4.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg4.setRotationPoint(4F, 21F, -1F); + setRotation(Leg4, 0F, -0.2792527F, 0.3490659F); + + Leg2 = new ModelRenderer(this, 40, 0); + Leg2.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg2.setRotationPoint(4F, 21F, 4F); + setRotation(Leg2, 0F, -0.6981317F, 0.3490659F); + + Leg3 = new ModelRenderer(this, 40, 0); + Leg3.mirror = true; + Leg3.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg3.setRotationPoint(-4F, 21F, -1F); + setRotation(Leg3, 0F, 0.2792527F, -0.3490659F); + + Leg1 = new ModelRenderer(this, 40, 0); + Leg1.mirror = true; + Leg1.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg1.setRotationPoint(-4F, 21F, 4F); + Leg1.setTextureSize(64, 32); + setRotation(Leg1, 0F, 0.6981317F, -0.3490659F); + + head = new ModelRenderer(this, 0, 0); + head.addBox(-4F, -4F, -6F, 8, 6, 6); + head.setRotationPoint(0F, 19F, -5F); + + jaw1a = new ModelRenderer(this, 40, 6); + jaw1a.addBox(-1F, -1F, -1.5F, 8, 2, 3); + jaw1a.setRotationPoint(-3F, 1F, -6F); + setRotation(jaw1a, 0F, 2.6354471F, 0F); + + jaw1b = new ModelRenderer(this, 40, 10); + jaw1b.addBox(-1F, -1F, -1F, 10, 2, 2); + jaw1b.setRotationPoint(7F, 0F, 0F); + setRotation(jaw1b, 0F, -1.047197F, 0F); + + jaw2a = new ModelRenderer(this, 40, 6); + jaw2a.addBox(-1F, -1F, -1.5F, 8, 2, 3); + jaw2a.setRotationPoint(3F, 1F, -6F); + setRotation(jaw2a, 0F, 0.5410520F, 0F); + + jaw2b = new ModelRenderer(this, 40, 10); + jaw2b.addBox(-1F, -1F, -1F, 10, 2, 2); + jaw2b.setRotationPoint(7F, 0F, 0F); + setRotation(jaw2b, 0F, 1.047197F, 0F); + + antenna1 = new ModelRenderer(this, 42, 4); + antenna1.addBox(0F, -0.5F, -0.5F, 10, 1, 1); + antenna1.setRotationPoint(1F, -3F, -5F); + setRotation(antenna1, 0F, 1.047198F, -0.296706F); + + antenna2 = new ModelRenderer(this, 42, 4); + antenna2.addBox(0F, -0.5F, -0.5F, 10, 1, 1); + antenna2.setRotationPoint(-1F, -3F, -5F); + setRotation(antenna2, 0F, 2.094395F, 0.296706F); + + eye1 = new ModelRenderer(this, 15, 12); + eye1.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + eye1.setRotationPoint(-3F, -2F, -5F); + + eye2 = new ModelRenderer(this, 15, 12); + eye2.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + eye2.setRotationPoint(3F, -2F, -5F); + + tooth1a = new ModelRenderer(this, 0, 0); + tooth1a.addBox(0F, -0.5F, -0F, 2, 1, 1); + tooth1a.setRotationPoint(9F, 0F, 0F); + setRotation(tooth1a, 0F, -0.5235987F, 0); + + tooth1b = new ModelRenderer(this, 0, 0); + tooth1b.addBox(-2.5F, -0.5F, -0F, 2, 1, 1); + tooth1b.setRotationPoint(6F, 0F, 0F); + setRotation(tooth1b, 0F, 1.5707963F, 0); + + tooth1c = new ModelRenderer(this, 0, 0); + tooth1c.addBox(-2.5F, -0.5F, -0F, 2, 1, 1); + tooth1c.setRotationPoint(3F, 0F, 0F); + setRotation(tooth1c, 0F, 1.5707963F, 0); + + tooth2a = new ModelRenderer(this, 0, 0); + tooth2a.addBox(0F, -0.5F, -1F, 2, 1, 1); + tooth2a.setRotationPoint(9F, 0F, 0F); + setRotation(tooth2a, 0F, 0.5235987F, 0); + + tooth2b = new ModelRenderer(this, 0, 0); + tooth2b.addBox(-2.5F, -0.5F, -1F, 2, 1, 1); + tooth2b.setRotationPoint(6F, 0F, 0F); + setRotation(tooth2b, 0F, -1.5707963F, 0); + + tooth2c = new ModelRenderer(this, 0, 0); + tooth2c.addBox(-2.5F, -0.5F, -1F, 2, 1, 1); + tooth2c.setRotationPoint(3F, 0F, 0F); + setRotation(tooth2c, 0F, -1.5707963F, 0); + + head.addChild(jaw1a); + jaw1a.addChild(jaw1b); + jaw1b.addChild(tooth1a); + jaw1b.addChild(tooth1b); + jaw1b.addChild(tooth1c); + jaw2b.addChild(tooth2a); + jaw2b.addChild(tooth2b); + jaw2b.addChild(tooth2c); + head.addChild(jaw2a); + jaw2a.addChild(jaw2b); + head.addChild(antenna1); + head.addChild(antenna2); + head.addChild(eye1); + head.addChild(eye2); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + thorax.render(scale); + head.render(scale); + connector2.render(scale); + RearEnd.render(scale); + Leg6.render(scale); + Leg4.render(scale); + Leg2.render(scale); + Leg5.render(scale); + Leg3.render(scale); + Leg1.render(scale); + connector1.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.head.rotateAngleX = headPitch / (180F / (float) Math.PI); + + float legZ = ((float) Math.PI / 11F); + this.Leg1.rotateAngleZ = -legZ; + this.Leg2.rotateAngleZ = legZ; + this.Leg3.rotateAngleZ = -legZ * 0.74F; + this.Leg4.rotateAngleZ = legZ * 0.74F; + this.Leg5.rotateAngleZ = -legZ; + this.Leg6.rotateAngleZ = legZ; + + float var9 = -0.0F; + float var10 = 0.3926991F; + this.Leg1.rotateAngleY = var10 * 2.0F + var9; + this.Leg2.rotateAngleY = -var10 * 2.0F - var9; + this.Leg3.rotateAngleY = var10 * 1.0F + var9; + this.Leg4.rotateAngleY = -var10 * 1.0F - var9; + this.Leg5.rotateAngleY = -var10 * 2.0F + var9; + this.Leg6.rotateAngleY = var10 * 2.0F - var9; + + float var11 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + 0.0F) * 0.4F) * limbSwingAmount; + float var12 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float var14 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + + float var15 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + 0.0F) * 0.4F) * limbSwingAmount; + float var16 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float var18 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + + this.Leg1.rotateAngleY += var11; + this.Leg2.rotateAngleY += -var11; + this.Leg3.rotateAngleY += var12; + this.Leg4.rotateAngleY += -var12; + this.Leg5.rotateAngleY += var14; + this.Leg6.rotateAngleY += -var14; + + this.Leg1.rotateAngleZ += var15; + this.Leg2.rotateAngleZ += -var15; + + this.Leg3.rotateAngleZ += var16; + this.Leg4.rotateAngleZ += -var16; + + this.Leg5.rotateAngleZ += var18; + this.Leg6.rotateAngleZ += -var18; + + + } + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + EntityTFPinchBeetle beetle = (EntityTFPinchBeetle) entity; + + if (beetle.isBeingRidden()) { + // open jaws + this.jaw1a.rotateAngleY = 2.96705972839036F; + this.jaw2a.rotateAngleY = 0.3490658503988659F; + } else { + // close jaws + this.jaw1a.rotateAngleY = 2.356194490192345F; + this.jaw2a.rotateAngleY = 0.7853981633974483F; + } + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFProtectionBox.java b/src/main/java/twilightforest/client/model/entity/ModelTFProtectionBox.java new file mode 100644 index 0000000000..53884fba65 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFProtectionBox.java @@ -0,0 +1,55 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import twilightforest.entity.EntityTFProtectionBox; + +public class ModelTFProtectionBox extends ModelBase { + + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + } + + public ModelRenderer box; + private int lastPixelsX; + private int lastPixelsY; + private int lastPixelsZ; + + public ModelTFProtectionBox() { + textureWidth = 16; + textureHeight = 16; + box = new ModelRenderer(this, 0, 0); + box.addBox(0F, 0F, 0F, 16, 16, 16, 0F); + box.setRotationPoint(0F, 0F, 0F); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + + EntityTFProtectionBox boxEntity = (EntityTFProtectionBox) entity; + + int pixelsX = boxEntity.sizeX * 16 + 2; + int pixelsY = boxEntity.sizeY * 16 + 2; + int pixelsZ = boxEntity.sizeZ * 16 + 2; + + if (pixelsX != this.lastPixelsX || pixelsY != this.lastPixelsY || pixelsZ != this.lastPixelsZ) { + resizeBoxElement(pixelsX, pixelsY, pixelsZ); + } + + box.render(scale); + } + + private void resizeBoxElement(int pixelsX, int pixelsY, int pixelsZ) { + box = new ModelRenderer(this, 0, 0); + box.addBox(-1F, -1F, -1F, pixelsX, pixelsY, pixelsZ, 0F); + box.setRotationPoint(0F, 0F, 0F); + + this.lastPixelsX = pixelsX; + this.lastPixelsY = pixelsY; + this.lastPixelsZ = pixelsZ; + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFQuestRam.java b/src/main/java/twilightforest/client/model/entity/ModelTFQuestRam.java new file mode 100644 index 0000000000..7282e0750d --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFQuestRam.java @@ -0,0 +1,232 @@ +// Date: 5/18/2012 11:45:03 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.passive.EntitySheep; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.passive.EntityTFQuestRam; + +public class ModelTFQuestRam extends ModelBase { + //fields + ModelRenderer frontbody; + ModelRenderer rearbody; + ModelRenderer leg1; + ModelRenderer haunch1; + ModelRenderer leg2; + ModelRenderer haunch2; + ModelRenderer leg3; + ModelRenderer haunch3; + ModelRenderer leg4; + ModelRenderer haunch4; + ModelRenderer neck; + ModelRenderer nose; + public ModelRenderer head; + + ModelRenderer[] segments; + boolean[] segmentEnabled; + + int[] colorOrder = new int[]{0, 8, 7, 15, 14, 1, 4, 5, 13, 3, 9, 11, 10, 2, 6, 12}; + + public ModelTFQuestRam() { + textureWidth = 128; + textureHeight = 128; + setTextureOffset("head.head", 0, 70); + setTextureOffset("head.horn1a", 0, 94); + setTextureOffset("head.horn1b", 20, 96); + setTextureOffset("head.horn1c", 34, 95); + setTextureOffset("head.horn1d", 46, 98); + setTextureOffset("head.horn1e", 58, 95); + setTextureOffset("head.horn1f", 76, 95); + setTextureOffset("head.horn1g", 88, 97); + setTextureOffset("head.horn1a", 0, 94); + setTextureOffset("head.horn1b", 20, 96); + setTextureOffset("head.horn1c", 34, 95); + setTextureOffset("head.horn1d", 46, 98); + setTextureOffset("head.horn1e", 58, 95); + setTextureOffset("head.horn1f", 76, 95); + setTextureOffset("head.horn1g", 88, 97); + + frontbody = new ModelRenderer(this, 0, 0); + frontbody.addBox(-9F, -7.5F, -15F, 18, 15, 15); + frontbody.setRotationPoint(0F, -1F, 2F); + + rearbody = new ModelRenderer(this, 0, 30); + rearbody.addBox(-9F, -7.5F, 0F, 18, 15, 15); + rearbody.setRotationPoint(0F, -1F, 4F); + + + leg1 = new ModelRenderer(this, 66, 0); + leg1.addBox(-3F, 10F, -3F, 6, 12, 6); + leg1.setRotationPoint(-6F, 2F, 13F); + + haunch1 = new ModelRenderer(this, 90, 0); + haunch1.addBox(-3.5F, 0F, -6F, 7, 10, 10); + haunch1.setRotationPoint(-6F, 2F, 13F); + + leg2 = new ModelRenderer(this, 66, 0); + leg2.addBox(-3F, 10F, -3F, 6, 12, 6); + leg2.setRotationPoint(6F, 2F, 13F); + + haunch2 = new ModelRenderer(this, 90, 0); + haunch2.addBox(-3.5F, 0F, -6F, 7, 10, 10); + haunch2.setRotationPoint(6F, 2F, 13F); + + leg3 = new ModelRenderer(this, 66, 18); + leg3.addBox(-3F, 10F, -3F, 6, 13, 6); + leg3.setRotationPoint(-6F, 1F, -8F); + + haunch3 = new ModelRenderer(this, 90, 20); + haunch3.addBox(-3.5F, 0F, -4F, 7, 10, 7); + haunch3.setRotationPoint(-6F, 1F, -8F); + + leg4 = new ModelRenderer(this, 66, 18); + leg4.addBox(-3F, 10F, -3F, 6, 13, 6); + leg4.setRotationPoint(6F, 1F, -8F); + + haunch4 = new ModelRenderer(this, 90, 20); + haunch4.addBox(-3.5F, 0F, -4F, 7, 10, 7); + haunch4.setRotationPoint(6F, 1F, -8F); + + neck = new ModelRenderer(this, 66, 37); + neck.addBox(-5.5F, -8F, -8F, 11, 14, 12); + neck.setRotationPoint(0F, -8F, -7F); + + setRotation(neck, 0.2617994F, 0F, 0F); + + head = new ModelRenderer(this, "head"); + head.setRotationPoint(0F, -13F, -5F); + + head.addBox("head", -6F, -4.5F, -15F, 12, 9, 15); + head.addBox("horn1a", 5F, -9F, -7F, 4, 4, 6); + head.addBox("horn1b", 7F, -8F, -2F, 3, 4, 4); + head.addBox("horn1c", 8F, -6F, 0F, 3, 6, 3); + head.addBox("horn1d", 9.5F, -2F, -2F, 3, 3, 3); + head.addBox("horn1e", 11F, 0F, -7F, 3, 3, 6); + head.addBox("horn1f", 12F, -4F, -9F, 3, 6, 3); + head.addBox("horn1g", 13F, -6F, -7F, 3, 3, 4); + head.addBox("horn1a", -9F, -9F, -7F, 4, 4, 6); + head.addBox("horn1b", -10F, -8F, -2F, 3, 4, 4); + head.addBox("horn1c", -11F, -6F, 0F, 3, 6, 3); + head.addBox("horn1d", -12.5F, -2F, -2F, 3, 3, 3); + head.addBox("horn1e", -14F, 0F, -7F, 3, 3, 6); + head.addBox("horn1f", -15F, -4F, -9F, 3, 6, 3); + head.addBox("horn1g", -16F, -6F, -7F, 3, 3, 4); + + nose = new ModelRenderer(this, 54, 73); + nose.addBox(-5.5F, -5F, -13F, 11, 9, 12); + nose.setRotationPoint(0F, -7F, -1F); + nose.setTextureSize(128, 128); + setRotation(nose, 0.5235988F, 0F, 0F); + head.addChild(nose); + + segments = new ModelRenderer[16]; + segmentEnabled = new boolean[16]; + for (int i = 0; i < 16; i++) { + segments[i] = new ModelRenderer(this, 0, 104); + segments[i].addBox(-9F, -7.5F, 0F, 18, 15, 2); + segments[i].setRotationPoint(0F, -1F, 2F); + + segmentEnabled[i] = false; + } + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + frontbody.render(scale); + rearbody.render(scale); + leg1.render(scale); + haunch1.render(scale); + leg2.render(scale); + haunch2.render(scale); + leg3.render(scale); + haunch3.render(scale); + leg4.render(scale); + haunch4.render(scale); + neck.render(scale); + //nose.render(scale); + head.render(scale); + + for (int i = 0; i < 16; i++) { + if (segmentEnabled[i]) { + float var4 = 1.0F; + final float[] dyeRgb = EntitySheep.getDyeRgb(EnumDyeColor.byMetadata(i)); + + GlStateManager.color(var4 * dyeRgb[0], var4 * dyeRgb[1], var4 * dyeRgb[2]); + segments[i].render(scale); + + } + } + GlStateManager.color(1.0F, 1.0F, 1.0F); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + /** + * Sets the models various rotation angles. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.head.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + + this.neck.rotateAngleY = this.head.rotateAngleY; + + this.leg1.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount * 0.5F; + this.leg2.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount * 0.5F; + this.leg3.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount * 0.5F; + this.leg4.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount * 0.5F; + this.haunch1.rotateAngleX = this.leg1.rotateAngleX; + this.haunch2.rotateAngleX = this.leg2.rotateAngleX; + this.haunch3.rotateAngleX = this.leg3.rotateAngleX; + this.haunch4.rotateAngleX = this.leg4.rotateAngleX; + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + EntityTFQuestRam ram = (EntityTFQuestRam) entity; + + // how many colors should we display? + int count = ram.countColorsSet(); + + this.rearbody.rotationPointZ = 2 + 2 * count; + this.leg1.rotationPointZ = 11 + 2 * count; + this.leg2.rotationPointZ = 11 + 2 * count; + this.haunch1.rotationPointZ = 11 + 2 * count; + this.haunch2.rotationPointZ = 11 + 2 * count; + + // set up the colors displayed in color order + int segmentOffset = 2; + for (int color : colorOrder) { + if (ram.isColorPresent(EnumDyeColor.byMetadata(color))) { + segmentEnabled[color] = true; + segments[color].rotationPointZ = segmentOffset; + + segmentOffset += 2; + } else { + segmentEnabled[color] = false; + } + } + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFRaven.java b/src/main/java/twilightforest/client/model/entity/ModelTFRaven.java new file mode 100644 index 0000000000..cd97afcc53 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFRaven.java @@ -0,0 +1,146 @@ +// Date: 4/28/2012 9:46:20 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.passive.EntityTFBird; + + +public class ModelTFRaven extends ModelBase { + //fields + ModelRenderer head; + ModelRenderer beak1; + ModelRenderer beak2; + ModelRenderer body; + ModelRenderer rightarm; + ModelRenderer leftarm; + ModelRenderer rightleg; + ModelRenderer leftleg; + ModelRenderer rightfoot; + ModelRenderer leftfoot; + ModelRenderer tail; + + public ModelTFRaven() { + textureWidth = 32; + textureHeight = 32; + + head = new ModelRenderer(this, 0, 0); + head.addBox(-1.5F, -1.5F, -3F, 3, 3, 3); + head.setRotationPoint(0F, 18F, 0F); + head.setTextureSize(32, 32); + head.mirror = true; + setRotation(head, 0F, 0F, 0F); + + beak1 = new ModelRenderer(this, 12, 0); + beak1.addBox(-0.5F, -1F, -2F, 1, 1, 2); + beak1.setRotationPoint(0F, 0F, -2.5F); + beak1.rotateAngleX = 0.2617994F; + head.addChild(beak1); + + beak2 = new ModelRenderer(this, 12, 0); + beak2.addBox(-0.5F, 0F, -2F, 1, 1, 2); + beak2.setRotationPoint(0F, 0F, -2.5F); + beak2.rotateAngleX = -0.2617994F; + head.addChild(beak2); + + body = new ModelRenderer(this, 0, 6); + body.addBox(-1.5F, 0F, -1F, 3, 4, 6); + body.setRotationPoint(0F, 17F, 1F); + body.setTextureSize(32, 32); + setRotation(body, -0.5235988F, 0F, 0F); + + rightarm = new ModelRenderer(this, 0, 16); + rightarm.addBox(-1F, 0F, -1.5F, 1, 3, 6); + rightarm.setRotationPoint(-1.5F, 18F, 1F); + rightarm.setTextureSize(32, 32); + + leftarm = new ModelRenderer(this, 0, 16); + leftarm.addBox(0F, 0F, -1.5F, 1, 3, 6); + leftarm.setRotationPoint(1.5F, 18F, 1F); + leftarm.setTextureSize(32, 32); + + rightleg = new ModelRenderer(this, 14, 16); + rightleg.addBox(0F, 0F, 0F, 1, 2, 1); + rightleg.setRotationPoint(-1.5F, 21F, 1F); + rightleg.setTextureSize(32, 32); + + rightfoot = new ModelRenderer(this, 14, 20); + rightfoot.addBox(0F, -1F, -2F, 1, 1, 2); + rightfoot.setRotationPoint(0F, 2F, 1F); + rightfoot.setTextureSize(32, 32); + setRotation(rightfoot, 0.5235988F, 0F, 0F); + rightleg.addChild(rightfoot); + + leftleg = new ModelRenderer(this, 14, 16); + leftleg.addBox(0F, 0F, 0F, 1, 2, 1); + leftleg.setRotationPoint(0.5F, 21F, 1F); + leftleg.setTextureSize(32, 32); + + leftfoot = new ModelRenderer(this, 14, 20); + leftfoot.addBox(0F, -1F, -2F, 1, 1, 2); + leftfoot.setRotationPoint(0F, 2F, 1F); + leftfoot.setTextureSize(32, 32); + setRotation(leftfoot, 0.5235988F, 0F, 0F); + leftleg.addChild(leftfoot); + + tail = new ModelRenderer(this, 0, 25); + tail.addBox(-1.5F, -0.5F, 0F, 3, 1, 3); + tail.setRotationPoint(0F, 21F, 4F); + tail.setTextureSize(32, 32); + setRotation(tail, -0.5235988F, 0F, 0F); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + head.render(scale); + body.render(scale); + rightarm.render(scale); + leftarm.render(scale); + rightleg.render(scale); + leftleg.render(scale); + + tail.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + + /** + * Sets the models various rotation angles. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + head.rotateAngleX = headPitch / (180F / (float) Math.PI); + head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + head.rotateAngleZ = netHeadYaw > 5 ? -0.2617994F : 0; + + rightleg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + leftleg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + + rightarm.rotateAngleZ = ageInTicks; + leftarm.rotateAngleZ = -ageInTicks; + + if (((EntityTFBird) entity).isBirdLanded()) { + rightleg.rotationPointY = 21; + leftleg.rotationPointY = 21; + } else { + rightleg.rotationPointY = 20F; + leftleg.rotationPointY = 20F; + } + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFRedcap.java b/src/main/java/twilightforest/client/model/entity/ModelTFRedcap.java new file mode 100644 index 0000000000..835ec55e3d --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFRedcap.java @@ -0,0 +1,74 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + + +public class ModelTFRedcap extends ModelBiped { + public ModelTFRedcap() { + bipedHead = new ModelRenderer(this, 0, 0); + bipedHead.addBox(-3.4F, 1F, -4F, 7, 7, 7, 0F); + bipedHead.setRotationPoint(0F, 0F, 0F); + + bipedHeadwear = new ModelRenderer(this, 32, 0); + bipedHeadwear.addBox(-2F, 0F, -3F, 4, 5, 7, 0F); + bipedHeadwear.setRotationPoint(0F, 0F, 0F); + + bipedBody = new ModelRenderer(this, 12, 19); + bipedBody.addBox(-4F, 6F, -2F, 8, 9, 4, 0F); + bipedBody.setRotationPoint(0F, 0F, 0F); + + bipedRightArm = new ModelRenderer(this, 36, 17); + bipedRightArm.addBox(-2F, -2F, -2F, 3, 12, 3, 0F); + bipedRightArm.setRotationPoint(-5F, 8F, 0F); + + bipedLeftArm = new ModelRenderer(this, 36, 17); + bipedLeftArm.addBox(-1F, -2F, -2F, 3, 12, 3, 0F); + bipedLeftArm.setRotationPoint(5F, 8F, 0F); + + bipedRightLeg = new ModelRenderer(this, 0, 20); + bipedRightLeg.addBox(-2F, 2F, -1F, 3, 9, 3, 0F); + bipedRightLeg.setRotationPoint(-2F, 12F, 0F); + + bipedLeftLeg = new ModelRenderer(this, 0, 20); + bipedLeftLeg.addBox(-1F, 3F, -1F, 3, 9, 3, 0F); + bipedLeftLeg.setRotationPoint(2F, 12F, 0F); + + goblinRightEar = new ModelRenderer(this, 48, 20); + goblinRightEar.addBox(3F, -2F, -1F, 2, 3, 1, 0F); + goblinRightEar.setRotationPoint(0F, 3F, 0F); + + goblinLeftEar = new ModelRenderer(this, 48, 24); + goblinLeftEar.addBox(-5F, -2F, -1F, 2, 3, 1, 0F); + goblinLeftEar.setRotationPoint(0F, 3F, 0F); + + goblinLeftEar.mirror = true; + } + + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + goblinRightEar.rotateAngleX = bipedHead.rotateAngleX; + goblinRightEar.rotateAngleY = bipedHead.rotateAngleY; + goblinRightEar.rotateAngleZ = bipedHead.rotateAngleZ; + + goblinLeftEar.rotateAngleX = bipedHead.rotateAngleX; + goblinLeftEar.rotateAngleY = bipedHead.rotateAngleY; + goblinLeftEar.rotateAngleZ = bipedHead.rotateAngleZ; + } + + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + + goblinRightEar.render(scale); + goblinLeftEar.render(scale); + } + + + ModelRenderer goblinRightEar; + ModelRenderer goblinLeftEar; +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFRisingZombie.java b/src/main/java/twilightforest/client/model/entity/ModelTFRisingZombie.java new file mode 100644 index 0000000000..5c8cf18bad --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFRisingZombie.java @@ -0,0 +1,59 @@ +package twilightforest.client.model.entity; + + +import net.minecraft.client.model.ModelZombie; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; + +public class ModelTFRisingZombie extends ModelZombie { + @Override + public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entityIn); + GlStateManager.pushMatrix(); + + if (this.isChild) { + GlStateManager.pushMatrix(); + { + GlStateManager.scale(0.75F, 0.75F, 0.75F); + GlStateManager.translate(0.0F, 16.0F * scale, 0.0F); + this.bipedHead.render(scale); + GlStateManager.popMatrix(); + GlStateManager.pushMatrix(); + GlStateManager.scale(0.5F, 0.5F, 0.5F); + GlStateManager.translate(0.0F, 24.0F * scale, 0.0F); + this.bipedBody.render(scale); + this.bipedRightArm.render(scale); + this.bipedLeftArm.render(scale); + this.bipedHeadwear.render(scale); + } + GlStateManager.popMatrix(); + this.bipedRightLeg.render(scale); + this.bipedLeftLeg.render(scale); + } else { + if (entityIn.isSneaking()) { + GlStateManager.translate(0.0F, 0.2F, 0.0F); + } + + GlStateManager.translate(0F, (80F - Math.min(80F, ageInTicks)) / 80F, 0F); + GlStateManager.translate(0F, (40F - Math.min(40F, Math.max(0F, ageInTicks - 80F))) / 40F, 0F); + GlStateManager.pushMatrix(); + { + final float yOff = 1F; + GlStateManager.translate(0, yOff, 0); + GlStateManager.rotate(-120F * (80F - Math.min(80F, ageInTicks)) / 80F, 1F, 0F, 0F); + GlStateManager.rotate(30F * (40F - Math.min(40F, Math.max(0F, ageInTicks - 80F))) / 40F, 1F, 0F, 0F); + GlStateManager.translate(0, -yOff, 0); + this.bipedHead.render(scale); + this.bipedBody.render(scale); + this.bipedRightArm.render(scale); + this.bipedLeftArm.render(scale); + this.bipedHeadwear.render(scale); + } + GlStateManager.popMatrix(); + this.bipedRightLeg.render(scale); + this.bipedLeftLeg.render(scale); + } + + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFSkeletonDruid.java b/src/main/java/twilightforest/client/model/entity/ModelTFSkeletonDruid.java new file mode 100644 index 0000000000..adb69e3064 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFSkeletonDruid.java @@ -0,0 +1,34 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.model.ModelSkeleton; +import net.minecraft.entity.Entity; + + +public class ModelTFSkeletonDruid extends ModelSkeleton { + private ModelRenderer dress; + + public ModelTFSkeletonDruid() { + bipedBody = new ModelRenderer(this, 8, 16); + bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F); + bipedBody.setRotationPoint(0.0F, 0.0F, 0.0F); + bipedRightArm = new ModelRenderer(this, 0, 16); + bipedRightArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, 0.0F); + bipedRightArm.setRotationPoint(-5.0F, 2.0F, 0.0F); + bipedLeftArm = new ModelRenderer(this, 0, 16); + bipedLeftArm.mirror = true; + bipedLeftArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, 0.0F); + bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); + + dress = new ModelRenderer(this, 32, 16); + dress.addBox(-4F, 12.0F, -2F, 8, 12, 4, 0); + dress.setRotationPoint(0.0F, 0.0F, 0.0F); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + + dress.render(scale); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFSlimeBeetle.java b/src/main/java/twilightforest/client/model/entity/ModelTFSlimeBeetle.java new file mode 100644 index 0000000000..c9460eb855 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFSlimeBeetle.java @@ -0,0 +1,242 @@ +// Date: 11/5/2012 7:35:56 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + +public class ModelTFSlimeBeetle extends ModelBase { + //fields + ModelRenderer head; + ModelRenderer RearEnd; + ModelRenderer Leg6; + ModelRenderer Leg4; + ModelRenderer Leg2; + ModelRenderer Leg5; + ModelRenderer Leg3; + ModelRenderer Leg1; + ModelRenderer connector1; + ModelRenderer antenna1; + ModelRenderer antenna2; + ModelRenderer eye1; + ModelRenderer eye2; + + ModelRenderer slimeCube; + ModelRenderer tail1; + ModelRenderer tail2; + ModelRenderer mouth; + ModelRenderer slimeCenter; + + boolean renderPassModel = false; + + + public ModelTFSlimeBeetle() { + this(false); + } + + public ModelTFSlimeBeetle(boolean renderpass) { + this.renderPassModel = renderpass; + + textureWidth = 64; + textureHeight = 64; + + connector1 = new ModelRenderer(this, 0, 12); + connector1.addBox(-3F, -3F, -1F, 6, 6, 1); + connector1.setRotationPoint(0F, 19F, -4F); + + RearEnd = new ModelRenderer(this, 31, 6); + RearEnd.addBox(-4F, -11F, -4F, 8, 10, 8); + RearEnd.setRotationPoint(0F, 18F, 7F); + setRotation(RearEnd, 1.570796F, 0F, 0F); + + Leg6 = new ModelRenderer(this, 40, 0); + Leg6.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg6.setRotationPoint(2F, 21F, -4F); + setRotation(Leg6, 0F, 0.2792527F, 0.3490659F); + + Leg5 = new ModelRenderer(this, 40, 0); + Leg5.mirror = true; + Leg5.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg5.setRotationPoint(-2F, 21F, -4F); + setRotation(Leg5, 0F, -0.2792527F, -0.3490659F); + + Leg4 = new ModelRenderer(this, 40, 0); + Leg4.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg4.setRotationPoint(2F, 21F, -1F); + setRotation(Leg4, 0F, -0.2792527F, 0.3490659F); + + Leg2 = new ModelRenderer(this, 40, 0); + Leg2.addBox(-1F, -1F, -1F, 10, 2, 2); + Leg2.setRotationPoint(2F, 21F, 4F); + setRotation(Leg2, 0F, -0.6981317F, 0.3490659F); + + Leg3 = new ModelRenderer(this, 40, 0); + Leg3.mirror = true; + Leg3.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg3.setRotationPoint(-2F, 21F, -1F); + setRotation(Leg3, 0F, 0.2792527F, -0.3490659F); + + Leg1 = new ModelRenderer(this, 40, 0); + Leg1.mirror = true; + Leg1.addBox(-9F, -1F, -1F, 10, 2, 2); + Leg1.setRotationPoint(-2F, 21F, 4F); + Leg1.setTextureSize(64, 32); + setRotation(Leg1, 0F, 0.6981317F, -0.3490659F); + + head = new ModelRenderer(this, 0, 0); + head.addBox(-4F, -4F, -6F, 8, 6, 6); + head.setRotationPoint(0F, 19F, -5F); + + antenna1 = new ModelRenderer(this, 38, 4); + antenna1.addBox(0F, -0.5F, -0.5F, 12, 1, 1); + antenna1.setRotationPoint(1F, -3F, -5F); + setRotation(antenna1, 0F, 1.047198F, -0.296706F); + + antenna2 = new ModelRenderer(this, 38, 4); + antenna2.addBox(0F, -0.5F, -0.5F, 12, 1, 1); + antenna2.setRotationPoint(-1F, -3F, -5F); + setRotation(antenna2, 0F, 2.094395F, 0.296706F); + + eye1 = new ModelRenderer(this, 15, 12); + eye1.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + eye1.setRotationPoint(-3F, -2F, -5F); + + eye2 = new ModelRenderer(this, 15, 12); + eye2.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + eye2.setRotationPoint(3F, -2F, -5F); + + + mouth = new ModelRenderer(this, 17, 12); + mouth.addBox(-1F, -1F, -1F, 2, 2, 1); + mouth.setRotationPoint(0F, 1, -6F); + + + head.addChild(antenna1); + head.addChild(antenna2); + head.addChild(eye1); + head.addChild(eye2); + head.addChild(mouth); + + + tail1 = new ModelRenderer(this, 0, 20); + tail1.addBox(-3F, -3F, -3F, 6, 6, 6); + tail1.setRotationPoint(0F, 19F, 9F); + + tail2 = new ModelRenderer(this, 0, 20); + tail2.addBox(-3F, -6F, -3F, 6, 6, 6); + tail2.setRotationPoint(0F, -3F, 2F); + + slimeCube = new ModelRenderer(this, 0, 40); + slimeCube.addBox(-6F, -12F, -9F, 12, 12, 12); + slimeCube.setRotationPoint(0F, -6, 0); + + slimeCenter = new ModelRenderer(this, 32, 24); + slimeCenter.addBox(-4F, -10F, -7F, 8, 8, 8); + slimeCenter.setRotationPoint(0F, -6, 0); + + tail1.addChild(tail2); + + if (renderPassModel) { + tail2.addChild(slimeCube); + } else { + tail2.addChild(slimeCenter); + } + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + tail1.render(scale); + + if (renderPassModel) { + } else { + head.render(scale); + RearEnd.render(scale); + Leg6.render(scale); + Leg4.render(scale); + Leg2.render(scale); + Leg5.render(scale); + Leg3.render(scale); + Leg1.render(scale); + connector1.render(scale); + //tail1.render(scale); +// tail2.render(scale); +// slimeCenter.render(scale); + } + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.head.rotateAngleX = headPitch / (180F / (float) Math.PI); + + // legs! + float legZ = ((float) Math.PI / 11F); + this.Leg1.rotateAngleZ = -legZ; + this.Leg2.rotateAngleZ = legZ; + this.Leg3.rotateAngleZ = -legZ * 0.74F; + this.Leg4.rotateAngleZ = legZ * 0.74F; + this.Leg5.rotateAngleZ = -legZ; + this.Leg6.rotateAngleZ = legZ; + + float var9 = -0.0F; + float var10 = 0.3926991F; + this.Leg1.rotateAngleY = var10 * 2.0F + var9; + this.Leg2.rotateAngleY = -var10 * 2.0F - var9; + this.Leg3.rotateAngleY = var10 * 1.0F + var9; + this.Leg4.rotateAngleY = -var10 * 1.0F - var9; + this.Leg5.rotateAngleY = -var10 * 2.0F + var9; + this.Leg6.rotateAngleY = var10 * 2.0F - var9; + + float var11 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + 0.0F) * 0.4F) * limbSwingAmount; + float var12 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float var14 = -(MathHelper.cos(limbSwing * 0.6662F * 2.0F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + + float var15 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + 0.0F) * 0.4F) * limbSwingAmount; + float var16 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + (float) Math.PI) * 0.4F) * limbSwingAmount; + float var18 = Math.abs(MathHelper.sin(limbSwing * 0.6662F + ((float) Math.PI * 3F / 2F)) * 0.4F) * limbSwingAmount; + + this.Leg1.rotateAngleY += var11; + this.Leg2.rotateAngleY += -var11; + this.Leg3.rotateAngleY += var12; + this.Leg4.rotateAngleY += -var12; + this.Leg5.rotateAngleY += var14; + this.Leg6.rotateAngleY += -var14; + + this.Leg1.rotateAngleZ += var15; + this.Leg2.rotateAngleZ += -var15; + + this.Leg3.rotateAngleZ += var16; + this.Leg4.rotateAngleZ += -var16; + + this.Leg5.rotateAngleZ += var18; + this.Leg6.rotateAngleZ += -var18; + + + // tail wiggle + this.tail1.rotateAngleX = MathHelper.cos(ageInTicks * 0.3335F) * 0.15F; + this.tail2.rotateAngleX = MathHelper.cos(ageInTicks * 0.4445F) * 0.20F; + this.slimeCube.rotateAngleX = MathHelper.cos(ageInTicks * 0.5555F) * 0.25F; + this.slimeCenter.rotateAngleX = MathHelper.cos(ageInTicks * 0.5555F + 0.25F) * 0.25F; + + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFSnowGuardian.java b/src/main/java/twilightforest/client/model/entity/ModelTFSnowGuardian.java new file mode 100644 index 0000000000..4565d3d465 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFSnowGuardian.java @@ -0,0 +1,28 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; + +public class ModelTFSnowGuardian extends ModelBiped { + + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + //float bounce = entity.ticksExisted + partialTicks; + //entity.yOffset = 0.5F + MathHelper.sin((bounce) * 0.3F) * 0.5F; + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFSnowQueen.java b/src/main/java/twilightforest/client/model/entity/ModelTFSnowQueen.java new file mode 100644 index 0000000000..e10ffa8db7 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFSnowQueen.java @@ -0,0 +1,144 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.boss.EntityTFSnowQueen; +import twilightforest.entity.boss.EntityTFSnowQueen.Phase; + +public class ModelTFSnowQueen extends ModelBiped { + + public ModelTFSnowQueen() { + + float par1 = 0; + float par2 = 0; + + + // crown + this.bipedHeadwear = new ModelRenderer(this, 0, 0); + + this.bipedHeadwear.addChild(makeFrontCrown(-1, -4, 10F)); + this.bipedHeadwear.addChild(makeFrontCrown(0, 4, -10F)); + this.bipedHeadwear.addChild(makeSideCrown(-1, -4, 10F)); + this.bipedHeadwear.addChild(makeSideCrown(0, 4, -10F)); + + // copy to back + + + // dress + this.bipedBody = new ModelRenderer(this, 32, 0); + this.bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 23, 4, par1); + this.bipedBody.setRotationPoint(0.0F, 0.0F + par2, 0.0F); + + // shrink + this.bipedRightArm = new ModelRenderer(this, 16, 16); + this.bipedRightArm.addBox(-2.0F, -2.0F, -1.5F, 3, 12, 3, par1); + this.bipedRightArm.setRotationPoint(-5.0F, 2.0F + par2, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 16, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.3F, 3, 12, 3, par1); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F + par2, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + this.bipedRightLeg.addBox(-1.5F, 0.0F, -1.5F, 3, 12, 3, par1); + this.bipedRightLeg.setRotationPoint(-1.9F, 12.0F + par2, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.5F, 0.0F, -1.5F, 3, 12, 3, par1); + this.bipedLeftLeg.setRotationPoint(1.9F, 12.0F + par2, 0.0F); + + } + + private ModelRenderer makeSideCrown(float spikeDepth, float crownX, float angle) { + ModelRenderer crownSide = new ModelRenderer(this, 28, 28); + crownSide.addBox(-3.5F, -0.5F, -0.5F, 7, 1, 1); + crownSide.setRotationPoint(crownX, -6.0F, 0.0F); + crownSide.rotateAngleY = 3.14159F / 2.0F; + + ModelRenderer spike4 = new ModelRenderer(this, 48, 27); + spike4.addBox(-0.5F, -3.5F, spikeDepth, 1, 4, 1); + spike4.rotateAngleX = angle * 1.5F / 180F * 3.14159F; + + ModelRenderer spike3l = new ModelRenderer(this, 52, 28); + spike3l.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); + spike3l.setRotationPoint(-2.5F, 0.0F, 0.0F); + spike3l.rotateAngleX = angle / 180F * 3.14159F; + spike3l.rotateAngleZ = -10F / 180F * 3.14159F; + + ModelRenderer spike3r = new ModelRenderer(this, 52, 28); + spike3r.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); + spike3r.setRotationPoint(2.5F, 0.0F, 0.0F); + spike3r.rotateAngleX = angle / 180F * 3.14159F; + spike3r.rotateAngleZ = 10F / 180F * 3.14159F; + + + crownSide.addChild(spike4); + crownSide.addChild(spike3l); + crownSide.addChild(spike3r); + return crownSide; + } + + private ModelRenderer makeFrontCrown(float spikeDepth, float crownZ, float angle) { + ModelRenderer crownFront = new ModelRenderer(this, 28, 30); + crownFront.addBox(-4.5F, -0.5F, -0.5F, 9, 1, 1); + crownFront.setRotationPoint(0.0F, -6.0F, crownZ); + + ModelRenderer spike4 = new ModelRenderer(this, 48, 27); + spike4.addBox(-0.5F, -3.5F, spikeDepth, 1, 4, 1); + spike4.rotateAngleX = angle * 1.5F / 180F * 3.14159F; + + ModelRenderer spike3l = new ModelRenderer(this, 52, 28); + spike3l.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); + spike3l.setRotationPoint(-2.5F, 0.0F, 0.0F); + spike3l.rotateAngleX = angle / 180F * 3.14159F; + spike3l.rotateAngleZ = -10F / 180F * 3.14159F; + + ModelRenderer spike3r = new ModelRenderer(this, 52, 28); + spike3r.addBox(-0.5F, -2.5F, spikeDepth, 1, 3, 1); + spike3r.setRotationPoint(2.5F, 0.0F, 0.0F); + spike3r.rotateAngleX = angle / 180F * 3.14159F; + spike3r.rotateAngleZ = 10F / 180F * 3.14159F; + + crownFront.addChild(spike4); + crownFront.addChild(spike3l); + crownFront.addChild(spike3r); + return crownFront; + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + EntityTFSnowQueen queen = (EntityTFSnowQueen) entity; + + // in beam phase, arms forwards + if (queen.getCurrentPhase() == Phase.BEAM) { + if (queen.isBreathing()) { + float f6 = MathHelper.sin(this.swingProgress * (float) Math.PI); + float f7 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * (float) Math.PI); + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - f6 * 0.6F); + this.bipedLeftArm.rotateAngleY = 0.1F - f6 * 0.6F; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedRightArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + this.bipedLeftArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + } else { + // arms up + this.bipedRightArm.rotateAngleX += Math.PI; + this.bipedLeftArm.rotateAngleX += Math.PI; + } + } + } + +} diff --git a/src/main/java/twilightforest/client/model/ModelTFSpikeBlock.java b/src/main/java/twilightforest/client/model/entity/ModelTFSpikeBlock.java similarity index 77% rename from src/main/java/twilightforest/client/model/ModelTFSpikeBlock.java rename to src/main/java/twilightforest/client/model/entity/ModelTFSpikeBlock.java index d904ce3447..c8d8178735 100644 --- a/src/main/java/twilightforest/client/model/ModelTFSpikeBlock.java +++ b/src/main/java/twilightforest/client/model/entity/ModelTFSpikeBlock.java @@ -1,29 +1,26 @@ -package twilightforest.client.model; +package twilightforest.client.model.entity; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import net.minecraft.entity.Entity; -public class ModelTFSpikeBlock extends ModelBase -{ - ModelRenderer block; - ModelRenderer[] spikes = new ModelRenderer[27]; - - public ModelTFSpikeBlock() - { - +public class ModelTFSpikeBlock extends ModelBase { + ModelRenderer block; + ModelRenderer[] spikes = new ModelRenderer[27]; + + public ModelTFSpikeBlock() { + block = new ModelRenderer(this, 32, 16); block.addBox(-4F, -8F, -4F, 8, 8, 8, 0F); block.setRotationPoint(0F, 0F, 0F); - - for (int i = 0; i < spikes.length; i++) - { + + for (int i = 0; i < spikes.length; i++) { spikes[i] = new ModelRenderer(this, 56, 16); spikes[i].addBox(-1F, -1F, -1F, 2, 2, 2, 0F); block.addChild(spikes[i]); } - + // X spikes[2].rotationPointX = 4; spikes[3].rotationPointX = 4; @@ -34,7 +31,7 @@ public ModelTFSpikeBlock() spikes[20].rotationPointX = 4; spikes[21].rotationPointX = 4; spikes[22].rotationPointX = 4; - + spikes[6].rotationPointX = -4; spikes[7].rotationPointX = -4; spikes[8].rotationPointX = -4; @@ -44,7 +41,7 @@ public ModelTFSpikeBlock() spikes[24].rotationPointX = -4; spikes[25].rotationPointX = -4; spikes[26].rotationPointX = -4; - + // Y spikes[0].rotationPointY = -9; spikes[1].rotationPointY = -8; @@ -55,7 +52,7 @@ public ModelTFSpikeBlock() spikes[6].rotationPointY = -8; spikes[7].rotationPointY = -8; spikes[8].rotationPointY = -8; - + spikes[9].rotationPointY = -4; // this spike is not really there spikes[10].rotationPointY = -4; spikes[11].rotationPointY = -4; @@ -65,9 +62,9 @@ public ModelTFSpikeBlock() spikes[15].rotationPointY = -4; spikes[16].rotationPointY = -4; spikes[17].rotationPointY = -4; - + spikes[18].rotationPointY = 1; - + // Z spikes[1].rotationPointZ = 4; spikes[2].rotationPointZ = 4; @@ -88,50 +85,50 @@ public ModelTFSpikeBlock() spikes[22].rotationPointZ = -4; spikes[23].rotationPointZ = -4; spikes[24].rotationPointZ = -4; - + // rotation float fourtyFive = (float) (Math.PI / 4F); - + spikes[1].rotateAngleX = fourtyFive; spikes[5].rotateAngleX = fourtyFive; spikes[19].rotateAngleX = fourtyFive; spikes[23].rotateAngleX = fourtyFive; - + spikes[11].rotateAngleY = fourtyFive; spikes[13].rotateAngleY = fourtyFive; spikes[15].rotateAngleY = fourtyFive; spikes[17].rotateAngleY = fourtyFive; - + spikes[3].rotateAngleZ = fourtyFive; spikes[7].rotateAngleZ = fourtyFive; spikes[21].rotateAngleZ = fourtyFive; spikes[25].rotateAngleZ = fourtyFive; - spikes[2].rotateAngleX = -55F / (180F / (float)Math.PI); + spikes[2].rotateAngleX = -55F / (180F / (float) Math.PI); spikes[2].rotateAngleY = fourtyFive; - spikes[24].rotateAngleX = -55F / (180F / (float)Math.PI); + spikes[24].rotateAngleX = -55F / (180F / (float) Math.PI); spikes[24].rotateAngleY = fourtyFive; - - spikes[4].rotateAngleX = -35F / (180F / (float)Math.PI); + + spikes[4].rotateAngleX = -35F / (180F / (float) Math.PI); spikes[4].rotateAngleY = -fourtyFive; - spikes[26].rotateAngleX = -35F / (180F / (float)Math.PI); + spikes[26].rotateAngleX = -35F / (180F / (float) Math.PI); spikes[26].rotateAngleY = -fourtyFive; spikes[6].rotateAngleY = fourtyFive; - spikes[6].rotateAngleX = -35F / (180F / (float)Math.PI); + spikes[6].rotateAngleX = -35F / (180F / (float) Math.PI); spikes[20].rotateAngleY = fourtyFive; - spikes[20].rotateAngleX = -35F / (180F / (float)Math.PI); + spikes[20].rotateAngleX = -35F / (180F / (float) Math.PI); - spikes[8].rotateAngleX = -55F / (180F / (float)Math.PI); + spikes[8].rotateAngleX = -55F / (180F / (float) Math.PI); spikes[8].rotateAngleY = -fourtyFive; - spikes[22].rotateAngleX = -55F / (180F / (float)Math.PI); + spikes[22].rotateAngleX = -55F / (180F / (float) Math.PI); spikes[22].rotateAngleY = -fourtyFive; - + } - + @Override - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { - block.render(f5); + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + block.render(scale); } } diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFSquirrel.java b/src/main/java/twilightforest/client/model/entity/ModelTFSquirrel.java new file mode 100644 index 0000000000..067a18a458 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFSquirrel.java @@ -0,0 +1,155 @@ +// Date: 4/27/2012 9:49:06 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; + + +public class ModelTFSquirrel extends ModelBase { + //fields + ModelRenderer body; + ModelRenderer leg1; + ModelRenderer leg2; + ModelRenderer leg3; + ModelRenderer leg4; + ModelRenderer head; + ModelRenderer tail; + ModelRenderer fluff1; + ModelRenderer fluff2; + ModelRenderer fluff3; + + public ModelTFSquirrel() { + textureWidth = 32; + textureHeight = 32; + setTextureOffset("head.head", 0, 0); + setTextureOffset("head.ear2", 16, 0); + setTextureOffset("head.ear1", 16, 0); + setTextureOffset("tail.fluff1", 0, 20); + setTextureOffset("tail.base", 0, 18); + setTextureOffset("tail.fluff2", 0, 20); + setTextureOffset("tail.fluff3", 0, 26); + + body = new ModelRenderer(this, 0, 8); + body.addBox(-2F, -1F, -2F, 4, 3, 5); + body.setRotationPoint(0F, 21F, 0F); + body.setTextureSize(32, 32); + body.mirror = true; + setRotation(body, 0F, 0F, 0F); + leg1 = new ModelRenderer(this, 0, 16); + leg1.addBox(0F, 0F, 0F, 1, 1, 1); + leg1.setRotationPoint(-2F, 23F, 2F); + leg1.setTextureSize(32, 32); + leg1.mirror = true; + setRotation(leg1, 0F, 0F, 0F); + leg2 = new ModelRenderer(this, 0, 16); + leg2.addBox(0F, 0F, 0F, 1, 1, 1); + leg2.setRotationPoint(1F, 23F, 2F); + leg2.setTextureSize(32, 32); + leg2.mirror = true; + setRotation(leg2, 0F, 0F, 0F); + leg3 = new ModelRenderer(this, 0, 16); + leg3.addBox(0F, 0F, 0F, 1, 1, 1); + leg3.setRotationPoint(-2F, 23F, -2F); + leg3.setTextureSize(32, 32); + + setRotation(leg3, 0F, 0F, 0F); + leg4 = new ModelRenderer(this, 0, 16); + leg4.addBox(0F, 0F, 0F, 1, 1, 1); + leg4.setRotationPoint(1F, 23F, -2F); + leg4.setTextureSize(32, 32); + + setRotation(leg4, 0F, 0F, 0F); + head = new ModelRenderer(this, "head"); + head.setRotationPoint(0F, 22F, -2F); + setRotation(head, 0F, 0F, 0F); + + head.addBox("head", -2F, -5F, -3F, 4, 4, 4); + head.addBox("ear2", -2F, -6F, -0.5F, 1, 1, 1); + head.addBox("ear1", 1F, -6F, -0.5F, 1, 1, 1); + + tail = new ModelRenderer(this, "tail"); + tail.setRotationPoint(0F, 21F, 2F); + + tail.addBox("base", -0.5F, -1.5F, 0.5F, 1, 1, 1); + + fluff1 = new ModelRenderer(this, 0, 20); + fluff1.addBox(-1.5F, -4F, 1F, 3, 3, 3); + tail.addChild(fluff1); + + fluff2 = new ModelRenderer(this, 0, 20); + fluff2.addBox(0F, -3F, -1.5F, 3, 3, 3); + fluff2.setRotationPoint(-1.5F, -4F, 2.5F); + fluff1.addChild(fluff2); + + fluff3 = new ModelRenderer(this, 0, 26); + fluff3.addBox(1.5F, -3F, -1.5F, 3, 3, 3); + fluff3.setRotationPoint(-1.5F, -3F, 0F); + fluff2.addChild(fluff3); + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + body.render(scale); + leg1.render(scale); + leg2.render(scale); + leg3.render(scale); + leg4.render(scale); + head.render(scale); + tail.render(scale); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTickTime) { + //EntityTFSquirrel squirrel = (EntityTFSquirrel)entity; + + + } + + /** + * Sets the models various rotation angles. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.head.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.leg1.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.leg2.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.leg3.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.leg4.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + + if (limbSwingAmount > 0.2) { + float wiggle = Math.min(limbSwingAmount, 0.6F); + this.tail.rotateAngleX = (MathHelper.cos(ageInTicks * 0.6662F) * 1.0F - (float) Math.PI / 3) * wiggle; + this.fluff2.rotateAngleX = MathHelper.cos(ageInTicks * 0.7774F) * 1.2F * wiggle; + this.fluff3.rotateAngleX = MathHelper.cos(ageInTicks * 0.8886F + (float) Math.PI / 2) * 1.4F * wiggle; + } else { + this.tail.rotateAngleX = 0.2F + MathHelper.cos(ageInTicks * 0.3335F) * 0.15F; + this.fluff2.rotateAngleX = 0.1F + MathHelper.cos(ageInTicks * 0.4445F) * 0.20F; + this.fluff3.rotateAngleX = 0.1F + MathHelper.cos(ageInTicks * 0.5555F) * 0.25F; + } + + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFSwarmSpider.java b/src/main/java/twilightforest/client/model/entity/ModelTFSwarmSpider.java new file mode 100644 index 0000000000..fe0d14efe9 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFSwarmSpider.java @@ -0,0 +1,13 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelSpider; +import net.minecraft.entity.Entity; + + +public class ModelTFSwarmSpider extends ModelSpider { + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale * 0.5f); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFTinyBird.java b/src/main/java/twilightforest/client/model/entity/ModelTFTinyBird.java new file mode 100644 index 0000000000..6364c8aa8c --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFTinyBird.java @@ -0,0 +1,147 @@ +// Date: 4/25/2012 10:28:13 PM +// Template version 1.1 +// Java generated by Techne +// Keep in mind that you still need to fill in some blanks +// - ZeuX + +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.passive.EntityTFBird; + +public class ModelTFTinyBird extends ModelBase { + //fields + ModelRenderer beak; + ModelRenderer head; + ModelRenderer body; + ModelRenderer rightarm; + ModelRenderer leftarm; + ModelRenderer rightleg; + ModelRenderer leftleg; + ModelRenderer tail; + + public ModelTFTinyBird() { + textureWidth = 32; + textureHeight = 32; + + head = new ModelRenderer(this, 0, 0); + head.addBox(-1.5F, -1.5F, -1.5F, 3, 3, 3); + head.setRotationPoint(0F, 20.5F, -0.5F); + head.setTextureSize(32, 32); + head.mirror = true; + setRotation(head, 0F, 0F, 0F); + + beak = new ModelRenderer(this, 12, 0); + beak.addBox(-0.5F, -0.5F, -0.5F, 1, 1, 1); + beak.setRotationPoint(0F, 0.5F, -2F); + + head.addChild(beak); + + + body = new ModelRenderer(this, 0, 6); + body.addBox(-1.5F, 0F, -1F, 3, 3, 3); + body.setRotationPoint(0F, 20F, 0F); + body.setTextureSize(32, 32); + body.mirror = true; + setRotation(body, 0F, 0F, 0F); + rightarm = new ModelRenderer(this, 12, 2); + rightarm.addBox(-1F, 0F, -1.5F, 1, 2, 3); + rightarm.setRotationPoint(-1.5F, 20.5F, 1F); + rightarm.setTextureSize(32, 32); + rightarm.mirror = true; + setRotation(rightarm, 0F, 0F, 0F); + leftarm = new ModelRenderer(this, 12, 2); + leftarm.addBox(0F, 0F, -1.5F, 1, 2, 3); + leftarm.setRotationPoint(1.5F, 20.5F, 1F); + leftarm.setTextureSize(32, 32); + leftarm.mirror = true; + setRotation(leftarm, 0F, 0F, 0F); + rightleg = new ModelRenderer(this, 0, 12); + rightleg.addBox(0F, 0F, 0F, 1, 1, 1); + rightleg.setRotationPoint(-1.5F, 23F, 0F); + rightleg.setTextureSize(32, 32); + rightleg.mirror = true; + setRotation(rightleg, 0F, 0F, 0F); + leftleg = new ModelRenderer(this, 0, 12); + leftleg.addBox(0.5F, 0F, 0F, 1, 1, 1); + leftleg.setRotationPoint(0F, 23F, 0F); + leftleg.setTextureSize(32, 32); + leftleg.mirror = true; + setRotation(leftleg, 0F, 0F, 0F); + tail = new ModelRenderer(this, 0, 14); + tail.addBox(-1.5F, -0.5F, 0F, 3, 1, 2); + tail.setRotationPoint(0F, 22F, 2F); + tail.setTextureSize(32, 32); + tail.mirror = true; + setRotation(tail, 0F, 0F, 0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + if (isChild) { + float f = 2.0F; + GlStateManager.pushMatrix(); + GlStateManager.translate(0.0F, 5F * scale, 0.75F * scale); + head.render(scale); + GlStateManager.popMatrix(); + GlStateManager.pushMatrix(); + GlStateManager.scale(1.0F / f, 1.0F / f, 1.0F / f); + GlStateManager.translate(0.0F, 24F * scale, 0.0F); + body.render(scale); + rightleg.render(scale); + leftleg.render(scale); + rightarm.render(scale); + leftarm.render(scale); + GlStateManager.popMatrix(); + } else { + head.render(scale); + body.render(scale); + rightleg.render(scale); + leftleg.render(scale); + rightarm.render(scale); + leftarm.render(scale); + tail.render(scale); +// beak.render(scale); + } + } + + private void setRotation(ModelRenderer model, float x, float y, float z) { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + + /** + * Sets the models various rotation angles. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + head.rotateAngleX = headPitch / (180F / (float) Math.PI); + head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + + rightleg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + leftleg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + + rightarm.rotateAngleZ = ageInTicks; + leftarm.rotateAngleZ = -ageInTicks; + + if (((EntityTFBird) entity).isBirdLanded()) { + rightleg.rotationPointY = 23; + leftleg.rotationPointY = 23; + } else { + rightleg.rotationPointY = 22.5F; + leftleg.rotationPointY = 22.5F; + } + + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFTinyFirefly.java b/src/main/java/twilightforest/client/model/entity/ModelTFTinyFirefly.java new file mode 100644 index 0000000000..fc01fb5186 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFTinyFirefly.java @@ -0,0 +1,27 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + + +public class ModelTFTinyFirefly extends ModelBase { + public ModelTFTinyFirefly() { + glow1 = new ModelRenderer(this, 20, 0); + glow1.addBox(-5F, -5F, 0F, 10, 10, 0, 0F); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + glow1.render(scale); + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5) { + //super.setRotationAngles(f, f1, f2, f3, f4, f5); + } + + //fields + public ModelRenderer glow1; + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFTowerBoss.java b/src/main/java/twilightforest/client/model/entity/ModelTFTowerBoss.java new file mode 100644 index 0000000000..17551ba1c2 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFTowerBoss.java @@ -0,0 +1,153 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + +import java.util.Random; + +public class ModelTFTowerBoss extends ModelTFGhast { + + protected ModelRenderer[][] subTentacles; + protected ModelRenderer[][] smallTentacles; + + public ModelTFTowerBoss() { + super(); + + this.smallTentacles = new ModelRenderer[2][3]; + for (int i = 0; i < this.smallTentacles.length; ++i) { + makeSmallTentacle(i); + } + } + + @Override + protected void makeTentacle(byte yOffset, Random random, int num) { + this.tentacles[num] = new ModelRenderer(this, num % 3, 0); + + int length = 5; + + this.tentacles[num].addBox(-1.5F, 0.0F, -1.5F, 3, length, 3); + + + if (num == 0) { + this.tentacles[num].rotationPointX = 4.5F; + this.tentacles[num].rotationPointZ = 4.5F; + this.tentacles[num].rotationPointY = (float) (23 + yOffset); + } + if (num == 1) { + this.tentacles[num].rotationPointX = -4.5F; + this.tentacles[num].rotationPointZ = 4.5F; + this.tentacles[num].rotationPointY = (float) (23 + yOffset); + } + if (num == 2) { + this.tentacles[num].rotationPointX = 0F; + this.tentacles[num].rotationPointZ = 0F; + this.tentacles[num].rotationPointY = (float) (23 + yOffset); + } + if (num == 3) { + this.tentacles[num].rotationPointX = 5.5F; + this.tentacles[num].rotationPointZ = -4.5F; + this.tentacles[num].rotationPointY = (float) (23 + yOffset); + } + if (num == 4) { + this.tentacles[num].rotationPointX = -5.5F; + this.tentacles[num].rotationPointZ = -4.5F; + this.tentacles[num].rotationPointY = (float) (23 + yOffset); + } else if (num == 5) { + this.tentacles[num].rotationPointX = -7.5F; + this.tentacles[num].rotationPointY = 3.5F; + this.tentacles[num].rotationPointZ = -1F; + + this.tentacles[num].rotateAngleZ = (float) Math.PI / 4.0F; + } else if (num == 6) { + this.tentacles[num].rotationPointX = -7.5F; + this.tentacles[num].rotationPointY = -1.5F; + this.tentacles[num].rotationPointZ = 3.5F; + + this.tentacles[num].rotateAngleZ = (float) Math.PI / 3.0F; + } else if (num == 7) { + this.tentacles[num].rotationPointX = 7.5F; + this.tentacles[num].rotationPointY = 3.5F; + this.tentacles[num].rotationPointZ = -1F; + + this.tentacles[num].rotateAngleZ = -(float) Math.PI / 4.0F; + } else if (num == 8) { + this.tentacles[num].rotationPointX = 7.5F; + this.tentacles[num].rotationPointY = -1.5F; + this.tentacles[num].rotationPointZ = 3.5F; + + this.tentacles[num].rotateAngleZ = -(float) Math.PI / 3.0F; + } + + // goofy mid-method initializer + if (this.subTentacles == null) { + this.subTentacles = new ModelRenderer[tentacles.length][3]; + } + + for (int i = 0; i < 3; i++) { + length = 4; + + this.subTentacles[num][i] = new ModelRenderer(this, num % 4, (i * 5) - 1); + + this.subTentacles[num][i].addBox(-1.5F, -0.5F, -1.5F, 3, length, 3); + this.subTentacles[num][i].rotationPointX = 0; + this.subTentacles[num][i].rotationPointZ = 0; + this.subTentacles[num][i].rotationPointY = length; + + if (i == 0) { + this.tentacles[num].addChild(this.subTentacles[num][i]); + } else { + this.subTentacles[num][i - 1].addChild(this.subTentacles[num][i]); + } + } + + this.body.addChild(this.tentacles[num]); + + } + + + /** + * Make one of the small tentacles + */ + protected void makeSmallTentacle(int num) { + ; + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + + // wave tentacles + for (int i = 0; i < this.subTentacles.length; ++i) { +// for (int j = 0; j < this.subTentacles[i].length; ++j) +// { +// this.subTentacles[i][j].rotateAngleX = 0.8F * MathHelper.sin(i * 2.3F) + 0.3F * MathHelper.sin(j) + 0.2F; +// +// } + + float wiggle = Math.min(limbSwingAmount, 0.6F); + + float time = (ageInTicks + (i * 9)) / 2.0F; + + this.subTentacles[i][0].rotateAngleX = (MathHelper.cos(time * 0.6662F) * 1.0F - (float) Math.PI / 3.0F) * wiggle; + this.subTentacles[i][1].rotateAngleX = MathHelper.cos(time * 0.7774F) * 1.2F * wiggle; + this.subTentacles[i][2].rotateAngleX = MathHelper.cos(time * 0.8886F + (float) Math.PI / 2.0F) * 1.4F * wiggle; + + this.subTentacles[i][0].rotateAngleX = 0.2F + MathHelper.cos(time * 0.3335F) * 0.15F; + this.subTentacles[i][1].rotateAngleX = 0.1F + MathHelper.cos(time * 0.4445F) * 0.20F; + this.subTentacles[i][2].rotateAngleX = 0.1F + MathHelper.cos(time * 0.5555F) * 0.25F; + + + float yTwist = 0.4F; + + this.tentacles[i].rotateAngleY = yTwist * MathHelper.sin(time * 0.3F); + + } + } + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFTowerGolem.java b/src/main/java/twilightforest/client/model/entity/ModelTFTowerGolem.java new file mode 100644 index 0000000000..83d87edbfc --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFTowerGolem.java @@ -0,0 +1,150 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.EntityTFTowerGolem; + +//Date: 3/9/2013 10:55:38 AM +//Template version 1.1 +//Java generated by Techne +//Keep in mind that you still need to fill in some blanks +//- ZeuX + + +public class ModelTFTowerGolem extends ModelBase { + //fields + ModelRenderer head; + ModelRenderer jaw; + ModelRenderer body; + ModelRenderer rightarm; + ModelRenderer leftarm; + ModelRenderer leftleg; + ModelRenderer leftfoot; + ModelRenderer ribs; + ModelRenderer hips; + ModelRenderer rightfoot; + ModelRenderer rightleg; + ModelRenderer spine; + + public ModelTFTowerGolem() { + textureWidth = 128; + textureHeight = 64; + + head = new ModelRenderer(this, 0, 0); + head.setRotationPoint(0F, -11F, -2F); + head.setTextureOffset(0, 0).addBox(-3.5F, -10F, -3F, 7, 8, 6); // head + head.setTextureOffset(0, 14).addBox(-4F, -6F, -3.5F, 8, 4, 6); // jaw + + body = new ModelRenderer(this, 0, 26); + body.addBox(-8F, 0F, -5F, 16, 10, 10); + body.setRotationPoint(0F, -13F, 0F); + + ribs = new ModelRenderer(this, 0, 46); + ribs.addBox(-5F, 0F, -3F, 10, 6, 6); + ribs.setRotationPoint(0F, -3F, 0F); + + rightarm = new ModelRenderer(this, 52, 0); + rightarm.setRotationPoint(-8F, -12F, 0F); + rightarm.setTextureOffset(52, 0).addBox(-5F, -2F, -1.5F, 3, 14, 3); // arm + rightarm.setTextureOffset(52, 17).addBox(-7F, 12F, -3F, 6, 12, 6); // fist + rightarm.setTextureOffset(52, 36).addBox(-7F, -3F, -3.5F, 7, 2, 7); // shoulder top + rightarm.setTextureOffset(52, 45).addBox(-7F, -1F, -3.5F, 7, 5, 2); // shoulder front + rightarm.setTextureOffset(52, 45).addBox(-7F, -1F, 1.5F, 7, 5, 2); // shoulder back + rightarm.setTextureOffset(52, 54).addBox(-2F, -1F, -2F, 2, 5, 3); // shoulder inner + + leftarm = new ModelRenderer(this, 52, 0); + leftarm.mirror = true; + leftarm.setRotationPoint(8F, -12F, 0F); + leftarm.setTextureOffset(52, 0).addBox(2F, -2F, -1.5F, 3, 14, 3); // arm + leftarm.setTextureOffset(52, 17).addBox(1F, 12F, -3F, 6, 12, 6); // fist + leftarm.setTextureOffset(52, 36).addBox(0F, -3F, -3.5F, 7, 2, 7); // shoulder top + leftarm.setTextureOffset(52, 45).addBox(0F, -1F, -3.5F, 7, 5, 2); // shoulder front + leftarm.setTextureOffset(52, 45).addBox(0F, -1F, 1.5F, 7, 5, 2); // shoulder back + leftarm.setTextureOffset(52, 54).addBox(0F, -1F, -2F, 2, 5, 3); // shoulder inner + + hips = new ModelRenderer(this, 84, 25); + hips.addBox(-5F, 0F, -2F, 10, 3, 4); + hips.setRotationPoint(0F, 1F, 0F); + + spine = new ModelRenderer(this, 84, 18); + spine.addBox(-1.5F, 0F, -1.5F, 3, 4, 3); + spine.setRotationPoint(0F, -3F, 0F); + + leftleg = new ModelRenderer(this, 84, 32); + leftleg.mirror = true; + leftleg.setRotationPoint(1F, 2F, 0F); + leftleg.setTextureOffset(84, 32).addBox(0F, 0F, -1.5F, 3, 8, 3); + leftleg.setTextureOffset(84, 43).addBox(-0.5F, 8F, -4F, 6, 14, 7); + + rightleg = new ModelRenderer(this, 84, 32); + rightleg.setRotationPoint(-1F, 2F, 0F); + rightleg.setTextureOffset(84, 32).addBox(-3F, 0F, -1.5F, 3, 8, 3); + rightleg.setTextureOffset(84, 43).addBox(-5.5F, 8F, -4F, 6, 14, 7); + + } + + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + //super.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + head.render(scale); + body.render(scale); + rightarm.render(scale); + leftarm.render(scale); + rightleg.render(scale); + leftleg.render(scale); + ribs.render(scale); + hips.render(scale); + spine.render(scale); + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + this.head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.head.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.leftleg.rotateAngleX = -1.5F * this.func_78172_a(limbSwing, 13.0F) * limbSwingAmount; + this.rightleg.rotateAngleX = 1.5F * this.func_78172_a(limbSwing, 13.0F) * limbSwingAmount; + this.leftleg.rotateAngleY = 0.0F; + this.rightleg.rotateAngleY = 0.0F; + +// this.leftleg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; // biped leg movement +// this.rightleg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float)Math.PI) * 1.4F * limbSwingAmount; + + + this.rightarm.rotateAngleZ = MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.leftarm.rotateAngleZ = -MathHelper.cos(ageInTicks * 0.09F) * 0.05F - 0.05F; + + } + + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + EntityTFTowerGolem golem = (EntityTFTowerGolem) entity; + int var6 = golem.getAttackTimer(); + + if (var6 > 0) { + this.rightarm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float) var6 - partialTicks, 10.0F); + this.leftarm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float) var6 - partialTicks, 10.0F); + } else { + this.rightarm.rotateAngleX = (-0.2F + 1.5F * this.func_78172_a(limbSwing, 25.0F)) * limbSwingAmount; + this.leftarm.rotateAngleX = (-0.2F - 1.5F * this.func_78172_a(limbSwing, 25.0F)) * limbSwingAmount; + } + } + + private float func_78172_a(float par1, float par2) { + return (Math.abs(par1 % par2 - par2 * 0.5F) - par2 * 0.25F) / (par2 * 0.25F); + } +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFTroll.java b/src/main/java/twilightforest/client/model/entity/ModelTFTroll.java new file mode 100644 index 0000000000..edd8543032 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFTroll.java @@ -0,0 +1,127 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.EntityTFTroll; + +public class ModelTFTroll extends ModelBiped { + + public ModelRenderer nose; + + + public ModelTFTroll() { + super(); + + this.textureWidth = 128; + this.textureHeight = 64; + + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-5.0F, -8.0F, -3.0F, 10, 10, 10); + this.bipedHead.setRotationPoint(0.0F, -9.0F, -6.0F); + + this.bipedHeadwear = new ModelRenderer(this, 32, 0); + this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); + + this.bipedBody = new ModelRenderer(this, 40, 0); + this.bipedBody.addBox(-8.0F, 0.0F, -5.0F, 16, 26, 10); + this.bipedBody.setRotationPoint(0.0F, -14.0F, 0.0F); + + + this.nose = new ModelRenderer(this, 0, 21); + this.nose.addBox(-2.0F, -2.0F, -2.0F, 4, 8, 4); + this.nose.setRotationPoint(0.0F, -2.0F, -4.0F); + this.bipedHead.addChild(nose); + + this.bipedRightArm = new ModelRenderer(this, 32, 36); + this.bipedRightArm.addBox(-5.0F, -2.0F, -3.0F, 6, 22, 6); + this.bipedRightArm.setRotationPoint(-9.0F, -9.0F, 0.0F); + + this.bipedLeftArm = new ModelRenderer(this, 32, 36); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -3.0F, 6, 22, 6); + this.bipedLeftArm.setRotationPoint(9.0F, -9.0F, 0.0F); + + + this.bipedRightLeg = new ModelRenderer(this, 0, 44); + this.bipedRightLeg.addBox(-3.0F, 0.0F, -4.0F, 6, 12, 8); + this.bipedRightLeg.setRotationPoint(-5.0F, 12.0F, 0.0F); + + this.bipedLeftLeg = new ModelRenderer(this, 0, 44); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-3.0F, 0.0F, -4.0F, 6, 12, 8); + this.bipedLeftLeg.setRotationPoint(5.0F, 12.0F, 0.0F); + } + + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + if (entity.isBeingRidden()) { + // arms up! + this.bipedRightArm.rotateAngleX += Math.PI; + this.bipedLeftArm.rotateAngleX += Math.PI; + + } + + if (this.leftArmPose != ArmPose.EMPTY) { + this.bipedRightArm.rotateAngleX += Math.PI; + } + if (this.rightArmPose != ArmPose.EMPTY) { + this.bipedLeftArm.rotateAngleX += Math.PI; + } + + if (this.swingProgress > 0F) { + float swing = 1.0F - this.swingProgress; + + this.bipedRightArm.rotateAngleX -= (Math.PI * swing); + this.bipedLeftArm.rotateAngleX -= (Math.PI * swing); + } + + this.bipedRightArm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + + } + + /** + * Change eye color if yeti is angry + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + EntityTFTroll troll = (EntityTFTroll) entity; + + if (troll.getAttackTarget() != null) { + this.bipedRightArm.rotateAngleX += Math.PI; + this.bipedLeftArm.rotateAngleX += Math.PI; + } + + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFWraith.java b/src/main/java/twilightforest/client/model/entity/ModelTFWraith.java new file mode 100644 index 0000000000..fe67ab5b19 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFWraith.java @@ -0,0 +1,61 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; + + +public class ModelTFWraith extends ModelBiped { + + public ModelRenderer dress; + + public ModelTFWraith() { + float f = 0.0F; + dress = new ModelRenderer(this, 40, 16); + dress.addBox(-4F, 12.0F, -2F, 8, 12, 4, f); + dress.setRotationPoint(0.0F, 0.0F, 0.0F); + + } + + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + bipedHead.render(scale); + bipedBody.render(scale); + bipedRightArm.render(scale); + bipedLeftArm.render(scale); + + dress.render(scale); + + //bipedRightLeg.render(scale); + //bipedLeftLeg.render(scale); + bipedHeadwear.render(scale); + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entity); + float var8 = MathHelper.sin(this.swingProgress * (float) Math.PI); + float var9 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * (float) Math.PI); + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - var8 * 0.6F); + this.bipedLeftArm.rotateAngleY = 0.1F - var8 * 0.6F; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedLeftArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFYeti.java b/src/main/java/twilightforest/client/model/entity/ModelTFYeti.java new file mode 100644 index 0000000000..2d330d1cd2 --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFYeti.java @@ -0,0 +1,165 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.EntityTFYeti; + +public class ModelTFYeti extends ModelBiped { + + public ModelRenderer mouth; + public ModelRenderer leftEye; + public ModelRenderer rightEye; + public ModelRenderer angryLeftEye; + public ModelRenderer angryRightEye; + + + public ModelTFYeti() { + super(); + + this.textureWidth = 128; + this.textureHeight = 64; + + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); + this.bipedHeadwear = new ModelRenderer(this, 32, 0); + this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); + + this.bipedBody = new ModelRenderer(this, 32, 0); + this.bipedBody.addBox(-10.0F, 0.0F, -6.0F, 20, 26, 12); + this.bipedBody.setRotationPoint(0.0F, -14.0F, 0.0F); + + + this.mouth = new ModelRenderer(this, 96, 6); + this.mouth.addBox(-7.0F, -5.0F, -0.5F, 14, 10, 1); + this.mouth.setRotationPoint(0.0F, 12.0F, -6.0F); + this.bipedBody.addChild(mouth); + + this.rightEye = new ModelRenderer(this, 96, 0); + this.rightEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); + this.rightEye.setRotationPoint(-5.5F, 4.5F, -6.0F); + this.bipedBody.addChild(rightEye); + + this.leftEye = new ModelRenderer(this, 96, 0); + this.leftEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); + this.leftEye.setRotationPoint(5.5F, 4.5F, -6.0F); + this.bipedBody.addChild(leftEye); + + this.angryRightEye = new ModelRenderer(this, 109, 0); + this.angryRightEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); + this.angryRightEye.setRotationPoint(5.5F, 4.5F, -6.0F); + this.bipedBody.addChild(angryRightEye); + + this.angryLeftEye = new ModelRenderer(this, 109, 0); + this.angryLeftEye.addBox(-2.5F, -2.5F, -0.5F, 5, 5, 1); + this.angryLeftEye.setRotationPoint(-5.5F, 4.5F, -6.0F); + this.bipedBody.addChild(angryLeftEye); + + this.bipedRightArm = new ModelRenderer(this, 0, 0); + this.bipedRightArm.addBox(-5.0F, -2.0F, -3.0F, 6, 16, 6); + this.bipedRightArm.setRotationPoint(-11.0F, -4.0F, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 0, 0); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -3.0F, 6, 16, 6); + this.bipedLeftArm.setRotationPoint(11.0F, -4.0F, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 0, 22); + this.bipedRightLeg.addBox(-4.0F, 0.0F, -4.0F, 8, 12, 8); + this.bipedRightLeg.setRotationPoint(-6.0F, 12.0F, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 0, 22); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-4.0F, 0.0F, -4.0F, 8, 12, 8); + this.bipedLeftLeg.setRotationPoint(6.0F, 12.0F, 0.0F); + } + + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + EntityTFYeti yeti = (EntityTFYeti) entity; + + + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + this.bipedHeadwear.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedHeadwear.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + if (entity.isBeingRidden()) { + // arms up! + this.bipedRightArm.rotateAngleX += Math.PI; + this.bipedLeftArm.rotateAngleX += Math.PI; + + } + + if (this.leftArmPose != ArmPose.EMPTY) { + this.bipedLeftArm.rotateAngleX = this.bipedLeftArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + if (this.rightArmPose != ArmPose.EMPTY) { + this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F); + } + + this.bipedRightArm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + + + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + + + // if yeti is angry, hold arms forwards like a zombie + if (yeti.isAngry()) { + float f6 = MathHelper.sin(this.swingProgress * (float) Math.PI); + float f7 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * (float) Math.PI); + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - f6 * 0.6F); + this.bipedLeftArm.rotateAngleY = 0.1F - f6 * 0.6F; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedRightArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + this.bipedLeftArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + } + } + + /** + * Change eye color if yeti is angry + */ + @Override + public void setLivingAnimations(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks) { + EntityTFYeti yeti = (EntityTFYeti) entity; + + if (yeti.isAngry()) { + this.rightEye.isHidden = true; + this.leftEye.isHidden = true; + this.angryRightEye.isHidden = false; + this.angryLeftEye.isHidden = false; + } else { + this.rightEye.isHidden = false; + this.leftEye.isHidden = false; + this.angryRightEye.isHidden = true; + this.angryLeftEye.isHidden = true; + } + } + + +} diff --git a/src/main/java/twilightforest/client/model/entity/ModelTFYetiAlpha.java b/src/main/java/twilightforest/client/model/entity/ModelTFYetiAlpha.java new file mode 100644 index 0000000000..c5bfc5736c --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/ModelTFYetiAlpha.java @@ -0,0 +1,215 @@ +package twilightforest.client.model.entity; + +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.boss.EntityTFYetiAlpha; + +public class ModelTFYetiAlpha extends ModelBiped { + + public ModelRenderer mouth; + public ModelRenderer leftEye; + public ModelRenderer rightEye; + + + public ModelTFYetiAlpha() { + super(); + + this.textureWidth = 256; + this.textureHeight = 128; + + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); + + this.bipedHeadwear = new ModelRenderer(this, 32, 0); + this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 0, 0, 0); + + this.bipedBody = new ModelRenderer(this, 80, 0); + this.bipedBody.addBox(-24.0F, -60.0F, -18.0F, 48, 72, 36); + this.bipedBody.setRotationPoint(0.0F, -6.0F, 0.0F); + + this.mouth = new ModelRenderer(this, 121, 50); + this.mouth.addBox(-17.0F, -7.0F, -1.5F, 34, 29, 2); + this.mouth.setRotationPoint(0.0F, -37.0F, -18.0F); + this.bipedBody.addChild(mouth); + + this.rightEye = new ModelRenderer(this, 64, 0); + this.rightEye.addBox(-6.0F, -6.0F, -1.5F, 12, 12, 2); + this.rightEye.setRotationPoint(-14.0F, -50.0F, -18.0F); + this.bipedBody.addChild(rightEye); + + this.leftEye = new ModelRenderer(this, 64, 0); + this.leftEye.addBox(-6.0F, -6.0F, -1.5F, 12, 12, 2); + this.leftEye.setRotationPoint(14.0F, -50.0F, -18.0F); + this.bipedBody.addChild(leftEye); + + this.bipedRightArm = new ModelRenderer(this, 0, 0); + this.bipedRightArm.addBox(-15.0F, -6.0F, -8.0F, 16, 48, 16); + this.bipedRightArm.setRotationPoint(-25.0F, -26.0F, 0.0F); + + this.bipedBody.addChild(this.bipedRightArm); + + this.bipedLeftArm = new ModelRenderer(this, 0, 0); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -6.0F, -8.0F, 16, 48, 16); + this.bipedLeftArm.setRotationPoint(25.0F, -26.0F, 0.0F); + + this.bipedBody.addChild(this.bipedLeftArm); + + + this.bipedRightLeg = new ModelRenderer(this, 0, 66); + this.bipedRightLeg.addBox(-10.0F, 0.0F, -10.0F, 20, 20, 20); + this.bipedRightLeg.setRotationPoint(-13.5F, 4.0F, 0.0F); + + this.bipedLeftLeg = new ModelRenderer(this, 0, 66); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-10.0F, 0.0F, -10.0F, 20, 20, 20); + this.bipedLeftLeg.setRotationPoint(13.5F, 4.0F, 0.0F); + + addPairHorns(-58.0F, 35F); + addPairHorns(-46.0F, 15F); + addPairHorns(-36.0F, -5F); + + + } + + + /** + * Add a pair of horns + */ + private void addPairHorns(float height, float zangle) { + ModelRenderer horn1a; + ModelRenderer horn1b; + + horn1a = new ModelRenderer(this, 0, 108); + horn1a.addBox(-9.0F, -5.0F, -5.0F, 10, 10, 10); + horn1a.setRotationPoint(-24.0F, height, -8.0F); + horn1a.rotateAngleY = -30F / (180F / (float) Math.PI); + horn1a.rotateAngleZ = zangle / (180F / (float) Math.PI); + this.bipedBody.addChild(horn1a); + + horn1b = new ModelRenderer(this, 40, 108); + horn1b.addBox(-14.0F, -4.0F, -4.0F, 18, 8, 8); + horn1b.setRotationPoint(-8.0F, 0.0F, 0.0F); + horn1b.rotateAngleY = -20F / (180F / (float) Math.PI); + horn1b.rotateAngleZ = zangle / (180F / (float) Math.PI); + horn1a.addChild(horn1b); + + ModelRenderer horn2a; + ModelRenderer horn2b; + + horn2a = new ModelRenderer(this, 0, 108); + horn2a.addBox(-1.0F, -5.0F, -5.0F, 10, 10, 10); + horn2a.setRotationPoint(24.0F, height, 0.0F); + horn2a.rotateAngleY = 30F / (180F / (float) Math.PI); + horn2a.rotateAngleZ = -zangle / (180F / (float) Math.PI); + this.bipedBody.addChild(horn2a); + + horn2b = new ModelRenderer(this, 40, 108); + horn2b.addBox(-2.0F, -4.0F, -4.0F, 18, 8, 8); + horn2b.setRotationPoint(8.0F, 0.0F, 0.0F); + horn2b.rotateAngleY = 20F / (180F / (float) Math.PI); + horn2b.rotateAngleZ = -zangle / (180F / (float) Math.PI); + horn2a.addChild(horn2b); + } + + + /** + * Sets the models various rotation angles then renders the model. + */ + @Override + public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + this.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale, entity); + + this.bipedBody.render(scale); + this.bipedRightLeg.render(scale); + this.bipedLeftLeg.render(scale); + } + + /** + * Sets the model's various rotation angles. For bipeds, limbSwing and limbSwingAmount are used for animating the movement of arms + * and legs, where limbSwing represents the time(so that arms and legs swing back and forth) and limbSwingAmount represents how + * "far" arms and legs can swing at most. + */ + @Override + public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entity) { + EntityTFYetiAlpha yeti = (EntityTFYetiAlpha) entity; + + + this.bipedHead.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.bipedHead.rotateAngleX = headPitch / (180F / (float) Math.PI); + + this.bipedBody.rotateAngleX = headPitch / (180F / (float) Math.PI); + + + this.bipedRightLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; + this.bipedLeftLeg.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 1.4F * limbSwingAmount; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + + float f6 = MathHelper.sin(this.swingProgress * (float) Math.PI); + float f7 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * (float) Math.PI); + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -(0.1F - f6 * 0.6F); + this.bipedLeftArm.rotateAngleY = 0.1F - f6 * 0.6F; + this.bipedRightArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedLeftArm.rotateAngleX = -((float) Math.PI / 2F); + this.bipedRightArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + this.bipedLeftArm.rotateAngleX -= f6 * 1.2F - f7 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleZ -= MathHelper.cos(ageInTicks * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + this.bipedLeftArm.rotateAngleX -= MathHelper.sin(ageInTicks * 0.067F) * 0.05F; + + this.bipedBody.rotationPointY = -6F; + this.bipedRightLeg.rotationPointY = 4F; + this.bipedLeftLeg.rotationPointY = 4F; + + + if (yeti.isTired()) { + // arms down + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 2.0F * limbSwingAmount * 0.5F; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + + // legs out + this.bipedRightArm.rotateAngleX += -((float) Math.PI / 5F); + this.bipedLeftArm.rotateAngleX += -((float) Math.PI / 5F); + this.bipedRightLeg.rotateAngleX = -((float) Math.PI * 2F / 5F); + this.bipedLeftLeg.rotateAngleX = -((float) Math.PI * 2F / 5F); + this.bipedRightLeg.rotateAngleY = ((float) Math.PI / 10F); + this.bipedLeftLeg.rotateAngleY = -((float) Math.PI / 10F); + + //body down + this.bipedBody.rotationPointY = 6F; + this.bipedRightLeg.rotationPointY = 12F; + this.bipedLeftLeg.rotationPointY = 12F; + } + + if (yeti.isRampaging()) { + // arms up + this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.66F + (float) Math.PI) * 2.0F * limbSwingAmount * 0.5F; + this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.66F) * 2.0F * limbSwingAmount * 0.5F; + +// this.bipedRightArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F) * 1.4F * limbSwingAmount; +// this.bipedLeftArm.rotateAngleX = MathHelper.cos(limbSwing * 0.6662F + (float)Math.PI) * 1.4F * limbSwingAmount; + + this.bipedRightArm.rotateAngleY += MathHelper.cos(limbSwing * 0.25F) * 0.5F + 0.5F; + this.bipedLeftArm.rotateAngleY -= MathHelper.cos(limbSwing * 0.25F) * 0.5F + 0.5F; + + this.bipedRightArm.rotateAngleX += Math.PI * 1.25; + this.bipedLeftArm.rotateAngleX += Math.PI * 1.25; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + } + + if (entity.isBeingRidden()) { + // arms up! + this.bipedRightArm.rotateAngleX += Math.PI; + this.bipedLeftArm.rotateAngleX += Math.PI; + } + } +} diff --git a/src/main/java/twilightforest/client/model/entity/finalcastle/ModelTFCastleGuardian.java b/src/main/java/twilightforest/client/model/entity/finalcastle/ModelTFCastleGuardian.java new file mode 100644 index 0000000000..5517f66fce --- /dev/null +++ b/src/main/java/twilightforest/client/model/entity/finalcastle/ModelTFCastleGuardian.java @@ -0,0 +1,576 @@ +package twilightforest.client.model.entity.finalcastle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; + +/** + * guardian - Drullkus + * Created using Tabula 7.0.0 + */ + +// TODO Optimize, holy fudge +@SuppressWarnings({"unused", "WeakerAccess"}) +public class ModelTFCastleGuardian extends ModelBase { + public ModelRenderer MainBody; + public ModelRenderer MidBody; + public ModelRenderer Head; + public ModelRenderer PlateGroup1; + public ModelRenderer PlateGroup2; + public ModelRenderer PlateGroup3; + public ModelRenderer PlateGroup4; + public ModelRenderer PlateGroup5; + public ModelRenderer PlateGroup6; + public ModelRenderer Plating; + public ModelRenderer SpikeWrapper; + public ModelRenderer InnerSupport; + public ModelRenderer Support; + public ModelRenderer Spike; + public ModelRenderer SpikeCap; + public ModelRenderer Plating_1; + public ModelRenderer SpikeWrapper_1; + public ModelRenderer InnerSupport_1; + public ModelRenderer Support_1; + public ModelRenderer Spike_1; + public ModelRenderer SpikeCap_1; + public ModelRenderer Plating_2; + public ModelRenderer SpikeWrapper_2; + public ModelRenderer InnerSupport_2; + public ModelRenderer Support_2; + public ModelRenderer Spike_2; + public ModelRenderer SpikeCap_2; + public ModelRenderer Plating_3; + public ModelRenderer SpikeWrapper_3; + public ModelRenderer InnerSupport_3; + public ModelRenderer Support_3; + public ModelRenderer Spike_3; + public ModelRenderer SpikeCap_3; + public ModelRenderer Plating_4; + public ModelRenderer SpikeWrapper_4; + public ModelRenderer InnerSupport_4; + public ModelRenderer Support_4; + public ModelRenderer Spike_4; + public ModelRenderer SpikeCap_4; + public ModelRenderer Plating_5; + public ModelRenderer SpikeWrapper_5; + public ModelRenderer InnerSupport_5; + public ModelRenderer Support_5; + public ModelRenderer Spike_5; + public ModelRenderer SpikeCap_5; + public ModelRenderer RunedSiding1; + public ModelRenderer Bridge1; + public ModelRenderer RunedSiding2; + public ModelRenderer Bridge2; + public ModelRenderer RunedSiding3; + public ModelRenderer Bridge3; + public ModelRenderer RunedSiding4; + public ModelRenderer Bridge4; + public ModelRenderer Cover; + public ModelRenderer HeadGroup2; + public ModelRenderer HeadGroup3; + public ModelRenderer HeadGroup4; + public ModelRenderer HeadGroup5; + public ModelRenderer HeadGroup6; + public ModelRenderer EyeBack; + public ModelRenderer HeadGroup1; + public ModelRenderer HeadPlate; + public ModelRenderer HeadSpikeWrapper; + public ModelRenderer HeadExtended; + public ModelRenderer HeadSpike; + public ModelRenderer HeadPlate_1; + public ModelRenderer HeadSpikeWrapper_1; + public ModelRenderer HeadExtended_1; + public ModelRenderer HeadSpike_1; + public ModelRenderer HeadPlate_2; + public ModelRenderer HeadSpikeWrapper_2; + public ModelRenderer HeadExtended_2; + public ModelRenderer HeadSpike_2; + public ModelRenderer HeadPlate_3; + public ModelRenderer HeadSpikeWrapper_3; + public ModelRenderer HeadExtended_3; + public ModelRenderer HeadSpike_3; + public ModelRenderer HeadPlate_4; + public ModelRenderer HeadSpikeWrapper_4; + public ModelRenderer HeadExtended_4; + public ModelRenderer HeadSpike_4; + public ModelRenderer Eye; + public ModelRenderer HeadPlate_5; + public ModelRenderer HeadSpikeWrapper_5; + public ModelRenderer HeadExtended_5; + public ModelRenderer EyeFrameR; + public ModelRenderer EyeFrameL; + public ModelRenderer EyeFrameLB; + public ModelRenderer EyeFrameRT; + public ModelRenderer EyeFrameLT; + public ModelRenderer EyeFrameRB; + public ModelRenderer HeadSpike_5; + + public ModelTFCastleGuardian() { + this.textureWidth = 128; + this.textureHeight = 64; + this.SpikeWrapper_5 = new ModelRenderer(this, 0, 0); + this.SpikeWrapper_5.setRotationPoint(0.0F, 0.0F, 0.0F); + this.SpikeWrapper_5.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(SpikeWrapper_5, 0.0F, 0.5235987755982988F, 0.0F); + this.EyeFrameL = new ModelRenderer(this, 0, 0); + this.EyeFrameL.setRotationPoint(-4.0F, 0.0F, -9.2F); + this.EyeFrameL.addBox(0.0F, -11.0F, 0.0F, 1, 5, 2, 0.0F); + this.Plating = new ModelRenderer(this, 0, 32); + this.Plating.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Plating.addBox(29.0F, -8.0F, -8.0F, 1, 16, 16, 0.0F); + this.setRotateAngle(Plating, 0.7853981633974483F, 0.0F, -0.7853981633974483F); + this.SpikeCap = new ModelRenderer(this, 7, 25); + this.SpikeCap.setRotationPoint(8.0F, -1.0F, 8.0F); + this.SpikeCap.addBox(0.0F, 0.0F, 0.0F, 6, 11, 6, 0.0F); + this.Spike_1 = new ModelRenderer(this, 0, 0); + this.Spike_1.setRotationPoint(0.0F, -20.0F, 0.0F); + this.Spike_1.addBox(1.0F, 0.0F, 1.0F, 12, 12, 12, 0.0F); + this.setRotateAngle(Spike_1, 0.0F, 0.7853981633974483F, -0.6065019150680295F); + this.HeadExtended_2 = new ModelRenderer(this, 64, 33); + this.HeadExtended_2.mirror = true; + this.HeadExtended_2.setRotationPoint(0.0F, -18.0F, -5.0F); + this.HeadExtended_2.addBox(-5.0F, 1.0F, 0.0F, 10, 1, 9, 0.0F); + this.setRotateAngle(HeadExtended_2, -0.2181661564992912F, 0.0F, 0.0F); + this.SpikeWrapper_1 = new ModelRenderer(this, 0, 0); + this.SpikeWrapper_1.setRotationPoint(0.0F, 0.0F, 0.0F); + this.SpikeWrapper_1.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(SpikeWrapper_1, 0.0F, 0.5235987755982988F, 0.0F); + this.Plating_1 = new ModelRenderer(this, 0, 32); + this.Plating_1.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Plating_1.addBox(29.0F, -8.0F, -8.0F, 1, 16, 16, 0.0F); + this.setRotateAngle(Plating_1, 0.7853981633974483F, 0.0F, -0.7853981633974483F); + this.HeadPlate_5 = new ModelRenderer(this, 86, 0); + this.HeadPlate_5.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadPlate_5.addBox(-5.0F, -17.0F, -9.2F, 10, 17, 4, 0.0F); + this.setRotateAngle(HeadPlate_5, 0.19634954084936207F, 0.0F, 0.0F); + this.HeadGroup1 = new ModelRenderer(this, 0, 0); + this.HeadGroup1.setRotationPoint(0.0F, -2.0F, 0.0F); + this.HeadGroup1.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.Support = new ModelRenderer(this, 31, 24); + this.Support.setRotationPoint(0.0F, -7.0F, 0.0F); + this.Support.addBox(23.5F, 0.0F, 0.0F, 6, 7, 7, 0.0F); + this.Plating_5 = new ModelRenderer(this, 0, 32); + this.Plating_5.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Plating_5.addBox(29.0F, -8.0F, -8.0F, 1, 16, 16, 0.0F); + this.setRotateAngle(Plating_5, 0.7853981633974483F, 0.0F, -0.7853981633974483F); + this.Spike_4 = new ModelRenderer(this, 0, 0); + this.Spike_4.setRotationPoint(0.0F, -20.0F, 0.0F); + this.Spike_4.addBox(1.0F, 0.0F, 1.0F, 12, 12, 12, 0.0F); + this.setRotateAngle(Spike_4, 0.0F, 0.7853981633974483F, -0.6065019150680295F); + this.MainBody = new ModelRenderer(this, 6, 49); + this.MainBody.setRotationPoint(0.0F, 0.0F, 0.0F); + this.MainBody.addBox(-7.0F, 18.8F, -7.5F, 14, 2, 14, 0.0F); + this.setRotateAngle(MainBody, 0.0F, 1.5707963267948966F, 0.0F); + this.HeadSpikeWrapper_3 = new ModelRenderer(this, 0, 0); + this.HeadSpikeWrapper_3.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpikeWrapper_3.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadSpikeWrapper_3, 0.0F, 2.0943951023931953F, 0.0F); + this.SpikeCap_3 = new ModelRenderer(this, 7, 25); + this.SpikeCap_3.setRotationPoint(8.0F, -1.0F, 8.0F); + this.SpikeCap_3.addBox(0.0F, 0.0F, 0.0F, 6, 11, 6, 0.0F); + this.SpikeWrapper = new ModelRenderer(this, 0, 0); + this.SpikeWrapper.setRotationPoint(0.0F, 0.0F, 0.0F); + this.SpikeWrapper.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(SpikeWrapper, 0.0F, 0.5235987755982988F, 0.0F); + this.Bridge3 = new ModelRenderer(this, 36, 0); + this.Bridge3.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Bridge3.addBox(-4.0F, -3.0F, 6.0F, 8, 9, 3, 0.0F); + this.setRotateAngle(Bridge3, -0.28361600344907856F, -2.356194490192345F, 0.0F); + this.HeadSpikeWrapper_4 = new ModelRenderer(this, 0, 0); + this.HeadSpikeWrapper_4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpikeWrapper_4.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadSpikeWrapper_4, 0.0F, 2.0943951023931953F, 0.0F); + this.HeadSpikeWrapper_5 = new ModelRenderer(this, 0, 0); + this.HeadSpikeWrapper_5.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpikeWrapper_5.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadSpikeWrapper_5, 0.0F, 2.0943951023931953F, 0.0F); + this.Support_3 = new ModelRenderer(this, 31, 24); + this.Support_3.setRotationPoint(0.0F, -7.0F, 0.0F); + this.Support_3.addBox(23.5F, 0.0F, 0.0F, 6, 7, 7, 0.0F); + this.InnerSupport_3 = new ModelRenderer(this, 23, 38); + this.InnerSupport_3.setRotationPoint(0.0F, -10.0F, 0.0F); + this.InnerSupport_3.addBox(7.0F, -1.4F, -4.0F, 11, 2, 8, 0.0F); + this.setRotateAngle(InnerSupport_3, 0.0F, 0.0F, -0.4553564018453205F); + this.SpikeWrapper_4 = new ModelRenderer(this, 0, 0); + this.SpikeWrapper_4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.SpikeWrapper_4.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(SpikeWrapper_4, 0.0F, 0.5235987755982988F, 0.0F); + this.HeadSpikeWrapper_2 = new ModelRenderer(this, 0, 0); + this.HeadSpikeWrapper_2.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpikeWrapper_2.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadSpikeWrapper_2, 0.0F, 2.0943951023931953F, 0.0F); + this.HeadSpike_4 = new ModelRenderer(this, 57, 21); + this.HeadSpike_4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpike_4.addBox(3.7F, -17.9F, 3.7F, 4, 17, 4, 0.0F); + this.setRotateAngle(HeadSpike_4, 0.0F, 0.7853981633974483F, 0.26703537555513246F); + this.HeadPlate_2 = new ModelRenderer(this, 58, 0); + this.HeadPlate_2.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadPlate_2.addBox(-5.0F, -17.0F, -9.2F, 10, 17, 4, 0.0F); + this.setRotateAngle(HeadPlate_2, 0.19634954084936207F, 0.0F, 0.0F); + this.EyeFrameR = new ModelRenderer(this, 4, 0); + this.EyeFrameR.setRotationPoint(3.0F, 0.0F, -9.2F); + this.EyeFrameR.addBox(0.0F, -11.0F, 0.0F, 1, 5, 2, 0.0F); + this.EyeFrameLT = new ModelRenderer(this, 0, 0); + this.EyeFrameLT.setRotationPoint(-4.0F, -10.0F, -9.2F); + this.EyeFrameLT.addBox(0.0F, -5.0F, 0.0F, 1, 5, 2, 0.0F); + this.setRotateAngle(EyeFrameLT, 0.0F, 0.0F, 0.7853981633974483F); + this.SpikeWrapper_3 = new ModelRenderer(this, 0, 0); + this.SpikeWrapper_3.setRotationPoint(0.0F, 0.0F, 0.0F); + this.SpikeWrapper_3.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(SpikeWrapper_3, 0.0F, 0.5235987755982988F, 0.0F); + this.Eye = new ModelRenderer(this, 73, 21); + this.Eye.setRotationPoint(0.0F, 4.8F, 0.5F); + this.Eye.addBox(-2.0F, -2.0F, -2.0F, 4, 4, 4, 0.0F); + this.setRotateAngle(Eye, -0.7853981633974483F, -0.6981317007977318F, 1.5707963267948966F); + this.HeadSpike_5 = new ModelRenderer(this, 57, 21); + this.HeadSpike_5.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpike_5.addBox(3.7F, -17.9F, 3.7F, 4, 17, 4, 0.0F); + this.setRotateAngle(HeadSpike_5, 0.0F, 0.7853981633974483F, 0.26703537555513246F); + this.Support_5 = new ModelRenderer(this, 31, 24); + this.Support_5.setRotationPoint(0.0F, -7.0F, 0.0F); + this.Support_5.addBox(23.5F, 0.0F, 0.0F, 6, 7, 7, 0.0F); + this.InnerSupport_2 = new ModelRenderer(this, 23, 38); + this.InnerSupport_2.setRotationPoint(0.0F, -10.0F, 0.0F); + this.InnerSupport_2.addBox(7.0F, -1.4F, -4.0F, 11, 2, 8, 0.0F); + this.setRotateAngle(InnerSupport_2, 0.0F, 0.0F, -0.4553564018453205F); + this.HeadGroup3 = new ModelRenderer(this, 0, 0); + this.HeadGroup3.setRotationPoint(0.0F, -2.0F, 0.0F); + this.HeadGroup3.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadGroup3, 0.0F, 2.0943951023931953F, 0.0F); + this.InnerSupport_5 = new ModelRenderer(this, 23, 38); + this.InnerSupport_5.setRotationPoint(0.0F, -10.0F, 0.0F); + this.InnerSupport_5.addBox(7.0F, -1.4F, -4.0F, 11, 2, 8, 0.0F); + this.setRotateAngle(InnerSupport_5, 0.0F, 0.0F, -0.4553564018453205F); + this.EyeBack = new ModelRenderer(this, 114, 0); + this.EyeBack.setRotationPoint(0.0F, -13.4F, -9.8F); + this.EyeBack.addBox(-3.0F, 0.0F, 0.0F, 6, 9, 1, 0.0F); + this.HeadExtended = new ModelRenderer(this, 64, 33); + this.HeadExtended.mirror = true; + this.HeadExtended.setRotationPoint(0.0F, -18.0F, -5.0F); + this.HeadExtended.addBox(-5.0F, 1.0F, 0.0F, 10, 1, 9, 0.0F); + this.setRotateAngle(HeadExtended, -0.2181661564992912F, 0.0F, 0.0F); + this.Support_1 = new ModelRenderer(this, 31, 24); + this.Support_1.setRotationPoint(0.0F, -7.0F, 0.0F); + this.Support_1.addBox(23.5F, 0.0F, 0.0F, 6, 7, 7, 0.0F); + this.Plating_2 = new ModelRenderer(this, 0, 32); + this.Plating_2.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Plating_2.addBox(29.0F, -8.0F, -8.0F, 1, 16, 16, 0.0F); + this.setRotateAngle(Plating_2, 0.7853981633974483F, 0.0F, -0.7853981633974483F); + this.HeadPlate_3 = new ModelRenderer(this, 58, 0); + this.HeadPlate_3.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadPlate_3.addBox(-5.0F, -17.0F, -9.2F, 10, 17, 4, 0.0F); + this.setRotateAngle(HeadPlate_3, 0.19634954084936207F, 0.0F, 0.0F); + this.HeadGroup6 = new ModelRenderer(this, 0, 0); + this.HeadGroup6.setRotationPoint(0.0F, -2.0F, 0.0F); + this.HeadGroup6.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadGroup6, 0.0F, 5.235987755982989F, 0.0F); + this.MidBody = new ModelRenderer(this, 0, 0); + this.MidBody.setRotationPoint(0.0F, 3.0F, 0.0F); + this.MidBody.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.PlateGroup1 = new ModelRenderer(this, 0, 0); + this.PlateGroup1.setRotationPoint(0.0F, 35.0F, 0.0F); + this.PlateGroup1.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.Bridge4 = new ModelRenderer(this, 36, 0); + this.Bridge4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Bridge4.addBox(-4.0F, -3.0F, 6.0F, 8, 9, 3, 0.0F); + this.setRotateAngle(Bridge4, -0.28361600344907856F, -0.7853981633974483F, 0.0F); + this.HeadSpikeWrapper_1 = new ModelRenderer(this, 0, 0); + this.HeadSpikeWrapper_1.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpikeWrapper_1.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadSpikeWrapper_1, 0.0F, 2.0943951023931953F, 0.0F); + this.SpikeCap_2 = new ModelRenderer(this, 7, 25); + this.SpikeCap_2.setRotationPoint(8.0F, -1.0F, 8.0F); + this.SpikeCap_2.addBox(0.0F, 0.0F, 0.0F, 6, 11, 6, 0.0F); + this.HeadSpike_1 = new ModelRenderer(this, 57, 21); + this.HeadSpike_1.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpike_1.addBox(3.7F, -17.9F, 3.7F, 4, 17, 4, 0.0F); + this.setRotateAngle(HeadSpike_1, 0.0F, 0.7853981633974483F, 0.26703537555513246F); + this.InnerSupport_4 = new ModelRenderer(this, 23, 38); + this.InnerSupport_4.setRotationPoint(0.0F, -10.0F, 0.0F); + this.InnerSupport_4.addBox(7.0F, -1.4F, -4.0F, 11, 2, 8, 0.0F); + this.setRotateAngle(InnerSupport_4, 0.0F, 0.0F, -0.4553564018453205F); + this.RunedSiding4 = new ModelRenderer(this, 48, 48); + this.RunedSiding4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.RunedSiding4.addBox(-4.0F, -4.0F, 6.0F, 8, 10, 4, 0.0F); + this.setRotateAngle(RunedSiding4, -0.39269908169872414F, -1.5707963267948966F, 0.0F); + this.SpikeCap_1 = new ModelRenderer(this, 7, 25); + this.SpikeCap_1.setRotationPoint(8.0F, -1.0F, 8.0F); + this.SpikeCap_1.addBox(0.0F, 0.0F, 0.0F, 6, 11, 6, 0.0F); + this.Head = new ModelRenderer(this, 0, 0); + this.Head.setRotationPoint(0.0F, 2.5F, 0.0F); + this.Head.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.EyeFrameRT = new ModelRenderer(this, 6, 7); + this.EyeFrameRT.setRotationPoint(4.0F, -10.0F, -9.2F); + this.EyeFrameRT.addBox(0.0F, 0.4F, 0.0F, 1, 5, 2, 0.0F); + this.setRotateAngle(EyeFrameRT, 0.0F, 0.0F, 2.356194490192345F); + this.RunedSiding1 = new ModelRenderer(this, 48, 48); + this.RunedSiding1.setRotationPoint(0.0F, 0.0F, 0.0F); + this.RunedSiding1.addBox(-4.0F, -4.0F, 6.0F, 8, 10, 4, 0.0F); + this.setRotateAngle(RunedSiding1, -0.39269908169872414F, 0.0F, 0.0F); + this.PlateGroup3 = new ModelRenderer(this, 0, 0); + this.PlateGroup3.setRotationPoint(0.0F, 35.0F, 0.0F); + this.PlateGroup3.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(PlateGroup3, 0.0F, 2.0943951023931953F, 0.0F); + this.Plating_3 = new ModelRenderer(this, 0, 32); + this.Plating_3.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Plating_3.addBox(29.0F, -8.0F, -8.0F, 1, 16, 16, 0.0F); + this.setRotateAngle(Plating_3, 0.7853981633974483F, 0.0F, -0.7853981633974483F); + this.Bridge1 = new ModelRenderer(this, 36, 0); + this.Bridge1.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Bridge1.addBox(-4.0F, -3.0F, 6.0F, 8, 9, 3, 0.0F); + this.setRotateAngle(Bridge1, -0.28361600344907856F, 0.7853981633974483F, 0.0F); + this.EyeFrameRB = new ModelRenderer(this, 6, 0); + this.EyeFrameRB.setRotationPoint(4.0F, -7.0F, -9.2F); + this.EyeFrameRB.addBox(0.0F, -5.0F, 0.0F, 1, 5, 2, 0.0F); + this.setRotateAngle(EyeFrameRB, 0.0F, 0.0F, -2.356194490192345F); + this.PlateGroup4 = new ModelRenderer(this, 0, 0); + this.PlateGroup4.setRotationPoint(0.0F, 35.0F, 0.0F); + this.PlateGroup4.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(PlateGroup4, 0.0F, 3.141592653589793F, 0.0F); + this.Cover = new ModelRenderer(this, 0, 0); + this.Cover.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Cover.addBox(-6.0F, -0.6F, -6.0F, 12, 1, 12, 0.0F); + this.setRotateAngle(Cover, 0.0F, 0.7853981633974483F, 0.0F); + this.HeadExtended_1 = new ModelRenderer(this, 64, 33); + this.HeadExtended_1.setRotationPoint(0.0F, -18.0F, -5.0F); + this.HeadExtended_1.addBox(-5.0F, 1.0F, 0.0F, 10, 1, 9, 0.0F); + this.setRotateAngle(HeadExtended_1, -0.2181661564992912F, 0.0F, 0.0F); + this.Spike = new ModelRenderer(this, 0, 0); + this.Spike.setRotationPoint(0.0F, -20.0F, 0.0F); + this.Spike.addBox(1.0F, 0.0F, 1.0F, 12, 12, 12, 0.0F); + this.setRotateAngle(Spike, 0.0F, 0.7853981633974483F, -0.6065019150680295F); + this.HeadExtended_4 = new ModelRenderer(this, 64, 33); + this.HeadExtended_4.mirror = true; + this.HeadExtended_4.setRotationPoint(0.0F, -18.0F, -5.0F); + this.HeadExtended_4.addBox(-5.0F, 1.0F, 0.0F, 10, 1, 9, 0.0F); + this.setRotateAngle(HeadExtended_4, -0.2181661564992912F, 0.0F, 0.0F); + this.InnerSupport_1 = new ModelRenderer(this, 23, 38); + this.InnerSupport_1.setRotationPoint(0.0F, -10.0F, 0.0F); + this.InnerSupport_1.addBox(7.0F, -1.4F, -4.0F, 11, 2, 8, 0.0F); + this.setRotateAngle(InnerSupport_1, 0.0F, 0.0F, -0.4553564018453205F); + this.SpikeCap_5 = new ModelRenderer(this, 7, 25); + this.SpikeCap_5.setRotationPoint(8.0F, -1.0F, 8.0F); + this.SpikeCap_5.addBox(0.0F, 0.0F, 0.0F, 6, 11, 6, 0.0F); + this.HeadExtended_5 = new ModelRenderer(this, 64, 33); + this.HeadExtended_5.setRotationPoint(0.0F, -18.0F, -5.0F); + this.HeadExtended_5.addBox(-5.0F, 1.0F, 0.0F, 10, 1, 9, 0.0F); + this.setRotateAngle(HeadExtended_5, -0.2181661564992912F, 0.0F, 0.0F); + this.Support_4 = new ModelRenderer(this, 31, 24); + this.Support_4.setRotationPoint(0.0F, -7.0F, 0.0F); + this.Support_4.addBox(23.5F, 0.0F, 0.0F, 6, 7, 7, 0.0F); + this.HeadPlate_1 = new ModelRenderer(this, 58, 0); + this.HeadPlate_1.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadPlate_1.addBox(-5.0F, -17.0F, -9.2F, 10, 17, 4, 0.0F); + this.setRotateAngle(HeadPlate_1, 0.19634954084936207F, 0.0F, 0.0F); + this.HeadGroup2 = new ModelRenderer(this, 0, 0); + this.HeadGroup2.setRotationPoint(0.0F, -2.0F, 0.0F); + this.HeadGroup2.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadGroup2, 0.0F, 1.0471975511965976F, 0.0F); + this.PlateGroup2 = new ModelRenderer(this, 0, 0); + this.PlateGroup2.setRotationPoint(0.0F, 35.0F, 0.0F); + this.PlateGroup2.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(PlateGroup2, 0.0F, 1.0471975511965976F, 0.0F); + this.SpikeWrapper_2 = new ModelRenderer(this, 0, 0); + this.SpikeWrapper_2.setRotationPoint(0.0F, 0.0F, 0.0F); + this.SpikeWrapper_2.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(SpikeWrapper_2, 0.0F, 0.5235987755982988F, 0.0F); + this.InnerSupport = new ModelRenderer(this, 23, 38); + this.InnerSupport.setRotationPoint(0.0F, -10.0F, 0.0F); + this.InnerSupport.addBox(7.0F, -1.4F, -4.0F, 11, 2, 8, 0.0F); + this.setRotateAngle(InnerSupport, 0.0F, 0.0F, -0.4553564018453205F); + this.Spike_2 = new ModelRenderer(this, 0, 0); + this.Spike_2.setRotationPoint(0.0F, -20.0F, 0.0F); + this.Spike_2.addBox(1.0F, 0.0F, 1.0F, 12, 12, 12, 0.0F); + this.setRotateAngle(Spike_2, 0.0F, 0.7853981633974483F, -0.6065019150680295F); + this.RunedSiding3 = new ModelRenderer(this, 48, 48); + this.RunedSiding3.setRotationPoint(0.0F, 0.0F, 0.0F); + this.RunedSiding3.addBox(-4.0F, -4.0F, 6.0F, 8, 10, 4, 0.0F); + this.setRotateAngle(RunedSiding3, -0.39269908169872414F, 3.141592653589793F, 0.0F); + this.HeadPlate = new ModelRenderer(this, 58, 0); + this.HeadPlate.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadPlate.addBox(-5.0F, -17.0F, -9.2F, 10, 17, 4, 0.0F); + this.setRotateAngle(HeadPlate, 0.19634954084936207F, 0.0F, 0.0F); + this.PlateGroup6 = new ModelRenderer(this, 0, 0); + this.PlateGroup6.setRotationPoint(0.0F, 35.0F, 0.0F); + this.PlateGroup6.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(PlateGroup6, 0.0F, 5.235987755982989F, 0.0F); + this.HeadGroup4 = new ModelRenderer(this, 0, 0); + this.HeadGroup4.setRotationPoint(0.0F, -2.0F, 0.0F); + this.HeadGroup4.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadGroup4, 0.0F, 3.141592653589793F, 0.0F); + this.RunedSiding2 = new ModelRenderer(this, 48, 48); + this.RunedSiding2.setRotationPoint(0.0F, 0.0F, 0.0F); + this.RunedSiding2.addBox(-4.0F, -4.0F, 6.0F, 8, 10, 4, 0.0F); + this.setRotateAngle(RunedSiding2, -0.39269908169872414F, 1.5707963267948966F, 0.0F); + this.Spike_5 = new ModelRenderer(this, 0, 0); + this.Spike_5.setRotationPoint(0.0F, -20.0F, 0.0F); + this.Spike_5.addBox(1.0F, 0.0F, 1.0F, 12, 12, 12, 0.0F); + this.setRotateAngle(Spike_5, 0.0F, 0.7853981633974483F, -0.6065019150680295F); + this.Bridge2 = new ModelRenderer(this, 36, 0); + this.Bridge2.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Bridge2.addBox(-4.0F, -3.0F, 6.0F, 8, 9, 3, 0.0F); + this.setRotateAngle(Bridge2, -0.28361600344907856F, 2.356194490192345F, 0.0F); + this.Spike_3 = new ModelRenderer(this, 0, 0); + this.Spike_3.setRotationPoint(0.0F, -20.0F, 0.0F); + this.Spike_3.addBox(1.0F, 0.0F, 1.0F, 12, 12, 12, 0.0F); + this.setRotateAngle(Spike_3, 0.0F, 0.7853981633974483F, -0.6065019150680295F); + this.HeadGroup5 = new ModelRenderer(this, 0, 0); + this.HeadGroup5.setRotationPoint(0.0F, -2.0F, 0.0F); + this.HeadGroup5.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadGroup5, 0.0F, 4.1887902047863905F, 0.0F); + this.SpikeCap_4 = new ModelRenderer(this, 7, 25); + this.SpikeCap_4.setRotationPoint(8.0F, -1.0F, 8.0F); + this.SpikeCap_4.addBox(0.0F, 0.0F, 0.0F, 6, 11, 6, 0.0F); + this.HeadSpikeWrapper = new ModelRenderer(this, 0, 0); + this.HeadSpikeWrapper.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpikeWrapper.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(HeadSpikeWrapper, 0.0F, 2.0943951023931953F, 0.0F); + this.HeadExtended_3 = new ModelRenderer(this, 64, 33); + this.HeadExtended_3.setRotationPoint(0.0F, -18.0F, -5.0F); + this.HeadExtended_3.addBox(-5.0F, 1.0F, 0.0F, 10, 1, 9, 0.0F); + this.setRotateAngle(HeadExtended_3, -0.2181661564992912F, 0.0F, 0.0F); + this.HeadPlate_4 = new ModelRenderer(this, 58, 0); + this.HeadPlate_4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadPlate_4.addBox(-5.0F, -17.0F, -9.2F, 10, 17, 4, 0.0F); + this.setRotateAngle(HeadPlate_4, 0.19634954084936207F, 0.0F, 0.0F); + this.PlateGroup5 = new ModelRenderer(this, 0, 0); + this.PlateGroup5.setRotationPoint(0.0F, 35.0F, 0.0F); + this.PlateGroup5.addBox(0.0F, 0.0F, 0.0F, 0, 0, 0, 0.0F); + this.setRotateAngle(PlateGroup5, 0.0F, 4.1887902047863905F, 0.0F); + this.HeadSpike = new ModelRenderer(this, 57, 21); + this.HeadSpike.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpike.addBox(3.7F, -17.9F, 3.7F, 4, 17, 4, 0.0F); + this.setRotateAngle(HeadSpike, 0.0F, 0.7853981633974483F, 0.26703537555513246F); + this.HeadSpike_2 = new ModelRenderer(this, 57, 21); + this.HeadSpike_2.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpike_2.addBox(3.7F, -17.9F, 3.7F, 4, 17, 4, 0.0F); + this.setRotateAngle(HeadSpike_2, 0.0F, 0.7853981633974483F, 0.26703537555513246F); + this.HeadSpike_3 = new ModelRenderer(this, 57, 21); + this.HeadSpike_3.setRotationPoint(0.0F, 0.0F, 0.0F); + this.HeadSpike_3.addBox(3.7F, -17.9F, 3.7F, 4, 17, 4, 0.0F); + this.setRotateAngle(HeadSpike_3, 0.0F, 0.7853981633974483F, 0.26703537555513246F); + this.EyeFrameLB = new ModelRenderer(this, 0, 7); + this.EyeFrameLB.setRotationPoint(-4.0F, -7.0F, -9.2F); + this.EyeFrameLB.addBox(0.0F, 0.4F, 0.0F, 1, 5, 2, 0.0F); + this.setRotateAngle(EyeFrameLB, 0.0F, 0.0F, -0.7853981633974483F); + this.Support_2 = new ModelRenderer(this, 31, 24); + this.Support_2.setRotationPoint(0.0F, -7.0F, 0.0F); + this.Support_2.addBox(23.5F, 0.0F, 0.0F, 6, 7, 7, 0.0F); + this.Plating_4 = new ModelRenderer(this, 0, 32); + this.Plating_4.setRotationPoint(0.0F, 0.0F, 0.0F); + this.Plating_4.addBox(29.0F, -8.0F, -8.0F, 1, 16, 16, 0.0F); + this.setRotateAngle(Plating_4, 0.7853981633974483F, 0.0F, -0.7853981633974483F); + this.PlateGroup6.addChild(this.SpikeWrapper_5); + this.HeadPlate_5.addChild(this.EyeFrameL); + this.PlateGroup1.addChild(this.Plating); + this.Spike.addChild(this.SpikeCap); + this.SpikeWrapper_1.addChild(this.Spike_1); + this.HeadPlate_2.addChild(this.HeadExtended_2); + this.PlateGroup2.addChild(this.SpikeWrapper_1); + this.PlateGroup2.addChild(this.Plating_1); + this.HeadGroup1.addChild(this.HeadPlate_5); + this.Head.addChild(this.HeadGroup1); + this.Plating.addChild(this.Support); + this.PlateGroup6.addChild(this.Plating_5); + this.SpikeWrapper_4.addChild(this.Spike_4); + this.HeadGroup5.addChild(this.HeadSpikeWrapper_3); + this.Spike_3.addChild(this.SpikeCap_3); + this.PlateGroup1.addChild(this.SpikeWrapper); + this.MidBody.addChild(this.Bridge3); + this.HeadGroup6.addChild(this.HeadSpikeWrapper_4); + this.HeadGroup1.addChild(this.HeadSpikeWrapper_5); + this.Plating_3.addChild(this.Support_3); + this.PlateGroup4.addChild(this.InnerSupport_3); + this.PlateGroup5.addChild(this.SpikeWrapper_4); + this.HeadGroup4.addChild(this.HeadSpikeWrapper_2); + this.HeadSpikeWrapper_4.addChild(this.HeadSpike_4); + this.HeadGroup4.addChild(this.HeadPlate_2); + this.HeadPlate_5.addChild(this.EyeFrameR); + this.HeadPlate_5.addChild(this.EyeFrameLT); + this.PlateGroup4.addChild(this.SpikeWrapper_3); + this.EyeBack.addChild(this.Eye); + this.HeadSpikeWrapper_5.addChild(this.HeadSpike_5); + this.Plating_5.addChild(this.Support_5); + this.PlateGroup3.addChild(this.InnerSupport_2); + this.Head.addChild(this.HeadGroup3); + this.PlateGroup6.addChild(this.InnerSupport_5); + this.Head.addChild(this.EyeBack); + this.HeadPlate.addChild(this.HeadExtended); + this.Plating_1.addChild(this.Support_1); + this.PlateGroup3.addChild(this.Plating_2); + this.HeadGroup5.addChild(this.HeadPlate_3); + this.Head.addChild(this.HeadGroup6); + this.MainBody.addChild(this.PlateGroup1); + this.MidBody.addChild(this.Bridge4); + this.HeadGroup3.addChild(this.HeadSpikeWrapper_1); + this.Spike_2.addChild(this.SpikeCap_2); + this.HeadSpikeWrapper_1.addChild(this.HeadSpike_1); + this.PlateGroup5.addChild(this.InnerSupport_4); + this.MidBody.addChild(this.RunedSiding4); + this.Spike_1.addChild(this.SpikeCap_1); + this.HeadPlate_5.addChild(this.EyeFrameRT); + this.MidBody.addChild(this.RunedSiding1); + this.MainBody.addChild(this.PlateGroup3); + this.PlateGroup4.addChild(this.Plating_3); + this.MidBody.addChild(this.Bridge1); + this.HeadPlate_5.addChild(this.EyeFrameRB); + this.MainBody.addChild(this.PlateGroup4); + this.MidBody.addChild(this.Cover); + this.HeadPlate_1.addChild(this.HeadExtended_1); + this.SpikeWrapper.addChild(this.Spike); + this.HeadPlate_4.addChild(this.HeadExtended_4); + this.PlateGroup2.addChild(this.InnerSupport_1); + this.Spike_5.addChild(this.SpikeCap_5); + this.HeadPlate_5.addChild(this.HeadExtended_5); + this.Plating_4.addChild(this.Support_4); + this.HeadGroup3.addChild(this.HeadPlate_1); + this.Head.addChild(this.HeadGroup2); + this.MainBody.addChild(this.PlateGroup2); + this.PlateGroup3.addChild(this.SpikeWrapper_2); + this.PlateGroup1.addChild(this.InnerSupport); + this.SpikeWrapper_2.addChild(this.Spike_2); + this.MidBody.addChild(this.RunedSiding3); + this.HeadGroup2.addChild(this.HeadPlate); + this.MainBody.addChild(this.PlateGroup6); + this.Head.addChild(this.HeadGroup4); + this.MidBody.addChild(this.RunedSiding2); + this.SpikeWrapper_5.addChild(this.Spike_5); + this.MidBody.addChild(this.Bridge2); + this.SpikeWrapper_3.addChild(this.Spike_3); + this.Head.addChild(this.HeadGroup5); + this.Spike_4.addChild(this.SpikeCap_4); + this.HeadGroup2.addChild(this.HeadSpikeWrapper); + this.HeadPlate_3.addChild(this.HeadExtended_3); + this.HeadGroup6.addChild(this.HeadPlate_4); + this.MainBody.addChild(this.PlateGroup5); + this.HeadSpikeWrapper.addChild(this.HeadSpike); + this.HeadSpikeWrapper_2.addChild(this.HeadSpike_2); + this.HeadSpikeWrapper_3.addChild(this.HeadSpike_3); + this.HeadPlate_5.addChild(this.EyeFrameLB); + this.Plating_2.addChild(this.Support_2); + this.PlateGroup5.addChild(this.Plating_4); + } + + private static final Minecraft minecraft = Minecraft.getMinecraft(); + + @Override + public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + final float partialTicks = minecraft.getRenderPartialTicks(); + + this.MainBody.render(scale); + this.MidBody.render(scale); + + this.Head.rotateAngleY = netHeadYaw / (180F / (float) Math.PI); + this.Head.render(scale); + } + + /** + * This is a helper function from Tabula to set the rotation of model parts + */ + public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) { + modelRenderer.rotateAngleX = x; + modelRenderer.rotateAngleY = y; + modelRenderer.rotateAngleZ = z; + } +} diff --git a/src/main/java/twilightforest/client/model/item/BuiltInItemModel.java b/src/main/java/twilightforest/client/model/item/BuiltInItemModel.java new file mode 100644 index 0000000000..63bc38238e --- /dev/null +++ b/src/main/java/twilightforest/client/model/item/BuiltInItemModel.java @@ -0,0 +1,79 @@ +package twilightforest.client.model.item; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.*; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.Nullable; +import javax.vecmath.Matrix4f; +import java.util.Collections; +import java.util.List; + +public abstract class BuiltInItemModel implements IBakedModel { + + private class Overrides extends ItemOverrideList { + + Overrides() { + super(Collections.emptyList()); + } + + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity) { + setItemStack(stack); + return BuiltInItemModel.this; + } + } + + private final TextureAtlasSprite particleTexture; + private final ItemOverrideList overrides = new Overrides(); + + protected BuiltInItemModel(String particleTextureName) { + this.particleTexture = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(particleTextureName); + } + + @Override + public List getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) { + return Collections.emptyList(); + } + + @Override + public boolean isAmbientOcclusion() { + return true; + } + + @Override + public boolean isGui3d() { + return true; + } + + @Override + public boolean isBuiltInRenderer() { + return true; + } + + @Override + public TextureAtlasSprite getParticleTexture() { + return particleTexture; + } + + @Override + public ItemOverrideList getOverrides() { + return overrides; + } + + @Override + public Pair handlePerspective(ItemCameraTransforms.TransformType cameraTransformType) { + setTransform(cameraTransformType); + return Pair.of(this, null); + } + + protected abstract void setItemStack(ItemStack stack); + + protected abstract void setTransform(ItemCameraTransforms.TransformType transform); +} diff --git a/src/main/java/twilightforest/client/model/item/ShaderGrabbagStackRenderer.java b/src/main/java/twilightforest/client/model/item/ShaderGrabbagStackRenderer.java new file mode 100644 index 0000000000..e78818d418 --- /dev/null +++ b/src/main/java/twilightforest/client/model/item/ShaderGrabbagStackRenderer.java @@ -0,0 +1,169 @@ +package twilightforest.client.model.item; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.block.model.*; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.event.ModelBakeEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.opengl.GL11; +import twilightforest.TFConfig; +import twilightforest.TwilightForestMod; +import twilightforest.client.TFClientEvents; +import twilightforest.client.shader.ShaderManager; +import twilightforest.compat.ie.ItemTFShaderGrabbag; + +public class ShaderGrabbagStackRenderer extends TileEntitySpecialRenderer { + + public static class DummyTile extends TileEntity {} + + private class BakedModel extends BuiltInItemModel { + + BakedModel() { + super("minecraft:blocks/iron_block"); + } + + @Override + protected void setItemStack(ItemStack stack) { + ShaderGrabbagStackRenderer.this.stack = stack; + } + + @Override + protected void setTransform(ItemCameraTransforms.TransformType transform) { + ShaderGrabbagStackRenderer.this.transform = transform; + } + } + + private ItemStack stack = ItemStack.EMPTY; + private ItemCameraTransforms.TransformType transform = ItemCameraTransforms.TransformType.NONE; + + private final ResourceLocation bg = new ResourceLocation(TwilightForestMod.ID, "textures/items/star_burst_mask.png"); + + private final ModelResourceLocation backModelLocation = new ModelResourceLocation(TwilightForestMod.ID + ":trophy_minor", "inventory"); + private final ModelResourceLocation caseModelLocation = new ModelResourceLocation(TwilightForestMod.ID + ":shader", "inventory"); + + private final ModelResourceLocation itemModelLocation; + + public ShaderGrabbagStackRenderer(ModelResourceLocation itemModelLocation) { + this.itemModelLocation = itemModelLocation; + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void onModelBake(ModelBakeEvent event) { + event.getModelRegistry().putObject(itemModelLocation, new BakedModel()); + } + + @Override + public void render(DummyTile te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { + GlStateManager.pushMatrix(); // Stack + 1 + GlStateManager.disableCull(); + + IBakedModel modelCase = Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getModelManager().getModel(caseModelLocation); + + // Render the trophy-backing if it's in a GUI. + if (transform == ItemCameraTransforms.TransformType.GUI) { + + IBakedModel modelBack = Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getModelManager().getModel(backModelLocation); + + GlStateManager.disableLighting(); + GlStateManager.pushMatrix(); // Stack + 2 + GlStateManager.translate(0.5F, 0.5F, -1.5F); + + Minecraft.getMinecraft().getRenderItem().renderItem(stack, ForgeHooksClient.handleCameraTransforms(modelBack, transform, false)); + + GlStateManager.popMatrix(); // Stack + 1 + GlStateManager.enableLighting(); + + GlStateManager.disableLighting(); + GlStateManager.translate(0.5F, 0.5F, 0F); + // Rotate the lunchbox if we're in the Gui. This is a setup for the next bit of rendering. + GlStateManager.rotate(TFConfig.rotateTrophyHeadsGui ? TFClientEvents.rotationTicker : 0F, 0.125F, 1F, 0.125F); + //GlStateManager.translate(0F, -0.5F, 0F); + } + + GlStateManager.pushMatrix(); // Stack + 2 + // Translate the item render to the right place if it's in inventory. + // Otherwise just re-scale the item because it's a bit big for the trophy sprite backing. + if (transform != ItemCameraTransforms.TransformType.GUI) GlStateManager.translate(0.5F, 0.5F, 0.5F); + else GlStateManager.scale(0.9F, 0.9F, 0.9F); + + // Render the lunchbox + Minecraft.getMinecraft().getRenderItem().renderItem(stack, ForgeHooksClient.handleCameraTransforms(modelCase, transform, false)); + GlStateManager.popMatrix(); // Stack + 1 + + // Render the star burst + if (transform == ItemCameraTransforms.TransformType.GUI) { + // Forgot why this was needed but it's needed + GlStateManager.enableLighting(); + + // Pop the previous stack and push new stack + GlStateManager.popMatrix(); // Stack + 0 + GlStateManager.pushMatrix(); // Stack + 1 + + GlStateManager.pushMatrix(); // Stack + 2 + + // Since we're in a new stack different than above rendering calls, we'll also need to re-translate. + // Z value -1 puts us behind the lunchbox but in front of trophy sprite + GlStateManager.translate(0.5F, 0.5F, -1.0F); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + + // Bind the star burst mask tex + Minecraft.getMinecraft().getTextureManager().bindTexture(bg); + + // Just gonna borrow your code for a sec blu, thnx + int c = blusunrize.immersiveengineering.client.ClientUtils.getFormattingColour(ItemTFShaderGrabbag.shader_bag.getRarity(stack).color); + + // unpack colors + float r = (c >> 16 & 0xFF) / 255.0f; + float g = (c >> 8 & 0xFF) / 255.0f; + float b = (c & 0xFF) / 255.0f; + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(x - 1, y + 1, 0) + .tex(0, 1) + .color(r, g, b, 1f) + .endVertex(); + buffer.pos(x + 1, y + 1, 0) + .tex(1, 1) + .color(r, g, b, 1f) + .endVertex(); + buffer.pos(x + 1, y - 1, 0) + .tex(1, 0) + .color(r, g, b, 1f) + .endVertex(); + buffer.pos(x - 1, y - 1, 0) + .tex(0, 0) + .color(r, g, b, 1f) + .endVertex(); + + // Shader, engage! + ShaderManager.useShader(ShaderManager.starburstShader, ShaderManager.Uniforms.TIME); + // Blur the star burst mask + GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + tessellator.draw(); + // Deblur, so we don't blur all of the textures in rendering calls afterwards + GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); + // Disengage shader + ShaderManager.releaseShader(); + + // reset color + GlStateManager.color(1f, 1f, 1f, 1f); + + GlStateManager.popMatrix(); // Stack + 1 + } + + GlStateManager.enableCull(); + GlStateManager.popMatrix(); // Stack + 0 + } +} diff --git a/src/main/java/twilightforest/client/model/item/package-info.java b/src/main/java/twilightforest/client/model/item/package-info.java new file mode 100644 index 0000000000..4380e59473 --- /dev/null +++ b/src/main/java/twilightforest/client/model/item/package-info.java @@ -0,0 +1,3 @@ +@mcp.MethodsReturnNonnullByDefault +@javax.annotation.ParametersAreNonnullByDefault +package twilightforest.client.model.item; diff --git a/src/main/java/twilightforest/client/particle/EntityTFAnnihilateFX.java b/src/main/java/twilightforest/client/particle/EntityTFAnnihilateFX.java deleted file mode 100644 index 8dda255f14..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFAnnihilateFX.java +++ /dev/null @@ -1,99 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.World; -import twilightforest.item.ItemTFCubeOfAnnihilation; -import twilightforest.item.ItemTFIceBomb; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class EntityTFAnnihilateFX extends EntityFX -{ - float initialParticleScale; - - public EntityTFAnnihilateFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) - { - this(par1World, par2, par4, par6, par8, par10, par12, 1.0F); - } - - public EntityTFAnnihilateFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) - { - super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); - this.motionX *= 0.10000000149011612D; - this.motionY *= 0.10000000149011612D; - this.motionZ *= 0.10000000149011612D; - this.motionX += par8 * 0.4D; - this.motionY += par10 * 0.4D; - this.motionZ += par12 * 0.4D; - this.particleRed = this.particleGreen = this.particleBlue = 1.0F; - this.particleScale *= 0.75F; - this.particleScale *= par14; - this.initialParticleScale = this.particleScale; - this.particleMaxAge = (int)(60.0D / (Math.random() * 0.8D + 0.6D)); - this.particleMaxAge = (int)((float)this.particleMaxAge * par14); - this.noClip = false; - - this.setParticleIcon(((ItemTFCubeOfAnnihilation)TFItems.cubeOfAnnihilation).getAnnihilateIcon()); - - this.onUpdate(); - } - - public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) - { - super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if (this.particleAge++ >= this.particleMaxAge) - { - this.setDead(); - } - - this.moveEntity(this.motionX, this.motionY, this.motionZ); - - this.motionX *= 0.9599999785423279D; - this.motionY *= 0.9599999785423279D; - this.motionZ *= 0.9599999785423279D; - //this.motionY -= 0.019999999552965164D; - - if (this.onGround) - { - this.motionX *= 0.699999988079071D; - this.motionZ *= 0.699999988079071D; - } - - this.particleScale *= 0.97D; - - if (this.particleScale < 0.4D) { - this.setDead(); - } - - float blacken = 0.985F; - - this.particleRed *= blacken; - this.particleGreen *= blacken; - this.particleBlue *= blacken; - - } - - public int getBrightnessForRender(float par1) - { - return 240 | 240 << 16; - } - - public int getFXLayer() - { - return 2; - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/particle/EntityTFBossTearFX.java b/src/main/java/twilightforest/client/particle/EntityTFBossTearFX.java deleted file mode 100644 index 3d16ffb7d3..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFBossTearFX.java +++ /dev/null @@ -1,99 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.world.World; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class EntityTFBossTearFX extends EntityFX -{ - public EntityTFBossTearFX(World par1World, double par2, double par4, double par6, Item par8Item) - { - super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); - this.setParticleIcon(par8Item.getIconFromDamage(0)); - this.particleRed = this.particleGreen = this.particleBlue = 1.0F; - this.particleGravity = Blocks.snow.blockParticleGravity * 2F; - this.particleScale = 16.0F; - - this.particleMaxAge = 20 + rand.nextInt(40); - } - - public EntityTFBossTearFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, Item par14Item) - { - this(par1World, par2, par4, par6, par14Item); - this.motionX *= 0.10000000149011612D; - this.motionY *= 0.10000000149011612D; - this.motionZ *= 0.10000000149011612D; - this.motionX += par8; - this.motionY += par10; - this.motionZ += par12; - } - - public int getFXLayer() - { - return 2; - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - super.onUpdate(); - - if (this.onGround && rand.nextBoolean()) - { - //worldObj.playSoundEffect(this.posX, this.posY + 1D, this.posZ, "random.fizz", 2.0F, 2.0F); - //worldObj.spawnParticle("lava", this.posX, this.posY, this.posZ, 0, 0, 0); - //worldObj.playAuxSFXAtEntity(null, 2001, (int)this.posX, (int)this.posY + 1, (int)this.posZ, 0); - //this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 2002, (int)this.posX, (int)this.posY, (int)this.posZ, 4037); - - worldObj.playSound(this.posX, this.posY + 1D, this.posZ, "random.glass", 0.5F, 1.0F, false); - - for (int var1 = 0; var1 < 50; ++var1) - { - double gaussX = rand.nextGaussian() * 0.1D; - double gaussY = rand.nextGaussian() * 0.2D; - double gaussZ = rand.nextGaussian() * 0.1D; - Item popItem = Items.ghast_tear; - - - worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(popItem), this.posX + rand.nextFloat() - rand.nextFloat(), this.posY + 0.5F, this.posZ + rand.nextFloat(), gaussX, gaussY, gaussZ); - } - this.setDead(); - } - } - - public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) - { - float f6 = ((float)this.particleTextureIndexX) / 16.0F; - float f7 = f6 + 0.015609375F * 4F; - float f8 = ((float)this.particleTextureIndexY) / 16.0F; - float f9 = f8 + 0.015609375F * 4F; - float f10 = 0.1F * this.particleScale; - - if (this.particleIcon != null) - { - f6 = this.particleIcon.getInterpolatedU(0); - f7 = this.particleIcon.getInterpolatedU(16.0F); - f8 = this.particleIcon.getInterpolatedV(0); - f9 = this.particleIcon.getInterpolatedV(16); - } - - float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)par2 - interpPosX); - float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)par2 - interpPosY); - float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)par2 - interpPosZ); - float f14 = 1.0F; - par1Tessellator.setColorOpaque_F(f14 * this.particleRed, f14 * this.particleGreen, f14 * this.particleBlue); - par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f6, (double)f9); - par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f6, (double)f8); - par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f7, (double)f8); - par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f7, (double)f9); - } - -} diff --git a/src/main/java/twilightforest/client/particle/EntityTFFireflyFX.java b/src/main/java/twilightforest/client/particle/EntityTFFireflyFX.java deleted file mode 100644 index 2aecb26f68..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFFireflyFX.java +++ /dev/null @@ -1,116 +0,0 @@ -// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. -// Jad home page: http://www.kpdus.com/jad.html -// Decompiler options: packimports(3) braces deadcode - -package twilightforest.client.particle; - - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.World; - -import org.lwjgl.opengl.GL11; - - -// Referenced classes of package net.minecraft.src: -// EntityFX, World, Tessellator - -public class EntityTFFireflyFX extends EntityFX -{ - - public EntityTFFireflyFX(World world, double d, double d1, double d2, - float f, float f1, float f2) - { - this(world, d, d1, d2, 1.0F, f, f1, f2); - } - - public EntityTFFireflyFX(World world, double d, double d1, double d2, - float f, float f1, float f2, float f3) - { - super(world, d, d1, d2, 0.0D, 0.0D, 0.0D); - motionX *= 2.10000000149011612D; - motionY *= 2.10000000149011612D; - motionZ *= 2.10000000149011612D; - if(f1 == 0.0F) - { - f1 = 1.0F; - } - particleRed = particleGreen = 1.0F * f; - particleRed *= 0.9F; - particleBlue = 0.0F; - particleScale *= 1.0F; - particleScale *= f; - fireflyParticleScale = particleScale; - particleMaxAge = (int)(32D / (Math.random() * 0.80000000000000004D + 0.20000000000000001D)); - particleMaxAge *= f; - fireflyHalfLife = particleMaxAge / 2; - noClip = false; - } - - public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) - { - float f6 = (float)this.particleTextureIndexX / 16.0F; - float f7 = f6 + 0.0624375F; - float f8 = (float)this.particleTextureIndexY / 16.0F; - float f9 = f8 + 0.0624375F; - float f10 = 0.1F * this.particleScale; - - - particleScale = fireflyParticleScale; - GL11.glDisable(3008 /*GL_ALPHA_TEST*/); - GL11.glEnable(3042 /*GL_BLEND*/); - GL11.glColorMask(true, true, true, true); - GL11.glBlendFunc(770, 1); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5f); - - float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)par2 - interpPosX); - float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)par2 - interpPosY); - float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)par2 - interpPosZ); - float f14 = 1.0F; - par1Tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha); - par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9); - par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8); - par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8); - par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9); - - GL11.glDisable(3042 /*GL_BLEND*/); - GL11.glEnable(3008 /*GL_ALPHA_TEST*/); - } - - - public void onUpdate() - { - prevPosX = posX; - prevPosY = posY; - prevPosZ = posZ; - if(particleAge++ >= particleMaxAge) - { - setDead(); - } - if (particleAge < fireflyHalfLife) - { - // get bigger - setParticleTextureIndex((particleAge * 8) / fireflyHalfLife); - } else { - // get smaller - setParticleTextureIndex(7 - ((particleAge - fireflyHalfLife) * 8) / particleMaxAge); - } - moveEntity(motionX, motionY, motionZ); - if(posY == prevPosY) - { - motionX *= 1.1000000000000001D; - motionZ *= 1.1000000000000001D; - } - motionX *= 0.95999997854232788D; - motionY *= 0.95999997854232788D; - motionZ *= 0.95999997854232788D; - if(onGround) - { - motionX *= 0.69999998807907104D; - motionZ *= 0.69999998807907104D; - } - } - - float fireflyParticleScale; - int fireflyHalfLife; -} diff --git a/src/main/java/twilightforest/client/particle/EntityTFGhastTrapFX.java b/src/main/java/twilightforest/client/particle/EntityTFGhastTrapFX.java deleted file mode 100644 index 6b29e7d021..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFGhastTrapFX.java +++ /dev/null @@ -1,127 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.World; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class EntityTFGhastTrapFX extends EntityFX -{ - float reddustParticleScale; - private double originX; - private double originY; - private double originZ; - - public EntityTFGhastTrapFX(World par1World, double par2, double par4, double par6, double par8, double par9, double par10) - { - this(par1World, par2, par4, par6, 3.0F, par8, par9, par10); - } - - public EntityTFGhastTrapFX(World par1World, double x, double y, double z, float scale, double mx, double my, double mz) - { - super(par1World, x + mx, y + my, z + mz, mx, my, mz); - this.motionX = mx; - this.motionY = my; - this.motionZ = mz; - - this.originX = x; - this.originY = y; - this.originZ = z; - - float f4 = (float)Math.random() * 0.4F;// + 0.6F; - //this.particleRed = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) * f4; - this.particleGreen = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) * f4; - this.particleBlue = ((float)(Math.random() * 0.20000000298023224D) + 0.8F) * f4; - - this.particleRed = 1.0F; - - this.particleScale *= 0.75F; - this.particleScale *= scale; - this.reddustParticleScale = this.particleScale; - this.particleMaxAge = (int)(10.0D / (Math.random() * 0.8D + 0.2D)); - //this.particleMaxAge = (int)((float)this.particleMaxAge * scale); - - this.noClip = false; - } - - public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) - { - float f6 = ((float)this.particleAge + par2) / (float)this.particleMaxAge * 32.0F; - - if (f6 < 0.0F) - { - f6 = 0.0F; - } - - if (f6 > 1.0F) - { - f6 = 1.0F; - } - - this.particleScale = this.reddustParticleScale * f6; - super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); - } - -// /** -// * Called to update the entity's position/logic. -// */ -// public void onUpdate() -// { -// this.prevPosX = this.posX; -// this.prevPosY = this.posY; -// this.prevPosZ = this.posZ; -// -// if (this.particleAge++ >= this.particleMaxAge) -// { -// this.setDead(); -// } -// -// this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); -// this.moveEntity(this.motionX, this.motionY, this.motionZ); -// -// if (this.posY == this.prevPosY) -// { -// this.motionX *= 1.1D; -// this.motionZ *= 1.1D; -// } -// -// this.motionX *= 0.9599999785423279D; -// this.motionY *= 0.9599999785423279D; -// this.motionZ *= 0.9599999785423279D; -// -// if (this.onGround) -// { -// this.motionX *= 0.699999988079071D; -// this.motionZ *= 0.699999988079071D; -// } -// } - - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - - this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); - - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - float proportion = (float)this.particleAge / (float)this.particleMaxAge; - proportion = 1.0F - proportion; -// float antiProportion = 1.0F - proportion; -// antiProportion *= antiProportion; -// antiProportion *= antiProportion; - this.posX = this.originX + this.motionX * (double)proportion; - this.posY = this.originY + this.motionY * (double)proportion;// - (double)(antiProportion * 1.2F); - this.posZ = this.originZ + this.motionZ * (double)proportion; - - if (this.particleAge++ >= this.particleMaxAge) - { - this.setDead(); - } - } -} diff --git a/src/main/java/twilightforest/client/particle/EntityTFIceBeamFX.java b/src/main/java/twilightforest/client/particle/EntityTFIceBeamFX.java deleted file mode 100644 index ea55680c66..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFIceBeamFX.java +++ /dev/null @@ -1,86 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.World; -import twilightforest.item.ItemTFIceBomb; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class EntityTFIceBeamFX extends EntityFX -{ - float initialParticleScale; - - public EntityTFIceBeamFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) - { - this(par1World, par2, par4, par6, par8, par10, par12, 1.0F); - } - - public EntityTFIceBeamFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) - { - super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); - this.motionX *= 0.10000000149011612D; - this.motionY *= 0.10000000149011612D; - this.motionZ *= 0.10000000149011612D; - this.motionX += par8 * 0.4D; - this.motionY += par10 * 0.4D; - this.motionZ += par12 * 0.4D; - this.particleRed = this.particleGreen = this.particleBlue = 1.0F; - this.particleScale *= 0.75F; - this.particleScale *= par14; - this.initialParticleScale = this.particleScale; -// this.particleMaxAge = (int)(6.0D / (Math.random() * 0.8D + 0.6D)); -// this.particleMaxAge = (int)((float)this.particleMaxAge * par14); - this.particleMaxAge = 50; - this.noClip = false; - - this.setParticleIcon(((ItemTFIceBomb)TFItems.iceBomb).getSnowIcon(rand.nextInt(4))); - - this.onUpdate(); - } - - public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) - { - super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if (this.particleAge++ >= this.particleMaxAge) - { - this.setDead(); - } - - this.moveEntity(this.motionX, this.motionY, this.motionZ); - - this.motionX *= 0.9599999785423279D; - this.motionY *= 0.9599999785423279D; - this.motionZ *= 0.9599999785423279D; - //this.motionY -= 0.019999999552965164D; - - if (this.onGround) - { - this.motionX *= 0.699999988079071D; - this.motionZ *= 0.699999988079071D; - } - } - - public int getBrightnessForRender(float par1) - { - return 240 | 240 << 16; - } - - public int getFXLayer() - { - return 2; - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/particle/EntityTFLargeFlameFX.java b/src/main/java/twilightforest/client/particle/EntityTFLargeFlameFX.java deleted file mode 100644 index 3b26787f28..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFLargeFlameFX.java +++ /dev/null @@ -1,111 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.World; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class EntityTFLargeFlameFX extends EntityFX -{ - /** the scale of the flame FX */ - private float flameScale; - - public EntityTFLargeFlameFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) - { - super(par1World, par2, par4, par6, par8, par10, par12); - this.motionX = this.motionX * 0.009999999776482582D + par8; - this.motionY = this.motionY * 0.009999999776482582D + par10; - this.motionZ = this.motionZ * 0.009999999776482582D + par12; - this.particleScale *= 5.0D; - this.flameScale = this.particleScale; - this.particleRed = this.particleGreen = this.particleBlue = 1.0F; - this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D)) + 4; - //this.noClip = true; - this.setParticleTextureIndex(48); - } - - public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) - { - float var8 = ((float)this.particleAge + par2) / (float)this.particleMaxAge; - this.particleScale = this.flameScale * (1.0F - var8 * var8 * 0.5F); - super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); - } - - public int getBrightnessForRender(float par1) - { - float var2 = ((float)this.particleAge + par1) / (float)this.particleMaxAge; - - if (var2 < 0.0F) - { - var2 = 0.0F; - } - - if (var2 > 1.0F) - { - var2 = 1.0F; - } - - int var3 = super.getBrightnessForRender(par1); - int var4 = var3 & 255; - int var5 = var3 >> 16 & 255; - var4 += (int)(var2 * 15.0F * 16.0F); - - if (var4 > 240) - { - var4 = 240; - } - - return var4 | var5 << 16; - } - - /** - * Gets how bright this entity is. - */ - public float getBrightness(float par1) - { - float var2 = ((float)this.particleAge + par1) / (float)this.particleMaxAge; - - if (var2 < 0.0F) - { - var2 = 0.0F; - } - - if (var2 > 1.0F) - { - var2 = 1.0F; - } - - float var3 = super.getBrightness(par1); - return var3 * var2 + (1.0F - var2); - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if (this.particleAge++ >= this.particleMaxAge) - { - this.setDead(); - } - - this.motionY += 0.004D; - - this.moveEntity(this.motionX, this.motionY, this.motionZ); - this.motionX *= 0.9599999785423279D; - this.motionY *= 0.9599999785423279D; - this.motionZ *= 0.9599999785423279D; - - if (this.onGround) - { - this.motionX *= 0.699999988079071D; - this.motionZ *= 0.699999988079071D; - } - } -} diff --git a/src/main/java/twilightforest/client/particle/EntityTFLeafRuneFX.java b/src/main/java/twilightforest/client/particle/EntityTFLeafRuneFX.java deleted file mode 100644 index 325043c4d5..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFLeafRuneFX.java +++ /dev/null @@ -1,39 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityEnchantmentTableParticleFX; -import net.minecraft.world.World; - -public class EntityTFLeafRuneFX extends EntityEnchantmentTableParticleFX { - - public EntityTFLeafRuneFX(World world, double x, double y, double z, double velX, double velY, double velZ) - { - super(world, x, y, z, velX, velY, velZ); - - this.particleScale = this.rand.nextFloat() + 1F; - this.particleMaxAge += 10; - this.particleGravity = 0.003F + rand.nextFloat() * 0.006F; - - - this.noClip = false; - } - - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - this.moveEntity(this.motionX, this.motionY, this.motionZ); - this.motionY -= (double)this.particleGravity; - - - if (this.particleAge++ >= this.particleMaxAge) - { - this.setDead(); - } - } -} diff --git a/src/main/java/twilightforest/client/particle/EntityTFProtectionFX.java b/src/main/java/twilightforest/client/particle/EntityTFProtectionFX.java deleted file mode 100644 index ba1008ca26..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFProtectionFX.java +++ /dev/null @@ -1,29 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityAuraFX; -import net.minecraft.world.World; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class EntityTFProtectionFX extends EntityAuraFX { - - public EntityTFProtectionFX(World world, double x, double y, double z, double velX, double velY, double velZ) { - super(world, x, y, z, velX, velY, velZ); - this.setParticleTextureIndex(82); - this.setRBGColorF(1.0F, 1.0F, 1.0F); - } - - /** - * Gets how bright this entity is. - */ - public float getBrightness(float par1) - { - return 1.0F; - } - - @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float par1) - { - return 15728880; - } -} diff --git a/src/main/java/twilightforest/client/particle/EntityTFSnowFX.java b/src/main/java/twilightforest/client/particle/EntityTFSnowFX.java deleted file mode 100644 index ba6bfd0faa..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFSnowFX.java +++ /dev/null @@ -1,85 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.client.particle.EntityFX; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.World; -import twilightforest.item.ItemTFIceBomb; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class EntityTFSnowFX extends EntityFX -{ - float initialParticleScale; - - public EntityTFSnowFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) - { - this(par1World, par2, par4, par6, par8, par10, par12, 1.0F); - } - - public EntityTFSnowFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) - { - super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D); - this.motionX *= 0.10000000149011612D; - this.motionY *= 0.10000000149011612D; - this.motionZ *= 0.10000000149011612D; - this.motionX += par8 * 0.4D; - this.motionY += par10 * 0.4D; - this.motionZ += par12 * 0.4D; - this.particleRed = this.particleGreen = this.particleBlue = 1.0F; - this.particleScale *= 0.75F; - this.particleScale *= par14; - this.initialParticleScale = this.particleScale; - this.particleMaxAge = (int)(6.0D / (Math.random() * 0.8D + 0.6D)); - this.particleMaxAge = (int)((float)this.particleMaxAge * par14); - this.noClip = false; - - this.setParticleIcon(((ItemTFIceBomb)TFItems.iceBomb).getSnowIcon(rand.nextInt(4))); - - this.onUpdate(); - } - - public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) - { - super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if (this.particleAge++ >= this.particleMaxAge) - { - this.setDead(); - } - - this.moveEntity(this.motionX, this.motionY, this.motionZ); - - this.motionX *= 0.699999988079071D; - this.motionY *= 0.699999988079071D; - this.motionZ *= 0.699999988079071D; - this.motionY -= 0.019999999552965164D; - - if (this.onGround) - { - this.motionX *= 0.699999988079071D; - this.motionZ *= 0.699999988079071D; - } - } - - public int getBrightnessForRender(float par1) - { - return 240 | 240 << 16; - } - - public int getFXLayer() - { - return 2; - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/particle/EntityTFSnowGuardianFX.java b/src/main/java/twilightforest/client/particle/EntityTFSnowGuardianFX.java deleted file mode 100644 index dec370fcc9..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFSnowGuardianFX.java +++ /dev/null @@ -1,17 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.world.World; - -public class EntityTFSnowGuardianFX extends EntityTFSnowFX { - - public EntityTFSnowGuardianFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) { - super(par1World, par2, par4, par6, par8, par10, par12, par14); - this.particleMaxAge = 10 + this.rand.nextInt(15); - - this.particleRed = this.particleGreen = this.particleBlue = 0.75F + this.rand.nextFloat() * 0.25F; - - } - - - -} diff --git a/src/main/java/twilightforest/client/particle/EntityTFSnowWarningFX.java b/src/main/java/twilightforest/client/particle/EntityTFSnowWarningFX.java deleted file mode 100644 index 0cca4eab61..0000000000 --- a/src/main/java/twilightforest/client/particle/EntityTFSnowWarningFX.java +++ /dev/null @@ -1,23 +0,0 @@ -package twilightforest.client.particle; - -import net.minecraft.world.World; - -public class EntityTFSnowWarningFX extends EntityTFSnowFX { - - public EntityTFSnowWarningFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14) { - super(par1World, par2, par4, par6, par8, par10, par12, par14); - this.particleMaxAge = 50; - } - - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - super.onUpdate(); - - this.motionY -= 0.019999999552965164D; - } - -} diff --git a/src/main/java/twilightforest/client/particle/ParticleAnnihilate.java b/src/main/java/twilightforest/client/particle/ParticleAnnihilate.java new file mode 100644 index 0000000000..c437306d9b --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleAnnihilate.java @@ -0,0 +1,85 @@ +package twilightforest.client.particle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; + +@SideOnly(Side.CLIENT) +public class ParticleAnnihilate extends Particle { + + float initialParticleScale; + + public ParticleAnnihilate(World world, double x, double y, double z, double vx, double vy, double vz) { + this(world, x, y, z, vx, vy, vz, 1.0F); + } + + public ParticleAnnihilate(World world, double x, double y, double z, double vx, double vy, double vz, float scale) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += vx * 0.4D; + this.motionY += vy * 0.4D; + this.motionZ += vz * 0.4D; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleScale *= 0.75F; + this.particleScale *= scale; + this.initialParticleScale = this.particleScale; + this.particleMaxAge = (int) (60.0D / (Math.random() * 0.8D + 0.6D)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * scale); + this.canCollide = true; + + this.setParticleTexture(Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(TwilightForestMod.ID + ":particles/annihilate_particle")); + + this.onUpdate(); + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setExpired(); + } + + this.move(this.motionX, this.motionY, this.motionZ); + + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + //this.motionY -= 0.019999999552965164D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + + this.particleScale *= 0.97D; + + if (this.particleScale < 0.4D) { + this.setExpired(); + } + + float blacken = 0.985F; + + this.particleRed *= blacken; + this.particleGreen *= blacken; + this.particleBlue *= blacken; + + } + + @Override + public int getBrightnessForRender(float partialTicks) { + return 240 | 240 << 16; + } + + @Override + public int getFXLayer() { + return 1; + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleFirefly.java b/src/main/java/twilightforest/client/particle/ParticleFirefly.java new file mode 100644 index 0000000000..10ba9ff282 --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleFirefly.java @@ -0,0 +1,71 @@ +package twilightforest.client.particle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.entity.Entity; +import net.minecraft.world.World; +import twilightforest.TwilightForestMod; + +public class ParticleFirefly extends Particle { + + private int lifeTime; + private int halfLife; + + public ParticleFirefly(World world, double x, double y, double z, double f, double f1, double f2) { + this(world, x, y, z, 1.0F, f, f1, f2); + } + + public ParticleFirefly(World world, double x, double y, double z, float f, double f1, double f2, double f3) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + motionX *= 2.10000000149011612D; + motionY *= 2.10000000149011612D; + motionZ *= 2.10000000149011612D; + particleRed = particleGreen = 1.0F * f; + particleRed *= 0.9F; + particleBlue = 0.0F; + particleScale = 1.0f + (rand.nextFloat() * 0.6f); + particleScale *= f; + lifeTime = particleMaxAge = 10 + rand.nextInt(21); + particleMaxAge *= f; + halfLife = lifeTime / 2; + canCollide = true; + + setParticleTexture(Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(TwilightForestMod.ID + ":particles/firefly")); + } + + @Override + public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, + float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { + + particleAlpha = getGlowBrightness(); + super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); + } + + @Override + public void onUpdate() { + if (lifeTime <= 1) { + setExpired(); + } else { + lifeTime--; + } + } + + public float getGlowBrightness() { + if (lifeTime <= halfLife) { + return (float) lifeTime / (float) halfLife; + } else { + return Math.max(1.0f - (((float) lifeTime - halfLife) / halfLife), 0); + } + } + + @Override + public int getBrightnessForRender(float partialTicks) { + return 0xF000F0; + } + + @Override + public int getFXLayer() { + return 1; + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleGhastTear.java b/src/main/java/twilightforest/client/particle/ParticleGhastTear.java new file mode 100644 index 0000000000..e03863fbaf --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleGhastTear.java @@ -0,0 +1,67 @@ +package twilightforest.client.particle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.Item; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.SoundCategory; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class ParticleGhastTear extends Particle { + + public ParticleGhastTear(World world, double x, double y, double z, Item item) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + this.setParticleTexture(Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getParticleIcon(item)); + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleGravity = Blocks.SNOW.blockParticleGravity * 2F; + this.particleScale = 16.0F; + + this.particleMaxAge = 20 + rand.nextInt(40); + this.canCollide = true; + } + + public ParticleGhastTear(World world, double x, double y, double z, double vx, double vy, double vz, Item item) { + this(world, x, y, z, item); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += vx; + this.motionY += vy; + this.motionZ += vz; + + //TwilightForestMod.LOGGER.info("creating tear particle {}, isremote {}", this, world.isRemote); + } + + @Override + public int getFXLayer() { + return 1; + } + + @Override + public void onUpdate() { + if (this.onGround && rand.nextBoolean()) { + world.playSound(null, this.posX, this.posY + 1D, this.posZ, SoundEvents.BLOCK_GLASS_BREAK, SoundCategory.HOSTILE, 0.5F, 1.0F); + + int itemID = Item.getIdFromItem(Items.GHAST_TEAR); + for (int i = 0; i < 20; ++i) { + double gaussX = rand.nextGaussian() * 0.1D; + double gaussY = rand.nextGaussian() * 0.2D; + double gaussZ = rand.nextGaussian() * 0.1D; + + //TwilightForestMod.LOGGER.info("tear impact {}, isremote {}", this, world.isRemote); + + world.spawnParticle(EnumParticleTypes.ITEM_CRACK, this.posX + rand.nextFloat() - rand.nextFloat(), this.posY + 0.5F, this.posZ + rand.nextFloat(), gaussX, gaussY, gaussZ, itemID); + world.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); + + } + this.setExpired(); + } + super.onUpdate(); + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleGhastTrap.java b/src/main/java/twilightforest/client/particle/ParticleGhastTrap.java new file mode 100644 index 0000000000..2cfc636c1e --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleGhastTrap.java @@ -0,0 +1,116 @@ +package twilightforest.client.particle; + +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class ParticleGhastTrap extends Particle { + + float reddustParticleScale; + + private double originX; + private double originY; + private double originZ; + + public ParticleGhastTrap(World world, double x, double y, double z, double vx, double vy, double vz) { + this(world, x, y, z, 3.0F, vx, vy, vz); + } + + public ParticleGhastTrap(World world, double x, double y, double z, float scale, double mx, double my, double mz) { + super(world, x + mx, y + my, z + mz, mx, my, mz); + this.motionX = mx; + this.motionY = my; + this.motionZ = mz; + + this.originX = x; + this.originY = y; + this.originZ = z; + + float brightness = (float) Math.random() * 0.4F;// + 0.6F; + //this.particleRed = ((float) (Math.random() * 0.20000000298023224D) + 0.8F) * brightness; + this.particleGreen = ((float) (Math.random() * 0.20000000298023224D) + 0.8F) * brightness; + this.particleBlue = ((float) (Math.random() * 0.20000000298023224D) + 0.8F) * brightness; + + this.particleRed = 1.0F; + + this.particleScale *= 0.75F; + this.particleScale *= scale; + this.reddustParticleScale = this.particleScale; + this.particleMaxAge = (int) (10.0D / (Math.random() * 0.8D + 0.2D)); + //this.particleMaxAge = (int)((float)this.particleMaxAge * scale); + + this.canCollide = true; + } + + @Override + public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, + float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { + + float f6 = ((float) this.particleAge + partialTicks) / (float) this.particleMaxAge * 32.0F; + f6 = MathHelper.clamp(f6, 0f, 1f); + + this.particleScale = this.reddustParticleScale * f6; + super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); + } + +// /** +// * Called to update the entity's position/logic. +// */ +// public void onUpdate() +// { +// this.prevPosX = this.posX; +// this.prevPosY = this.posY; +// this.prevPosZ = this.posZ; +// +// if (this.particleAge++ >= this.particleMaxAge) +// { +// this.setDead(); +// } +// +// this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); +// this.moveEntity(this.motionX, this.motionY, this.motionZ); +// +// if (this.posY == this.prevPosY) +// { +// this.motionX *= 1.1D; +// this.motionZ *= 1.1D; +// } +// +// this.motionX *= 0.9599999785423279D; +// this.motionY *= 0.9599999785423279D; +// this.motionZ *= 0.9599999785423279D; +// +// if (this.isCollided) +// { +// this.motionX *= 0.699999988079071D; +// this.motionZ *= 0.699999988079071D; +// } +// } + + @Override + public void onUpdate() { + + this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge); + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + float proportion = (float) this.particleAge / (float) this.particleMaxAge; + proportion = 1.0F - proportion; +// float antiProportion = 1.0F - proportion; +// antiProportion *= antiProportion; +// antiProportion *= antiProportion; + this.posX = this.originX + this.motionX * (double) proportion; + this.posY = this.originY + this.motionY * (double) proportion;// - (double)(antiProportion * 1.2F); + this.posZ = this.originZ + this.motionZ * (double) proportion; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setExpired(); + } + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleIceBeam.java b/src/main/java/twilightforest/client/particle/ParticleIceBeam.java new file mode 100644 index 0000000000..c5eaaaf4c8 --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleIceBeam.java @@ -0,0 +1,73 @@ +package twilightforest.client.particle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; + +@SideOnly(Side.CLIENT) +public class ParticleIceBeam extends Particle { + + float initialParticleScale; + + public ParticleIceBeam(World world, double x, double y, double z, double vx, double vy, double vz) { + this(world, x, y, z, vx, vy, vz, 1.0F); + } + + public ParticleIceBeam(World world, double x, double y, double z, double vx, double vy, double vz, float scale) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += vx * 0.4D; + this.motionY += vy * 0.4D; + this.motionZ += vz * 0.4D; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleScale *= 0.75F; + this.particleScale *= scale; + this.initialParticleScale = this.particleScale; +// this.particleMaxAge = (int)(6.0D / (Math.random() * 0.8D + 0.6D)); +// this.particleMaxAge = (int)((float)this.particleMaxAge * scale); + this.particleMaxAge = 50; + this.canCollide = true; + + this.setParticleTexture(Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(TwilightForestMod.ID + ":particles/snow_" + rand.nextInt(4))); + + this.onUpdate(); + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setExpired(); + } + + this.move(this.motionX, this.motionY, this.motionZ); + + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + //this.motionY -= 0.019999999552965164D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } + + @Override + public int getBrightnessForRender(float partialTicks) { + return 240 | 240 << 16; + } + + @Override + public int getFXLayer() { + return 1; + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleLargeFlame.java b/src/main/java/twilightforest/client/particle/ParticleLargeFlame.java new file mode 100644 index 0000000000..6e9ae2b20a --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleLargeFlame.java @@ -0,0 +1,83 @@ +package twilightforest.client.particle; + +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.entity.Entity; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class ParticleLargeFlame extends Particle { + + private float flameScale; + + public ParticleLargeFlame(World world, double x, double y, double z, double vx, double vy, double vz) { + super(world, x, y, z, vx, vy, vz); + this.motionX = this.motionX * 0.009999999776482582D + vx; + this.motionY = this.motionY * 0.009999999776482582D + vy; + this.motionZ = this.motionZ * 0.009999999776482582D + vz; + this.particleScale *= 5.0D; + this.flameScale = this.particleScale; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleMaxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)) + 4; + //this.noClip = true; + this.setParticleTextureIndex(48); + } + + @Override + public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, + float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { + + float var8 = ((float) this.particleAge + partialTicks) / (float) this.particleMaxAge; + this.particleScale = this.flameScale * (1.0F - var8 * var8 * 0.5F); + super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); + } + + @Override + public int getBrightnessForRender(float partialTicks) { + float var2 = ((float) this.particleAge + partialTicks) / (float) this.particleMaxAge; + + if (var2 < 0.0F) { + var2 = 0.0F; + } + + if (var2 > 1.0F) { + var2 = 1.0F; + } + + int var3 = super.getBrightnessForRender(partialTicks); + int var4 = var3 & 255; + int var5 = var3 >> 16 & 255; + var4 += (int) (var2 * 15.0F * 16.0F); + + if (var4 > 240) { + var4 = 240; + } + + return var4 | var5 << 16; + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setExpired(); + } + + this.motionY += 0.004D; + + this.move(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleLeaf.java b/src/main/java/twilightforest/client/particle/ParticleLeaf.java new file mode 100644 index 0000000000..875b4776d4 --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleLeaf.java @@ -0,0 +1,92 @@ +package twilightforest.client.particle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; + +@SideOnly(Side.CLIENT) +public class ParticleLeaf extends Particle { + + private final Vec3d target; + private float rot; + + public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz) { + this(world, x, y, z, vx, vy, vz, 1.0F); + } + + public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz, float scale) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + target = new Vec3d(x, y, z); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += vx * 0.4D; + this.motionY += vy * 0.4D; + this.motionZ += vz * 0.4D; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleAlpha = 0F; + this.particleScale *= 0.75F * (rand.nextBoolean() ? -1F : 1F); + this.particleScale *= scale; + this.particleMaxAge = 160 + ((int) (rand.nextFloat() * 30F)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * scale); + this.canCollide = true; + + this.setParticleTexture(Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(TwilightForestMod.ID + ":particles/fallen_leaf")); + + this.onUpdate(); + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setExpired(); + } + + this.move(this.motionX, this.motionY, this.motionZ); + + this.motionY *= 0.699999988079071D; + this.motionY -= 0.019999999552965164D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } else { + rot += 5F; + if (motionX == 0) + motionX += (rand.nextBoolean() ? 1 : -1) * 0.001F; + if (motionZ == 0) + motionZ += (rand.nextBoolean() ? 1 : -1) * 0.001F; + if (rand.nextInt(5) == 0) + motionX += Math.signum(target.x - posX) * rand.nextFloat() * 0.005F; + if (rand.nextInt(5) == 0) + motionZ += Math.signum(target.z - posZ) * rand.nextFloat() * 0.005F; + } + } + + @Override + public void renderParticle(BufferBuilder buffer, Entity entityIn, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { + particleAlpha = Math.min(MathHelper.clamp(particleAge, 0, 20) / 20F, MathHelper.clamp(particleMaxAge - particleAge, 0, 20) / 20F); + super.renderParticle(buffer, entityIn, partialTicks, rotationX, rotationZ + MathHelper.cos((float) Math.toRadians((rot + partialTicks) % 360F)), rotationYZ, rotationXY, rotationXZ); + } + + @Override + public int getBrightnessForRender(float partialTicks) { + return 240 | 240 << 16; + } + + @Override + public int getFXLayer() { + return 1; + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleLeafRune.java b/src/main/java/twilightforest/client/particle/ParticleLeafRune.java new file mode 100644 index 0000000000..697204bf8b --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleLeafRune.java @@ -0,0 +1,33 @@ +package twilightforest.client.particle; + +import net.minecraft.client.particle.ParticleEnchantmentTable; +import net.minecraft.world.World; + +public class ParticleLeafRune extends ParticleEnchantmentTable { + + public ParticleLeafRune(World world, double x, double y, double z, double velX, double velY, double velZ) { + super(world, x, y, z, velX, velY, velZ); + + this.particleScale = this.rand.nextFloat() + 1F; + this.particleMaxAge += 10; + this.particleGravity = 0.003F + rand.nextFloat() * 0.006F; + + + this.canCollide = true; + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + this.move(this.motionX, this.motionY, this.motionZ); + this.motionY -= (double) this.particleGravity; + + + if (this.particleAge++ >= this.particleMaxAge) { + this.setExpired(); + } + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleProtection.java b/src/main/java/twilightforest/client/particle/ParticleProtection.java new file mode 100644 index 0000000000..4ac488c60d --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleProtection.java @@ -0,0 +1,21 @@ +package twilightforest.client.particle; + +import net.minecraft.client.particle.ParticleSuspendedTown; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class ParticleProtection extends ParticleSuspendedTown { + + public ParticleProtection(World world, double x, double y, double z, double velX, double velY, double velZ) { + super(world, x, y, z, velX, velY, velZ); + this.setParticleTextureIndex(82); + this.setRBGColorF(1.0F, 1.0F, 1.0F); + } + + @SideOnly(Side.CLIENT) + @Override + public int getBrightnessForRender(float partialTicks) { + return 0xF000F0; + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleSmokeScale.java b/src/main/java/twilightforest/client/particle/ParticleSmokeScale.java new file mode 100644 index 0000000000..41ff4446e2 --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleSmokeScale.java @@ -0,0 +1,11 @@ +package twilightforest.client.particle; + +import net.minecraft.client.particle.ParticleSmokeNormal; +import net.minecraft.world.World; + +public class ParticleSmokeScale extends ParticleSmokeNormal { + + public ParticleSmokeScale(World world, double x, double y, double z, double velX, double velY, double velZ, float scale) { + super(world, x, y, z, velX, velY, velZ, scale); + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleSnow.java b/src/main/java/twilightforest/client/particle/ParticleSnow.java new file mode 100644 index 0000000000..d2c6f9a4b5 --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleSnow.java @@ -0,0 +1,72 @@ +package twilightforest.client.particle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.Particle; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; + +@SideOnly(Side.CLIENT) +public class ParticleSnow extends Particle { + + float initialParticleScale; + + public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz) { + this(world, x, y, z, vx, vy, vz, 1.0F); + } + + public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz, float scale) { + super(world, x, y, z, 0.0D, 0.0D, 0.0D); + this.motionX *= 0.10000000149011612D; + this.motionY *= 0.10000000149011612D; + this.motionZ *= 0.10000000149011612D; + this.motionX += vx * 0.4D; + this.motionY += vy * 0.4D; + this.motionZ += vz * 0.4D; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + this.particleScale *= 0.75F; + this.particleScale *= scale; + this.initialParticleScale = this.particleScale; + this.particleMaxAge = (int) (6.0D / (Math.random() * 0.8D + 0.6D)); + this.particleMaxAge = (int) ((float) this.particleMaxAge * scale); + this.canCollide = true; + + this.setParticleTexture(Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(TwilightForestMod.ID + ":particles/snow_" + rand.nextInt(4))); + + this.onUpdate(); + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) { + this.setExpired(); + } + + this.move(this.motionX, this.motionY, this.motionZ); + + this.motionX *= 0.699999988079071D; + this.motionY *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY -= 0.019999999552965164D; + + if (this.onGround) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } + + @Override + public int getBrightnessForRender(float partialTicks) { + return 240 | 240 << 16; + } + + @Override + public int getFXLayer() { + return 1; + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleSnowGuardian.java b/src/main/java/twilightforest/client/particle/ParticleSnowGuardian.java new file mode 100644 index 0000000000..9f05718050 --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleSnowGuardian.java @@ -0,0 +1,12 @@ +package twilightforest.client.particle; + +import net.minecraft.world.World; + +public class ParticleSnowGuardian extends ParticleSnow { + + public ParticleSnowGuardian(World world, double x, double y, double z, double vx, double vy, double vz, float scale) { + super(world, x, y, z, vx, vy, vz, scale); + this.particleMaxAge = 10 + this.rand.nextInt(15); + this.particleRed = this.particleGreen = this.particleBlue = 0.75F + this.rand.nextFloat() * 0.25F; + } +} diff --git a/src/main/java/twilightforest/client/particle/ParticleSnowWarning.java b/src/main/java/twilightforest/client/particle/ParticleSnowWarning.java new file mode 100644 index 0000000000..f9e4706e82 --- /dev/null +++ b/src/main/java/twilightforest/client/particle/ParticleSnowWarning.java @@ -0,0 +1,17 @@ +package twilightforest.client.particle; + +import net.minecraft.world.World; + +public class ParticleSnowWarning extends ParticleSnow { + + public ParticleSnowWarning(World world, double x, double y, double z, double vx, double vy, double vz, float scale) { + super(world, x, y, z, vx, vy, vz, scale); + this.particleMaxAge = 50; + } + + @Override + public void onUpdate() { + super.onUpdate(); + this.motionY -= 0.019999999552965164D; + } +} diff --git a/src/main/java/twilightforest/client/particle/TFParticleFactory.java b/src/main/java/twilightforest/client/particle/TFParticleFactory.java new file mode 100644 index 0000000000..e38be745cb --- /dev/null +++ b/src/main/java/twilightforest/client/particle/TFParticleFactory.java @@ -0,0 +1,54 @@ +package twilightforest.client.particle; + +import net.minecraft.client.particle.Particle; +import net.minecraft.init.Items; +import net.minecraft.world.World; + +import javax.annotation.Nullable; +import java.util.EnumMap; +import java.util.Map; + +public class TFParticleFactory { + + private static final Map factories = new EnumMap<>(TFParticleType.class); + + static { + factories.put(TFParticleType.LARGE_FLAME, ParticleLargeFlame::new); + factories.put(TFParticleType.LEAF_RUNE, ParticleLeafRune::new); + factories.put(TFParticleType.BOSS_TEAR, (world, x, y, z, vx, vy, vz) + -> new ParticleGhastTear(world, x, y, z, vx, vy, vz, Items.GHAST_TEAR) + ); + factories.put(TFParticleType.GHAST_TRAP, ParticleGhastTrap::new); + factories.put(TFParticleType.PROTECTION, ParticleProtection::new); + factories.put(TFParticleType.SNOW, ParticleSnow::new); + factories.put(TFParticleType.SNOW_GUARDIAN, (world, x, y, z, vx, vy, vz) + -> new ParticleSnowGuardian(world, x, y, z, vx, vy, vz, 0.75F) + ); + factories.put(TFParticleType.SNOW_WARNING, (world, x, y, z, vx, vy, vz) + -> new ParticleSnowWarning(world, x, y, z, vx, vy, vz, 1F) + ); + factories.put(TFParticleType.ICE_BEAM, (world, x, y, z, vx, vy, vz) + -> new ParticleIceBeam(world, x, y, z, vx, vy, vz, 0.75F) + ); + factories.put(TFParticleType.ANNIHILATE, (world, x, y, z, vx, vy, vz) + -> new ParticleAnnihilate(world, x, y, z, vx, vy, vz, 0.75F) + ); + factories.put(TFParticleType.HUGE_SMOKE, (world, x, y, z, vx, vy, vz) + -> new ParticleSmokeScale(world, x, y, z, vx, vy, vz, 4.0F + world.rand.nextFloat()) + ); + factories.put(TFParticleType.FIREFLY, ParticleFirefly::new); + factories.put(TFParticleType.FALLEN_LEAF, ParticleLeaf::new); + } + + @Nullable + public static Particle createParticle(TFParticleType particleType, World world, double x, double y, double z, double vx, double vy, double vz) { + IParticleFactory factory = factories.get(particleType); + return factory != null ? factory.createParticle(world, x, y, z, vx, vy, vz) : null; + } + + @FunctionalInterface + private interface IParticleFactory { + + Particle createParticle(World world, double x, double y, double z, double vx, double vy, double vz); + } +} diff --git a/src/main/java/twilightforest/client/particle/TFParticleType.java b/src/main/java/twilightforest/client/particle/TFParticleType.java new file mode 100644 index 0000000000..e1356b5ebd --- /dev/null +++ b/src/main/java/twilightforest/client/particle/TFParticleType.java @@ -0,0 +1,17 @@ +package twilightforest.client.particle; + +public enum TFParticleType { + LARGE_FLAME, + LEAF_RUNE, + BOSS_TEAR, + GHAST_TRAP, + PROTECTION, + SNOW, + SNOW_WARNING, + SNOW_GUARDIAN, + ICE_BEAM, + ANNIHILATE, + HUGE_SMOKE, + FIREFLY, + FALLEN_LEAF +} diff --git a/src/main/java/twilightforest/client/renderer/TFFieryItemRenderer.java b/src/main/java/twilightforest/client/renderer/TFFieryItemRenderer.java deleted file mode 100644 index ce48f4169d..0000000000 --- a/src/main/java/twilightforest/client/renderer/TFFieryItemRenderer.java +++ /dev/null @@ -1,198 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.renderer.texture.TextureUtil; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.IItemRenderer; - -import org.lwjgl.opengl.GL11; - -public class TFFieryItemRenderer implements IItemRenderer { - - private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); - private TextureManager texturemanager; - - public TFFieryItemRenderer(GameSettings gameSettings, TextureManager textureManager) { - this.texturemanager = textureManager; - } - - /** - * Checks if this renderer should handle a specific item's render type - * @param item The item we are trying to render - * @param type A render type to check if this renderer handles - * @return true if this renderer should handle the given render type, - * otherwise false - */ - @Override - public boolean handleRenderType(ItemStack item, ItemRenderType type) { - return type == ItemRenderType.ENTITY || type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON; - } - - /** - * Checks if certain helper functionality should be executed for this renderer. - * See ItemRendererHelper for more info - * - * @param type The render type - * @param item The ItemStack being rendered - * @param helper The type of helper functionality to be ran - * @return True to run the helper functionality, false to not. - */ - @Override - public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { - return type == ItemRenderType.ENTITY && (helper == ItemRendererHelper.ENTITY_ROTATION || helper == ItemRendererHelper.ENTITY_BOBBING); - } - - /** - * Called to do the actual rendering, see ItemRenderType for details on when specific - * types are run, and what extra data is passed into the data parameter. - * - * @param type The render type - * @param item The ItemStack being rendered - * @param data Extra Type specific data - */ - @Override - public void renderItem(ItemRenderType type, ItemStack item, Object... data) { - - - - if (type == ItemRenderType.EQUIPPED_FIRST_PERSON) { - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - renderFieryItemEquipped(iicon, item); - } else if (type == ItemRenderType.EQUIPPED) { - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - renderFieryItemEquipped(iicon, item); - } else if (type == ItemRenderType.ENTITY) { - EntityItem entityItem = (EntityItem)data[1]; - - this.renderDroppedItem(entityItem, item); - } - } - - private void renderFieryItemEquipped(IIcon iicon, ItemStack par2ItemStack) { - int par3 = 0; - - if (iicon == null) - { - GL11.glPopMatrix(); - return; - } - - texturemanager.bindTexture(texturemanager.getResourceLocation(par2ItemStack.getItemSpriteNumber())); - TextureUtil.func_152777_a(false, false, 1.0F); - Tessellator tessellator = Tessellator.instance; - float f = iicon.getMinU(); - float f1 = iicon.getMaxU(); - float f2 = iicon.getMinV(); - float f3 = iicon.getMaxV(); - - // FULL BRIGHT - Minecraft.getMinecraft().entityRenderer.disableLightmap(0); - - ItemRenderer.renderItemIn2D(tessellator, f1, f2, f, f3, iicon.getIconWidth(), iicon.getIconHeight(), 0.0625F); - - - if (true) - { - GL11.glDepthFunc(GL11.GL_EQUAL); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glEnable(GL11.GL_BLEND); - GL11.glDisable(GL11.GL_TEXTURE_2D); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA); - - // pulse yellow - float f9 = (float) Math.sin((float)(Minecraft.getSystemTime() % 6000L) / 6000.0F * 2 * 3.14159F) * 0.2F + 0.2F; - - float yellooo = 0.4F; - GL11.glColor4f(yellooo, yellooo, 0.0F, f9); - - ItemRenderer.renderItemIn2D(tessellator, f1, f2, f, f3, iicon.getIconWidth(), iicon.getIconHeight(), 0.0625F); - - GL11.glEnable(GL11.GL_TEXTURE_2D); - - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDepthFunc(GL11.GL_LEQUAL); - } - - if (par2ItemStack.hasEffect(par3)) - { - GL11.glDepthFunc(GL11.GL_EQUAL); - GL11.glDisable(GL11.GL_LIGHTING); - texturemanager.bindTexture(RES_ITEM_GLINT); - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(768, 1, 1, 0); - float f7 = 0.76F; - GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); - GL11.glMatrixMode(GL11.GL_TEXTURE); - GL11.glPushMatrix(); - float f8 = 0.125F; - GL11.glScalef(f8, f8, f8); - float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; - GL11.glTranslatef(f9, 0.0F, 0.0F); - GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - GL11.glScalef(f8, f8, f8); - f9 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; - GL11.glTranslatef(-f9, 0.0F, 0.0F); - GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glMatrixMode(GL11.GL_MODELVIEW); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDepthFunc(GL11.GL_LEQUAL); - } - - texturemanager.bindTexture(texturemanager.getResourceLocation(par2ItemStack.getItemSpriteNumber())); - TextureUtil.func_147945_b(); - - Minecraft.getMinecraft().entityRenderer.enableLightmap(0); - } - - private void renderDroppedItem(EntityItem entityItem, ItemStack item) { - Tessellator tessellator = Tessellator.instance; - - float f9 = 0.5F; - float f10 = 0.25F; - - GL11.glPushMatrix(); - - float f12 = 0.0625F; - float f11 = 0.021875F; - - - GL11.glTranslatef(-f9, -f10, -(f12 + f11)); - - GL11.glTranslatef(0f, 0f, f12 + f11); - - this.texturemanager.bindTexture(TextureMap.locationItemsTexture); - - IIcon par2Icon = item.getIconIndex(); - - // FULL BRIGHT - Minecraft.getMinecraft().entityRenderer.disableLightmap(0); - - //GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, par2Icon.getMaxU(), par2Icon.getMinV(), par2Icon.getMinU(), par2Icon.getMaxV(), par2Icon.getIconWidth(), par2Icon.getIconHeight(), f12); - - Minecraft.getMinecraft().entityRenderer.enableLightmap(0); - - - GL11.glPopMatrix(); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TFGiantBlockRenderer.java b/src/main/java/twilightforest/client/renderer/TFGiantBlockRenderer.java deleted file mode 100644 index c0ea19eada..0000000000 --- a/src/main/java/twilightforest/client/renderer/TFGiantBlockRenderer.java +++ /dev/null @@ -1,111 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraftforge.client.IItemRenderer; - -import org.lwjgl.opengl.GL11; - -public class TFGiantBlockRenderer implements IItemRenderer { - - public TFGiantBlockRenderer(GameSettings gameSettings, TextureManager textureManager) { - } - - /** - * Checks if this renderer should handle a specific item's render type - * @param item The item we are trying to render - * @param type A render type to check if this renderer handles - * @return true if this renderer should handle the given render type, - * otherwise false - */ - @Override - public boolean handleRenderType(ItemStack item, ItemRenderType type) { - return type == ItemRenderType.ENTITY || type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON; - } - - /** - * Checks if certain helper functionality should be executed for this renderer. - * See ItemRendererHelper for more info - * - * @param type The render type - * @param item The ItemStack being rendered - * @param helper The type of helper functionality to be ran - * @return True to run the helper functionality, false to not. - */ - @Override - public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { - return (type == ItemRenderType.ENTITY && (helper == ItemRendererHelper.ENTITY_ROTATION || helper == ItemRendererHelper.ENTITY_BOBBING)) || helper == ItemRendererHelper.BLOCK_3D; - } - - /** - * Called to do the actual rendering, see ItemRenderType for details on when specific - * types are run, and what extra data is passed into the data parameter. - * - * @param type The render type - * @param item The ItemStack being rendered - * @param data Extra Type specific data - */ - @Override - public void renderItem(ItemRenderType type, ItemStack item, Object... data) { - - if (type == ItemRenderType.EQUIPPED_FIRST_PERSON) { - // extra scaling - float scale = 4.0F; - GL11.glScalef(scale, scale, scale); - // move for first person - GL11.glTranslatef(1.0F, 0.3F, 0.75F); - GL11.glRotatef(45.0F, 0.0F, 0.0F, 1.0F); - - - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - RenderBlocks renderBlocks = (RenderBlocks)data[0]; - renderGiantItemEquipped(iicon, renderBlocks, item); - } else if (type == ItemRenderType.EQUIPPED) { - // extra scaling - float scale = 4.0F; - GL11.glScalef(scale, scale, scale); - // move item for equipped - GL11.glTranslatef(0.25F, 0.3F, -0.5F); - GL11.glRotatef(15.0F, 0.0F, 0.0F, 1.0F); - - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - RenderBlocks renderBlocks = (RenderBlocks)data[0]; - renderGiantItemEquipped(iicon, renderBlocks, item); - } else if (type == ItemRenderType.ENTITY) { - // extra scaling - float scale = 4.0F; - GL11.glScalef(scale, scale, scale); - // move item for dropped - GL11.glTranslatef(0.0F, 0.5F, 0.0F); - - RenderBlocks renderBlocks = (RenderBlocks)data[0]; - EntityItem entityItem = (EntityItem)data[1]; - - this.renderDroppedItem(entityItem, renderBlocks, item); - } - } - - - private void renderGiantItemEquipped(IIcon iicon, RenderBlocks renderBlocks, ItemStack itemStack) { - Block block = Block.getBlockFromItem(itemStack.getItem()); - - renderBlocks.renderBlockAsItem(block, itemStack.getItemDamage(), 1.0F); - - } - - private void renderDroppedItem(EntityItem entityItem, RenderBlocks renderBlocks, ItemStack itemStack) { - - Block block = Block.getBlockFromItem(itemStack.getItem()); - - renderBlocks.renderBlockAsItem(block, itemStack.getItemDamage(), 1.0F); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TFGiantItemRenderer.java b/src/main/java/twilightforest/client/renderer/TFGiantItemRenderer.java deleted file mode 100644 index e402669d59..0000000000 --- a/src/main/java/twilightforest/client/renderer/TFGiantItemRenderer.java +++ /dev/null @@ -1,215 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.entity.RenderItem; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.renderer.texture.TextureUtil; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.IItemRenderer; - -import org.lwjgl.opengl.GL11; - -public class TFGiantItemRenderer implements IItemRenderer { - - private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); - private TextureManager texturemanager; - - public TFGiantItemRenderer(GameSettings gameSettings, TextureManager textureManager) { - this.texturemanager = textureManager; - } - - /** - * Checks if this renderer should handle a specific item's render type - * @param item The item we are trying to render - * @param type A render type to check if this renderer handles - * @return true if this renderer should handle the given render type, - * otherwise false - */ - @Override - public boolean handleRenderType(ItemStack item, ItemRenderType type) { - return type == ItemRenderType.ENTITY || type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON || type == ItemRenderType.INVENTORY; - } - - /** - * Checks if certain helper functionality should be executed for this renderer. - * See ItemRendererHelper for more info - * - * @param type The render type - * @param item The ItemStack being rendered - * @param helper The type of helper functionality to be ran - * @return True to run the helper functionality, false to not. - */ - @Override - public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { - return type == ItemRenderType.ENTITY && (helper == ItemRendererHelper.ENTITY_ROTATION || helper == ItemRendererHelper.ENTITY_BOBBING); - } - - /** - * Called to do the actual rendering, see ItemRenderType for details on when specific - * types are run, and what extra data is passed into the data parameter. - * - * @param type The render type - * @param item The ItemStack being rendered - * @param data Extra Type specific data - */ - @Override - public void renderItem(ItemRenderType type, ItemStack item, Object... data) { - - - - if (type == ItemRenderType.EQUIPPED_FIRST_PERSON) { - // extra scaling - float scale = 4.0F; - GL11.glScalef(scale, scale, scale); - // move for first person - GL11.glTranslatef(-0.25F, -0.2F, 0.25F); - - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - renderGiantItemEquipped(iicon, item); - } else if (type == ItemRenderType.EQUIPPED) { - // extra scaling - float scale = 4.0F; - GL11.glScalef(scale, scale, scale); - // move item for equipped - GL11.glTranslatef(-0.625F, -0.1F, 0.03F); - - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - renderGiantItemEquipped(iicon, item); - } else if (type == ItemRenderType.ENTITY) { - // extra scaling - float scale = 4.0F; - GL11.glScalef(scale, scale, scale); - // move item for dropped - GL11.glTranslatef(0.0F, 0.15F, 0.0F); - - EntityItem entityItem = (EntityItem)data[1]; - - this.renderDroppedItem(entityItem, item); - } else if (type == ItemRenderType.INVENTORY) { - this.renderInventoryItem(item, (RenderBlocks)data[0]); - } - - - - - } - - private void renderInventoryItem(ItemStack itemStack, RenderBlocks renderBlocks) { - // how do we get the itemrender? - //RenderManager.instance.itemRenderer. - - IIcon iicon = itemStack.getItem().getIcon(itemStack, -1); - - GL11.glDisable(GL11.GL_LIGHTING); //Forge: Make sure that render states are reset, ad renderEffect can derp them up. - GL11.glEnable(GL11.GL_ALPHA_TEST); - - RenderItem.getInstance().renderIcon(0, 0, iicon, 16, 16); - - GL11.glDisable(GL11.GL_ALPHA_TEST); - GL11.glEnable(GL11.GL_LIGHTING); - - if (itemStack.hasEffect(0)) - { - RenderItem.getInstance().renderEffect(this.texturemanager, 0, 0); - } - GL11.glEnable(GL11.GL_LIGHTING); - - //RenderItem.getInstance().renderItemIntoGUI(null, this.texturemanager, item, 0, 0, true); - //renderItemIntoGUI - } - - private void renderGiantItemEquipped(IIcon iicon, ItemStack par2ItemStack) { - int par3 = 0; - - if (iicon == null) - { - GL11.glPopMatrix(); - return; - } - - texturemanager.bindTexture(texturemanager.getResourceLocation(par2ItemStack.getItemSpriteNumber())); - TextureUtil.func_152777_a(false, false, 1.0F); - Tessellator tessellator = Tessellator.instance; - float f = iicon.getMinU(); - float f1 = iicon.getMaxU(); - float f2 = iicon.getMinV(); - float f3 = iicon.getMaxV(); - - ItemRenderer.renderItemIn2D(tessellator, f1, f2, f, f3, iicon.getIconWidth(), iicon.getIconHeight(), 0.0625F); - - if (par2ItemStack.hasEffect(par3)) - { - GL11.glDepthFunc(GL11.GL_EQUAL); - GL11.glDisable(GL11.GL_LIGHTING); - texturemanager.bindTexture(RES_ITEM_GLINT); - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(768, 1, 1, 0); - float f7 = 0.76F; - GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); - GL11.glMatrixMode(GL11.GL_TEXTURE); - GL11.glPushMatrix(); - float f8 = 0.125F; - GL11.glScalef(f8, f8, f8); - float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; - GL11.glTranslatef(f9, 0.0F, 0.0F); - GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - GL11.glScalef(f8, f8, f8); - f9 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; - GL11.glTranslatef(-f9, 0.0F, 0.0F); - GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glMatrixMode(GL11.GL_MODELVIEW); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDepthFunc(GL11.GL_LEQUAL); - } - - texturemanager.bindTexture(texturemanager.getResourceLocation(par2ItemStack.getItemSpriteNumber())); - TextureUtil.func_147945_b(); - } - - private void renderDroppedItem(EntityItem entityItem, ItemStack item) { - Tessellator tessellator = Tessellator.instance; - - float f9 = 0.5F; - float f10 = 0.25F; - - GL11.glPushMatrix(); - - float f12 = 0.0625F; - float f11 = 0.021875F; - - - GL11.glTranslatef(-f9, -f10, -(f12 + f11)); - - GL11.glTranslatef(0f, 0f, f12 + f11); - - this.texturemanager.bindTexture(TextureMap.locationItemsTexture); - - IIcon par2Icon = item.getIconIndex(); - - - //GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, par2Icon.getMaxU(), par2Icon.getMinV(), par2Icon.getMinU(), par2Icon.getMaxV(), par2Icon.getIconWidth(), par2Icon.getIconHeight(), f12); - - - GL11.glPopMatrix(); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TFIceItemRenderer.java b/src/main/java/twilightforest/client/renderer/TFIceItemRenderer.java deleted file mode 100644 index 8a01934da7..0000000000 --- a/src/main/java/twilightforest/client/renderer/TFIceItemRenderer.java +++ /dev/null @@ -1,197 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.entity.RenderItem; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.renderer.texture.TextureUtil; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.IItemRenderer; -import org.lwjgl.opengl.GL11; - -public class TFIceItemRenderer implements IItemRenderer { - - private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); - private TextureManager texturemanager; - - public TFIceItemRenderer(GameSettings gameSettings, TextureManager textureManager) { - this.texturemanager = textureManager; - } - - /** - * Checks if this renderer should handle a specific item's render type - * @param item The item we are trying to render - * @param type A render type to check if this renderer handles - * @return true if this renderer should handle the given render type, - * otherwise false - */ - @Override - public boolean handleRenderType(ItemStack item, ItemRenderType type) { - return type == ItemRenderType.ENTITY || type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON || type == ItemRenderType.INVENTORY; - } - - /** - * Checks if certain helper functionality should be executed for this renderer. - * See ItemRendererHelper for more info - * - * @param type The render type - * @param item The ItemStack being rendered - * @param helper The type of helper functionality to be ran - * @return True to run the helper functionality, false to not. - */ - @Override - public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { - return type == ItemRenderType.ENTITY && (helper == ItemRendererHelper.ENTITY_ROTATION || helper == ItemRendererHelper.ENTITY_BOBBING); - } - - /** - * Called to do the actual rendering, see ItemRenderType for details on when specific - * types are run, and what extra data is passed into the data parameter. - * - * @param type The render type - * @param item The ItemStack being rendered - * @param data Extra Type specific data - */ - @Override - public void renderItem(ItemRenderType type, ItemStack item, Object... data) { - - - - if (type == ItemRenderType.EQUIPPED_FIRST_PERSON) { - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - renderIcyItemEquipped(iicon, item); - } else if (type == ItemRenderType.EQUIPPED) { - // render item - IIcon iicon = ((EntityLivingBase)data[1]).getItemIcon(item, 0); - renderIcyItemEquipped(iicon, item); - } else if (type == ItemRenderType.ENTITY) { - EntityItem entityItem = (EntityItem)data[1]; - - this.renderDroppedItem(entityItem, item); - } else if (type == ItemRenderType.INVENTORY) { - this.renderInventoryItem(item, (RenderBlocks)data[0]); - } - } - - private void renderIcyItemEquipped(IIcon iicon, ItemStack par2ItemStack) { - int par3 = 0; - - if (iicon == null) - { - GL11.glPopMatrix(); - return; - } - - texturemanager.bindTexture(texturemanager.getResourceLocation(par2ItemStack.getItemSpriteNumber())); - TextureUtil.func_152777_a(false, false, 1.0F); - Tessellator tessellator = Tessellator.instance; - float f = iicon.getMinU(); - float f1 = iicon.getMaxU(); - float f2 = iicon.getMinV(); - float f3 = iicon.getMaxV(); - - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - ItemRenderer.renderItemIn2D(tessellator, f1, f2, f, f3, iicon.getIconWidth(), iicon.getIconHeight(), 0.0625F); - - GL11.glDisable(GL11.GL_BLEND); - - if (par2ItemStack.hasEffect(par3)) - { - GL11.glDepthFunc(GL11.GL_EQUAL); - GL11.glDisable(GL11.GL_LIGHTING); - texturemanager.bindTexture(RES_ITEM_GLINT); - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(768, 1, 1, 0); - float f7 = 0.76F; - GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); - GL11.glMatrixMode(GL11.GL_TEXTURE); - GL11.glPushMatrix(); - float f8 = 0.125F; - GL11.glScalef(f8, f8, f8); - float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; - GL11.glTranslatef(f9, 0.0F, 0.0F); - GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - GL11.glScalef(f8, f8, f8); - f9 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; - GL11.glTranslatef(-f9, 0.0F, 0.0F); - GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); - GL11.glPopMatrix(); - GL11.glMatrixMode(GL11.GL_MODELVIEW); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDepthFunc(GL11.GL_LEQUAL); - } - - texturemanager.bindTexture(texturemanager.getResourceLocation(par2ItemStack.getItemSpriteNumber())); - TextureUtil.func_147945_b(); - } - - private void renderDroppedItem(EntityItem entityItem, ItemStack item) { - Tessellator tessellator = Tessellator.instance; - - float f9 = 0.5F; - float f10 = 0.25F; - - GL11.glPushMatrix(); - - float f12 = 0.0625F; - float f11 = 0.021875F; - - - GL11.glTranslatef(-f9, -f10, -(f12 + f11)); - - GL11.glTranslatef(0f, 0f, f12 + f11); - - this.texturemanager.bindTexture(TextureMap.locationItemsTexture); - - IIcon par2Icon = item.getIconIndex(); - - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - ItemRenderer.renderItemIn2D(tessellator, par2Icon.getMaxU(), par2Icon.getMinV(), par2Icon.getMinU(), par2Icon.getMaxV(), par2Icon.getIconWidth(), par2Icon.getIconHeight(), f12); - - GL11.glDisable(GL11.GL_BLEND); - - - GL11.glPopMatrix(); - } - - - private void renderInventoryItem(ItemStack itemStack, RenderBlocks renderBlocks) { - IIcon iicon = itemStack.getItem().getIcon(itemStack, -1); - - GL11.glDisable(GL11.GL_LIGHTING); //Forge: Make sure that render states are reset, ad renderEffect can derp them up. - GL11.glEnable(GL11.GL_ALPHA_TEST); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - RenderItem.getInstance().renderIcon(0, 0, iicon, 16, 16); - - GL11.glDisable(GL11.GL_BLEND); - GL11.glDisable(GL11.GL_ALPHA_TEST); - GL11.glEnable(GL11.GL_LIGHTING); - - if (itemStack.hasEffect(0)) - { - RenderItem.getInstance().renderEffect(this.texturemanager, 0, 0); - } - GL11.glEnable(GL11.GL_LIGHTING); - } -} diff --git a/src/main/java/twilightforest/client/renderer/TFMagicMapRenderer.java b/src/main/java/twilightforest/client/renderer/TFMagicMapRenderer.java deleted file mode 100644 index 2cd0a72b48..0000000000 --- a/src/main/java/twilightforest/client/renderer/TFMagicMapRenderer.java +++ /dev/null @@ -1,229 +0,0 @@ -package twilightforest.client.renderer; - -import java.util.Collection; -import java.util.List; - -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.entity.RenderItem; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.texture.DynamicTexture; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.storage.MapData; -import net.minecraft.world.storage.MapData.MapCoord; - -import org.lwjgl.opengl.GL11; - -import twilightforest.TFMagicMapData; -import twilightforest.TwilightForestMod; -import twilightforest.item.ItemTFMagicMap; -import twilightforest.item.TFItems; - -public class TFMagicMapRenderer implements net.minecraftforge.client.IItemRenderer { - - private static final ResourceLocation vanillaMapIcons = new ResourceLocation("textures/map/map_icons.png"); - private static final ResourceLocation twilightMapIcons = new ResourceLocation(TwilightForestMod.GUI_DIR + "mapicons.png"); - private static final ResourceLocation mapBackgroundTextures = new ResourceLocation("textures/map/map_background.png"); - private int[] intArray = new int[16384]; - private DynamicTexture bufferedImage; - private final ResourceLocation textureLoc; - - - public TFMagicMapRenderer(GameSettings par1GameSettings, TextureManager par2TextureManager) - { - this.bufferedImage = new DynamicTexture(128, 128); - this.textureLoc = par2TextureManager.getDynamicTextureLocation("map", this.bufferedImage); - this.intArray = this.bufferedImage.getTextureData(); - - for (int i = 0; i < this.intArray.length; ++i) - { - this.intArray[i] = 0; - } - } - - /** - * Checks if this renderer should handle a specific item's render type - * @param item The item we are trying to render - * @param type A render type to check if this renderer handles - * @return true if this renderer should handle the given render type, - * otherwise false - */ - @Override - public boolean handleRenderType(ItemStack item, ItemRenderType type) { - return item.getItem() == TFItems.magicMap && (type == ItemRenderType.FIRST_PERSON_MAP || (RenderItem.renderInFrame && type == ItemRenderType.ENTITY)); - } - - /** - * Checks if certain helper functionality should be executed for this renderer. - * See ItemRendererHelper for more info - * - * @param type The render type - * @param item The ItemStack being rendered - * @param helper The type of helper functionality to be ran - * @return True to run the helper functionality, false to not. - */ - @Override - public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { - return false; - } - - /** - * Called to do the actual rendering, see ItemRenderType for details on when specific - * types are run, and what extra data is passed into the data parameter. - * - * @param type The render type - * @param item The ItemStack being rendered - * @param data Extra Type specific data - */ - @Override - public void renderItem(ItemRenderType type, ItemStack item, Object... data) { - - if (type == ItemRenderType.FIRST_PERSON_MAP) - { - // get our stuff out of that object array - EntityPlayer player = (EntityPlayer)data[0]; - TextureManager renderEngine = (TextureManager)data[1]; - MapData mapData = (MapData)data[2]; - // if we have data, render it - if (mapData != null && mapData instanceof TFMagicMapData) - { - renderMap(player, renderEngine, (TFMagicMapData)mapData); - } - } - else if (RenderItem.renderInFrame) - { - EntityItem entity = (EntityItem)data[1]; - - TFMagicMapData mapData = ((ItemTFMagicMap) TFItems.magicMap).getMapData(item, entity.worldObj); - - - // if we have data, render it - if (mapData != null) - { - renderMapInFrame(item, RenderManager.instance, mapData); - } - } - } - - - @SuppressWarnings("unchecked") - public void renderMap(EntityPlayer par1EntityPlayer, TextureManager par2TextureManager, TFMagicMapData par3MapData) - { - TFMagicMapData magicMapData = (TFMagicMapData)par3MapData; - - for (int i = 0; i < 16384; ++i) - { - int colorByte = par3MapData.colors[i] & 0xFF; - - if (colorByte == 0) { - this.intArray[i] = (i + i / 128 & 1) * 8 + 16 << 24; - } - else { - int biomeID = colorByte - 1; - BiomeGenBase biome = BiomeGenBase.getBiomeGenArray()[biomeID]; - if (biome != null) { - this.intArray[i] = -16777216 | biome.color; - } - } - } - - this.bufferedImage.updateDynamicTexture(); - byte var15 = 0; - byte var16 = 0; - Tessellator tesselator = Tessellator.instance; - float var18 = 0.0F; - par2TextureManager.bindTexture(this.textureLoc); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); - GL11.glDisable(GL11.GL_ALPHA_TEST); - tesselator.startDrawingQuads(); - tesselator.addVertexWithUV((double)((float)(var15 + 0) + var18), (double)((float)(var16 + 128) - var18), -0.009999999776482582D, 0.0D, 1.0D); - tesselator.addVertexWithUV((double)((float)(var15 + 128) - var18), (double)((float)(var16 + 128) - var18), -0.009999999776482582D, 1.0D, 1.0D); - tesselator.addVertexWithUV((double)((float)(var15 + 128) - var18), (double)((float)(var16 + 0) + var18), -0.009999999776482582D, 1.0D, 0.0D); - tesselator.addVertexWithUV((double)((float)(var15 + 0) + var18), (double)((float)(var16 + 0) + var18), -0.009999999776482582D, 0.0D, 0.0D); - tesselator.draw(); - GL11.glEnable(GL11.GL_ALPHA_TEST); - GL11.glDisable(GL11.GL_BLEND); - par2TextureManager.bindTexture(vanillaMapIcons); - for(MapCoord mapCoord : (Collection)par3MapData.playersVisibleOnMap.values()) - { - GL11.glPushMatrix(); - GL11.glTranslatef((float)var15 + (float)mapCoord.centerX / 2.0F + 64.0F, (float)var16 + (float)mapCoord.centerZ / 2.0F + 64.0F, -0.04F); - GL11.glRotatef((float)(mapCoord.iconRotation * 360) / 16.0F, 0.0F, 0.0F, 1.0F); - GL11.glScalef(4.0F, 4.0F, 3.0F); - GL11.glTranslatef(-0.125F, 0.125F, 0.0F); - float var21 = (float)(mapCoord.iconSize % 4 + 0) / 4.0F; - float var23 = (float)(mapCoord.iconSize / 4 + 0) / 4.0F; - float var22 = (float)(mapCoord.iconSize % 4 + 1) / 4.0F; - float var24 = (float)(mapCoord.iconSize / 4 + 1) / 4.0F; - tesselator.startDrawingQuads(); - tesselator.addVertexWithUV(-1.0D, 1.0D, 0.0D, (double)var21, (double)var23); - tesselator.addVertexWithUV(1.0D, 1.0D, 0.0D, (double)var22, (double)var23); - tesselator.addVertexWithUV(1.0D, -1.0D, 0.0D, (double)var22, (double)var24); - tesselator.addVertexWithUV(-1.0D, -1.0D, 0.0D, (double)var21, (double)var24); - tesselator.draw(); - GL11.glPopMatrix(); - } - - par2TextureManager.bindTexture(twilightMapIcons); - - for(MapCoord mapCoord : (List)magicMapData.featuresVisibleOnMap) - { - GL11.glPushMatrix(); - GL11.glTranslatef((float)var15 + (float)mapCoord.centerX / 2.0F + 64.0F, (float)var16 + (float)mapCoord.centerZ / 2.0F + 64.0F, -0.02F); - GL11.glRotatef((float)(mapCoord.iconRotation * 360) / 16.0F, 0.0F, 0.0F, 1.0F); - GL11.glScalef(4.0F, 4.0F, 3.0F); - GL11.glTranslatef(-0.125F, 0.125F, 0.0F); - float var21 = (float)(mapCoord.iconSize % 8 + 0) / 8.0F; - float var23 = (float)(mapCoord.iconSize / 8 + 0) / 8.0F; - float var22 = (float)(mapCoord.iconSize % 8 + 1) / 8.0F; - float var24 = (float)(mapCoord.iconSize / 8 + 1) / 8.0F; - tesselator.startDrawingQuads(); - tesselator.addVertexWithUV(-1.0D, 1.0D, 0.0D, (double)var21, (double)var23); - tesselator.addVertexWithUV(1.0D, 1.0D, 0.0D, (double)var22, (double)var23); - tesselator.addVertexWithUV(1.0D, -1.0D, 0.0D, (double)var22, (double)var24); - tesselator.addVertexWithUV(-1.0D, -1.0D, 0.0D, (double)var21, (double)var24); - tesselator.draw(); - GL11.glPopMatrix(); - } - -// GL11.glPushMatrix(); -// GL11.glTranslatef(0.0F, 0.0F, -0.04F); -// GL11.glScalef(1.0F, 1.0F, 1.0F); -// this.fontRenderer.drawString(par3MapData.mapName, var15, var16, -16777216); -// GL11.glPopMatrix(); - } - - private void renderMapInFrame(ItemStack item, RenderManager renderManager, TFMagicMapData mapData) { - - // do some rotations so that we get vaguely in the right place - GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); - GL11.glScalef(0.00781250F, 0.00781250F, 0.00781250F); - GL11.glTranslatef(-65.0F, -111.0F, -3.0F); - GL11.glNormal3f(0.0F, 0.0F, -1.0F); - - // draw background - renderManager.renderEngine.bindTexture(mapBackgroundTextures); - Tessellator tessellator = Tessellator.instance; - tessellator.startDrawingQuads(); - byte b0 = 7; - tessellator.addVertexWithUV((double)(0 - b0), (double)(128 + b0), 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV((double)(128 + b0), (double)(128 + b0), 0.0D, 1.0D, 1.0D); - tessellator.addVertexWithUV((double)(128 + b0), (double)(0 - b0), 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV((double)(0 - b0), (double)(0 - b0), 0.0D, 0.0D, 0.0D); - tessellator.draw(); - - // push map texture slightly off background - GL11.glTranslatef(0.0F, 0.0F, -1.0F); - - // draw map - renderMap(null, renderManager.renderEngine, mapData); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TFMazeMapRenderer.java b/src/main/java/twilightforest/client/renderer/TFMazeMapRenderer.java deleted file mode 100644 index 6a934d0b3b..0000000000 --- a/src/main/java/twilightforest/client/renderer/TFMazeMapRenderer.java +++ /dev/null @@ -1,110 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.entity.RenderItem; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.settings.GameSettings; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.IItemRenderer; - -import org.lwjgl.opengl.GL11; - -import twilightforest.TFMazeMapData; -import twilightforest.item.ItemTFMazeMap; -import twilightforest.item.TFItems; - -public class TFMazeMapRenderer implements IItemRenderer { - - private static final ResourceLocation mapBackgroundTextures = new ResourceLocation("textures/map/map_background.png"); - - - public TFMazeMapRenderer(GameSettings gameSettings, TextureManager textureManager) { - // TODO Auto-generated constructor stub - } - - /** - * Checks if this renderer should handle a specific item's render type - * @param item The item we are trying to render - * @param type A render type to check if this renderer handles - * @return true if this renderer should handle the given render type, - * otherwise false - */ - @Override - public boolean handleRenderType(ItemStack item, ItemRenderType type) { - return (item.getItem() == TFItems.mazeMap || item.getItem() == TFItems.oreMap) && (RenderItem.renderInFrame && type == ItemRenderType.ENTITY); - } - - /** - * Checks if certain helper functionality should be executed for this renderer. - * See ItemRendererHelper for more info - * - * @param type The render type - * @param item The ItemStack being rendered - * @param helper The type of helper functionality to be ran - * @return True to run the helper functionality, false to not. - */ - @Override - public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { - return false; - } - - /** - * Called to do the actual rendering, see ItemRenderType for details on when specific - * types are run, and what extra data is passed into the data parameter. - * - * @param type The render type - * @param item The ItemStack being rendered - * @param data Extra Type specific data - */ - @Override - public void renderItem(ItemRenderType type, ItemStack item, Object... data) { - - if (RenderItem.renderInFrame) - { - //RenderBlocks renderBlocks = (RenderBlocks)data[0]; - EntityItem entity = (EntityItem)data[1]; - - TFMazeMapData mapData = ((ItemTFMazeMap) TFItems.mazeMap).getMapData(item, entity.worldObj); - - - // if we have data, render it - if (mapData != null) - { - renderMapInFrame(item, RenderManager.instance, mapData); - } - } - } - - private void renderMapInFrame(ItemStack item, RenderManager renderManager, TFMazeMapData mapData) { - - // do some rotations so that we get vaguely in the right place - GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); - GL11.glScalef(0.00781250F, 0.00781250F, 0.00781250F); - GL11.glTranslatef(-65.0F, -111.0F, -3.0F); - GL11.glNormal3f(0.0F, 0.0F, -1.0F); - - // draw background - renderManager.renderEngine.bindTexture(mapBackgroundTextures); - Tessellator tessellator = Tessellator.instance; - tessellator.startDrawingQuads(); - byte b0 = 7; - tessellator.addVertexWithUV((double)(0 - b0), (double)(128 + b0), 0.0D, 0.0D, 1.0D); - tessellator.addVertexWithUV((double)(128 + b0), (double)(128 + b0), 0.0D, 1.0D, 1.0D); - tessellator.addVertexWithUV((double)(128 + b0), (double)(0 - b0), 0.0D, 1.0D, 0.0D); - tessellator.addVertexWithUV((double)(0 - b0), (double)(0 - b0), 0.0D, 0.0D, 0.0D); - tessellator.draw(); - - // push map texture slightly off background - GL11.glTranslatef(0.0F, 0.0F, -1.0F); - - // draw map - Minecraft.getMinecraft().entityRenderer.getMapItemRenderer().func_148250_a(mapData, false); - - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TFSkyRenderer.java b/src/main/java/twilightforest/client/renderer/TFSkyRenderer.java index 68697487f7..437e02db4c 100644 --- a/src/main/java/twilightforest/client/renderer/TFSkyRenderer.java +++ b/src/main/java/twilightforest/client/renderer/TFSkyRenderer.java @@ -1,348 +1,270 @@ package twilightforest.client.renderer; -import java.util.Random; - import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.util.Vec3; -import net.minecraft.world.World; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexBuffer; +import net.minecraft.util.math.Vec3d; import net.minecraftforge.client.IRenderHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; -import org.lwjgl.opengl.GL11; - -import twilightforest.world.TFWorld; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import java.util.Random; +@SideOnly(Side.CLIENT) public class TFSkyRenderer extends IRenderHandler { - /** The star GL Call list */ - private int starGLCallList; - - /** OpenGL sky list */ - private int glSkyList; - - /** OpenGL sky list 2 */ - private int glSkyList2; - - @SideOnly(Side.CLIENT) - public TFSkyRenderer() - { - this.starGLCallList = GLAllocation.generateDisplayLists(3); - GL11.glPushMatrix(); - GL11.glNewList(this.starGLCallList, GL11.GL_COMPILE); - this.renderStars(); - GL11.glEndList(); - GL11.glPopMatrix(); - Tessellator var5 = Tessellator.instance; - this.glSkyList = this.starGLCallList + 1; - GL11.glNewList(this.glSkyList, GL11.GL_COMPILE); - byte var7 = 64; - int var8 = 256 / var7 + 2; - float var6 = 16.0F; - int var9; - int var10; - - for (var9 = -var7 * var8; var9 <= var7 * var8; var9 += var7) - { - for (var10 = -var7 * var8; var10 <= var7 * var8; var10 += var7) - { - var5.startDrawingQuads(); - var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + 0)); - var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + 0)); - var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + var7)); - var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + var7)); - var5.draw(); - } - } + private boolean vboEnabled; + private int starGLCallList; + private VertexBuffer starVBO; - GL11.glEndList(); - this.glSkyList2 = this.starGLCallList + 2; - GL11.glNewList(this.glSkyList2, GL11.GL_COMPILE); - var6 = -16.0F; - var5.startDrawingQuads(); - - for (var9 = -var7 * var8; var9 <= var7 * var8; var9 += var7) - { - for (var10 = -var7 * var8; var10 <= var7 * var8; var10 += var7) - { - var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + 0)); - var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + 0)); - var5.addVertex((double)(var9 + 0), (double)var6, (double)(var10 + var7)); - var5.addVertex((double)(var9 + var7), (double)var6, (double)(var10 + var7)); - } - } + public TFSkyRenderer() { + vboEnabled = OpenGlHelper.useVbo(); + generateStars(); + } - var5.draw(); - GL11.glEndList(); - } - - + // [VanillaCopy] RenderGlobal.renderSky's overworld branch, without sun/moon/sunrise/sunset, and using our own stars at full brightness + @SuppressWarnings("unused") @Override @SideOnly(Side.CLIENT) public void render(float partialTicks, WorldClient world, Minecraft mc) { - GL11.glDisable(GL11.GL_TEXTURE_2D); - Vec3 var2 = getTwilightSkyColor(world);//Vec3 var2 = world.getSkyColor(mc.renderViewEntity, partialTicks); - float var3 = (float)var2.xCoord; - float var4 = (float)var2.yCoord; - float var5 = (float)var2.zCoord; - float var8; - - if (mc.gameSettings.anaglyph) - { - float var6 = (var3 * 30.0F + var4 * 59.0F + var5 * 11.0F) / 100.0F; - float var7 = (var3 * 30.0F + var4 * 70.0F) / 100.0F; - var8 = (var3 * 30.0F + var5 * 70.0F) / 100.0F; - var3 = var6; - var4 = var7; - var5 = var8; - } - - GL11.glColor3f(var3, var4, var5); - Tessellator var23 = Tessellator.instance; - GL11.glDepthMask(false); - GL11.glEnable(GL11.GL_FOG); - GL11.glColor3f(var3, var4, var5); - GL11.glCallList(this.glSkyList); - GL11.glDisable(GL11.GL_FOG); - GL11.glDisable(GL11.GL_ALPHA_TEST); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - RenderHelper.disableStandardItemLighting(); -// float[] var24 = world.provider.calcSunriseSunsetColors(world.getCelestialAngle(partialTicks), partialTicks); - float var9; - float var10; - float var11; - float var12; - -// if (var24 != null) -// { -// GL11.glDisable(GL11.GL_TEXTURE_2D); -// GL11.glShadeModel(GL11.GL_SMOOTH); -// GL11.glPushMatrix(); -// GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); -// GL11.glRotatef(MathHelper.sin(world.getCelestialAngleRadians(partialTicks)) < 0.0F ? 180.0F : 0.0F, 0.0F, 0.0F, 1.0F); -// GL11.glRotatef(90.0F, 0.0F, 0.0F, 1.0F); -// var8 = var24[0]; -// var9 = var24[1]; -// var10 = var24[2]; -// float var13; -// -// if (mc.gameSettings.anaglyph) -// { -// var11 = (var8 * 30.0F + var9 * 59.0F + var10 * 11.0F) / 100.0F; -// var12 = (var8 * 30.0F + var9 * 70.0F) / 100.0F; -// var13 = (var8 * 30.0F + var10 * 70.0F) / 100.0F; -// var8 = var11; -// var9 = var12; -// var10 = var13; -// } -// -// var23.startDrawing(6); -// var23.setColorRGBA_F(var8, var9, var10, var24[3]); -// var23.addVertex(0.0D, 100.0D, 0.0D); -// byte var26 = 16; -// var23.setColorRGBA_F(var24[0], var24[1], var24[2], 0.0F); -// -// for (int var27 = 0; var27 <= var26; ++var27) -// { -// var13 = (float)var27 * (float)Math.PI * 2.0F / (float)var26; -// float var14 = MathHelper.sin(var13); -// float var15 = MathHelper.cos(var13); -// var23.addVertex((double)(var14 * 120.0F), (double)(var15 * 120.0F), (double)(-var15 * 40.0F * var24[3])); -// } -// -// var23.draw(); -// GL11.glPopMatrix(); -// GL11.glShadeModel(GL11.GL_FLAT); -// } - GL11.glEnable(GL11.GL_TEXTURE_2D); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); - GL11.glPushMatrix(); - var8 = 1.0F - world.getRainStrength(partialTicks); - var9 = 0.0F; - var10 = 0.0F; - var11 = 0.0F; - GL11.glColor4f(1.0F, 1.0F, 1.0F, var8); - GL11.glTranslatef(var9, var10, var11); - GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(getRealCelestialAngle(world, partialTicks) * 360.0F, 1.0F, 0.0F, 0.0F);//GL11.glRotatef(world.getCelestialAngle(partialTicks) * 360.0F, 1.0F, 0.0F, 0.0F); - var12 = 30.0F; -// GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.renderEngine.getTexture("/terrain/sun.png")); -// var23.startDrawingQuads(); -// var23.addVertexWithUV((double)(-var12), 100.0D, (double)(-var12), 0.0D, 0.0D); -// var23.addVertexWithUV((double)var12, 100.0D, (double)(-var12), 1.0D, 0.0D); -// var23.addVertexWithUV((double)var12, 100.0D, (double)var12, 1.0D, 1.0D); -// var23.addVertexWithUV((double)(-var12), 100.0D, (double)var12, 0.0D, 1.0D); -// var23.draw(); -// var12 = 20.0F; -// GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.renderEngine.getTexture("/terrain/moon_phases.png")); -// int var28 = world.getMoonPhase(partialTicks); -// int var30 = var28 % 4; -// int var29 = var28 / 4 % 2; -// float var16 = (float)(var30 + 0) / 4.0F; -// float var17 = (float)(var29 + 0) / 2.0F; -// float var18 = (float)(var30 + 1) / 4.0F; -// float var19 = (float)(var29 + 1) / 2.0F; -// var23.startDrawingQuads(); -// var23.addVertexWithUV((double)(-var12), -100.0D, (double)var12, (double)var18, (double)var19); -// var23.addVertexWithUV((double)var12, -100.0D, (double)var12, (double)var16, (double)var19); -// var23.addVertexWithUV((double)var12, -100.0D, (double)(-var12), (double)var16, (double)var17); -// var23.addVertexWithUV((double)(-var12), -100.0D, (double)(-var12), (double)var18, (double)var17); -// var23.draw(); - GL11.glDisable(GL11.GL_TEXTURE_2D); - float var20 = 1.0f;//world.getStarBrightness(partialTicks) * var8; - - if (var20 > 0.0F) - { - GL11.glColor4f(var20, var20, var20, var20); - GL11.glCallList(this.starGLCallList); - } - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_ALPHA_TEST); - GL11.glEnable(GL11.GL_FOG); - GL11.glPopMatrix(); - GL11.glDisable(GL11.GL_TEXTURE_2D); - GL11.glColor3f(0.0F, 0.0F, 0.0F); - double var25 = mc.thePlayer.getPosition(partialTicks).yCoord - TFWorld.SEALEVEL; - - if (var25 < 0.0D) - { - GL11.glPushMatrix(); - GL11.glTranslatef(0.0F, 12.0F, 0.0F); - GL11.glCallList(this.glSkyList2); - GL11.glPopMatrix(); - var10 = 1.0F; - var11 = -((float)(var25 + 65.0D)); - var12 = -var10; - var23.startDrawingQuads(); - var23.setColorRGBA_I(0, 255); - var23.addVertex((double)(-var10), (double)var11, (double)var10); - var23.addVertex((double)var10, (double)var11, (double)var10); - var23.addVertex((double)var10, (double)var12, (double)var10); - var23.addVertex((double)(-var10), (double)var12, (double)var10); - var23.addVertex((double)(-var10), (double)var12, (double)(-var10)); - var23.addVertex((double)var10, (double)var12, (double)(-var10)); - var23.addVertex((double)var10, (double)var11, (double)(-var10)); - var23.addVertex((double)(-var10), (double)var11, (double)(-var10)); - var23.addVertex((double)var10, (double)var12, (double)(-var10)); - var23.addVertex((double)var10, (double)var12, (double)var10); - var23.addVertex((double)var10, (double)var11, (double)var10); - var23.addVertex((double)var10, (double)var11, (double)(-var10)); - var23.addVertex((double)(-var10), (double)var11, (double)(-var10)); - var23.addVertex((double)(-var10), (double)var11, (double)var10); - var23.addVertex((double)(-var10), (double)var12, (double)var10); - var23.addVertex((double)(-var10), (double)var12, (double)(-var10)); - var23.addVertex((double)(-var10), (double)var12, (double)(-var10)); - var23.addVertex((double)(-var10), (double)var12, (double)var10); - var23.addVertex((double)var10, (double)var12, (double)var10); - var23.addVertex((double)var10, (double)var12, (double)(-var10)); - var23.draw(); - } - - if (world.provider.isSkyColored()) - { - GL11.glColor3f(var3 * 0.2F + 0.04F, var4 * 0.2F + 0.04F, var5 * 0.6F + 0.1F); - } - else - { - GL11.glColor3f(var3, var4, var5); - } - - GL11.glPushMatrix(); - GL11.glTranslatef(0.0F, -((float)(var25 - 16.0D)), 0.0F); - GL11.glCallList(this.glSkyList2); - GL11.glPopMatrix(); - GL11.glEnable(GL11.GL_TEXTURE_2D); - GL11.glDepthMask(true); + // [VanillaCopy] Excerpt from RenderGlobal.loadRenderers as we don't get a callback + boolean flag = this.vboEnabled; + this.vboEnabled = OpenGlHelper.useVbo(); + if (flag != this.vboEnabled) { + generateStars(); + } + + RenderGlobal rg = mc.renderGlobal; + int pass = EntityRenderer.anaglyphEnable ? EntityRenderer.anaglyphField : 2; + + GlStateManager.disableTexture2D(); + Vec3d vec3d = world.getSkyColor(mc.getRenderViewEntity(), partialTicks); + float f = (float) vec3d.x; + float f1 = (float) vec3d.y; + float f2 = (float) vec3d.z; + + if (pass != 2) { + float f3 = (f * 30.0F + f1 * 59.0F + f2 * 11.0F) / 100.0F; + float f4 = (f * 30.0F + f1 * 70.0F) / 100.0F; + float f5 = (f * 30.0F + f2 * 70.0F) / 100.0F; + f = f3; + f1 = f4; + f2 = f5; + } + + GlStateManager.color(f, f1, f2); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + GlStateManager.depthMask(false); + GlStateManager.enableFog(); + GlStateManager.color(f, f1, f2); + + if (this.vboEnabled) { + rg.skyVBO.bindBuffer(); + GlStateManager.glEnableClientState(32884); + GlStateManager.glVertexPointer(3, 5126, 12, 0); + rg.skyVBO.drawArrays(7); + rg.skyVBO.unbindBuffer(); + GlStateManager.glDisableClientState(32884); + } else { + GlStateManager.callList(rg.glSkyList); + } + + GlStateManager.disableFog(); + GlStateManager.disableAlpha(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + RenderHelper.disableStandardItemLighting(); + /* TF - snip out sunrise/sunset since that doesn't happen here + * float[] afloat = ... + * if (afloat != null) ... + */ + + GlStateManager.enableTexture2D(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.pushMatrix(); + float f16 = 1.0F - world.getRainStrength(partialTicks); + GlStateManager.color(1.0F, 1.0F, 1.0F, f16); + GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(world.getCelestialAngle(partialTicks) * 360.0F, 1.0F, 0.0F, 0.0F); + /* TF - snip out sun/moon + * float f17 = 30.0F; + * ... + * tessellator.draw(); + */ + GlStateManager.disableTexture2D(); + float f15 = 1.0F; // TF - stars are always bright + + if (f15 > 0.0F) { + GlStateManager.color(f15, f15, f15, f15); + + if (this.vboEnabled) { + this.starVBO.bindBuffer(); + GlStateManager.glEnableClientState(32884); + GlStateManager.glVertexPointer(3, 5126, 12, 0); + this.starVBO.drawArrays(7); + this.starVBO.unbindBuffer(); + GlStateManager.glDisableClientState(32884); + } else { + GlStateManager.callList(this.starGLCallList); + } + } + + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableFog(); + GlStateManager.popMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.color(0.0F, 0.0F, 0.0F); + double d0 = mc.player.getPositionEyes(partialTicks).y - world.getHorizon(); + + if (d0 < 0.0D) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0.0F, 12.0F, 0.0F); + + if (this.vboEnabled) { + rg.sky2VBO.bindBuffer(); + GlStateManager.glEnableClientState(32884); + GlStateManager.glVertexPointer(3, 5126, 12, 0); + rg.sky2VBO.drawArrays(7); + rg.sky2VBO.unbindBuffer(); + GlStateManager.glDisableClientState(32884); + } else { + GlStateManager.callList(rg.glSkyList2); + } + + GlStateManager.popMatrix(); + float f18 = 1.0F; + float f19 = -((float) (d0 + 65.0D)); + float f20 = -1.0F; + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos(-1.0D, (double) f19, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, (double) f19, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, (double) f19, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, (double) f19, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, (double) f19, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, (double) f19, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, (double) f19, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, (double) f19, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(-1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, -1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); + bufferbuilder.pos(1.0D, -1.0D, -1.0D).color(0, 0, 0, 255).endVertex(); + tessellator.draw(); + } + + if (world.provider.isSkyColored()) { + GlStateManager.color(f * 0.2F + 0.04F, f1 * 0.2F + 0.04F, f2 * 0.6F + 0.1F); + } else { + GlStateManager.color(f, f1, f2); + } + + GlStateManager.pushMatrix(); + GlStateManager.translate(0.0F, -((float) (d0 - 16.0D)), 0.0F); + GlStateManager.callList(rg.glSkyList2); + GlStateManager.popMatrix(); + GlStateManager.enableTexture2D(); + GlStateManager.depthMask(true); } - - private float getRealCelestialAngle(World world, float partialTicks) { - int var4 = (int)(world.getWorldTime() % 24000L); - float var5 = ((float)var4 + partialTicks) / 24000.0F - 0.25F; - - if (var5 < 0.0F) - { - ++var5; - } - - if (var5 > 1.0F) - { - --var5; - } - float var6 = var5; - var5 = 1.0F - (float)((Math.cos((double)var5 * Math.PI) + 1.0D) / 2.0D); - var5 = var6 + (var5 - var6) / 3.0F; - return var5; + // [VanillaCopy] RenderGlobal.generateStars + private void generateStars() { + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + + if (this.starVBO != null) { + this.starVBO.deleteGlBuffers(); + } + + if (this.starGLCallList >= 0) { + GLAllocation.deleteDisplayLists(this.starGLCallList); + this.starGLCallList = -1; + } + + if (this.vboEnabled) { + // TF - inlined RenderGlobal field that's only used once here + this.starVBO = new VertexBuffer(DefaultVertexFormats.POSITION); + this.renderStars(bufferbuilder); + bufferbuilder.finishDrawing(); + bufferbuilder.reset(); + this.starVBO.bufferData(bufferbuilder.getByteBuffer()); + + } else { + this.starGLCallList = GLAllocation.generateDisplayLists(1); + GlStateManager.pushMatrix(); + GlStateManager.glNewList(this.starGLCallList, 4864); + this.renderStars(bufferbuilder); + tessellator.draw(); + GlStateManager.glEndList(); + GlStateManager.popMatrix(); + } } - /** - * Maybe in the future we can get the return of sky color by biome? - * @return - */ - private Vec3 getTwilightSkyColor(World world) { - return Vec3.createVectorHelper(32 / 256.0, 34 / 256.0, 74 / 256.0); -// return Vec3.createVectorHelper(43 / 256.0, 46 / 256.0, 99 / 256.0); - } - - - private void renderStars() - { - Random var1 = new Random(10842L); - Tessellator var2 = Tessellator.instance; - var2.startDrawingQuads(); - - for (int var3 = 0; var3 < 3000; ++var3) - { - double var4 = (double)(var1.nextFloat() * 2.0F - 1.0F); - double var6 = (double)(var1.nextFloat() * 2.0F - 1.0F); - double var8 = (double)(var1.nextFloat() * 2.0F - 1.0F); - double size = (double)(0.10F + var1.nextFloat() * 0.25F); - double var12 = var4 * var4 + var6 * var6 + var8 * var8; - - if (var12 < 1.0D && var12 > 0.01D) - { - var12 = 1.0D / Math.sqrt(var12); - var4 *= var12; - var6 *= var12; - var8 *= var12; - double var14 = var4 * 100.0D; - double var16 = var6 * 100.0D; - double var18 = var8 * 100.0D; - double var20 = Math.atan2(var4, var8); - double var22 = Math.sin(var20); - double var24 = Math.cos(var20); - double var26 = Math.atan2(Math.sqrt(var4 * var4 + var8 * var8), var6); - double var28 = Math.sin(var26); - double var30 = Math.cos(var26); - double var32 = var1.nextDouble() * Math.PI * 2.0D; - double var34 = Math.sin(var32); - double var36 = Math.cos(var32); - - for (int var38 = 0; var38 < 4; ++var38) - { - double var39 = 0.0D; - double var41 = (double)((var38 & 2) - 1) * size; - double var43 = (double)((var38 + 1 & 2) - 1) * size; - double var47 = var41 * var36 - var43 * var34; - double var49 = var43 * var36 + var41 * var34; - double var53 = var47 * var28 + var39 * var30; - double var55 = var39 * var28 - var47 * var30; - double var57 = var55 * var22 - var49 * var24; - double var61 = var49 * var22 + var55 * var24; - var2.addVertex(var14 + var57, var16 + var53, var18 + var61); - } - } - } - - var2.draw(); - } - + // [VanillaCopy] of RenderGlobal.renderStars but with double the number of them + @SuppressWarnings("unused") + private void renderStars(BufferBuilder bufferBuilder) { + Random random = new Random(10842L); + bufferBuilder.begin(7, DefaultVertexFormats.POSITION); + + // TF - 1500 -> 3000 + for (int i = 0; i < 3000; ++i) { + double d0 = (double) (random.nextFloat() * 2.0F - 1.0F); + double d1 = (double) (random.nextFloat() * 2.0F - 1.0F); + double d2 = (double) (random.nextFloat() * 2.0F - 1.0F); + double d3 = (double) (0.15F + random.nextFloat() * 0.1F); + double d4 = d0 * d0 + d1 * d1 + d2 * d2; + + if (d4 < 1.0D && d4 > 0.01D) { + d4 = 1.0D / Math.sqrt(d4); + d0 = d0 * d4; + d1 = d1 * d4; + d2 = d2 * d4; + double d5 = d0 * 100.0D; + double d6 = d1 * 100.0D; + double d7 = d2 * 100.0D; + double d8 = Math.atan2(d0, d2); + double d9 = Math.sin(d8); + double d10 = Math.cos(d8); + double d11 = Math.atan2(Math.sqrt(d0 * d0 + d2 * d2), d1); + double d12 = Math.sin(d11); + double d13 = Math.cos(d11); + double d14 = random.nextDouble() * Math.PI * 2.0D; + double d15 = Math.sin(d14); + double d16 = Math.cos(d14); + + for (int j = 0; j < 4; ++j) { + double d17 = 0.0D; + double d18 = (double) ((j & 2) - 1) * d3; + double d19 = (double) ((j + 1 & 2) - 1) * d3; + double d20 = 0.0D; + double d21 = d18 * d16 - d19 * d15; + double d22 = d19 * d16 + d18 * d15; + double d23 = d21 * d12 + 0.0D * d13; + double d24 = 0.0D * d12 - d21 * d13; + double d25 = d24 * d9 - d22 * d10; + double d26 = d22 * d9 + d24 * d10; + bufferBuilder.pos(d5 + d25, d6 + d23, d7 + d26).endVertex(); + } + } + } + } } diff --git a/src/main/java/twilightforest/client/renderer/TFWeatherRenderer.java b/src/main/java/twilightforest/client/renderer/TFWeatherRenderer.java index d9793dc304..95b183ac81 100644 --- a/src/main/java/twilightforest/client/renderer/TFWeatherRenderer.java +++ b/src/main/java/twilightforest/client/renderer/TFWeatherRenderer.java @@ -1,73 +1,72 @@ package twilightforest.client.renderer; -import java.util.Random; - import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.WorldClient; -import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraftforge.client.IRenderHandler; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; import twilightforest.biomes.TFBiomeDarkForest; +import twilightforest.biomes.TFBiomeFinalPlateau; import twilightforest.biomes.TFBiomeFireSwamp; import twilightforest.biomes.TFBiomeGlacier; import twilightforest.biomes.TFBiomeHighlands; -import twilightforest.biomes.TFBiomeFinalPlateau; import twilightforest.biomes.TFBiomeSnow; import twilightforest.biomes.TFBiomeSwamp; import twilightforest.biomes.TFBiomeThornlands; +import twilightforest.world.TFWorld; + +import java.util.Random; /** * Copypasta of EntityRenderer.renderRainSnow() hacked to include progression environmental effects */ public class TFWeatherRenderer extends IRenderHandler { - - private static final ResourceLocation locationRainPng = new ResourceLocation("textures/environment/rain.png"); - private static final ResourceLocation locationSnowPng = new ResourceLocation("textures/environment/snow.png"); - private static final ResourceLocation locationBlizzardPng = new ResourceLocation(TwilightForestMod.ENVRIO_DIR + "blizzard.png"); - private static final ResourceLocation locationMosquitoPng = new ResourceLocation(TwilightForestMod.ENVRIO_DIR + "mosquitoes.png"); - private static final ResourceLocation locationAshesPng = new ResourceLocation(TwilightForestMod.ENVRIO_DIR + "ashes.png"); - private static final ResourceLocation locationDarkstreamPng = new ResourceLocation(TwilightForestMod.ENVRIO_DIR + "darkstream.png"); - private static final ResourceLocation locationBigrainPng = new ResourceLocation(TwilightForestMod.ENVRIO_DIR + "bigrain.png"); - private static final ResourceLocation locationSparklesPng = new ResourceLocation(TwilightForestMod.ENVRIO_DIR + "sparkles.png"); - - /** Rain X coords */ - float[] rainXCoords; - /** Rain Y coords */ - float[] rainYCoords; + + private static final ResourceLocation RAIN_TEXTURES = new ResourceLocation("textures/environment/rain.png"); + private static final ResourceLocation SNOW_TEXTURES = new ResourceLocation("textures/environment/snow.png"); + + private static final ResourceLocation SPARKLES_TEXTURE = TwilightForestMod.getEnvTexture("sparkles.png"); + + private final float[] rainxs = new float[1024]; + private final float[] rainys = new float[1024]; + + private final Random random = new Random(); + private int rendererUpdateCount; - private Random random; - - private StructureBoundingBox protectedBox; - - + public TFWeatherRenderer() { - this.random = new Random(); + for (int i = 0; i < 32; ++i) { + for (int j = 0; j < 32; ++j) { + float f = (float) (j - 16); + float f1 = (float) (i - 16); + float f2 = MathHelper.sqrt(f * f + f1 * f1); + this.rainxs[i << 5 | j] = -f1 / f2; + this.rainys[i << 5 | j] = f / f2; + } + } } - + public void tick() { + ++this.rendererUpdateCount; + } @Override public void render(float partialTicks, WorldClient world, Minecraft mc) { - - ++this.rendererUpdateCount; - // do normal weather rendering renderNormalWeather(partialTicks, mc); - - if (world.getGameRules().getGameRuleBooleanValue(TwilightForestMod.ENFORCED_PROGRESSION_RULE) && !mc.thePlayer.capabilities.isCreativeMode) { + + if (TFWorld.isProgressionEnforced(world) && !mc.player.isCreative() && !mc.player.isSpectator()) { // locked biome weather effects renderLockedBiome(partialTicks, world, mc); @@ -76,631 +75,506 @@ public void render(float partialTicks, WorldClient world, Minecraft mc) { } } - - + // [VanillaCopy] exact of EntityRenderer.renderRainSnow private void renderNormalWeather(float partialTicks, Minecraft mc) { - float rainStrength = mc.theWorld.getRainStrength(partialTicks); - - if (rainStrength > 0.0F) - { - mc.entityRenderer.enableLightmap((double)partialTicks); - - this.initializeRainCoords(); - - EntityLivingBase entitylivingbase = mc.renderViewEntity; - WorldClient worldclient = mc.theWorld; - int k2 = MathHelper.floor_double(entitylivingbase.posX); - int l2 = MathHelper.floor_double(entitylivingbase.posY); - int i3 = MathHelper.floor_double(entitylivingbase.posZ); - Tessellator tessellator = Tessellator.instance; - GL11.glDisable(GL11.GL_CULL_FACE); - GL11.glNormal3f(0.0F, 1.0F, 0.0F); - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(770, 771, 1, 0); - GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); - double d0 = entitylivingbase.lastTickPosX + (entitylivingbase.posX - entitylivingbase.lastTickPosX) * (double)partialTicks; - double d1 = entitylivingbase.lastTickPosY + (entitylivingbase.posY - entitylivingbase.lastTickPosY) * (double)partialTicks; - double d2 = entitylivingbase.lastTickPosZ + (entitylivingbase.posZ - entitylivingbase.lastTickPosZ) * (double)partialTicks; - int k = MathHelper.floor_double(d1); - byte range = 5; - - if (mc.gameSettings.fancyGraphics) - { - range = 10; - } - - byte b1 = -1; - float f5 = (float)this.rendererUpdateCount + partialTicks; - - if (mc.gameSettings.fancyGraphics) - { - range = 10; - } - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - for (int l = i3 - range; l <= i3 + range; ++l) - { - for (int i1 = k2 - range; i1 <= k2 + range; ++i1) - { - int j1 = (l - i3 + 16) * 32 + i1 - k2 + 16; - float f6 = this.rainXCoords[j1] * 0.5F; - float f7 = this.rainYCoords[j1] * 0.5F; - BiomeGenBase biomegenbase = worldclient.getBiomeGenForCoords(i1, l); - - if (biomegenbase.canSpawnLightningBolt() || biomegenbase.getEnableSnow()) - { - int k1 = worldclient.getPrecipitationHeight(i1, l); - int l1 = l2 - range; - int i2 = l2 + range; - - if (l1 < k1) - { - l1 = k1; - } - - if (i2 < k1) - { - i2 = k1; - } - - float f8 = 1.0F; - int j2 = k1; - - if (k1 < k) - { - j2 = k; - } - - if (l1 != i2) - { - this.random.setSeed((long)(i1 * i1 * 3121 + i1 * 45238971 ^ l * l * 418711 + l * 13761)); - float f9 = biomegenbase.getFloatTemperature(i1, l1, l); - float downwardsMotion; - double xDist; - - if (worldclient.getWorldChunkManager().getTemperatureAtHeight(f9, k1) >= 0.15F) - { - if (b1 != 0) - { - if (b1 >= 0) - { - tessellator.draw(); - } - - b1 = 0; - mc.getTextureManager().bindTexture(locationRainPng); - tessellator.startDrawingQuads(); - } - - downwardsMotion = ((float)(this.rendererUpdateCount + i1 * i1 * 3121 + i1 * 45238971 + l * l * 418711 + l * 13761 & 31) + partialTicks) / 32.0F * (3.0F + this.random.nextFloat()); - double d3 = (double)((float)i1 + 0.5F) - entitylivingbase.posX; - xDist = (double)((float)l + 0.5F) - entitylivingbase.posZ; - float f12 = MathHelper.sqrt_double(d3 * d3 + xDist * xDist) / (float)range; - float f13 = 1.0F; - tessellator.setBrightness(worldclient.getLightBrightnessForSkyBlocks(i1, j2, l, 0)); - tessellator.setColorRGBA_F(f13, f13, f13, ((1.0F - f12 * f12) * 0.5F + 0.5F) * rainStrength); - tessellator.setTranslation(-d0 * 1.0D, -d1 * 1.0D, -d2 * 1.0D); - tessellator.addVertexWithUV((double)((float)i1 - f6) + 0.5D, (double)l1, (double)((float)l - f7) + 0.5D, (double)(0.0F * f8), (double)((float)l1 * f8 / 4.0F + downwardsMotion * f8)); - tessellator.addVertexWithUV((double)((float)i1 + f6) + 0.5D, (double)l1, (double)((float)l + f7) + 0.5D, (double)(1.0F * f8), (double)((float)l1 * f8 / 4.0F + downwardsMotion * f8)); - tessellator.addVertexWithUV((double)((float)i1 + f6) + 0.5D, (double)i2, (double)((float)l + f7) + 0.5D, (double)(1.0F * f8), (double)((float)i2 * f8 / 4.0F + downwardsMotion * f8)); - tessellator.addVertexWithUV((double)((float)i1 - f6) + 0.5D, (double)i2, (double)((float)l - f7) + 0.5D, (double)(0.0F * f8), (double)((float)i2 * f8 / 4.0F + downwardsMotion * f8)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - } - else - { - if (b1 != 1) - { - if (b1 >= 0) - { - tessellator.draw(); - } - - b1 = 1; - mc.getTextureManager().bindTexture(locationSnowPng); - tessellator.startDrawingQuads(); - } - - downwardsMotion = ((float)(this.rendererUpdateCount & 511) + partialTicks) / 512.0F; - float f16 = this.random.nextFloat() + f5 * 0.01F * (float)this.random.nextGaussian(); - float f11 = this.random.nextFloat() + f5 * (float)this.random.nextGaussian() * 0.001F; - xDist = (double)((float)i1 + 0.5F) - entitylivingbase.posX; - double zDist = (double)((float)l + 0.5F) - entitylivingbase.posZ; - float f14 = MathHelper.sqrt_double(xDist * xDist + zDist * zDist) / (float)range; - float f15 = 1.0F; - tessellator.setBrightness((worldclient.getLightBrightnessForSkyBlocks(i1, j2, l, 0) * 3 + 15728880) / 4); - tessellator.setColorRGBA_F(f15, f15, f15, ((1.0F - f14 * f14) * 0.3F + 0.5F) * rainStrength); - tessellator.setTranslation(-d0 * 1.0D, -d1 * 1.0D, -d2 * 1.0D); - tessellator.addVertexWithUV((double)((float)i1 - f6) + 0.5D, (double)l1, (double)((float)l - f7) + 0.5D, (double)(0.0F * f8 + f16), (double)((float)l1 * f8 / 4.0F + downwardsMotion * f8 + f11)); - tessellator.addVertexWithUV((double)((float)i1 + f6) + 0.5D, (double)l1, (double)((float)l + f7) + 0.5D, (double)(1.0F * f8 + f16), (double)((float)l1 * f8 / 4.0F + downwardsMotion * f8 + f11)); - tessellator.addVertexWithUV((double)((float)i1 + f6) + 0.5D, (double)i2, (double)((float)l + f7) + 0.5D, (double)(1.0F * f8 + f16), (double)((float)i2 * f8 / 4.0F + downwardsMotion * f8 + f11)); - tessellator.addVertexWithUV((double)((float)i1 - f6) + 0.5D, (double)i2, (double)((float)l - f7) + 0.5D, (double)(0.0F * f8 + f16), (double)((float)i2 * f8 / 4.0F + downwardsMotion * f8 + f11)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - } - } - } - } - } - - if (b1 >= 0) - { - tessellator.draw(); - } - - GL11.glEnable(GL11.GL_CULL_FACE); - GL11.glDisable(GL11.GL_BLEND); - GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); - mc.entityRenderer.disableLightmap((double)partialTicks); - } + float f = mc.world.getRainStrength(partialTicks); + + if (f > 0.0F) { + mc.entityRenderer.enableLightmap(); + Entity entity = mc.getRenderViewEntity(); + World world = mc.world; + int i = MathHelper.floor(entity.posX); + int j = MathHelper.floor(entity.posY); + int k = MathHelper.floor(entity.posZ); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + GlStateManager.disableCull(); + GlStateManager.glNormal3f(0.0F, 1.0F, 0.0F); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.alphaFunc(516, 0.1F); + double d0 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double) partialTicks; + double d1 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double) partialTicks; + double d2 = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double) partialTicks; + int l = MathHelper.floor(d1); + int i1 = 5; + + if (mc.gameSettings.fancyGraphics) { + i1 = 10; + } + + int j1 = -1; + float f1 = (float) this.rendererUpdateCount + partialTicks; + bufferbuilder.setTranslation(-d0, -d1, -d2); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + for (int k1 = k - i1; k1 <= k + i1; ++k1) { + for (int l1 = i - i1; l1 <= i + i1; ++l1) { + int i2 = (k1 - k + 16) * 32 + l1 - i + 16; + double d3 = (double) this.rainxs[i2] * 0.5D; + double d4 = (double) this.rainys[i2] * 0.5D; + blockpos$mutableblockpos.setPos(l1, 0, k1); + Biome biome = world.getBiome(blockpos$mutableblockpos); + + if (biome.canRain() || biome.getEnableSnow()) { + int j2 = world.getPrecipitationHeight(blockpos$mutableblockpos).getY(); + int k2 = j - i1; + int l2 = j + i1; + + if (k2 < j2) { + k2 = j2; + } + + if (l2 < j2) { + l2 = j2; + } + + int i3 = j2; + + if (j2 < l) { + i3 = l; + } + + if (k2 != l2) { + this.random.setSeed((long) (l1 * l1 * 3121 + l1 * 45238971 ^ k1 * k1 * 418711 + k1 * 13761)); + blockpos$mutableblockpos.setPos(l1, k2, k1); + float f2 = biome.getTemperature(blockpos$mutableblockpos); + + if (world.getBiomeProvider().getTemperatureAtHeight(f2, j2) >= 0.15F) { + if (j1 != 0) { + if (j1 >= 0) { + tessellator.draw(); + } + + j1 = 0; + mc.getTextureManager().bindTexture(RAIN_TEXTURES); + bufferbuilder.begin(7, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + } + + double d5 = -((double) (this.rendererUpdateCount + l1 * l1 * 3121 + l1 * 45238971 + k1 * k1 * 418711 + k1 * 13761 & 31) + (double) partialTicks) / 32.0D * (3.0D + this.random.nextDouble()); + double d6 = (double) ((float) l1 + 0.5F) - entity.posX; + double d7 = (double) ((float) k1 + 0.5F) - entity.posZ; + float f3 = MathHelper.sqrt(d6 * d6 + d7 * d7) / (float) i1; + float f4 = ((1.0F - f3 * f3) * 0.5F + 0.5F) * f; + blockpos$mutableblockpos.setPos(l1, i3, k1); + int j3 = world.getCombinedLight(blockpos$mutableblockpos, 0); + int k3 = j3 >> 16 & 65535; + int l3 = j3 & 65535; + bufferbuilder.pos((double) l1 - d3 + 0.5D, (double) l2, (double) k1 - d4 + 0.5D).tex(0.0D, (double) k2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) l1 + d3 + 0.5D, (double) l2, (double) k1 + d4 + 0.5D).tex(1.0D, (double) k2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) l1 + d3 + 0.5D, (double) k2, (double) k1 + d4 + 0.5D).tex(1.0D, (double) l2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) l1 - d3 + 0.5D, (double) k2, (double) k1 - d4 + 0.5D).tex(0.0D, (double) l2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + } else { + if (j1 != 1) { + if (j1 >= 0) { + tessellator.draw(); + } + + j1 = 1; + mc.getTextureManager().bindTexture(SNOW_TEXTURES); + bufferbuilder.begin(7, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + } + + double d8 = (double) (-((float) (this.rendererUpdateCount & 511) + partialTicks) / 512.0F); + double d9 = this.random.nextDouble() + (double) f1 * 0.01D * (double) ((float) this.random.nextGaussian()); + double d10 = this.random.nextDouble() + (double) (f1 * (float) this.random.nextGaussian()) * 0.001D; + double d11 = (double) ((float) l1 + 0.5F) - entity.posX; + double d12 = (double) ((float) k1 + 0.5F) - entity.posZ; + float f6 = MathHelper.sqrt(d11 * d11 + d12 * d12) / (float) i1; + float f5 = ((1.0F - f6 * f6) * 0.3F + 0.5F) * f; + blockpos$mutableblockpos.setPos(l1, i3, k1); + int i4 = (world.getCombinedLight(blockpos$mutableblockpos, 0) * 3 + 15728880) / 4; + int j4 = i4 >> 16 & 65535; + int k4 = i4 & 65535; + bufferbuilder.pos((double) l1 - d3 + 0.5D, (double) l2, (double) k1 - d4 + 0.5D).tex(0.0D + d9, (double) k2 * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) l1 + d3 + 0.5D, (double) l2, (double) k1 + d4 + 0.5D).tex(1.0D + d9, (double) k2 * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) l1 + d3 + 0.5D, (double) k2, (double) k1 + d4 + 0.5D).tex(1.0D + d9, (double) l2 * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) l1 - d3 + 0.5D, (double) k2, (double) k1 - d4 + 0.5D).tex(0.0D + d9, (double) l2 * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + } + } + } + } + } + + if (j1 >= 0) { + tessellator.draw(); + } + + bufferbuilder.setTranslation(0.0D, 0.0D, 0.0D); + GlStateManager.enableCull(); + GlStateManager.disableBlend(); + GlStateManager.alphaFunc(516, 0.1F); + mc.entityRenderer.disableLightmap(); + } } - - - private void renderLockedBiome(float partialTicks, WorldClient world, Minecraft mc) { + // [VanillaCopy] inside of EntityRenderer.renderRainSnow, edits noted + private void renderLockedBiome(float partialTicks, WorldClient wc, Minecraft mc) { // check nearby for locked biome - if (isNearLockedBiome(world, mc.renderViewEntity)) { - this.initializeRainCoords(); - - EntityLivingBase entitylivingbase = mc.renderViewEntity; - WorldClient worldclient = mc.theWorld; - int px = MathHelper.floor_double(entitylivingbase.posX); - int py = MathHelper.floor_double(entitylivingbase.posY); - int pz = MathHelper.floor_double(entitylivingbase.posZ); - Tessellator tessellator = Tessellator.instance; - GL11.glDisable(GL11.GL_CULL_FACE); - GL11.glNormal3f(0.0F, 1.0F, 0.0F); - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(770, 771, 1, 0); - GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); - double offX = entitylivingbase.lastTickPosX + (entitylivingbase.posX - entitylivingbase.lastTickPosX) * (double)partialTicks; - double offY = entitylivingbase.lastTickPosY + (entitylivingbase.posY - entitylivingbase.lastTickPosY) * (double)partialTicks; - double offZ = entitylivingbase.lastTickPosZ + (entitylivingbase.posZ - entitylivingbase.lastTickPosZ) * (double)partialTicks; - int floorY = MathHelper.floor_double(offY); - byte range = 5; - - if (mc.gameSettings.fancyGraphics) - { - range = 10; - } - - byte drawFlag = -1; - float preciseCount = (float)this.rendererUpdateCount + partialTicks; - - if (mc.gameSettings.fancyGraphics) - { - range = 15; - } - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - for (int dz = pz - range; dz <= pz + range; ++dz) - { - for (int dx = px - range; dx <= px + range; ++dx) - { - int rainIndex = (dz - pz + 16) * 32 + dx - px + 16; - float rainX = this.rainXCoords[rainIndex] * 0.5F; - float rainZ = this.rainYCoords[rainIndex] * 0.5F; - BiomeGenBase biomegenbase = worldclient.getBiomeGenForCoords(dx, dz); - - - if (biomegenbase instanceof TFBiomeBase && entitylivingbase instanceof EntityPlayer && !((TFBiomeBase)biomegenbase).doesPlayerHaveRequiredAchievement((EntityPlayer)entitylivingbase)) { - - int rainHeight = 0;//worldclient.getPrecipitationHeight(dx, dz); - int rainMin = py - range; - int rainMax = py + range * 2; - - if (rainMin < rainHeight) - { - rainMin = rainHeight; - } - - if (rainMax < rainHeight) - { - rainMax = rainHeight; - } - - float one = 1.0F; - int rainFloor = rainHeight; - - if (rainHeight < floorY) - { - rainFloor = floorY; - } - - if (rainMin != rainMax) - { - this.random.setSeed((long)(dx * dx * 3121 + dx * 45238971 ^ dz * dz * 418711 + dz * 13761)); - - if (biomegenbase instanceof TFBiomeSnow || biomegenbase instanceof TFBiomeGlacier) { - // SNOW - - if (drawFlag != 0) - { - if (drawFlag >= 0) - { - tessellator.draw(); - } - - drawFlag = 0; - mc.getTextureManager().bindTexture(locationBlizzardPng); - tessellator.startDrawingQuads(); - } - - float countFactor = ((float)(this.rendererUpdateCount & 511) + partialTicks) / 512.0F; - float uFactor = this.random.nextFloat() + preciseCount * 0.03F * (float)this.random.nextGaussian(); - float vFactor = this.random.nextFloat() + preciseCount * 0.001F * (float)this.random.nextGaussian(); - double xRange = (double)((float)dx + 0.5F) - entitylivingbase.posX; - double zRange = (double)((float)dz + 0.5F) - entitylivingbase.posZ; - float f14 = MathHelper.sqrt_double(xRange * xRange + zRange * zRange) / (float)range; - float onee = 1.0F; - tessellator.setBrightness((worldclient.getLightBrightnessForSkyBlocks(dx, rainFloor, dz, 0) * 3 + 15728880) / 4); - tessellator.setColorRGBA_F(onee, onee, onee, ((1.0F - f14 * f14) * 0.3F + 0.5F) * 1.0F); - tessellator.setTranslation(-offX * 1.0D, -offY * 1.0D, -offZ * 1.0D); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMin, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMin, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMax, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMax, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - - } else if (biomegenbase instanceof TFBiomeSwamp) { - // MOSQUITOES - - if (drawFlag != 1) - { - if (drawFlag >= 0) - { - tessellator.draw(); - } - - drawFlag = 1; - mc.getTextureManager().bindTexture(locationMosquitoPng); - tessellator.startDrawingQuads(); - } - - float countFactor = 0;//((float)(this.rendererUpdateCount & 511) + partialTicks) / 512.0F; - float uFactor = this.random.nextFloat() + preciseCount * 0.03F * (float)this.random.nextGaussian(); - float vFactor = this.random.nextFloat() + preciseCount * 0.003F * (float)this.random.nextGaussian(); - //double xRange = (double)((float)dx + 0.5F) - entitylivingbase.posX; - //double zRange = (double)((float)dz + 0.5F) - entitylivingbase.posZ; - //float distanceFromPlayer = MathHelper.sqrt_double(xRange * xRange + zRange * zRange) / (float)range; - tessellator.setBrightness(983055); - float r = random.nextFloat() * 0.3F; - float g = random.nextFloat() * 0.3F; - float b = random.nextFloat() * 0.3F; - tessellator.setColorRGBA_F(r, g, b, 1.0F);//((1.0F - distanceFromPlayer * distanceFromPlayer) * 0.3F + 0.5F) * 1.0F); - tessellator.setTranslation(-offX * 1.0D, -offY * 1.0D, -offZ * 1.0D); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMin, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMin, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMax, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMax, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - } else if (biomegenbase instanceof TFBiomeFireSwamp) { - // ASHES - - if (drawFlag != 2) - { - if (drawFlag >= 0) - { - tessellator.draw(); - } - - drawFlag = 2; - mc.getTextureManager().bindTexture(locationAshesPng); - tessellator.startDrawingQuads(); - } - - float countFactor = -((float)(this.rendererUpdateCount & 1023) + partialTicks) / 1024.0F; - float uFactor = this.random.nextFloat() + preciseCount * 0.001F * (float)this.random.nextGaussian(); - float vFactor = this.random.nextFloat() + preciseCount * 0.001F * (float)this.random.nextGaussian(); - double xRange = (double)((float)dx + 0.5F) - entitylivingbase.posX; - double zRange = (double)((float)dz + 0.5F) - entitylivingbase.posZ; - float distanceFromPlayer = MathHelper.sqrt_double(xRange * xRange + zRange * zRange) / (float)range; - tessellator.setBrightness(983055); - float bright = random.nextFloat() * 0.2F + 0.8F; - tessellator.setColorRGBA_F(bright, bright, bright, ((1.0F - distanceFromPlayer * distanceFromPlayer) * 0.3F + 0.5F) * 1.0F); - tessellator.setTranslation(-offX * 1.0D, -offY * 1.0D, -offZ * 1.0D); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMin, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMin, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMax, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMax, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - } else if (biomegenbase instanceof TFBiomeDarkForest && random.nextInt(2) == 0) { - // DARKTHINGS - - if (drawFlag != 3) - { - if (drawFlag >= 0) - { - tessellator.draw(); - } - - drawFlag = 3; - mc.getTextureManager().bindTexture(locationDarkstreamPng); - tessellator.startDrawingQuads(); - } - - int darkRainMax = Math.min(rainMax, worldclient.getPrecipitationHeight(dx, dz)); - int darkRainMin = Math.min(rainMin, darkRainMax); - - float countFactor = -((float)(this.rendererUpdateCount & 511) + partialTicks) / 512.0F; - float uFactor = 0;//this.random.nextFloat() + preciseCount * 0.001F * (float)this.random.nextGaussian(); - float vFactor = this.random.nextFloat() + preciseCount * 0.01F * (float)this.random.nextGaussian(); - double xRange = (double)((float)dx + 0.5F) - entitylivingbase.posX; - double zRange = (double)((float)dz + 0.5F) - entitylivingbase.posZ; - float distanceFromPlayer = MathHelper.sqrt_double(xRange * xRange + zRange * zRange) / (float)range; - tessellator.setBrightness(983055); - float bright = 1.0F; - float alpha = random.nextFloat(); - tessellator.setColorRGBA_F(bright, bright, bright, ((1.0F - distanceFromPlayer * distanceFromPlayer) * 0.3F + 0.5F) * alpha); - tessellator.setTranslation(-offX * 1.0D, -offY * 1.0D, -offZ * 1.0D); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)darkRainMin, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)darkRainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)darkRainMin, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)darkRainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)darkRainMax, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)darkRainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)darkRainMax, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)darkRainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - } else if (biomegenbase instanceof TFBiomeHighlands || biomegenbase instanceof TFBiomeThornlands || biomegenbase instanceof TFBiomeFinalPlateau) { - // GREENRAIN - - if (drawFlag != 4) - { - if (drawFlag >= 0) - { - tessellator.draw(); - } - - drawFlag = 4; - mc.getTextureManager().bindTexture(locationBigrainPng); - tessellator.startDrawingQuads(); - } - - float countFactor = ((float)(this.rendererUpdateCount + dx * dx * 3121 + dx * 45238971 + dz * dz * 418711 + dz * 13761 & 31) + partialTicks) / 32.0F * (3.0F + this.random.nextFloat()); - float uFactor = this.random.nextFloat(); - float vFactor = this.random.nextFloat(); - double xRange = (double)((float)dx + 0.5F) - entitylivingbase.posX; - double zRange = (double)((float)dz + 0.5F) - entitylivingbase.posZ; - float distanceFromPlayer = MathHelper.sqrt_double(xRange * xRange + zRange * zRange) / (float)range; - tessellator.setBrightness(worldclient.getLightBrightnessForSkyBlocks(dx, rainFloor, dz, 0)); - float bright = 1.0F; - float alpha = 1.0F;//random.nextFloat(); - tessellator.setColorRGBA_F(bright, bright, bright, ((1.0F - distanceFromPlayer * distanceFromPlayer) * 0.3F + 0.5F) * alpha); - tessellator.setTranslation(-offX * 1.0D, -offY * 1.0D, -offZ * 1.0D); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMin, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMin, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMax, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMax, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - } - - } - } - } - } - - if (drawFlag >= 0) - { - tessellator.draw(); - } - - GL11.glEnable(GL11.GL_CULL_FACE); - GL11.glDisable(GL11.GL_BLEND); - GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); - mc.entityRenderer.disableLightmap((double)partialTicks); - - } + if (isNearLockedBiome(wc, mc.getRenderViewEntity())) { + + mc.entityRenderer.enableLightmap(); + Entity entity = mc.getRenderViewEntity(); + World world = mc.world; + + int x0 = MathHelper.floor(entity.posX); + int y0 = MathHelper.floor(entity.posY); + int z0 = MathHelper.floor(entity.posZ); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + + GlStateManager.disableCull(); + GlStateManager.glNormal3f(0.0F, 1.0F, 0.0F); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.alphaFunc(516, 0.1F); + + double dx = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double) partialTicks; + double dy = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double) partialTicks; + double dz = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double) partialTicks; + + int y1 = MathHelper.floor(dy); + int range = 5; + + if (mc.gameSettings.fancyGraphics) { + range = 10; + } + + RenderType currentType = null; + float combinedTicks = (float) this.rendererUpdateCount + partialTicks; + bufferbuilder.setTranslation(-dx, -dy, -dz); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + for (int z = z0 - range; z <= z0 + range; ++z) { + for (int x = x0 - range; x <= x0 + range; ++x) { + + int idx = (z - z0 + 16) * 32 + x - x0 + 16; + double rx = (double) this.rainxs[idx] * 0.5D; + double ry = (double) this.rainys[idx] * 0.5D; + + blockpos$mutableblockpos.setPos(x, 0, z); + Biome biome = world.getBiome(blockpos$mutableblockpos); + + // TF - check for our own biomes + if (!TFWorld.isBiomeSafeFor(biome, entity)) { + + int groundY = 0; // TF - extend through full height + int minY = y0 - range; + int maxY = y0 + range; + + if (minY < groundY) { + minY = groundY; + } + + if (maxY < groundY) { + maxY = groundY; + } + + int y = groundY; + + if (groundY < y1) { + y = y1; + } + + if (minY != maxY) { + + this.random.setSeed((long) (x * x * 3121 + x * 45238971 ^ z * z * 418711 + z * 13761)); + + // TF - replace temperature check with biome check + RenderType nextType = getRenderType(biome); + if (nextType == null) { + continue; + } + + // TF - share this logic and use an enum instead of magic numbers + if (currentType != nextType) { + if (currentType != null) { + tessellator.draw(); + } + currentType = nextType; + mc.getTextureManager().bindTexture(nextType.getTextureLocation()); + bufferbuilder.begin(7, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + } + + // TF - replicate for each render type with own changes + switch (currentType) { + case BLIZZARD: { + double d5 = -((double) (this.rendererUpdateCount + x * x * 3121 + x * 45238971 + z * z * 418711 + z * 13761 & 31) + (double) partialTicks) / 32.0D * (3.0D + this.random.nextDouble()); + double d6 = (double) ((float) x + 0.5F) - entity.posX; + double d7 = (double) ((float) z + 0.5F) - entity.posZ; + float f3 = MathHelper.sqrt(d6 * d6 + d7 * d7) / (float) range; + float f4 = ((1.0F - f3 * f3) * 0.5F + 0.5F) * 1.0F; + blockpos$mutableblockpos.setPos(x, y, z); + int j3 = world.getCombinedLight(blockpos$mutableblockpos, 0); + int k3 = j3 >> 16 & 65535; + int l3 = j3 & 65535; + bufferbuilder.pos((double) x - rx + 0.5D, (double) maxY, (double) z - ry + 0.5D).tex(0.0D, (double) minY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) maxY, (double) z + ry + 0.5D).tex(1.0D, (double) minY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) minY, (double) z + ry + 0.5D).tex(1.0D, (double) maxY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) x - rx + 0.5D, (double) minY, (double) z - ry + 0.5D).tex(0.0D, (double) maxY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + } break; + case MOSQUITO: { + double d8 = 0; // TF - no wiggle + double d9 = this.random.nextDouble() + (double) combinedTicks * 0.01D * (double) ((float) this.random.nextGaussian()); + double d10 = this.random.nextDouble() + (double) (combinedTicks * (float) this.random.nextGaussian()) * 0.001D; + double d11 = (double) ((float) x + 0.5F) - entity.posX; + double d12 = (double) ((float) z + 0.5F) - entity.posZ; + float f6 = MathHelper.sqrt(d11 * d11 + d12 * d12) / (float) range; + float r = random.nextFloat() * 0.3F; // TF - random color + float g = random.nextFloat() * 0.3F; + float b = random.nextFloat() * 0.3F; + float f5 = ((1.0F - f6 * f6) * 0.3F + 0.5F) * 1.0F; + int i4 = 15 << 20 | 15 << 4; // TF - fullbright + int j4 = i4 >> 16 & 65535; + int k4 = i4 & 65535; + bufferbuilder.pos((double) x - rx + 0.5D, (double) maxY, (double) z - ry + 0.5D).tex(0.0D + d9, (double) minY * 0.25D + d8 + d10).color(r, g, b, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) maxY, (double) z + ry + 0.5D).tex(1.0D + d9, (double) minY * 0.25D + d8 + d10).color(r, g, b, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) minY, (double) z + ry + 0.5D).tex(1.0D + d9, (double) maxY * 0.25D + d8 + d10).color(r, g, b, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x - rx + 0.5D, (double) minY, (double) z - ry + 0.5D).tex(0.0D + d9, (double) maxY * 0.25D + d8 + d10).color(r, g, b, f5).lightmap(j4, k4).endVertex(); + } break; + case ASHES: { + double d8 = (double) (-((float) (this.rendererUpdateCount & 511) + partialTicks) / 512.0F); + double d9 = this.random.nextDouble() + (double) combinedTicks * 0.01D * (double) ((float) this.random.nextGaussian()); + double d10 = this.random.nextDouble() + (double) (combinedTicks * (float) this.random.nextGaussian()) * 0.001D; + double d11 = (double) ((float) x + 0.5F) - entity.posX; + double d12 = (double) ((float) z + 0.5F) - entity.posZ; + float f6 = MathHelper.sqrt(d11 * d11 + d12 * d12) / (float) range; + float f5 = ((1.0F - f6 * f6) * 0.3F + 0.5F) * 1.0F; + int i4 = 15 << 20 | 15 << 4; // TF - fullbright + int j4 = i4 >> 16 & 65535; + int k4 = i4 & 65535; + float color = random.nextFloat() * 0.2F + 0.8F; // TF - random color + bufferbuilder.pos((double) x - rx + 0.5D, (double) maxY, (double) z - ry + 0.5D).tex(0.0D + d9, (double) minY * 0.25D + d8 + d10).color(color, color, color, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) maxY, (double) z + ry + 0.5D).tex(1.0D + d9, (double) minY * 0.25D + d8 + d10).color(color, color, color, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) minY, (double) z + ry + 0.5D).tex(1.0D + d9, (double) maxY * 0.25D + d8 + d10).color(color, color, color, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x - rx + 0.5D, (double) minY, (double) z - ry + 0.5D).tex(0.0D + d9, (double) maxY * 0.25D + d8 + d10).color(color, color, color, f5).lightmap(j4, k4).endVertex(); + } break; + case DARK_STREAM: { + double d8 = (double) (-((float) (this.rendererUpdateCount & 511) + partialTicks) / 512.0F); + double d9 = 0; // TF - no u wiggle + double d10 = this.random.nextDouble() + (double) (combinedTicks * (float) this.random.nextGaussian()) * 0.001D; + double d11 = (double) ((float) x + 0.5F) - entity.posX; + double d12 = (double) ((float) z + 0.5F) - entity.posZ; + float f6 = MathHelper.sqrt(d11 * d11 + d12 * d12) / (float) range; + float f5 = ((1.0F - f6 * f6) * 0.3F + 0.5F) * random.nextFloat(); // TF - random alpha multiplier + int i4 = 15 << 20 | 15 << 4; // TF - fullbright + int j4 = i4 >> 16 & 65535; + int k4 = i4 & 65535; + bufferbuilder.pos((double) x - rx + 0.5D, (double) maxY, (double) z - ry + 0.5D).tex(0.0D + d9, (double) minY * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) maxY, (double) z + ry + 0.5D).tex(1.0D + d9, (double) minY * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) minY, (double) z + ry + 0.5D).tex(1.0D + d9, (double) maxY * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + bufferbuilder.pos((double) x - rx + 0.5D, (double) minY, (double) z - ry + 0.5D).tex(0.0D + d9, (double) maxY * 0.25D + d8 + d10).color(1.0F, 1.0F, 1.0F, f5).lightmap(j4, k4).endVertex(); + } break; + case BIG_RAIN: { + double d5 = -((double) (this.rendererUpdateCount + x * x * 3121 + x * 45238971 + z * z * 418711 + z * 13761 & 31) + (double) partialTicks) / 32.0D * (3.0D + this.random.nextDouble()); + double d6 = (double) ((float) x + 0.5F) - entity.posX; + double d7 = (double) ((float) z + 0.5F) - entity.posZ; + float f3 = MathHelper.sqrt(d6 * d6 + d7 * d7) / (float) range; + float f4 = ((1.0F - f3 * f3) * 0.5F + 0.5F) * 1.0F; + blockpos$mutableblockpos.setPos(x, y, z); + int j3 = world.getCombinedLight(blockpos$mutableblockpos, 0); + int k3 = j3 >> 16 & 65535; + int l3 = j3 & 65535; + bufferbuilder.pos((double) x - rx + 0.5D, (double) maxY, (double) z - ry + 0.5D).tex(0.0D, (double) minY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) maxY, (double) z + ry + 0.5D).tex(1.0D, (double) minY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) x + rx + 0.5D, (double) minY, (double) z + ry + 0.5D).tex(1.0D, (double) maxY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) x - rx + 0.5D, (double) minY, (double) z - ry + 0.5D).tex(0.0D, (double) maxY * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + } break; + } + } + } + } + } + + if (currentType != null) { + tessellator.draw(); + } + + bufferbuilder.setTranslation(0.0D, 0.0D, 0.0D); + GlStateManager.enableCull(); + GlStateManager.disableBlend(); + GlStateManager.alphaFunc(516, 0.1F); + mc.entityRenderer.disableLightmap(); + } } - - - private void renderLockedStructure(float partialTicks, WorldClient world, Minecraft mc) { + // [VanillaCopy] inside of EntityRenderer.renderRainSnow, edits noted + private void renderLockedStructure(float partialTicks, WorldClient wc, Minecraft mc) { // draw locked structure thing - if (isNearLockedStructure(world, mc.renderViewEntity)) { - this.initializeRainCoords(); - - EntityLivingBase entitylivingbase = mc.renderViewEntity; - int px = MathHelper.floor_double(entitylivingbase.posX); - int py = MathHelper.floor_double(entitylivingbase.posY); - int pz = MathHelper.floor_double(entitylivingbase.posZ); - Tessellator tessellator = Tessellator.instance; - GL11.glDisable(GL11.GL_CULL_FACE); - GL11.glNormal3f(0.0F, 1.0F, 0.0F); - GL11.glEnable(GL11.GL_BLEND); - OpenGlHelper.glBlendFunc(770, 771, 1, 0); - GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); - double offX = entitylivingbase.lastTickPosX + (entitylivingbase.posX - entitylivingbase.lastTickPosX) * (double)partialTicks; - double offY = entitylivingbase.lastTickPosY + (entitylivingbase.posY - entitylivingbase.lastTickPosY) * (double)partialTicks; - double offZ = entitylivingbase.lastTickPosZ + (entitylivingbase.posZ - entitylivingbase.lastTickPosZ) * (double)partialTicks; - byte range = 5; - - if (mc.gameSettings.fancyGraphics) - { - range = 10; - } - - byte drawFlag = -1; - float preciseCount = (float)this.rendererUpdateCount + partialTicks; - - if (mc.gameSettings.fancyGraphics) - { - range = 15; - } - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - for (int dz = pz - range; dz <= pz + range; ++dz) - { - for (int dx = px - range; dx <= px + range; ++dx) - { - int rainIndex = (dz - pz + 16) * 32 + dx - px + 16; - float rainX = this.rainXCoords[rainIndex] * 0.5F; - float rainZ = this.rainYCoords[rainIndex] * 0.5F; - - if (this.protectedBox != null && this.protectedBox.intersectsWith(dx, dz, dx, dz)) { - - //System.out.println("Column in structure"); - - int structureMin = this.protectedBox.minY - 4; - int structureMax = this.protectedBox.maxY + 4; - int rainMin = py - range; - int rainMax = py + range * 2; - - if (rainMin < structureMin) - { - rainMin = structureMin; - } - - if (rainMax < structureMin) - { - rainMax = structureMin; - } - - if (rainMin > structureMax) - { - rainMin = structureMax; - } - - if (rainMax > structureMax) - { - rainMax = structureMax; - } - - float one = 1.0F; - if (rainMin != rainMax) - { - this.random.setSeed((long)(dx * dx * 3121 + dx * 45238971 ^ dz * dz * 418711 + dz * 13761)); - - if (true) { - - if (drawFlag != 0) - { - if (drawFlag >= 0) - { - tessellator.draw(); - } - - drawFlag = 0; - mc.getTextureManager().bindTexture(locationSparklesPng); - tessellator.startDrawingQuads(); - } - - float countFactor = ((float)(this.rendererUpdateCount & 511) + partialTicks) / 512.0F; - float uFactor = this.random.nextFloat() + preciseCount * 0.01F * (float)this.random.nextGaussian(); - float vFactor = this.random.nextFloat() + preciseCount * 0.01F * (float)this.random.nextGaussian(); - double xRange = (double)((float)dx + 0.5F) - entitylivingbase.posX; - double zRange = (double)((float)dz + 0.5F) - entitylivingbase.posZ; - float distanceFromPlayer = MathHelper.sqrt_double(xRange * xRange + zRange * zRange) / (float)range; - tessellator.setBrightness(983055); - float bright = 1.0F; - float alpha = random.nextFloat(); - tessellator.setColorRGBA_F(bright, bright, bright, ((1.0F - distanceFromPlayer * distanceFromPlayer) * 0.3F + 0.5F) * alpha); - tessellator.setTranslation(-offX * 1.0D, -offY * 1.0D, -offZ * 1.0D); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMin, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMin, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMin * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx + rainX) + 0.5D, (double)rainMax, (double)((float)dz + rainZ) + 0.5D, (double)(1.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.addVertexWithUV((double)((float)dx - rainX) + 0.5D, (double)rainMax, (double)((float)dz - rainZ) + 0.5D, (double)(0.0F * one + uFactor), (double)((float)rainMax * one / 4.0F + countFactor * one + vFactor)); - tessellator.setTranslation(0.0D, 0.0D, 0.0D); - - } - - } - } - } - } - - if (drawFlag >= 0) - { - tessellator.draw(); - } - - GL11.glEnable(GL11.GL_CULL_FACE); - GL11.glDisable(GL11.GL_BLEND); - GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); - mc.entityRenderer.disableLightmap((double)partialTicks); - - } + if (isNearLockedStructure(wc, mc.getRenderViewEntity())) { + mc.entityRenderer.enableLightmap(); + Entity entity = mc.getRenderViewEntity(); + World world = mc.world; + int i = MathHelper.floor(entity.posX); + int j = MathHelper.floor(entity.posY); + int k = MathHelper.floor(entity.posZ); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + GlStateManager.disableCull(); + GlStateManager.glNormal3f(0.0F, 1.0F, 0.0F); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.alphaFunc(516, 0.1F); + double d0 = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * (double) partialTicks; + double d1 = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * (double) partialTicks; + double d2 = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * (double) partialTicks; + int l = MathHelper.floor(d1); + int i1 = 5; + + if (mc.gameSettings.fancyGraphics) { + i1 = 10; + } + + int j1 = -1; + float f1 = (float) this.rendererUpdateCount + partialTicks; + bufferbuilder.setTranslation(-d0, -d1, -d2); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + for (int k1 = k - i1; k1 <= k + i1; ++k1) { + for (int l1 = i - i1; l1 <= i + i1; ++l1) { + int i2 = (k1 - k + 16) * 32 + l1 - i + 16; + double d3 = (double) this.rainxs[i2] * 0.5D; + double d4 = (double) this.rainys[i2] * 0.5D; + + // TF - replace biome check with box check + if (this.protectedBox != null && this.protectedBox.intersectsWith(l1, k1, l1, k1)) { + int structureMin = this.protectedBox.minY - 4; + int structureMax = this.protectedBox.maxY + 4; + int k2 = j - i1; + int l2 = j + i1 * 2; + + if (k2 < structureMin) { + k2 = structureMin; + } + + if (l2 < structureMin) { + l2 = structureMin; + } + + if (k2 > structureMax) { + k2 = structureMax; + } + + if (l2 > structureMax) { + l2 = structureMax; + } + + if (k2 != l2) { + this.random.setSeed((long) (l1 * l1 * 3121 + l1 * 45238971 ^ k1 * k1 * 418711 + k1 * 13761)); + blockpos$mutableblockpos.setPos(l1, k2, k1); + + // TF - unwrap temperature check for snow, only one branch. Use our own texture + if (j1 != 0) { + if (j1 >= 0) { + tessellator.draw(); + } + + j1 = 0; + mc.getTextureManager().bindTexture(SPARKLES_TEXTURE); + bufferbuilder.begin(7, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); + } + + double d5 = -((double) (this.rendererUpdateCount + l1 * l1 * 3121 + l1 * 45238971 + k1 * k1 * 418711 + k1 * 13761 & 31) + (double) partialTicks) / 32.0D * (3.0D + this.random.nextDouble()); + double d6 = (double) ((float) l1 + 0.5F) - entity.posX; + double d7 = (double) ((float) k1 + 0.5F) - entity.posZ; + float f3 = MathHelper.sqrt(d6 * d6 + d7 * d7) / (float) i1; + // TF - "f" was rain strength for alpha + float f = random.nextFloat(); + float f4 = ((1.0F - f3 * f3) * 0.5F + 0.5F) * f; + int j3 = 15 << 20 | 15 << 4; // TF - fullbright + int k3 = j3 >> 16 & 65535; + int l3 = j3 & 65535; + bufferbuilder.pos((double) l1 - d3 + 0.5D, (double) l2, (double) k1 - d4 + 0.5D).tex(0.0D, (double) k2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) l1 + d3 + 0.5D, (double) l2, (double) k1 + d4 + 0.5D).tex(1.0D, (double) k2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) l1 + d3 + 0.5D, (double) k2, (double) k1 + d4 + 0.5D).tex(1.0D, (double) l2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + bufferbuilder.pos((double) l1 - d3 + 0.5D, (double) k2, (double) k1 - d4 + 0.5D).tex(0.0D, (double) l2 * 0.25D + d5).color(1.0F, 1.0F, 1.0F, f4).lightmap(k3, l3).endVertex(); + } + } + } + } + + if (j1 >= 0) { + tessellator.draw(); + } + + bufferbuilder.setTranslation(0.0D, 0.0D, 0.0D); + GlStateManager.enableCull(); + GlStateManager.disableBlend(); + GlStateManager.alphaFunc(516, 0.1F); + mc.entityRenderer.disableLightmap(); + } } - - - private void initializeRainCoords() { - if (this.rainXCoords == null) - { - this.rainXCoords = new float[1024]; - this.rainYCoords = new float[1024]; - - for (int i = 0; i < 32; ++i) - { - for (int j = 0; j < 32; ++j) - { - float f2 = (float)(j - 16); - float f3 = (float)(i - 16); - float f4 = MathHelper.sqrt_float(f2 * f2 + f3 * f3); - this.rainXCoords[i << 5 | j] = -f3 / f4; - this.rainYCoords[i << 5 | j] = f2 / f4; - } - } + private boolean isNearLockedBiome(World world, Entity viewEntity) { + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + final int range = 15; + int px = MathHelper.floor(viewEntity.posX); + int pz = MathHelper.floor(viewEntity.posZ); + + for (int z = pz - range; z <= pz + range; ++z) { + for (int x = px - range; x <= px + range; ++x) { + Biome biome = world.getBiome(pos.setPos(x, 0, z)); + if (!TFWorld.isBiomeSafeFor(biome, viewEntity)) { + return true; + } + } } + + return false; } + private boolean isNearLockedStructure(World world, Entity viewEntity) { + final int range = 15; + int px = MathHelper.floor(viewEntity.posX); + int pz = MathHelper.floor(viewEntity.posZ); + if (this.protectedBox != null && this.protectedBox.intersectsWith(px - range, pz - range, px + range, pz + range)) { + return true; + } - private boolean isNearLockedBiome(World world, EntityLivingBase viewEntity) { - int range = 15; - int px = MathHelper.floor_double(viewEntity.posX); - int pz = MathHelper.floor_double(viewEntity.posZ); - - for (int z = pz - range ; z <= pz + range; ++z) { - for (int x = px - range; x <= px + range; ++x) { - BiomeGenBase biomegenbase = world.getBiomeGenForCoords(x, z); - if (biomegenbase instanceof TFBiomeBase && viewEntity instanceof EntityPlayer) { - TFBiomeBase tfBiome = (TFBiomeBase)biomegenbase; - EntityPlayer player = (EntityPlayer)viewEntity; - if (!tfBiome.doesPlayerHaveRequiredAchievement(player)) { - return true; - } - } - } - } - return false; } - private boolean isNearLockedStructure(World world, EntityLivingBase viewEntity) { - int range = 15; - int px = MathHelper.floor_double(viewEntity.posX); - int pz = MathHelper.floor_double(viewEntity.posZ); - - if (this.protectedBox != null && this.protectedBox.intersectsWith(px - range, pz - range, px + range, pz + range)) { - return true; - } - - return false; + public void setProtectedBox(StructureBoundingBox protectedBox) { + this.protectedBox = protectedBox; } + // TODO: move to biome + private RenderType getRenderType(Biome biome) { + if (biome instanceof TFBiomeSnow || biome instanceof TFBiomeGlacier) { + return RenderType.BLIZZARD; + } else if (biome instanceof TFBiomeSwamp) { + return RenderType.MOSQUITO; + } else if (biome instanceof TFBiomeFireSwamp) { + return RenderType.ASHES; + } else if (biome instanceof TFBiomeDarkForest) { + return random.nextInt(2) == 0 ? RenderType.DARK_STREAM : null; + } else if (biome instanceof TFBiomeHighlands || biome instanceof TFBiomeThornlands || biome instanceof TFBiomeFinalPlateau) { + return RenderType.BIG_RAIN; + } + return null; + } + private enum RenderType { - public StructureBoundingBox getProtectedBox() { - return protectedBox; - } + BLIZZARD("blizzard.png"), + MOSQUITO("mosquitoes.png"), + ASHES("ashes.png"), + DARK_STREAM("darkstream.png"), + BIG_RAIN("bigrain.png"); + RenderType(String textureName) { + this.textureLocation = TwilightForestMod.getEnvTexture(textureName); + } + private final ResourceLocation textureLocation; - public void setProtectedBox(StructureBoundingBox protectedBox) { - this.protectedBox = protectedBox; - - //System.out.println("Set protected box to " + protectedBox); + public ResourceLocation getTextureLocation() { + return textureLocation; + } } - } - - - -//if (l > 0 && this.random.nextInt(3) < this.rainSoundCounter++) -//{ -// this.rainSoundCounter = 0; -// -// if (d1 > entitylivingbase.posY + 1.0D && worldclient.getPrecipitationHeight(MathHelper.floor_double(entitylivingbase.posX), MathHelper.floor_double(entitylivingbase.posZ)) > MathHelper.floor_double(entitylivingbase.posY)) -// { -// this.mc.theWorld.playSound(d0, d1, d2, "ambient.weather.rain", 0.1F, 0.5F, false); -// } -// else -// { -// this.mc.theWorld.playSound(d0, d1, d2, "ambient.weather.rain", 0.2F, 1.0F, false); -// } -//} diff --git a/src/main/java/twilightforest/client/renderer/TileEntityTFCicadaRenderer.java b/src/main/java/twilightforest/client/renderer/TileEntityTFCicadaRenderer.java deleted file mode 100644 index dd3754145d..0000000000 --- a/src/main/java/twilightforest/client/renderer/TileEntityTFCicadaRenderer.java +++ /dev/null @@ -1,77 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - -import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFCicada; -import twilightforest.tileentity.TileEntityTFCicada; - - -public class TileEntityTFCicadaRenderer extends TileEntitySpecialRenderer { - - private ModelTFCicada cicadaModel; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "cicada-model.png"); - - public TileEntityTFCicadaRenderer() - { - cicadaModel = new ModelTFCicada(); - } - - - @Override - public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f) { - renderTileEntityCicadaAt((TileEntityTFCicada)tileentity, d, d1, d2, f); - - } - - /** - * Render a cute cicada! - */ - private void renderTileEntityCicadaAt(TileEntityTFCicada tileentity, double d, double d1, double d2, float f) { - GL11.glPushMatrix(); - int facing = tileentity.getBlockMetadata(); - float rotX = 90.0F; - float rotZ = 0.0F; - if(facing == 3) - { - rotZ = 0F; - } - if(facing == 4) - { - rotZ = 180F; - } - if(facing == 1) - { - rotZ = -90F; - } - if(facing == 2) - { - rotZ = 90F; - } - if(facing == 5) - { - rotX = 0F; - } - if(facing == 6) - { - rotX = 180F; - } - GL11.glTranslatef((float)d + 0.5F, (float)d1 + 0.5F, (float)d2 + 0.5F); - GL11.glRotatef(rotX, 1F, 0F, 0F); - GL11.glRotatef(rotZ, 0F, 0F, 1F); - GL11.glRotatef((float) tileentity.currentYaw, 0F, 1F, 0F); - - this.bindTexture(textureLoc); - GL11.glPushMatrix(); - GL11.glScalef(1f, -1f, -1f); - cicadaModel.render(0.0625f); - GL11.glPopMatrix(); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glPopMatrix(); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TileEntityTFFireflyRenderer.java b/src/main/java/twilightforest/client/renderer/TileEntityTFFireflyRenderer.java deleted file mode 100644 index 67eaff0928..0000000000 --- a/src/main/java/twilightforest/client/renderer/TileEntityTFFireflyRenderer.java +++ /dev/null @@ -1,103 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - -import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFFirefly; -import twilightforest.tileentity.TileEntityTFFirefly; - - -public class TileEntityTFFireflyRenderer extends TileEntitySpecialRenderer { - - private ModelTFFirefly fireflyModel; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "firefly-tiny.png"); - - public TileEntityTFFireflyRenderer() - { - fireflyModel = new ModelTFFirefly(); - } - - - @Override - public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f) { - renderTileEntityFireflyAt((TileEntityTFFirefly)tileentity, d, d1, d2, f); - - } - - - /** - * Render a cute firefly! - */ - private void renderTileEntityFireflyAt(TileEntityTFFirefly tileentity, double d, double d1, double d2, float f) { - GL11.glPushMatrix(); - int facing = tileentity.getBlockMetadata(); - - float rotX = 90.0F; - float rotZ = 0.0F; - if(facing == 3) - { - rotZ = 0F; - } - if(facing == 4) - { - rotZ = 180F; - } - if(facing == 1) - { - rotZ = -90F; - } - if(facing == 2) - { - rotZ = 90F; - } - if(facing == 5) - { - rotX = 0F; - } - if(facing == 6) - { - rotX = 180F; - } - GL11.glTranslatef((float)d + 0.5F, (float)d1 + 0.5F, (float)d2 + 0.5F); - GL11.glRotatef(rotX, 1F, 0F, 0F); - GL11.glRotatef(rotZ, 0F, 0F, 1F); - GL11.glRotatef((float) tileentity.currentYaw, 0F, 1F, 0F); - - this.bindTexture(textureLoc); - GL11.glPushMatrix(); - GL11.glScalef(1f, -1f, -1f); - - GL11.glColorMask(true, true, true, true); - - // render the firefly body - GL11.glDisable(3042 /*GL_BLEND*/); - fireflyModel.render(0.0625f); - -// -// GL11.glEnable(3042 /*GL_BLEND*/); -// GL11.glDisable(3008 /*GL_ALPHA_TEST*/); -// GL11.glBlendFunc(770, 771); -// GL11.glColor4f(1.0F, 1.0F, 1.0F, f1); - - // render the firefly glow - GL11.glEnable(3042 /*GL_BLEND*/); - GL11.glDisable(3008 /*GL_ALPHA_TEST*/); -// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glBlendFunc(770, 1); - GL11.glColor4f(1.0F, 1.0F, 1.0F, tileentity.glowIntensity); - fireflyModel.glow.render(0.0625f); - GL11.glDisable(3042 /*GL_BLEND*/); - GL11.glEnable(3008 /*GL_ALPHA_TEST*/); - GL11.glEnable(GL11.GL_LIGHTING); - - GL11.glPopMatrix(); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glPopMatrix(); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TileEntityTFMoonwormRenderer.java b/src/main/java/twilightforest/client/renderer/TileEntityTFMoonwormRenderer.java deleted file mode 100644 index 49af783e37..0000000000 --- a/src/main/java/twilightforest/client/renderer/TileEntityTFMoonwormRenderer.java +++ /dev/null @@ -1,81 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - -import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFMoonworm; -import twilightforest.tileentity.TileEntityTFMoonworm; - - -public class TileEntityTFMoonwormRenderer extends TileEntitySpecialRenderer { - - private ModelTFMoonworm moonwormModel; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "moonworm.png"); - - public TileEntityTFMoonwormRenderer() - { - moonwormModel = new ModelTFMoonworm(); - } - - - @Override - public void renderTileEntityAt(TileEntity tileentity, double d, double d1, double d2, float f) { - renderTileEntityFireflyAt((TileEntityTFMoonworm)tileentity, d, d1, d2, f); - - } - - /** - * Render a cute firefly! - */ - private void renderTileEntityFireflyAt(TileEntityTFMoonworm tileentity, double d, double d1, double d2, float partialTime) { - GL11.glPushMatrix(); - int facing = tileentity.getBlockMetadata(); - - float rotX = 90.0F; - float rotZ = 0.0F; - if(facing == 3) - { - rotZ = 0F; - } - if(facing == 4) - { - rotZ = 180F; - } - if(facing == 1) - { - rotZ = -90F; - } - if(facing == 2) - { - rotZ = 90F; - } - if(facing == 5) - { - rotX = 0F; - } - if(facing == 6) - { - rotX = 180F; - } - GL11.glTranslatef((float)d + 0.5F, (float)d1 + 0.5F, (float)d2 + 0.5F); - GL11.glRotatef(rotX, 1F, 0F, 0F); - GL11.glRotatef(rotZ, 0F, 0F, 1F); - GL11.glRotatef((float) tileentity.currentYaw, 0F, 1F, 0F); - - this.bindTexture(textureLoc); - - GL11.glScalef(1f, -1f, -1f); - - moonwormModel.setLivingAnimations(tileentity, partialTime); - - // render the firefly body - moonwormModel.render(0.0625f); - - GL11.glPopMatrix(); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/TileEntityTFTrophyRenderer.java b/src/main/java/twilightforest/client/renderer/TileEntityTFTrophyRenderer.java deleted file mode 100644 index c0d6cc1206..0000000000 --- a/src/main/java/twilightforest/client/renderer/TileEntityTFTrophyRenderer.java +++ /dev/null @@ -1,219 +0,0 @@ -package twilightforest.client.renderer; - -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - -import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFHydraHead; -import twilightforest.client.model.ModelTFLich; -import twilightforest.client.model.ModelTFNaga; -import twilightforest.client.model.ModelTFSnowQueen; -import twilightforest.client.model.ModelTFTowerBoss; -import twilightforest.tileentity.TileEntityTFTrophy; - - -public class TileEntityTFTrophyRenderer extends TileEntitySpecialRenderer { - - private ModelTFHydraHead hydraHeadModel; - private static final ResourceLocation textureLocHydra = new ResourceLocation(TwilightForestMod.MODEL_DIR + "hydra4.png"); - private ModelTFNaga nagaHeadModel; - private static final ResourceLocation textureLocNaga = new ResourceLocation(TwilightForestMod.MODEL_DIR + "nagahead.png"); - private ModelTFLich lichModel; - private static final ResourceLocation textureLocLich = new ResourceLocation(TwilightForestMod.MODEL_DIR + "twilightlich64.png"); - private ModelTFTowerBoss urGhastModel; - private static final ResourceLocation textureLocUrGhast = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerboss.png"); - private ModelTFSnowQueen snowQueenModel; - private static final ResourceLocation textureLocSnowQueen = new ResourceLocation(TwilightForestMod.MODEL_DIR + "snowqueen.png"); - - public TileEntityTFTrophyRenderer() - { - hydraHeadModel = new ModelTFHydraHead(); - nagaHeadModel = new ModelTFNaga(); - lichModel = new ModelTFLich(); - urGhastModel = new ModelTFTowerBoss(); - snowQueenModel = new ModelTFSnowQueen(); - } - - - @Override - public void renderTileEntityAt(TileEntity tileentity, double x, double y, double z, float partialTime) { - TileEntityTFTrophy trophy = (TileEntityTFTrophy)tileentity; - - - GL11.glPushMatrix(); - GL11.glDisable(GL11.GL_CULL_FACE); - - int meta = trophy.getBlockMetadata() & 7; - - float rotation = (float)(trophy.func_145906_b() * 360) / 16.0F; - boolean onGround = true; - - // wall mounted? - if (meta != 1) - { - switch (meta) - { - case 2: - onGround = false; - break; - case 3: - onGround = false; - rotation = 180.0F; - break; - case 4: - onGround = false; - rotation = 270.0F; - break; - case 5: - default: - onGround = false; - rotation = 90.0F; - } - } - - - GL11.glTranslatef((float)x + 0.5F, (float)y + 0.5F, (float)z + 0.5F); - - - - switch (trophy.func_145904_a()) - { - case 0: - renderHydraHead(rotation, onGround); - break; - case 1: - renderNagaHead(rotation, onGround); - break; - case 2: - renderLichHead(rotation, onGround); - break; - case 3: - renderUrGhastHead(trophy, rotation, onGround, partialTime); - break; - case 4: - renderSnowQueenHead(rotation, onGround); - break; - } - - GL11.glPopMatrix(); - - } - - /** - * Render a hydra head - */ - private void renderHydraHead(float rotation, boolean onGround) { - - GL11.glScalef(0.25f, 0.25f, 0.25f); - - this.bindTexture(textureLocHydra); - - GL11.glScalef(1f, -1f, -1f); - - // we seem to be getting a 180 degree rotation here - GL11.glRotatef(rotation, 0F, 1F, 0F); - GL11.glRotatef(180F, 0F, 1F, 0F); - - GL11.glTranslatef(0, onGround ? 1F : -0F, 1.5F); - - // open mouth? - hydraHeadModel.openMouthForTrophy(onGround ? 0F : 0.25F); - - // render the hydra head - hydraHeadModel.render((Entity)null, 0.0F, 0.0F, 0.0F, rotation, 0.0F, 0.0625F); - } - - - private void renderNagaHead(float rotation, boolean onGround) { - - GL11.glTranslatef(0, -0.125F, 0); - - - GL11.glScalef(0.25f, 0.25f, 0.25f); - - this.bindTexture(textureLocNaga); - - GL11.glScalef(1f, -1f, -1f); - - // we seem to be getting a 180 degree rotation here - GL11.glRotatef(rotation, 0F, 1F, 0F); - GL11.glRotatef(180F, 0F, 1F, 0F); - - GL11.glTranslatef(0, onGround ? 1F : -0F, onGround ? 0F : 1F); - - // render the naga head - nagaHeadModel.render((Entity)null, 0.0F, 0.0F, 0.0F, rotation, 0.0F, 0.0625F); - } - - - private void renderLichHead(float rotation, boolean onGround) { - - GL11.glTranslatef(0, 1, 0); - - - //GL11.glScalef(0.5f, 0.5f, 0.5f); - - this.bindTexture(textureLocLich); - - GL11.glScalef(1f, -1f, -1f); - - // we seem to be getting a 180 degree rotation here - GL11.glRotatef(rotation, 0F, 1F, 0F); - GL11.glRotatef(180F, 0F, 1F, 0F); - - GL11.glTranslatef(0, onGround ? 1.75F : 1.5F, onGround ? 0F : 0.24F); - - // render the naga head - lichModel.bipedHead.render(0.0625F); - lichModel.bipedHeadwear.render(0.0625F); - } - - - - private void renderUrGhastHead(TileEntityTFTrophy trophy, float rotation, boolean onGround, float partialTime) { - - GL11.glTranslatef(0, 1, 0); - - GL11.glScalef(0.5f, 0.5f, 0.5f); - - this.bindTexture(textureLocUrGhast); - - GL11.glScalef(1f, -1f, -1f); - - // we seem to be getting a 180 degree rotation here - GL11.glRotatef(rotation, 0F, 1F, 0F); - GL11.glRotatef(180F, 0F, 1F, 0F); - - GL11.glTranslatef(0, onGround ? 1F : 1F, onGround ? 0F : 0F); - - // render the naga head - urGhastModel.render((Entity)null, 0.0F, 0, trophy.ticksExisted + partialTime, 0, 0.0F, 0.0625F); - } - - private void renderSnowQueenHead(float rotation, boolean onGround) { - - GL11.glTranslatef(0, 1, 0); - - - //GL11.glScalef(0.5f, 0.5f, 0.5f); - - this.bindTexture(textureLocSnowQueen); - - GL11.glScalef(1f, -1f, -1f); - - // we seem to be getting a 180 degree rotation here - GL11.glRotatef(rotation, 0F, 1F, 0F); - GL11.glRotatef(180F, 0F, 1F, 0F); - - GL11.glTranslatef(0, onGround ? 1.5F : 1.25F, onGround ? 0F : 0.24F); - - // render the naga head - snowQueenModel.bipedHead.render(0.0625F); - snowQueenModel.bipedHeadwear.render(0.0625F); - } - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFCastleMagic.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFCastleMagic.java deleted file mode 100644 index 554131dcde..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFCastleMagic.java +++ /dev/null @@ -1,183 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import org.lwjgl.opengl.GL11; - -import twilightforest.block.BlockTFCastleMagic; -import twilightforest.block.BlockTFFireflyJar; -import twilightforest.block.TFBlocks; -import net.minecraft.block.Block; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.util.IIcon; -import net.minecraft.world.IBlockAccess; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFCastleMagic implements ISimpleBlockRenderingHandler { - - private int renderID; - - public RenderBlockTFCastleMagic(int castleMagicBlockRenderID) { - this.renderID = castleMagicBlockRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { - renderInvBlock(renderer, block, metadata); - } - - public static void renderInvBlock(RenderBlocks renderblocks, Block par1Block, int meta) { - Tessellator tessellator = Tessellator.instance; - - GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - - renderInvBlock(renderblocks, par1Block, meta, tessellator); - - GL11.glTranslatef(0.5F, 0.5F, 0.5F); - - par1Block.setBlockBoundsForItemRender(); - } - - protected static void renderInvBlock(RenderBlocks renderblocks, Block par1Block, int meta, Tessellator tessellator) { - - - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(0, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(1, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(2, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(3, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(4, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(5, meta)); - tessellator.draw(); - - - float pixel = 1F / 16F; - - IIcon icon = BlockTFCastleMagic.getMagicIconFor(meta, 0, 0); - - int color = BlockTFCastleMagic.getMagicColorFor(meta); - - float red = (float)(color >> 16 & 255) / 255.0F; - float grn = (float)(color >> 8 & 255) / 255.0F; - float blu = (float)(color & 255) / 255.0F; - - renderblocks.enableAO = false; - - GL11.glDisable(GL11.GL_LIGHTING); - - - tessellator.startDrawingQuads(); - tessellator.setBrightness(15 << 20 | 15 << 4); // full brightness - tessellator.setColorOpaque_F(red, grn, blu); - renderblocks.renderFaceYNeg(par1Block, 0.0D, -pixel, 0.0D, icon); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setBrightness(15 << 20 | 15 << 4); // full brightness - tessellator.setColorOpaque_F(red, grn, blu); - renderblocks.renderFaceYPos(par1Block, 0.0D, +pixel, 0.0D, icon); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setBrightness(15 << 20 | 15 << 4); // full brightness - tessellator.setColorOpaque_F(red, grn, blu); - renderblocks.renderFaceXPos(par1Block, +pixel, 0.0D, 0.0D, icon); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setBrightness(15 << 20 | 15 << 4); // full brightness - tessellator.setColorOpaque_F(red, grn, blu); - renderblocks.renderFaceXNeg(par1Block, -pixel, 0.0D, 0.0D, icon); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setBrightness(15 << 20 | 15 << 4); // full brightness - tessellator.setColorOpaque_F(red, grn, blu); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, -pixel, icon); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setBrightness(15 << 20 | 15 << 4); // full brightness - tessellator.setColorOpaque_F(red, grn, blu); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, +pixel, icon); - tessellator.draw(); - - GL11.glEnable(GL11.GL_LIGHTING); - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - renderer.clearOverrideBlockTexture(); - renderer.setRenderBounds(0, 0, 0, 1, 1, 1); - renderer.renderStandardBlock(block, x, y, z); - - renderer.overrideBlockTexture = BlockTFCastleMagic.getMagicIconFor(x, y, z); - - int meta = world.getBlockMetadata(x, y, z); - int color = BlockTFCastleMagic.getMagicColorFor(meta); - float red = (float)(color >> 16 & 255) / 255.0F; - float grn = (float)(color >> 8 & 255) / 255.0F; - float blu = (float)(color & 255) / 255.0F; - - - // if the block is a door or other clickable block(?), pulse the glyph a little - if (block == TFBlocks.castleDoor) { - - } - - - Tessellator tessellator = Tessellator.instance; - tessellator.setBrightness(15 << 20 | 15 << 4); // full brightness - tessellator.setColorOpaque_F(red, grn, blu); - - renderer.enableAO = false; - float pixel = 1/16F; - - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x, y - 1, z, 0) && world.isAirBlock(x, y - 1, z)) { - renderer.renderFaceYNeg(block, (double)x, (double)y - pixel, (double)z, renderer.overrideBlockTexture); - } - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x, y + 1, z, 1) && world.isAirBlock(x, y + 1, z)) { - renderer.renderFaceYPos(block, (double)x, (double)y + pixel, (double)z, renderer.overrideBlockTexture); - } - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x, y, z - 1, 2) && world.isAirBlock(x, y, z - 1)) { - renderer.renderFaceZNeg(block, (double)x, (double)y, (double)z - pixel, renderer.overrideBlockTexture); - } - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x, y, z + 1, 3) && world.isAirBlock(x, y, z + 1)) { - renderer.renderFaceZPos(block, (double)x, (double)y, (double)z + pixel, renderer.overrideBlockTexture); - } - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x - 1, y, z, 4) && world.isAirBlock(x - 1, y, z)) { - renderer.renderFaceXNeg(block, (double)x - pixel, (double)y, (double)z, renderer.overrideBlockTexture); - } - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x + 1, y, z, 5) && world.isAirBlock(x + 1, y, z)) { - renderer.renderFaceXPos(block, (double)x + pixel, (double)y, (double)z, renderer.overrideBlockTexture); - } - - renderer.clearOverrideBlockTexture(); - return true; - - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - @Override - public int getRenderId() { - return this.renderID; - } - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFCritters.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFCritters.java deleted file mode 100644 index 977e826be7..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFCritters.java +++ /dev/null @@ -1,38 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.world.IBlockAccess; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFCritters implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFCritters(int blockComplexRenderID) { - this.renderID = blockComplexRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - // TODO Auto-generated method stub - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return false; - } - - @Override - public int getRenderId() { - return renderID; - } - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFFireflyJar.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFFireflyJar.java deleted file mode 100644 index 0b381909ac..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFFireflyJar.java +++ /dev/null @@ -1,133 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.IBlockAccess; - -import org.lwjgl.opengl.GL11; - -import twilightforest.block.BlockTFFireflyJar; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFFireflyJar implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFFireflyJar(int blockComplexRenderID) { - this.renderID = blockComplexRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - renderInvJar(renderer, block, metadata); - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - return renderJar(renderer, world, x, y, z, block); - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - @Override - public int getRenderId() { - return renderID; - } - - /** - * Look, this is no longer in the Block class! I'm an object oriented genius! - */ - public static boolean renderJar(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) { - renderblocks.clearOverrideBlockTexture(); - renderblocks.setRenderBounds(0.1875F, 0.0F, 0.1875F, 0.8125F, 0.875F, 0.8125F); - renderblocks.renderStandardBlock(block, x, y, z); - - renderblocks.overrideBlockTexture = BlockTFFireflyJar.jarCork; - renderblocks.setRenderBounds(0.25F, 0.75F, 0.25F, 0.75F, 1.0F, 0.75F); - renderblocks.renderStandardBlock(block, x, y, z); - renderblocks.clearOverrideBlockTexture(); - - block.setBlockBoundsForItemRender(); - return true; - } - - public static void renderInvJar(RenderBlocks renderblocks, Block par1Block, int meta) { - Tessellator tessellator = Tessellator.instance; - - GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - - // render jar portion - renderblocks.setRenderBounds(0.1875F, 0.0F, 0.1875F, 0.8125F, 0.875F, 0.8125F); - - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarTop); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarTop); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarSide); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarSide); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarSide); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarSide); - tessellator.draw(); - - // render lid thing - renderblocks.setRenderBounds(0.25F, 0.75F, 0.25F, 0.75F, 1.0F, 0.75F); - - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarCork); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarCork); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarCork); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarCork); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarCork); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, BlockTFFireflyJar.jarCork); - tessellator.draw(); -// renderblocks.renderBottomFace(par1Block, 0.0D, 0.0D, 0.0D, sprLid); -// renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, sprLid); -// renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, sprLid); -// renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, sprLid); -// renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, sprLid); -// renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, sprLid); - - GL11.glTranslatef(0.5F, 0.5F, 0.5F); - - par1Block.setBlockBoundsForItemRender(); - } - - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFGiantBlocks.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFGiantBlocks.java deleted file mode 100644 index 222d62880a..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFGiantBlocks.java +++ /dev/null @@ -1,36 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.world.IBlockAccess; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFGiantBlocks implements ISimpleBlockRenderingHandler { - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelId, - RenderBlocks renderer) { - // TODO Auto-generated method stub - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, - Block block, int modelId, RenderBlocks renderer) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - // TODO Auto-generated method stub - return false; - } - - @Override - public int getRenderId() { - // TODO Auto-generated method stub - return 0; - } - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFHugeLilyPad.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFHugeLilyPad.java deleted file mode 100644 index e281a04f52..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFHugeLilyPad.java +++ /dev/null @@ -1,73 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.IBlockAccess; - -import org.lwjgl.opengl.GL11; - -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFHugeLilyPad implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFHugeLilyPad(int blockComplexRenderID) { - this.renderID = blockComplexRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - ; - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // rotate the sides - int meta = world.getBlockMetadata(x, y, z); - - setRenderRotate(renderer, meta); - boolean didRender = renderer.renderStandardBlock(block, x, y, z); - restoreRendererRotate(renderer); - - return didRender; - - } - - private void restoreRendererRotate(RenderBlocks renderer) { - renderer.uvRotateSouth = 0; - renderer.uvRotateEast = 0; - renderer.uvRotateWest = 0; - renderer.uvRotateNorth = 0; - renderer.uvRotateTop = 0; - renderer.uvRotateBottom = 0; - } - - private void setRenderRotate(RenderBlocks renderer, int meta) { - int orient = meta >> 2; - - // why can't this just be simple? - if (orient == 2) { - orient = 3; - } else if (orient == 3) { - orient = 2; - } - - renderer.uvRotateTop = orient; - renderer.uvRotateBottom = orient; - - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return false; - } - - @Override - public int getRenderId() { - return renderID; - } - - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFKnightMetal.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFKnightMetal.java deleted file mode 100644 index a495e6433e..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFKnightMetal.java +++ /dev/null @@ -1,126 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.IBlockAccess; - -import org.lwjgl.opengl.GL11; - -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFKnightMetal implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFKnightMetal(int blockComplexRenderID) { - this.renderID = blockComplexRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - renderInvJar(renderer, block, metadata); - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - return renderSpikeBlock(renderer, world, x, y, z, block); - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - @Override - public int getRenderId() { - return renderID; - } - - /** - * Look, this is no longer in the Block class! I'm an object oriented genius! - */ - public static boolean renderSpikeBlock(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) { - float p = 1F / 16F; - float a = 1F / 1024F; - float p4 = 4F / 16F - a; - - for (int rx = 0; rx < 3; rx++) { - for (int ry = 0; ry < 3; ry++) { - for (int rz = 0; rz < 3; rz++) { - renderblocks.setRenderBounds(rx * 6F * p + a, ry * 6F * p + a, rz * 6F * p + a, rx * 6F * p + p4, ry * 6F * p + p4, rz * 6F * p + p4); - renderblocks.renderStandardBlock(block, x, y, z); - } - } - } - - // middle - renderblocks.setRenderBounds(p, p, p, 15 * p, 15 * p, 15 * p); - renderblocks.renderStandardBlock(block, x, y, z); - - - block.setBlockBoundsForItemRender(); - return true; - } - - public static void renderInvJar(RenderBlocks renderblocks, Block par1Block, int meta) { - Tessellator tessellator = Tessellator.instance; - - GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - - // spikes - float p = 1F / 16F; - float a = 1F / 1024F; - float p4 = 4F / 16F - a; - - for (int rx = 0; rx < 3; rx++) { - for (int ry = 0; ry < 3; ry++) { - for (int rz = 0; rz < 3; rz++) { - renderblocks.setRenderBounds(rx * 6F * p + a, ry * 6F * p + a, rz * 6F * p + a, rx * 6F * p + p4, ry * 6F * p + p4, rz * 6F * p + p4); - renderInvBlock(renderblocks, par1Block, meta, tessellator); - - } - } - } - - // middle - renderblocks.setRenderBounds(p, p, p, 15 * p, 15 * p, 15 * p); - renderInvBlock(renderblocks, par1Block, meta, tessellator); - - - GL11.glTranslatef(0.5F, 0.5F, 0.5F); - - par1Block.setBlockBoundsForItemRender(); - } - - protected static void renderInvBlock(RenderBlocks renderblocks, Block par1Block, int meta, Tessellator tessellator) { - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(0, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(1, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(2, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(3, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(4, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(5, meta)); - tessellator.draw(); - } - - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFMagicLeaves.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFMagicLeaves.java deleted file mode 100644 index 40a8eec9f7..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFMagicLeaves.java +++ /dev/null @@ -1,162 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.IBlockAccess; - -import org.lwjgl.opengl.GL11; - -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFMagicLeaves implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFMagicLeaves(int myRenderID) { - this.renderID = myRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - setRenderRotate(renderer, metadata); - renderInvNormalBlock(renderer, block, metadata); - restoreRendererRotate(renderer); - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // rotate the sides - int meta = world.getBlockMetadata(x, y, z); - - setRenderRotate(renderer, meta, x, y, z); - boolean didRender = renderer.renderStandardBlock(block, x, y, z); - restoreRendererRotate(renderer); - - return didRender; - - } - - private void restoreRendererRotate(RenderBlocks renderer) { - renderer.uvRotateSouth = 0; - renderer.uvRotateEast = 0; - renderer.uvRotateWest = 0; - renderer.uvRotateNorth = 0; - renderer.uvRotateTop = 0; - renderer.uvRotateBottom = 0; - } - - private void setRenderRotate(RenderBlocks renderer, int meta) { - this.setRenderRotate(renderer, meta, 0, 0, 0); - } - - private void setRenderRotate(RenderBlocks renderer, int meta, int x, int y, int z) { - int type = meta & 3; - - if (type == 0) - { - renderer.uvRotateEast = 3; - renderer.uvRotateBottom = 0; - - renderer.uvRotateNorth = 2; - renderer.uvRotateSouth = 2; - } - else if (type == 1) - { - // bottom and top are semi-random - renderer.uvRotateBottom = (x + y + z) & 3; - renderer.uvRotateTop = (x + y + z) & 3; - - // sides flow down - renderer.uvRotateEast = 1; - renderer.uvRotateWest = 2; - - renderer.uvRotateNorth = 2; - renderer.uvRotateSouth = 1; - } - else if (type == 2) - { - // bottom and top are semi-random - renderer.uvRotateBottom = (x + y + z) & 3; - renderer.uvRotateTop = (x + y + z) & 3; - - // sides flow up - renderer.uvRotateEast = 2; - renderer.uvRotateWest = 1; - - renderer.uvRotateNorth = 1; - renderer.uvRotateSouth = 2; - } - else if (type == 3) - { - // all semi-random - renderer.uvRotateBottom = (x + y + z) & 3; - renderer.uvRotateTop = (x + y + z) & 3; - - renderer.uvRotateEast = (x + y + z) & 3;; - renderer.uvRotateWest = (x + y + z) & 3;; - - renderer.uvRotateNorth = (x + y + z) & 3;; - renderer.uvRotateSouth = (x + y + z) & 3;; - } - - - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - @Override - public int getRenderId() { - return renderID; - } - - - public static void renderInvNormalBlock(RenderBlocks renderblocks, Block par1Block, int meta) { - Tessellator tessellator = Tessellator.instance; - - if (renderblocks.useInventoryTint) - { - int colorInt = par1Block.getRenderColor(meta); - - float red = (float)(colorInt >> 16 & 255) / 255.0F; - float green = (float)(colorInt >> 8 & 255) / 255.0F; - float blue = (float)(colorInt & 255) / 255.0F; - GL11.glColor4f(red, green, blue, 1.0F); - } - - GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - - // block! - par1Block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(0, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(1, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(2, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(3, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(4, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(5, meta)); - tessellator.draw(); - } - - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFNagastone.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFNagastone.java deleted file mode 100644 index 62ca291ea5..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFNagastone.java +++ /dev/null @@ -1,172 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.IBlockAccess; - -import org.lwjgl.opengl.GL11; - -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFNagastone implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFNagastone(int nagastoneRenderID) { - this.renderID = nagastoneRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - setRenderRotate(renderer, metadata); - renderInvNormalBlock(renderer, block, metadata); - restoreRendererRotate(renderer); - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - // rotate the sides - int meta = world.getBlockMetadata(x, y, z); - - setRenderRotate(renderer, meta); - boolean didRender = renderer.renderStandardBlock(block, x, y, z); - restoreRendererRotate(renderer); - - return didRender; - - } - - private void restoreRendererRotate(RenderBlocks renderer) { - renderer.uvRotateSouth = 0; - renderer.uvRotateEast = 0; - renderer.uvRotateWest = 0; - renderer.uvRotateNorth = 0; - renderer.uvRotateTop = 0; - renderer.uvRotateBottom = 0; - } - - private void setRenderRotate(RenderBlocks renderer, int meta) { - int type = meta & 12; - int orient = meta & 3; - - // heads - if (type == 0) - { - switch (orient) - { - case 0: - renderer.uvRotateTop = 1; - renderer.uvRotateBottom = 2; - break; - case 1: - renderer.uvRotateTop = 2; - renderer.uvRotateBottom = 1; - renderer.uvRotateSouth = 0; - break; - case 2: - renderer.uvRotateTop = 0; - renderer.uvRotateBottom = 3; - break; - case 3: - renderer.uvRotateTop = 3; - renderer.uvRotateBottom = 0; - break; - } - } - else if (type == 4 || type == 8) - { - switch (orient) - { - case 0: - renderer.uvRotateTop = 2; - renderer.uvRotateBottom = 1; - renderer.uvRotateWest = 2; - break; - case 1: - renderer.uvRotateTop = 1; - renderer.uvRotateBottom = 2; - renderer.uvRotateEast = 2; - break; - case 2: - renderer.uvRotateTop = 3; - renderer.uvRotateBottom = 0; - renderer.uvRotateSouth = 2; - break; - case 3: - renderer.uvRotateTop = 0; - renderer.uvRotateBottom = 3; - renderer.uvRotateNorth = 2; - break; - } - } - else if (type == 12) - { - switch (orient) - { - case 0: - renderer.uvRotateTop = 0; - renderer.uvRotateBottom = 0; - break; - case 1: - renderer.uvRotateTop = 1; - renderer.uvRotateBottom = 1; - break; - case 2: - renderer.uvRotateNorth = 2; - renderer.uvRotateSouth = 2; - renderer.uvRotateEast = 2; - renderer.uvRotateWest = 2; - break; - } - } - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - @Override - public int getRenderId() { - return renderID; - } - - - public static void renderInvNormalBlock(RenderBlocks renderblocks, Block par1Block, int meta) { - Tessellator tessellator = Tessellator.instance; - - GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - - // render jar portion - par1Block.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); - - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(0, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(1, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(2, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(3, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(4, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(5, meta)); - tessellator.draw(); - } - - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFPedestal.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFPedestal.java deleted file mode 100644 index 181cc27b80..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFPedestal.java +++ /dev/null @@ -1,112 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.world.IBlockAccess; - -import org.lwjgl.opengl.GL11; - -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFPedestal implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFPedestal(int blockComplexRenderID) { - this.renderID = blockComplexRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - renderInvJar(renderer, block, metadata); - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - return renderPedestal(renderer, world, x, y, z, block); - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - @Override - public int getRenderId() { - return renderID; - } - - /** - * Look, this is no longer in the Block class! I'm an object oriented genius! - */ - public static boolean renderPedestal(RenderBlocks renderblocks, IBlockAccess world, int x, int y, int z, Block block) { - // top - renderblocks.setRenderBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.1875F, 0.9375F); - renderblocks.renderStandardBlock(block, x, y, z); - - // middle - renderblocks.setRenderBounds(0.125, 0.1875F, 0.125, 0.875F, 0.8125F, 0.875F); - renderblocks.renderStandardBlock(block, x, y, z); - - // bottom - renderblocks.setRenderBounds(0.0625F, 0.8125F, 0.0625F, 0.9375F, 1.0F, 0.9375F); - renderblocks.renderStandardBlock(block, x, y, z); - - block.setBlockBoundsForItemRender(); - return true; - } - - public static void renderInvJar(RenderBlocks renderblocks, Block par1Block, int meta) { - Tessellator tessellator = Tessellator.instance; - - GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - - // top - renderblocks.setRenderBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.1875F, 0.9375F); - renderInvBlock(renderblocks, par1Block, meta, tessellator); - - // middle - renderblocks.setRenderBounds(0.125, 0.1875F, 0.125, 0.875F, 0.8125F, 0.875F); - renderInvBlock(renderblocks, par1Block, meta, tessellator); - - // bottom - renderblocks.setRenderBounds(0.0625F, 0.8125F, 0.0625F, 0.9375F, 1.0F, 0.9375F); - renderInvBlock(renderblocks, par1Block, meta, tessellator); - - GL11.glTranslatef(0.5F, 0.5F, 0.5F); - - par1Block.setBlockBoundsForItemRender(); - } - - protected static void renderInvBlock(RenderBlocks renderblocks, Block par1Block, int meta, Tessellator tessellator) { - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(0, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(1, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(2, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(3, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(4, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(5, meta)); - tessellator.draw(); - } - - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFPlants.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFPlants.java deleted file mode 100644 index 0bdcc320fa..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFPlants.java +++ /dev/null @@ -1,205 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.world.IBlockAccess; -import twilightforest.block.BlockTFPlant; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFPlants implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFPlants(int blockRenderID) { - this.renderID = blockRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - // TODO Auto-generated method stub - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - int meta = world.getBlockMetadata(x, y, z); - if (meta == BlockTFPlant.META_MOSSPATCH) { - renderMossPatch(x, y, z, block, renderer); - - } - else if (meta == BlockTFPlant.META_CLOVERPATCH) { - renderCloverPatch(x, y, z, block, renderer); - - } - else if (meta == BlockTFPlant.META_MAYAPPLE) { - renderMayapple(x, y, z, block, renderer); - } - else if (meta == BlockTFPlant.META_ROOT_STRAND) { - renderer.renderBlockCrops(block, x, y, z); - } - else - { - renderer.renderCrossedSquares(block, x, y, z); - } - - return true; - } - - private void renderMayapple(int x, int y, int z, Block block, - RenderBlocks renderer) { - renderer.clearOverrideBlockTexture(); - renderer.setRenderBounds(4F / 16F, 6F / 16F, 4F / 16F, 13F / 16F, 6F / 16F, 13F / 16F); - renderer.renderStandardBlock(block, x, y, z); - - renderer.overrideBlockTexture = BlockTFPlant.mayappleSide; - renderer.setRenderBounds(8F / 16F, 0F, 8F / 16F, 9F / 16F, 5.99F / 16F, 9F / 16F); - renderer.renderStandardBlock(block, x, y, z); - renderer.clearOverrideBlockTexture(); - } - - private void renderCloverPatch(int x, int y, int z, Block block, - RenderBlocks renderer) { - renderer.renderMinY = renderer.renderMaxY; - renderer.renderStandardBlock(block, x, y, z); - - renderer.renderMinY = 0F; - renderer.renderMaxY -= 0.01F; - - renderer.renderMinX += 1F / 16F; - renderer.renderMinZ += 1F / 16F; - renderer.renderMaxX -= 1F / 16F; - renderer.renderMaxZ -= 1F / 16F; - renderer.renderStandardBlock(block, x, y, z); - } - - private void renderMossPatch(int x, int y, int z, Block block, - RenderBlocks renderer) { - renderer.renderStandardBlock(block, x, y, z); - - // add on shaggy edges - if (renderer.renderMinX > 0) - { - double originalMaxZ = renderer.renderMaxZ; - - long seed = (long)(x * 3129871) ^ (long)y * 116129781L ^ (long)z; - seed = seed * seed * 42317861L + seed * 7L; - - int num0 = (int) (seed >> 12 & 3L) + 1; - int num1 = (int) (seed >> 15 & 3L) + 1; - int num2 = (int) (seed >> 18 & 3L) + 1; - int num3 = (int) (seed >> 21 & 3L) + 1; - - renderer.renderMaxX = renderer.renderMinX; - renderer.renderMinX -= 1F / 16F; - renderer.renderMinZ += num0 / 16F; - if (renderer.renderMaxZ - ((num1 +num2 + num3) / 16F) > renderer.renderMinZ) - { - // draw two blobs - renderer.renderMaxZ = renderer.renderMinZ + num1 / 16F; - renderer.renderStandardBlock(block, x, y, z); - renderer.renderMaxZ = originalMaxZ - num2 / 16F; - renderer.renderMinZ = renderer.renderMaxZ - num3 / 16F; - renderer.renderStandardBlock(block, x, y, z); - } - else - { - //draw one blob - renderer.renderMaxZ -= num2 / 16F; - renderer.renderStandardBlock(block, x, y, z); - } - - // reset render bounds - renderer.setRenderBoundsFromBlock(block); - } - if (renderer.renderMaxX < 1F) - { - double originalMaxZ = renderer.renderMaxZ; - - long seed = (long)(x * 3129871) ^ (long)y * 116129781L ^ (long)z; - seed = seed * seed * 42317861L + seed * 17L; - - int num0 = (int) (seed >> 12 & 3L) + 1; - int num1 = (int) (seed >> 15 & 3L) + 1; - int num2 = (int) (seed >> 18 & 3L) + 1; - int num3 = (int) (seed >> 21 & 3L) + 1; - - renderer.renderMinX = renderer.renderMaxX; - renderer.renderMaxX += 1F / 16F; - renderer.renderMinZ += num0 / 16F; - if (renderer.renderMaxZ - ((num1 +num2 + num3) / 16F) > renderer.renderMinZ) - { - // draw two blobs - renderer.renderMaxZ = renderer.renderMinZ + num1 / 16F; - renderer.renderStandardBlock(block, x, y, z); - renderer.renderMaxZ = originalMaxZ - num2 / 16F; - renderer.renderMinZ = renderer.renderMaxZ - num3 / 16F; - renderer.renderStandardBlock(block, x, y, z); - } - else - { - //draw one blob - renderer.renderMaxZ -= num2 / 16F; - renderer.renderStandardBlock(block, x, y, z); - } - // reset render bounds - renderer.setRenderBoundsFromBlock(block); - } - if (renderer.renderMinZ > 0) - { - double originalMaxX = renderer.renderMaxX; - - long seed = (long)(x * 3129871) ^ (long)y * 116129781L ^ (long)z; - seed = seed * seed * 42317861L + seed * 23L; - - int num0 = (int) (seed >> 12 & 3L) + 1; - int num1 = (int) (seed >> 15 & 3L) + 1; - int num2 = (int) (seed >> 18 & 3L) + 1; - int num3 = (int) (seed >> 21 & 3L) + 1; - - renderer.renderMaxZ = renderer.renderMinZ; - renderer.renderMinZ -= 1F / 16F; - renderer.renderMinX += num0 / 16F; - renderer.renderMaxX = renderer.renderMinX + num1 / 16F; - renderer.renderStandardBlock(block, x, y, z); - renderer.renderMaxX = originalMaxX - num2 / 16F; - renderer.renderMinX = renderer.renderMaxX - num3 / 16F; - renderer.renderStandardBlock(block, x, y, z); - // reset render bounds - renderer.setRenderBoundsFromBlock(block); - } - if (renderer.renderMaxZ < 1F) - { - double originalMaxX = renderer.renderMaxX; - - long seed = (long)(x * 3129871) ^ (long)y * 116129781L ^ (long)z; - seed = seed * seed * 42317861L + seed * 11L; - - int num0 = (int) (seed >> 12 & 3L) + 1; - int num1 = (int) (seed >> 15 & 3L) + 1; - int num2 = (int) (seed >> 18 & 3L) + 1; - int num3 = (int) (seed >> 21 & 3L) + 1; - - renderer.renderMinZ = renderer.renderMaxZ; - renderer.renderMaxZ += 1F / 16F; - renderer.renderMinX += num0 / 16F; - renderer.renderMaxX = renderer.renderMinX + num1 / 16F; - renderer.renderStandardBlock(block, x, y, z); - renderer.renderMaxX = originalMaxX - num2 / 16F; - renderer.renderMinX = renderer.renderMaxX - num3 / 16F; - renderer.renderStandardBlock(block, x, y, z); - // reset render bounds - renderer.setRenderBoundsFromBlock(block); - } - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return false; - } - - @Override - public int getRenderId() { - return renderID; - } - -} diff --git a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFThorns.java b/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFThorns.java deleted file mode 100644 index 406687e87e..0000000000 --- a/src/main/java/twilightforest/client/renderer/blocks/RenderBlockTFThorns.java +++ /dev/null @@ -1,434 +0,0 @@ -package twilightforest.client.renderer.blocks; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.util.IIcon; -import net.minecraft.world.IBlockAccess; - -import org.lwjgl.opengl.GL11; - -import twilightforest.block.TFBlocks; -import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; - -public class RenderBlockTFThorns implements ISimpleBlockRenderingHandler { - - final int renderID; - - public RenderBlockTFThorns(int blockComplexRenderID) { - this.renderID = blockComplexRenderID; - } - - @Override - public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) { - renderInvBlock(renderer, block, metadata); - - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - int l = block.colorMultiplier(world, x, y, z); - float f = (float)(l >> 16 & 255) / 255.0F; - float f1 = (float)(l >> 8 & 255) / 255.0F; - float f2 = (float)(l & 255) / 255.0F; - - int metadata = world.getBlockMetadata(x, y, z); - int type = metadata & 12; - - switch (type) { - case 0: - default: - return this.renderCactusLikeY(block, x, y, z, f, f1, f2, metadata, world, renderer); - case 4: - return this.renderCactusLikeX(block, x, y, z, f, f1, f2, metadata, world, renderer); - case 8: - return this.renderCactusLikeZ(block, x, y, z, f, f1, f2, metadata, world, renderer); - } - - - } - - @Override - public boolean shouldRender3DInInventory(int modelId) { - return true; - } - - @Override - public int getRenderId() { - return renderID; - } - - /** - * Render block cactus implementation - * @param metadata - */ - public boolean renderCactusLikeX(Block block, int x, int y, int z, float red, float green, float blue, int metadata, IBlockAccess world, RenderBlocks renderer) - { - setUVRotationX(renderer); - - Tessellator tessellator = Tessellator.instance; - float middle = 0.5F; - float full = 1.0F; - float f5 = 0.8F; - float f6 = 0.6F; - float bRed = middle * red; - float tRed = full * red; - float zRed = f5 * red; - float xRed = f6 * red; - float bGreen = middle * green; - float tGreen = full * green; - float zGreen = f5 * green; - float xGreen = f6 * green; - float bBlue = middle * blue; - float tBlue = full * blue; - float zBlue = f5 * blue; - float xBlue = f6 * blue; - float onePixel = 0.0625F * 3F; - int blockBrightness = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); - - if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x - 1, y, z, 4)) - { - tessellator.setBrightness(renderer.renderMinX > 0.0D ? blockBrightness : block.getMixedBrightnessForBlock(renderer.blockAccess, x - 1, y, z)); - tessellator.setColorOpaque_F(bRed, bGreen, bBlue); - renderer.renderFaceXNeg(block, (double)x, (double)y, (double)z, renderer.getBlockIcon(block, renderer.blockAccess, x, y, z, 4)); - } - - if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x + 1, y, z, 5)) - { - tessellator.setBrightness(renderer.renderMaxX < 1.0D ? blockBrightness : block.getMixedBrightnessForBlock(renderer.blockAccess, x + 1, y, z)); - tessellator.setColorOpaque_F(tRed, tGreen, tBlue); - renderer.renderFaceXPos(block, (double)x, (double)y, (double)z, renderer.getBlockIcon(block, renderer.blockAccess, x, y, z, 5)); - } - - drawXSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, onePixel, blockBrightness); - - resetUVRotation(renderer); - - - if (canConnectTo(world, x, y, z + 1)) { - setUVRotationZ(renderer); - renderer.setRenderBounds(0F, 0F, 1F - onePixel, 1F, 1F, 1F); - drawZSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - if (canConnectTo(world, x, y, z - 1)) { - setUVRotationZ(renderer); - renderer.setRenderBounds(0F, 0F, 0F, 1F, 1F, onePixel); - drawZSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - if (canConnectTo(world, x, y + 1, z)) { - resetUVRotation(renderer); - renderer.setRenderBounds(0F, 1F - onePixel, 0F, 1F, 1F, 1F); - drawYSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - } - - if (canConnectTo(world, x, y - 1, z)) { - resetUVRotation(renderer); - renderer.setRenderBounds(0F, 0F, 0F, 1F, onePixel, 1F); - drawYSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - } - - - return true; - } - - /** - * Render block cactus implementation - * @param metadata - */ - public boolean renderCactusLikeY(Block block, int x, int y, int z, float red, float green, float blue, int metadata, IBlockAccess world, RenderBlocks renderer) - { - Tessellator tessellator = Tessellator.instance; - float middle = 0.5F; - float full = 1.0F; - float f5 = 0.8F; - float f6 = 0.6F; - float bRed = middle * red; - float tRed = full * red; - float zRed = f5 * red; - float xRed = f6 * red; - float bGreen = middle * green; - float tGreen = full * green; - float zGreen = f5 * green; - float xGreen = f6 * green; - float bBlue = middle * blue; - float tBlue = full * blue; - float zBlue = f5 * blue; - float xBlue = f6 * blue; - float onePixel = 0.0625F * 3F; - int blockBrightness = block.getMixedBrightnessForBlock(world, x, y, z); - - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x, y - 1, z, 0)) - { - tessellator.setBrightness(renderer.renderMinY > 0.0D ? blockBrightness : block.getMixedBrightnessForBlock(world, x, y - 1, z)); - tessellator.setColorOpaque_F(bRed, bGreen, bBlue); - renderer.renderFaceYNeg(block, (double)x, (double)y, (double)z, renderer.getBlockIcon(block, world, x, y, z, 0)); - } - - if (renderer.renderAllFaces || block.shouldSideBeRendered(world, x, y + 1, z, 1)) - { - tessellator.setBrightness(renderer.renderMaxY < 1.0D ? blockBrightness : block.getMixedBrightnessForBlock(world, x, y + 1, z)); - tessellator.setColorOpaque_F(tRed, tGreen, tBlue); - renderer.renderFaceYPos(block, (double)x, (double)y, (double)z, renderer.getBlockIcon(block, world, x, y, z, 1)); - } - - drawYSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, onePixel, blockBrightness); - - if (canConnectTo(world, x + 1, y, z)) { - setUVRotationX(renderer); - renderer.setRenderBounds(1F - onePixel, 0F, 0F, 1F, 1F, 1F); - drawXSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - if (canConnectTo(world, x - 1, y, z)) { - setUVRotationX(renderer); - renderer.setRenderBounds(0F, 0F, 0F, onePixel, 1F, 1F); - drawXSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - if (canConnectTo(world, x, y, z + 1)) { - setUVRotationZ(renderer); - renderer.setRenderBounds(0F, 0F, 1F - onePixel, 1F, 1F, 1F); - drawZSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - if (canConnectTo(world, x, y, z - 1)) { - setUVRotationZ(renderer); - renderer.setRenderBounds(0F, 0F, 0F, 1F, 1F, onePixel); - drawZSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - - return true; - } - - /** - * Render block cactus implementation - * @param metadata - */ - public boolean renderCactusLikeZ(Block block, int x, int y, int z, float red, float green, float blue, int metadata, IBlockAccess world, RenderBlocks renderer) - { - setUVRotationZ(renderer); - - Tessellator tessellator = Tessellator.instance; - float middle = 0.5F; - float full = 1.0F; - float f5 = 0.8F; - float f6 = 0.6F; - float bRed = middle * red; - float tRed = full * red; - float zRed = f5 * red; - float xRed = f6 * red; - float bGreen = middle * green; - float tGreen = full * green; - float zGreen = f5 * green; - float xGreen = f6 * green; - float bBlue = middle * blue; - float tBlue = full * blue; - float zBlue = f5 * blue; - float xBlue = f6 * blue; - float onePixel = 0.0625F * 3F; - int blockBrightness = block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z); - - if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x, y, z - 1, 0)) - { - tessellator.setBrightness(renderer.renderMinZ > 0.0D ? blockBrightness : block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z - 1)); - tessellator.setColorOpaque_F(bRed, bGreen, bBlue); - renderer.renderFaceZNeg(block, (double)x, (double)y, (double)z, renderer.getBlockIcon(block, renderer.blockAccess, x, y, z, 2)); - } - - if (renderer.renderAllFaces || block.shouldSideBeRendered(renderer.blockAccess, x, y, z + 1, 1)) - { - tessellator.setBrightness(renderer.renderMaxZ < 1.0D ? blockBrightness : block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z + 1)); - tessellator.setColorOpaque_F(tRed, tGreen, tBlue); - renderer.renderFaceZPos(block, (double)x, (double)y, (double)z, renderer.getBlockIcon(block, renderer.blockAccess, x, y, z, 3)); - } - - drawZSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, onePixel, blockBrightness); - - resetUVRotation(renderer); - - if (canConnectTo(world, x + 1, y, z)) { - setUVRotationX(renderer); - renderer.setRenderBounds(1F - onePixel, 0F, 0F, 1F, 1F, 1F); - drawXSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - if (canConnectTo(world, x - 1, y, z)) { - setUVRotationX(renderer); - renderer.setRenderBounds(0F, 0F, 0F, onePixel, 1F, 1F); - drawXSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - resetUVRotation(renderer); - } - - if (canConnectTo(world, x, y + 1, z)) { - resetUVRotation(renderer); - renderer.setRenderBounds(0F, 1F - onePixel, 0F, 1F, 1F, 1F); - drawYSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - } - - if (canConnectTo(world, x, y - 1, z)) { - resetUVRotation(renderer); - renderer.setRenderBounds(0F, 0F, 0F, 1F, onePixel, 1F); - drawYSides(block, x, y, z, renderer, metadata, zRed, xRed, zGreen, xGreen, zBlue, xBlue, 0.063F * 3F, blockBrightness); - } - - return true; - } - - private void drawXSides(Block block, int x, int y, int z, RenderBlocks renderer, int metadata, float zRed, - float xRed, float zGreen, float xGreen, float zBlue, float xBlue, float onePixel, int l) { - Tessellator tessellator = Tessellator.instance; - - tessellator.setBrightness(l); - tessellator.setColorOpaque_F(zRed, zGreen, zBlue); - tessellator.addTranslation(0.0F, 0.0F, onePixel); - renderer.renderFaceZNeg(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, 0.0F, -onePixel); - tessellator.addTranslation(0.0F, 0.0F, -onePixel); - renderer.renderFaceZPos(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, 0.0F, onePixel); - tessellator.setColorOpaque_F(xRed, xGreen, xBlue); - tessellator.addTranslation(0.0F, onePixel, 0.0F); - renderer.renderFaceYNeg(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, -onePixel, 0.0F); - tessellator.addTranslation(0.0F, -onePixel, 0.0F); - renderer.renderFaceYPos(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, onePixel, 0.0F); - } - - private void drawYSides(Block block, int x, int y, int z, RenderBlocks renderer, int metadata, - float zRed, float xRed, float zGreen, float xGreen, float zBlue, float xBlue, float onePixel, int blockBrightness) { - Tessellator tessellator = Tessellator.instance; - - tessellator.setBrightness(blockBrightness); - tessellator.setColorOpaque_F(zRed, zGreen, zBlue); - tessellator.addTranslation(0.0F, 0.0F, onePixel); - renderer.renderFaceZNeg(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, 0.0F, -onePixel); - tessellator.addTranslation(0.0F, 0.0F, -onePixel); - renderer.renderFaceZPos(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, 0.0F, onePixel); - tessellator.setColorOpaque_F(xRed, xGreen, xBlue); - tessellator.addTranslation(onePixel, 0.0F, 0.0F); - renderer.renderFaceXNeg(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(-onePixel, 0.0F, 0.0F); - tessellator.addTranslation(-onePixel, 0.0F, 0.0F); - renderer.renderFaceXPos(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(onePixel, 0.0F, 0.0F); - } - - private void drawZSides(Block block, int x, int y, int z, RenderBlocks renderer, int metadata, - float zRed, float xRed, float zGreen, float xGreen, float zBlue, float xBlue, float onePixel, int blockBrightness) { - Tessellator tessellator = Tessellator.instance; - - tessellator.setBrightness(blockBrightness); - tessellator.setColorOpaque_F(xRed, xGreen, xBlue); - tessellator.addTranslation(onePixel, 0.0F, 0.0F); - renderer.renderFaceXNeg(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(-onePixel, 0.0F, 0.0F); - tessellator.addTranslation(-onePixel, 0.0F, 0.0F); - renderer.renderFaceXPos(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(onePixel, 0.0F, 0.0F); - tessellator.setColorOpaque_F(zRed, zGreen, zBlue); - tessellator.addTranslation(0.0F, onePixel, 0.0F); - renderer.renderFaceYNeg(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, -onePixel, 0.0F); - tessellator.addTranslation(0.0F, -onePixel, 0.0F); - renderer.renderFaceYPos(block, (double)x, (double)y, (double)z, getSideIcon(block, metadata)); - tessellator.addTranslation(0.0F, onePixel, 0.0F); - } - - private boolean canConnectTo(IBlockAccess world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - return block == TFBlocks.thorns || block == TFBlocks.burntThorns || block == TFBlocks.thornRose; - } - - private void setUVRotationX(RenderBlocks renderer) { - renderer.uvRotateEast = 1; - renderer.uvRotateWest = 1; - renderer.uvRotateTop = 1; - renderer.uvRotateBottom = 1; - } - - private void setUVRotationZ(RenderBlocks renderer) { - renderer.uvRotateSouth = 1; - renderer.uvRotateNorth = 1; - } - - private void resetUVRotation(RenderBlocks renderer) { - renderer.uvRotateTop = 0; - renderer.uvRotateBottom = 0; - renderer.uvRotateEast = 0; - renderer.uvRotateWest = 0; - renderer.uvRotateNorth = 0; - renderer.uvRotateSouth = 0; - } - - private IIcon getSideIcon(Block block, int metadata) { - return block.getIcon(2, metadata & 3); - } - - public static void renderInvBlock(RenderBlocks renderblocks, Block par1Block, int meta) { - Tessellator tessellator = Tessellator.instance; - - GL11.glTranslatef(-0.5F, -0.5F, -0.5F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - -// // top -// renderblocks.setRenderBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.1875F, 0.9375F); -// renderInvBlock(renderblocks, par1Block, meta, tessellator); -// -// // middle -// renderblocks.setRenderBounds(0.125, 0.1875F, 0.125, 0.875F, 0.8125F, 0.875F); -// renderInvBlock(renderblocks, par1Block, meta, tessellator); -// -// // bottom -// renderblocks.setRenderBounds(0.0625F, 0.8125F, 0.0625F, 0.9375F, 1.0F, 0.9375F); - renderInvBlock(renderblocks, par1Block, meta, tessellator); - - GL11.glTranslatef(0.5F, 0.5F, 0.5F); - - par1Block.setBlockBoundsForItemRender(); - } - - protected static void renderInvBlock(RenderBlocks renderblocks, Block par1Block, int meta, Tessellator tessellator) { - float onePixel = 0.0625F * 3F; - - - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, -1.0F, 0.0F); - renderblocks.renderFaceYNeg(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(0, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 1.0F, 0.0F); - renderblocks.renderFaceYPos(par1Block, 0.0D, 0.0D, 0.0D, par1Block.getIcon(1, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, -1.0F); - renderblocks.renderFaceXPos(par1Block, -onePixel, 0.0D, 0.0D, par1Block.getIcon(2, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(0.0F, 0.0F, 1.0F); - renderblocks.renderFaceXNeg(par1Block, onePixel, 0.0D, 0.0D, par1Block.getIcon(3, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(-1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZNeg(par1Block, 0.0D, 0.0D, onePixel, par1Block.getIcon(4, meta)); - tessellator.draw(); - tessellator.startDrawingQuads(); - tessellator.setNormal(1.0F, 0.0F, 0.0F); - renderblocks.renderFaceZPos(par1Block, 0.0D, 0.0D, -onePixel, par1Block.getIcon(5, meta)); - tessellator.draw(); - } - - -} diff --git a/src/main/java/twilightforest/client/renderer/entity/LayerShields.java b/src/main/java/twilightforest/client/renderer/entity/LayerShields.java new file mode 100644 index 0000000000..e237155111 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/entity/LayerShields.java @@ -0,0 +1,86 @@ +package twilightforest.client.renderer.entity; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.client.ForgeHooksClient; +import org.lwjgl.opengl.GL11; +import twilightforest.capabilities.CapabilityList; +import twilightforest.capabilities.shield.IShieldCapability; +import twilightforest.entity.boss.EntityTFLich; +import twilightforest.item.TFItems; + +import javax.annotation.Nonnull; + +public class LayerShields implements LayerRenderer { + private int getShieldCount(EntityLivingBase entity) { + EntityTFLich lich = null; + if (entity instanceof EntityTFLich) + lich = (EntityTFLich) entity; + + IShieldCapability cap = null; + if (entity.hasCapability(CapabilityList.SHIELDS, null)) + cap = entity.getCapability(CapabilityList.SHIELDS, null); + + return lich != null ? lich.getShieldStrength() : cap != null ? cap.shieldsLeft() : 0; + } + + private void renderShields(float scale, EntityLivingBase entity, float partialTicks) { + float rotateAngleY = (entity.ticksExisted + partialTicks) / 5.0F; + float rotateAngleX = MathHelper.sin((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + float rotateAngleZ = MathHelper.cos((entity.ticksExisted + partialTicks) / 5.0F) / 4.0F; + + ItemStack shieldStack = new ItemStack(TFItems.experiment_115, 1, 3); + IBakedModel model = Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides(shieldStack, entity.world, entity); + + float prevX = OpenGlHelper.lastBrightnessX, prevY = OpenGlHelper.lastBrightnessY; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(1f, 1f, 1f, 1f)); + + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + int count = getShieldCount(entity); + for (int c = 0; c < count; c++) { + GlStateManager.pushMatrix(); + + GlStateManager.rotate(rotateAngleZ * (180F / (float) Math.PI) , 0.0F, 0.0F, 1.0F); + GlStateManager.rotate(rotateAngleY * (180F / (float) Math.PI) + (c * (360F / count)), 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(rotateAngleX * (180F / (float) Math.PI) , 1.0F, 0.0F, 0.0F); + + // It's upside-down, gotta make it upside-up + GlStateManager.scale(scale, -scale, scale); + + // Move the draw away from the entity being drawn around + GlStateManager.translate(0F, 0F, 1F); + + Minecraft.getMinecraft().getRenderItem().renderItem(shieldStack, ForgeHooksClient.handleCameraTransforms(model, ItemCameraTransforms.TransformType.NONE, false)); + + GlStateManager.popMatrix(); + } + + GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(0f, 0f, 0f, 1f)); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, prevX, prevY); + } + + @Override + public void doRenderLayer(@Nonnull EntityLivingBase living, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + if (getShieldCount(living) > 0) { + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0f); + renderShields(scale * 13, living, partialTicks); + } + } + + @Override + public boolean shouldCombineTextures() { + return false; + } +} diff --git a/src/main/java/twilightforest/client/renderer/entity/ModelTFApocalypseCube.java b/src/main/java/twilightforest/client/renderer/entity/ModelTFApocalypseCube.java deleted file mode 100644 index 3245d0e10a..0000000000 --- a/src/main/java/twilightforest/client/renderer/entity/ModelTFApocalypseCube.java +++ /dev/null @@ -1,59 +0,0 @@ -package twilightforest.client.renderer.entity; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelQuadruped; -import net.minecraft.client.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; - -public class ModelTFApocalypseCube extends ModelQuadruped { - - public ModelTFApocalypseCube() { - this(0.0F); - } - - public ModelTFApocalypseCube(float fNumber) { - super(6, fNumber); - - this.textureWidth = 128; - this.textureHeight = 64; - - this.head = new ModelRenderer(this, 0, 0); - - body = new ModelRenderer(this, 0, 0); - body.addBox(-16F, -16F, -16F, 32, 32, 32); - body.setRotationPoint(0F, 0F, -2F); - - leg1 = new ModelRenderer(this, 0, 0); - leg1.addBox(-4F, 0F, -4F, 8, 8, 8); - leg1.setRotationPoint(-6F, 16F, 9F); - - leg2 = new ModelRenderer(this, 0, 0); - leg2.addBox(-4F, 0F, -4F, 8, 8, 8); - leg2.setRotationPoint(6F, 16F, 9F); - - leg3 = new ModelRenderer(this, 0, 0); - leg3.addBox(-4F, 0F, -4F, 8, 8, 8); - leg3.setRotationPoint(-9F, 16F, -14F); - - leg4 = new ModelRenderer(this, 0, 0); - leg4.addBox(-4F, 0F, -4F, 8, 8, 8); - leg4.setRotationPoint(9F, 16F, -14F); - - - this.field_78145_g = 4.0F; - } - - /** - * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms - * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how - * "far" arms and legs can swing at most. - */ - public void setRotationAngles(float p_78087_1_, float p_78087_2_, float p_78087_3_, float p_78087_4_, float p_78087_5_, float p_78087_6_, Entity p_78087_7_) - { - super.setRotationAngles(p_78087_1_, p_78087_2_, p_78087_3_, p_78087_4_, p_78087_5_, p_78087_6_, p_78087_7_); - - this.body.rotateAngleX = 0F; - } - -} diff --git a/src/main/java/twilightforest/client/renderer/entity/NagaEyelidsLayer.java b/src/main/java/twilightforest/client/renderer/entity/NagaEyelidsLayer.java new file mode 100644 index 0000000000..b09a964de1 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/entity/NagaEyelidsLayer.java @@ -0,0 +1,31 @@ +package twilightforest.client.renderer.entity; + +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.entity.boss.EntityTFNaga; + +@SideOnly(Side.CLIENT) +public class NagaEyelidsLayer implements LayerRenderer { + private static final ResourceLocation textureLocDazed = TwilightForestMod.getModelTexture("nagahead_dazed.png"); + private final RenderTFNaga nagaRenderer; + + public NagaEyelidsLayer(RenderTFNaga nagaRenderer) { + this.nagaRenderer = nagaRenderer; + } + + @Override + public void doRenderLayer(T entitylivingbaseIn, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + if(entitylivingbaseIn.isDazed()) { + this.nagaRenderer.bindTexture(textureLocDazed); + this.nagaRenderer.getMainModel().render(entitylivingbaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + } + } + + @Override + public boolean shouldCombineTextures() { + return true; + } +} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderDefaultArrow.java b/src/main/java/twilightforest/client/renderer/entity/RenderDefaultArrow.java new file mode 100644 index 0000000000..1e4f842377 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/entity/RenderDefaultArrow.java @@ -0,0 +1,19 @@ +package twilightforest.client.renderer.entity; + +import net.minecraft.client.renderer.entity.RenderArrow; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.util.ResourceLocation; + +public class RenderDefaultArrow extends RenderArrow { + public static final ResourceLocation RES_ARROW = new ResourceLocation("textures/entity/projectiles/arrow.png"); + + public RenderDefaultArrow(RenderManager manager) { + super(manager); + } + + @Override + protected ResourceLocation getEntityTexture(T entity) { + return RES_ARROW; + } +} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFAdherent.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFAdherent.java index ded4c6b37f..ccf6c55a3f 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFAdherent.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFAdherent.java @@ -1,32 +1,20 @@ package twilightforest.client.renderer.entity; -import org.lwjgl.opengl.GL11; - import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.entity.Render; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; +import net.minecraft.client.renderer.entity.RenderManager; +import twilightforest.entity.EntityTFAdherent; -public class RenderTFAdherent extends RenderTFBiped { +public class RenderTFAdherent extends RenderTFBiped { - public RenderTFAdherent(ModelBiped modelBiped, float scale, String textureName) { - super(modelBiped, scale, textureName); + public RenderTFAdherent(RenderManager manager, ModelBiped modelBiped, float shadowSize, String textureName) { + super(manager, modelBiped, shadowSize, textureName); } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render extends RenderBiped { private final ResourceLocation textureLoc; - public RenderTFBiped(ModelBiped modelBiped, float scale, String textureName) { - super(modelBiped, scale); - - if (textureName.startsWith("textures")) - { + public RenderTFBiped(RenderManager manager, ModelBiped modelBiped, float shadowSize, String textureName) { + super(manager, modelBiped, shadowSize); + this.addLayer(new LayerBipedArmor(this)); + + if (textureName.startsWith("textures")) { textureLoc = new ResourceLocation(textureName); - } - else - { - textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + textureName); + } else { + textureLoc = TwilightForestMod.getModelTexture(textureName); } } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(T entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFBird.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFBird.java index 2f735919de..b2d02676cd 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFBird.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFBird.java @@ -2,68 +2,33 @@ import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; import twilightforest.TwilightForestMod; import twilightforest.entity.passive.EntityTFBird; +public class RenderTFBird extends RenderLiving { -public class RenderTFBird extends RenderLiving -{ private final ResourceLocation textureLoc; - - public RenderTFBird(ModelBase par1ModelBase, float par2, String textureName) - { - super(par1ModelBase, par2); - - textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + textureName); - } - - public void renderTFBird(EntityTFBird par1EntityTFBird, double par2, double par4, double par6, float par8, float par9) - { - super.doRender(par1EntityTFBird, par2, par4, par6, par8, par9); - } - - protected float getWingRotation(EntityTFBird par1EntityTFBird, float time) - { - float var3 = par1EntityTFBird.lastFlapLength + (par1EntityTFBird.flapLength - par1EntityTFBird.lastFlapLength) * time; - float var4 = par1EntityTFBird.lastFlapIntensity + (par1EntityTFBird.flapIntensity - par1EntityTFBird.lastFlapIntensity) * time; - return (MathHelper.sin(var3) + 1.0F) * var4; - } - - /** - * Defines what float the third param in setRotationAngles of ModelBase is - */ - protected float handleRotationFloat(EntityLivingBase par1EntityLiving, float par2) - { - return this.getWingRotation((EntityTFBird)par1EntityLiving, par2); - } - - public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) - { - this.renderTFBird((EntityTFBird)par1EntityLiving, par2, par4, par6, par8, par9); - } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "blockgoblin.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("blockgoblin.png"); - public RenderTFBlockGoblin(ModelBiped par1ModelBiped, float par2) { - super(par1ModelBiped, par2); + public RenderTFBlockGoblin(RenderManager manager, ModelBiped model, float shadowSize) { + super(manager, model, shadowSize); } - /** - * Render the goblin and the block both - */ @Override - public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) { - - EntityTFBlockGoblin goblin = (EntityTFBlockGoblin)entity; - - super.doRender(entity, d, d1, d2, f, f1); + public void doRender(EntityTFBlockGoblin goblin, double x, double y, double z, float yaw, float partialTicks) { + super.doRender(goblin, x, y, z, yaw, partialTicks); + renderManager.renderEntityStatic(goblin.block, partialTicks, false); + renderManager.renderEntityStatic(goblin.chain1, partialTicks, false); + renderManager.renderEntityStatic(goblin.chain2, partialTicks, false); + renderManager.renderEntityStatic(goblin.chain3, partialTicks, false);//renderEntity + } - RenderManager.instance.renderEntitySimple(goblin.block, f1); - RenderManager.instance.renderEntitySimple(goblin.chain1, f1); - RenderManager.instance.renderEntitySimple(goblin.chain2, f1); - RenderManager.instance.renderEntitySimple(goblin.chain3, f1);//renderEntity + @Override + protected ResourceLocation getEntityTexture(EntityTFBlockGoblin entity) { + return textureLoc; } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFBoar.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFBoar.java index c22de877d4..b6fd5d23f8 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFBoar.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFBoar.java @@ -1,25 +1,24 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderPig; -import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.EntityPig; import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; public class RenderTFBoar extends RenderPig { - - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "wildboar.png"); - public RenderTFBoar(ModelBase par1ModelBase, ModelBase par2ModelBase, float par3) { - super(par1ModelBase, par2ModelBase, par3); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("wildboar.png"); + + public RenderTFBoar(RenderManager manager, ModelBase model) { + super(manager); + this.mainModel = model; + } + + @Override + protected ResourceLocation getEntityTexture(EntityPig entity) { + return textureLoc; } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFBunny.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFBunny.java index 3f0b96200b..56f3aa30bd 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFBunny.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFBunny.java @@ -2,49 +2,32 @@ import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.entity.Entity; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; import twilightforest.entity.passive.EntityTFBunny; -public class RenderTFBunny extends RenderLiving { - - final ResourceLocation textureLocDutch; - final ResourceLocation textureLocWhite; - final ResourceLocation textureLocBrown; - - public RenderTFBunny(ModelBase par1ModelBase, float par2) { - super(par1ModelBase, par2); - - textureLocDutch = new ResourceLocation(TwilightForestMod.MODEL_DIR + "bunnydutch.png"); - textureLocWhite = new ResourceLocation(TwilightForestMod.MODEL_DIR + "bunnywhite.png"); - textureLocBrown = new ResourceLocation(TwilightForestMod.MODEL_DIR + "bunnybrown.png"); +public class RenderTFBunny extends RenderLiving { + + private final ResourceLocation textureLocDutch = TwilightForestMod.getModelTexture("bunnydutch.png"); + private final ResourceLocation textureLocWhite = TwilightForestMod.getModelTexture("bunnywhite.png"); + private final ResourceLocation textureLocBrown = TwilightForestMod.getModelTexture("bunnybrown.png"); + + public RenderTFBunny(RenderManager manager, ModelBase model, float shadowSize) { + super(manager, model, shadowSize); } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - if (par1Entity instanceof EntityTFBunny) - { - switch (((EntityTFBunny)par1Entity).getBunnyType()) - { - default: + @Override + protected ResourceLocation getEntityTexture(EntityTFBunny entity) { + switch (entity.getBunnyType()) { + default: case 0: case 1: return textureLocDutch; - case 2: return textureLocWhite; - case 3: return textureLocBrown; - } } - - // fallback - return textureLocDutch; - } - + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFCastleGuardian.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFCastleGuardian.java new file mode 100644 index 0000000000..06fd849c82 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFCastleGuardian.java @@ -0,0 +1,29 @@ +package twilightforest.client.renderer.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.RenderLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; +import twilightforest.entity.finalcastle.EntityTFCastleGuardian; + +import javax.annotation.Nonnull; + +public class RenderTFCastleGuardian extends RenderLivingBase { + + private final ResourceLocation textureLoc; + + public RenderTFCastleGuardian(RenderManager manager, ModelBase model, float shadowSize, String textureName) { + super(manager, model, shadowSize); + + if (textureName.startsWith("textures")) + textureLoc = new ResourceLocation(textureName); + else + textureLoc = TwilightForestMod.getModelTexture(textureName); + } + + @Override + protected ResourceLocation getEntityTexture(@Nonnull EntityTFCastleGuardian entity) { + return textureLoc; + } +} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFChainBlock.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFChainBlock.java index 465485998d..fbb28998ac 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFChainBlock.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFChainBlock.java @@ -1,75 +1,53 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - +import net.minecraft.util.math.MathHelper; import twilightforest.TwilightForestMod; -import twilightforest.entity.EntityTFBlockGoblin; import twilightforest.entity.EntityTFChainBlock; -public class RenderTFChainBlock extends Render { +public class RenderTFChainBlock extends Render { - private ModelBase model; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "blockgoblin.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("blockgoblin.png"); + private final ModelBase model; - public RenderTFChainBlock(ModelBase modelTFSpikeBlock, float f) { + public RenderTFChainBlock(RenderManager manager, ModelBase modelTFSpikeBlock) { + super(manager); this.model = modelTFSpikeBlock; } - /** - * The render method used in RenderBoat that renders the boat model. - */ - public void renderSpikeBlock(EntityTFChainBlock par1Entity, double par2, double par4, double par6, float par8, float time) - { - GL11.glPushMatrix(); - GL11.glTranslatef((float)par2, (float)par4, (float)par6); + @Override + public void doRender(EntityTFChainBlock chainBlock, double x, double y, double z, float yaw, float partialTicks) { + super.doRender(chainBlock, x, y, z, yaw, partialTicks); + + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); + + this.bindEntityTexture(chainBlock); - this.bindEntityTexture(par1Entity); + GlStateManager.scale(-1.0F, -1.0F, 1.0F); - GL11.glScalef(-1.0F, -1.0F, 1.0F); - - - GL11.glRotatef(MathHelper.wrapAngleTo180_float((float)par4), 1, 0, 1); - GL11.glRotatef(MathHelper.wrapAngleTo180_float(((float)par2 + (float)par6) * 11F), 0, 1, 0); -// GL11.glRotatef(MathHelper.wrapAngleTo180_float((float)par8), 0, 0, 1); - - - this.model.render(par1Entity, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F); - GL11.glPopMatrix(); - } + GlStateManager.rotate(MathHelper.wrapDegrees((float) y), 1, 0, 1); + GlStateManager.rotate(MathHelper.wrapDegrees(((float) x + (float) z) * 11F), 0, 1, 0); +// GlStateManager.rotate(MathHelper.wrapDegrees((float)yaw), 0, 0, 1); - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render 0) - { - //this.itemIcon = Items.itemsList[charm.getItemID()].getIconFromDamage(0); - this.itemIcon = TFItems.charmOfKeeping1.getIconFromDamage(0); - } - } - - GL11.glPushMatrix(); - GL11.glTranslatef((float)par2, (float)par4, (float)par6); - GL11.glEnable(GL12.GL_RESCALE_NORMAL); - GL11.glScalef(0.5F, 0.5F, 0.5F); - this.bindEntityTexture(par1Entity); - Tessellator var10 = Tessellator.instance; +public class RenderTFCharm extends RenderSnowball { - - this.func_77026_a(var10, this.itemIcon); - GL11.glDisable(GL12.GL_RESCALE_NORMAL); - GL11.glPopMatrix(); - } + public RenderTFCharm(RenderManager manager, RenderItem itemRenderer) { + super(manager, Item.getItemFromBlock(Blocks.BARRIER), itemRenderer); + } - private void func_77026_a(Tessellator par1Tessellator, IIcon par2Icon) - { - float f = par2Icon.getMinU(); - float f1 = par2Icon.getMaxU(); - float f2 = par2Icon.getMinV(); - float f3 = par2Icon.getMaxV(); - float f4 = 1.0F; - float f5 = 0.5F; - float f6 = 0.25F; - GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(-this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F); - par1Tessellator.startDrawingQuads(); - par1Tessellator.setNormal(0.0F, 1.0F, 0.0F); - par1Tessellator.addVertexWithUV((double)(0.0F - f5), (double)(0.0F - f6), 0.0D, (double)f, (double)f3); - par1Tessellator.addVertexWithUV((double)(f4 - f5), (double)(0.0F - f6), 0.0D, (double)f1, (double)f3); - par1Tessellator.addVertexWithUV((double)(f4 - f5), (double)(f4 - f6), 0.0D, (double)f1, (double)f2); - par1Tessellator.addVertexWithUV((double)(0.0F - f5), (double)(f4 - f6), 0.0D, (double)f, (double)f2); - par1Tessellator.draw(); - } - - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return TextureMap.locationItemsTexture; - } + @Override + public ItemStack getStackToRender(EntityTFCharmEffect charm) { + if (charm.getItemID() > -1) { + return new ItemStack(Item.getItemById(charm.getItemID())); + } else { + return ItemStack.EMPTY; + } + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFCubeOfAnnihilation.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFCubeOfAnnihilation.java index a230dba7ef..64becb6cba 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFCubeOfAnnihilation.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFCubeOfAnnihilation.java @@ -1,76 +1,53 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; - +import net.minecraft.util.math.MathHelper; import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFCubeOfAnnihilation; -import twilightforest.client.model.ModelTFHydraMortar; -import twilightforest.entity.EntityTFBlockGoblin; -import twilightforest.entity.EntityTFChainBlock; +import twilightforest.client.model.entity.ModelTFCubeOfAnnihilation; +import twilightforest.entity.EntityTFCubeOfAnnihilation; -public class RenderTFCubeOfAnnihilation extends Render { +public class RenderTFCubeOfAnnihilation extends Render { - private ModelBase model; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "cubeofannihilation.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("cubeofannihilation.png"); + private final ModelBase model = new ModelTFCubeOfAnnihilation(); - public RenderTFCubeOfAnnihilation() { - this.model = new ModelTFCubeOfAnnihilation(); + public RenderTFCubeOfAnnihilation(RenderManager manager) { + super(manager); } - /** - * The render method used in RenderBoat that renders the boat model. - */ - public void renderSpikeBlock(Entity entity, double x, double y, double z, float par8, float time) - { - GL11.glPushMatrix(); - GL11.glTranslatef((float)x, (float)y, (float)z); + @Override + public void doRender(EntityTFCubeOfAnnihilation entity, double x, double y, double z, float yaw, float partialTicks) { + super.doRender(entity, x, y, z, yaw, partialTicks); + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y, (float) z); + + this.bindEntityTexture(entity); - this.bindEntityTexture(entity); + GlStateManager.scale(-1.0F, -1.0F, 1.0F); - GL11.glScalef(-1.0F, -1.0F, 1.0F); - - // rotate - GL11.glRotatef(MathHelper.wrapAngleTo180_float(((float)x + (float)z + entity.ticksExisted + time) * 11F), 0, 1, 0); - + GlStateManager.rotate(MathHelper.wrapDegrees(((float) x + (float) z + entity.ticksExisted + partialTicks) * 11F), 0, 1, 0); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - GL11.glTranslatef(0F, -0.5F, 0F); - this.model.render(entity, 0.0F, 0.0F, 0.0F, 0.0F, time, 0.0625F / 2F); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDisable(GL11.GL_BLEND); - - GL11.glPopMatrix(); - } + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { - public RenderTFDeer(ModelBase par1ModelBase, float par2) { - super(par1ModelBase, par2); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("wilddeer.png"); + + public RenderTFDeer(RenderManager manager, ModelBase model, float shadowSize) { + super(manager, model, shadowSize); } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(EntityTFDeer entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFFallingIce.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFFallingIce.java index fb48f3c433..a7bf7c93fa 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFFallingIce.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFFallingIce.java @@ -1,60 +1,74 @@ package twilightforest.client.renderer.entity; -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; - import org.lwjgl.opengl.GL11; - import twilightforest.entity.boss.EntityTFFallingIce; -public class RenderTFFallingIce extends Render { - - private final RenderBlocks renderBlocks = new RenderBlocks(); - - @Override - public void doRender(Entity var1, double var2, double var4, double var6, float var8, float var9) { - this.doRender((EntityTFFallingIce)var1, var2, var4, var6, var8, var9); +// [VanillaCopy] complete copy of RenderFallingBlock but scaling by 3 before rendering +public class RenderTFFallingIce extends Render { + public RenderTFFallingIce(RenderManager renderManagerIn) { + super(renderManagerIn); + this.shadowSize = 0.5F; } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render extends RenderLiving { - public RenderTFGenericLiving(ModelBase par1ModelBase, float par2, String textureName) { - super(par1ModelBase, par2); - - if (textureName.startsWith("textures")) - { + private final ResourceLocation textureLoc; + + public RenderTFGenericLiving(RenderManager manager, ModelBase model, float shadowSize, String textureName) { + super(manager, model, shadowSize); + + if (textureName.startsWith("textures")) { textureLoc = new ResourceLocation(textureName); - } - else - { - textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + textureName); + } else { + textureLoc = TwilightForestMod.getModelTexture(textureName); } } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(T entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFGhast.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFGhast.java new file mode 100644 index 0000000000..2958434e8e --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFGhast.java @@ -0,0 +1,32 @@ +package twilightforest.client.renderer.entity; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFTowerGhast; + +public class RenderTFGhast extends RenderLiving { + + private static final ResourceLocation textureLocClosed = TwilightForestMod.getModelTexture("towerghast.png"); + private static final ResourceLocation textureLocOpen = TwilightForestMod.getModelTexture("towerghast_openeyes.png"); + private static final ResourceLocation textureLocAttack = TwilightForestMod.getModelTexture("towerghast_fire.png"); + + public RenderTFGhast(RenderManager manager, ModelBase model, float shadowSize) { + super(manager, model, shadowSize); + } + + @Override + protected ResourceLocation getEntityTexture(EntityTFTowerGhast entity) { + switch (entity.isAttacking() ? 2 : entity.getAttackStatus()) { + default: + case 0: + return textureLocClosed; + case 1: + return textureLocOpen; + case 2: + return textureLocAttack; + } + } +} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFGiant.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFGiant.java index 41feffeae9..0fb63ae011 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFGiant.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFGiant.java @@ -1,43 +1,45 @@ package twilightforest.client.renderer.entity; -import org.lwjgl.opengl.GL11; - import net.minecraft.client.Minecraft; -import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.model.ModelPlayer; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderBiped; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerBipedArmor; +import net.minecraft.client.resources.DefaultPlayerSkin; import net.minecraft.util.ResourceLocation; +import twilightforest.entity.EntityTFGiantMiner; + +public class RenderTFGiant extends RenderBiped { -public class RenderTFGiant extends RenderBiped { + private boolean typeCache = false; - private ResourceLocation textureLoc; + public RenderTFGiant(RenderManager manager) { + super(manager, new ModelPlayer(0, false), 1.8F); + this.addLayer(new LayerBipedArmor(this)); + } - public RenderTFGiant() { - super(new ModelBiped(), 0.625F); - - this.textureLoc = new ResourceLocation("textures/entity/steve.png"); + @Override + protected ResourceLocation getEntityTexture(EntityTFGiantMiner entity) { + Minecraft mc = Minecraft.getMinecraft(); + boolean type = false; + ResourceLocation texture = DefaultPlayerSkin.getDefaultSkinLegacy(); + if (mc.getRenderViewEntity() instanceof AbstractClientPlayer) { + AbstractClientPlayer client = ((AbstractClientPlayer) mc.getRenderViewEntity()); + texture = client.getLocationSkin(); + type = client.getSkinType().equals("slim"); + } + if (type != typeCache) { + typeCache = type; + mainModel = new ModelPlayer(0, type); + } + return texture; } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - if (Minecraft.getMinecraft().thePlayer.getLocationSkin() != null) { - return Minecraft.getMinecraft().thePlayer.getLocationSkin(); - } else { - return textureLoc; - } - } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = 4.0F; - GL11.glScalef(scale, scale, scale); - } + @Override + protected void preRenderCallback(EntityTFGiantMiner entity, float partialTicks) { + float scale = 4.0F; + GlStateManager.scale(scale, scale, scale); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFGoblinKnightUpper.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFGoblinKnightUpper.java index 1241bdba4b..04d8d7dce5 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFGoblinKnightUpper.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFGoblinKnightUpper.java @@ -1,100 +1,49 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBiped; -import net.minecraft.entity.EntityLivingBase; - -import org.lwjgl.opengl.GL11; - +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; import twilightforest.entity.EntityTFGoblinKnightUpper; -public class RenderTFGoblinKnightUpper extends RenderTFBiped { - - public RenderTFGoblinKnightUpper(ModelBiped par1ModelBiped, float par2) { - super(par1ModelBiped, par2, "doublegoblin.png"); +public class RenderTFGoblinKnightUpper extends RenderTFBiped { + public RenderTFGoblinKnightUpper(RenderManager manager, ModelBiped model, float shadowSize) { + super(manager, model, shadowSize, "doublegoblin.png"); } - - protected void rotateCorpse(EntityLivingBase par1EntityLiving, float par2, float par3, float par4) - { - this.rotateGoblinKnight((EntityTFGoblinKnightUpper)par1EntityLiving, par2, par3, par4); - } - - /** - * Rotates the goblin knight whether it is alive or dead - */ - protected void rotateGoblinKnight(EntityTFGoblinKnightUpper upperKnight, float par2, float par3, float par4) - { - super.rotateCorpse(upperKnight, par2, par3, par4); - - if (upperKnight.heavySpearTimer > 0) - { - GL11.glRotatef(getPitchForAttack((60 - upperKnight.heavySpearTimer) + par4), 1.0F, 0.0F, 0.0F); - - //System.out.println("Getting attack pitch. Result is " + getPitchForAttack((100 - upperKnight.heavySpearTimer) + (1.0F - par4))); + @Override + protected void applyRotations(EntityTFGoblinKnightUpper upperKnight, float ageInTicks, float rotationYaw, float partialTicks) { + super.applyRotations(upperKnight, ageInTicks, rotationYaw, partialTicks); - } - } + if (upperKnight.heavySpearTimer > 0) { + GlStateManager.rotate(getPitchForAttack((60 - upperKnight.heavySpearTimer) + partialTicks), 1.0F, 0.0F, 0.0F); + } + } - /** - * Figure out what pitch the goblin should be at depending on where it's at on the the timer - */ - public float getPitchForAttack(float attackTime) { - //System.out.println("Getting attack pitch. AttackTime is " + attackTime); - - if (attackTime <= 10) - { + /** + * Figure out what pitch the goblin should be at depending on where it's at on the the timer + */ + private float getPitchForAttack(float attackTime) { + if (attackTime <= 10) { // rock back return attackTime * 3.0F; } - if (attackTime > 10 && attackTime <= 30) - { + if (attackTime > 10 && attackTime <= 30) { // hang back return 30F; } - if (attackTime > 30 && attackTime <= 33) - { + if (attackTime > 30 && attackTime <= 33) { // slam forward return (attackTime - 30) * -25F + 30F; } - if (attackTime > 33 && attackTime <= 50) - { + if (attackTime > 33 && attackTime <= 50) { // stay forward return -45F; } - if (attackTime > 50 && attackTime <= 60) - { + if (attackTime > 50 && attackTime <= 60) { // back to normal return (10 - (attackTime - 50)) * -4.5F; } - - -// if (attackTime <= 10) -// { -// // rock back -// return attackTime * 3.0F; -// } -// if (attackTime > 10 && attackTime <= 40) -// { -// // hang back -// return 30F; -// } -// if (attackTime > 40 && attackTime <= 43) -// { -// // slam forward -// return (attackTime - 40) * -25F + 30F; -// } -// if (attackTime > 43 && attackTime <= 90) -// { -// // stay forward -// return -45F; -// } -// if (attackTime > 90 && attackTime <= 100) -// { -// // back to normal -// return (10 - (attackTime - 90)) * -4.5F; -// } - - return 0; + return 0; } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFHarbingerCube.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFHarbingerCube.java index 98c8576f25..d6519a6aef 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFHarbingerCube.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFHarbingerCube.java @@ -1,46 +1,29 @@ package twilightforest.client.renderer.entity; -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderLiving; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFCubeOfAnnihilation; -import twilightforest.client.model.ModelTFHydraMortar; -import twilightforest.entity.EntityTFBlockGoblin; -import twilightforest.entity.EntityTFChainBlock; +import twilightforest.client.model.entity.ModelTFApocalypseCube; +import twilightforest.entity.EntityTFHarbingerCube; -public class RenderTFHarbingerCube extends RenderLiving { +public class RenderTFHarbingerCube extends RenderLiving { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "apocalypse2.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("apocalypse2.png"); - public RenderTFHarbingerCube() { - super(new ModelTFApocalypseCube(), 1.0F); + public RenderTFHarbingerCube(RenderManager manager) { + super(manager, new ModelTFApocalypseCube(), 1.0F); } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = 1.0F; - GL11.glScalef(scale, scale, scale); - } + @Override + protected ResourceLocation getEntityTexture(EntityTFHarbingerCube entity) { + return textureLoc; + } + + @Override + protected void preRenderCallback(EntityTFHarbingerCube entity, float partialTicks) { + float scale = 1.0F; + GlStateManager.scale(scale, scale, scale); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFHedgeSpider.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFHedgeSpider.java index 3fff7b4628..61b0cebbf7 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFHedgeSpider.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFHedgeSpider.java @@ -1,16 +1,21 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderSpider; -import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFHedgeSpider; -public class RenderTFHedgeSpider extends RenderSpider { +public class RenderTFHedgeSpider extends RenderSpider { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "hedgespider.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("hedgespider.png"); + + public RenderTFHedgeSpider(RenderManager manager) { + super(manager); + } @Override - protected ResourceLocation getEntityTexture(Entity entity) { + protected ResourceLocation getEntityTexture(EntityTFHedgeSpider entity) { return textureLoc; } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFHydra.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFHydra.java index 05699cfd26..a64f0d3936 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFHydra.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFHydra.java @@ -1,61 +1,27 @@ package twilightforest.client.renderer.entity; - import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.boss.BossStatus; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; import twilightforest.entity.boss.EntityTFHydra; +public class RenderTFHydra extends RenderLiving { + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("hydra4.png"); -public class RenderTFHydra extends RenderLiving { - - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "hydra4.png"); - - - public RenderTFHydra(ModelBase modelbase, float f) { - super(modelbase, f); - + public RenderTFHydra(RenderManager manager, ModelBase modelbase, float shadowSize) { + super(manager, modelbase, shadowSize); } @Override - public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) { - // render the hydra body, legs, tail normally - super.doRender(entity, d, d1, d2, f, f1); - - BossStatus.setBossStatus((EntityTFHydra)entity, false); - -// GL11.glPushMatrix(); -//// renderOffsetAABB(entity.boundingBox, d - entity.lastTickPosX, d1 - entity.lastTickPosY, d2 - entity.lastTickPosZ); -// renderOffsetAABB(hydra.body.boundingBox, d - entity.lastTickPosX, d1 - entity.lastTickPosY, d2 - entity.lastTickPosZ); -// renderOffsetAABB(hydra.tail.boundingBox, d - entity.lastTickPosX, d1 - entity.lastTickPosY, d2 - entity.lastTickPosZ); -// GL11.glPopMatrix(); - -// System.out.println("Rendering AABB, d = " + d + ", " + d1 + ", " + d2 + ". entity = " + entity.lastTickPosX + ", " + entity.lastTickPosY + ", " + entity.lastTickPosZ + ". tail = " + hydra.tail.posX + ", " + hydra.tail.posY + ", " + hydra.tail.posZ); -// System.out.println("AABB, at " + (d - entity.lastTickPosX - (entity.lastTickPosX - hydra.tail.posX)) + ", " + (d1 - entity.lastTickPosY - (entity.lastTickPosY - hydra.tail.posY)) + ", " + (d2 - entity.lastTickPosZ - (entity.lastTickPosZ - hydra.tail.posZ))); -// System.out.println("Theoretically it could be " + (d - hydra.tail.posX) + ", " + (d1 - hydra.tail.posY) + ", " + (d2 - hydra.tail.posZ)); - + protected float getDeathMaxRotation(EntityTFHydra entity) { + return 0F; } @Override - protected float getDeathMaxRotation(EntityLivingBase par1EntityLiving) { - return 0F; + protected ResourceLocation getEntityTexture(EntityTFHydra entity) { + return textureLoc; } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } - - - - - } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraHead.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraHead.java index b8212982ec..5dafc5c93a 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraHead.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraHead.java @@ -7,71 +7,56 @@ import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; import twilightforest.entity.boss.EntityTFHydra; +import twilightforest.entity.boss.EntityTFHydraHead; import twilightforest.entity.boss.EntityTFHydraPart; import twilightforest.entity.boss.HydraHeadContainer; -public class RenderTFHydraHead extends RenderLiving { +public class RenderTFHydraHead extends RenderLiving { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "hydra4.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("hydra4.png"); - public RenderTFHydraHead(ModelBase modelbase, float f) { - super(modelbase, f); - + public RenderTFHydraHead(RenderManager manager, ModelBase modelbase, float shadowSize) { + super(manager, modelbase, shadowSize); } - - /** - * Override render to perform a few special rendering tricks, like not rendering "dead" heads & their necks - */ + @Override - public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) { + public void doRender(EntityTFHydraHead entity, double x, double y, double z, float yaw, float partialTicks) { // get the HydraHeadContainer that we're taking about HydraHeadContainer headCon = getHeadObject(entity); - if (headCon != null) - { + if (headCon != null) { // see whether we want to render these - if (headCon.shouldRenderHead()) - { - super.doRender(entity, d, d1, d2, f, f1); + if (headCon.shouldRenderHead()) { + super.doRender(entity, x, y, z, yaw, partialTicks); } - if (headCon.shouldRenderNeck(0)) - { - RenderManager.instance.renderEntitySimple(headCon.necka, f1); + if (headCon.shouldRenderNeck(0)) { + renderManager.renderEntityStatic(headCon.necka, partialTicks, false); } - if (headCon.shouldRenderNeck(1)) - { - RenderManager.instance.renderEntitySimple(headCon.neckb, f1); + if (headCon.shouldRenderNeck(1)) { + renderManager.renderEntityStatic(headCon.neckb, partialTicks, false); } - if (headCon.shouldRenderNeck(2)) - { - RenderManager.instance.renderEntitySimple(headCon.neckc, f1); + if (headCon.shouldRenderNeck(2)) { + renderManager.renderEntityStatic(headCon.neckc, partialTicks, false); } - if (headCon.shouldRenderNeck(3)) - { - RenderManager.instance.renderEntitySimple(headCon.neckd, f1); + if (headCon.shouldRenderNeck(3)) { + renderManager.renderEntityStatic(headCon.neckd, partialTicks, false); } - if (headCon.shouldRenderNeck(4)) - { - RenderManager.instance.renderEntitySimple(headCon.necke, f1); + if (headCon.shouldRenderNeck(4)) { + renderManager.renderEntityStatic(headCon.necke, partialTicks, false); } - } - else - { - super.doRender(entity, d, d1, d2, f, f1); + } else { + super.doRender(entity, x, y, z, yaw, partialTicks); } } private HydraHeadContainer getHeadObject(Entity entity) { - EntityTFHydra hydra = ((EntityTFHydraPart)entity).hydraObj; - - if (hydra != null) - { - for (int i = 0; i < hydra.numHeads; i++) - { - if (hydra.hc[i].headEntity == entity) - { + EntityTFHydra hydra = ((EntityTFHydraPart) entity).hydra; + + if (hydra != null) { + for (int i = 0; i < hydra.numHeads; i++) { + if (hydra.hc[i].headEntity == entity) { return hydra.hc[i]; } @@ -80,12 +65,9 @@ private HydraHeadContainer getHeadObject(Entity entity) { return null; } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(EntityTFHydraHead entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraMortar.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraMortar.java index 6d1a487eca..8ced261a72 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraMortar.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFHydraMortar.java @@ -1,93 +1,72 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.entity.Entity; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; - import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFHydraMortar; +import twilightforest.client.model.entity.ModelTFHydraMortar; import twilightforest.entity.boss.EntityTFHydraMortar; -public class RenderTFHydraMortar extends Render { - - private ModelTFHydraMortar mortarModel; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "hydramortar.png"); - - - public RenderTFHydraMortar() - { - mortarModel = new ModelTFHydraMortar(); - this.shadowSize = 0.5F; - } - - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { + + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("hydramortar.png"); + private final ModelTFHydraMortar mortarModel = new ModelTFHydraMortar(); + + public RenderTFHydraMortar(RenderManager manager) { + super(manager); + this.shadowSize = 0.5F; + } + @Override - public void doRender(Entity var1, double x, double y, double z, float var8, float partialTick) { - - EntityTFHydraMortar mortar = (EntityTFHydraMortar)var1; - - GL11.glPushMatrix(); - GL11.glTranslatef((float)x, (float)y, (float)z); - float var10; - - if ((float)mortar.fuse - partialTick + 1.0F < 10.0F) - { - var10 = 1.0F - ((float)mortar.fuse - partialTick + 1.0F) / 10.0F; - - if (var10 < 0.0F) - { - var10 = 0.0F; - } - - if (var10 > 1.0F) - { - var10 = 1.0F; - } - - var10 *= var10; - var10 *= var10; - float var11 = 1.0F + var10 * 0.3F; - GL11.glScalef(var11, var11, var11); - } - - var10 = (1.0F - ((float)mortar.fuse - partialTick + 1.0F) / 100.0F) * 0.8F; - //this.loadTexture(TwilightForestMod.MODEL_DIR + "hydramortar.png"); - this.bindTexture(textureLoc); - - mortarModel.render(0.075F); - - if (mortar.fuse / 5 % 2 == 0) - { - GL11.glDisable(GL11.GL_TEXTURE_2D); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA); - GL11.glColor4f(1.0F, 1.0F, 1.0F, var10); - - mortarModel.render(0.075F); - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glEnable(GL11.GL_TEXTURE_2D); - } - - GL11.glPopMatrix(); + public void doRender(EntityTFHydraMortar mortar, double x, double y, double z, float yaw, float partialTicks) { + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y, (float) z); + float var10; + + if ((float) mortar.fuse - partialTicks + 1.0F < 10.0F) { + var10 = 1.0F - ((float) mortar.fuse - partialTicks + 1.0F) / 10.0F; + + if (var10 < 0.0F) { + var10 = 0.0F; + } + + if (var10 > 1.0F) { + var10 = 1.0F; + } + + var10 *= var10; + var10 *= var10; + float var11 = 1.0F + var10 * 0.3F; + GlStateManager.scale(var11, var11, var11); + } + + var10 = (1.0F - ((float) mortar.fuse - partialTicks + 1.0F) / 100.0F) * 0.8F; + this.bindTexture(textureLoc); + + mortarModel.render(0.075F); + + if (mortar.fuse / 5 % 2 == 0) { + GlStateManager.disableTexture2D(); + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA); + GlStateManager.color(1.0F, 1.0F, 1.0F, var10); + + mortarModel.render(0.075F); + + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + GlStateManager.enableTexture2D(); + } + + GlStateManager.popMatrix(); } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(EntityTFHydraMortar entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFIceCrystal.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFIceCrystal.java index 4f0d816e4d..f9a844dd6f 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFIceCrystal.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFIceCrystal.java @@ -1,41 +1,31 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - +import net.minecraft.util.math.MathHelper; import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFIceCrystal; - -public class RenderTFIceCrystal extends RenderLiving { +import twilightforest.client.model.entity.ModelTFIceCrystal; +import twilightforest.entity.boss.EntityTFIceCrystal; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "icecrystal.png"); +public class RenderTFIceCrystal extends RenderLiving { + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("icecrystal.png"); - public RenderTFIceCrystal() { - super(new ModelTFIceCrystal(), 1.0F); + public RenderTFIceCrystal(RenderManager manager) { + super(manager, new ModelTFIceCrystal(), 0.25F); } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float partialTick) - { - float bounce = par1EntityLivingBase.ticksExisted + partialTick; - - GL11.glTranslatef(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); - } - + @Override + protected void preRenderCallback(EntityTFIceCrystal entity, float partialTicks) { + float bounce = entity.ticksExisted + partialTicks; + GlStateManager.translate(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); + } @Override - protected ResourceLocation getEntityTexture(Entity var1) { - return RenderTFIceCrystal.textureLoc; + protected ResourceLocation getEntityTexture(EntityTFIceCrystal entity) { + return textureLoc; } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFIceExploder.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFIceExploder.java index 4e4d0bf8bc..4800249f08 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFIceExploder.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFIceExploder.java @@ -1,41 +1,34 @@ package twilightforest.client.renderer.entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.math.MathHelper; +import twilightforest.client.model.entity.ModelTFIceExploder; +import twilightforest.entity.EntityTFIceExploder; -import org.lwjgl.opengl.GL11; +public class RenderTFIceExploder extends RenderTFBiped { -import twilightforest.client.model.ModelTFIceExploder; - -public class RenderTFIceExploder extends RenderTFBiped { - - public RenderTFIceExploder() { - super(new ModelTFIceExploder(), 1.0F, "iceexploder.png"); + public RenderTFIceExploder(RenderManager manager) { + super(manager, new ModelTFIceExploder(), 0.4F, "iceexploder.png"); } - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float partialTick) - { - float bounce = par1EntityLivingBase.ticksExisted + partialTick; - - GL11.glTranslatef(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); + @Override + protected void preRenderCallback(EntityTFIceExploder entity, float partialTicks) { + float bounce = entity.ticksExisted + partialTicks; + + GlStateManager.translate(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); // flash - float f1 = par1EntityLivingBase.deathTime; + float f1 = entity.deathTime; if (f1 > 0) { float f2 = 1.0F + MathHelper.sin(f1 * 100.0F) * f1 * 0.01F; - if (f1 < 0.0F) - { + if (f1 < 0.0F) { f1 = 0.0F; } - if (f1 > 1.0F) - { + if (f1 > 1.0F) { f1 = 1.0F; } @@ -43,51 +36,42 @@ protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float pa f1 *= f1; float f3 = (1.0F + f1 * 0.4F) * f2; float f4 = (1.0F + f1 * 0.1F) / f2; - GL11.glScalef(f3, f4, f3); + GlStateManager.scale(f3, f4, f3); + } + } + + @Override + protected void applyRotations(EntityTFIceExploder entity, float ageInTicks, float rotationYaw, float partialTicks) { + GlStateManager.rotate(180.0F - rotationYaw, 0.0F, 1.0F, 0.0F); + } + + @Override + protected int getColorMultiplier(EntityTFIceExploder entity, float brightness, float partialTicks) { + if (entity.deathTime > 0) { + float f2 = entity.deathTime + partialTicks; + + if ((int) (f2 / 2) % 2 == 0) { + return 0; + } else { + int i = (int) (f2 * 0.2F * 255.0F); + + if (i < 0) { + i = 0; + } + + if (i > 255) { + i = 255; + } + + short short1 = 255; + short short2 = 255; + short short3 = 255; + return i << 24 | short1 << 16 | short2 << 8 | short3; + } + } else { + return 0; } - } - - protected void rotateCorpse(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) - { - GL11.glRotatef(180.0F - par3, 0.0F, 1.0F, 0.0F); - } - - - /** - * Returns an ARGB int color back. Args: entityLiving, lightBrightness, partialTickTime - */ - protected int getColorMultiplier(EntityLivingBase par1EntityLivingBase, float par2, float par3) - { - if (par1EntityLivingBase.deathTime > 0) { - float f2 = par1EntityLivingBase.deathTime + par3; - - if ((int)(f2 / 2) % 2 == 0) - { - return 0; - } - else - { - int i = (int)(f2 * 0.2F * 255.0F); - - if (i < 0) - { - i = 0; - } - - if (i > 255) - { - i = 255; - } - - short short1 = 255; - short short2 = 255; - short short3 = 255; - return i << 24 | short1 << 16 | short2 << 8 | short3; - } - } else { - return 0; - } - } + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFIceShooter.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFIceShooter.java index 5860f861b9..1046834c71 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFIceShooter.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFIceShooter.java @@ -1,27 +1,20 @@ package twilightforest.client.renderer.entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.math.MathHelper; +import twilightforest.client.model.entity.ModelTFIceShooter; +import twilightforest.entity.EntityTFIceShooter; -import org.lwjgl.opengl.GL11; +public class RenderTFIceShooter extends RenderTFBiped { -import twilightforest.client.model.ModelTFIceShooter; -import twilightforest.client.renderer.entity.RenderTFBiped; - -public class RenderTFIceShooter extends RenderTFBiped { - - public RenderTFIceShooter() { - super(new ModelTFIceShooter(), 1.0F, "iceshooter.png"); + public RenderTFIceShooter(RenderManager manager) { + super(manager, new ModelTFIceShooter(), 0.4F, "iceshooter.png"); } - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float partialTick) - { - float bounce = par1EntityLivingBase.ticksExisted + partialTick; - - GL11.glTranslatef(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); - } + @Override + protected void preRenderCallback(EntityTFIceShooter entity, float partialTicks) { + float bounce = entity.ticksExisted + partialTicks; + GlStateManager.translate(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFKingSpider.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFKingSpider.java index 6aa0c62de5..a57c4fdaea 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFKingSpider.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFKingSpider.java @@ -1,30 +1,28 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderSpider; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFKingSpider; + +public class RenderTFKingSpider extends RenderSpider { -public class RenderTFKingSpider extends RenderSpider { + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("kingspider.png"); - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "kingspider.png"); + public RenderTFKingSpider(RenderManager manager) { + super(manager); + } @Override - protected ResourceLocation getEntityTexture(Entity entity) { + protected ResourceLocation getEntityTexture(EntityTFKingSpider entity) { return textureLoc; } - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = 1.9F; - GL11.glScalef(scale, scale, scale); - } + @Override + protected void preRenderCallback(EntityTFKingSpider entity, float partialTicks) { + float scale = 1.9F; + GlStateManager.scale(scale, scale, scale); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFKnightPhantom.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFKnightPhantom.java index 13f45422f9..991b0344f9 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFKnightPhantom.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFKnightPhantom.java @@ -1,38 +1,34 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderBiped; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerBipedArmor; +import net.minecraft.client.renderer.entity.layers.LayerHeldItem; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFKnightPhantom2; +import twilightforest.client.model.entity.ModelTFKnightPhantom2; import twilightforest.entity.boss.EntityTFKnightPhantom; -public class RenderTFKnightPhantom extends RenderBiped { +public class RenderTFKnightPhantom extends RenderBiped { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "phantomskeleton.png"); + private static final ResourceLocation PHANTOM_TEXTURE = TwilightForestMod.getModelTexture("phantomskeleton.png"); - - public RenderTFKnightPhantom(ModelTFKnightPhantom2 modelTFKnightPhantom2, float f) { - super(modelTFKnightPhantom2, f); + public RenderTFKnightPhantom(RenderManager manager, ModelTFKnightPhantom2 model, float shadowSize) { + super(manager, model, shadowSize); + this.addLayer(new LayerHeldItem(this)); + this.addLayer(new LayerBipedArmor(this)); + } + + @Override + protected ResourceLocation getEntityTexture(EntityTFKnightPhantom entity) { + return PHANTOM_TEXTURE; } @Override - protected ResourceLocation getEntityTexture(Entity entity) { - return textureLoc; + protected void preRenderCallback(EntityTFKnightPhantom entity, float partialTicks) { + float scale = entity.isChargingAtPlayer() ? 1.8F : 1.2F; + GlStateManager.scale(scale, scale, scale); } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = ((EntityTFKnightPhantom)par1EntityLivingBase).isChargingAtPlayer() ? 1.8F : 1.2F; - GL11.glScalef(scale, scale, scale); - } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFKobold.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFKobold.java index 5f2a861e94..0359008513 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFKobold.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFKobold.java @@ -1,134 +1,24 @@ package twilightforest.client.renderer.entity; -import java.util.UUID; - -import org.lwjgl.opengl.GL11; - -import com.mojang.authlib.GameProfile; - -import net.minecraft.block.Block; import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer; -import net.minecraft.entity.EntityLiving; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTUtil; -import net.minecraft.util.StringUtils; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerHeldItem; +import twilightforest.entity.EntityTFKobold; -public class RenderTFKobold extends RenderTFBiped { +public class RenderTFKobold extends RenderTFBiped { - public RenderTFKobold(ModelBiped modelBiped, float scale, String textureName) { - super(modelBiped, scale, textureName); + public RenderTFKobold(RenderManager manager, ModelBiped modelBiped, float shadowSize, String textureName) { + super(manager, modelBiped, shadowSize, textureName); + this.addLayer(new LayerHeldItem(this)); } - - - protected void renderEquippedItems(EntityLiving p_77029_1_, float p_77029_2_) - { - GL11.glColor3f(1.0F, 1.0F, 1.0F); - //super.renderEquippedItems(p_77029_1_, p_77029_2_); - ItemStack itemstack = p_77029_1_.getHeldItem(); - ItemStack itemstack1 = p_77029_1_.func_130225_q(3); - Item item; - float f1; - - // no armor - - if (itemstack != null && itemstack.getItem() != null) - { - item = itemstack.getItem(); - GL11.glPushMatrix(); - - this.modelBipedMain.bipedRightArm.postRender(0.0625F); - GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F); - - net.minecraftforge.client.IItemRenderer customRenderer = net.minecraftforge.client.MinecraftForgeClient.getItemRenderer(itemstack, net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED); - boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper(net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED, itemstack, net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D)); - - if (item instanceof ItemBlock && (is3D || RenderBlocks.renderItemIn3d(Block.getBlockFromItem(item).getRenderType()))) - { - f1 = 0.5F; - GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); - f1 *= 0.75F; - GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); - GL11.glScalef(-f1, -f1, f1); - } - else if (item == Items.bow) - { - f1 = 0.625F; - GL11.glTranslatef(0.0F, 0.125F, 0.3125F); - GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F); - GL11.glScalef(f1, -f1, f1); - GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); - } - else if (item.isFull3D()) - { - f1 = 0.625F; - - if (item.shouldRotateAroundWhenRendering()) - { - GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); - GL11.glTranslatef(0.0F, -0.125F, 0.0F); - } - - this.func_82422_c(); - GL11.glScalef(f1, -f1, f1); - GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); - } - else - { - f1 = 0.375F; - GL11.glTranslatef(0.25F, 0.0F, -0.1875F); - this.func_82422_c(); // include short arms even when rendering non-tools - GL11.glScalef(f1, f1, f1); - GL11.glRotatef(60.0F, 0.0F, 0.0F, 1.0F); - GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); - GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F); - } - - float f2; - int i; - float f5; - - if (itemstack.getItem().requiresMultipleRenderPasses()) - { - for (i = 0; i < itemstack.getItem().getRenderPasses(itemstack.getItemDamage()); ++i) - { - int j = itemstack.getItem().getColorFromItemStack(itemstack, i); - f5 = (float)(j >> 16 & 255) / 255.0F; - f2 = (float)(j >> 8 & 255) / 255.0F; - float f3 = (float)(j & 255) / 255.0F; - GL11.glColor4f(f5, f2, f3, 1.0F); - this.renderManager.itemRenderer.renderItem(p_77029_1_, itemstack, i); - } - } - else - { - i = itemstack.getItem().getColorFromItemStack(itemstack, 0); - float f4 = (float)(i >> 16 & 255) / 255.0F; - f5 = (float)(i >> 8 & 255) / 255.0F; - f2 = (float)(i & 255) / 255.0F; - GL11.glColor4f(f4, f5, f2, 1.0F); - this.renderManager.itemRenderer.renderItem(p_77029_1_, itemstack, 0); - } - - GL11.glPopMatrix(); - } - } - /** * How far down the arm should we render the equipped item? */ - protected void func_82422_c() - { - GL11.glTranslatef(0.0F, 0.01875F, 0.0F); - } + //TODO: AtomicBlom: Somehow introduce this into LayerHeldItem + protected void func_82422_c() { + GlStateManager.translate(0.0F, 0.01875F, 0.0F); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFLich.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFLich.java index 387b5d0d6e..246c4cd7c4 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFLich.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFLich.java @@ -1,69 +1,26 @@ package twilightforest.client.renderer.entity; - import net.minecraft.client.model.ModelBiped; import net.minecraft.client.renderer.entity.RenderBiped; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.boss.BossStatus; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFLich; import twilightforest.entity.boss.EntityTFLich; +import javax.annotation.Nonnull; +public class RenderTFLich extends RenderBiped { -public class RenderTFLich extends RenderBiped { - - public static EntityTFLich entityLich = null; - - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "twilightlich64.png"); + private static final ResourceLocation LICH_TEXTURE = TwilightForestMod.getModelTexture("twilightlich64.png"); - - public RenderTFLich(ModelBiped modelbiped, float f) { - super(modelbiped, f); - this.setRenderPassModel(new ModelTFLich(true)); + public RenderTFLich(RenderManager manager, ModelBiped modelbiped, float shadowSize) { + super(manager, modelbiped, shadowSize); + addLayer(new LayerShields()); } - - protected int shouldRenderPass(EntityLivingBase entity, int i, float f) - { - EntityTFLich lich = (EntityTFLich)entity; - if (i == 2) { - GL11.glEnable(3042 /*GL_BLEND*/); -// GL11.glDisable(3008 /*GL_ALPHA_TEST*/); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - if (lich.isShadowClone()) { - // clone alpha - float shadow = 0.33f; - GL11.glColor4f(shadow, shadow, shadow, 0.8F); - return 2; - } - else - { - if (lich.ticksExisted > 0) - { - BossStatus.setBossStatus(lich, false); - } - // shield alpha (shield texture already has alpha - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0f); - return 1; - } - - - } else { - return 0; - } - } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(@Nonnull EntityTFLich entity) { + return LICH_TEXTURE; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFMazeSlime.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFMazeSlime.java index 0466dfd276..878025685c 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFMazeSlime.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFMazeSlime.java @@ -1,26 +1,22 @@ package twilightforest.client.renderer.entity; -import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderSlime; -import net.minecraft.entity.Entity; +import net.minecraft.entity.monster.EntitySlime; import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; public class RenderTFMazeSlime extends RenderSlime { - - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "mazeslime.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("mazeslime.png"); - public RenderTFMazeSlime(ModelBase par1ModelBase, ModelBase par2ModelBase, float par3) { - super(par1ModelBase, par2ModelBase, par3); + public RenderTFMazeSlime(RenderManager manager, float shadowSize) { + super(manager); + this.shadowSize = shadowSize; } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(EntitySlime entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFMiniGhast.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFMiniGhast.java deleted file mode 100644 index e9b5e44999..0000000000 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFMiniGhast.java +++ /dev/null @@ -1,49 +0,0 @@ -package twilightforest.client.renderer.entity; - -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.entity.Entity; -import net.minecraft.util.ResourceLocation; -import twilightforest.TwilightForestMod; -import twilightforest.entity.EntityTFTowerGhast; - -public class RenderTFMiniGhast extends RenderLiving { - - final ResourceLocation textureLocClosed; - final ResourceLocation textureLocOpen; - final ResourceLocation textureLocAttack; - - public RenderTFMiniGhast(ModelBase par1ModelBase, float par2) { - super(par1ModelBase, par2); - - textureLocClosed = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerghast.png"); - textureLocOpen = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerghast_openeyes.png"); - textureLocAttack = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerghast_fire.png"); - } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - if (par1Entity instanceof EntityTFTowerGhast) - { - switch (((EntityTFTowerGhast)par1Entity).getAttackStatus()) - { - default: - case 0: - return textureLocClosed; - - case 1: - return textureLocOpen; - - case 2: - return textureLocAttack; - } - } - - // fallback - return textureLocClosed; - } - -} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFMinoshroom.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFMinoshroom.java index 385d27b3a6..63ab7cf8c1 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFMinoshroom.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFMinoshroom.java @@ -1,62 +1,73 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderBiped; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; +import twilightforest.entity.boss.EntityTFMinoshroom; -import org.lwjgl.opengl.GL11; +public class RenderTFMinoshroom extends RenderBiped { -import twilightforest.TwilightForestMod; + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("minoshroomtaur.png"); -public class RenderTFMinoshroom extends RenderBiped { + public RenderTFMinoshroom(RenderManager manager, ModelBiped model, float shadowSize) { + super(manager, model, shadowSize); + this.addLayer(new LayerMinoshroomMushroom()); + } - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "minoshroomtaur.png"); + // TODO fix offsets (currently copypastedfrom LayerMooshroomMushroom) + class LayerMinoshroomMushroom implements LayerRenderer { + @Override + public void doRenderLayer(EntityTFMinoshroom minoshroom, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + if (!minoshroom.isChild() && !minoshroom.isInvisible()) { + BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); + RenderTFMinoshroom.this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + GlStateManager.enableCull(); + GlStateManager.cullFace(GlStateManager.CullFace.FRONT); + GlStateManager.pushMatrix(); + GlStateManager.scale(1.0F, -1.0F, 1.0F); + GlStateManager.translate(0.2F, 0.35F, 0.5F); + GlStateManager.rotate(42.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.pushMatrix(); + GlStateManager.translate(-0.5F, -0.5F, 0.5F); + blockrendererdispatcher.renderBlockBrightness(Blocks.RED_MUSHROOM.getDefaultState(), 1.0F); + GlStateManager.popMatrix(); + GlStateManager.pushMatrix(); + GlStateManager.translate(0.1F, 0.0F, -0.6F); + GlStateManager.rotate(42.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.translate(-0.5F, -0.5F, 0.5F); + blockrendererdispatcher.renderBlockBrightness(Blocks.RED_MUSHROOM.getDefaultState(), 1.0F); + GlStateManager.popMatrix(); + GlStateManager.popMatrix(); + GlStateManager.pushMatrix(); + ((ModelBiped) RenderTFMinoshroom.this.getMainModel()).bipedHead.postRender(0.0625F); + GlStateManager.scale(1.0F, -1.0F, 1.0F); + GlStateManager.translate(0.0F, 1.0F, 0.0F); + GlStateManager.rotate(12.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.translate(-0.5F, -0.5F, 0.5F); + blockrendererdispatcher.renderBlockBrightness(Blocks.RED_MUSHROOM.getDefaultState(), 1.0F); + GlStateManager.popMatrix(); + GlStateManager.cullFace(GlStateManager.CullFace.BACK); + GlStateManager.disableCull(); + } + } + + @Override + public boolean shouldCombineTextures() { + return false; + } + } - public RenderTFMinoshroom(ModelBiped par1ModelBase, float par2) { - super(par1ModelBase, par2); + @Override + protected ResourceLocation getEntityTexture(EntityTFMinoshroom entity) { + return textureLoc; } - - protected void renderMooshroomEquippedItems(EntityLivingBase par1EntityLiving, float par2) - { - super.renderEquippedItems(par1EntityLiving, par2); - - this.bindTexture(TextureMap.locationBlocksTexture); - GL11.glEnable(GL11.GL_CULL_FACE); - GL11.glPushMatrix(); - GL11.glScalef(1.0F, -1.0F, 1.0F); - GL11.glTranslatef(0.2F, 0.375F, 0.5F); - GL11.glRotatef(42.0F, 0.0F, 1.0F, 0.0F); - this.field_147909_c.renderBlockAsItem(Blocks.red_mushroom, 0, 1.0F); - GL11.glTranslatef(0.1F, 0.0F, -0.6F); - GL11.glRotatef(42.0F, 0.0F, 1.0F, 0.0F); - this.field_147909_c.renderBlockAsItem(Blocks.red_mushroom, 0, 1.0F); - GL11.glPopMatrix(); - GL11.glPushMatrix(); - ((ModelBiped)this.mainModel).bipedHead.postRender(0.0625F); - GL11.glScalef(1.0F, -1.0F, 1.0F); - GL11.glTranslatef(0.0F, 1.0F, 0F); - GL11.glRotatef(12.0F, 0.0F, 1.0F, 0.0F); - this.field_147909_c.renderBlockAsItem(Blocks.red_mushroom, 0, 1.0F); - GL11.glPopMatrix(); - GL11.glDisable(GL11.GL_CULL_FACE); - } - - @Override - protected void renderEquippedItems(EntityLivingBase par1EntityLiving, float par2) - { - this.renderMooshroomEquippedItems(par1EntityLiving, par2); - } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFMistWolf.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFMistWolf.java index c653e9d2a8..fdce9c7858 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFMistWolf.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFMistWolf.java @@ -1,69 +1,56 @@ package twilightforest.client.renderer.entity; -import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderWolf; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.passive.EntityWolf; import net.minecraft.util.ResourceLocation; - import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; public class RenderTFMistWolf extends RenderWolf { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "mistwolf.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("mistwolf.png"); - public RenderTFMistWolf(ModelBase par1ModelBase, ModelBase par2ModelBase, float par3) { - super(par1ModelBase, par2ModelBase, par3); + public RenderTFMistWolf(RenderManager manager) { + super(manager); + this.shadowSize = 1.0F; } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLiving, float par2) - { - float wolfScale = 1.9F; - GL11.glScalef(wolfScale, wolfScale, wolfScale); - - GL11.glEnable(3042 /*GL_BLEND*/); - GL11.glDisable(3008 /*GL_ALPHA_TEST*/); - //GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - //GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_ALPHA, GL11.GL_DST_ALPHA); - - float misty = par1EntityLiving.getBrightness(0F) * 3F + 0.25F; - misty = Math.min(1F, misty); + @Override + protected void preRenderCallback(EntityWolf entity, float partialTicks) { + float wolfScale = 1.9F; + GlStateManager.scale(wolfScale, wolfScale, wolfScale); - float smoky = par1EntityLiving.getBrightness(0F) * 2F + 0.6F; + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + //GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_ONE); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + //GlStateManager.blendFunc(GL11.GL_ONE_MINUS_DST_ALPHA, GL11.GL_DST_ALPHA); - //System.out.println("Misty value is " + misty); - - GL11.glColor4f(misty, misty, misty, smoky); + float misty = entity.getBrightness() * 3F + 0.25F; + misty = Math.min(1F, misty); - } - - /** - * Queries whether should render the specified pass or not. - */ - protected int shouldRenderPass(EntityLivingBase par1EntityLiving, int par2, float par3) - { -// GL11.glFogf(GL11.GL_FOG_START, 1.0f); -// GL11.glFogf(GL11.GL_FOG_END, 5.0f); - + float smoky = entity.getBrightness() * 2F + 0.6F; + + GlStateManager.color(misty, misty, misty, smoky); + } - - return -1; - } - /** - * Return our specific texture + * Queries whether should render the specified pass or not. */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } - + protected int shouldRenderPass(EntityLivingBase par1EntityLiving, int par2, float par3) { +// GL11.glFogf(GL11.GL_FOG_START, 1.0f); +// GL11.glFogf(GL11.GL_FOG_END, 5.0f); + + + return -1; + } + + @Override + protected ResourceLocation getEntityTexture(EntityWolf entity) { + return textureLoc; + } + } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFMobileFirefly.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFMobileFirefly.java new file mode 100644 index 0000000000..0604a596ee --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFMobileFirefly.java @@ -0,0 +1,79 @@ +package twilightforest.client.renderer.entity; + +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; +import twilightforest.TwilightForestMod; +import twilightforest.client.model.entity.ModelTFTinyFirefly; +import twilightforest.entity.passive.EntityTFMobileFirefly; + +import java.nio.FloatBuffer; + +public class RenderTFMobileFirefly extends Render { + + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("firefly-tiny.png"); + private final ModelTFTinyFirefly fireflyModel = new ModelTFTinyFirefly(); + + public RenderTFMobileFirefly(RenderManager manager) { + super(manager); + } + + private void doRenderTinyFirefly(EntityTFMobileFirefly firefly, double x, double y, double z, float brightness, float size) { + GlStateManager.pushMatrix(); + + GlStateManager.translate((float) x, (float) y + 0.5F, (float) z); + + // undo rotations so we can draw a billboarded firefly + FloatBuffer modelview = BufferUtils.createFloatBuffer(16); + + GlStateManager.getFloat(GL11.GL_MODELVIEW_MATRIX, modelview); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + int index = i * 4 + j; + if (i == j) { + modelview.put(index, 1.0f); + } else { + modelview.put(index, 0.0f); + } + } + } + + GL11.glLoadMatrix(modelview); + + bindEntityTexture(firefly); + + GlStateManager.colorMask(true, true, true, true); + + // render the firefly glow + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.enableAlpha(); + GlStateManager.disableLighting(); + + +// GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + GlStateManager.color(1.0F, 1.0F, 1.0F, brightness); + fireflyModel.glow1.render(0.0625f * size); + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.popMatrix(); + } + + + @Override + public void doRender(EntityTFMobileFirefly firefly, double x, double y, double z, float yaw, float partialTicks) { + doRenderTinyFirefly(firefly, x, y, z, firefly.getGlowBrightness(), 1.0F); + } + + @Override + protected ResourceLocation getEntityTexture(EntityTFMobileFirefly entity) { + return textureLoc; + } + +} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFMoonwormShot.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFMoonwormShot.java index 2c93aa91de..8fa5eee495 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFMoonwormShot.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFMoonwormShot.java @@ -1,52 +1,38 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.entity.Entity; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFMoonworm; - -public class RenderTFMoonwormShot extends Render { +import twilightforest.client.model.entity.ModelTFMoonworm; +import twilightforest.entity.EntityTFMoonwormShot; - private ModelTFMoonworm wormModel; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "moonworm.png"); +public class RenderTFMoonwormShot extends Render { + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("moonworm.png"); + private final ModelTFMoonworm wormModel = new ModelTFMoonworm(); - public RenderTFMoonwormShot() - { - wormModel = new ModelTFMoonworm(); - this.shadowSize = 0.5F; - } + public RenderTFMoonwormShot(RenderManager manager) { + super(manager); + this.shadowSize = 0.5F; + } - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { -public class RenderTFNaga extends RenderLiving { - - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "nagahead.png"); - - public RenderTFNaga(ModelBase modelbase, float f) { - super(modelbase, f); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("nagahead.png"); + + public RenderTFNaga(RenderManager manager, ModelBase modelbase, float shadowSize) { + super(manager, modelbase, shadowSize); + this.addLayer(new NagaEyelidsLayer(this)); } - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { - private ModelBase model; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "nagasegment.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("nagasegment.png"); + private final ModelBase model; - public RenderTFNagaSegment(ModelBase model, float f) { + public RenderTFNagaSegment(RenderManager manager, ModelBase model) { + super(manager); this.model = model; } - /** - * The render method used in RenderBoat that renders the boat model. - */ - public void renderMe(Entity par1Entity, double par2, double par4, double par6, float par8, float time) - { - GL11.glPushMatrix(); - GL11.glTranslatef((float)par2, (float)par4, (float)par6); - GL11.glRotatef(180 - MathHelper.wrapAngleTo180_float(par8), 0.0F, 1.0F, 0.0F); - - // pitch - float pitch = par1Entity.prevRotationPitch + (par1Entity.rotationPitch - par1Entity.prevRotationPitch) * time; - - GL11.glRotatef(pitch, 1.0F, 0.0F, 0.0F); - - -// float f4 = 0.75F; -// GL11.glScalef(f4, f4, f4); -// GL11.glScalef(1.0F / f4, 1.0F / f4, 1.0F / f4); - //this.loadTexture(par1Entity.getTexture()); - this.bindTexture(textureLoc); - - - GL11.glScalef(-1.0F, -1.0F, 1.0F); - this.model.render(par1Entity, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F); - GL11.glPopMatrix(); - } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render 180) { + yawDiff -= 360; + } else if (yawDiff < -180) { + yawDiff += 360; + } + float yaw = entity.prevRotationYaw + yawDiff * partialTicks; + + GlStateManager.rotate(yaw, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(entity.rotationPitch, 1.0F, 0.0F, 0.0F); + this.bindTexture(textureLoc); + this.model.render(entity, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F); + GlStateManager.popMatrix(); + } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + @Override + protected ResourceLocation getEntityTexture(EntityTFNagaSegment entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFProtectionBox.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFProtectionBox.java index bebb691656..0f6f991faf 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFProtectionBox.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFProtectionBox.java @@ -1,93 +1,76 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; - import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFProtectionBox; +import twilightforest.client.model.entity.ModelTFProtectionBox; import twilightforest.entity.EntityTFProtectionBox; -public class RenderTFProtectionBox extends Render { - +public class RenderTFProtectionBox extends Render { + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("protectionbox.png"); + private final ModelTFProtectionBox boxModel = new ModelTFProtectionBox(); - private ModelTFProtectionBox boxModel; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "protectionbox.png"); + public RenderTFProtectionBox(RenderManager manager) { + super(manager); + this.shadowSize = 0.5F; + } - public RenderTFProtectionBox() - { - this.boxModel = new ModelTFProtectionBox(); - this.shadowSize = 0.5F; - } - @Override - public void doRender(Entity var1, double x, double y, double z, float var8, float partialTick) { - GL11.glPushMatrix(); - - - GL11.glTranslatef((float)x, (float)y, (float)z); - - this.bindTexture(textureLoc); - - // move texture - float f1 = (float)var1.ticksExisted + partialTick; - GL11.glMatrixMode(GL11.GL_TEXTURE); - GL11.glLoadIdentity(); - float f2 = f1 * 0.05F; - float f3 = f1 * 0.05F; - GL11.glTranslatef(f2, f3, 0.0F); - GL11.glScalef(1.0f, 1.0f, 1.0f); - - GL11.glMatrixMode(GL11.GL_MODELVIEW); - - // enable transparency, go full brightness - GL11.glColorMask(true, true, true, true); - GL11.glEnable(GL11.GL_BLEND); - GL11.glDisable(GL11.GL_CULL_FACE); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GL11.glDisable(GL11.GL_ALPHA_TEST); - GL11.glDisable(GL11.GL_LIGHTING); - - float alpha = 1.0F; - if (((EntityTFProtectionBox)var1).lifeTime < 20) { - alpha = ((EntityTFProtectionBox)var1).lifeTime / 20F; - } - - GL11.glColor4f(1.0F, 1.0F, 1.0F, alpha); - - boxModel.render(var1, 0F, 0F, 0F, 0F, 0F, 1F / 16F); - - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_CULL_FACE); - - GL11.glMatrixMode(GL11.GL_TEXTURE); - GL11.glLoadIdentity(); - GL11.glMatrixMode(GL11.GL_MODELVIEW); - - GL11.glPopMatrix(); + public void doRender(EntityTFProtectionBox entity, double x, double y, double z, float yaw, float partialTicks) { + GlStateManager.pushMatrix(); + + + GlStateManager.translate((float) x, (float) y, (float) z); + + this.bindTexture(textureLoc); + + // move texture + float f1 = (float) entity.ticksExisted + partialTicks; + GlStateManager.matrixMode(GL11.GL_TEXTURE); + GlStateManager.loadIdentity(); + float f2 = f1 * 0.05F; + float f3 = f1 * 0.05F; + GlStateManager.translate(f2, f3, 0.0F); + GlStateManager.scale(1.0f, 1.0f, 1.0f); + + GlStateManager.matrixMode(GL11.GL_MODELVIEW); + + // enable transparency, go full brightness + GlStateManager.colorMask(true, true, true, true); + GlStateManager.enableBlend(); + GlStateManager.disableCull(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.disableAlpha(); + GlStateManager.disableLighting(); + + float alpha = 1.0F; + if (entity.lifeTime < 20) { + alpha = entity.lifeTime / 20F; + } + + GlStateManager.color(1.0F, 1.0F, 1.0F, alpha); + + boxModel.render(entity, 0F, 0F, 0F, 0F, 0F, 1F / 16F); + + GlStateManager.disableBlend(); + GlStateManager.enableCull(); + GlStateManager.enableAlpha(); + GlStateManager.enableLighting(); + + GlStateManager.matrixMode(GL11.GL_TEXTURE); + GlStateManager.loadIdentity(); + GlStateManager.matrixMode(GL11.GL_MODELVIEW); + + GlStateManager.popMatrix(); } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLiving, float par2) - { - float scale = 1.0F; - GL11.glScalef(scale, scale, scale); - } - - /** - * Return our specific texture - */ + @Override - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + protected ResourceLocation getEntityTexture(EntityTFProtectionBox entity) { + return textureLoc; + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFQuestRam.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFQuestRam.java index 300765ed0a..7372d97870 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFQuestRam.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFQuestRam.java @@ -1,70 +1,55 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; import net.minecraft.util.ResourceLocation; - import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFQuestRam; +import twilightforest.client.model.entity.ModelTFQuestRam; import twilightforest.entity.passive.EntityTFQuestRam; -public class RenderTFQuestRam extends RenderLiving { +public class RenderTFQuestRam extends RenderLiving { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "questram.png"); - private static final ResourceLocation textureLocLines = new ResourceLocation(TwilightForestMod.MODEL_DIR + "questram_lines.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("questram.png"); + private static final ResourceLocation textureLocLines = TwilightForestMod.getModelTexture("questram_lines.png"); - public RenderTFQuestRam() { - super(new ModelTFQuestRam(), 1.0F); - this.setRenderPassModel(new ModelTFQuestRam()); + public RenderTFQuestRam(RenderManager manager) { + super(manager, new ModelTFQuestRam(), 1.0F); + addLayer(new LayerGlowingLines()); } + @Override + protected ResourceLocation getEntityTexture(EntityTFQuestRam entity) { + return textureLoc; + } - /** - * Sets the ram's glowing lines - */ - protected int setQuestRamLineBrightness(EntityTFQuestRam par1EntityQuestRam, int par2, float par3) - { - if (par2 != 0) - { - return -1; - } - else - { - this.bindTexture(textureLocLines); - float var4 = 1.0F; - GL11.glEnable(GL11.GL_BLEND); - GL11.glDisable(GL11.GL_ALPHA_TEST); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); - GL11.glScalef(1.025f, 1.025f, 1.025f); - char var5 = 61680; - int var6 = var5 % 65536; - int var7 = var5 / 65536; - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)var6 / 1.0F, (float)var7 / 1.0F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glColor4f(1.0F, 1.0F, 1.0F, var4); - return 1; - } - } - - /** - * Queries whether should render the specified pass or not. - */ - protected int shouldRenderPass(EntityLivingBase par1EntityLiving, int par2, float par3) - { - return this.setQuestRamLineBrightness((EntityTFQuestRam)par1EntityLiving, par2, par3); - } + // todo verify / cleanup gl state? + class LayerGlowingLines implements LayerRenderer { + @Override + public void doRenderLayer(EntityTFQuestRam entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + RenderTFQuestRam.this.bindTexture(textureLocLines); + float var4 = 1.0F; + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + GlStateManager.scale(1.025f, 1.025f, 1.025f); + char var5 = 61680; + int var6 = var5 % 65536; + int var7 = var5 / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var6 / 1.0F, (float) var7 / 1.0F); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.color(1.0F, 1.0F, 1.0F, var4); + RenderTFQuestRam.this.getMainModel().render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } + + @Override + public boolean shouldCombineTextures() { + return false; + } + } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } - } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFRovingCube.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFRovingCube.java index 6d379faa96..5e015f7e16 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFRovingCube.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFRovingCube.java @@ -1,76 +1,51 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; - +import net.minecraft.util.math.MathHelper; import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFCubeOfAnnihilation; -import twilightforest.client.model.ModelTFHydraMortar; -import twilightforest.entity.EntityTFBlockGoblin; -import twilightforest.entity.EntityTFChainBlock; +import twilightforest.client.model.entity.ModelTFCubeOfAnnihilation; +import twilightforest.entity.EntityTFRovingCube; -public class RenderTFRovingCube extends Render { +public class RenderTFRovingCube extends Render { - private ModelBase model; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "cubeofannihilation.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("cubeofannihilation.png"); + private final ModelBase model = new ModelTFCubeOfAnnihilation(); - public RenderTFRovingCube() { - this.model = new ModelTFCubeOfAnnihilation(); + public RenderTFRovingCube(RenderManager manager) { + super(manager); } - /** - * The render method used in RenderBoat that renders the boat model. - */ - public void renderSpikeBlock(Entity entity, double x, double y, double z, float par8, float time) - { - GL11.glPushMatrix(); - GL11.glTranslatef((float)x, (float)y, (float)z); + @Override + public void doRender(EntityTFRovingCube entity, double x, double y, double z, float yaw, float partialTicks) { + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); - this.bindEntityTexture(entity); + this.bindEntityTexture(entity); - GL11.glScalef(2.0F, 2.0F, 2.0F); - - // rotate - GL11.glRotatef(MathHelper.wrapAngleTo180_float(((float)x + (float)z + entity.ticksExisted + time) * 11F), 0, 1, 0); - + GlStateManager.scale(2.0F, 2.0F, 2.0F); - GL11.glDisable(GL11.GL_LIGHTING); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - GL11.glTranslatef(0F, 0.75F, 0F); - this.model.render(entity, 0.0F, 0.0F, 0.0F, 0.0F, time, 0.0625F / 2F); - GL11.glEnable(GL11.GL_LIGHTING); - GL11.glDisable(GL11.GL_BLEND); + GlStateManager.rotate(MathHelper.wrapDegrees(((float) x + (float) z + ((Entity) entity).ticksExisted + partialTicks) * 11F), 0, 1, 0); - - GL11.glPopMatrix(); - } + GlStateManager.disableLighting(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { -public class RenderTFSlideBlock extends Render { - - private final RenderBlocks renderBlocks = new RenderBlocks(); - - public RenderTFSlideBlock() { - } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { - /** - * Queries whether should render the specified pass or not. - */ - protected int shouldRenderPass(EntityLivingBase par1EntityLiving, int par2, float par3) - { - return this.shouldSlimeRenderPass((EntityLivingBase)par1EntityLiving, par2, par3); - } + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("slimebeetle.png"); + public RenderTFSlimeBeetle(RenderManager manager, ModelBase par1ModelBase, float shadowSize) { + super(manager, par1ModelBase, shadowSize); + addLayer(new LayerInner()); + } - /** - * Determines whether Slime Render should pass or not. - */ - protected int shouldSlimeRenderPass(EntityLivingBase par1EntitySlime, int par2, float par3) - { - if (par1EntitySlime.isInvisible()) - { - return 0; - } - else if (par2 == 0) - { - this.setRenderPassModel(this.renderModel); - GL11.glEnable(GL11.GL_NORMALIZE); - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - return 1; - } - else - { - if (par2 == 1) - { - GL11.glDisable(GL11.GL_BLEND); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - } + @Override + protected ResourceLocation getEntityTexture(EntityTFSlimeBeetle entity) { + return textureLoc; + } - return -1; - } - } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } + class LayerInner implements LayerRenderer { + private final ModelBase innerModel = new ModelTFSlimeBeetle(true); + + @Override + public void doRenderLayer(EntityTFSlimeBeetle entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + if (!entity.isInvisible()) { + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.enableNormalize(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + this.innerModel.setModelAttributes(RenderTFSlimeBeetle.this.getMainModel()); + this.innerModel.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + GlStateManager.disableBlend(); + GlStateManager.disableNormalize(); + } + } + + @Override + public boolean shouldCombineTextures() { + return true; + } + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowGuardian.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowGuardian.java index 171eb5f062..8eca521334 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowGuardian.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowGuardian.java @@ -1,26 +1,22 @@ package twilightforest.client.renderer.entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerBipedArmor; +import net.minecraft.util.math.MathHelper; +import twilightforest.client.model.entity.ModelTFSnowGuardian; +import twilightforest.entity.EntityTFSnowGuardian; -import org.lwjgl.opengl.GL11; +public class RenderTFSnowGuardian extends RenderTFBiped { -import twilightforest.client.model.ModelTFSnowGuardian; - -public class RenderTFSnowGuardian extends RenderTFBiped { - - public RenderTFSnowGuardian() { - super(new ModelTFSnowGuardian(), 1.0F, "textures/entity/zombie/zombie.png"); + public RenderTFSnowGuardian(RenderManager manager) { + super(manager, new ModelTFSnowGuardian(), 0.25F, "textures/entity/zombie/zombie.png"); + this.addLayer(new LayerBipedArmor(this)); } - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float partialTick) - { - float bounce = par1EntityLivingBase.ticksExisted + partialTick; - - GL11.glTranslatef(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); - } + @Override + protected void preRenderCallback(EntityTFSnowGuardian entity, float partialTicks) { + float bounce = entity.ticksExisted + partialTicks; + GlStateManager.translate(0F, MathHelper.sin((bounce) * 0.2F) * 0.15F, 0F); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueen.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueen.java index ceb404b830..73ecde1641 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueen.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueen.java @@ -1,58 +1,38 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderBiped; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.boss.BossStatus; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFSnowQueen; +import twilightforest.client.model.entity.ModelTFSnowQueen; import twilightforest.entity.boss.EntityTFSnowQueen; -public class RenderTFSnowQueen extends RenderBiped { +public class RenderTFSnowQueen extends RenderBiped { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "snowqueen.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("snowqueen.png"); - public RenderTFSnowQueen() { - super(new ModelTFSnowQueen(), 0.625F); + public RenderTFSnowQueen(RenderManager manager) { + super(manager, new ModelTFSnowQueen(), 0.625F); } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = 1.2F; - GL11.glScalef(scale, scale, scale); - } - - /** - * Render the queen and shield - */ @Override - public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) { + protected ResourceLocation getEntityTexture(EntityTFSnowQueen entity) { + return textureLoc; + } - EntityTFSnowQueen queen = (EntityTFSnowQueen)entity; - - BossStatus.setBossStatus(queen, false); + @Override + protected void preRenderCallback(EntityTFSnowQueen queen, float partialTicks) { + float scale = 1.2F; + GlStateManager.scale(scale, scale, scale); + } + + @Override + public void doRender(EntityTFSnowQueen queen, double x, double y, double z, float yaw, float partialTicks) { + super.doRender(queen, x, y, z, yaw, partialTicks); - super.doRender(entity, d, d1, d2, f, f1); - for (int i = 0; i < queen.iceArray.length; i++) { - RenderManager.instance.renderEntitySimple(queen.iceArray[i], f1); + renderManager.renderEntityStatic(queen.iceArray[i], partialTicks, false); } } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueenIceShield.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueenIceShield.java index b106da2240..84d9240cf1 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueenIceShield.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFSnowQueenIceShield.java @@ -1,61 +1,72 @@ package twilightforest.client.renderer.entity; -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.entity.Entity; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; - import org.lwjgl.opengl.GL11; - import twilightforest.entity.boss.EntityTFSnowQueenIceShield; -public class RenderTFSnowQueenIceShield extends Render { +public class RenderTFSnowQueenIceShield extends Render { - private final RenderBlocks renderBlocks = new RenderBlocks(); + public RenderTFSnowQueenIceShield(RenderManager manager) { + super(manager); + } + // [VanillaCopy] RenderFallingBlock.doRender with hardcoded state @Override - public void doRender(Entity var1, double var2, double var4, double var6, float var8, float var9) { - this.doRender((EntityTFSnowQueenIceShield)var1, var2, var4, var6, var8, var9); + public void doRender(EntityTFSnowQueenIceShield entity, double x, double y, double z, float entityYaw, float partialTicks) { + IBlockState iblockstate = Blocks.PACKED_ICE.getDefaultState(); + + if (iblockstate.getRenderType() == EnumBlockRenderType.MODEL) { + World world = entity.world; + + if (iblockstate != world.getBlockState(new BlockPos(entity)) && iblockstate.getRenderType() != EnumBlockRenderType.INVISIBLE) { + this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + GlStateManager.pushMatrix(); + GlStateManager.disableLighting(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + + if (this.renderOutlines) { + GlStateManager.enableColorMaterial(); + GlStateManager.enableOutlineMode(this.getTeamColor(entity)); + } + + bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + BlockPos blockpos = new BlockPos(entity.posX, entity.getEntityBoundingBox().maxY, entity.posZ); + GlStateManager.translate((float) (x - (double) blockpos.getX() - 0.5D), (float) (y - (double) blockpos.getY()), (float) (z - (double) blockpos.getZ() - 0.5D)); + BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); + blockrendererdispatcher.getBlockModelRenderer().renderModel(world, blockrendererdispatcher.getModelForState(iblockstate), iblockstate, blockpos, bufferbuilder, false, MathHelper.getPositionRandom(BlockPos.ORIGIN)); + tessellator.draw(); + + if (this.renderOutlines) { + GlStateManager.disableOutlineMode(); + GlStateManager.disableColorMaterial(); + } + + GlStateManager.enableLighting(); + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + } } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { - private ModelBase model; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "blockgoblin.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("blockgoblin.png"); + private final ModelBase model; - public RenderTFSpikeBlock(ModelBase modelTFSpikeBlock, float f) { + public RenderTFSpikeBlock(RenderManager manager, ModelBase modelTFSpikeBlock) { + super(manager); this.model = modelTFSpikeBlock; } - /** - * The render method used in RenderBoat that renders the boat model. - */ - public void renderSpikeBlock(Entity par1Entity, double par2, double par4, double par6, float par8, float time) - { - GL11.glPushMatrix(); - GL11.glTranslatef((float)par2, (float)par4, (float)par6); - GL11.glRotatef(180 - MathHelper.wrapAngleTo180_float(par8), 0.0F, 1.0F, 0.0F); - - // pitch - float pitch = par1Entity.prevRotationPitch + (par1Entity.rotationPitch - par1Entity.prevRotationPitch) * time; - - GL11.glRotatef(pitch, 1.0F, 0.0F, 0.0F); + @Override + public void doRender(Entity entity, double x, double y, double z, float yaw, float partialTicks) { + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); + GlStateManager.rotate(180 - MathHelper.wrapDegrees(yaw), 0.0F, 1.0F, 0.0F); + float pitch = entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks; -// float f4 = 0.75F; -// GL11.glScalef(f4, f4, f4); -// GL11.glScalef(1.0F / f4, 1.0F / f4, 1.0F / f4); -// this.loadTexture(par1Entity.getTexture()); - - this.bindEntityTexture(par1Entity); - - GL11.glScalef(-1.0F, -1.0F, 1.0F); - this.model.render(par1Entity, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F); - GL11.glPopMatrix(); - } + GlStateManager.rotate(pitch, 1.0F, 0.0F, 0.0F); + this.bindEntityTexture(entity); - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { -public class RenderTFSwarmSpider extends RenderSpider { + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("swarmspider.png"); - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "swarmspider.png"); + public RenderTFSwarmSpider(RenderManager manager) { + super(manager); + } @Override - protected ResourceLocation getEntityTexture(Entity entity) { + protected ResourceLocation getEntityTexture(EntityTFSwarmSpider entity) { return textureLoc; } - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = 0.5F; - GL11.glScalef(scale, scale, scale); - } + @Override + protected void preRenderCallback(EntityTFSwarmSpider entity, float partialTicks) { + float scale = 0.5F; + GlStateManager.scale(scale, scale, scale); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFThrownAxe.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFThrownAxe.java deleted file mode 100644 index acd8613e6e..0000000000 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFThrownAxe.java +++ /dev/null @@ -1,104 +0,0 @@ -package twilightforest.client.renderer.entity; - -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.entity.RenderItem; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.item.Item; -import net.minecraft.util.IIcon; -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL12; - - -public class RenderTFThrownAxe extends RenderItem { - - Item myItem; - - public RenderTFThrownAxe(Item knightlyAxe) { - this.myItem = knightlyAxe; - } - - @Override - public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9) { - - GL11.glPushMatrix(); - //GL11.glScalef(1.25F, 1.25F, 1.25F); - - float spin = (entity.ticksExisted + par9) * -10F + 90F; - - this.doRenderItem(null, par2, par4, par6, par8, spin); - - GL11.glPopMatrix(); - - } - - /** - * Renders the item - */ - public void doRenderItem(EntityItem par1EntityItem, double x, double y, double z, float rotation, float spin) - { - GL11.glPushMatrix(); - - GL11.glTranslatef((float)x, (float)y, (float)z); - GL11.glEnable(GL12.GL_RESCALE_NORMAL); - - // size up - GL11.glScalef(1.25F, 1.25F, 1.25F); - - IIcon icon1 = this.myItem.getIconFromDamage(0); - - this.renderDroppedItem(icon1, rotation, spin); - - GL11.glDisable(GL12.GL_RESCALE_NORMAL); - GL11.glPopMatrix(); - } - - - private void renderDroppedItem(IIcon par2Icon, float rotation, float spin) - { - Tessellator tessellator = Tessellator.instance; - - float f9 = 0.5F; - float f10 = 0.25F; - - GL11.glPushMatrix(); - - GL11.glRotatef(rotation + 270f, 0.0F, 1.0F, 0.0F); - GL11.glRotatef(spin, 0.0F, 0.0F, 1.0F); - - float f12 = 0.0625F; - float f11 = 0.021875F; - - - GL11.glTranslatef(-f9, -f10, -(f12 + f11)); - - GL11.glTranslatef(0f, 0f, f12 + f11); - - this.bindTexture(TextureMap.locationItemsTexture); - - //GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - ItemRenderer.renderItemIn2D(tessellator, par2Icon.getMaxU(), par2Icon.getMinV(), par2Icon.getMinU(), par2Icon.getMaxV(), par2Icon.getIconWidth(), par2Icon.getIconHeight(), f12); - - - GL11.glPopMatrix(); - } - - @Override - protected ResourceLocation getEntityTexture(Entity entity) { - return this.renderManager.renderEngine.getResourceLocation(this.myItem.getSpriteNumber()); - } - - - /** - * Items should have a bob effect - * @return - */ - public boolean shouldBob() - { - return false; - } -} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFThrownIce.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFThrownIce.java index 406421d99a..7be91ab90a 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFThrownIce.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFThrownIce.java @@ -1,60 +1,74 @@ package twilightforest.client.renderer.entity; -import net.minecraft.block.Block; -import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; - import org.lwjgl.opengl.GL11; - import twilightforest.entity.boss.EntityTFIceBomb; -public class RenderTFThrownIce extends Render { +// [VanillaCopy] direct of RenderFallingBlock because of generic type restrictions +public class RenderTFThrownIce extends Render { - private final RenderBlocks renderBlocks = new RenderBlocks(); + public RenderTFThrownIce(RenderManager manager) { + super(manager); + this.shadowSize = 0.5F; + } @Override - public void doRender(Entity var1, double var2, double var4, double var6, float var8, float var9) { - this.doRender((EntityTFIceBomb)var1, var2, var4, var6, var8, var9); + public void doRender(EntityTFIceBomb entity, double x, double y, double z, float entityYaw, float partialTicks) { + if (entity.getBlock() != null) { + IBlockState iblockstate = entity.getBlock(); + + if (iblockstate.getRenderType() == EnumBlockRenderType.MODEL) { + World world = entity.world; + + if (iblockstate != world.getBlockState(new BlockPos(entity)) && iblockstate.getRenderType() != EnumBlockRenderType.INVISIBLE) { + this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + GlStateManager.pushMatrix(); + GlStateManager.disableLighting(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + + if (this.renderOutlines) { + GlStateManager.enableColorMaterial(); + GlStateManager.enableOutlineMode(this.getTeamColor(entity)); + } + + bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + BlockPos blockpos = new BlockPos(entity.posX, entity.getEntityBoundingBox().maxY, entity.posZ); + GlStateManager.translate((float) (x - (double) blockpos.getX() - 0.5D), (float) (y - (double) blockpos.getY()), (float) (z - (double) blockpos.getZ() - 0.5D)); + BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); + blockrendererdispatcher.getBlockModelRenderer().renderModel(world, blockrendererdispatcher.getModelForState(iblockstate), iblockstate, blockpos, bufferbuilder, false, MathHelper.getPositionRandom(BlockPos.ORIGIN)); + tessellator.draw(); + + if (this.renderOutlines) { + GlStateManager.disableOutlineMode(); + GlStateManager.disableColorMaterial(); + } + + GlStateManager.enableLighting(); + GlStateManager.popMatrix(); + super.doRender(entity, x, y, z, entityYaw, partialTicks); + } + } + } } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render { + + public RenderTFThrownWep(RenderManager manager) { + super(manager); + } + + @Override + public void doRender(EntityTFThrownWep entity, double x, double y, double z, float yaw, float partialTicks) { + + GlStateManager.pushMatrix(); + + float spin = (entity.ticksExisted + partialTicks) * -10F + 90F; + + + GlStateManager.translate((float) x, (float) y, (float) z); + GlStateManager.enableRescaleNormal(); + + // size up + GlStateManager.scale(1.25F, 1.25F, 1.25F); + + this.renderDroppedItem(entity.getItem(), yaw, spin); + + GlStateManager.disableRescaleNormal(); + GlStateManager.popMatrix(); + } + + // todo recheck transformations + private void renderDroppedItem(ItemStack stack, float rotation, float spin) { + GlStateManager.pushMatrix(); + + float f9 = 0.5F; + float f10 = 0.25F; + + GlStateManager.rotate(rotation + 270f, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(spin, 0.0F, 0.0F, 1.0F); + + float f12 = 0.0625F; + float f11 = 0.021875F; + + GlStateManager.translate(-f9, -f10, -(f12 + f11)); + GlStateManager.translate(0f, 0f, f12 + f11); + + Minecraft.getMinecraft().getRenderItem().renderItem(stack, ItemCameraTransforms.TransformType.GROUND); + + GlStateManager.popMatrix(); + } + + @Override + protected ResourceLocation getEntityTexture(EntityTFThrownWep entity) { + return TextureMap.LOCATION_BLOCKS_TEXTURE; + } +} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFTinyBird.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFTinyBird.java index e3319887c4..f8b9106886 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFTinyBird.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFTinyBird.java @@ -1,50 +1,40 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBase; -import net.minecraft.entity.Entity; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; +import twilightforest.entity.passive.EntityTFBird; import twilightforest.entity.passive.EntityTFTinyBird; public class RenderTFTinyBird extends RenderTFBird { - - final ResourceLocation textureLocSparrow; - final ResourceLocation textureLocFinch; - final ResourceLocation textureLocCardinal; - final ResourceLocation textureLocBluebird; + private static final ResourceLocation textureLocSparrow = TwilightForestMod.getModelTexture("tinybirdbrown.png"); + private static final ResourceLocation textureLocFinch = TwilightForestMod.getModelTexture("tinybirdgold.png"); + private static final ResourceLocation textureLocCardinal = TwilightForestMod.getModelTexture("tinybirdred.png"); + private static final ResourceLocation textureLocBluebird = TwilightForestMod.getModelTexture("tinybirdblue.png"); - public RenderTFTinyBird(ModelBase par1ModelBase, float par2) { - super(par1ModelBase, par2, "tinybirdbrown.png"); - - textureLocSparrow = new ResourceLocation(TwilightForestMod.MODEL_DIR + "tinybirdbrown.png"); - textureLocFinch = new ResourceLocation(TwilightForestMod.MODEL_DIR + "tinybirdgold.png"); - textureLocCardinal = new ResourceLocation(TwilightForestMod.MODEL_DIR + "tinybirdred.png"); - textureLocBluebird = new ResourceLocation(TwilightForestMod.MODEL_DIR + "tinybirdblue.png"); + public RenderTFTinyBird(RenderManager manager, ModelBase model, float shadowSize) { + super(manager, model, shadowSize, ""); } - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - if (par1Entity instanceof EntityTFTinyBird) - { - switch (((EntityTFTinyBird)par1Entity).getBirdType()) - { - default: - case 0: - return textureLocSparrow; - case 1: - return textureLocBluebird; - case 2: - return textureLocCardinal; - case 3: - return textureLocFinch; + @Override + protected ResourceLocation getEntityTexture(EntityTFBird entity) { + if (entity instanceof EntityTFTinyBird) { + switch (((EntityTFTinyBird) entity).getBirdType()) { + default: + case 0: + return textureLocSparrow; + case 1: + return textureLocBluebird; + case 2: + return textureLocCardinal; + case 3: + return textureLocFinch; } } // fallback return textureLocSparrow; - } + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFTinyFirefly.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFTinyFirefly.java deleted file mode 100644 index d6337d4c48..0000000000 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFTinyFirefly.java +++ /dev/null @@ -1,119 +0,0 @@ -package twilightforest.client.renderer.entity; - -import java.nio.FloatBuffer; - -import net.minecraft.client.renderer.entity.Render; -import net.minecraft.entity.Entity; -import net.minecraft.util.ResourceLocation; - -import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.GL11; - -import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFTinyFirefly; -import twilightforest.entity.passive.EntityTFMobileFirefly; -import twilightforest.entity.passive.EntityTFTinyFirefly; - - - - -public class RenderTFTinyFirefly extends Render { - - ModelTFTinyFirefly fireflyModel; - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "firefly-tiny.png"); - - public RenderTFTinyFirefly() - { - fireflyModel = new ModelTFTinyFirefly(); - } - - - /** - * Draw a cute firefly! - * - * @param firefly - * @param x - * @param y - * @param z - * @param f - * @param f1 - */ - public void doRenderTinyFirefly(EntityTFTinyFirefly firefly, double x, double y, double z, float brightness, float size) { - - GL11.glPushMatrix(); - - GL11.glTranslatef((float)x, (float)y + 0.5F, (float)z); - - // undo rotations so we can draw a billboarded firefly - FloatBuffer modelview = BufferUtils.createFloatBuffer(16); - - GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelview); - - for(int i=0; i<3; i++ ) { - for(int j=0; j<3; j++ ) { - int index = i * 4 + j; - if ( i==j ) { - modelview.put(index, 1.0f); - } else { - modelview.put(index, 0.0f); - } - } - } - - GL11.glLoadMatrix(modelview); - - //loadTexture(TwilightForestMod.MODEL_DIR + "firefly-tiny.png"); - this.renderManager.renderEngine.bindTexture(textureLoc); - - GL11.glColorMask(true, true, true, true); - - // render the firefly glow - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GL11.glEnable(GL11.GL_ALPHA_TEST); - - GL11.glDisable(GL11.GL_LIGHTING); - - -// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); - GL11.glColor4f(1.0F, 1.0F, 1.0F, brightness); - fireflyModel.glow1.render(0.0625f * size); - GL11.glDisable(GL11.GL_BLEND); - GL11.glEnable(GL11.GL_LIGHTING); - - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glPopMatrix(); - } - - - - @Override - public void doRender(Entity entity, double d, double d1, double d2, float f, float f1) { - - if (entity instanceof EntityTFTinyFirefly) - { - EntityTFTinyFirefly firefly = (EntityTFTinyFirefly)entity; - - doRenderTinyFirefly(firefly, d, d1, d2, firefly.getGlowBrightness(), firefly.glowSize); - - } - else if (entity instanceof EntityTFMobileFirefly) - { - EntityTFMobileFirefly firefly = (EntityTFMobileFirefly)entity; - - - doRenderTinyFirefly(null, d, d1, d2, firefly.getGlowBrightness(), 1.0F); - } - - - } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } - -} diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerBroodling.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerBroodling.java index 9267c70641..fe0ac3b5be 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerBroodling.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerBroodling.java @@ -1,30 +1,28 @@ package twilightforest.client.renderer.entity; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderSpider; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFTowerBroodling; + +public class RenderTFTowerBroodling extends RenderSpider { -public class RenderTFTowerBroodling extends RenderSpider { + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("towerbroodling.png"); - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerbroodling.png"); + public RenderTFTowerBroodling(RenderManager manager) { + super(manager); + } @Override - protected ResourceLocation getEntityTexture(Entity entity) { + protected ResourceLocation getEntityTexture(EntityTFTowerBroodling entity) { return textureLoc; } - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = 0.7F; - GL11.glScalef(scale, scale, scale); - } + @Override + protected void preRenderCallback(EntityTFTowerBroodling entity, float partialTicks) { + float scale = 0.7F; + GlStateManager.scale(scale, scale, scale); + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGhast.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGhast.java index cb5de4549d..e79df829e5 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGhast.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGhast.java @@ -1,75 +1,39 @@ package twilightforest.client.renderer.entity; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.boss.BossStatus; -import net.minecraft.entity.monster.EntityGhast; - -import org.lwjgl.opengl.GL11; - -import twilightforest.client.model.ModelTFGhast; -import twilightforest.entity.boss.EntityTFUrGhast; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; +import twilightforest.client.model.entity.ModelTFGhast; +import twilightforest.entity.EntityTFTowerGhast; /** * This is a copy of the RenderGhast class that changes the model - * */ -public class RenderTFTowerGhast extends RenderTFMiniGhast { - - private float ghastScale = 8.0F; +public class RenderTFTowerGhast extends RenderTFGhast { + + private float ghastScale = 8.0F; - public RenderTFTowerGhast(ModelTFGhast modelTFGhast, float f) { - super(modelTFGhast, f); + public RenderTFTowerGhast(RenderManager renderManager, ModelTFGhast modelTFGhast, float f) { + super(renderManager, modelTFGhast, f); } - public RenderTFTowerGhast(ModelTFGhast modelTFGhast, float f, float scale) { - super(modelTFGhast, f); + public RenderTFTowerGhast(RenderManager renderManager, ModelTFGhast modelTFGhast, float f, float scale) { + super(renderManager, modelTFGhast, f); this.ghastScale = scale; } - - /** - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic - * (Render 0) - { - BossStatus.setBossStatus((EntityTFUrGhast)entity, false); + protected void preRenderCallback(EntityTFTowerGhast ghast, float partialTicks) { + int attackTimer = ghast.getAttackTimer(); + int prevAttackTimer = ghast.getPrevAttackTimer(); + float scaleVariable = (prevAttackTimer + (attackTimer - prevAttackTimer) * partialTicks) / 20.0F; + if (scaleVariable < 0.0F) { + scaleVariable = 0.0F; } - } - - /** - * Pre-Renders the Ghast. - */ - protected void preRenderGhast(EntityGhast par1EntityGhast, float par2) - { - float scaleVariable = ((float)par1EntityGhast.prevAttackCounter + (float)(par1EntityGhast.attackCounter - par1EntityGhast.prevAttackCounter) * par2) / 20.0F; - if (scaleVariable < 0.0F) - { - scaleVariable = 0.0F; - } - - scaleVariable = 1.0F / (scaleVariable * scaleVariable * scaleVariable * scaleVariable * scaleVariable * 2.0F + 1.0F); + scaleVariable = 1.0F / (scaleVariable * scaleVariable * scaleVariable * scaleVariable * scaleVariable * 2.0F + 1.0F); float yScale = (ghastScale + scaleVariable) / 2.0F; - float xzScale = (ghastScale + 1.0F / scaleVariable) / 2.0F; - GL11.glScalef(xzScale, yScale, xzScale); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLiving, float par2) - { - this.preRenderGhast((EntityGhast)par1EntityLiving, par2); - } - - -} + float xzScale = (ghastScale + 1.0F / scaleVariable) / 2.0F; + GlStateManager.scale(xzScale, yScale, xzScale); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGolem.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGolem.java index 111b164060..52825b566b 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGolem.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFTowerGolem.java @@ -1,52 +1,36 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; import twilightforest.entity.EntityTFTowerGolem; -public class RenderTFTowerGolem extends RenderLiving -{ +public class RenderTFTowerGolem extends RenderLiving { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "carminitegolem.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("carminitegolem.png"); - public RenderTFTowerGolem(ModelBase par1ModelBase, float par2) - { - super(par1ModelBase, par2); + public RenderTFTowerGolem(RenderManager manager, ModelBase model, float shadowSize) { + super(manager, model, shadowSize); } - - protected void rotateCorpse(EntityLivingBase par1EntityLiving, float par2, float par3, float par4) - { - this.rotateTowerGolem((EntityTFTowerGolem)par1EntityLiving, par2, par3, par4); - } + @Override + protected void applyRotations(EntityTFTowerGolem entity, float ageInTicks, float rotationYaw, float partialTicks) { + super.applyRotations(entity, ageInTicks, rotationYaw, partialTicks); + if ((double) entity.limbSwingAmount >= 0.01D) { + float var5 = 13.0F; + float var6 = entity.limbSwing - entity.limbSwingAmount * (1.0F - partialTicks) + 6.0F; + float var7 = (Math.abs(var6 % var5 - var5 * 0.5F) - var5 * 0.25F) / (var5 * 0.25F); + GlStateManager.rotate(6.5F * var7, 0.0F, 0.0F, 1.0F); + } + } - private void rotateTowerGolem(EntityTFTowerGolem par1EntityLiving, float par2, float par3, float par4) - { - super.rotateCorpse(par1EntityLiving, par2, par3, par4); - - if ((double)par1EntityLiving.limbSwingAmount >= 0.01D) - { - float var5 = 13.0F; - float var6 = par1EntityLiving.limbSwing - par1EntityLiving.limbSwingAmount * (1.0F - par4) + 6.0F; - float var7 = (Math.abs(var6 % var5 - var5 * 0.5F) - var5 * 0.25F) / (var5 * 0.25F); - GL11.glRotatef(6.5F * var7, 0.0F, 0.0F, 1.0F); - } + @Override + protected ResourceLocation getEntityTexture(EntityTFTowerGolem entity) { + return textureLoc; } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFUrGhast.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFUrGhast.java index 94d63071e4..39c0cb2648 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFUrGhast.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFUrGhast.java @@ -1,50 +1,31 @@ package twilightforest.client.renderer.entity; -import net.minecraft.entity.Entity; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.util.ResourceLocation; import twilightforest.TwilightForestMod; -import twilightforest.client.model.ModelTFGhast; +import twilightforest.client.model.entity.ModelTFGhast; import twilightforest.entity.EntityTFTowerGhast; - public class RenderTFUrGhast extends RenderTFTowerGhast { - - final ResourceLocation textureLocClosed; - final ResourceLocation textureLocOpen; - final ResourceLocation textureLocAttack; - - - public RenderTFUrGhast(ModelTFGhast modelTFGhast, float f, float scale) { - super(modelTFGhast, f, scale); - textureLocClosed = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerboss.png"); - textureLocOpen = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerboss_openeyes.png"); - textureLocAttack = new ResourceLocation(TwilightForestMod.MODEL_DIR + "towerboss_fire.png"); + private final ResourceLocation textureLocClosed = TwilightForestMod.getModelTexture("towerboss.png"); + private final ResourceLocation textureLocOpen = TwilightForestMod.getModelTexture("towerboss_openeyes.png"); + private final ResourceLocation textureLocAttack = TwilightForestMod.getModelTexture("towerboss_fire.png"); + + public RenderTFUrGhast(RenderManager manager, ModelTFGhast modelTFGhast, float shadowSize, float scale) { + super(manager, modelTFGhast, shadowSize, scale); } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - if (par1Entity instanceof EntityTFTowerGhast) - { - switch (((EntityTFTowerGhast)par1Entity).getAttackStatus()) - { - default: + @Override + protected ResourceLocation getEntityTexture(EntityTFTowerGhast entity) { + switch (entity.isAttacking() ? 2 : entity.getAttackStatus()) { + default: case 0: return textureLocClosed; - case 1: return textureLocOpen; - case 2: return textureLocAttack; - } } - - // fallback - return textureLocClosed; - } + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFWinterWolf.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFWinterWolf.java index d6a03811fd..f0ae1a5f40 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFWinterWolf.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFWinterWolf.java @@ -1,69 +1,56 @@ package twilightforest.client.renderer.entity; -import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderWolf; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.passive.EntityWolf; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; public class RenderTFWinterWolf extends RenderWolf { - private static final ResourceLocation textureLoc = new ResourceLocation(TwilightForestMod.MODEL_DIR + "winterwolf.png"); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("winterwolf.png"); - public RenderTFWinterWolf(ModelBase par1ModelBase, ModelBase par2ModelBase, float par3) { - super(par1ModelBase, par2ModelBase, par3); + public RenderTFWinterWolf(RenderManager manager) { + super(manager); + this.shadowSize = 1.0F; } - - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLiving, float par2) - { - float wolfScale = 1.9F; - GL11.glScalef(wolfScale, wolfScale, wolfScale); - -// GL11.glEnable(3042 /*GL_BLEND*/); -// GL11.glDisable(3008 /*GL_ALPHA_TEST*/); -// //GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); -// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); -// //GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_ALPHA, GL11.GL_DST_ALPHA); + @Override + protected void preRenderCallback(EntityWolf entity, float partialTicks) { + float wolfScale = 1.9F; + GlStateManager.scale(wolfScale, wolfScale, wolfScale); + +// GlStateManager.enableBlend(); +// GlStateManager.disableAlpha(); +// //GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_ONE); +// GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); +// //GlStateManager.blendFunc(GL11.GL_ONE_MINUS_DST_ALPHA, GL11.GL_DST_ALPHA); // -// float misty = par1EntityLiving.getBrightness(0F) * 3F + 0.25F; +// float misty = entity.getBrightness(0F) * 3F + 0.25F; // misty = Math.min(1F, misty); // -// float smoky = par1EntityLiving.getBrightness(0F) * 2F + 0.6F; +// float smoky = entity.getBrightness(0F) * 2F + 0.6F; // -// //System.out.println("Misty value is " + misty); -// -// GL11.glColor4f(misty, misty, misty, smoky); +// GlStateManager.color(misty, misty, misty, smoky); - } - - /** - * Queries whether should render the specified pass or not. - */ - protected int shouldRenderPass(EntityLivingBase par1EntityLiving, int par2, float par3) - { -// GL11.glFogf(GL11.GL_FOG_START, 1.0f); -// GL11.glFogf(GL11.GL_FOG_END, 5.0f); - + } - - return -1; - } - /** - * Return our specific texture + * Queries whether should render the specified pass or not. */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureLoc; - } - + protected int shouldRenderPass(EntityLivingBase par1EntityLiving, int par2, float par3) { +// GL11.glFogf(GL11.GL_FOG_START, 1.0f); +// GL11.glFogf(GL11.GL_FOG_END, 5.0f); + + + return -1; + } + + @Override + protected ResourceLocation getEntityTexture(EntityWolf entity) { + return textureLoc; + } + } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFWraith.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFWraith.java index 365ffeae14..7cd1966a5a 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFWraith.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFWraith.java @@ -1,54 +1,43 @@ package twilightforest.client.renderer.entity; - import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderBiped; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; import net.minecraft.util.ResourceLocation; - -import org.lwjgl.opengl.GL11; - import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFWraith; +import javax.annotation.Nonnull; -public class RenderTFWraith extends RenderBiped { - - //texture = TwilightForestMod.MODEL_DIR + "ghost-crown.png"; +public class RenderTFWraith extends RenderBiped { - private static final ResourceLocation textureWraith = new ResourceLocation(TwilightForestMod.MODEL_DIR + "ghost.png"); - private static final ResourceLocation textureCrown = new ResourceLocation(TwilightForestMod.MODEL_DIR + "ghost-crown.png"); + private static final ResourceLocation textureWraith = TwilightForestMod.getModelTexture("ghost.png"); + private static final ResourceLocation textureCrown = TwilightForestMod.getModelTexture("ghost-crown.png"); - public RenderTFWraith(ModelBiped modelbiped, float f) { - super(modelbiped, f); + public RenderTFWraith(RenderManager manager, ModelBiped modelbiped, float shadowSize) { + super(manager, modelbiped, shadowSize); + addLayer(new LayerWraith()); } + @Override + protected ResourceLocation getEntityTexture(@Nonnull EntityTFWraith wraith) { + return textureCrown; + } - protected int shouldRenderPass(EntityLivingBase entityliving, int i, float f) - { - setRenderPassModel(this.mainModel); - - if (i == 1) { - this.bindTexture(textureWraith); - GL11.glEnable(3042 /*GL_BLEND*/); - GL11.glDisable(3008 /*GL_ALPHA_TEST*/); - GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE); - //GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - //GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_ALPHA, GL11.GL_DST_ALPHA); - GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5f); - - return 1; - } else { - return 0; - } - } - - /** - * Return our specific texture - */ - protected ResourceLocation getEntityTexture(Entity par1Entity) - { - return textureCrown; - } - + class LayerWraith implements LayerRenderer { + @Override + public void doRenderLayer(@Nonnull EntityTFWraith wraith, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { + RenderTFWraith.this.bindTexture(textureWraith); + GlStateManager.enableBlendProfile(GlStateManager.Profile.TRANSPARENT_MODEL); + RenderTFWraith.this.mainModel.render(wraith, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); + GlStateManager.disableBlendProfile(GlStateManager.Profile.TRANSPARENT_MODEL); + } + + @Override + public boolean shouldCombineTextures() { + return false; + } + } } diff --git a/src/main/java/twilightforest/client/renderer/entity/RenderTFYeti.java b/src/main/java/twilightforest/client/renderer/entity/RenderTFYeti.java index 4649562530..217dcfd376 100644 --- a/src/main/java/twilightforest/client/renderer/entity/RenderTFYeti.java +++ b/src/main/java/twilightforest/client/renderer/entity/RenderTFYeti.java @@ -1,23 +1,18 @@ package twilightforest.client.renderer.entity; import net.minecraft.client.model.ModelBiped; -import net.minecraft.entity.EntityLivingBase; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.EntityLiving; -import org.lwjgl.opengl.GL11; - -public class RenderTFYeti extends RenderTFBiped { - - public RenderTFYeti(ModelBiped modelBiped, float scale, String textureName) { - super(modelBiped, scale, textureName); +public class RenderTFYeti extends RenderTFBiped { + public RenderTFYeti(RenderManager manager, ModelBiped modelBiped, float shadowSize, String textureName) { + super(manager, modelBiped, shadowSize, textureName); } - /** - * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: - * entityLiving, partialTickTime - */ - protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) - { - float scale = 1.0F; - GL11.glScalef(scale, scale, scale); - } + @Override + protected void preRenderCallback(EntityLiving living, float partialTicks) { + float scale = 1.0F; + GlStateManager.scale(scale, scale, scale); + } } diff --git a/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFCicadaRenderer.java b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFCicadaRenderer.java new file mode 100644 index 0000000000..c2fce2f3f0 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFCicadaRenderer.java @@ -0,0 +1,55 @@ +package twilightforest.client.renderer.tileentity; + +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; +import twilightforest.client.BugModelAnimationHelper; +import twilightforest.client.model.entity.ModelTFCicada; +import twilightforest.tileentity.critters.TileEntityTFCicadaTicking; + +import javax.annotation.Nullable; + +public class TileEntityTFCicadaRenderer extends TileEntitySpecialRenderer { + + private final ModelTFCicada cicadaModel = new ModelTFCicada(); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("cicada-model.png"); + + @Override + public void render(@Nullable TileEntityTFCicadaTicking te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { + + int yaw = te != null ? te.currentYaw : BugModelAnimationHelper.currentYaw; + + GlStateManager.pushMatrix(); + EnumFacing facing = EnumFacing.byIndex(te != null ? te.getBlockMetadata() : 0); + + float rotX = 90.0F; + float rotZ = 0.0F; + if (facing == EnumFacing.SOUTH) { + rotZ = 0F; + } else if (facing == EnumFacing.NORTH) { + rotZ = 180F; + } else if (facing == EnumFacing.EAST) { + rotZ = -90F; + } else if (facing == EnumFacing.WEST) { + rotZ = 90F; + } else if (facing == EnumFacing.UP) { + rotX = 0F; + } else if (facing == EnumFacing.DOWN) { + rotX = 180F; + } + GlStateManager.translate((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F); + GlStateManager.rotate(rotX, 1F, 0F, 0F); + GlStateManager.rotate(rotZ, 0F, 0F, 1F); + GlStateManager.rotate(yaw, 0F, 1F, 0F); + + this.bindTexture(textureLoc); + GlStateManager.pushMatrix(); + GlStateManager.scale(1f, -1f, -1f); + cicadaModel.render(0.0625f); + GlStateManager.popMatrix(); + GlStateManager.color(1, 1, 1, 1); + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFFireflyRenderer.java b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFFireflyRenderer.java new file mode 100644 index 0000000000..ee13b5a398 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFFireflyRenderer.java @@ -0,0 +1,81 @@ +package twilightforest.client.renderer.tileentity; + +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; +import twilightforest.TwilightForestMod; +import twilightforest.client.BugModelAnimationHelper; +import twilightforest.client.model.entity.ModelTFFirefly; +import twilightforest.tileentity.critters.TileEntityTFFireflyTicking; + +import javax.annotation.Nullable; + +public class TileEntityTFFireflyRenderer extends TileEntitySpecialRenderer { + + private final ModelTFFirefly fireflyModel = new ModelTFFirefly(); + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("firefly-tiny.png"); + + @Override + public void render(@Nullable TileEntityTFFireflyTicking te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { + + int yaw = te != null ? te.currentYaw : BugModelAnimationHelper.currentYaw; + float glow = te != null ? te.glowIntensity : BugModelAnimationHelper.glowIntensity; + + GlStateManager.pushMatrix(); + EnumFacing facing = EnumFacing.byIndex(te != null ? te.getBlockMetadata() : 0); + + float rotX = 90.0F; + float rotZ = 0.0F; + if (facing == EnumFacing.SOUTH) { + rotZ = 0F; + } else if (facing == EnumFacing.NORTH) { + rotZ = 180F; + } else if (facing == EnumFacing.EAST) { + rotZ = -90F; + } else if (facing == EnumFacing.WEST) { + rotZ = 90F; + } else if (facing == EnumFacing.UP) { + rotX = 0F; + } else if (facing == EnumFacing.DOWN) { + rotX = 180F; + } + GlStateManager.translate((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F); + GlStateManager.rotate(rotX, 1F, 0F, 0F); + GlStateManager.rotate(rotZ, 0F, 0F, 1F); + GlStateManager.rotate(yaw, 0F, 1F, 0F); + + this.bindTexture(textureLoc); + GlStateManager.pushMatrix(); + GlStateManager.scale(1f, -1f, -1f); + + GlStateManager.colorMask(true, true, true, true); + + // render the firefly body + GlStateManager.disableBlend(); + fireflyModel.render(0.0625f); + +// +// GL11.glEnable(3042 /*GL_BLEND*/); +// GL11.glDisable(3008 /*GL_ALPHA_TEST*/); +// GL11.glBlendFunc(770, 771); +// GL11.glColor4f(1.0F, 1.0F, 1.0F, f1); + + // render the firefly glow + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.disableLighting(); + GlStateManager.color(1.0F, 1.0F, 1.0F, glow); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + fireflyModel.glow.render(0.0625f); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableLighting(); + + GlStateManager.popMatrix(); + GlStateManager.color(1, 1, 1, 1); + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFMoonwormRenderer.java b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFMoonwormRenderer.java new file mode 100644 index 0000000000..a28e63fc40 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFMoonwormRenderer.java @@ -0,0 +1,60 @@ +package twilightforest.client.renderer.tileentity; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; +import twilightforest.client.BugModelAnimationHelper; +import twilightforest.client.model.entity.ModelTFMoonworm; +import twilightforest.tileentity.critters.TileEntityTFMoonwormTicking; + +import javax.annotation.Nullable; + +public class TileEntityTFMoonwormRenderer extends TileEntitySpecialRenderer { + + private static final ResourceLocation textureLoc = TwilightForestMod.getModelTexture("moonworm.png"); + private final ModelTFMoonworm moonwormModel = new ModelTFMoonworm(); + + @Override + public void render(@Nullable TileEntityTFMoonwormTicking te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { + + int yaw = te != null ? te.currentYaw : BugModelAnimationHelper.currentRotation; + if (te == null) partialTicks = Minecraft.getMinecraft().getRenderPartialTicks(); + + GlStateManager.pushMatrix(); + EnumFacing facing = EnumFacing.byIndex(te != null ? te.getBlockMetadata() : 0); + + float rotX = 90.0F; + float rotZ = 0.0F; + if (facing == EnumFacing.SOUTH) { + rotZ = 0F; + } else if (facing == EnumFacing.NORTH) { + rotZ = 180F; + } else if (facing == EnumFacing.EAST) { + rotZ = -90F; + } else if (facing == EnumFacing.WEST) { + rotZ = 90F; + } else if (facing == EnumFacing.UP) { + rotX = 0F; + } else if (facing == EnumFacing.DOWN) { + rotX = 180F; + } + GlStateManager.translate(x + 0.5F, y + 0.5F, z + 0.5F); + GlStateManager.rotate(rotX, 1F, 0F, 0F); + GlStateManager.rotate(rotZ, 0F, 0F, 1F); + GlStateManager.rotate(yaw, 0F, 1F, 0F); + + this.bindTexture(textureLoc); + + GlStateManager.scale(1f, -1f, -1f); + + moonwormModel.setLivingAnimations(te, partialTicks); + + // render the firefly body + moonwormModel.render(0.0625f); + + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFTrophyRenderer.java b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFTrophyRenderer.java new file mode 100644 index 0000000000..8aeae622f5 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/tileentity/TileEntityTFTrophyRenderer.java @@ -0,0 +1,403 @@ +package twilightforest.client.renderer.tileentity; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.event.ModelBakeEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.opengl.GL11; +import twilightforest.TFConfig; +import twilightforest.TwilightForestMod; +import twilightforest.client.model.item.BuiltInItemModel; +import twilightforest.enums.BossVariant; +import twilightforest.client.TFClientEvents; +import twilightforest.client.model.entity.ModelTFHydraHead; +import twilightforest.client.model.entity.ModelTFKnightPhantom2; +import twilightforest.client.model.entity.ModelTFLich; +import twilightforest.client.model.entity.ModelTFMinoshroom; +import twilightforest.client.model.entity.ModelTFNaga; +import twilightforest.client.model.armor.ModelTFPhantomArmor; +import twilightforest.client.model.entity.ModelTFQuestRam; +import twilightforest.client.model.entity.ModelTFSnowQueen; +import twilightforest.client.model.entity.ModelTFTowerBoss; +import twilightforest.tileentity.TileEntityTFTrophy; + +import javax.annotation.Nullable; + +public class TileEntityTFTrophyRenderer extends TileEntitySpecialRenderer { + + public static class DummyTile extends TileEntityTFTrophy {} + + private final ModelTFHydraHead hydraHeadModel = new ModelTFHydraHead(); + private static final ResourceLocation textureLocHydra = TwilightForestMod.getModelTexture("hydra4.png"); + + private final ModelTFNaga nagaHeadModel = new ModelTFNaga(); + private static final ResourceLocation textureLocNaga = TwilightForestMod.getModelTexture("nagahead.png"); + + private final ModelTFLich lichModel = new ModelTFLich(); + private static final ResourceLocation textureLocLich = TwilightForestMod.getModelTexture("twilightlich64.png"); + + private final ModelTFTowerBoss urGhastModel = new ModelTFTowerBoss(); + private static final ResourceLocation textureLocUrGhast = TwilightForestMod.getModelTexture("towerboss.png"); + + private final ModelTFSnowQueen snowQueenModel = new ModelTFSnowQueen(); + private static final ResourceLocation textureLocSnowQueen = TwilightForestMod.getModelTexture("snowqueen.png"); + + private final ModelTFMinoshroom minoshroomModel = new ModelTFMinoshroom(); + private static final ResourceLocation textureLocMinoshroom = TwilightForestMod.getModelTexture("minoshroomtaur.png"); + + private final ModelTFKnightPhantom2 knightPhantomModel = new ModelTFKnightPhantom2(); + private static final ResourceLocation textureLocKnightPhantom = TwilightForestMod.getModelTexture("phantomskeleton.png"); + private final ModelTFPhantomArmor knightPhantomArmorModel = new ModelTFPhantomArmor(EntityEquipmentSlot.HEAD, 0.5F); + private static final ResourceLocation textureLocKnightPhantomArmor = new ResourceLocation(TwilightForestMod.ARMOR_DIR + "phantom_1.png"); + + private final ModelTFQuestRam questRamModel = new ModelTFQuestRam(); + private static final ResourceLocation textureLocQuestRam = TwilightForestMod.getModelTexture("questram.png"); + private static final ResourceLocation textureLocQuestRamLines = TwilightForestMod.getModelTexture("questram_lines.png"); + + private final ModelResourceLocation itemModelLocation; + + public TileEntityTFTrophyRenderer() { + this.itemModelLocation = null; + } + + public TileEntityTFTrophyRenderer(ModelResourceLocation itemModelLocation) { + this.itemModelLocation = itemModelLocation; + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void onModelBake(ModelBakeEvent event) { + event.getModelRegistry().putObject(itemModelLocation, new BakedModel()); + } + + private class BakedModel extends BuiltInItemModel { + + BakedModel() { + super("minecraft:blocks/soul_sand"); + } + + @Override + protected void setItemStack(ItemStack stack) { + TileEntityTFTrophyRenderer.this.stack = stack; + } + + @Override + protected void setTransform(ItemCameraTransforms.TransformType transform) { + TileEntityTFTrophyRenderer.this.transform = transform; + } + } + + private ItemStack stack = ItemStack.EMPTY; + private ItemCameraTransforms.TransformType transform = ItemCameraTransforms.TransformType.NONE; + + @Override + public void render(@Nullable TileEntityTFTrophy trophy, double x, double y, double z, float partialTime, int destroyStage, float alpha) { + GlStateManager.pushMatrix(); + GlStateManager.disableCull(); + + if (trophy == null) { + if (transform == ItemCameraTransforms.TransformType.GUI) { + String modelName = BossVariant.getVariant(stack.getMetadata()).getTrophyType().getModelName(); + ModelResourceLocation trophyModelLocation = new ModelResourceLocation(TwilightForestMod.ID + ":" + modelName, "inventory"); + IBakedModel trophyModel = Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getModelManager().getModel(trophyModelLocation); + + GlStateManager.disableLighting(); + GlStateManager.translate(0.5F, 0.5F, -1.5F); + Minecraft.getMinecraft().getRenderItem().renderItem(stack, ForgeHooksClient.handleCameraTransforms(trophyModel, transform, false)); + GlStateManager.enableLighting(); + GlStateManager.translate(-0.5F, 0.0F, 1.5F); + + //if (variant == BossVariant.QUEST_RAM) + // GlStateManager.translate(0.0F,0.0625F,0.0F); + + GlStateManager.rotate(30, 1F, 0F, 0F); + + } else if (transform == ItemCameraTransforms.TransformType.THIRD_PERSON_LEFT_HAND + || transform == ItemCameraTransforms.TransformType.THIRD_PERSON_RIGHT_HAND) { + GlStateManager.scale(0.5F, 0.5F, 0.5F); + GlStateManager.rotate(45, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(45, 0.0F, 1.0F, 0.0F); + GlStateManager.translate(0.40625F, 1.171875F, 0.0F); + + } else if (transform == ItemCameraTransforms.TransformType.GROUND) { + GlStateManager.translate(0.25F, 0.3F, 0.25F); + GlStateManager.scale(0.5F, 0.5F, 0.5F); + + } else if (transform == ItemCameraTransforms.TransformType.HEAD) { + if (BossVariant.getVariant(stack.getMetadata()) == BossVariant.QUEST_RAM) { + GlStateManager.scale(3F, 3F, 3F); + GlStateManager.translate(-0.33F, -0.13F, -0.33F); + } else { + GlStateManager.scale(2.0F, 2.0F, 2.0F); + GlStateManager.translate(-0.25F, 0.0F, -0.25F); + } + } + } + + //int meta = trophy != null ? trophy.getBlockMetadata() & 7 : stack.getMetadata() & 7; + + float rotation = trophy != null ? (float) (trophy.getSkullRotation() * 360) / 16.0F : 0.0F; + boolean onGround = true; + + // wall mounted? + if (trophy != null && trophy.getBlockMetadata() != 1) { + switch (trophy.getBlockMetadata() & 7) { + case 2: + onGround = false; + break; + case 3: + onGround = false; + rotation = 180.0F; + break; + case 4: + onGround = false; + rotation = 270.0F; + break; + case 5: + default: + onGround = false; + rotation = 90.0F; + } + } else if (trophy == null && transform == ItemCameraTransforms.TransformType.GUI) { + rotation = TFConfig.rotateTrophyHeadsGui ? TFClientEvents.rotationTicker : 135; + } + + GlStateManager.translate((float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F); + + switch (BossVariant.getVariant(trophy != null ? trophy.getSkullType() : stack.getMetadata())) { + case HYDRA: + if (trophy == null) { + GlStateManager.translate(0.0F, -0.25F, transform == ItemCameraTransforms.TransformType.HEAD ? -0.125F : 0.0F); + } + renderHydraHead(rotation, onGround && trophy != null); + break; + case NAGA: + renderNagaHead(rotation, onGround); + break; + case LICH: + renderLichHead(rotation, onGround); + break; + case UR_GHAST: + if (trophy == null) GlStateManager.translate(0.0F, -0.5F, 0.0F); + renderUrGhastHead(trophy, rotation, onGround, partialTime); + break; + case SNOW_QUEEN: + renderSnowQueenHead(rotation, onGround); + break; + case MINOSHROOM: + renderMinoshroomHead(rotation, onGround); + break; + case KNIGHT_PHANTOM: + renderKnightPhantomHead(rotation, onGround); + break; + case QUEST_RAM: + renderQuestRamHead(rotation, onGround); + break; + default: + break; + } + + GlStateManager.enableCull(); + GlStateManager.popMatrix(); + } + + /** + * Render a hydra head + */ + private void renderHydraHead(float rotation, boolean onGround) { + GlStateManager.scale(0.25f, 0.25f, 0.25f); + + this.bindTexture(textureLocHydra); + + GlStateManager.scale(1f, -1f, -1f); + + // we seem to be getting a 180 degree rotation here + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0, onGround ? 1F : -0F, 1.5F); + + // open mouth? + hydraHeadModel.openMouthForTrophy(onGround ? 0F : 0.25F); + + // render the hydra head + hydraHeadModel.render(null, 0.0F, 0.0F, 0.0F, rotation, 0.0F, 0.0625F); + } + + private void renderNagaHead(float rotation, boolean onGround) { + GlStateManager.translate(0, -0.125F, 0); + + GlStateManager.scale(0.25f, 0.25f, 0.25f); + + this.bindTexture(textureLocNaga); + + GlStateManager.scale(1f, -1f, -1f); + + // we seem to be getting a 180 degree rotation here + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0, onGround ? 1F : -0F, onGround ? 0F : 1F); + + // render the naga head + nagaHeadModel.render(null, 0.0F, 0.0F, 0.0F, rotation, 0.0F, 0.0625F); + } + + + private void renderLichHead(float rotation, boolean onGround) { + GlStateManager.translate(0, 1, 0); + + //GlStateManager.scale(0.5f, 0.5f, 0.5f); + + this.bindTexture(textureLocLich); + + GlStateManager.scale(1f, -1f, -1f); + + // we seem to be getting a 180 degree rotation here + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0, onGround ? 1.75F : 1.5F, onGround ? 0F : 0.24F); + + // render the lich head + lichModel.bipedHead.render(0.0625F); + lichModel.bipedHeadwear.render(0.0625F); + } + + + private void renderUrGhastHead(@Nullable TileEntityTFTrophy trophy, float rotation, boolean onGround, float partialTime) { + GlStateManager.translate(0, 1, 0); + + GlStateManager.scale(0.5f, 0.5f, 0.5f); + + this.bindTexture(textureLocUrGhast); + + GlStateManager.scale(1f, -1f, -1f); + + // we seem to be getting a 180 degree rotation here + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0, onGround ? 1F : 1F, onGround ? 0F : 0F); + + // render the head + urGhastModel.render(null, 0.0F, 0, trophy != null ? trophy.ticksExisted + partialTime : TFClientEvents.sineTicker + partialTime, 0, 0.0F, 0.0625F); + } + + private void renderSnowQueenHead(float rotation, boolean onGround) { + GlStateManager.translate(0, 1, 0); + + //GlStateManager.scale(0.5f, 0.5f, 0.5f); + + this.bindTexture(textureLocSnowQueen); + + GlStateManager.scale(1f, -1f, -1f); + + // we seem to be getting a 180 degree rotation here + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0, onGround ? 1.5F : 1.25F, onGround ? 0F : 0.24F); + + // render the head + snowQueenModel.bipedHead.render(0.0625F); + snowQueenModel.bipedHeadwear.render(0.0625F); + } + + private void renderMinoshroomHead(float rotation, boolean onGround) { + GlStateManager.translate(0, 1, 0); + + //GlStateManager.scale(0.5f, 0.5f, 0.5f); + + this.bindTexture(textureLocMinoshroom); + + GlStateManager.scale(1f, -1f, -1f); + + // we seem to be getting a 180 degree rotation here + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0, onGround ? 1.875F : 1.625F, onGround ? 0.5625F : 0.8125F); + + // render the head + minoshroomModel.bipedHead.render(0.0625F); + } + + private void renderKnightPhantomHead(float rotation, boolean onGround) { + GlStateManager.translate(0, 1, 0); + + GlStateManager.scale(1f, -1f, -1f); + + // we seem to be getting a 180 degree rotation here + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0, onGround ? 1.5F : 1.25F, onGround ? 0.0F : 0.25F); + + GlStateManager.scale(0.9375F, 0.9375F, 0.9375F); + + // render the head + this.bindTexture(textureLocKnightPhantomArmor); + knightPhantomArmorModel.bipedHead.render(0.0625F); + + GlStateManager.color(1.0F, 1.0F, 1.0F, 0.75F); + + this.bindTexture(textureLocKnightPhantom); + knightPhantomModel.bipedHead.render(0.0625F); + } + + private void renderQuestRamHead(float rotation, boolean onGround) { + if (transform == ItemCameraTransforms.TransformType.GUI) + GlStateManager.scale(0.55f, 0.55f, 0.55f); + else if (stack.isEmpty()) + GlStateManager.scale(0.65f, 0.65f, 0.65f); + else + GlStateManager.scale(0.5f, 0.5f, 0.5f); + + if (transform == ItemCameraTransforms.TransformType.FIRST_PERSON_LEFT_HAND + || transform == ItemCameraTransforms.TransformType.FIRST_PERSON_RIGHT_HAND) { + GlStateManager.translate(0.0F, 0.5F, 0.0F); + } + + this.bindTexture(textureLocQuestRam); + + GlStateManager.scale(1f, -1f, -1f); + + GlStateManager.rotate(rotation, 0F, 1F, 0F); + GlStateManager.rotate(180F, 0F, 1F, 0F); + + GlStateManager.translate(0F, onGround ? 1.30F : 1.03F, onGround ? 0.765625F : 1.085F); + + // render the head + questRamModel.head.render(0.0625F); + + GlStateManager.disableLighting(); + this.bindTexture(textureLocQuestRamLines); + float var4 = 1.0F; + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + GlStateManager.scale(1.025f, 1.025f, 1.025f); + char var5 = 61680; + int var6 = var5 % 65536; + int var7 = var5 / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) var6 / 1.0F, (float) var7 / 1.0F); + GlStateManager.color(1.0F, 1.0F, 1.0F, var4); + questRamModel.head.render(0.0625F); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240F, 240F); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.enableAlpha(); + GlStateManager.enableLighting(); + } +} diff --git a/src/main/java/twilightforest/client/renderer/tileentity/package-info.java b/src/main/java/twilightforest/client/renderer/tileentity/package-info.java new file mode 100644 index 0000000000..eb1338e417 --- /dev/null +++ b/src/main/java/twilightforest/client/renderer/tileentity/package-info.java @@ -0,0 +1,3 @@ +@mcp.MethodsReturnNonnullByDefault +@javax.annotation.ParametersAreNonnullByDefault +package twilightforest.client.renderer.tileentity; diff --git a/src/main/java/twilightforest/client/shader/FloatSupplier.java b/src/main/java/twilightforest/client/shader/FloatSupplier.java new file mode 100644 index 0000000000..5e53ffbe5e --- /dev/null +++ b/src/main/java/twilightforest/client/shader/FloatSupplier.java @@ -0,0 +1,7 @@ +package twilightforest.client.shader; + +@FunctionalInterface +public interface FloatSupplier { + + float get(); +} diff --git a/src/main/java/twilightforest/client/shader/ShaderManager.java b/src/main/java/twilightforest/client/shader/ShaderManager.java new file mode 100644 index 0000000000..818d3c5819 --- /dev/null +++ b/src/main/java/twilightforest/client/shader/ShaderManager.java @@ -0,0 +1,288 @@ +/* + * Original class written by Vazkii for Botania. + * Copied from TTFTCUTS' ShadowsOfPhysis + */ + +// TEMA: this is the main shader stuff, where the programs are loaded and compiled for the card. +// other relevant files are the shader in /assets/physis/shader/, and the tesr in /client/render/tile/ +// they have other comments like this in. + +package twilightforest.client.shader; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.util.function.IntConsumer; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.SimpleReloadableResourceManager; +import net.minecraftforge.client.resource.ISelectiveResourceReloadListener; +import net.minecraftforge.client.resource.VanillaResourceType; + +import org.apache.commons.io.IOUtils; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.*; +import twilightforest.TFConfig; +import twilightforest.TwilightForestMod; +import twilightforest.client.TFClientEvents; + +import javax.annotation.Nullable; + +public final class ShaderManager { + + private static ISelectiveResourceReloadListener shaderReloadListener; + + private static final int VERT = OpenGlHelper.arbShaders ? ARBVertexShader.GL_VERTEX_SHADER_ARB : GL20.GL_VERTEX_SHADER; + private static final int FRAG = OpenGlHelper.arbShaders ? ARBFragmentShader.GL_FRAGMENT_SHADER_ARB : GL20.GL_FRAGMENT_SHADER; + + private static final String PREFIX = "/assets/twilightforest/shaders/"; + + @SuppressWarnings({"WeakerAccess", "unused"}) + public static int + enderPortalShader, + twilightSkyShader, + fireflyShader, + auroraShader, + carminiteShader, + towerDeviceShader, + yellowCircuitShader, + bloomShader, + starburstShader, + shieldShader, + outlineShader; + + @SuppressWarnings("WeakerAccess") + public static final class Uniforms { + + public static final ShaderUniform TIME = ShaderUniform.create("time" , () -> TFClientEvents.time + Minecraft.getMinecraft().getRenderPartialTicks()); + public static final ShaderUniform YAW = ShaderUniform.create("yaw" , () -> (Minecraft.getMinecraft().player.rotationYaw * 2.0f * TFClientEvents.PI) / 360.0f); + public static final ShaderUniform PITCH = ShaderUniform.create("pitch" , () -> -(Minecraft.getMinecraft().player.rotationPitch * 2.0f * TFClientEvents.PI) / 360.0f); + public static final ShaderUniform RESOLUTION = ShaderUniform.create("resolution", () -> Minecraft.getMinecraft().displayWidth, () -> Minecraft.getMinecraft().displayHeight); + public static final ShaderUniform ZERO = ShaderUniform.create("zero" , 0); + public static final ShaderUniform ONE = ShaderUniform.create("one" , 1); + public static final ShaderUniform TWO = ShaderUniform.create("two" , 2); + + public static final ShaderUniform[] STAR_UNIFORMS = { TIME, YAW, PITCH, RESOLUTION, ZERO, TWO }; + public static final ShaderUniform[] TIME_UNIFORM = { TIME }; + } + + //@SuppressWarnings("WeakerAccess") + //public static Framebuffer bloomFbo; + + public static void initShaders() { + IResourceManager iManager; + + if ((iManager = Minecraft.getMinecraft().getResourceManager()) instanceof SimpleReloadableResourceManager) { + ((SimpleReloadableResourceManager) iManager).registerReloadListener(shaderReloadListener = (manager, predicate) -> { + if (predicate.test(VanillaResourceType.SHADERS)) reloadShaders(); + }); + } + + //bloomFbo = new Framebuffer(MINECRAFT.displayWidth, MINECRAFT.displayHeight, true); + } + + public static ISelectiveResourceReloadListener getShaderReloadListener() { + return shaderReloadListener; + } + + private static void reloadShaders() { + //deleteProgram(enderPortalShader); + deleteProgram(twilightSkyShader); + deleteProgram(fireflyShader); + deleteProgram(auroraShader); + deleteProgram(carminiteShader); + deleteProgram(towerDeviceShader); + deleteProgram(yellowCircuitShader); + //deleteProgram(bloomShader); + deleteProgram(starburstShader); + //deleteProgram(outlineShader); + + initShaderList(); + } + + private static void deleteProgram(int id) { + if (id != 0) OpenGlHelper.glDeleteProgram(id); + } + + private static void initShaderList() { + //enderPortalShader = createProgram("standard.vert", "ender.frag"); + twilightSkyShader = createProgram("standard_texcoord.vert" , "twilight_sky.frag"); + fireflyShader = createProgram("standard_texcoord2.vert", "firefly.frag"); + auroraShader = createProgram("standard_texcoord2.vert", "aurora.frag"); + carminiteShader = createProgram("camera_fixed.vert" , "spiral.frag"); + towerDeviceShader = createProgram("camera_fixed.vert" , "pulsing.frag"); + yellowCircuitShader = createProgram("standard_texcoord2.vert", "pulsing_yellow.frag"); + //bloomShader = createProgram("standard.vert", "bloom.frag"); + starburstShader = createProgram("standard_texcoord2.vert", "starburst.frag"); + shieldShader = createProgram("standard_texcoord2.vert", "shield.frag"); + //outlineShader = createProgram("outline.vert", "outline.frag"); + } + + public static void useShader(int shader, @Nullable IntConsumer callback) { + if(!useShaders()) + return; + + OpenGlHelper.glUseProgram(shader); + + if(shader != 0 && callback != null) callback.accept(shader); + } + + public static void useShader(int shader, ShaderUniform uniform) { + if(!useShaders()) + return; + + OpenGlHelper.glUseProgram(shader); + + if(shader != 0) uniform.assignUniform(shader); + } + + public static void useShader(int shader, ShaderUniform... uniforms) { + if(!useShaders()) + return; + + OpenGlHelper.glUseProgram(shader); + + if(shader != 0) { + for (ShaderUniform uniform : uniforms) { + uniform.assignUniform(shader); + } + } + } + + @SuppressWarnings("WeakerAccess") + public static void useShader(int shader) { + if(!useShaders()) + return; + + OpenGlHelper.glUseProgram(shader); + } + + public static void releaseShader() { + useShader(0); + } + + @SuppressWarnings("WeakerAccess") + public static boolean useShaders() { + return TFConfig.performance.shadersSupported && OpenGlHelper.shadersSupported; + } + + // Most of the code taken from the LWJGL wiki + // http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL + + @SuppressWarnings("SameParameterValue") + private static int createProgram(String vert, String frag) { + int program = OpenGlHelper.glCreateProgram(); + + if(program == 0) + return 0; + + int vertId = createShader(PREFIX + vert, VERT); + OpenGlHelper.glAttachShader(program, vertId); + + int fragId = createShader(PREFIX + frag, FRAG); + OpenGlHelper.glAttachShader(program, fragId); + + OpenGlHelper.glLinkProgram(program); + if (OpenGlHelper.glGetProgrami(program, OpenGlHelper.GL_LINK_STATUS) == GL11.GL_FALSE) { + TwilightForestMod.LOGGER.error("Failed to create shader! (LINK) {} {}", vert, frag); + TwilightForestMod.LOGGER.error(getProgramInfoLog(program)); + return 0; + } + + glValidateProgram(program); + if (OpenGlHelper.glGetProgrami(program, VALIDATE_STATUS) == GL11.GL_FALSE) { + TwilightForestMod.LOGGER.error("Failed to create shader! (VALIDATE) {} {}", vert, frag); + TwilightForestMod.LOGGER.error(getProgramInfoLog(program)); + return 0; + } + + return program; + } + + private static int createShader(String filename, int shaderType){ + int shader = 0; + try { + shader = OpenGlHelper.glCreateShader(shaderType); + + if(shader == 0) + return 0; + + OpenGlHelper.glShaderSource(shader, readFile(filename)); + OpenGlHelper.glCompileShader(shader); + + if (OpenGlHelper.glGetShaderi(shader, OpenGlHelper.GL_COMPILE_STATUS) == GL11.GL_FALSE) { + TwilightForestMod.LOGGER.error("Failed to create shader! (COMPILE) {}", filename); + throw new RuntimeException("Error creating shader: " + getShaderInfoLog(shader)); + } + + return shader; + + } catch (Exception e) { + OpenGlHelper.glDeleteShader(shader); + e.printStackTrace(); + return -1; + } + } + + // See ShaderLoader.loadShader for buffer management + private static ByteBuffer readFile(String path) throws IOException { + try (InputStream in = ShaderManager.class.getResourceAsStream(path)) { + byte[] bytes = IOUtils.toByteArray(in); + return (ByteBuffer) BufferUtils.createByteBuffer(bytes.length).put(bytes).position(0); + } + } + + private static String getShaderInfoLog(int shader) { + return OpenGlHelper.glGetShaderInfoLog(shader, OpenGlHelper.glGetShaderi(shader, INFO_LOG_LENGTH)); + } + + private static String getProgramInfoLog(int program) { + return OpenGlHelper.glGetProgramInfoLog(program, OpenGlHelper.glGetProgrami(program, INFO_LOG_LENGTH)); + } + + /* Assorted constants/functions missing from OpenGlHelper */ + + private static final int INFO_LOG_LENGTH + = OpenGlHelper.arbShaders + ? ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB + : GL20.GL_INFO_LOG_LENGTH; + + private static final int VALIDATE_STATUS + = OpenGlHelper.arbShaders + ? ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB + : GL20.GL_VALIDATE_STATUS; + + private static void glValidateProgram(int program) { + if (OpenGlHelper.arbShaders) { + ARBShaderObjects.glValidateProgramARB(program); + } else { + GL20.glValidateProgram(program); + } + } + + static void glUniform2i(int location, int v0, int v1) { + if (OpenGlHelper.arbShaders) { + ARBShaderObjects.glUniform2iARB(location, v0, v1); + } else { + GL20.glUniform2i(location, v0, v1); + } + } + + static void glUniform1f(int location, float v0) { + if (OpenGlHelper.arbShaders) { + ARBShaderObjects.glUniform1fARB(location, v0); + } else { + GL20.glUniform1f(location, v0); + } + } + + static void glUniform2f(int location, float v0, float v1) { + if (OpenGlHelper.arbShaders) { + ARBShaderObjects.glUniform2fARB(location, v0, v1); + } else { + GL20.glUniform2f(location, v0, v1); + } + } +} diff --git a/src/main/java/twilightforest/client/shader/ShaderUniform.java b/src/main/java/twilightforest/client/shader/ShaderUniform.java new file mode 100644 index 0000000000..1d5ec39db5 --- /dev/null +++ b/src/main/java/twilightforest/client/shader/ShaderUniform.java @@ -0,0 +1,89 @@ +package twilightforest.client.shader; + +import net.minecraft.client.renderer.OpenGlHelper; + +import java.util.function.IntSupplier; + +public abstract class ShaderUniform { + + protected final String name; + + @SuppressWarnings("WeakerAccess") + protected ShaderUniform(String name) { + this.name = name; + } + + public abstract void assignUniform(int shader); + + public static ShaderUniform create(String name, int value) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + OpenGlHelper.glUniform1i(OpenGlHelper.glGetUniformLocation(shader, name), value); + } + }; + } + + public static ShaderUniform create(String name, IntSupplier supplier) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + OpenGlHelper.glUniform1i(OpenGlHelper.glGetUniformLocation(shader, name), supplier.getAsInt()); + } + }; + } + + public static ShaderUniform create(String name, int value0, int value1) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + ShaderManager.glUniform2i(OpenGlHelper.glGetUniformLocation(shader, name), value0, value1); + } + }; + } + + public static ShaderUniform create(String name, IntSupplier supplier0, IntSupplier supplier1) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + ShaderManager.glUniform2i(OpenGlHelper.glGetUniformLocation(shader, name), supplier0.getAsInt(), supplier1.getAsInt()); + } + }; + } + + public static ShaderUniform create(String name, float value) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + ShaderManager.glUniform1f(OpenGlHelper.glGetUniformLocation(shader, name), value); + } + }; + } + + public static ShaderUniform create(String name, FloatSupplier supplier) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + ShaderManager.glUniform1f(OpenGlHelper.glGetUniformLocation(shader, name), supplier.get()); + } + }; + } + + public static ShaderUniform create(String name, float value0, float value1) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + ShaderManager.glUniform2f(OpenGlHelper.glGetUniformLocation(shader, name), value0, value1); + } + }; + } + + public static ShaderUniform create(String name, FloatSupplier supplier0, FloatSupplier supplier1) { + return new ShaderUniform(name) { + @Override + public void assignUniform(int shader) { + ShaderManager.glUniform2f(OpenGlHelper.glGetUniformLocation(shader, name), supplier0.get(), supplier1.get()); + } + }; + } +} diff --git a/src/main/java/twilightforest/client/shader/package-info.java b/src/main/java/twilightforest/client/shader/package-info.java new file mode 100644 index 0000000000..b91aad9bab --- /dev/null +++ b/src/main/java/twilightforest/client/shader/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.client.shader; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/client/texture/GradientMappedTexture.java b/src/main/java/twilightforest/client/texture/GradientMappedTexture.java new file mode 100644 index 0000000000..7c114dced3 --- /dev/null +++ b/src/main/java/twilightforest/client/texture/GradientMappedTexture.java @@ -0,0 +1,205 @@ +package twilightforest.client.texture; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; + +import static net.minecraft.util.math.MathHelper.sqrt; + +public class GradientMappedTexture extends TextureAtlasSprite { + private final ResourceLocation textureDependency; + + private boolean shouldNormalize; + private final GradientNode[] GRADIENT_MAP; + private float minimumValue; + private float maximumValue; + + public GradientMappedTexture(ResourceLocation textureDependency, ResourceLocation spriteName, boolean shouldNormalize, GradientNode[] gradient_map) { + super(spriteName.toString()); + this.textureDependency = textureDependency; + this.GRADIENT_MAP = gradient_map; + this.shouldNormalize = shouldNormalize; + } + + @Override + public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) { + return true; + } + + @Override + public Collection getDependencies() { + return ImmutableList.of(textureDependency); + } + + @Override + public boolean load(IResourceManager manager, ResourceLocation location, Function textureGetter) { + final TextureAtlasSprite sprite = textureGetter.apply(textureDependency); + + // Copy all coord data from texture we're mapping + copyFrom(sprite); + this.animationMetadata = sprite.animationMetadata; + + this.framesTextureData = Lists.newArrayList(); + + int minimumValue = 255; + int maximumValue = 0; + + // Copy all textures from texture dependency + for (int i = 0; i < sprite.getFrameCount(); i++) { + // getFrameTextureData() is oddly named; the param passed in is the frame index + // Returned is an array of mipmaps of each actual texture, from largest to smallest mips. + final int[][] textureFrom = sprite.getFrameTextureData(i); + int [][] textureTo = new int[textureFrom.length][]; + + for (int j = 0; j < textureFrom.length; j++) { + textureTo[j] = Arrays.copyOf(textureFrom[j], textureFrom[j].length); + } + + // Graying out textures will usually produce float ranges that are only a fragment the 0.0 -> 1.0 range. + // Resulting grayscale texture will not fully capture the entire gradient map which are designed for + // the 0.0 -> 1.0 range. Test all animation frames for the darkest and lightest value. + if (this.shouldNormalize) { + for (int pixel : textureTo[0]) { + if ((pixel >> 24 & 0xFF) == 0) continue; // Fully transparent pixels should not be considered + + minimumValue = Math.min(minimumValue, getPerceptualBrightness(pixel)); + maximumValue = Math.max(maximumValue, getPerceptualBrightness(pixel)); + } + } + + this.framesTextureData.add(i, textureTo); + } + + if (shouldNormalize) { + if (minimumValue > maximumValue) { + this.minimumValue = maximumValue / 255f; + this.maximumValue = minimumValue / 255f; + } else { + this.minimumValue = minimumValue / 255f; + this.maximumValue = maximumValue / 255f; + } + + // foreach iterates 'texture frames' in framesTextureData, l iterates each mipmap, j iterates each pixel + for (int[][] texture : framesTextureData) { + for (int l = 0; l < texture.length; l++) { + for (int j = 0; j < texture[l].length; j++) { + texture[l][j] = getGradient(texture[l][j], GRADIENT_MAP, this.minimumValue, this.maximumValue); + } + } + } + + TwilightForestMod.LOGGER.debug("Autogenerated {} from {} with min value {} and max value {}", this.getIconName(), this.textureDependency, this.minimumValue, this.maximumValue); + } else { + // foreach iterates 'texture frames', l iterates each mipmap, j iterates each pixel + for (int[][] texture : framesTextureData) { + for (int l = 0; l < texture.length; l++) { + for (int j = 0; j < texture[l].length; j++) { + texture[l][j] = getGradient(texture[l][j], GRADIENT_MAP, 0.0f, 1.0f); + } + } + } + + TwilightForestMod.LOGGER.debug("Autogenerated {} from {}", this.getIconName(), this.textureDependency); + } + + return false; + } + + public static int getGradient(int packedColor, GradientNode[] gradientMap, float minimumValue, float maximumValue) { + int a = packedColor >> 24 & 0xFF; + + if (a == 0) { + return packedColor; // Full alpha no color + } + + // Make a gray from the colors and use it as a gradient map coordinate + float gray = normalize(getPerceptualBrightness(packedColor) / 255.0F, minimumValue, maximumValue); + + int rTo = 0, gTo = 0, bTo = 0; + + if (gray <= gradientMap[0].node) { + // Coord gray matches or is located before first gradient transition + rTo = red (gradientMap[0].color); + gTo = green(gradientMap[0].color); + bTo = blue (gradientMap[0].color); + } else if (gray >= gradientMap[gradientMap.length-1].node) { + // Coord gray matches or is located after last gradient transition + int i = gradientMap[gradientMap.length-1].color; + + rTo = red (i); + gTo = green(i); + bTo = blue (i); + } else { + for (int i = 0; i < gradientMap.length - 1; i++) { + if (gray == gradientMap[i].node) { + // Coord gray matches a gradient node + rTo = red (gradientMap[i].color); + gTo = green(gradientMap[i].color); + bTo = blue (gradientMap[i].color); + } else if (gray >= gradientMap[i].node && gray <= gradientMap[i+1].node) { + return interpolateColors(normalize(gray, gradientMap[i].node, gradientMap[i+1].node), gradientMap[i].color, gradientMap[i+1].color, a); + } + } + } + + return getColorFromARGB(rTo, gTo, bTo, a); + } + + public static int interpolateColors(float placement, int color1, int color2, int alpha) { + int r1 = red (color1); + int g1 = green(color1); + int b1 = blue (color1); + int r2 = red (color2); + int g2 = green(color2); + int b2 = blue (color2); + + return getColorFromARGB( + parabolicInterpolation(placement, r1, r2), + parabolicInterpolation(placement, g1, g2), + parabolicInterpolation(placement, b1, b2), alpha); + } + + // Normally, a regular mathematical interpolation function would be linear, except these are colors. + // Colors being linearly interpolated would produce colors that appear a little more 'dull' than + // interpolating parabolically which makes the transition appear more vibrant. + public static int parabolicInterpolation(float placement, float v1, float v2) { + return (int) sqrt(((v1 * v1) * (1.0f - placement)) + ((v2 * v2) * placement)); + } + + public static float normalize(float valueIn, float minimumValue, float maximumValue) { + return (valueIn - minimumValue) / (maximumValue - minimumValue); + } + + static int red(int pixel) { + return pixel >> 16 & 0xFF; + } + + static int green(int pixel) { + return pixel >> 8 & 0xFF; + } + + static int blue(int pixel) { + return pixel & 0xFF; + } + + static int getColorFromARGB(int r, int g, int b, int a) { + return (((a << 8) + r << 8) + g << 8) + b; + } + + // getPerceptualBrightness will produce an accurate gray value from the colors. + // Thanks TTFTCUTS! :) + private static int getPerceptualBrightness(int col) { + return getPerceptualBrightness(red(col) / 255.0, green(col) / 255.0, blue(col) / 255.0); + } + + private static int getPerceptualBrightness(double r, double g, double b) { + return (int) (Math.sqrt(0.241 * r * r + 0.691 * g * g + 0.068 * b * b) * 255); + } +} diff --git a/src/main/java/twilightforest/client/texture/GradientNode.java b/src/main/java/twilightforest/client/texture/GradientNode.java new file mode 100644 index 0000000000..75165af483 --- /dev/null +++ b/src/main/java/twilightforest/client/texture/GradientNode.java @@ -0,0 +1,12 @@ +package twilightforest.client.texture; + +public class GradientNode { + public GradientNode() {} + public GradientNode(float node, int color) { + this.node = node; + this.color = color; + } + + public float node; + public int color; +} diff --git a/src/main/java/twilightforest/client/texture/MoltenFieryTexture.java b/src/main/java/twilightforest/client/texture/MoltenFieryTexture.java new file mode 100644 index 0000000000..f6badf3a1f --- /dev/null +++ b/src/main/java/twilightforest/client/texture/MoltenFieryTexture.java @@ -0,0 +1,102 @@ +package twilightforest.client.texture; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +import java.util.Collection; +import java.util.function.Function; + +public class MoltenFieryTexture extends TextureAtlasSprite { + private final ResourceLocation textureDependency; + private float minimumValue; + private float maximumValue; + + private static final GradientNode[] GRADIENT_MAP = { + new GradientNode(0.0f, 0xFF_08_06_06), + new GradientNode(0.2f, 0xFF_19_13_13), + new GradientNode(0.7f, 0xFF_3C_23_23) + }; + + public MoltenFieryTexture(ResourceLocation textureDependency, ResourceLocation spriteName) { + super(spriteName.toString()); + this.textureDependency = textureDependency; + } + + @Override + public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) { + return true; + } + + @Override + public boolean load(IResourceManager manager, ResourceLocation location, Function textureGetter) { + final TextureAtlasSprite sprite = textureGetter.apply(textureDependency); + + copyFrom(sprite); + this.animationMetadata = sprite.animationMetadata; + + this.framesTextureData = Lists.newArrayList(); + + int minimumValue = 255; + int maximumValue = 0; + + for (int i = 0; i < sprite.getFrameCount(); i++) { + final int[][] textureFrom = sprite.getFrameTextureData(i).clone(); + int [][] textureTo = new int[textureFrom.length][]; + + for (int j = 0; j < textureFrom.length; j++) { + textureTo[j] = new int[textureFrom[j].length]; + System.arraycopy(textureFrom[j], 0, textureTo[j], 0, textureFrom[j].length); + } + + for (int pixel : textureTo[0]) { + if ((pixel >> 24 & 0xFF) == 0) continue; + + minimumValue = Math.min(minimumValue, getPerceptualBrightness(pixel)); + maximumValue = Math.max(maximumValue, getPerceptualBrightness(pixel)); + } + + this.framesTextureData.add(i, textureTo); + } + + if (minimumValue > maximumValue) { + this.minimumValue = maximumValue / 255f; + this.maximumValue = minimumValue / 255f; + } else { + this.minimumValue = minimumValue / 255f; + this.maximumValue = maximumValue / 255f; + } + + for (int i = 0; i < framesTextureData.size(); i++) { + int [][] texture = this.framesTextureData.get(i); + + for (int l = 0; l < texture.length; l++) { + for (int j = 0; j < texture[l].length; j++) { + texture[l][j] = GradientMappedTexture.getGradient(texture[l][j], GRADIENT_MAP, this.minimumValue, this.maximumValue); + } + } + } + + TwilightForestMod.LOGGER.debug("Autogenerated {} from {}", this.getIconName(), this.textureDependency); + + return false; + } + + @Override + public Collection getDependencies() { + return ImmutableList.of(textureDependency); + } + + // borrowed from Shadows of Physis + // Thanks TTFTCUTS! :) + private static int getPerceptualBrightness(int col) { + return getPerceptualBrightness((col >> 16 & 0xFF) / 255.0, (col >> 8 & 0xFF) / 255.0, (col & 0xFF) / 255.0); + } + + private static int getPerceptualBrightness(double r, double g, double b) { + return (int) (Math.sqrt(0.241 * r * r + 0.691 * g * g + 0.068 * b * b) * 255); + } +} diff --git a/src/main/java/twilightforest/client/texture/render/CTMLogicEast.java b/src/main/java/twilightforest/client/texture/render/CTMLogicEast.java new file mode 100644 index 0000000000..bda5e359aa --- /dev/null +++ b/src/main/java/twilightforest/client/texture/render/CTMLogicEast.java @@ -0,0 +1,28 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package twilightforest.client.texture.render; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.client.util.CTMLogic; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +public class CTMLogicEast extends CTMLogic { + public static CTMLogicEast getInstance() { + return new CTMLogicEast(); + } + + @Override + public boolean isConnected(IBlockAccess world, BlockPos current, BlockPos connection, EnumFacing dir, IBlockState state) { + BlockPos difference = current.subtract(connection); + + return super.isConnected(world, current, current.add(new BlockPos(difference.getZ(), -difference.getX(), difference.getY())), dir, state); + } +} diff --git a/src/main/java/twilightforest/client/texture/render/CTMLogicNorth.java b/src/main/java/twilightforest/client/texture/render/CTMLogicNorth.java new file mode 100644 index 0000000000..b0fa8aaf0d --- /dev/null +++ b/src/main/java/twilightforest/client/texture/render/CTMLogicNorth.java @@ -0,0 +1,28 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package twilightforest.client.texture.render; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.client.util.CTMLogic; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +public class CTMLogicNorth extends CTMLogic { + public static CTMLogicNorth getInstance() { + return new CTMLogicNorth(); + } + + @Override + public boolean isConnected(IBlockAccess world, BlockPos current, BlockPos connection, EnumFacing dir, IBlockState state) { + BlockPos difference = current.subtract(connection); + + return super.isConnected(world, current, current.add(new BlockPos(difference.getX(), difference.getZ(), difference.getY())), dir, state); + } +} diff --git a/src/main/java/twilightforest/client/texture/render/CTMLogicSouth.java b/src/main/java/twilightforest/client/texture/render/CTMLogicSouth.java new file mode 100644 index 0000000000..28603d6606 --- /dev/null +++ b/src/main/java/twilightforest/client/texture/render/CTMLogicSouth.java @@ -0,0 +1,28 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package twilightforest.client.texture.render; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.client.util.CTMLogic; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +public class CTMLogicSouth extends CTMLogic { + public static CTMLogicSouth getInstance() { + return new CTMLogicSouth(); + } + + @Override + public boolean isConnected(IBlockAccess world, BlockPos current, BlockPos connection, EnumFacing dir, IBlockState state) { + BlockPos difference = current.subtract(connection); + + return super.isConnected(world, current, current.add(new BlockPos(-difference.getX(), difference.getZ(), difference.getY())), dir, state); + } +} diff --git a/src/main/java/twilightforest/client/texture/render/CTMLogicWest.java b/src/main/java/twilightforest/client/texture/render/CTMLogicWest.java new file mode 100644 index 0000000000..a1d71c61ec --- /dev/null +++ b/src/main/java/twilightforest/client/texture/render/CTMLogicWest.java @@ -0,0 +1,28 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +package twilightforest.client.texture.render; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.client.util.CTMLogic; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +public class CTMLogicWest extends CTMLogic { + public static CTMLogicWest getInstance() { + return new CTMLogicWest(); + } + + @Override + public boolean isConnected(IBlockAccess world, BlockPos current, BlockPos connection, EnumFacing dir, IBlockState state) { + BlockPos difference = current.subtract(connection); + + return super.isConnected(world, current, current.add(new BlockPos(-difference.getZ(), difference.getX(), difference.getY())), dir, state); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/texture/type/TextureTypeCTMEast.java b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMEast.java new file mode 100644 index 0000000000..9cc8450ddf --- /dev/null +++ b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMEast.java @@ -0,0 +1,41 @@ +package twilightforest.client.texture.type; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.api.texture.ICTMTexture; +import team.chisel.ctm.api.texture.TextureType; +import team.chisel.ctm.api.util.TextureInfo; +import team.chisel.ctm.client.model.AbstractCTMBakedModel; +import team.chisel.ctm.client.texture.ctx.TextureContextCTM; +import team.chisel.ctm.client.texture.render.TextureCTM; +import team.chisel.ctm.client.texture.type.TextureTypeCTM; +import team.chisel.ctm.client.util.CTMLogic; +import twilightforest.client.texture.render.CTMLogicEast; + +import javax.annotation.Nonnull; + +@TextureType("ctm_tf_east") +public class TextureTypeCTMEast extends TextureTypeCTM { + + @Override + public ICTMTexture makeTexture(TextureInfo info) { + return new TextureCTM(this, info); + } + + @Override + public TextureContextCTM getBlockRenderContext(IBlockState state, IBlockAccess world, BlockPos pos, ICTMTexture tex) { + return new TextureContextCTM(state, world, pos, (TextureCTM) tex) { + @Override + protected CTMLogic createCTM(@Nonnull IBlockState state) { + IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state); + if (model instanceof AbstractCTMBakedModel) { + return CTMLogicEast.getInstance().ignoreStates(((AbstractCTMBakedModel) model).getModel().ignoreStates()); + } + return CTMLogicEast.getInstance(); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/texture/type/TextureTypeCTMNorth.java b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMNorth.java new file mode 100644 index 0000000000..a70890c123 --- /dev/null +++ b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMNorth.java @@ -0,0 +1,41 @@ +package twilightforest.client.texture.type; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.api.texture.ICTMTexture; +import team.chisel.ctm.api.texture.TextureType; +import team.chisel.ctm.api.util.TextureInfo; +import team.chisel.ctm.client.model.AbstractCTMBakedModel; +import team.chisel.ctm.client.texture.ctx.TextureContextCTM; +import team.chisel.ctm.client.texture.render.TextureCTM; +import team.chisel.ctm.client.texture.type.TextureTypeCTM; +import team.chisel.ctm.client.util.CTMLogic; +import twilightforest.client.texture.render.CTMLogicNorth; + +import javax.annotation.Nonnull; + +@TextureType("ctm_tf_north") +public class TextureTypeCTMNorth extends TextureTypeCTM { + + @Override + public ICTMTexture makeTexture(TextureInfo info) { + return new TextureCTM(this, info); + } + + @Override + public TextureContextCTM getBlockRenderContext(IBlockState state, IBlockAccess world, BlockPos pos, ICTMTexture tex) { + return new TextureContextCTM(state, world, pos, (TextureCTM) tex) { + @Override + protected CTMLogic createCTM(@Nonnull IBlockState state) { + IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state); + if (model instanceof AbstractCTMBakedModel) { + return CTMLogicNorth.getInstance().ignoreStates(((AbstractCTMBakedModel) model).getModel().ignoreStates()); + } + return CTMLogicNorth.getInstance(); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/texture/type/TextureTypeCTMSouth.java b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMSouth.java new file mode 100644 index 0000000000..245248f961 --- /dev/null +++ b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMSouth.java @@ -0,0 +1,41 @@ +package twilightforest.client.texture.type; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.api.texture.ICTMTexture; +import team.chisel.ctm.api.texture.TextureType; +import team.chisel.ctm.api.util.TextureInfo; +import team.chisel.ctm.client.model.AbstractCTMBakedModel; +import team.chisel.ctm.client.texture.ctx.TextureContextCTM; +import team.chisel.ctm.client.texture.render.TextureCTM; +import team.chisel.ctm.client.texture.type.TextureTypeCTM; +import team.chisel.ctm.client.util.CTMLogic; +import twilightforest.client.texture.render.CTMLogicSouth; + +import javax.annotation.Nonnull; + +@TextureType("ctm_tf_south") +public class TextureTypeCTMSouth extends TextureTypeCTM { + + @Override + public ICTMTexture makeTexture(TextureInfo info) { + return new TextureCTM(this, info); + } + + @Override + public TextureContextCTM getBlockRenderContext(IBlockState state, IBlockAccess world, BlockPos pos, ICTMTexture tex) { + return new TextureContextCTM(state, world, pos, (TextureCTM) tex) { + @Override + protected CTMLogic createCTM(@Nonnull IBlockState state) { + IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state); + if (model instanceof AbstractCTMBakedModel) { + return CTMLogicSouth.getInstance().ignoreStates(((AbstractCTMBakedModel) model).getModel().ignoreStates()); + } + return CTMLogicSouth.getInstance(); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/client/texture/type/TextureTypeCTMWest.java b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMWest.java new file mode 100644 index 0000000000..37d2920280 --- /dev/null +++ b/src/main/java/twilightforest/client/texture/type/TextureTypeCTMWest.java @@ -0,0 +1,41 @@ +package twilightforest.client.texture.type; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import team.chisel.ctm.api.texture.ICTMTexture; +import team.chisel.ctm.api.texture.TextureType; +import team.chisel.ctm.api.util.TextureInfo; +import team.chisel.ctm.client.model.AbstractCTMBakedModel; +import team.chisel.ctm.client.texture.ctx.TextureContextCTM; +import team.chisel.ctm.client.texture.render.TextureCTM; +import team.chisel.ctm.client.texture.type.TextureTypeCTM; +import team.chisel.ctm.client.util.CTMLogic; +import twilightforest.client.texture.render.CTMLogicWest; + +import javax.annotation.Nonnull; + +@TextureType("ctm_tf_west") +public class TextureTypeCTMWest extends TextureTypeCTM { + + @Override + public ICTMTexture makeTexture(TextureInfo info) { + return new TextureCTM(this, info); + } + + @Override + public TextureContextCTM getBlockRenderContext(IBlockState state, IBlockAccess world, BlockPos pos, ICTMTexture tex) { + return new TextureContextCTM(state, world, pos, (TextureCTM) tex) { + @Override + protected CTMLogic createCTM(@Nonnull IBlockState state) { + IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state); + if (model instanceof AbstractCTMBakedModel) { + return CTMLogicWest.getInstance().ignoreStates(((AbstractCTMBakedModel) model).getModel().ignoreStates()); + } + return CTMLogicWest.getInstance(); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/compat/Baubles.java b/src/main/java/twilightforest/compat/Baubles.java new file mode 100644 index 0000000000..b95c224601 --- /dev/null +++ b/src/main/java/twilightforest/compat/Baubles.java @@ -0,0 +1,99 @@ +package twilightforest.compat; + +import baubles.api.BaubleType; +import baubles.api.BaublesApi; +import baubles.api.IBauble; +import baubles.api.cap.BaublesCapabilities; +import baubles.api.cap.IBaublesItemHandler; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.items.ItemHandlerHelper; +import twilightforest.TwilightForestMod; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.function.Predicate; + +public class Baubles { + + public static boolean consumeInventoryItem(EntityPlayer player, Predicate matcher, int count) { + + IBaublesItemHandler baubles = BaublesApi.getBaublesHandler(player); + boolean consumedSome = false; + + int slots = baubles.getSlots(); + for (int i = 0; i < slots && count > 0; i++) { + ItemStack stack = baubles.getStackInSlot(i); + if (matcher.test(stack)) { + ItemStack consumed = baubles.extractItem(i, count, false); + count -= consumed.getCount(); + consumedSome = true; + } + } + + return consumedSome; + } + + public static NonNullList keepBaubles(EntityPlayer player) { + + IBaublesItemHandler baubles = BaublesApi.getBaublesHandler(player); + NonNullList kept = NonNullList.withSize(baubles.getSlots(), ItemStack.EMPTY); + + for (int i = 0; i < baubles.getSlots(); i++) { + kept.set(i, baubles.getStackInSlot(i).copy()); + baubles.setStackInSlot(i, ItemStack.EMPTY); + } + + return kept; + } + + public static void returnBaubles(EntityPlayer player, NonNullList items) { + + IBaublesItemHandler baubles = BaublesApi.getBaublesHandler(player); + + if (items.size() != baubles.getSlots()) { + TwilightForestMod.LOGGER.warn("The list size doesn't equal amount of bauble slots, wtf did you do?"); + giveItems(player, items); + return; + } + + NonNullList displaced = NonNullList.create(); + + for (int i = 0; i < baubles.getSlots(); i++) { + ItemStack kept = items.get(i); + if (!kept.isEmpty()) { + ItemStack existing = baubles.getStackInSlot(i); + baubles.setStackInSlot(i, kept); + if (!existing.isEmpty()) { + displaced.add(existing); + } + } + } + + giveItems(player, displaced); + } + + private static void giveItems(EntityPlayer player, NonNullList items) { + for (ItemStack stack : items) { + ItemHandlerHelper.giveItemToPlayer(player, stack); + } + } + + @SuppressWarnings("unchecked") + public static final class BasicBaubleProvider implements ICapabilityProvider { + @Override + public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { + return capability == BaublesCapabilities.CAPABILITY_ITEM_BAUBLE; + } + + @Nullable + @Override + public T getCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { + return capability == BaublesCapabilities.CAPABILITY_ITEM_BAUBLE ? (T) (IBauble) itemStack -> BaubleType.TRINKET : null; + } + } +} diff --git a/src/main/java/twilightforest/compat/JEI.java b/src/main/java/twilightforest/compat/JEI.java new file mode 100644 index 0000000000..7b5ccc6419 --- /dev/null +++ b/src/main/java/twilightforest/compat/JEI.java @@ -0,0 +1,21 @@ +package twilightforest.compat; + +import mezz.jei.api.IModPlugin; +import mezz.jei.api.IModRegistry; +import mezz.jei.api.JEIPlugin; +import mezz.jei.api.recipe.VanillaRecipeCategoryUid; +import mezz.jei.api.recipe.transfer.IRecipeTransferRegistry; +import net.minecraft.item.ItemStack; +import twilightforest.block.TFBlocks; + +@JEIPlugin +public class JEI implements IModPlugin { + @Override + public void register(IModRegistry registry) { + registry.addRecipeCatalyst(new ItemStack(TFBlocks.uncrafting_table), VanillaRecipeCategoryUid.CRAFTING); + + IRecipeTransferRegistry recipeTransferRegistry = registry.getRecipeTransferRegistry(); + + recipeTransferRegistry.addRecipeTransferHandler(new UncraftingRecipeTransferHandler()); + } +} diff --git a/src/main/java/twilightforest/compat/TConstruct.java b/src/main/java/twilightforest/compat/TConstruct.java new file mode 100644 index 0000000000..5f74209d16 --- /dev/null +++ b/src/main/java/twilightforest/compat/TConstruct.java @@ -0,0 +1,124 @@ +package twilightforest.compat; + +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.relauncher.Side; +import slimeknights.tconstruct.library.MaterialIntegration; +import slimeknights.tconstruct.library.TinkerRegistry; +import slimeknights.tconstruct.library.client.material.MaterialRenderInfoLoader; +import slimeknights.tconstruct.library.materials.*; +import slimeknights.tconstruct.library.traits.AbstractTrait; +import slimeknights.tconstruct.library.utils.HarvestLevels; +import slimeknights.tconstruct.tools.TinkerTraits; +import twilightforest.block.RegisterBlockEvent; +import twilightforest.compat.tcon.texture.FieryInfoDeserializer; +import twilightforest.compat.tcon.texture.GradientMapInfoDeserializer; +import twilightforest.compat.tcon.trait.*; +import twilightforest.item.TFItems; + +public class TConstruct { + + public static final Material nagascale = new Material("nagascale" , 0x32_5D_25); + public static final Material steeleaf = new Material("steeleaf" , 0x52_87_3A); + public static final Material fierymetal = new Material("fierymetal" , 0xFD_D4_5D); + public static final Material knightmetal = new Material("knightmetal" , 0xC4_E6_AE); + public static final Material ravenFeather = new Material("raven_feather", 0x47_4C_52); + + public static final AbstractTrait twilit = new TraitTwilit(); + public static final AbstractTrait precipitate = new TraitPrecipitate(); + public static final AbstractTrait stalwart = new TraitStalwart(); + public static final AbstractTrait synergy = new TraitSynergy(); + public static final AbstractTrait veiled = new TraitVeiled(); + + static void preInit() { + TinkerRegistry.addMaterialStats(TConstruct.nagascale, + new HeadMaterialStats(460, 8.9f, 4.3f, HarvestLevels.IRON), + new BowMaterialStats(0.6f, 2f, 0f), + new ArrowShaftMaterialStats(1.4f, 20) + ); + TinkerRegistry.integrate(TConstruct.nagascale).preInit(); + + TinkerRegistry.addMaterialStats(TConstruct.steeleaf, + new HeadMaterialStats(180, 7f, 6f, HarvestLevels.DIAMOND), + new HandleMaterialStats(0.8f, 100), + new ExtraMaterialStats(90), + new BowMaterialStats(1.2f, 1.5f, 2f), + new ArrowShaftMaterialStats(0.6f, 10), + new FletchingMaterialStats(1f, 0.8f) + ); + TinkerRegistry.integrate(new MaterialIntegration(TConstruct.steeleaf, null, "Steeleaf")).toolforge().preInit(); + + TinkerRegistry.addMaterialStats(TConstruct.fierymetal, + new HeadMaterialStats(720, 7.2f, 6.6f, HarvestLevels.OBSIDIAN), + new HandleMaterialStats(0.7f, 400), + new ExtraMaterialStats(200), + new BowMaterialStats(1f, 0.9f, 4f), + new ArrowShaftMaterialStats(0.8f, 0) + ); + TinkerRegistry.integrate(new MaterialIntegration(TConstruct.fierymetal, RegisterBlockEvent.moltenFiery, "Fiery")).toolforge().preInit(); + + TinkerRegistry.addMaterialStats(TConstruct.knightmetal, + new HeadMaterialStats(900, 7f, 6f, HarvestLevels.COBALT), + new HandleMaterialStats(1.25f, 100), + new ExtraMaterialStats(400) + ); + TinkerRegistry.integrate(new MaterialIntegration(TConstruct.knightmetal, RegisterBlockEvent.moltenKnightmetal, "Knightmetal")).preInit(); + + TinkerRegistry.addMaterialStats(TConstruct.ravenFeather, + new FletchingMaterialStats(0.95f, 1.15f) + ); + TinkerRegistry.integrate(TConstruct.ravenFeather).preInit(); + + if (FMLCommonHandler.instance().getSide() == Side.CLIENT) { + MaterialRenderInfoLoader.addRenderInfo("gradient_map_colors", GradientMapInfoDeserializer.class); + MaterialRenderInfoLoader.addRenderInfo("fierymetal", FieryInfoDeserializer.class); + } + } + + static void init() { + TConstruct.nagascale.addItem(TFItems.naga_scale, 1, Material.VALUE_Ingot); + TConstruct.nagascale + .addTrait(TConstruct.twilit) + .addTrait(TConstruct.precipitate) + .setCraftable(true).setCastable(false) + .setRepresentativeItem(TFItems.naga_scale); + + TConstruct.steeleaf.addCommonItems("Steeleaf"); + TConstruct.steeleaf + .addTrait(TConstruct.twilit) + .addTrait(TConstruct.synergy) + .setCraftable(true).setCastable(false) + .setRepresentativeItem(TFItems.steeleaf_ingot); + + TConstruct.fierymetal.addCommonItems("Fiery"); + TConstruct.fierymetal + .addTrait(TConstruct.twilit) + .addTrait(TinkerTraits.flammable) + .addTrait(TConstruct.twilit, MaterialTypes.HEAD) + .addTrait(TinkerTraits.autosmelt, MaterialTypes.HEAD) + .addTrait(TinkerTraits.superheat, MaterialTypes.HEAD) + .addTrait(TinkerTraits.flammable, MaterialTypes.HEAD) + .setCraftable(false).setCastable(true) + .setRepresentativeItem(TFItems.fiery_ingot); + + TConstruct.knightmetal.addCommonItems("Knightmetal"); + TConstruct.knightmetal.addItem(TFItems.armor_shard, 1, Material.VALUE_Nugget); + TConstruct.knightmetal.addItem(TFItems.block_and_chain, 1, (Material.VALUE_Ingot * 7) + Material.VALUE_Block); + TConstruct.knightmetal + .addTrait(TConstruct.twilit) + .addTrait(TConstruct.stalwart) + .setCraftable(false).setCastable(true) + .setRepresentativeItem(TFItems.knightmetal_ingot); + + TConstruct.ravenFeather.addItem(TFItems.raven_feather, 1, Material.VALUE_Ingot); + TConstruct.ravenFeather + .addTrait(TConstruct.twilit) + .addTrait(TConstruct.veiled) + .setCraftable(true).setCastable(false) + .setRepresentativeItem(TFItems.raven_feather); + } + + static void postInit() { + TinkerRegistry.registerSmelteryFuel(new FluidStack(RegisterBlockEvent.essenceFiery, 50), 1000); + } +} diff --git a/src/main/java/twilightforest/compat/TFCompat.java b/src/main/java/twilightforest/compat/TFCompat.java new file mode 100644 index 0000000000..ef37117662 --- /dev/null +++ b/src/main/java/twilightforest/compat/TFCompat.java @@ -0,0 +1,255 @@ +package twilightforest.compat; + +import net.minecraft.block.Block; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityFallingBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.NonNullList; +import net.minecraft.util.SoundCategory; +import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.event.FMLInterModComms; +import net.minecraftforge.fml.relauncher.Side; +import org.apache.commons.lang3.tuple.Pair; +import twilightforest.TFSounds; +import twilightforest.TwilightForestMod; +import twilightforest.block.TFBlocks; +import twilightforest.compat.ie.IEShaderRegister; +import twilightforest.compat.ie.ItemTFShader; +import twilightforest.compat.ie.ItemTFShaderGrabbag; +import twilightforest.entity.boss.*; +import twilightforest.enums.TowerWoodVariant; +import twilightforest.item.RegisterItemEvent; + +import java.util.Locale; + +public enum TFCompat { + + BAUBLES("Baubles"), + CHISEL("Chisel") { + @Override + public void init() { + addBlockToCarvingGroup("stonebrick", TFBlocks.spiral_bricks); + + addBlockToCarvingGroup("nagastone", TFBlocks.etched_nagastone); + addBlockToCarvingGroup("nagastone", TFBlocks.nagastone_pillar); + addBlockToCarvingGroup("nagastone", TFBlocks.etched_nagastone_mossy); + addBlockToCarvingGroup("nagastone", TFBlocks.nagastone_pillar_mossy); + addBlockToCarvingGroup("nagastone", TFBlocks.etched_nagastone_weathered); + addBlockToCarvingGroup("nagastone", TFBlocks.nagastone_pillar_weathered); + addVariantsToCarvingGroup("nagastone", TFBlocks.naga_stone); + + addVariantsToCarvingGroup("nagastonestairs", TFBlocks.nagastone_stairs); + addVariantsToCarvingGroup("nagastonestairs", TFBlocks.nagastone_stairs_mossy); + addVariantsToCarvingGroup("nagastonestairs", TFBlocks.nagastone_stairs_weathered); + + addVariantsToCarvingGroup("mazestone", TFBlocks.maze_stone); + + addVariantsToCarvingGroup("underbrick", TFBlocks.underbrick); + + for (TowerWoodVariant variant : TowerWoodVariant.values()) { + if (variant != TowerWoodVariant.INFESTED) { + addToCarvingGroup("towerwood", new ItemStack(TFBlocks.tower_wood, 1, variant.ordinal())); + } + } + + addVariantsToCarvingGroup("deadrock", TFBlocks.deadrock); + + addVariantsToCarvingGroup("castlebrick", TFBlocks.castle_brick); + addVariantsToCarvingGroup("castlebrick", TFBlocks.castle_pillar); + + addVariantsToCarvingGroup("castlebrickstairs", TFBlocks.castle_stairs); + addBlockToCarvingGroup("castlebrickstairs", TFBlocks.castle_stairs_brick); + addBlockToCarvingGroup("castlebrickstairs", TFBlocks.castle_stairs_cracked); + addBlockToCarvingGroup("castlebrickstairs", TFBlocks.castle_stairs_worn); + addBlockToCarvingGroup("castlebrickstairs", TFBlocks.castle_stairs_mossy); + + addBlockToCarvingGroup("terrorcotta", TFBlocks.terrorcotta_circle); + addBlockToCarvingGroup("terrorcotta", TFBlocks.terrorcotta_diagonal); + } + + private void addVariantsToCarvingGroup(String group, Block block) { + NonNullList variants = NonNullList.create(); + block.getSubBlocks(CreativeTabs.SEARCH, variants); + for (ItemStack stack : variants) { + addToCarvingGroup(group, stack); + } + } + + private void addBlockToCarvingGroup(String group, Block block) { + addToCarvingGroup(group, new ItemStack(block)); + } + + private void addToCarvingGroup(String group, ItemStack stack) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setString("group", group); + nbt.setTag("stack", stack.serializeNBT()); + FMLInterModComms.sendMessage("chisel", "add_variation", nbt); + } + }, + FORESTRY("Forestry"), + IMMERSIVEENGINEERING("Immersive Engineering") { + + @Override + protected void initItems(RegisterItemEvent.ItemRegistryHelper items) { + items.register("shader", ItemTFShader.shader.setTranslationKey("tfEngineeringShader")); + items.register("shader_bag", ItemTFShaderGrabbag.shader_bag.setTranslationKey("tfEngineeringShaderBag")); + + new IEShaderRegister(); // Calling to initialize it all + } + + @Override + protected void init() { + // Yeah, it's a thing! https://twitter.com/AtomicBlom/status/1004931868012056583 + blusunrize.immersiveengineering.api.tool.RailgunHandler.projectilePropertyMap.add(Pair.of(blusunrize.immersiveengineering.api.ApiUtils.createIngredientStack(TFBlocks.cicada), new blusunrize.immersiveengineering.api.tool.RailgunHandler.RailgunProjectileProperties(2, 0.25){ + @Override + public boolean overrideHitEntity(Entity entityHit, Entity shooter) { + World world = entityHit.getEntityWorld(); + + world.spawnEntity(new EntityFallingBlock(world, entityHit.posX, entityHit.posY, entityHit.posZ, TFBlocks.cicada.getDefaultState())); + + world.playSound(null, entityHit.posX, entityHit.posY, entityHit.posZ, TFSounds.CICADA, SoundCategory.NEUTRAL, 1.0f, (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F + 1.0F); + + return false; + } + })); + + excludeFromShaderBags(EntityTFNaga.class); + + excludeFromShaderBags(EntityTFLich.class); + + excludeFromShaderBags(EntityTFMinoshroom.class); + excludeFromShaderBags(EntityTFHydra.class); + + excludeFromShaderBags(EntityTFKnightPhantom.class); + excludeFromShaderBags(EntityTFUrGhast.class); + + excludeFromShaderBags(EntityTFYetiAlpha.class); + excludeFromShaderBags(EntityTFSnowQueen.class); + } + + private void excludeFromShaderBags(Class entityClass) { + FMLInterModComms.sendMessage("immersiveengineering", "shaderbag_exclude", entityClass.getName()); + } + }, + JEI("Just Enough Items"), + TCONSTRUCT("Tinkers' Construct") { + @Override + protected boolean preInit() { + TConstruct.preInit(); + return true; + } + + @Override + protected void init() { + TConstruct.init(); + } + + @Override + protected void postInit() { + TConstruct.postInit(); + } + }, + THAUMCRAFT("Thaumcraft") { + @Override + protected boolean preInit() { + MinecraftForge.EVENT_BUS.register(Thaumcraft.class); + return true; + } + }; + + private static final TFCompat[] VALUES = values(); + + protected boolean preInit() { return true; } + protected void init() {} + protected void postInit() {} + + protected void initItems(RegisterItemEvent.ItemRegistryHelper items) {} + + private final String modName; + + private boolean isActivated = false; + + public boolean isActivated() { + return isActivated; + } + + TFCompat(String modName) { + this.modName = modName; + } + + public static void initCompatItems(RegisterItemEvent.ItemRegistryHelper items) { + for (TFCompat compat : VALUES) { + if (compat.isActivated) { + try { + compat.initItems(items); + } catch (Exception e) { + compat.isActivated = false; + TwilightForestMod.LOGGER.error("Had a {} error loading {} compatibility in initializing items!", e.getLocalizedMessage(), compat.modName); + TwilightForestMod.LOGGER.catching(e.fillInStackTrace()); + } + } + } + } + + public static void preInitCompat() { + for (TFCompat compat : VALUES) { + if (Loader.isModLoaded(compat.name().toLowerCase(Locale.ROOT))) { + try { + compat.isActivated = compat.preInit(); + + if (compat.isActivated) { + TwilightForestMod.LOGGER.info("Loaded compatibility for mod {}.", compat.modName); + } else { + TwilightForestMod.LOGGER.warn("Couldn't activate compatibility for mod {}!", compat.modName); + } + } catch (Exception e) { + compat.isActivated = false; + TwilightForestMod.LOGGER.error("Had a {} error loading {} compatibility in preInit!", e.getLocalizedMessage(), compat.modName); + TwilightForestMod.LOGGER.catching(e.fillInStackTrace()); + } + } else { + compat.isActivated = false; + TwilightForestMod.LOGGER.info("Skipped compatibility for mod {}.", compat.modName); + } + } + } + + public static void initCompat() { + for (TFCompat compat : VALUES) { + if (compat.isActivated) { + try { + compat.init(); + } catch (Exception e) { + compat.isActivated = false; + TwilightForestMod.LOGGER.error("Had a {} error loading {} compatibility in init!", e.getLocalizedMessage(), compat.modName); + TwilightForestMod.LOGGER.catching(e.fillInStackTrace()); + } + } + } + } + + public static void postInitCompat() { + for (TFCompat compat : VALUES) { + if (compat.isActivated) { + try { + compat.postInit(); + } catch (Exception e) { + compat.isActivated = false; + TwilightForestMod.LOGGER.error("Had a {} error loading {} compatibility in postInit!", e.getLocalizedMessage(), compat.modName); + TwilightForestMod.LOGGER.catching(e.fillInStackTrace()); + } + } + } + } + + static void registerSidedHandler(Side side, Object handler) { + if (FMLCommonHandler.instance().getSide() == side) { + MinecraftForge.EVENT_BUS.register(handler); + } + } +} diff --git a/src/main/java/twilightforest/compat/Thaumcraft.java b/src/main/java/twilightforest/compat/Thaumcraft.java new file mode 100644 index 0000000000..0bb2eac412 --- /dev/null +++ b/src/main/java/twilightforest/compat/Thaumcraft.java @@ -0,0 +1,869 @@ +package twilightforest.compat; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.oredict.OreDictionary; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.AspectRegistryEvent; +import twilightforest.TwilightForestMod; +import twilightforest.block.TFBlocks; +import twilightforest.item.TFItems; + +public class Thaumcraft { + // Use the thaumcraft API to register our things with aspects and biomes with values + @SubscribeEvent + public static void registerAspects(AspectRegistryEvent event) { + TwilightForestMod.LOGGER.debug("Attempting to register Thaumcraft Aspects for Twilight Forest items!"); + + try { + TFAspectRegisterHelper helper = new TFAspectRegisterHelper(event); + + helper.registerTCObjectTag(TFBlocks.twilight_log, new int[]{0, 1}, new AspectList() + .add(Aspect.PLANT, 20)); + + helper.registerTCObjectTag(TFBlocks.twilight_log, 2, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.WATER, 5)); + + helper.registerTCObjectTag(TFBlocks.twilight_log, 3, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.DARKNESS, 5)); + + helper.registerTCObjectTag(TFBlocks.root, 0, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.EARTH, 10)); + + helper.registerTCObjectTag(TFBlocks.root, 1, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.EARTH, 10) + .add(Aspect.LIFE, 10)); + + helper.registerTCObjectTag(TFBlocks.twilight_leaves, -1, new AspectList() + .add(Aspect.PLANT, 5)); + + helper.registerTCObjectTag(TFBlocks.firefly, -1, new AspectList() + .add(Aspect.LIGHT, 5) + .add(Aspect.LIFE, 2)); + + helper.registerTCObjectTag(TFBlocks.cicada, -1, new AspectList() + .add(Aspect.SENSES, 6) + .add(Aspect.LIFE, 2)); + + helper.registerTCObjectTag(TFBlocks.maze_stone, 0, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.TRAP, 1)); + + helper.registerTCObjectTag(TFBlocks.maze_stone, 1, new AspectList() + .add(Aspect.EARTH, 3) + .add(Aspect.TRAP, 1)); + + helper.registerTCObjectTag(TFBlocks.maze_stone, new int[]{2, 3, 6, 7}, new AspectList() + .add(Aspect.EARTH, 3) + .add(Aspect.TRAP, 1) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.maze_stone, 4, new AspectList() + .add(Aspect.EARTH, 3) + .add(Aspect.TRAP, 1) + .add(Aspect.ENTROPY, 1)); + + helper.registerTCObjectTag(TFBlocks.maze_stone, 5, new AspectList() + .add(Aspect.EARTH, 3) + .add(Aspect.TRAP, 1) + .add(Aspect.PLANT, 1)); + + helper.registerTCObjectTag(TFBlocks.hedge, -1, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.AVERSION, 2)); + + helper.registerTCObjectTag(TFBlocks.firefly_jar, new AspectList() + .add(Aspect.CRYSTAL, 35) + .add(Aspect.LIGHT, 20) + .add(Aspect.SENSES, 10)); + + helper.registerTCObjectTag(TFBlocks.twilight_plant, 0, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.WATER, 2)); + + helper.registerTCObjectTag(TFBlocks.twilight_plant, new int[]{1, 2, 3, 5}, new AspectList() + .add(Aspect.PLANT, 5)); + + helper.registerTCObjectTag(TFBlocks.twilight_plant, 4, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.LIGHT, 5) + .add(Aspect.AIR, 5)); + + helper.registerTCObjectTag(TFBlocks.fire_jet, 0, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.AIR,16)); + + helper.registerTCObjectTag(TFBlocks.fire_jet, 3, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.FIRE, 16)); + + helper.registerTCObjectTag(TFBlocks.fire_jet, 1, new AspectList() + .add(Aspect.PLANT, 33) + .add(Aspect.AIR, 16) + .add(Aspect.ENERGY, 30) + .add(Aspect.MECHANISM, 20)); + + helper.registerTCObjectTag(TFBlocks.fire_jet, 6, new AspectList() + .add(Aspect.PLANT, 16) + .add(Aspect.FIRE, 46) + .add(Aspect.ENERGY, 22) + .add(Aspect.MECHANISM, 20)); + + helper.registerTCObjectTag(TFBlocks.naga_stone, -1, new AspectList() + .add(Aspect.EARTH, 3) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.twilight_sapling, 5, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.LIFE, 5) + .add(Aspect.AURA, 40)); + + helper.registerTCObjectTag(TFBlocks.twilight_sapling, 6, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.LIFE, 5) + .add(Aspect.EXCHANGE, 40)); + + helper.registerTCObjectTag(TFBlocks.twilight_sapling, 7, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.LIFE, 5) + .add(Aspect.DESIRE, 40)); + + helper.registerTCObjectTag(TFBlocks.twilight_sapling, 8, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.LIFE, 5) + .add(Aspect.ORDER, 40)); + + helper.registerTCObjectTag(TFBlocks.moonworm, -1, new AspectList() + .add(Aspect.LIGHT, 5) + .add(Aspect.LIFE, 2)); + + helper.registerTCObjectTag(TFBlocks.magic_log, 0, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.AURA, 3)); + + helper.registerTCObjectTag(TFBlocks.magic_log, 1, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.EXCHANGE, 3)); + + helper.registerTCObjectTag(TFBlocks.magic_log, 2, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.DESIRE, 3)); + + helper.registerTCObjectTag(TFBlocks.magic_log, 3, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.ORDER, 3)); + + helper.registerTCObjectTag(TFBlocks.magic_leaves, 0, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.AURA, 1)); + + helper.registerTCObjectTag(TFBlocks.magic_leaves, 1, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.EXCHANGE, 1)); + + helper.registerTCObjectTag(TFBlocks.magic_leaves, 2, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.DESIRE, 1)); + + helper.registerTCObjectTag(TFBlocks.magic_leaves, 3, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.magic_log_core, 0, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.AURA, 55)); + + helper.registerTCObjectTag(TFBlocks.magic_log_core, 1, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.EXCHANGE, 55)); + + helper.registerTCObjectTag(TFBlocks.magic_log_core, 2, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.DESIRE, 55)); + + helper.registerTCObjectTag(TFBlocks.magic_log_core, 3, new AspectList() + .add(Aspect.PLANT, 20) + .add(Aspect.ORDER, 55)); + + helper.registerTCObjectTag(TFBlocks.tower_wood, 2, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.ENTROPY, 3)); + + helper.registerTCObjectTag(TFBlocks.tower_wood, 3, new AspectList() + .add(Aspect.PLANT, 18)); + + helper.registerTCObjectTag(TFBlocks.tower_wood, 4, new AspectList() + .add(Aspect.PLANT, 15) + .add(Aspect.ENTROPY, 3) + .add(Aspect.BEAST, 5)); + + helper.registerTCObjectTag(TFBlocks.stronghold_shield, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.PROTECT, 5)); + + helper.registerTCObjectTag(TFBlocks.trophy_pedestal, -1, new AspectList() + .add(Aspect.MECHANISM, 35) + .add(Aspect.SENSES, 10) + .add(Aspect.EARTH, 5)); + + helper.registerTCObjectTag(TFBlocks.aurora_block, -1, new AspectList() + .add(Aspect.COLD, 6) + .add(Aspect.AURA, 1)); + + helper.registerTCObjectTag(TFBlocks.underbrick, new int[]{0, 3}, new AspectList() + .add(Aspect.EARTH, 3)); + + helper.registerTCObjectTag(TFBlocks.underbrick, 1, new AspectList() + .add(Aspect.EARTH, 3) + .add(Aspect.PLANT, 1)); + + helper.registerTCObjectTag(TFBlocks.underbrick, 2, new AspectList() + .add(Aspect.EARTH, 3) + .add(Aspect.ENTROPY, 1)); + + helper.registerTCObjectTag(TFBlocks.thorns, -1, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.AVERSION, 4)); + + helper.registerTCObjectTag(TFBlocks.burnt_thorns, -1, new AspectList() + .add(Aspect.ENTROPY, 5)); + + helper.registerTCObjectTag(TFBlocks.twilight_leaves_3, -1, new AspectList() + .add(Aspect.PLANT, 5)); + + helper.registerTCObjectTag(TFBlocks.deadrock, new int[]{0, 2}, new AspectList() + .add(Aspect.EARTH, 1) + .add(Aspect.VOID, 1)); + + helper.registerTCObjectTag(TFBlocks.deadrock, 1, new AspectList() + .add(Aspect.EARTH, 1) + .add(Aspect.VOID, 1) + .add(Aspect.ENTROPY, 1)); + + helper.registerTCObjectTag(TFBlocks.dark_leaves, -1, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.DARKNESS, 1)); + + helper.registerTCObjectTag(TFBlocks.aurora_pillar, -1, new AspectList() + .add(Aspect.COLD, 6) + .add(Aspect.ORDER, 2) + .add(Aspect.AURA, 1)); + + helper.registerTCObjectTag(TFBlocks.aurora_slab, -1, new AspectList() + .add(Aspect.COLD, 3) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.trollsteinn, new AspectList() + .add(Aspect.EARTH, 5)); + + helper.registerTCObjectTag(TFBlocks.wispy_cloud, new AspectList() + .add(Aspect.AIR, 20) + .add(Aspect.FLIGHT, 5)); + + helper.registerTCObjectTag(TFBlocks.fluffy_cloud, new AspectList() + .add(Aspect.AIR, 20) + .add(Aspect.FLIGHT, 5)); + + helper.registerTCObjectTag(TFBlocks.giant_cobblestone, new AspectList() + .add(Aspect.EARTH, 320) + .add(Aspect.ENTROPY, 64)); + + helper.registerTCObjectTag(TFBlocks.giant_log, new AspectList() + .add(Aspect.PLANT, 1280)); + + helper.registerTCObjectTag(TFBlocks.giant_leaves, new AspectList() + .add(Aspect.PLANT, 320)); + + helper.registerTCObjectTag(TFBlocks.giant_obsidian, new AspectList() + .add(Aspect.EARTH, 320) + .add(Aspect.FIRE, 320) + .add(Aspect.DARKNESS, 320)); + + helper.registerTCObjectTag(TFBlocks.uberous_soil, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.PLANT, 2) + .add(Aspect.LIFE, 15)); + + helper.registerTCObjectTag(TFBlocks.huge_stalk, new AspectList() + .add(Aspect.PLANT, 25)); + + helper.registerTCObjectTag(TFBlocks.huge_mushgloom, -1, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.LIGHT, 5) + .add(Aspect.AIR, 5)); + + helper.registerTCObjectTag(TFBlocks.trollvidr, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.DARKNESS, 3)); + + helper.registerTCObjectTag(TFBlocks.unripe_trollber, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.DARKNESS, 6)); + + helper.registerTCObjectTag(TFBlocks.trollber, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.LIGHT, 25) + .add(Aspect.DARKNESS, 3)); + + helper.registerTCObjectTag(TFBlocks.knightmetal_block, new AspectList() + .add(Aspect.METAL, 121) + .add(Aspect.CRAFT, 40) + .add(Aspect.AVERSION, 6)); + + helper.registerTCObjectTag(TFBlocks.huge_lilypad, -1, new AspectList() + .add(Aspect.PLANT, 25) + .add(Aspect.WATER, 5)); + + helper.registerTCObjectTag(TFBlocks.huge_waterlily, new AspectList() + .add(Aspect.PLANT, 10) + .add(Aspect.WATER, 2)); + + helper.registerTCObjectTag(TFBlocks.castle_brick, new int[]{0, 1, 3, 5}, new AspectList() + .add(Aspect.ORDER, 5) + .add(Aspect.MECHANISM, 1)); + + helper.registerTCObjectTag(TFBlocks.castle_brick, 2, new AspectList() + .add(Aspect.ORDER, 5) + .add(Aspect.MECHANISM, 1) + .add(Aspect.ENTROPY, 1)); + + helper.registerTCObjectTag(TFBlocks.castle_brick, 4, new AspectList() + .add(Aspect.ORDER, 5) + .add(Aspect.MECHANISM, 1) + .add(Aspect.PLANT, 1)); + + helper.registerTCObjectTag(TFBlocks.castle_pillar, -1, new AspectList() + .add(Aspect.ORDER, 5) + .add(Aspect.MECHANISM, 1)); + + helper.registerTCObjectTag(TFBlocks.castle_stairs, -1, new AspectList() + .add(Aspect.ORDER, 5) + .add(Aspect.MECHANISM, 1)); + + helper.registerTCObjectTag(TFBlocks.castle_rune_brick, -1, new AspectList() + .add(Aspect.ORDER, 5) + .add(Aspect.MECHANISM, 1) + .add(Aspect.AURA, 3)); + + helper.registerTCObjectTag(TFBlocks.force_field, -1, new AspectList() + .add(Aspect.AURA, 40)); + + helper.registerTCObjectTag(TFBlocks.cinder_log, -1, new AspectList() + .add(Aspect.FIRE, 4) + .add(Aspect.ENTROPY, 12)); + + helper.registerTCObjectTag(TFBlocks.castle_door, -1, new AspectList() + .add(Aspect.AURA, 20) + .add(Aspect.MECHANISM, 10) + .add(Aspect.TRAP, 5)); + + helper.registerTCObjectTag(TFBlocks.spiral_bricks, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.etched_nagastone, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.nagastone_stairs, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.nagastone_pillar, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ORDER, 1)); + + helper.registerTCObjectTag(TFBlocks.etched_nagastone_mossy, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ORDER, 1) + .add(Aspect.PLANT, 1)); + + helper.registerTCObjectTag(TFBlocks.nagastone_stairs_mossy, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ORDER, 1) + .add(Aspect.PLANT, 1)); + + helper.registerTCObjectTag(TFBlocks.nagastone_pillar_mossy, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ORDER, 1) + .add(Aspect.PLANT, 1)); + + helper.registerTCObjectTag(TFBlocks.etched_nagastone_weathered, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ENTROPY, 1)); + + helper.registerTCObjectTag(TFBlocks.nagastone_stairs_weathered, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ENTROPY, 1)); + + helper.registerTCObjectTag(TFBlocks.nagastone_pillar_weathered, -1, new AspectList() + .add(Aspect.EARTH, 5) + .add(Aspect.ENTROPY, 1)); + + helper.registerTCObjectTag(TFItems.naga_scale, new AspectList() + .add(Aspect.PROTECT, 5) + .add(Aspect.BEAST, 4) + .add(Aspect.MOTION, 2)); + + helper.registerTCObjectTag(TFItems.naga_chestplate, -1, new AspectList() + .add(Aspect.PROTECT, 28) + .add(Aspect.BEAST, 12) + .add(Aspect.MOTION, 15)); + + helper.registerTCObjectTag(TFItems.naga_leggings, -1, new AspectList() + .add(Aspect.PROTECT, 24) + .add(Aspect.BEAST, 10) + .add(Aspect.MOTION, 12)); + + helper.registerTCObjectTag(TFItems.twilight_scepter, -1, new AspectList() + .add(Aspect.MAGIC, 60) + .add(Aspect.DARKNESS, 30) + .add(Aspect.VOID, 15)); + + helper.registerTCObjectTag(TFItems.lifedrain_scepter, -1, new AspectList() + .add(Aspect.MAGIC, 60) + .add(Aspect.LIFE, 26) + .add(Aspect.EXCHANGE,18)); + + helper.registerTCObjectTag(TFItems.zombie_scepter, -1, new AspectList() + .add(Aspect.MAGIC, 60) + .add(Aspect.DEATH, 25) + .add(Aspect.SOUL, 25) + .add(Aspect.TRAP, 22)); + + helper.registerTCObjectTag(TFItems.ore_meter, new AspectList() + .add(Aspect.SENSES, 17) + .add(Aspect.DESIRE, 8) + .add(Aspect.MECHANISM, 15) + .add(Aspect.MIND, 10)); + + helper.registerTCObjectTag(TFItems.magic_map, -1, new AspectList() + .add(Aspect.PLANT, 18) + .add(Aspect.MIND, 16) + .add(Aspect.MAGIC, 12) + .add(Aspect.SENSES, 10) + .add(Aspect.LIGHT, 5)); + + helper.registerTCObjectTag(TFItems.maze_map, -1, new AspectList() + .add(Aspect.PLANT, 18) + .add(Aspect.MIND, 16) + .add(Aspect.MAGIC, 12) + .add(Aspect.SENSES, 10) + .add(Aspect.TRAP, 10)); + + helper.registerTCObjectTag(TFItems.ore_map, -1, new AspectList() + .add(Aspect.PLANT, 18) + .add(Aspect.MIND, 16) + .add(Aspect.MAGIC, 12) + .add(Aspect.SENSES, 10) + .add(Aspect.DESIRE, 72)); + + helper.registerTCObjectTag(TFItems.raven_feather, new AspectList() + .add(Aspect.FLIGHT, 5) + .add(Aspect.AIR, 5) + .add(Aspect.DARKNESS, 1)); + + helper.registerTCObjectTag(TFItems.magic_map_focus, new AspectList() + .add(Aspect.FLIGHT, 5) + .add(Aspect.AIR, 5) + .add(Aspect.LIGHT, 14)); + + helper.registerTCObjectTag(TFItems.maze_map_focus, new AspectList() + .add(Aspect.TRAP, 10) + .add(Aspect.MECHANISM, 15)); + + helper.registerTCObjectTag(TFItems.liveroot, new AspectList() + .add(Aspect.EARTH, 9) + .add(Aspect.LIFE, 6) + .add(Aspect.PLANT, 7)); + + helper.registerTCObjectTag(TFItems.ironwood_raw, new AspectList() + .add(Aspect.EARTH, 9) + .add(Aspect.LIFE, 6) + .add(Aspect.PLANT, 7) + .add(Aspect.METAL, 16) + .add(Aspect.DESIRE, 1)); + + helper.registerTCObjectTag(TFItems.ironwood_ingot, new AspectList() + .add(Aspect.METAL, 8) + .add(Aspect.PLANT, 3)); + + helper.registerTCObjectTag(TFItems.torchberries, new AspectList() + .add(Aspect.LIGHT, 8) + .add(Aspect.PLANT, 3)); + + helper.registerTCObjectTag(TFItems.raw_venison, new AspectList() + .add(Aspect.BEAST, 5) + .add(Aspect.LIFE, 5) + .add(Aspect.EARTH, 5)); + + helper.registerTCObjectTag(TFItems.cooked_venison, new AspectList() + .add(Aspect.BEAST, 5) + .add(Aspect.LIFE, 5) + .add(Aspect.CRAFT, 1)); + + helper.registerTCObjectTag(TFItems.hydra_chop, new AspectList() + .add(Aspect.BEAST, 25) + .add(Aspect.LIFE, 25) + .add(Aspect.FIRE, 5)); + + helper.registerTCObjectTag(TFItems.fiery_blood, new AspectList() + .add(Aspect.FIRE, 40) + .add(Aspect.LIFE, 22)); + + helper.registerTCObjectTag(TFItems.trophy, 0, new AspectList() + .add(Aspect.DEATH, 45) + .add(Aspect.SENSES, 20) + .add(Aspect.BEAST, 80) + .add(Aspect.MOTION, 40)); + + helper.registerTCObjectTag(TFItems.trophy, 1, new AspectList() + .add(Aspect.DEATH, 45) + .add(Aspect.SENSES, 20) + .add(Aspect.UNDEAD, 75) + .add(Aspect.MAN, 5) + .add(Aspect.ELDRITCH, 40)); + + helper.registerTCObjectTag(TFItems.trophy, 2, new AspectList() + .add(Aspect.DEATH, 45) + .add(Aspect.SENSES, 20) + .add(Aspect.BEAST, 30) + .add(Aspect.FIRE, 80)); + + helper.registerTCObjectTag(TFItems.trophy, 3, new AspectList() + .add(Aspect.DEATH, 45) + .add(Aspect.SENSES, 20) + .add(Aspect.FLUX, 80) + .add(Aspect.ALCHEMY, 40)); + + helper.registerTCObjectTag(TFItems.trophy, 4, new AspectList() + .add(Aspect.DEATH, 45) + .add(Aspect.SENSES, 20) + .add(Aspect.SOUL, 80) + .add(Aspect.MAN, 40)); + + helper.registerTCObjectTag(TFItems.trophy, 5, new AspectList() + .add(Aspect.DEATH, 45) + .add(Aspect.SENSES, 20) + .add(Aspect.COLD, 80) + .add(Aspect.MAN, 40)); + + helper.registerTCObjectTag(TFItems.trophy, 6, new AspectList() + .add(Aspect.DEATH, 45) + .add(Aspect.SENSES, 20) + .add(Aspect.BEAST, 70) + .add(Aspect.MAN, 50)); + + helper.registerTCObjectTag(TFItems.trophy, 8, new AspectList() + .add(Aspect.LIFE, 45) + .add(Aspect.DESIRE, 40) + .add(Aspect.EXCHANGE, 40)); + + helper.registerTCObjectTag(TFItems.steeleaf_ingot, new AspectList() + .add(Aspect.PLANT, 12) + .add(Aspect.METAL, 4)); + + helper.registerTCObjectTag(TFItems.minotaur_axe, -1, new AspectList() + .add(Aspect.AVERSION, 20) + .add(Aspect.TOOL, 16) + .add(Aspect.DESIRE, 44) + .add(Aspect.CRYSTAL, 44)); + + helper.registerTCObjectTag(TFItems.mazebreaker_pickaxe, -1, new AspectList() + .add(Aspect.TOOL, 16) + .add(Aspect.TRAP, 8) + .add(Aspect.METAL, 33)); + + helper.registerTCObjectTag(TFItems.transformation_powder, new AspectList() + .add(Aspect.EXCHANGE, 30) + .add(Aspect.MAGIC, 12)); + + helper.registerTCObjectTag(TFItems.raw_meef, new AspectList() + .add(Aspect.BEAST, 5) + .add(Aspect.LIFE, 5) + .add(Aspect.EARTH, 5)); + + helper.registerTCObjectTag(TFItems.cooked_meef, new AspectList() + .add(Aspect.BEAST, 5) + .add(Aspect.LIFE, 5) + .add(Aspect.CRAFT, 1)); + + helper.registerTCObjectTag(TFItems.meef_stroganoff, new AspectList() + .add(Aspect.BEAST, 25) + .add(Aspect.MAN, 15) + .add(Aspect.LIFE, 25) + .add(Aspect.CRAFT, 5)); + + helper.registerTCObjectTag(TFItems.maze_wafer, new AspectList() + .add(Aspect.PLANT, 2)); + + helper.registerTCObjectTag(TFItems.ore_magnet, -1, new AspectList() + .add(Aspect.METAL, 24) + .add(Aspect.DESIRE, 30)); + + helper.registerTCObjectTag(TFItems.crumble_horn, -1, new AspectList() + .add(Aspect.BEAST, 35) + .add(Aspect.SENSES, 30) + .add(Aspect.MAGIC, 32)); + + helper.registerTCObjectTag(TFItems.peacock_fan, -1, new AspectList() + .add(Aspect.BEAST, 35) + .add(Aspect.MOTION, 48) + .add(Aspect.FLIGHT, 60) + .add(Aspect.MAGIC, 32)); + + helper.registerTCObjectTag(TFItems.moonworm_queen, -1, new AspectList() + .add(Aspect.BEAST, 35) + .add(Aspect.LIGHT, 54) + .add(Aspect.LIFE, 36) + .add(Aspect.EXCHANGE, 28)); + + helper.registerTCObjectTag(TFItems.charm_of_life_1, new AspectList() + .add(Aspect.LIFE, 10) + .add(Aspect.DEATH, 10) + .add(Aspect.EXCHANGE, 16 ) + .add(Aspect.MAGIC, 8)); + + helper.registerTCObjectTag(TFItems.charm_of_keeping_1, new AspectList() + .add(Aspect.EXCHANGE, 16) + .add(Aspect.MAGIC, 8)); + + helper.registerTCObjectTag(TFItems.tower_key, new AspectList() + .add(Aspect.TRAP, 16)); + + helper.registerTCObjectTag(TFItems.armor_shard, new AspectList() + .add(Aspect.METAL, 2)); + + helper.registerTCObjectTag(TFItems.knightmetal_ingot, new AspectList() + .add(Aspect.METAL, 18) + .add(Aspect.CRAFT, 6)); + + helper.registerTCObjectTag(TFItems.phantom_helmet, -1, new AspectList() + .add(Aspect.PROTECT, 12) + .add(Aspect.SOUL, 24) + .add(Aspect.DEATH, 7) + .add(Aspect.ELDRITCH, 8) + .add(Aspect.TRAP, 22)); + + helper.registerTCObjectTag(TFItems.phantom_chestplate, -1, new AspectList() + .add(Aspect.PROTECT, 32) + .add(Aspect.SOUL, 62) + .add(Aspect.DEATH, 19) + .add(Aspect.ELDRITCH, 22) + .add(Aspect.TRAP, 48)); + + helper.registerTCObjectTag(TFItems.lamp_of_cinders, -1, new AspectList() + .add(Aspect.MAGIC, 53) + .add(Aspect.FIRE, 87) + .add(Aspect.ENERGY, 42)); + + helper.registerTCObjectTag(TFItems.fiery_tears, new AspectList() + .add(Aspect.FIRE, 40) + .add(Aspect.WATER, 22)); + + helper.registerTCObjectTag(TFItems.alpha_fur, new AspectList() + .add(Aspect.BEAST, 48) + .add(Aspect.COLD, 28)); + + helper.registerTCObjectTag(TFItems.ice_bomb, new AspectList() + .add(Aspect.COLD, 22) + .add(Aspect.MOTION, 8)); + + helper.registerTCObjectTag(TFItems.arctic_fur, new AspectList() + .add(Aspect.BEAST, 12) + .add(Aspect.COLD, 7)); + + helper.registerTCObjectTag(TFItems.magic_beans, new AspectList() + .add(Aspect.PLANT, 8) + .add(Aspect.MAGIC, 36)); + + helper.registerTCObjectTag(TFItems.triple_bow, -1, new AspectList() + .add(Aspect.AVERSION, 10) + .add(Aspect.FLIGHT, 5) + .add(Aspect.EXCHANGE, 30)); + + helper.registerTCObjectTag(TFItems.seeker_bow, -1, new AspectList() + .add(Aspect.AVERSION, 10) + .add(Aspect.FLIGHT, 5) + .add(Aspect.MECHANISM, 30)); + + helper.registerTCObjectTag(TFItems.ice_bow, -1, new AspectList() + .add(Aspect.AVERSION, 10) + .add(Aspect.FLIGHT, 5) + .add(Aspect.COLD, 30)); + + helper.registerTCObjectTag(TFItems.ender_bow, -1, new AspectList() + .add(Aspect.AVERSION, 10) + .add(Aspect.FLIGHT, 5) + .add(Aspect.ELDRITCH, 30)); + + helper.registerTCObjectTag(TFItems.ice_sword, -1, new AspectList() + .add(Aspect.AVERSION, 16) + .add(Aspect.COLD, 24)); + + helper.registerTCObjectTag(TFItems.glass_sword, -1, new AspectList() + .add(Aspect.AVERSION, 148) + .add(Aspect.CRYSTAL, 96)); + + helper.registerTCObjectTag(TFItems.fiery_ingot, new AspectList() + .add(Aspect.FIRE, 40) + .add(Aspect.METAL, 15) + .add(Aspect.AURA, 12)); + + helper.registerTCObjectTag(TFItems.fiery_boots, -1, new AspectList() + .add(Aspect.METAL, 45) + .add(Aspect.FIRE, 120) + .add(Aspect.PROTECT, 16) + .add(Aspect.AURA, 36)); + + helper.registerTCObjectTag(TFItems.fiery_leggings, -1, new AspectList() + .add(Aspect.METAL, 78) + .add(Aspect.FIRE, 210) + .add(Aspect.PROTECT, 28) + .add(Aspect.AURA, 63)); + + helper.registerTCObjectTag(TFItems.fiery_chestplate, -1, new AspectList() + .add(Aspect.METAL, 90) + .add(Aspect.FIRE, 240) + .add(Aspect.PROTECT, 36) + .add(Aspect.AURA, 72)); + + helper.registerTCObjectTag(TFItems.fiery_helmet, -1, new AspectList() + .add(Aspect.METAL, 56) + .add(Aspect.FIRE, 150) + .add(Aspect.PROTECT, 16) + .add(Aspect.AURA, 45)); + + helper.registerTCObjectTag(TFItems.yeti_boots, -1, new AspectList() + .add(Aspect.BEAST, 144) + .add(Aspect.COLD, 84) + .add(Aspect.PROTECT, 12) + .add(Aspect.AURA, 36)); + + helper.registerTCObjectTag(TFItems.yeti_leggings, -1, new AspectList() + .add(Aspect.BEAST, 252) + .add(Aspect.COLD, 147) + .add(Aspect.PROTECT, 24) + .add(Aspect.AURA, 63)); + + helper.registerTCObjectTag(TFItems.yeti_chestplate, -1, new AspectList() + .add(Aspect.BEAST, 288) + .add(Aspect.COLD, 168) + .add(Aspect.PROTECT, 28) + .add(Aspect.AURA, 72)); + + helper.registerTCObjectTag(TFItems.yeti_helmet, -1, new AspectList() + .add(Aspect.BEAST, 180) + .add(Aspect.COLD, 105) + .add(Aspect.PROTECT, 16) + .add(Aspect.AURA, 45)); + + helper.registerTCObjectTag(TFItems.borer_essence, new AspectList() + .add(Aspect.ALCHEMY, 10)); + + helper.registerTCObjectTag(TFItems.carminite, new AspectList() + .add(Aspect.ALCHEMY, 38) + .add(Aspect.ENERGY, 30) + .add(Aspect.FLUX, 26) + .add(Aspect.SOUL, 7) + .add(Aspect.UNDEAD, 3)); + + helper.registerTCObjectTag(TFItems.experiment_115, new AspectList() + .add(Aspect.FLUX, 15) + .add(Aspect.ALCHEMY, 2)); + + helper.registerTCObjectTag(TFItems.magic_map_empty, new AspectList() + .add(Aspect.PLANT, 18) + .add(Aspect.MIND, 16) + .add(Aspect.MAGIC, 12) + .add(Aspect.SENSES, 10) + .add(Aspect.LIGHT, 5)); + + helper.registerTCObjectTag(TFItems.maze_map_empty, new AspectList() + .add(Aspect.PLANT, 18) + .add(Aspect.MIND, 16) + .add(Aspect.MAGIC, 12) + .add(Aspect.SENSES, 10) + .add(Aspect.TRAP, 10)); + + helper.registerTCObjectTag(TFItems.ore_map_empty, new AspectList() + .add(Aspect.PLANT, 18) + .add(Aspect.MIND, 16) + .add(Aspect.MAGIC, 12) + .add(Aspect.SENSES, 10) + .add(Aspect.DESIRE, 72)); + + helper.registerTCObjectTag(TFItems.block_and_chain, -1, new AspectList() + .add(Aspect.METAL, 171) + .add(Aspect.CRAFT, 57) + .add(Aspect.TOOL, 16) + .add(Aspect.AVERSION, 16)); + + helper.registerTCObjectTag(TFBlocks.twilight_plant, 7, new AspectList() + .add(Aspect.LIGHT, 10) + .add(Aspect.PLANT, 5)); + + helper.registerTCObjectTag(TFBlocks.thorn_rose, new AspectList() + .add(Aspect.PLANT, 5) + .add(Aspect.AVERSION, 2) + .add(Aspect.SENSES, 2)); + + //TwilightForestMod.LOGGER.info("Loaded ThaumcraftApi integration."); + } catch (Exception e) { + //TwilightForestMod.LOGGER.warn("Had an %s error while trying to register with ThaumcraftApi.", e.getLocalizedMessage()); + // whatever. + } + } + + private static class TFAspectRegisterHelper { + + private final AspectRegistryEvent event; + + private TFAspectRegisterHelper(AspectRegistryEvent event) { + this.event = event; + } + + private void registerTCObjectTag(Block block, AspectList list) { + registerTCObjectTag(new ItemStack(block), list); + } + + // Register a block with Thaumcraft aspects + private void registerTCObjectTag(Block block, int meta, AspectList list) { + if (meta == -1) meta = OreDictionary.WILDCARD_VALUE; + registerTCObjectTag(new ItemStack(block, 1, meta), list); + } + + // Register blocks with Thaumcraft aspects + private void registerTCObjectTag(Block block, int[] metas, AspectList list) { + for (int meta : metas) + this.registerTCObjectTag(block, meta, list); + } + + private void registerTCObjectTag(Item item, AspectList list) { + registerTCObjectTag(new ItemStack(item), list); + } + + // Register an item with Thaumcraft aspects + private void registerTCObjectTag(Item item, int meta, AspectList list) { + if (meta == -1) meta = OreDictionary.WILDCARD_VALUE; + registerTCObjectTag(new ItemStack(item, 1, meta), list); + } + + // Register item swith Thaumcraft aspects + private void registerTCObjectTag(Item item, int[] metas, AspectList list) { + for (int meta : metas) + this.registerTCObjectTag(item, meta, list); + } + + private void registerTCObjectTag(ItemStack stack, AspectList list) { + event.register.registerObjectTag(stack, list); + } + } +} diff --git a/src/main/java/twilightforest/compat/UncraftingRecipeTransferHandler.java b/src/main/java/twilightforest/compat/UncraftingRecipeTransferHandler.java new file mode 100644 index 0000000000..4ccea48900 --- /dev/null +++ b/src/main/java/twilightforest/compat/UncraftingRecipeTransferHandler.java @@ -0,0 +1,46 @@ +package twilightforest.compat; + +import mezz.jei.api.recipe.VanillaRecipeCategoryUid; +import mezz.jei.api.recipe.transfer.IRecipeTransferInfo; +import net.minecraft.inventory.Slot; +import twilightforest.inventory.ContainerTFUncrafting; + +import java.util.ArrayList; +import java.util.List; + +public class UncraftingRecipeTransferHandler implements IRecipeTransferInfo { + @Override + public Class getContainerClass() { + return ContainerTFUncrafting.class; + } + + @Override + public String getRecipeCategoryUid() { + return VanillaRecipeCategoryUid.CRAFTING; + } + + @Override + public boolean canHandle(ContainerTFUncrafting container) { + return true; + } + + @Override + public List getRecipeSlots(ContainerTFUncrafting container) { + List slots = new ArrayList<>(); + + for(int i = 11; i < 20; i++) + slots.add(container.getSlot(i)); + + return slots; + } + + @Override + public List getInventorySlots(ContainerTFUncrafting container) { + List slots = new ArrayList<>(); + + for(int i = 20; i < container.inventorySlots.size(); i++) + slots.add(container.getSlot(i)); + + return slots; + } +} diff --git a/src/main/java/twilightforest/compat/forestry/BeeBranchRegister.java b/src/main/java/twilightforest/compat/forestry/BeeBranchRegister.java new file mode 100644 index 0000000000..1baf151b2f --- /dev/null +++ b/src/main/java/twilightforest/compat/forestry/BeeBranchRegister.java @@ -0,0 +1,65 @@ +package twilightforest.compat.forestry; + +import forestry.api.apiculture.BeeManager; +import forestry.api.apiculture.EnumBeeChromosome; +import forestry.api.genetics.IAllele; +import forestry.api.genetics.IClassification; +import forestry.apiculture.genetics.alleles.AlleleEffects; +import forestry.core.genetics.IBranchDefinition; +import forestry.core.genetics.alleles.AlleleHelper; +import forestry.core.genetics.alleles.EnumAllele; + +import java.util.Locale; + +public enum BeeBranchRegister implements IBranchDefinition { + TWILIGHT ( "Crepusculum" ), + SWAMP ( "Palus" ), + DARK_FOREST ( "Maestus" ), + SNOWY_FOREST ( "Frigidus" ), + HIGHLANDS ( "Superior" ); + + private final IClassification classification; + private static IAllele[] defaultTemplate; + + BeeBranchRegister(String genus) { + classification = BeeManager.beeFactory.createBranch(this.name().toLowerCase(Locale.ENGLISH), genus); + } + + @Override + public IAllele[] getTemplate() { + IAllele[] template = copyDefaultTemplate(); + IAllele[] copiedAlleles = new IAllele[template.length]; + System.arraycopy(template, 0, copiedAlleles, 0, template.length); + + return copiedAlleles; + } + + @Override + public IClassification getBranch() { + return this.classification; + } + + private static IAllele[] copyDefaultTemplate() { + if (defaultTemplate == null) { + defaultTemplate = new IAllele[EnumBeeChromosome.values().length]; + + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.SPEED , EnumAllele.Speed.NORMAL ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.LIFESPAN , EnumAllele.Lifespan.NORMAL ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.FERTILITY , EnumAllele.Fertility.NORMAL ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.TEMPERATURE_TOLERANCE, EnumAllele.Tolerance.NONE ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.NEVER_SLEEPS , false ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.HUMIDITY_TOLERANCE , EnumAllele.Tolerance.NONE ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.TOLERATES_RAIN , false ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.CAVE_DWELLING , false ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.FLOWER_PROVIDER , EnumAllele.Flowers.VANILLA ); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.FLOWERING , EnumAllele.Flowering.AVERAGE); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.TERRITORY , EnumAllele.Territory.AVERAGE); + AlleleHelper.getInstance().set(defaultTemplate, EnumBeeChromosome.EFFECT , AlleleEffects.effectNone ); + } + + IAllele[] copiedAlleles = new IAllele[defaultTemplate.length]; + System.arraycopy(defaultTemplate, 0, copiedAlleles, 0, defaultTemplate.length); + + return copiedAlleles; + } +} diff --git a/src/main/java/twilightforest/compat/forestry/BeeRegister.java b/src/main/java/twilightforest/compat/forestry/BeeRegister.java new file mode 100644 index 0000000000..c7def83a73 --- /dev/null +++ b/src/main/java/twilightforest/compat/forestry/BeeRegister.java @@ -0,0 +1,127 @@ +package twilightforest.compat.forestry; + +import forestry.api.apiculture.*; +import forestry.api.genetics.IAllele; +import forestry.apiculture.genetics.Bee; +import forestry.apiculture.genetics.IBeeDefinition; +import forestry.core.genetics.IBranchDefinition; +import forestry.core.genetics.alleles.AlleleHelper; +import net.minecraft.item.ItemStack; +import twilightforest.TwilightForestMod; + +import java.util.Locale; + +public enum BeeRegister implements IBeeDefinition { + + TWILIT ( BeeBranchRegister.TWILIGHT , "Crepusculum" ), + ENSORCELIZED ( BeeBranchRegister.TWILIGHT , "Carminibus" ), + MIRY ( BeeBranchRegister.SWAMP , "Paluster" ), + OMINOUS ( BeeBranchRegister.DARK_FOREST , "Minaces" ), + FRIGID ( BeeBranchRegister.SNOWY_FOREST , "Frigidus" ), + DRAINED ( BeeBranchRegister.HIGHLANDS , "Adficio" ), + + CONFUSED ( BeeBranchRegister.TWILIGHT , "Confusus" ), + ENLIGHTENED ( BeeBranchRegister.TWILIGHT , "Cultus" ), + + HERBAL ( BeeBranchRegister.TWILIGHT , "Herba" ), + TREE ( BeeBranchRegister.TWILIGHT , "Arboreal" ), + + DRUIDIC ( BeeBranchRegister.TWILIGHT , "Druidae" ), + + RHYTHMIC ( BeeBranchRegister.TWILIGHT , "Tempus" ), + TRANSFIGURATIVE ( BeeBranchRegister.TWILIGHT , "Transformato" ), + EXCAVATOR ( BeeBranchRegister.TWILIGHT , "Tergeo" ), + CATEGORICAL ( BeeBranchRegister.TWILIGHT , "Catalogus" ), + + ENTANGLED ( BeeBranchRegister.SWAMP , "Capti" ), + LABYRINTHINE ( BeeBranchRegister.SWAMP , "Labyrinthus" ), + + MISTY ( BeeBranchRegister.DARK_FOREST , "Caliginosus" ), + PIERCING ( BeeBranchRegister.DARK_FOREST , "Penetralis" ), + + FROZEN ( BeeBranchRegister.SNOWY_FOREST , "Glacialis" ), + GELID ( BeeBranchRegister.SNOWY_FOREST , "Gelida" ), + + ANIMATED ( BeeBranchRegister.HIGHLANDS , "Vividus" ), + SENTINEL ( BeeBranchRegister.HIGHLANDS , "Excubitor" ), + + MYTHOLOGICAL ( BeeBranchRegister.TWILIGHT , "Fabulares" ), + ENTROPHIED ( BeeBranchRegister.TWILIGHT , "Champion" ), + + SHEEPISH ( BeeBranchRegister.TWILIGHT , "Modestus" ), + + SERPENTINE ( BeeBranchRegister.TWILIGHT , "Anguis" ), + + NECROMANTIC ( BeeBranchRegister.TWILIGHT , "Necromantiae" ), + + MINOTAUR ( BeeBranchRegister.SWAMP , "Minotaurus" ), + DUPLICATIVE ( BeeBranchRegister.SWAMP , "Capitibus" ), + + PHANTASMAGORICAL ( BeeBranchRegister.DARK_FOREST , "Inconcilio" ), + CARMINIATED ( BeeBranchRegister.DARK_FOREST , "Vis" ), + + CRYPTID ( BeeBranchRegister.SNOWY_FOREST , "Creatura" ), + MONARCHICAL ( BeeBranchRegister.SNOWY_FOREST , "Monarchica" ), + + ONTOMANTIC ( BeeBranchRegister.HIGHLANDS , "Rego" ); + + private final IBranchDefinition branch; + private final IAlleleBeeSpecies species; + private IAllele[] template; + private IBeeGenome genome; + + BeeRegister(IBranchDefinition branch, String species) { + this.branch = branch; + + String lowerCase = this.toString().toLowerCase(Locale.ROOT); + + IAlleleBeeSpeciesBuilder speciesBuilder = BeeManager.beeFactory.createSpecies( + TwilightForestMod.ID, + TwilightForestMod.ID + ":" + lowerCase, + true, + "Drullkus", + TwilightForestMod.ID + ".bee." + lowerCase, + TwilightForestMod.ID + ".bee." + lowerCase + ".desc", + branch.getBranch(), + species.toLowerCase(Locale.ROOT), + 0xFF_FF_FF, + 0xFF_FF_FF + ); + this.setSpeciesProperties(speciesBuilder); + this.species = speciesBuilder.build(); + + this.template = this.branch.getTemplate(); + AlleleHelper.getInstance().set(this.template, EnumBeeChromosome.SPECIES, this.species); + this.setAlleles(this.template); + this.genome = BeeManager.beeRoot.templateAsGenome(this.template); + BeeManager.beeRoot.registerTemplate(this.template); + } + + @Override + public IAllele[] getTemplate() { + IAllele[] copiedAlleles = new IAllele[template.length]; + System.arraycopy(this.template, 0, copiedAlleles, 0, template.length); + + return copiedAlleles; + } + + @Override + public final IBeeGenome getGenome() { + return this.genome; + } + + @Override + public final IBee getIndividual() { + return new Bee(this.genome); + } + + @Override + public ItemStack getMemberStack(EnumBeeType enumBeeType) { + IBee bee = this.getIndividual(); + return BeeManager.beeRoot.getMemberStack(bee, enumBeeType); + } + + private void setSpeciesProperties(IAlleleBeeSpeciesBuilder speciesProperties) {} + + private void setAlleles(IAllele[] alleles) {} +} diff --git a/src/main/java/twilightforest/compat/ie/IEShaderRegister.java b/src/main/java/twilightforest/compat/ie/IEShaderRegister.java new file mode 100644 index 0000000000..90a83a648f --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/IEShaderRegister.java @@ -0,0 +1,422 @@ +package twilightforest.compat.ie; + +import blusunrize.immersiveengineering.api.crafting.IngredientStack; +import blusunrize.immersiveengineering.api.shader.*; +import blusunrize.immersiveengineering.client.ClientUtils; +import com.google.common.collect.ImmutableList; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import org.apache.logging.log4j.util.TriConsumer; +import org.lwjgl.opengl.GL11; +import twilightforest.TwilightForestMod; +import twilightforest.client.shader.ShaderManager; +import twilightforest.client.shader.ShaderUniform; +import twilightforest.item.TFItems; + +import java.util.List; +import java.util.function.IntConsumer; + +public class IEShaderRegister { + // Layer Constants + private static final ShaderCase.ShaderLayer NULL_LAYER = new ShaderCase.ShaderLayer( null , 0xFFFFFFFF); + private static final ShaderCase.ShaderLayer UNCOLORED_REVOLVER_LAYER = new ShaderCase.ShaderLayer( new ResourceLocation("immersiveengineering", "revolvers/shaders/revolver_uncoloured" ), 0xFFFFFFFF); + private static final ShaderCase.ShaderLayer UNCOLORED_CHEMTHROW_LAYER = new ShaderCase.ShaderLayer( new ResourceLocation("immersiveengineering", "items/shaders/chemthrower_uncoloured" ), 0xFFFFFFFF); + private static final ShaderCase.ShaderLayer UNCOLORED_DRILL_LAYER = new ShaderCase.ShaderLayer( new ResourceLocation("immersiveengineering", "items/shaders/drill_diesel_uncoloured" ), 0xFFFFFFFF); + private static final ShaderCase.ShaderLayer UNCOLORED_RAILGUN_LAYER = new ShaderCase.ShaderLayer( new ResourceLocation("immersiveengineering", "items/shaders/railgun_uncoloured" ), 0xFFFFFFFF); + private static final ShaderCase.ShaderLayer UNCOLORED_SHIELD_LAYER = new ShaderCase.ShaderLayer( new ResourceLocation("immersiveengineering", "items/shaders/shield_uncoloured" ), 0xFFFFFFFF); + private static final ShaderCase.ShaderLayer UNCOLORED_MINECART_LAYER = new ShaderCase.ShaderLayer( new ResourceLocation("immersiveengineering", "textures/models/shaders/minecart_uncoloured.png" ), 0xFFFFFFFF); + private static final ShaderCase.ShaderLayer UNCOLORED_BALLOON_LAYER = new ShaderCase.ShaderLayer( new ResourceLocation("immersiveengineering", "blocks/shaders/balloon_uncoloured" ), 0xFFFFFFFF); + + public static final ResourceLocation PROCESSED_REVOLVER_GRIP_LAYER = new ResourceLocation(TwilightForestMod.ID, "items/immersiveengineering/revolver_grip_processed"); + public static final ResourceLocation PROCESSED_REVOLVER_LAYER = new ResourceLocation(TwilightForestMod.ID, "items/immersiveengineering/revolver_processed"); + public static final ResourceLocation PROCESSED_CHEMTHROW_LAYER = new ResourceLocation(TwilightForestMod.ID, "items/immersiveengineering/chemthrower_processed"); + public static final ResourceLocation PROCESSED_DRILL_LAYER = new ResourceLocation(TwilightForestMod.ID, "items/immersiveengineering/drill_processed"); + public static final ResourceLocation PROCESSED_RAILGUN_LAYER = new ResourceLocation(TwilightForestMod.ID, "items/immersiveengineering/railgun_processed"); + public static final ResourceLocation PROCESSED_SHIELD_LAYER = new ResourceLocation(TwilightForestMod.ID, "items/immersiveengineering/shield_processed"); + //public static final ResourceLocation PROCESSED_MINECART_LAYER = new ResourceLocation(TwilightForestMod.ID, "textures/items/immersiveengineering/minecart_processed.png"); + public static final ResourceLocation PROCESSED_BALLOON_LAYER = new ResourceLocation(TwilightForestMod.ID, "blocks/immersiveengineering/balloon_processed"); + + private static final ResourceLocation TEXTURE_STARS = new ResourceLocation("textures/entity/end_portal.png"); + + private static final TriConsumer TWILIGHT_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + if (pre) { + ShaderManager.useShader(ShaderManager.twilightSkyShader, shaderCallback); + + OpenGlHelper.setActiveTexture(OpenGlHelper.GL_TEXTURE2); + Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE_STARS); + + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + } else { + ShaderManager.releaseShader(); + + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + } + }; + + // TODO There's got to be a better way! + private static final TriConsumer FIREFLY_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + if (pre) ShaderManager.useShader(ShaderManager.fireflyShader, shaderCallback); + else ShaderManager.releaseShader(); + }; + + private static final TriConsumer CARMINITE_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + if (pre) ShaderManager.useShader(ShaderManager.carminiteShader, shaderCallback); + else ShaderManager.releaseShader(); + }; + + private static final TriConsumer DEVICE_RED_ENERGY_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + if (pre) ShaderManager.useShader(ShaderManager.towerDeviceShader, shaderCallback); + else ShaderManager.releaseShader(); + }; + + private static final TriConsumer DEVICE_YELLOW_ENERGY_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + if (pre) { + GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + ShaderManager.useShader(ShaderManager.yellowCircuitShader, shaderCallback); + } else { + ShaderManager.releaseShader(); + GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); + } + }; + + private static final TriConsumer AURORA_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + if (pre) ShaderManager.useShader(ShaderManager.auroraShader, shaderCallback); + else ShaderManager.releaseShader(); + }; + + private static final TriConsumer RAM_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + ClientUtils.toggleLightmap(pre, true); + }; + + //private static final TriConsumer OUTLINE_TRICONSUMER = (shaderCallback, pre, partialTick) -> { + // if (pre) { + // GlStateManager.pushMatrix(); + // } else { + // GlStateManager.popMatrix(); + // } + // //if (pre) { + // // //GlStateManager.pushMatrix(); + // // //GlStateManager.scale(1.05f, 1.05f, 1.05f); + // // GlStateManager.enableCull(); + // // //GL11.glFrontFace(GL11.GL_CW); + // // GlStateManager.cullFace(GlStateManager.CullFace.FRONT); + // // ShaderHelper.useShader(ShaderHelper.outlineShader, shaderCallback); + // //} else { + // // ShaderHelper.releaseShader(); + // // GlStateManager.cullFace(GlStateManager.CullFace.BACK); + // // //GL11.glFrontFace(GL11.GL_CCW); + // // GlStateManager.disableCull(); + // // //GlStateManager.scale(0.8333f, 0.8333f, 0.8333f); + // // //GlStateManager.popMatrix(); + // //} + //}; + + // m Mod + // t CaseType + // s Suffix + // c Color + private static final ShaderLayerProvider LAYER_PROVIDER = (m, t, s, c) -> new ShaderCase.ShaderLayer( m.provideTex(t, s), c ); + private static final ShaderLayerProvider TOWER_DEVICE_SHADER_PROVIDER = (m, t, s, c) -> new ShaderConsumerLayer ( ModType.TWILIGHT_FOREST.provideTex(t, "energy"), 0xFFFFFFFF, DEVICE_RED_ENERGY_TRICONSUMER, ShaderManager.Uniforms.STAR_UNIFORMS ); + private static final ShaderLayerProvider YELLOW_CIRCUIT_SHADER_PROVIDER = (m, t, s, c) -> new ShaderConsumerLayer ( ModType.IMMERSIVE_ENGINEERING.provideTex(t, "circuit"), 0xFF_BA_EE_02, DEVICE_YELLOW_ENERGY_TRICONSUMER, ShaderManager.Uniforms.STAR_UNIFORMS ); + + // Registering + private static List SHADERS; + private static List NONBOSSES; + + private static final EnumRarity RARITY = TwilightForestMod.getRarity(); + + static { + if (RARITY != EnumRarity.EPIC) + ShaderRegistry.rarityWeightMap.put(RARITY, 1); + + initShaders(); + } + + public static void initShaders() { + NONBOSSES = ImmutableList.of( + // MAIN COLOR, MINOR COLOR (EDGES), SECONDARY COLOR (GRIP, etc) + registerShaderCases ( "Twilight" , ModType.TWILIGHT_FOREST, "1_4" , RARITY, 0xFF_4C_64_5B, 0xFF_28_25_3F, 0xFF_00_AA_00, 0xFF_FF_FF_FF, (m, t, s, c) -> new ShaderConsumerLayer( m.provideTex(t, s), 0xFFFFFFFF, TWILIGHT_TRICONSUMER , ShaderManager.Uniforms.STAR_UNIFORMS ) ).setInfo("Twilight Forest", "Twilight Forest" , "twilightforest" ), + registerShaderCases ( "Firefly" , ModType.TWILIGHT_FOREST, "1_6" , RARITY, 0xFF_66_41_40, 0xFF_F5_99_2F, 0xFF_C0_FF_00, 0xFF_C0_FF_00, LAYER_PROVIDER, (m, t, s, c) -> new ShaderConsumerLayer( ModType.TWILIGHT_FOREST.provideTex(t, "processed"), 0xFFFFFFFF, FIREFLY_TRICONSUMER , ShaderManager.Uniforms.TIME_UNIFORM ) ).setInfo("Twilight Forest", "Firefly" , "firefly" ), + registerShaderCases ( "Pinch Beetle" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_BC_93_27, 0xFF_24_16_09, 0xFF_24_16_09, 0xFF_44_44_44, LAYER_PROVIDER, (m, t, s, c) -> new ShaderCase.ShaderLayer( m.provideTex(t, "1_6"), c ) ).setInfo("Twilight Forest", "Pinch Beetle" , "pinch_beetle" ), + + registerShaderCases ( "Snakestone" , ModType.TWILIGHT_FOREST, "streaks" , RARITY, 0xFF_9F_9F_9F, 0xFF_68_68_68, 0xFF_60_60_60, 0xFF_FF_FF_FF, LAYER_PROVIDER, (m, t, s, c) -> new ShaderCase.ShaderLayer( ModType.TWILIGHT_FOREST.provideTex(t, "scales"), 0xFF_50_50_50 ), (m, t, s, c) -> new ShaderCase.ShaderLayer( ModType.IMMERSIVE_ENGINEERING.provideTex(t, "circuit"), 0xFF_58_58_58 ) ).setInfo("Twilight Forest", "Nagastone" , "courtyard" ), + + registerShaderCases ( "Mazestone" , ModType.TWILIGHT_FOREST, "scales" , RARITY, 0xFF_8E_99_8E, 0xFF_50_59_50, 0xFF_70_7B_70, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Mazestone" , "mazestone" ), + + registerShaderCases ( "Underbrick" , ModType.TWILIGHT_FOREST, "scales" , RARITY, 0xFF_85_68_45, 0xFF_76_7F_76, 0xFF_61_4D_33, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Underbrick" , "underbrick" ), + registerShaderCasesTopped( "Towerwood" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_A6_65_3A, 0xFF_F5_DA_93, 0xFF_83_5A_35, 0xFF_FF_FF_FF, new ShaderLayerProvider[]{ LAYER_PROVIDER, YELLOW_CIRCUIT_SHADER_PROVIDER } , TOWER_DEVICE_SHADER_PROVIDER ).setInfo("Twilight Forest", "Towerwood Planks" , "towerwood" ), + registerShaderCasesTopped( "Carminite" , ModType.TWILIGHT_FOREST, "carminite", RARITY, 0xFF_72_00_00, 0xFF_FF_00_00, 0xFF_FF_00_00, 0xFF_FF_00_00, new ShaderLayerProvider[]{ (m, t, s, c) -> new ShaderConsumerLayer( m.provideTex(t, s), 0xFFFFFFFF, CARMINITE_TRICONSUMER, ShaderManager.Uniforms.STAR_UNIFORMS ) }, TOWER_DEVICE_SHADER_PROVIDER ).setInfo("Twilight Forest", "Carminite" , "carminite" ), + + registerShaderCases ( "Auroralized" , ModType.TWILIGHT_FOREST, "1_5" , RARITY, 0xFF_00_FF_FF, 0xFF_00_FF_00, 0xFF_00_00_FF, 0xFF_FF_FF_FF, (m, t, s, c) -> new ShaderConsumerLayer( m.provideTex(t, s), 0xFFFFFFFF, AURORA_TRICONSUMER , ShaderManager.Uniforms.TIME_UNIFORM ) ).setInfo("Twilight Forest", "Aurora Palace" , "aurora" ), + + registerShaderCases ( "Ironwood" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_6B_61_61, 0xFF_5F_4D_40, 0xFF_5E_57_4B, 0xFF_FF_FF_FF, (m, t, s, c) -> new ShaderCase.ShaderLayer( ModType.TWILIGHT_FOREST.provideTex(t, "streaks"), 0xFF_79_7C_43 ), LAYER_PROVIDER ).setInfo("Twilight Forest", "Ironwood" , "ironwood" ), + registerShaderCases ( "Steeleaf" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_52_87_3A, 0xFF_1E_32_14, 0xFF_41_62_30, 0xFF_FF_FF_FF, (m, t, s, c) -> new ShaderCase.ShaderLayer( ModType.IMMERSIVE_ENGINEERING.provideTex(t, "1_4"), 0xFF_41_62_30 ), (m, t, s, c) -> new ShaderCase.ShaderLayer( ModType.TWILIGHT_FOREST.provideTex(t, "streaks"), 0xFF_6D_A2_5E ), LAYER_PROVIDER ).setInfo("Twilight Forest", "Steeleaf" , "steeleaf" ), + registerShaderCases ( "Knightly" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_E7_FC_CD, 0xFF_4D_4C_4B, 0xFF_80_8C_72, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Knightly" , "knightly" ), + registerShaderCases ( "Fiery" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_19_13_13, 0xFF_FD_D4_5D, 0xFF_77_35_11, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Fiery" , "fiery" ), + + registerShaderCases ( "Final Castle" , ModType.TWILIGHT_FOREST, "scales" , RARITY, 0xFF_EC_EA_E6, 0xFF_C8_BB_BC, 0xFF_00_FF_FF, 0xFF_00_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Final Castle" , "finalcastle" ), + // TODO Throbbing effect + //registerShaderCases ( "Cube of Annihilation", ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_00_00_03, 0xFF_14_00_40, 0xFF_00_00_03, 0xFF_14_00_40, (m, t, s, c) -> new ShaderConsumerLayer( m.provideTex(t, s), 0xFF_14_00_40, OUTLINE_TRICONSUMER, ShaderHelper.TIME_UNIFORM ) ).setInfo("Twilight Forest", "Cube of Annilation" , "cube_of_annilation" ) + registerShaderCases ( "Cube of Annihilation", ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_00_00_03, 0xFF_14_00_40, 0xFF_00_00_03, 0xFF_14_00_40, (m, t, s, c) -> new ShaderCase.ShaderLayer( m.provideTex(t, s), 0xFF_14_00_40 ) ).setInfo("Twilight Forest", "Cube of Annilation" , "cube_of_annilation" ) + ); + + ImmutableList.Builder listBuilder = ImmutableList.builder(); + + listBuilder.addAll(NONBOSSES); + + listBuilder.add( + registerShaderCases ( "Questing Ram" , ModType.TWILIGHT_FOREST, "streaks" , RARITY, 0xFF_F9_E1_C8, 0xFF_9A_85_69, 0xFF_2F_2B_36, 0xFF_90_D8_EF, LAYER_PROVIDER, (m, t, s, c) -> new ShaderConsumerLayer( ModType.IMMERSIVE_ENGINEERING.provideTex(t, "circuit"), 0x30_90_D8_EF, RAM_TRICONSUMER ) ).setInfo("Twilight Forest", "Questing Ram" , "questing_ram" ), + + registerShaderCases ( "Naga" , ModType.TWILIGHT_FOREST, "scales" , RARITY, 0xFF_32_5D_25, 0xFF_17_29_11, 0xFF_A5_D4_16, 0xFF_FF_FF_FF, LAYER_PROVIDER, (m, t, s, c) -> new ShaderCase.ShaderLayer( ModType.IMMERSIVE_ENGINEERING.provideTex(t, "shark"), 0xFF_FF_FF_FF ) ).setInfo("Twilight Forest", "Naga Boss" , "naga" ), + registerShaderCases ( "Lich" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_DF_D9_CC, 0xFF_C3_9C_00, 0xFF_3A_04_75, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Twilight Lich Boss" , "lich" ), + + registerShaderCases ( "Minoshroom" , ModType.TWILIGHT_FOREST, "1_6" , RARITY, 0xFF_A8_10_12, 0xFF_B3_B3_B3, 0xFF_33_EB_CB, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Minoshroom Miniboss" , "minoshroom" ), + registerShaderCases ( "Hydra" , ModType.TWILIGHT_FOREST, "scales" , RARITY, 0xFF_14_29_40, 0xFF_29_80_6B, 0xFF_F1_0A_92, 0xFF_FF_FF_FF, LAYER_PROVIDER, (m, t, s, c) -> new ShaderCase.ShaderLayer( ModType.IMMERSIVE_ENGINEERING.provideTex(t, "shark"), 0xFF_FF_FF_FF ) ).setInfo("Twilight Forest", "Hydra Boss" , "hydra" ), + + registerShaderCases ( "Knight Phantom" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xCC_40_6D_05, 0xFF_36_35_34, 0xFF_7A_5C_49, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Knight Phantom Minibosses", "knight_phantom" ), + registerShaderCases ( "Ur-Ghast" , ModType.TWILIGHT_FOREST, "1_2" , RARITY, 0xFF_F9_F9_F9, 0xFF_9A_37_37, 0xFF_56_56_56, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Ur-Ghast" , "ur-ghast" ), + + registerShaderCases ( "Alpha Yeti" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_FC_FC_FC, 0xFF_4A_80_CE, 0xFF_25_3F_66, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Alpha Yeti" , "alpha_yeti" ), + registerShaderCases ( "Snow Queen" , ModType.TWILIGHT_FOREST, "1_0" , RARITY, 0xFF_DC_FB_FF, 0xFF_C3_9C_00, 0xFF_03_05_89, 0xFF_FF_FF_FF, LAYER_PROVIDER ).setInfo("Twilight Forest", "Snow Queen" , "snow_queen" ) + ); + + SHADERS = listBuilder.build(); + } + + public static List getAllTwilightShaders() { + return SHADERS; + } + + public static List getAllNonbossShaders() { + return NONBOSSES; + } + + // Shaderizing! + private static class ShaderConsumerLayer extends ShaderCase.DynamicShaderLayer { + + private final TriConsumer render; + private final IntConsumer shaderCallback; + + ShaderConsumerLayer(ResourceLocation texture, int colour, TriConsumer render, ShaderUniform... shaderParams) { + super(texture, colour); + this.render = render; + + shaderCallback = shader -> { for(ShaderUniform param: shaderParams) { param.assignUniform(shader); } }; + } + + @Override + public void modifyRender(boolean pre, float partialTick) { + this.render.accept(shaderCallback, pre, partialTick); + } + } + + @SafeVarargs + private static ShaderRegistry.ShaderRegistryEntry registerShaderCasesTopped(String name, ModType mod, String overlayType, EnumRarity rarity, int bodyColor, int colorSecondary, int gripColor, int colorBlade, ShaderLayerProvider[] providers, ShaderLayerProvider... extraProviders) { + ShaderRegistry.registerShader_Item(name, rarity, gripColor, bodyColor, colorSecondary); + + registerShaderCaseRevolver ( name, gripColor, bodyColor, colorBlade, rarity, provideFromProviders( mod, CaseType.REVOLVER , overlayType, colorSecondary, providers ), provideFromProviders( mod, CaseType.REVOLVER , overlayType , colorSecondary, extraProviders )); + registerShaderCaseChemthrower( name, gripColor, bodyColor, rarity, provideFromProviders( mod, CaseType.CHEMICAL_THROWER, overlayType, colorSecondary, providers ), provideFromProviders( mod, CaseType.CHEMICAL_THROWER, overlayType , colorSecondary, extraProviders )); + registerShaderCaseDrill ( name, gripColor, bodyColor, colorBlade, rarity, provideFromProviders( mod, CaseType.DRILL , overlayType, colorSecondary, providers ), provideFromProviders( mod, CaseType.DRILL , overlayType , colorSecondary, extraProviders )); + registerShaderCaseRailgun ( name, gripColor, bodyColor, rarity, provideFromProviders( mod, CaseType.RAILGUN , overlayType, colorSecondary, providers ), provideFromProviders( mod, CaseType.RAILGUN , overlayType , colorSecondary, extraProviders )); + registerShaderCaseShield ( name, gripColor, bodyColor, rarity, provideFromProviders( mod, CaseType.SHIELD , overlayType, colorSecondary, providers ), provideFromProviders( mod, CaseType.SHIELD , overlayType , colorSecondary, extraProviders )); + registerShaderCaseMinecart ( name, gripColor, bodyColor, rarity, provideFromProviders( mod, CaseType.MINECART , overlayType, colorSecondary, providers ), provideFromProviders( mod, CaseType.MINECART , overlayType + ".png" , colorSecondary, extraProviders )); + registerShaderCaseBalloon ( name, gripColor, bodyColor, rarity, provideFromProviders( mod, CaseType.BALLOON , overlayType, colorSecondary, providers ), provideFromProviders( mod, CaseType.BALLOON , overlayType , colorSecondary, extraProviders )); + + // Since shaders won't occur in a way we'd like them to, we should register any additional variants ourselves if we know of any + for (ShaderRegistry.IShaderRegistryMethod method : ShaderRegistry.shaderRegistrationMethods) { + method.apply(name, overlayType, rarity, gripColor, bodyColor, colorSecondary, colorBlade, null, 0); + } + + return ShaderRegistry.shaderRegistry.get(name).setCrateLoot(false).setBagLoot(false).setInLowerBags(false).setReplicationCost(new IngredientStack(new ItemStack(TFItems.ore_meter))); + } + + @SafeVarargs + private static ShaderRegistry.ShaderRegistryEntry registerShaderCases(String name, ModType type, String overlayType, EnumRarity rarity, int bodyColor, int colorSecondary, int gripColor, int colorBlade, ShaderLayerProvider... providers) { + return registerShaderCasesTopped(name, type, overlayType, rarity, bodyColor, colorSecondary, gripColor, colorBlade, providers); + } + + // Shader Case Registration helpers + @FunctionalInterface + private interface ShaderLayerProvider { + T get(ModType mod, CaseType type, String suffix, int color); + } + + private static ShaderCase.ShaderLayer[] provideFromProviders( ModType mod, CaseType type, String suffix, int color, ShaderLayerProvider[] layerProviders) { + ShaderCase.ShaderLayer[] array = new ShaderCase.ShaderLayer[layerProviders.length]; + + for (int i = 0; i < layerProviders.length; i++) + array[i] = layerProviders[i].get( mod, type, suffix, color ); + + return array; + } + + @SuppressWarnings("UnusedReturnValue") + private static ShaderCaseRevolver registerShaderCaseRevolver(String name, int gripColor, int bodyColor, int bladeColor, EnumRarity rarity, ShaderCase.ShaderLayer[] additionalLayers, ShaderCase.ShaderLayer... topLayers) { + ImmutableList.Builder shaderLayerBuilder = ImmutableList.builder(); + + return ShaderRegistry.registerShaderCase(name, new ShaderCaseRevolver( + shaderLayerBuilder.add( + new ShaderCase.ShaderLayer(PROCESSED_REVOLVER_GRIP_LAYER, gripColor), + new ShaderCase.ShaderLayer(PROCESSED_REVOLVER_LAYER, bodyColor), + new ShaderCase.ShaderLayer(PROCESSED_REVOLVER_LAYER, bladeColor) + ).add(additionalLayers).add(UNCOLORED_REVOLVER_LAYER).add(topLayers).build()), rarity); + } + + @SuppressWarnings("UnusedReturnValue") + private static ShaderCaseChemthrower registerShaderCaseChemthrower(String name, int gripColor, int bodyColor, EnumRarity rarity, ShaderCase.ShaderLayer[] additionalLayers, ShaderCase.ShaderLayer... topLayers) { + ImmutableList.Builder shaderLayerBuilder = ImmutableList.builder(); + + return ShaderRegistry.registerShaderCase(name, new TFShaderCaseChemthrower( 3 + additionalLayers.length, + shaderLayerBuilder.add( + new ShaderCase.ShaderLayer(PROCESSED_CHEMTHROW_LAYER, gripColor), + new ShaderCase.ShaderLayer(PROCESSED_CHEMTHROW_LAYER, bodyColor) + ).add(additionalLayers).add(UNCOLORED_CHEMTHROW_LAYER).add(topLayers).build()), rarity); + } + + @SuppressWarnings("UnusedReturnValue") + private static ShaderCaseDrill registerShaderCaseDrill(String name, int gripColor, int bodyColor, int bladeColor, EnumRarity rarity, ShaderCase.ShaderLayer[] additionalLayers, ShaderCase.ShaderLayer... topLayers) { + ImmutableList.Builder shaderLayerBuilder = ImmutableList.builder(); + + return ShaderRegistry.registerShaderCase(name, new TFShaderCaseDrill( 5 + additionalLayers.length, + shaderLayerBuilder.add( + new ShaderCase.ShaderLayer(PROCESSED_DRILL_LAYER, gripColor), + new ShaderCase.ShaderLayer(PROCESSED_DRILL_LAYER, bodyColor) + ).add(UNCOLORED_DRILL_LAYER).add(additionalLayers).add(UNCOLORED_DRILL_LAYER).add(NULL_LAYER).add(topLayers).build()), rarity);//.addHeadLayers(new ShaderCase.ShaderLayer(new ResourceLocation("immersiveengineering", "items/drill_iron"), bladeColor)); + } + + @SuppressWarnings("UnusedReturnValue") + private static ShaderCaseRailgun registerShaderCaseRailgun(String name, int gripColor, int bodyColor, EnumRarity rarity, ShaderCase.ShaderLayer[] additionalLayers, ShaderCase.ShaderLayer... topLayers) { + ImmutableList.Builder shaderLayerBuilder = ImmutableList.builder(); + + return ShaderRegistry.registerShaderCase(name, new TFShaderCaseRailgun( 3 + additionalLayers.length, + shaderLayerBuilder.add( + new ShaderCase.ShaderLayer(PROCESSED_RAILGUN_LAYER, gripColor), + new ShaderCase.ShaderLayer(PROCESSED_RAILGUN_LAYER, bodyColor) + ).add(additionalLayers).add(UNCOLORED_RAILGUN_LAYER).add(topLayers).build()), rarity); + } + + @SuppressWarnings("UnusedReturnValue") + private static ShaderCaseShield registerShaderCaseShield(String name, int gripColor, int bodyColor, EnumRarity rarity, ShaderCase.ShaderLayer[] additionalLayers, ShaderCase.ShaderLayer... topLayers) { + ImmutableList.Builder shaderLayerBuilder = ImmutableList.builder(); + + return ShaderRegistry.registerShaderCase(name, new TFShaderCaseShield( 3 + additionalLayers.length, + shaderLayerBuilder.add( + new ShaderCase.ShaderLayer(PROCESSED_SHIELD_LAYER, gripColor), + new ShaderCase.ShaderLayer(PROCESSED_SHIELD_LAYER, bodyColor) + ).add(additionalLayers).add(UNCOLORED_SHIELD_LAYER).add(topLayers).build()), rarity); + } + + @SuppressWarnings("UnusedReturnValue") + private static ShaderCaseMinecart registerShaderCaseMinecart(String name, int bodyColor, int secondaryColor, EnumRarity rarity, ShaderCase.ShaderLayer[] additionalLayers, ShaderCase.ShaderLayer... topLayers) { + ImmutableList.Builder shaderLayerBuilder = ImmutableList.builder(); + + return ShaderRegistry.registerShaderCase(name, new ShaderCaseMinecart( + shaderLayerBuilder.add( + new ShaderCase.ShaderLayer( new ResourceLocation( "immersiveengineering", "textures/models/shaders/minecart_0.png" ), bodyColor), + new ShaderCase.ShaderLayer( new ResourceLocation( "immersiveengineering", "textures/models/shaders/minecart_1_0.png" ), secondaryColor) + ).add(additionalLayers).add(UNCOLORED_MINECART_LAYER).add(topLayers).build()), rarity); + } + + @SuppressWarnings("UnusedReturnValue") + private static ShaderCaseBalloon registerShaderCaseBalloon(String name, int gripColor, int bodyColor, EnumRarity rarity, ShaderCase.ShaderLayer[] additionalLayers, ShaderCase.ShaderLayer... topLayers) { + ImmutableList.Builder shaderLayerBuilder = ImmutableList.builder(); + + return ShaderRegistry.registerShaderCase(name, new ShaderCaseBalloon( + shaderLayerBuilder.add( + new ShaderCase.ShaderLayer(PROCESSED_BALLOON_LAYER, gripColor), + new ShaderCase.ShaderLayer(PROCESSED_BALLOON_LAYER, bodyColor) + ).add(additionalLayers).add(UNCOLORED_BALLOON_LAYER).add(topLayers).build()), rarity); + } + + public enum ModType { + + IMMERSIVE_ENGINEERING("immersiveengineering") { + @Override + String getPath(CaseType caseType, String suffix) { + switch (caseType) { + case REVOLVER: + return "revolvers/shaders/revolver_" + suffix; + case CHEMICAL_THROWER: + return "items/shaders/chemthrower_" + suffix; + case DRILL: + return "items/shaders/drill_diesel_" + suffix; + case RAILGUN: + return "items/shaders/railgun_" + suffix; + case SHIELD: + return "items/shaders/shield_" + suffix; + case MINECART: + return "textures/models/shaders/minecart_" + suffix + ".png"; + case BALLOON: + return "blocks/shaders/balloon_" + suffix; + } + + return ""; + } + }, + TWILIGHT_FOREST(TwilightForestMod.ID) { + @Override + String getPath(CaseType caseType, String suffix) { + switch (caseType) { + case REVOLVER: + return "items/immersiveengineering/revolver_" + suffix; + case CHEMICAL_THROWER: + return "items/immersiveengineering/chemthrower_" + suffix; + case DRILL: + return "items/immersiveengineering/drill_" + suffix; + case RAILGUN: + return "items/immersiveengineering/railgun_" + suffix; + case SHIELD: + return "items/immersiveengineering/shield_" + suffix; + case MINECART: + return "textures/model/immersiveengineering/minecart_" + suffix + ".png"; + case BALLOON: + return "blocks/immersiveengineering/balloon_" + suffix; + } + + return ""; + } + + @Override + public ResourceLocation provideTex(CaseType caseType, String suffix) { + if (caseType == CaseType.MINECART && suffix.startsWith("1_")) { + return IMMERSIVE_ENGINEERING.provideTex(caseType, suffix); + } + return super.provideTex(caseType, suffix); + } + }; + + private final String namespace; + + ModType(String namespace) { + this.namespace = namespace; + } + + abstract String getPath(CaseType caseType, String suffix); + + public ResourceLocation provideTex(CaseType caseType, String suffix) { + return new ResourceLocation(namespace, getPath(caseType, suffix)); + } + } + + public enum CaseType { + + REVOLVER, + CHEMICAL_THROWER, + DRILL, + RAILGUN, + SHIELD, + MINECART, + BALLOON; + + public static CaseType[] everythingButMinecart() { + return new CaseType[]{ REVOLVER, CHEMICAL_THROWER, DRILL, RAILGUN, SHIELD, BALLOON }; + } + } +} diff --git a/src/main/java/twilightforest/compat/ie/ItemTFShader.java b/src/main/java/twilightforest/compat/ie/ItemTFShader.java new file mode 100644 index 0000000000..1d40a7b759 --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/ItemTFShader.java @@ -0,0 +1,132 @@ +package twilightforest.compat.ie; + +import blusunrize.immersiveengineering.api.Lib; +import blusunrize.immersiveengineering.api.shader.IShaderItem; +import blusunrize.immersiveengineering.api.shader.ShaderCase; +import blusunrize.immersiveengineering.api.shader.ShaderCaseItem; +import blusunrize.immersiveengineering.api.shader.ShaderRegistry; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.NonNullList; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.translation.I18n; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.Optional; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.item.TFItems; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; +import java.util.Locale; + +// TODO Move to shader capability, where we can then just turn item Trophies into the shaders +@Optional.Interface(modid = Lib.MODID, iface = "blusunrize.immersiveengineering.api.shader.IShaderItem") +public class ItemTFShader extends Item implements IShaderItem, ModelRegisterCallback { + + public ItemTFShader() { + this.setHasSubtypes(true); + this.setCreativeTab(TFItems.creativeTab); + } + + static final String TAG_SHADER = "shader_type"; + + public static final ItemTFShader shader = new ItemTFShader(); + + @Optional.Method(modid = Lib.MODID) + @Override + public ShaderCase getShaderCase(ItemStack shader, ItemStack tool, String shaderType) { + return ShaderRegistry.getShader(getShaderType(shader), shaderType); + } + + @Optional.Method(modid = Lib.MODID) + @Override + public String getShaderName(ItemStack stack) { + return getShaderType(stack); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + String rawShaderName = this.getShaderName(stack); + String unlocalizedShaderName = "twilightforest.shader." + rawShaderName.replace(' ', '_').toLowerCase(Locale.ROOT); + String localizedShaderName = I18n.translateToLocal(unlocalizedShaderName); + + if (unlocalizedShaderName.equals(localizedShaderName)) + return I18n.translateToLocalFormatted(this.getTranslationKey(stack), rawShaderName); // Translation failure + else + return I18n.translateToLocalFormatted(this.getTranslationKey(stack), localizedShaderName); + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World world, List list, ITooltipFlag flag) { + list.add(I18n.translateToLocalFormatted("Level: " + this.getRarity(stack).color + this.getRarity(stack).rarityName)); + + if(!GuiScreen.isShiftKeyDown()) + list.add(I18n.translateToLocalFormatted(Lib.DESC_INFO + "shader.applyTo") + " " + I18n.translateToLocalFormatted(Lib.DESC_INFO + "holdShift")); + else { + list.add(I18n.translateToLocalFormatted(Lib.DESC_INFO + "shader.applyTo")); + + for (ShaderCase sCase : ShaderRegistry.shaderRegistry.get(getShaderName(stack)).getCases()) + if (!(sCase instanceof ShaderCaseItem)) + list.add(TextFormatting.DARK_GRAY + " " + I18n.translateToLocalFormatted(Lib.DESC_INFO + "shader." + sCase.getShaderType())); + } + } + + @Override + public EnumRarity getRarity(ItemStack stack) { + return ShaderRegistry.shaderRegistry.get(getShaderType(stack)).getRarity(); + } + + @Nonnull + private static String getShaderType(ItemStack stack) { + NBTTagCompound compound = stack.getTagCompound(); + + if (compound != null) { + String string = stack.getTagCompound().getString(TAG_SHADER); + + if (!string.isEmpty() && ShaderRegistry.shaderRegistry.containsKey(string)) + return string; + } + + return "Twilight"; + } + + public static int getShaderColors(ItemStack stack, int layer) { + ShaderRegistry.ShaderRegistryEntry entry = ShaderRegistry.shaderRegistry.get(getShaderType(stack)); + + if (entry != null) { + ShaderCase shaderCase = entry.getCase("immersiveengineering:item"); + + if (shaderCase != null) { + ShaderCase.ShaderLayer[] layers = shaderCase.getLayers(); + + return layers[layer % layers.length].getColour(); + } + } + + return 0xFF_FF_FF_FF; + } + + @Override + public void getSubItems(CreativeTabs tab, NonNullList items) { + if (tab == TFItems.creativeTab) { + for (ShaderRegistry.ShaderRegistryEntry entry : IEShaderRegister.getAllTwilightShaders()) { + NBTTagCompound compound = new NBTTagCompound(); + + ItemStack stack = new ItemStack(this, 1, 0); + compound.setString(TAG_SHADER, entry.getName()); + stack.setTagCompound(compound); + + items.add(stack); + } + } + } +} diff --git a/src/main/java/twilightforest/compat/ie/ItemTFShaderGrabbag.java b/src/main/java/twilightforest/compat/ie/ItemTFShaderGrabbag.java new file mode 100644 index 0000000000..80e8197a27 --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/ItemTFShaderGrabbag.java @@ -0,0 +1,133 @@ +package twilightforest.compat.ie; + +import blusunrize.immersiveengineering.api.shader.ShaderRegistry; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.text.translation.I18n; +import net.minecraft.world.World; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.client.registry.ClientRegistry; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.model.item.ShaderGrabbagStackRenderer; +import twilightforest.item.TFItems; + +import javax.annotation.Nullable; +import java.util.List; + +public class ItemTFShaderGrabbag extends Item implements ModelRegisterCallback { + + public ItemTFShaderGrabbag() { + this.setHasSubtypes(true); + this.setCreativeTab(TFItems.creativeTab); + } + + private static final String TAG_SHADER = "shader_rarity"; + public static final ItemTFShaderGrabbag shader_bag = new ItemTFShaderGrabbag(); + + @Override + public void getSubItems(CreativeTabs tab, NonNullList items) { + if (tab == TFItems.creativeTab) { + for(int i = ShaderRegistry.sortedRarityMap.size() - 1; i >= 0; i--) { + ItemStack stack = new ItemStack(this, 1, 0); + + NBTTagCompound compound = new NBTTagCompound(); + compound.setString(TAG_SHADER, ShaderRegistry.sortedRarityMap.get(i).toString()); + + stack.setTagCompound(compound); + + items.add(stack); + } + } + } + + @Override + public EnumRarity getRarity(ItemStack stack) { + NBTTagCompound compound = stack.getTagCompound(); + + if (compound == null) { + stack.setTagCompound(new NBTTagCompound()); + compound = stack.getTagCompound(); + } + + String rarityString = compound.getString(TAG_SHADER); + + for(EnumRarity rarity : EnumRarity.values()) + if(rarity.toString().equalsIgnoreCase(rarityString)) + return rarity; + + return EnumRarity.COMMON; + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + String name = this.getRarity(stack).rarityName; + + return I18n.translateToLocalFormatted(this.getTranslationKey(stack), name); + } + + @Override + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { + ItemStack stack = playerIn.getHeldItem(handIn); + + if (!worldIn.isRemote) { + EnumRarity rarity = stack.getRarity(); + + if (rarity == TwilightForestMod.getRarity()) { + List list = IEShaderRegister.getAllNonbossShaders(); + + return randomShader(list.get(playerIn.getRNG().nextInt(list.size())).name, stack, playerIn); + } else if (ShaderRegistry.totalWeight.containsKey(rarity)) { + return randomShader(ShaderRegistry.getRandomShader(playerIn.getName(), playerIn.getRNG(), rarity, true), stack, playerIn); + } + } + + return new ActionResult<>(EnumActionResult.PASS, stack); + } + + private static ActionResult randomShader(@Nullable String shader, ItemStack stack, EntityPlayer playerIn) { + if ( shader == null || shader.isEmpty() ) + return new ActionResult<>(EnumActionResult.FAIL, stack); + + ItemStack shaderItem = new ItemStack(ItemTFShader.shader); + NBTTagCompound compound = shaderItem.getTagCompound(); + + if (compound == null) { + shaderItem.setTagCompound(new NBTTagCompound()); + compound = shaderItem.getTagCompound(); + } + + compound.setString(ItemTFShader.TAG_SHADER, shader); + + stack.shrink(1); + + if (stack.getCount() <= 0) + return new ActionResult<>(EnumActionResult.SUCCESS, shaderItem); + + if (!playerIn.inventory.addItemStackToInventory(shaderItem)) + playerIn.dropItem(shaderItem, false, true); + + return new ActionResult<>(EnumActionResult.PASS, stack); + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelResourceLocation mrl = new ModelResourceLocation(TwilightForestMod.ID + ":grabbag_tesr", "inventory"); + ModelLoader.setCustomModelResourceLocation(this, 0, mrl); + ClientRegistry.bindTileEntitySpecialRenderer(ShaderGrabbagStackRenderer.DummyTile.class, new ShaderGrabbagStackRenderer(mrl)); + ForgeHooksClient.registerTESRItemStack(this, 0, ShaderGrabbagStackRenderer.DummyTile.class); + } +} diff --git a/src/main/java/twilightforest/compat/ie/TFShaderCaseChemthrower.java b/src/main/java/twilightforest/compat/ie/TFShaderCaseChemthrower.java new file mode 100644 index 0000000000..4a7f17ad22 --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/TFShaderCaseChemthrower.java @@ -0,0 +1,33 @@ +package twilightforest.compat.ie; + +import blusunrize.immersiveengineering.api.shader.ShaderCaseChemthrower; +import net.minecraft.item.ItemStack; + +import java.util.Collection; + +public class TFShaderCaseChemthrower extends ShaderCaseChemthrower { + private final int STACK_BREAK; + + public TFShaderCaseChemthrower(int stackBreak, Collection layers) { + super(layers); + this.STACK_BREAK = stackBreak; + } + + @Override + public boolean renderModelPartForPass(ItemStack shader, ItemStack item, String part, int pass) { + if ("grip".equals(part)) + return pass == 0; + + if (pass == 0) + return false; + + if (pass == 1 && "cage".equals(part)) + return renderCageOnBase; + + if (tanksUncoloured && "tanks".equals(part)) + return pass >= STACK_BREAK - 1; + + return tanksUncoloured || !"tanks".equals(part) || pass < STACK_BREAK - 1; + + } +} diff --git a/src/main/java/twilightforest/compat/ie/TFShaderCaseDrill.java b/src/main/java/twilightforest/compat/ie/TFShaderCaseDrill.java new file mode 100644 index 0000000000..1b8968d968 --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/TFShaderCaseDrill.java @@ -0,0 +1,40 @@ +package twilightforest.compat.ie; + +import blusunrize.immersiveengineering.api.shader.ShaderCase; +import blusunrize.immersiveengineering.api.shader.ShaderCaseDrill; +import net.minecraft.item.ItemStack; + +import java.util.Collection; + +public class TFShaderCaseDrill extends ShaderCaseDrill { + private final int STACK_BREAK; + private int headLayers = 1; + + public TFShaderCaseDrill(int stackBreak, Collection layers) { + super(layers); + this.STACK_BREAK = stackBreak; + } + + @Override + public boolean renderModelPartForPass(ItemStack shader, ItemStack item, String modelPart, int pass) { + if("drill_head".equals(modelPart) || "upgrade_damage0".equals(modelPart) || "upgrade_damage1".equals(modelPart) || "upgrade_damage2".equals(modelPart) || "upgrade_damage3".equals(modelPart) || "upgrade_damage4".equals(modelPart)) + return pass >= STACK_BREAK - 1; + + if( pass == STACK_BREAK - 1 ) //Last pass on drills is just for the head and augers + return false; + + if("upgrade_speed".equals(modelPart) || "upgrade_waterproof".equals(modelPart)) //Upgrades only render on the uncoloured pass + return pass < STACK_BREAK - 2;// && pass < getLayers().length - headLayers; + + if("drill_grip".equals(modelPart)) + return pass == 0; + + return pass != 0; + } + + @Override + public ShaderCaseDrill addHeadLayers(ShaderLayer... addedLayers) { + headLayers+=addedLayers.length; + return super.addHeadLayers(); + } +} diff --git a/src/main/java/twilightforest/compat/ie/TFShaderCaseRailgun.java b/src/main/java/twilightforest/compat/ie/TFShaderCaseRailgun.java new file mode 100644 index 0000000000..faf5b60d21 --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/TFShaderCaseRailgun.java @@ -0,0 +1,27 @@ +package twilightforest.compat.ie; + +import blusunrize.immersiveengineering.api.shader.ShaderCaseRailgun; +import net.minecraft.item.ItemStack; + +import java.util.Collection; + +// Fix for the uncolored top layer not rendering +public class TFShaderCaseRailgun extends ShaderCaseRailgun { + private final int STACK_BREAK; + + public TFShaderCaseRailgun(int stackBreak, Collection layers) { + super(layers); + this.STACK_BREAK = stackBreak; + } + + @Override + public boolean renderModelPartForPass(ItemStack shader, ItemStack item, String part, int pass) { + if("sled".equals(part) || "wires".equals(part) || "tubes".equals(part)) + return pass >= STACK_BREAK - 1; + + if("grip".equals(part)) + return pass == 0; + + return pass != 0; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/compat/ie/TFShaderCaseShield.java b/src/main/java/twilightforest/compat/ie/TFShaderCaseShield.java new file mode 100644 index 0000000000..5b317bcb76 --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/TFShaderCaseShield.java @@ -0,0 +1,21 @@ +package twilightforest.compat.ie; + +import blusunrize.immersiveengineering.api.shader.ShaderCaseShield; +import net.minecraft.item.ItemStack; + +import java.util.Collection; + +public class TFShaderCaseShield extends ShaderCaseShield { + private final int STACK_BREAK; + + public TFShaderCaseShield(int stackBreak, Collection layers) { + super(layers); + this.STACK_BREAK = stackBreak; + } + + @Override + public boolean renderModelPartForPass(ItemStack shader, ItemStack item, String part, int pass) { + return !"flash".equals(part) && !"shock".equals(part) || pass >= STACK_BREAK - 1; + + } +} diff --git a/src/main/java/twilightforest/compat/ie/package-info.java b/src/main/java/twilightforest/compat/ie/package-info.java new file mode 100644 index 0000000000..222c9dcf22 --- /dev/null +++ b/src/main/java/twilightforest/compat/ie/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.compat.ie; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/compat/package-info.java b/src/main/java/twilightforest/compat/package-info.java new file mode 100644 index 0000000000..fc8760f549 --- /dev/null +++ b/src/main/java/twilightforest/compat/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.compat; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/compat/patchouli/GalleryComponent.java b/src/main/java/twilightforest/compat/patchouli/GalleryComponent.java new file mode 100644 index 0000000000..8d7721ceec --- /dev/null +++ b/src/main/java/twilightforest/compat/patchouli/GalleryComponent.java @@ -0,0 +1,64 @@ +package twilightforest.compat.patchouli; + +import com.google.gson.annotations.SerializedName; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; +import vazkii.patchouli.api.IComponentRenderContext; +import vazkii.patchouli.api.ICustomComponent; +import vazkii.patchouli.api.VariableHolder; +import vazkii.patchouli.common.util.ItemStackUtil; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@SuppressWarnings("unused") +public class GalleryComponent implements ICustomComponent { + int x, y; + @SuppressWarnings("WeakerAccess") + @SerializedName("table_x") + int xCount = 6; + + @SuppressWarnings("WeakerAccess") + @VariableHolder + public String items; + + private transient List stacks; + private static final transient Minecraft mc = Minecraft.getMinecraft(); + + @Override + public void build(int x, int y, int pageNum) { + stacks = Arrays.stream(items.split("\\|")).map(ItemStackUtil::loadStackFromString).filter(i -> !i.isEmpty()).collect(Collectors.toList()); + + if (xCount <= 0 || xCount > 6) + xCount = MathHelper.clamp(stacks.size(), 1, 6); + } + + @Override + public void render(IComponentRenderContext context, float pTicks, int mouseX, int mouseY) { + int x = this.x + 5, y = this.y; + int row, column; + int listSize = stacks.size(); + int extras = Math.floorMod(listSize, xCount); + int listBlock = listSize - extras; + + for (int c = 0; c < listSize; c++) { + ItemStack stack = stacks.get(c); + column = Math.floorMod(c, xCount); + row = c / xCount; + + // Pages are 108 pixels wide. + if (c < listBlock) { + context.renderItemStack(column * 18 + x, row * 18 + y, mouseX, mouseY, stack); + } else { + int columnPushed = (column * 18) + 54 - (extras * 9); + + context.renderItemStack(columnPushed + x, row * 18 + y, mouseX, mouseY, stack); + } + } + + //mc.fontRenderer.drawString(listSize + "", x - 40, y , 0xFFAADD); + //mc.fontRenderer.drawString(listBlock + "", x - 40, y + 15, 0xFFAADD); + } +} diff --git a/src/main/java/twilightforest/compat/patchouli/RevisableComponent.java b/src/main/java/twilightforest/compat/patchouli/RevisableComponent.java new file mode 100644 index 0000000000..cd4e3fbb2c --- /dev/null +++ b/src/main/java/twilightforest/compat/patchouli/RevisableComponent.java @@ -0,0 +1,57 @@ +package twilightforest.compat.patchouli; + +import com.google.gson.annotations.SerializedName; +import vazkii.patchouli.api.IComponentRenderContext; +import vazkii.patchouli.api.ICustomComponent; +import vazkii.patchouli.api.VariableHolder; +import vazkii.patchouli.client.base.ClientAdvancements; +import vazkii.patchouli.client.book.gui.BookTextRenderer; +import vazkii.patchouli.client.book.gui.GuiBook; +import vazkii.patchouli.common.base.PatchouliConfig; + +public class RevisableComponent implements ICustomComponent { + + int x, y; + + @SerializedName("advancement_key") + @VariableHolder + public String advancementKey; + + @SerializedName("locked_text") + @VariableHolder + public String oldText; + + @VariableHolder + @SerializedName("unlocked_text") + public String newText; + + @SerializedName("max_width") + int maxWidth = 116; + + @SerializedName("line_height") + int lineHeight = 9; + + transient BookTextRenderer textRenderer; + + @Override + public void build(int x, int y, int pageNum) { + + } + + @Override + public void onDisplayed(IComponentRenderContext context) { + this.textRenderer = new BookTextRenderer((GuiBook) context.getGui(), PatchouliConfig.disableAdvancementLocking || advancementKey == null || advancementKey.isEmpty() || ClientAdvancements.hasDone(this.advancementKey) ? this.newText : this.oldText, this.x, this.y, this.maxWidth, this.lineHeight, 0xFF_000000); + + //TwilightForestMod.LOGGER.info(x + " " + y + " " + maxWidth + " " + lineHeight); + } + + @Override + public void render(IComponentRenderContext context, float pTicks, int mouseX, int mouseY) { + this.textRenderer.render(mouseX, mouseY); + } + + @Override + public void mouseClicked(IComponentRenderContext context, int mouseX, int mouseY, int mouseButton) { + this.textRenderer.click(mouseX, mouseY, mouseButton); + } +} diff --git a/src/main/java/twilightforest/compat/tcon/texture/FieryInfoDeserializer.java b/src/main/java/twilightforest/compat/tcon/texture/FieryInfoDeserializer.java new file mode 100644 index 0000000000..81f7cfa0e6 --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/texture/FieryInfoDeserializer.java @@ -0,0 +1,18 @@ +package twilightforest.compat.tcon.texture; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.ResourceLocation; +import slimeknights.tconstruct.library.client.MaterialRenderInfo; +import slimeknights.tconstruct.library.client.material.deserializers.AbstractRenderInfoDeserializer; + +public class FieryInfoDeserializer extends AbstractRenderInfoDeserializer { + @Override + public MaterialRenderInfo getMaterialRenderInfo() { + return new MaterialRenderInfo.AbstractMaterialRenderInfo() { + @Override + public TextureAtlasSprite getTexture(ResourceLocation baseTexture, String location) { + return new FieryTConTexture(baseTexture, location); + } + }; + } +} diff --git a/src/main/java/twilightforest/compat/tcon/texture/FieryTConTexture.java b/src/main/java/twilightforest/compat/tcon/texture/FieryTConTexture.java new file mode 100644 index 0000000000..4ab3dc2daf --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/texture/FieryTConTexture.java @@ -0,0 +1,183 @@ +package twilightforest.compat.tcon.texture; + +import com.google.common.collect.Lists; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.data.AnimationFrame; +import net.minecraft.client.resources.data.AnimationMetadataSection; +import net.minecraft.util.ResourceLocation; +import slimeknights.tconstruct.library.TinkerAPIException; +import twilightforest.TwilightForestMod; +import twilightforest.client.texture.GradientMappedTexture; +import twilightforest.client.texture.GradientNode; + +import java.awt.image.DirectColorModel; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +// This code contains some copied stuff from AbstractColoredTexture and ExtraUtilityTexture from TCon. Thanks, boni and RWTema! ~ Drullkus + +public class FieryTConTexture extends GradientMappedTConTexture { + private final ResourceLocation textureIn; + + private boolean[] translucent; + private boolean[] edge; + + private static final GradientNode[] outlineColors = { + new GradientNode(0f, 0xFF_FF_FF_FF), + new GradientNode(1f/8f, 0xFF_FF_FA_96), + new GradientNode(3f/8f, 0xFF_FB_AD_24), + new GradientNode(0.5f, 0xFF_FB_96_24), + new GradientNode(5f/8f, 0xFF_FB_AD_24), + new GradientNode(7f/8f, 0xFF_FF_FA_96), + new GradientNode(1f, 0xFF_FF_FF_FF) + }; + + public static final GradientNode[] innerColors = { + new GradientNode(0.1f, 0xFF_3C_23_23), + new GradientNode(0.7f, 0xFF_19_13_13), + new GradientNode(0.9f, 0xFF_08_06_06) + }; + + private static final GradientNode[] innerColorsGlow = { + new GradientNode(0.1f, 0xFF_77_35_11), + new GradientNode(0.7f, 0xFF_66_2D_09), + new GradientNode(0.9f, 0xFF_5d_26_03) + }; + + FieryTConTexture(ResourceLocation textureIn, String spriteName) { + super(textureIn, spriteName, true, innerColors); + + this.textureIn = textureIn; + } + + @Override + public boolean load(IResourceManager manager, ResourceLocation location, Function textureGetter) { + this.framesTextureData = Lists.newArrayList(); + this.frameCounter = 0; + this.tickCounter = 0; + + TextureAtlasSprite baseTexture = textureGetter.apply(textureIn); + if(baseTexture == null || baseTexture.getFrameCount() <= 0) { + this.width = 1; + this.height = 1; + // failure + return false; + } + + this.copyFrom(baseTexture); + + int[][] data; + int[][] dataSecondFrame; + int[][] original = baseTexture.getFrameTextureData(0); + data = new int[original.length][]; + dataSecondFrame = new int[original.length][]; + data[0] = Arrays.copyOf(original[0], original[0].length); + dataSecondFrame[0] = Arrays.copyOf(original[0], original[0].length); + + // do the transformation on the data for mipmap level 0 + // looks like other mipmaps are generated correctly + try { + preProcess(data[0]); + // go over the base texture and color it + for(int pxCoord = 0; pxCoord < data[0].length; pxCoord++) { + data[0][pxCoord] = colorPixel(data[0][pxCoord], pxCoord); + this.gradientMap = innerColorsGlow; + dataSecondFrame[0][pxCoord] = colorPixel(dataSecondFrame[0][pxCoord], pxCoord); + this.gradientMap = innerColors; + } + } catch(Exception e) { + throw new TinkerAPIException("Error occured while processing: " + this.getIconName(), e); + } + + if(this.framesTextureData.isEmpty()) { + this.framesTextureData.add(data); + this.framesTextureData.add(dataSecondFrame); + } + + List frames = new ArrayList<>(); + frames.add(new AnimationFrame(0)); + frames.add(new AnimationFrame(1)); + + this.animationMetadata = new AnimationMetadataSection(frames, width, height, 18, true); + + TwilightForestMod.LOGGER.debug("Autogenerated {} from {}", this.getIconName(), this.textureIn); + + return false; + } + + private static final DirectColorModel colorModel = new DirectColorModel(32, 16711680, '\uff00', 255, -16777216); + + @Override + protected void preProcess(final int[] data) { + edge = new boolean[width * height]; + translucent = new boolean[width * height]; + int c; + + for (int x = 0; x < width; ++x) { + for (int y = 0; y < height; ++y) { + if (x == 0 || y == 0 || x == width - 1 || y == height - 1) edge[coord(x, y)] = true; + + c = data[coord(x, y)]; + if (c == 0 || colorModel.getAlpha(c) < 64) { + translucent[coord(x, y)] = true; + + if (x > 0) { + edge[coord(x - 1, y)] = true; + } + + if (y > 0) { + edge[coord(x, y - 1)] = true; + } + + if (x < width - 1) { + edge[coord(x + 1, y)] = true; + } + + if (y < height - 1) { + edge[coord(x, y + 1)] = true; + } + } + } + } + + int minimumValue = 255; + int maximumValue = 0; + + for (int i = 0; i < data.length; i++) { + int pixel = data[i]; + + if (!edge[i] && !translucent[i]) { + minimumValue = Math.min(minimumValue, getPerceptualBrightness(pixel)); + maximumValue = Math.max(maximumValue, getPerceptualBrightness(pixel)); + } + } + + if (minimumValue > maximumValue) { + this.minimumValue = maximumValue / 255f; + this.maximumValue = minimumValue / 255f; + } else { + this.minimumValue = minimumValue / 255f; + this.maximumValue = maximumValue / 255f; + } + } + + @Override + protected int colorPixel(int pixel, int pxCoord) { + if(!translucent[pxCoord]) { + if(edge[pxCoord]) { + short ff = 0xFF; + int x = (getX(pxCoord) * 0xFF) / width; + int y = (getY(pxCoord) * 0xFF) / height; + int gray = (this.hashCode() + x - y) & ff; + + //noinspection NumericOverflow + return GradientMappedTexture.getGradient((ff << 24) | (gray << 16) | (gray << 8) | gray, outlineColors, 0f, 1f); + } + }//*/ + + return super.colorPixel(pixel, pxCoord); + } +} diff --git a/src/main/java/twilightforest/compat/tcon/texture/GradientMapInfo.java b/src/main/java/twilightforest/compat/tcon/texture/GradientMapInfo.java new file mode 100644 index 0000000000..cd2f791790 --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/texture/GradientMapInfo.java @@ -0,0 +1,23 @@ +package twilightforest.compat.tcon.texture; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.ResourceLocation; +import slimeknights.tconstruct.library.client.MaterialRenderInfo; +import twilightforest.client.texture.GradientNode; + +@SuppressWarnings("WeakerAccess") +public class GradientMapInfo extends MaterialRenderInfo.AbstractMaterialRenderInfo { + + private GradientNode[] gradientMap; + private boolean shouldStretchMinimumMaximum; + + public GradientMapInfo(boolean shouldStretchMinimumMaximum, GradientNode... gradientMap) { + this.gradientMap = gradientMap; + this.shouldStretchMinimumMaximum = shouldStretchMinimumMaximum; + } + + @Override + public TextureAtlasSprite getTexture(ResourceLocation baseTexture, String location) { + return new GradientMappedTConTexture(baseTexture, location, shouldStretchMinimumMaximum, gradientMap); + } +} diff --git a/src/main/java/twilightforest/compat/tcon/texture/GradientMapInfoDeserializer.java b/src/main/java/twilightforest/compat/tcon/texture/GradientMapInfoDeserializer.java new file mode 100644 index 0000000000..65f885adf0 --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/texture/GradientMapInfoDeserializer.java @@ -0,0 +1,46 @@ +package twilightforest.compat.tcon.texture; + +import com.google.gson.annotations.SerializedName; +import slimeknights.tconstruct.library.client.MaterialRenderInfo; +import slimeknights.tconstruct.library.client.material.deserializers.AbstractRenderInfoDeserializer; +import twilightforest.client.texture.GradientNode; + +@SuppressWarnings("WeakerAccess") +public class GradientMapInfoDeserializer extends AbstractRenderInfoDeserializer { + @SuppressWarnings("WeakerAccess") + @SerializedName("gradient_map") + protected SerializedGradientNode[] serializedGradientMap; + @SerializedName("min_max_texture") + protected boolean shouldStretchMinimumMaximum; + + @Override + public MaterialRenderInfo getMaterialRenderInfo() { + GradientNode[] gradientMap = new GradientNode[serializedGradientMap.length]; + + for (int iteration = 0; iteration < serializedGradientMap.length - 1; iteration++) { + int minimumIndex = iteration; + + for (int search = iteration + 1; search < serializedGradientMap.length; search++) + if (serializedGradientMap[search].node < serializedGradientMap[minimumIndex].node) + minimumIndex = search; + + SerializedGradientNode accumulator = serializedGradientMap[minimumIndex]; + serializedGradientMap[minimumIndex] = serializedGradientMap[iteration]; + serializedGradientMap[iteration] = accumulator; + } + + for (int i = 0; i < serializedGradientMap.length; i++) { + gradientMap[i] = new GradientNode(); + gradientMap[i].node = serializedGradientMap[i].node; + gradientMap[i].color = fromHex(serializedGradientMap[i].color); + } + + return new GradientMapInfo(shouldStretchMinimumMaximum, gradientMap); + } + + @SuppressWarnings("unused") + static class SerializedGradientNode { + float node; + String color; + } +} diff --git a/src/main/java/twilightforest/compat/tcon/texture/GradientMappedTConTexture.java b/src/main/java/twilightforest/compat/tcon/texture/GradientMappedTConTexture.java new file mode 100644 index 0000000000..b079d508d5 --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/texture/GradientMappedTConTexture.java @@ -0,0 +1,111 @@ +package twilightforest.compat.tcon.texture; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; +import slimeknights.tconstruct.library.client.RenderUtil; +import slimeknights.tconstruct.library.client.texture.AbstractColoredTexture; +import twilightforest.TwilightForestMod; +import twilightforest.client.texture.GradientMappedTexture; +import twilightforest.client.texture.GradientNode; + +import java.util.function.Function; + +@SuppressWarnings("WeakerAccess") +public class GradientMappedTConTexture extends AbstractColoredTexture { + + private final ResourceLocation textureIn; + protected GradientNode[] gradientMap; + protected boolean shouldStretchMinimumMaximum; + protected float minimumValue; + protected float maximumValue; + + GradientMappedTConTexture(ResourceLocation baseTextureLocation, String spriteName, boolean shouldStretchMinimumMaximum, GradientNode[] gradientMap) { + super(baseTextureLocation, spriteName); + this.shouldStretchMinimumMaximum = shouldStretchMinimumMaximum; + this.gradientMap = gradientMap; + + this.textureIn = baseTextureLocation; + } + + @Override + public boolean load(IResourceManager manager, ResourceLocation location, Function textureGetter) { + TwilightForestMod.LOGGER.debug("Autogenerated {} from {}", this.getIconName(), this.textureIn); + return super.load(manager, location, textureGetter); + } + + @Override + protected void preProcess(final int[] data) { + if (shouldStretchMinimumMaximum) { + int minimumValue = 255; + int maximumValue = 0; + + for (int pixel : data) { + if (RenderUtil.alpha(pixel) == 0) continue; + + minimumValue = Math.min(minimumValue, getPerceptualBrightness(pixel)); + maximumValue = Math.max(maximumValue, getPerceptualBrightness(pixel)); + } + + if (minimumValue > maximumValue) { + this.minimumValue = maximumValue / 255f; + this.maximumValue = minimumValue / 255f; + } else { + this.minimumValue = minimumValue / 255f; + this.maximumValue = maximumValue / 255f; + } + } else { + this.minimumValue = 0f; + this.maximumValue = 1f; + } + } + + @Override + protected int colorPixel(int pixel, int pxCoord) { + int a = RenderUtil.alpha(pixel); + if(a == 0) { + return pixel; + } + + int rFrom = RenderUtil.red (pixel); + int gFrom = RenderUtil.green(pixel); + int bFrom = RenderUtil.blue (pixel); + + int rTo = 0, gTo = 0, bTo = 0; + + // average it + float gray = getModifiedValue((rFrom + gFrom + bFrom) / (3.0f * 255.0f)); + + if (gray <= gradientMap[0].node) { + rTo = RenderUtil.red (gradientMap[0].color); + gTo = RenderUtil.green(gradientMap[0].color); + bTo = RenderUtil.blue (gradientMap[0].color); + } else if (gray >= gradientMap[gradientMap.length-1].node) { + int i = gradientMap[gradientMap.length-1].color; + + rTo = RenderUtil.red (i); + gTo = RenderUtil.green(i); + bTo = RenderUtil.blue (i); + } else { + for (int i = 0; i < gradientMap.length - 1; i++) { + if (gray == gradientMap[i].node) { + rTo = RenderUtil.red (gradientMap[i].color); + gTo = RenderUtil.green(gradientMap[i].color); + bTo = RenderUtil.blue (gradientMap[i].color); + } else if (gray >= gradientMap[i].node && gray <= gradientMap[i+1].node) { + return GradientMappedTexture.interpolateColors(GradientMappedTexture.normalize(gray, gradientMap[i].node, gradientMap[i+1].node), gradientMap[i].color, gradientMap[i+1].color, a); + } + } + } + + return RenderUtil.compose(rTo, gTo, bTo, a); + } + + protected final float getModifiedValue(float valueIn) { + if (shouldStretchMinimumMaximum) + //return (valueIn * (maximumValue - minimumValue)) + minimumValue; + return (valueIn - minimumValue) / (maximumValue - minimumValue); + else + return valueIn; + } +} diff --git a/src/main/java/twilightforest/compat/tcon/trait/TraitPrecipitate.java b/src/main/java/twilightforest/compat/tcon/trait/TraitPrecipitate.java new file mode 100644 index 0000000000..802dedc58c --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/trait/TraitPrecipitate.java @@ -0,0 +1,37 @@ +package twilightforest.compat.tcon.trait; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import net.minecraftforge.event.entity.player.PlayerEvent; +import slimeknights.tconstruct.library.entity.EntityProjectileBase; +import slimeknights.tconstruct.library.traits.AbstractProjectileTrait; + +import javax.annotation.Nullable; + +public class TraitPrecipitate extends AbstractProjectileTrait { + public TraitPrecipitate() { + super("precipitate", TextFormatting.DARK_GREEN); + } + + @Override + public void miningSpeed(ItemStack tool, PlayerEvent.BreakSpeed event) { + event.setNewSpeed(event.getNewSpeed() + (getBonusPercentage(event.getEntityLiving()) * event.getOriginalSpeed())); + } + + @Override + public void onLaunch(EntityProjectileBase projectileBase, World world, @Nullable EntityLivingBase shooter) { + float bonus = getBonusPercentage(shooter); + + projectileBase.motionX += (projectileBase.motionX * bonus); + projectileBase.motionY += (projectileBase.motionY * bonus); + projectileBase.motionZ += (projectileBase.motionZ * bonus); + } + + private float getBonusPercentage(EntityLivingBase entity) { + if (entity == null) return 0.1f; + float maxHealth = entity.getMaxHealth(); + return (maxHealth - entity.getHealth()) / maxHealth; + } +} diff --git a/src/main/java/twilightforest/compat/tcon/trait/TraitStalwart.java b/src/main/java/twilightforest/compat/tcon/trait/TraitStalwart.java new file mode 100644 index 0000000000..8b212c170b --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/trait/TraitStalwart.java @@ -0,0 +1,20 @@ +package twilightforest.compat.tcon.trait; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.MobEffects; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.text.TextFormatting; +import slimeknights.tconstruct.library.traits.AbstractTrait; + +public class TraitStalwart extends AbstractTrait { + public TraitStalwart() { + super("stalwart", TextFormatting.GRAY); + } + + @Override + public void onHit(ItemStack tool, EntityLivingBase player, EntityLivingBase target, float damage, boolean isCritical) { + if (isCritical || random.nextInt(10) == 0) + player.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 200)); + } +} diff --git a/src/main/java/twilightforest/compat/tcon/trait/TraitSynergy.java b/src/main/java/twilightforest/compat/tcon/trait/TraitSynergy.java new file mode 100644 index 0000000000..b9daa24f4c --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/trait/TraitSynergy.java @@ -0,0 +1,61 @@ +package twilightforest.compat.tcon.trait; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import net.minecraftforge.common.util.FakePlayer; +import slimeknights.tconstruct.library.traits.AbstractTrait; +import slimeknights.tconstruct.library.utils.ToolHelper; +import twilightforest.enums.CompressedVariant; +import twilightforest.item.TFItems; +import twilightforest.util.TFItemStackUtils; + +public class TraitSynergy extends AbstractTrait { + public TraitSynergy() { + super("synergy", TextFormatting.GREEN); + } + + private static final float REPAIR_DAMPENER = 1f / 256f; + + @Override + public void onUpdate(ItemStack tool, World world, Entity entity, int itemSlot, boolean isSelected) { + if (!world.isRemote && entity instanceof EntityPlayer && !(entity instanceof FakePlayer)) { + if (!InventoryPlayer.isHotbar(itemSlot) && ((EntityPlayer) entity).getHeldItemOffhand() != tool) return; + if (!needsRepair(tool)) return; + + int healPower = 0; + + NonNullList playerInv = ((EntityPlayer) entity).inventory.mainInventory; + + for (int i = 0; i < 9; i++) { + if (i != itemSlot) { + ItemStack stack = playerInv.get(i); + if (stack.getItem() == TFItems.steeleaf_ingot) { + healPower += stack.getCount(); + } else if (stack.getItem() == TFItems.block_storage && stack.getMetadata() == CompressedVariant.STEELLEAF.ordinal()) { + healPower += stack.getCount() * 9; + } else if (TFItemStackUtils.hasToolMaterial(stack, TFItems.TOOL_STEELEAF)) { + healPower += 1; + } + } + } + + ToolHelper.healTool(tool, averageInt(healPower * REPAIR_DAMPENER), (EntityLivingBase) entity); + } + } + + private static boolean needsRepair(ItemStack itemStack) { + return !itemStack.isEmpty() && itemStack.getItemDamage() > 0 && !ToolHelper.isBroken(itemStack); + } + + private static int averageInt(float value) { + double floor = Math.floor(value); + double rem = value - floor; + return (int) floor + (Math.random() < rem ? 1 : 0); + } +} diff --git a/src/main/java/twilightforest/compat/tcon/trait/TraitTwilit.java b/src/main/java/twilightforest/compat/tcon/trait/TraitTwilit.java new file mode 100644 index 0000000000..b1f7c9d25d --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/trait/TraitTwilit.java @@ -0,0 +1,59 @@ +package twilightforest.compat.tcon.trait; + +import com.google.common.collect.ImmutableList; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import net.minecraftforge.event.entity.player.PlayerEvent; +import slimeknights.tconstruct.library.Util; +import slimeknights.tconstruct.library.entity.EntityProjectileBase; +import slimeknights.tconstruct.library.traits.AbstractProjectileTrait; +import twilightforest.world.TFWorld; + +import javax.annotation.Nullable; +import java.util.List; + +public class TraitTwilit extends AbstractProjectileTrait { + + private static final float bonus = 2.0f; + + public TraitTwilit() { + super("twilit", TextFormatting.GOLD); + } + + @Override + public void miningSpeed(ItemStack tool, PlayerEvent.BreakSpeed event) { + if (TFWorld.isTwilightForest(event.getEntity().world)) + event.setNewSpeed(event.getNewSpeed() + bonus); + } + + @Override + public float damage(ItemStack tool, EntityLivingBase player, EntityLivingBase target, float damage, float newDamage, boolean isCritical) { + if (TFWorld.isTwilightForest(target.world)) + return super.damage(tool, player, target, damage, newDamage, isCritical); + else + return super.damage(tool, player, target, damage, newDamage + bonus, isCritical); + } + + @Override + public void onLaunch(EntityProjectileBase projectileBase, World world, @Nullable EntityLivingBase shooter) { + if (!TFWorld.isTwilightForest(projectileBase.world)) return; + + projectileBase.motionX += (projectileBase.motionX * bonus * 0.1f); + projectileBase.motionY += (projectileBase.motionY * bonus * 0.1f); + projectileBase.motionZ += (projectileBase.motionZ * bonus * 0.1f); + } + + @Override + public List getExtraInfo(ItemStack tool, NBTTagCompound modifierTag) { + String speed = String.format(LOC_Extra + ".speed", getModifierIdentifier()); + String damage = String.format(LOC_Extra + ".damage", getModifierIdentifier()); + + return ImmutableList.of( + Util.translateFormatted(speed , Util.df.format(bonus)), + Util.translateFormatted(damage, Util.df.format(bonus)) + ); + } +} diff --git a/src/main/java/twilightforest/compat/tcon/trait/TraitVeiled.java b/src/main/java/twilightforest/compat/tcon/trait/TraitVeiled.java new file mode 100644 index 0000000000..ad113b62f1 --- /dev/null +++ b/src/main/java/twilightforest/compat/tcon/trait/TraitVeiled.java @@ -0,0 +1,20 @@ +package twilightforest.compat.tcon.trait; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import slimeknights.tconstruct.library.entity.EntityProjectileBase; +import slimeknights.tconstruct.library.traits.AbstractProjectileTrait; + +import javax.annotation.Nullable; + +public class TraitVeiled extends AbstractProjectileTrait { + public TraitVeiled() { + super("veiled", TextFormatting.GRAY); + } + + @Override + public void onLaunch(EntityProjectileBase projectileBase, World world, @Nullable EntityLivingBase shooter) { + projectileBase.setInvisible(true); + } +} diff --git a/src/main/java/twilightforest/enchantment/EnchantmentTFChillAura.java b/src/main/java/twilightforest/enchantment/EnchantmentTFChillAura.java index f21f4bc243..532609c956 100644 --- a/src/main/java/twilightforest/enchantment/EnchantmentTFChillAura.java +++ b/src/main/java/twilightforest/enchantment/EnchantmentTFChillAura.java @@ -2,13 +2,15 @@ import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnumEnchantmentType; +import net.minecraft.inventory.EntityEquipmentSlot; public class EnchantmentTFChillAura extends Enchantment { - - public EnchantmentTFChillAura(int par1, int par2) - { - super(par1, par2, EnumEnchantmentType.armor); - this.setName("tfChillAura"); - - } + // TODO implement + public EnchantmentTFChillAura(Rarity rarity) { + super(rarity, EnumEnchantmentType.ARMOR, new EntityEquipmentSlot[]{ + EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, + EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET + }); + this.setName("tfChillAura"); + } } diff --git a/src/main/java/twilightforest/enchantment/EnchantmentTFFireReact.java b/src/main/java/twilightforest/enchantment/EnchantmentTFFireReact.java index 7cbfe33e90..ac26fedfa9 100644 --- a/src/main/java/twilightforest/enchantment/EnchantmentTFFireReact.java +++ b/src/main/java/twilightforest/enchantment/EnchantmentTFFireReact.java @@ -2,13 +2,15 @@ import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnumEnchantmentType; +import net.minecraft.inventory.EntityEquipmentSlot; public class EnchantmentTFFireReact extends Enchantment { - - public EnchantmentTFFireReact(int par1, int par2) - { - super(par1, par2, EnumEnchantmentType.armor); - this.setName("tfFireReact"); - - } + // TODO implement + public EnchantmentTFFireReact(Rarity rarity) { + super(rarity, EnumEnchantmentType.ARMOR, new EntityEquipmentSlot[]{ + EntityEquipmentSlot.HEAD, EntityEquipmentSlot.CHEST, + EntityEquipmentSlot.LEGS, EntityEquipmentSlot.FEET + }); + this.setName("tfFireReact"); + } } diff --git a/src/main/java/twilightforest/enchantment/TFEnchantment.java b/src/main/java/twilightforest/enchantment/TFEnchantment.java index 700c0bfd9d..7dfb43239b 100644 --- a/src/main/java/twilightforest/enchantment/TFEnchantment.java +++ b/src/main/java/twilightforest/enchantment/TFEnchantment.java @@ -1,34 +1,29 @@ package twilightforest.enchantment; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnumEnchantmentType; import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; -import twilightforest.TwilightForestMod; import twilightforest.item.ItemTFFieryArmor; import twilightforest.item.ItemTFYetiArmor; -public class TFEnchantment extends Enchantment -{ +public class TFEnchantment extends Enchantment { - protected TFEnchantment(int par1, int par2, EnumEnchantmentType par3EnumEnchantmentType) { - super(par1, par2, par3EnumEnchantmentType); + protected TFEnchantment(Rarity rarity, EnumEnchantmentType type, EntityEquipmentSlot[] slots) { + super(rarity, type, slots); } /** * Add up the number of fiery armor pieces the player is wearing, multiplied by 5 */ - public static int getFieryAuraLevel(InventoryPlayer par0InventoryPlayer, DamageSource par1DamageSource) - { + public static int getFieryAuraLevel(InventoryPlayer inventory, DamageSource source) { int modifier = 0; - for (int i = 0; i < par0InventoryPlayer.armorInventory.length; i++) { - ItemStack armor = par0InventoryPlayer.armorInventory[i]; - - if (armor != null && armor.getItem() instanceof ItemTFFieryArmor) { + for (ItemStack armor : inventory.armorInventory) { + if (!armor.isEmpty() && armor.getItem() instanceof ItemTFFieryArmor) { modifier += 5; } } @@ -39,14 +34,11 @@ public static int getFieryAuraLevel(InventoryPlayer par0InventoryPlayer, DamageS /** * Add up the number of yeti armor pieces the player is wearing, 0-4 */ - public static int getChillAuraLevel(InventoryPlayer par0InventoryPlayer, DamageSource par1DamageSource) - { + public static int getChillAuraLevel(InventoryPlayer inventory, DamageSource source) { int modifier = 0; - for (int i = 0; i < par0InventoryPlayer.armorInventory.length; i++) { - ItemStack armor = par0InventoryPlayer.armorInventory[i]; - - if (armor != null && armor.getItem() instanceof ItemTFYetiArmor) { + for (ItemStack armor : inventory.armorInventory) { + if (!armor.isEmpty() && armor.getItem() instanceof ItemTFYetiArmor) { modifier++; } } diff --git a/src/main/java/twilightforest/entity/EntityIceArrow.java b/src/main/java/twilightforest/entity/EntityIceArrow.java index 2a52f652ac..24b6c85f62 100644 --- a/src/main/java/twilightforest/entity/EntityIceArrow.java +++ b/src/main/java/twilightforest/entity/EntityIceArrow.java @@ -1,23 +1,41 @@ package twilightforest.entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Blocks; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import twilightforest.potions.TFPotions; -public class EntityIceArrow extends EntityArrow { +public class EntityIceArrow extends EntityTFArrow { - public EntityIceArrow(World par1World) { - super(par1World); + public EntityIceArrow(World world) { + super(world); } - public EntityIceArrow(World world, EntityPlayer player, float velocity) { - super(world, player, velocity); + public EntityIceArrow(World world, EntityLivingBase shooter) { + super(world, shooter); } - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() { - super.onUpdate(); - } + @Override + public void onUpdate() { + super.onUpdate(); + if (world.isRemote && !inGround) { + int stateId = Block.getStateId(Blocks.SNOW.getDefaultState()); + for (int i = 0; i < 4; ++i) { + this.world.spawnParticle(EnumParticleTypes.FALLING_DUST, this.posX + this.motionX * (double) i / 4.0D, this.posY + this.motionY * (double) i / 4.0D, this.posZ + this.motionZ * (double) i / 4.0D, -this.motionX, -this.motionY + 0.2D, -this.motionZ, stateId); + } + } + } + + @Override + protected void onHit(RayTraceResult ray) { + super.onHit(ray); + if (!world.isRemote && ray.entityHit instanceof EntityLivingBase) { + int chillLevel = 2; + ((EntityLivingBase) ray.entityHit).addPotionEffect(new PotionEffect(TFPotions.frosty, 20 * 10, chillLevel)); + } + } } diff --git a/src/main/java/twilightforest/entity/EntitySeekerArrow.java b/src/main/java/twilightforest/entity/EntitySeekerArrow.java index 3f3432942d..663e111eb4 100644 --- a/src/main/java/twilightforest/entity/EntitySeekerArrow.java +++ b/src/main/java/twilightforest/entity/EntitySeekerArrow.java @@ -1,152 +1,152 @@ package twilightforest.entity; -import java.util.List; - -import net.minecraft.command.IEntitySelector; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class EntitySeekerArrow extends EntityArrow { +import javax.annotation.Nullable; + +public class EntitySeekerArrow extends EntityTFArrow { - private EntityLivingBase homingTarget; - double seekDistance = 5.0; + private static final DataParameter TARGET = EntityDataManager.createKey(EntitySeekerArrow.class, DataSerializers.VARINT); + private static final double seekDistance = 5.0; + private static final double seekFactor = 0.2; + private static final double seekAngle = Math.PI / 6.0; + private static final double seekThreshold = 0.5; - public EntitySeekerArrow(World par1World) { - super(par1World); + public EntitySeekerArrow(World world) { + super(world); } - public EntitySeekerArrow(World world, EntityPlayer player, float velocity) { - super(world, player, velocity); + public EntitySeekerArrow(World world, EntityLivingBase shooter) { + super(world, shooter); } - /** - * Called to update the entity's position/logic. - */ - @SuppressWarnings("rawtypes") - public void onUpdate() - { - // seek! - if (isThisArrowFlying()) { - - if (this.homingTarget == null) { - // find new target - - // target BB - double minX = this.lastTickPosX; - double minY = this.lastTickPosY; - double minZ = this.lastTickPosZ; - double maxX = this.lastTickPosX; - double maxY = this.lastTickPosY; - double maxZ = this.lastTickPosZ; - - - AxisAlignedBB targetBB = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ); - - // add two possible courses to our selection box - Vec3 courseVec = Vec3.createVectorHelper(this.motionX * seekDistance, this.motionY * seekDistance, this.motionZ * seekDistance); - courseVec.rotateAroundY((float) (Math.PI / 6F)); - targetBB = targetBB.addCoord(courseVec.xCoord, courseVec.yCoord, courseVec.zCoord); - - courseVec = Vec3.createVectorHelper(this.motionX * seekDistance, this.motionY * seekDistance, this.motionZ * seekDistance); - courseVec.rotateAroundY(-(float) (Math.PI / 6F)); - targetBB = targetBB.addCoord(courseVec.xCoord, courseVec.yCoord, courseVec.zCoord); - - targetBB.minY -= 3; - targetBB.maxY += 3; - - // find targets in box - List targets = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, targetBB, IEntitySelector.selectAnything); - - double closestDot = 1; - - for (Object thing : targets) { - if (thing instanceof EntityLivingBase && !(thing instanceof EntityPlayer)) { - EntityLivingBase living = (EntityLivingBase)thing; - - System.out.println("Possible target : " + living); - //System.out.println("Selection box = " + targetBB); - - courseVec = Vec3.createVectorHelper(this.motionX, this.motionY, this.motionZ); - courseVec = courseVec.normalize(); - Vec3 targetVec = Vec3.createVectorHelper(this.posX - living.posX, this.posY - (living.posY + (double)living.getEyeHeight()), this.posZ - living.posZ); - - //double d0 = targetVec.lengthVector(); // do we need this? - targetVec = targetVec.normalize(); - double dot = courseVec.dotProduct(targetVec); - - //System.out.println("dot product : " + dot); - - if (dot < closestDot) { - this.homingTarget = living; - closestDot = dot; - } - } - } - if (targets.size() > 0) { - //System.out.println("--- End of list"); - //System.out.println("We have chosen " + this.homingTarget + " as the target"); - } - } else { - // find ideal heading - Vec3 targetVec = Vec3.createVectorHelper(this.posX - this.homingTarget.posX, this.posY - (this.homingTarget.posY + this.homingTarget.getEyeHeight()), this.posZ - this.homingTarget.posZ); - targetVec = targetVec.normalize(); - - Vec3 courseVec = Vec3.createVectorHelper(this.motionX * seekDistance, this.motionY * seekDistance, this.motionZ * seekDistance); - courseVec = courseVec.normalize(); - - double dotProduct = courseVec.dotProduct(targetVec); - //System.out.println("target vec compared to course vec= " + dotProduct); - - if (dotProduct < 0) { - - // match current speed - float currentSpeed = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); - - currentSpeed *= 1.0; - - targetVec.xCoord *= currentSpeed; - targetVec.yCoord *= currentSpeed; - targetVec.zCoord *= currentSpeed; - - // adjust current heading - double dx = MathHelper.clamp_double(targetVec.xCoord, -2.0, 2.0); - double dy = MathHelper.clamp_double(targetVec.yCoord, -1.0, 1.0); - double dz = MathHelper.clamp_double(targetVec.zCoord, -2.0, 2.0); - - // System.out.println("Current heading is " + this.motionX + ", " + this.motionY + ", " + this.motionZ); - // System.out.println("Ideal heading is " + targetVec.xCoord + ", " + targetVec.yCoord + ", " + targetVec.zCoord); - // System.out.println("Adjustment is " + dx + ", " + dy + ", " + dz); - - this.motionX -= dx; - this.motionY -= dy; - this.motionZ -= dz; - } else { - // abandon target, they're behind us! - //System.out.println("abandoning target!"); - - this.homingTarget = null; + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(TARGET, -1); + } + + @Override + public void onUpdate() { + if (isThisArrowFlying()) { + if (!world.isRemote) { + updateTarget(); + } + + if (world.isRemote && !inGround) { + for (int i = 0; i < 4; ++i) { + this.world.spawnParticle(EnumParticleTypes.SPELL_WITCH, this.posX + this.motionX * (double) i / 4.0D, this.posY + this.motionY * (double) i / 4.0D, this.posZ + this.motionZ * (double) i / 4.0D, -this.motionX, -this.motionY + 0.2D, -this.motionZ); } - } + } - this.motionY += 0.045F; + Entity target = getTarget(); + if (target != null) { - } - - // this is a slower arrow, adjust for gravity slightly - - super.onUpdate(); - + Vec3d targetVec = getVectorToTarget(target).scale(seekFactor); + Vec3d courseVec = getMotionVec(); - } + // vector lengths + double courseLen = courseVec.length(); + double targetLen = targetVec.length(); + double totalLen = Math.sqrt(courseLen*courseLen + targetLen*targetLen); - private boolean isThisArrowFlying() { - return MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ) > 1.0; + double dotProduct = courseVec.dotProduct(targetVec) / (courseLen * targetLen); // cosine similarity + + if (dotProduct > seekThreshold) { + + // add vector to target, scale to match current velocity + Vec3d newMotion = courseVec.scale(courseLen / totalLen).add(targetVec.scale(targetLen / totalLen)); + + this.motionX = newMotion.x; + this.motionY = newMotion.y; + this.motionZ = newMotion.z; + + // compensate (mostly) for gravity + this.motionY += 0.045F; + + } else if (!world.isRemote) { + // too inaccurate for our intended target, give up on it + setTarget(null); + } + } + } + + super.onUpdate(); } + private void updateTarget() { + + Entity target = getTarget(); + + if (target != null && target.isDead) { + setTarget(target = null); + } + + if (target == null) { + AxisAlignedBB positionBB = new AxisAlignedBB(posX, posY, posZ, posX, posY, posZ); + AxisAlignedBB targetBB = positionBB; + + // add two possible courses to our selection box + Vec3d courseVec = getMotionVec().scale(seekDistance).rotateYaw((float) seekAngle); + targetBB = targetBB.union(positionBB.offset(courseVec)); + + courseVec = getMotionVec().scale(seekDistance).rotateYaw((float) -seekAngle); + targetBB = targetBB.union(positionBB.offset(courseVec)); + + targetBB = targetBB.grow(0, seekDistance * 0.5, 0); + + double closestDot = -1.0; + Entity closestTarget = null; + + for (EntityLivingBase living : this.world.getEntitiesWithinAABB(EntityLivingBase.class, targetBB)) { + + if (living instanceof EntityPlayer) continue; + + Vec3d motionVec = getMotionVec().normalize(); + Vec3d targetVec = getVectorToTarget(living).normalize(); + + double dot = motionVec.dotProduct(targetVec); + + if (dot > Math.max(closestDot, seekThreshold)) { + closestDot = dot; + closestTarget = living; + } + } + + if (closestTarget != null) { + setTarget(closestTarget); + } + } + } + + private Vec3d getMotionVec() { + return new Vec3d(this.motionX, this.motionY, this.motionZ); + } + + private Vec3d getVectorToTarget(Entity target) { + return new Vec3d(target.posX - this.posX, (target.posY + (double) target.getEyeHeight()) - this.posY, target.posZ - this.posZ); + } + + @Nullable + private Entity getTarget() { + return world.getEntityByID(dataManager.get(TARGET)); + } + + private void setTarget(@Nullable Entity e) { + dataManager.set(TARGET, e == null ? -1 : e.getEntityId()); + } + + private boolean isThisArrowFlying() { + return !inGround && motionX * motionX + motionY * motionY + motionZ * motionZ > 1.0; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFAdherent.java b/src/main/java/twilightforest/entity/EntityTFAdherent.java index 38d89a4588..42423e071e 100644 --- a/src/main/java/twilightforest/entity/EntityTFAdherent.java +++ b/src/main/java/twilightforest/entity/EntityTFAdherent.java @@ -1,125 +1,97 @@ package twilightforest.entity; -import twilightforest.TFAchievementPage; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIArrowAttack; +import net.minecraft.entity.ai.EntityAIAttackRanged; import net.minecraft.entity.ai.EntityAIFleeSun; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIRestrictSun; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.init.SoundEvents; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; +public class EntityTFAdherent extends EntityMob implements IRangedAttackMob, ITFCharger { -public class EntityTFAdherent extends EntityMob implements IRangedAttackMob, ITFCharger { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/adherent"); - private static final int CHARGE_FLAG = 17; + private static final DataParameter CHARGE_FLAG = EntityDataManager.createKey(EntityTFAdherent.class, DataSerializers.BOOLEAN); public EntityTFAdherent(World world) { super(world); + this.setSize(0.8F, 2.2F); + } + @Override + protected void initEntityAI() { this.tasks.addTask(1, new EntityAISwimming(this)); this.tasks.addTask(2, new EntityAIRestrictSun(this)); this.tasks.addTask(3, new EntityAIFleeSun(this, 1.0D)); - this.tasks.addTask(4, new EntityAIArrowAttack(this, 1.0D, 60, 10.0F)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(4, new EntityAIAttackRanged(this, 1.0D, 60, 10.0F)); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(6, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - this.setSize(0.8F, 2.2F); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } - - @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(CHARGE_FLAG, Byte.valueOf((byte)0)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ + @Override - public boolean isAIEnabled() - { - return true; + protected void entityInit() { + super.entityInit(); + dataManager.register(CHARGE_FLAG, false); } - /** - * Set monster attributes - */ - @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); // movement speed - } - - - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D); } - /** - * Attack the specified entity using a ranged attack. - */ @Override public void attackEntityWithRangedAttack(EntityLivingBase attackTarget, float extraDamage) { - EntityTFNatureBolt natureBolt = new EntityTFNatureBolt(this.worldObj, this); - this.worldObj.playSoundAtEntity(this, "mob.ghast.fireball", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); - - natureBolt.setTarget(attackTarget); - - double tx = attackTarget.posX - this.posX; - double ty = attackTarget.posY + attackTarget.getEyeHeight() - 2.699999988079071D - this.posY; - double tz = attackTarget.posZ - this.posZ; - float heightOffset = MathHelper.sqrt_double(tx * tx + tz * tz) * 0.2F; - natureBolt.setThrowableHeading(tx, ty + heightOffset, tz, 0.6F, 6.0F); // 0.6 speed, 6.0 inaccuracy - this.worldObj.spawnEntityInWorld(natureBolt); + EntityTFNatureBolt natureBolt = new EntityTFNatureBolt(this.world, this); + playSound(SoundEvents.ENTITY_GHAST_SHOOT, 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); + + // [VanillaCopy] adapted from EntitySnowman, with lower velocity and inaccuracy calculation + double d0 = attackTarget.posY + (double) attackTarget.getEyeHeight() - 1.100000023841858D; + double d1 = attackTarget.posX - this.posX; + double d2 = d0 - natureBolt.posY; + double d3 = attackTarget.posZ - this.posZ; + float f = MathHelper.sqrt(d1 * d1 + d3 * d3) * 0.2F; + natureBolt.shoot(d1, d2 + (double) f, d3, 0.6F, 10 - this.world.getDifficulty().getId() * 4); + + this.world.spawnEntity(natureBolt); } - - /** - * In this case we're not charging like a bull, but charging up a ranged attack - * @return - */ - public boolean isCharging() - { - return dataWatcher.getWatchableObjectByte(CHARGE_FLAG) != 0; - } - - public void setCharging(boolean flag) - { - if (flag) - { - dataWatcher.updateObject(CHARGE_FLAG, Byte.valueOf((byte)127)); - } - else - { - dataWatcher.updateObject(CHARGE_FLAG, Byte.valueOf((byte)0)); - } - } - + @Override + public void setSwingingArms(boolean swingingArms) {} // todo 1.12 + + @Override + public boolean isCharging() { + return dataManager.get(CHARGE_FLAG); + } + + @Override + public void setCharging(boolean flag) { + dataManager.set(CHARGE_FLAG, flag); + } + + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFArmoredGiant.java b/src/main/java/twilightforest/entity/EntityTFArmoredGiant.java index 80d3431caf..19a7fb041b 100644 --- a/src/main/java/twilightforest/entity/EntityTFArmoredGiant.java +++ b/src/main/java/twilightforest/entity/EntityTFArmoredGiant.java @@ -1,26 +1,33 @@ package twilightforest.entity; -import twilightforest.item.TFItems; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; public class EntityTFArmoredGiant extends EntityTFGiantMiner { - public EntityTFArmoredGiant(World par1World) { - super(par1World); - - this.setCurrentItemOrArmor(0, new ItemStack(Items.stone_sword)); - this.setCurrentItemOrArmor(1, new ItemStack(Items.iron_helmet)); - this.setCurrentItemOrArmor(2, new ItemStack(Items.iron_chestplate)); - this.setCurrentItemOrArmor(3, new ItemStack(Items.iron_leggings)); - this.setCurrentItemOrArmor(4, new ItemStack(Items.iron_boots)); + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/armored_giant"); + public EntityTFArmoredGiant(World world) { + super(world); } - protected Item getDropItem() - { - return TFItems.giantSword; - } + @Override + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + super.setEquipmentBasedOnDifficulty(difficulty); + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); + this.setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(Items.IRON_HELMET)); + this.setItemStackToSlot(EntityEquipmentSlot.CHEST, new ItemStack(Items.IRON_CHESTPLATE)); + this.setItemStackToSlot(EntityEquipmentSlot.LEGS, new ItemStack(Items.IRON_LEGGINGS)); + this.setItemStackToSlot(EntityEquipmentSlot.FEET, new ItemStack(Items.IRON_BOOTS)); + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFArrow.java b/src/main/java/twilightforest/entity/EntityTFArrow.java new file mode 100644 index 0000000000..5d088d28d3 --- /dev/null +++ b/src/main/java/twilightforest/entity/EntityTFArrow.java @@ -0,0 +1,34 @@ +package twilightforest.entity; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public abstract class EntityTFArrow extends EntityArrow implements ITFProjectile { + + public EntityTFArrow(World worldIn) { + super(worldIn); + } + + public EntityTFArrow(World worldIn, EntityLivingBase shooter) { + super(worldIn, shooter); + } + + @Override + protected ItemStack getArrowStack() { + return new ItemStack(Items.ARROW); + } + + @Override + public Entity getThrower() { + return this.shootingEntity; + } + + @Override + public void setThrower(Entity entity) { + this.shootingEntity = entity; + } +} diff --git a/src/main/java/twilightforest/entity/EntityTFBlockGoblin.java b/src/main/java/twilightforest/entity/EntityTFBlockGoblin.java index 468d133c99..578c35f4d1 100644 --- a/src/main/java/twilightforest/entity/EntityTFBlockGoblin.java +++ b/src/main/java/twilightforest/entity/EntityTFBlockGoblin.java @@ -1,379 +1,339 @@ package twilightforest.entity; -import java.util.List; - import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityMultiPart; +import net.minecraft.entity.MultiPartEntityPart; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIAvoidEntity; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.boss.EntityDragonPart; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.item.EntityTNTPrimed; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; +import twilightforest.entity.ai.EntityAIThrowSpikeBlock; +import java.util.List; +import java.util.UUID; public class EntityTFBlockGoblin extends EntityMob implements IEntityMultiPart { - + private static final UUID MODIFIER_UUID = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"); + private static final AttributeModifier MODIFIER = (new AttributeModifier(MODIFIER_UUID, "speedPenalty", -0.25D, 0)).setSaved(false); + - + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/block_goblin"); private static final float CHAIN_SPEED = 16F; - private static final int DATA_CHAINLENGTH = 17; - private static final int DATA_CHAINPOS = 18; - - int recoilCounter; - float chainAngle; - - public EntityTFSpikeBlock block; - public EntityTFGoblinChain chain1; - public EntityTFGoblinChain chain2; - public EntityTFGoblinChain chain3; - - public Entity[] partsArray; - - - public EntityTFBlockGoblin(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "blockgoblin.png"; - //moveSpeed = 0.28F; - setSize(0.9F, 1.4F); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIAvoidEntity(this, EntityTNTPrimed.class, 2.0F, 0.8F, 1.5F)); - this.tasks.addTask(5, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0F, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(7, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - this.recoilCounter = 0; - - this.partsArray = (new Entity[] - { - block = new EntityTFSpikeBlock(this), chain1 = new EntityTFGoblinChain(this), chain2 = new EntityTFGoblinChain(this), chain3 = new EntityTFGoblinChain(this) - }); - - } + private static final DataParameter DATA_CHAINLENGTH = EntityDataManager.createKey(EntityTFBlockGoblin.class, DataSerializers.BYTE); + private static final DataParameter DATA_CHAINPOS = EntityDataManager.createKey(EntityTFBlockGoblin.class, DataSerializers.BYTE); + private static final DataParameter IS_THROWING = EntityDataManager.createKey(EntityTFBlockGoblin.class, DataSerializers.BOOLEAN); + + private int recoilCounter; + private float chainAngle; + + private float chainMoveLength; + + public final EntityTFSpikeBlock block = new EntityTFSpikeBlock(this); + public final EntityTFGoblinChain chain1 = new EntityTFGoblinChain(this); + public final EntityTFGoblinChain chain2 = new EntityTFGoblinChain(this); + public final EntityTFGoblinChain chain3 = new EntityTFGoblinChain(this); + private final Entity[] partsArray = new Entity[]{block, chain1, chain2, chain3}; + + public EntityTFBlockGoblin(World world) { + super(world); + setSize(0.9F, 1.4F); + } @Override - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(DATA_CHAINLENGTH, Byte.valueOf((byte) 0)); - this.dataWatcher.addObject(DATA_CHAINPOS, Byte.valueOf((byte) 0)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAvoidEntity<>(this, EntityTNTPrimed.class, 2.0F, 0.8F, 1.5F)); + this.tasks.addTask(4, new EntityAIThrowSpikeBlock(this, this.block)); + this.tasks.addTask(5, new EntityAIAttackMelee(this, 1.0F, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_CHAINLENGTH, (byte) 0); + dataManager.register(DATA_CHAINPOS, (byte) 0); + dataManager.register(IS_THROWING, false); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(8.0D); // attack damage - } - - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.redcap.redcap"; - } - - @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.redcap.hurt"; - } - - @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.redcap.die"; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItemId() - { - return TFItems.armorShard; - } - - - /** - * Trigger achievement when killed - */ + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(8.0D); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(11.0D); + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + public float getEyeHeight() { + return this.height * 0.78F; } - - /** - * How high is the chain - */ - public double getChainYOffset() - { - return 1.5 - this.getChainLength() / 4.0; - } - - /** - * Get the block & chain position - */ - public Vec3 getChainPosition() - { - return this.getChainPosition(getChainAngle(), getChainLength()); - } - - /** - * Get the block & chain position - */ - public Vec3 getChainPosition(float angle, float distance) - { - double var1 = Math.cos((angle) * Math.PI / 180.0D) * distance; - double var3 = Math.sin((angle) * Math.PI / 180.0D) * distance; - - return Vec3.createVectorHelper(this.posX + var1, this.posY + this.getChainYOffset(), this.posZ + var3); - } - - public boolean isSwingingChain() - { - return this.isSwingInProgress || (this.getAttackTarget() != null && this.recoilCounter == 0); - } - - /** - * Do not deal damage by colliding with the goblin - */ + @Override - public boolean attackEntityAsMob(Entity par1Entity) { - - this.swingItem(); + protected SoundEvent getAmbientSound() { + return TFSounds.REDCAP_AMBIENT; + } - - return false; + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.REDCAP_HURT; + } - - //return super.attackEntityAsMob(par1Entity); + @Override + protected SoundEvent getDeathSound() { + return TFSounds.REDCAP_AMBIENT; } - - /** - * Keep block position updated - */ - @Override + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + /** + * How high is the chain + */ + public double getChainYOffset() { + return 1.5 - this.getChainLength() / 4.0; + } + + /** + * Get the block & chain position + */ + public Vec3d getChainPosition() { + return this.getChainPosition(getChainAngle(), getChainLength()); + } + + /** + * Get the block & chain position + */ + public Vec3d getChainPosition(float angle, float distance) { + double dx = Math.cos((angle) * Math.PI / 180.0D) * distance; + double dz = Math.sin((angle) * Math.PI / 180.0D) * distance; + + return new Vec3d(this.posX + dx, this.posY + this.getChainYOffset(), this.posZ + dz); + } + + public boolean isSwingingChain() { + return this.isSwingInProgress || (this.getAttackTarget() != null && this.recoilCounter == 0); + } + + @Override + public boolean attackEntityAsMob(Entity entity) { + swingArm(EnumHand.MAIN_HAND); + return false; + } + + @Override public void onUpdate() { - super.onUpdate(); block.onUpdate(); chain1.onUpdate(); chain2.onUpdate(); chain3.onUpdate(); - - if (recoilCounter > 0) - { + + if (recoilCounter > 0) { recoilCounter--; } - - chainAngle += CHAIN_SPEED; - chainAngle %= 360; - - if (!this.worldObj.isRemote) - { - this.dataWatcher.updateObject(DATA_CHAINLENGTH, Byte.valueOf((byte) Math.floor(getChainLength() * 127F))); - this.dataWatcher.updateObject(DATA_CHAINPOS, Byte.valueOf((byte) Math.floor(getChainAngle() / 360F * 255F))); - } - else - { - // synch chain pos if it's wrong - if (Math.abs(this.chainAngle - this.getChainAngle()) > CHAIN_SPEED * 2) - { - //FMLLog.info("Fixing chain pos on client"); - this.chainAngle = getChainAngle(); - } - } - - // set block position - Vec3 blockPos = this.getChainPosition(); - this.block.setPosition(blockPos.xCoord, blockPos.yCoord, blockPos.zCoord); - this.block.rotationYaw = getChainAngle(); - - // interpolate chain position - double sx = this.posX; - double sy = this.posY + this.height - 0.1; - double sz = this.posZ; - - double ox = sx - blockPos.xCoord; - double oy = sy - blockPos.yCoord - (block.height / 3D); - double oz = sz - blockPos.zCoord; - - this.chain1.setPosition(sx - ox * 0.4, sy - oy * 0.4, sz - oz * 0.4); - this.chain2.setPosition(sx - ox * 0.5, sy - oy * 0.5, sz - oz * 0.5); - this.chain3.setPosition(sx - ox * 0.6, sy - oy * 0.6, sz - oz * 0.6); - + + chainAngle += CHAIN_SPEED; + chainAngle %= 360; + + if (!this.world.isRemote) { + dataManager.set(DATA_CHAINLENGTH, (byte) Math.floor(getChainLength() * 127.0F)); + dataManager.set(DATA_CHAINPOS, (byte) Math.floor(getChainAngle() / 360.0F * 255.0F)); + } else { + // synch chain pos if it's wrong + if (Math.abs(this.chainAngle - this.getChainAngle()) > CHAIN_SPEED * 2) { + //FMLLog.info("Fixing chain pos on client"); + this.chainAngle = getChainAngle(); + } + } + + if (this.chainMoveLength > 0) { + + Vec3d blockPos = this.getThrowPos(); + + double sx2 = this.posX; + double sy2 = this.posY + this.height - 0.1; + double sz2 = this.posZ; + + double ox2 = sx2 - blockPos.x; + double oy2 = sy2 - blockPos.y - 0.25F; + double oz2 = sz2 - blockPos.z; + + //When the thrown chainblock exceeds a certain distance, return to the owner + if (this.chainMoveLength >= 6.0F || !this.isEntityAlive()) { + this.setThrowing(false); + } + + this.chain1.setPosition(sx2 - ox2 * 0.25, sy2 - oy2 * 0.25, sz2 - oz2 * 0.25); + this.chain2.setPosition(sx2 - ox2 * 0.5, sy2 - oy2 * 0.5, sz2 - oz2 * 0.5); + this.chain3.setPosition(sx2 - ox2 * 0.85, sy2 - oy2 * 0.85, sz2 - oz2 * 0.85); + + this.block.setPosition(sx2 - ox2 * 1.0, sy2 - oy2 * 1.0, sz2 - oz2 * 1.0); + } else { + + + // set block position + Vec3d blockPos = this.getChainPosition(); + this.block.setPosition(blockPos.x, blockPos.y, blockPos.z); + this.block.rotationYaw = getChainAngle(); + + // interpolate chain position + double sx = this.posX; + double sy = this.posY + this.height - 0.1; + double sz = this.posZ; + + double ox = sx - blockPos.x; + double oy = sy - blockPos.y - (block.height / 3D); + double oz = sz - blockPos.z; + + this.chain1.setPosition(sx - ox * 0.4, sy - oy * 0.4, sz - oz * 0.4); + this.chain2.setPosition(sx - ox * 0.5, sy - oy * 0.5, sz - oz * 0.5); + this.chain3.setPosition(sx - ox * 0.6, sy - oy * 0.6, sz - oz * 0.6); + + } + // collide things with the block - if (!worldObj.isRemote && this.isSwingingChain()) - { - this.applyBlockCollisions(this.block); - } - - } - - /** - * Check if the block is colliding with any nearby entities - */ - @SuppressWarnings("unchecked") - protected void applyBlockCollisions(Entity collider) - { - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(collider, collider.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); - - if (list != null && !list.isEmpty()) - { - for (int i = 0; i < list.size(); ++i) - { - Entity entity = (Entity)list.get(i); - - if (entity.canBePushed()) - { - applyBlockCollision(collider, entity); - } - } - } - } - - /** - * Do the effect where the block hits something - */ - protected void applyBlockCollision(Entity collider, Entity collided) - { - if (collided != this) - { - collided.applyEntityCollision(collider); - if (collided instanceof EntityLivingBase) - { - //FMLLog.info("Spike ball collided with entity %s", collided); - - // do hit and throw - boolean attackSuccess = super.attackEntityAsMob(collided); - - if (attackSuccess) - { - collided.motionY += 0.4000000059604645D; - this.playSound("mob.irongolem.throw", 1.0F, 1.0F); - - //System.out.println("Spike ball attack success"); - - this.recoilCounter = 40; - } + if (!world.isRemote && (this.isThrowing() || this.isSwingingChain())) { + this.applyBlockCollisions(this.block); + } + this.chainMove(); + } + + private Vec3d getThrowPos() { + Vec3d vec3d = this.getLook(1.0F); + return new Vec3d(this.posX + vec3d.x * this.chainMoveLength, this.posY + this.getEyeHeight(), this.posZ + vec3d.z * this.chainMoveLength); + } + + private void chainMove() { + + if (this.isThrowing()) { + + this.chainMoveLength = MathHelper.clamp(this.chainMoveLength + 0.5F, 0.0F, 6.0F); + } else { + + this.chainMoveLength = MathHelper.clamp(this.chainMoveLength - 1.5F, 0.0F, 6.0F); + + } + } + + public float getChainMoveLength() { + return chainMoveLength; + } + /** + * Check if the block is colliding with any nearby entities + */ + protected void applyBlockCollisions(Entity collider) { + List list = this.world.getEntitiesWithinAABBExcludingEntity(collider, collider.getEntityBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + for (Entity entity : list) { + if (entity.canBePushed()) { + applyBlockCollision(collider, entity); } } - } - - /** - * Angle between 0 and 360 to place the chain at - */ - public float getChainAngle() - { - if (!this.worldObj.isRemote) - { - return this.chainAngle; - } - else - { - return (this.dataWatcher.getWatchableObjectByte(DATA_CHAINPOS) & 0xFF) / 255F * 360F; - } - } - + } + + /** + * Do the effect where the block hits something + */ + protected void applyBlockCollision(Entity collider, Entity collided) { + if (collided != this) { + collided.applyEntityCollision(collider); + if (collided instanceof EntityLivingBase) { + if (super.attackEntityAsMob(collided)) { + collided.motionY += 0.4; + this.playSound(SoundEvents.ENTITY_IRONGOLEM_ATTACK, 1.0F, 1.0F); + this.recoilCounter = 40; + if (this.isThrowing()) { + this.setThrowing(false); + } + } + + } + } + } + + public boolean isThrowing() { + return this.dataManager.get(IS_THROWING); + } + + public void setThrowing(boolean isThrowing) { + this.dataManager.set(IS_THROWING, isThrowing); + } + + /** + * Angle between 0 and 360 to place the chain at + */ + private float getChainAngle() { + if (!this.world.isRemote) { + return this.chainAngle; + } else { + return (dataManager.get(DATA_CHAINPOS) & 0xFF) / 255.0F * 360.0F; + } + } + /** * Between 0.0F and 2.0F, how long is the chain right now? */ - public float getChainLength() - { - if (!this.worldObj.isRemote) - { - if (isSwingingChain()) - { + private float getChainLength() { + if (!this.world.isRemote) { + if (isSwingingChain()) { return 0.9F; - } - else - { + } else { return 0.3F; } - } - else - { - return (this.dataWatcher.getWatchableObjectByte(DATA_CHAINLENGTH) & 0xFF) / 127F; - } + } else { + return (dataManager.get(DATA_CHAINLENGTH) & 0xFF) / 127.0F; + } } @Override - public World func_82194_d() { - return this.worldObj; + public World getWorld() { + return this.world; } @Override - public boolean attackEntityFromPart(EntityDragonPart entitydragonpart, DamageSource damagesource, float i) { + public boolean attackEntityFromPart(MultiPartEntityPart part, DamageSource source, float damage) { return false; } - - - /** - * We need to do this for the bounding boxes on the parts to become active - */ - @Override - public Entity[] getParts() - { - return partsArray; - } - - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - public int getTotalArmorValue() - { - int i = super.getTotalArmorValue() + 11; - - if (i > 20) - { - i = 20; - } - - return i; - } - - - - + /** + * We need to do this for the bounding boxes on the parts to become active + */ + @Override + public Entity[] getParts() { + return partsArray; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFBoggard.java b/src/main/java/twilightforest/entity/EntityTFBoggard.java index 3df2edb9a8..3d9ee8e349 100644 --- a/src/main/java/twilightforest/entity/EntityTFBoggard.java +++ b/src/main/java/twilightforest/entity/EntityTFBoggard.java @@ -1,220 +1,70 @@ package twilightforest.entity; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.TFFeature; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFChargeAttack; -import twilightforest.item.TFItems; - public class EntityTFBoggard extends EntityMob { - - private boolean shy; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/boggard"); - public EntityTFBoggard(World world) - { - super(world); - //texture = "/mob/pigzombie.png"; - //moveSpeed = 0.28F; - setSize(0.8F, 1.1F); - //attackStrength = 3; + public EntityTFBoggard(World world) { + super(world); + setSize(0.8F, 1.1F); + } - shy = true; - - this.tasks.addTask(0, new EntityAISwimming(this)); + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); // this.tasks.addTask(1, new EntityAITFRedcapShy(this, this.moveSpeed)); - this.tasks.addTask(2, new EntityAITFChargeAttack(this, 2.0F)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0F, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(7, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, false)); - - } - - public EntityTFBoggard(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - + this.tasks.addTask(2, new EntityAITFChargeAttack(this, 2.0F, false)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0F, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, false)); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(14.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D); // attack damage - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.redcap.redcap"; - } - - @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.redcap.redcaphurt"; - } - - @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.redcap.redcapdie"; - } - - @Override - protected Item getDropItem() - { - return Items.iron_boots; - } - - @Override - protected void dropFewItems(boolean flag, int i) - { - if (rand.nextInt(5) == 0) - { - this.dropItem(TFItems.mazeMapFocus, 1 + i); - } - if (rand.nextInt(6) == 0) - { - this.dropItem(Items.iron_boots, 1 + i); - } - if (rand.nextInt(9) == 0) - { - this.dropItem(Items.iron_pickaxe, 1 + i); - } - } - - /** - * The redcap is hesitant, and when he is getting close to the player, he may suddenly veer off to the side - * - * This is our old AI, no longer used - * - protected void updateEntityActionState() - { - super.updateEntityActionState(); - - if (entityToAttack != null) { - float enemyDist = entityToAttack.getDistanceToEntity(this); - - // speed up when very close to enemy or feeling bold - if (enemyDist < 4 || !shy) { - moveSpeed = 0.8F; - } else { - moveSpeed = 0.5F; - } - - // avoid frontal assault - if (enemyDist > 4 && enemyDist < 6 && shy) { - - if (isTargetLookingAtMe()) { - // strafe to the side - moveStrafing = lefty ? moveForward : -moveForward; - moveForward = 0; - } - } - } - - } - */ - - public boolean isShy() { - return shy && this.recentlyHit <= 0; - } - - /** - * Fairly straightforward. Returns true in a 120 degree arc in front of the player's view. - * @return - */ - public boolean isTargetLookingAtMe() { - // find angle of approach - double dx = posX - entityToAttack.posX; - double dz = posZ - entityToAttack.posZ; - float angle = (float)((Math.atan2(dz, dx) * 180D) / 3.1415927410125732D) - 90F; - - float difference = MathHelper.abs((entityToAttack.rotationYaw - angle) % 360); - -// System.out.println("Difference in angle of approach is " + difference); - - return difference < 60 || difference > 300; - } - - - -// @Override -// public boolean attackEntityFrom(Entity entity, int i) { -// -// if (entityToAttack != null && entityToAttack == entity) { -// shy = false; -// // possibly notify others? -// } -// -// return super.attackEntityFrom(entity, i); -// } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(14.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0D); + } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - // are we in a level 1 hill? - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hill1) { - // award level 1 hill cheevo - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHill1); - } - - } + protected SoundEvent getAmbientSound() { + return TFSounds.REDCAP_AMBIENT; } @Override - public void moveEntityWithHeading(float par1, float par2) { - super.moveEntityWithHeading(par1, par2); - -// System.out.println("prevLegYaw = " + this.prevLimbYaw); -// System.out.println("legYaw = " + this.limbYaw); - + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.REDCAP_HURT; } + @Override + protected SoundEvent getDeathSound() { + return TFSounds.REDCAP_AMBIENT; + } - - - + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFChainBlock.java b/src/main/java/twilightforest/entity/EntityTFChainBlock.java index 869227c301..e0688e57c4 100644 --- a/src/main/java/twilightforest/entity/EntityTFChainBlock.java +++ b/src/main/java/twilightforest/entity/EntityTFChainBlock.java @@ -1,351 +1,278 @@ package twilightforest.entity; -import java.util.List; - -import twilightforest.item.ItemTFChainBlock; -import twilightforest.item.TFItems; +import io.netty.buffer.ByteBuf; import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityMultiPart; -import net.minecraft.entity.boss.EntityDragonPart; -import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.MultiPartEntityPart; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityThrowable; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; +import twilightforest.item.TFItems; +import twilightforest.util.WorldUtil; +public class EntityTFChainBlock extends EntityThrowable implements IEntityMultiPart, IEntityAdditionalSpawnData { -public class EntityTFChainBlock extends EntityThrowable implements IEntityMultiPart { - private static final int MAX_SMASH = 12; private static final int MAX_CHAIN = 16; + + private EnumHand hand = EnumHand.MAIN_HAND; private boolean isReturning = false; private int blocksSmashed = 0; - - // where are we headed? private double velX; private double velY; private double velZ; + public final EntityTFGoblinChain chain1 = new EntityTFGoblinChain(this); + public final EntityTFGoblinChain chain2 = new EntityTFGoblinChain(this); + public final EntityTFGoblinChain chain3 = new EntityTFGoblinChain(this); + public final EntityTFGoblinChain chain4 = new EntityTFGoblinChain(this); + public final EntityTFGoblinChain chain5 = new EntityTFGoblinChain(this); + private final Entity[] partsArray = { chain1, chain2, chain3, chain4, chain5 }; - // for the client to show the chain - private boolean isAttached; - private EntityLivingBase attachedTo; - - public EntityTFGoblinChain chain1; - public EntityTFGoblinChain chain2; - public EntityTFGoblinChain chain3; - public EntityTFGoblinChain chain4; - public EntityTFGoblinChain chain5; - public Entity[] partsArray; - - public EntityTFChainBlock(World par1World) { - super(par1World); - + public EntityTFChainBlock(World world) { + super(world); this.setSize(0.6F, 0.6F); - - - this.partsArray = (new Entity[] - { - chain1 = new EntityTFGoblinChain(this), chain2 = new EntityTFGoblinChain(this), chain3 = new EntityTFGoblinChain(this), chain4 = new EntityTFGoblinChain(this), chain5 = new EntityTFGoblinChain(this) - }); } - - public EntityTFChainBlock(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); - // TODO Auto-generated constructor stub - } - - - public EntityTFChainBlock(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); - + public EntityTFChainBlock(World world, EntityLivingBase thrower, EnumHand hand) { + super(world, thrower); this.setSize(0.6F, 0.6F); - this.isReturning = false; + this.hand = hand; + this.shoot(thrower, thrower.rotationPitch, thrower.rotationYaw, 0F, 1.5F, 1F); } - - /** - * Similar to setArrowHeading, it's point the throwable entity to a x, y, z direction. - */ - public void setThrowableHeading(double x, double y, double z, float speed, float accuracy) - { - super.setThrowableHeading(x, y, z, speed, accuracy); - - // save velocity - this.velX = this.motionX; - this.velY = this.motionY; - this.velZ = this.motionZ; - } - - /** - * How much this entity falls each tick - */ + @Override - protected float getGravityVelocity() - { - return 0.05F; - } + public void shoot(double x, double y, double z, float speed, float accuracy) { + super.shoot(x, y, z, speed, accuracy); + // save velocity + this.velX = this.motionX; + this.velY = this.motionY; + this.velZ = this.motionZ; + } + @Override + protected float getGravityVelocity() { + return 0.05F; + } @Override - protected void onImpact(MovingObjectPosition mop) { + protected void onImpact(RayTraceResult ray) { + if (world.isRemote) { + return; + } + // only hit living things - if (mop.entityHit != null && mop.entityHit instanceof EntityLivingBase && mop.entityHit != this.getThrower()) { - if (mop.entityHit.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer) this.getThrower()), 10)) { - // age when we hit a monster so that we go back to the player faster - this.ticksExisted += 60; - } - } - - if (!this.worldObj.isAirBlock(mop.blockX, mop.blockY, mop.blockZ)) { - - // clang! - if (!this.isReturning) { - this.worldObj.playSoundAtEntity(this, "random.anvil_land", 0.125f, this.rand.nextFloat()); - } - - if (!this.worldObj.isRemote && this.blocksSmashed < MAX_SMASH) { - if (this.worldObj.getBlock(mop.blockX, mop.blockY, mop.blockZ).getBlockHardness(worldObj, mop.blockX, mop.blockY, mop.blockZ) > 0.3F) { - // riccochet - double bounce = 0.6; - this.velX *= bounce; - this.velY *= bounce; - this.velZ *= bounce; - - - switch (mop.sideHit) { - case 0: - if (this.velY > 0) { - this.velY *= -bounce; - } - break; - case 1: - if (this.velY < 0) { - this.velY *= -bounce; - } - break; - case 2: - if (this.velZ > 0) { - this.velZ *= -bounce; - } - break; - case 3: - if (this.velZ < 0) { - this.velZ *= -bounce; - } - break; - case 4: - if (this.velX > 0) { - this.velX *= -bounce; - } - break; - case 5: - if (this.velX < 0) { - this.velX *= -bounce; - } - break; - } - } - - // demolish some blocks - this.affectBlocksInAABB(this.boundingBox, this.getThrower()); - } - - // head back to owner - if (!this.worldObj.isRemote) { - this.isReturning = true; - } - - // if we have smashed enough, add to ticks so that we go back faster - if (this.blocksSmashed > MAX_SMASH && this.ticksExisted < 60) { - this.ticksExisted += 60; - } - } + if (ray.entityHit instanceof EntityLivingBase && ray.entityHit != this.getThrower()) { + if (ray.entityHit.attackEntityFrom(this.getDamageSource(), 10)) { + // age when we hit a monster so that we go back to the player faster + this.ticksExisted += 60; + } + } + + if (ray.getBlockPos() != null && !this.world.isAirBlock(ray.getBlockPos())) { + if (!this.isReturning) { + playSound(SoundEvents.BLOCK_ANVIL_LAND, 0.125f, this.rand.nextFloat()); + } + + if (this.blocksSmashed < MAX_SMASH) { + if (this.world.getBlockState(ray.getBlockPos()).getBlockHardness(world, ray.getBlockPos()) > 0.3F) { + // riccochet + double bounce = 0.6; + this.velX *= bounce; + this.velY *= bounce; + this.velZ *= bounce; + + + switch (ray.sideHit) { + case DOWN: + if (this.velY > 0) { + this.velY *= -bounce; + } + break; + case UP: + if (this.velY < 0) { + this.velY *= -bounce; + } + break; + case NORTH: + if (this.velZ > 0) { + this.velZ *= -bounce; + } + break; + case SOUTH: + if (this.velZ < 0) { + this.velZ *= -bounce; + } + break; + case WEST: + if (this.velX > 0) { + this.velX *= -bounce; + } + break; + case EAST: + if (this.velX < 0) { + this.velX *= -bounce; + } + break; + } + } + + // demolish some blocks + this.affectBlocksInAABB(this.getEntityBoundingBox()); + } + + this.isReturning = true; + + // if we have smashed enough, add to ticks so that we go back faster + if (this.blocksSmashed > MAX_SMASH && this.ticksExisted < 60) { + this.ticksExisted += 60; + } + } + } + + private DamageSource getDamageSource() { + EntityLivingBase thrower = this.getThrower(); + if (thrower instanceof EntityPlayer) { + return DamageSource.causePlayerDamage((EntityPlayer) thrower); + } else if (thrower != null) { + return DamageSource.causeMobDamage(thrower); + } else { + return DamageSource.causeThrownDamage(this, null); + } + } + + private void affectBlocksInAABB(AxisAlignedBB box) { + for (BlockPos pos : WorldUtil.getAllInBB(box)) { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + + if (!block.isAir(state, world, pos) && block.getExplosionResistance(this) < 7F + && state.getBlockHardness(world, pos) >= 0 && block.canEntityDestroy(state, world, pos, this)) { + + if (getThrower() instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) getThrower(); + + if (block.canHarvestBlock(world, pos, player)) { + block.harvestBlock(world, player, pos, state, world.getTileEntity(pos), player.getHeldItem(hand)); + } + } + + world.destroyBlock(pos, false); + this.blocksSmashed++; + } + } } - - - /** - * Do our ball and chain effect on blocks we hit. Harvest/destroy/whatevs - * @param entity - */ - private boolean affectBlocksInAABB(AxisAlignedBB par1AxisAlignedBB, EntityLivingBase entity) { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - boolean hitBlock = false; - for (int dx = minX; dx <= maxX; ++dx) { - for (int dy = minY; dy <= maxY; ++dy) { - for (int dz = minZ; dz <= maxZ; ++dz) { - Block block = this.worldObj.getBlock(dx, dy, dz); - int currentMeta = this.worldObj.getBlockMetadata(dx, dy, dz); - - if (block != Blocks.air && block.getExplosionResistance(this) < 7F && block.getBlockHardness(worldObj, dx, dy, dz) >= 0) { - - if (entity != null && entity instanceof EntityPlayer) { - EntityPlayer player = (EntityPlayer)entity; - - if (block.canHarvestBlock(player, currentMeta)){ - block.harvestBlock(this.worldObj, player, dx, dy, dz, currentMeta); - } - } - - this.worldObj.setBlockToAir(dx, dy, dz); - - // here, this effect will have to do - worldObj.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(block) + (currentMeta << 12)); - - this.blocksSmashed++; - - hitBlock = true; - } - } - } - } - - return hitBlock; - } - - - /** - * Skip most of the living update things - */ - @Override - public void onUpdate() { - super.onUpdate(); - - // chains are probably always null on the server - if (this.chain1 != null) { + + @Override + public void onUpdate() { + super.onUpdate(); + + if (world.isRemote) { chain1.onUpdate(); chain2.onUpdate(); chain3.onUpdate(); chain4.onUpdate(); chain5.onUpdate(); - } - - if (this.getThrower() == null && !this.worldObj.isRemote) { - this.setDead(); - } - - if (this.getThrower() != null) { - float distToPlayer = this.getDistanceToEntity(this.getThrower()); - // return if far enough away - if (!this.isReturning && distToPlayer > MAX_CHAIN) { - this.isReturning = true; - } - - // despawn if close enough - if (this.isReturning && distToPlayer < 1F) { - //System.out.println("we have returned after smashing " + this.blocksSmashed + " blocks"); - if (this.getThrower() instanceof EntityPlayer) { - ItemTFChainBlock.setChainAsReturned((EntityPlayer)this.getThrower()); - } - this.setDead(); - } - } - - // if we are returning, set course for the player - if (this.isReturning && !this.worldObj.isRemote && this.getThrower() != null) { - - EntityLivingBase returnTo = this.getThrower(); - - Vec3 back = Vec3.createVectorHelper(returnTo.posX - this.posX, returnTo.posY + (double)returnTo.getEyeHeight() - 1.200000023841858D - this.posY, returnTo.posZ - this.posZ).normalize(); - - float age = Math.min(this.ticksExisted * 0.03F, 1.0F); - - // separate the return velocity from the normal bouncy velocity - this.motionX = this.velX * (1.0 - age) + (back.xCoord * 2F * age); - this.motionY = this.velY * (1.0 - age) + (back.yCoord * 2F * age) - this.getGravityVelocity(); - this.motionZ = this.velZ * (1.0 - age) + (back.zCoord * 2F * age); - - } - - - // on the client, if we are not attached, assume we have just spawned, and attach to the player - if (this.worldObj.isRemote && !this.isAttached) { - List nearbyEntities = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(-this.motionX, -this.motionY, -this.motionZ).expand(2.0D, 2.0D, 2.0D)); - for (int i = 0; i < nearbyEntities.size(); ++i) { - Entity nearby = (Entity)nearbyEntities.get(i); - - // attach? should we check for closest player? - if (nearby instanceof EntityPlayer) { - this.attachedTo = (EntityPlayer) nearby; - - //System.out.println("Attached to player nearby"); - } - } - - this.isAttached = true; - } - - // set chain positions, client only - if (this.attachedTo != null) { - // interpolate chain position - Vec3 handVec = this.attachedTo.getLookVec(); - - handVec.rotateAroundY(-0.4F); - - double sx = this.attachedTo.posX + handVec.xCoord; - double sy = this.attachedTo.posY + handVec.yCoord - 0.6F; - double sz = this.attachedTo.posZ + handVec.zCoord; - - double ox = sx - this.posX; - double oy = sy - this.posY - 0.25F; - double oz = sz - this.posZ; - - this.chain1.setPosition(sx - ox * 0.05, sy - oy * 0.05, sz - oz * 0.05); - this.chain2.setPosition(sx - ox * 0.25, sy - oy * 0.25, sz - oz * 0.25); - this.chain3.setPosition(sx - ox * 0.45, sy - oy * 0.45, sz - oz * 0.45); - this.chain4.setPosition(sx - ox * 0.65, sy - oy * 0.65, sz - oz * 0.65); - this.chain5.setPosition(sx - ox * 0.85, sy - oy * 0.85, sz - oz * 0.85); - } - } - - - - /** - * Velocity - */ - protected float func_70182_d() - { - return 1.5F; - } + // set chain positions + if (this.getThrower() != null) { + // interpolate chain position + Vec3d handVec = this.getThrower().getLookVec().rotateYaw(hand == EnumHand.MAIN_HAND ? -0.4F : 0.4F); + + double sx = this.getThrower().posX + handVec.x; + double sy = this.getThrower().posY + handVec.y - 0.4F + this.getThrower().getEyeHeight(); + double sz = this.getThrower().posZ + handVec.z; + + double ox = sx - this.posX; + double oy = sy - this.posY - 0.25F; + double oz = sz - this.posZ; + + this.chain1.setPosition(sx - ox * 0.05, sy - oy * 0.05, sz - oz * 0.05); + this.chain2.setPosition(sx - ox * 0.25, sy - oy * 0.25, sz - oz * 0.25); + this.chain3.setPosition(sx - ox * 0.45, sy - oy * 0.45, sz - oz * 0.45); + this.chain4.setPosition(sx - ox * 0.65, sy - oy * 0.65, sz - oz * 0.65); + this.chain5.setPosition(sx - ox * 0.85, sy - oy * 0.85, sz - oz * 0.85); + } + } else { + if (getThrower() == null) { + setDead(); + } else { + double distToPlayer = this.getDistance(this.getThrower().posX, this.getThrower().posY + this.getThrower().getEyeHeight(), this.getThrower().posZ); + // return if far enough away + if (!this.isReturning && distToPlayer > MAX_CHAIN) { + this.isReturning = true; + } + + if (this.isReturning) { + // despawn if close enough + if (distToPlayer < 2F) { + this.setDead(); + } + + EntityLivingBase returnTo = this.getThrower(); + + Vec3d back = new Vec3d(returnTo.posX, returnTo.posY + returnTo.getEyeHeight(), returnTo.posZ).subtract(this.getPositionVector()).normalize(); + float age = Math.min(this.ticksExisted * 0.03F, 1.0F); + + // separate the return velocity from the normal bouncy velocity + this.motionX = this.velX * (1.0 - age) + (back.x * 2F * age); + this.motionY = this.velY * (1.0 - age) + (back.y * 2F * age) - this.getGravityVelocity(); + this.motionZ = this.velZ * (1.0 - age) + (back.z * 2F * age); + } + } + } + } @Override - public World func_82194_d() { - return this.worldObj; + public void setDead() { + super.setDead(); + EntityLivingBase thrower = this.getThrower(); + if (thrower != null && thrower.getActiveItemStack().getItem() == TFItems.block_and_chain) { + thrower.resetActiveHand(); + } } + @Override + public World getWorld() { + return this.world; + } @Override - public boolean attackEntityFromPart(EntityDragonPart p_70965_1_, DamageSource p_70965_2_, float p_70965_3_) { + public boolean attackEntityFromPart(MultiPartEntityPart part, DamageSource source, float damage) { return false; } - - /** - * We need to do this for the bounding boxes on the parts to become active - */ - @Override - public Entity[] getParts() - { - return partsArray; - } - + + @Override + public Entity[] getParts() { + return partsArray; + } + + @Override + public void writeSpawnData(ByteBuf buffer) { + buffer.writeInt(getThrower() != null ? getThrower().getEntityId() : -1); + buffer.writeBoolean(hand == EnumHand.MAIN_HAND); + } + + @Override + public void readSpawnData(ByteBuf additionalData) { + Entity e = world.getEntityByID(additionalData.readInt()); + if (e instanceof EntityLivingBase) { + thrower = (EntityLivingBase) e; + } + hand = additionalData.readBoolean() ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFCharmEffect.java b/src/main/java/twilightforest/entity/EntityTFCharmEffect.java index edc2fb9162..3c9b6a0bdf 100644 --- a/src/main/java/twilightforest/entity/EntityTFCharmEffect.java +++ b/src/main/java/twilightforest/entity/EntityTFCharmEffect.java @@ -4,178 +4,139 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.item.TFItems; -public class EntityTFCharmEffect extends Entity -{ +import javax.annotation.Nullable; - private static final int DATA_OWNER = 17; - private static final int DATA_ITEMID = 16; +public class EntityTFCharmEffect extends Entity { + private static final DataParameter DATA_OWNER = EntityDataManager.createKey(EntityTFCharmEffect.class, DataSerializers.VARINT); + private static final DataParameter DATA_ITEMID = EntityDataManager.createKey(EntityTFCharmEffect.class, DataSerializers.VARINT); private static final double DISTANCE = 1.75; - private EntityLivingBase orbiting; - private double newPosX; - private double newPosY; - private double newPosZ; - private double newRotationYaw; - private double newRotationPitch; + private double interpTargetX; + private double interpTargetY; + private double interpTargetZ; + private double interpTargetYaw; + private double interpTargetPitch; private int newPosRotationIncrements; - + public float offset; - // client constructor - public EntityTFCharmEffect(World par1World) - { - super(par1World); + public EntityTFCharmEffect(World world) { + super(world); this.setSize(0.25F, 0.25F); - - this.setItemID(TFItems.charmOfLife1); } - // server constructor - public EntityTFCharmEffect(World par1World, EntityLivingBase par2EntityLiving, Item item) - { - super(par1World); - this.setSize(0.25F, 0.25F); - - this.orbiting = par2EntityLiving; - //this.setOwner(orbiting.getEntityName()); + public EntityTFCharmEffect(World world, EntityLivingBase owner, Item item) { + this(world); + + this.setOwner(owner); this.setItemID(item); - - Vec3 look = Vec3.createVectorHelper(DISTANCE, 0, 0); - - this.setLocationAndAngles(par2EntityLiving.posX, par2EntityLiving.posY + par2EntityLiving.getEyeHeight(), par2EntityLiving.posZ, par2EntityLiving.rotationYaw, par2EntityLiving.rotationPitch); - this.posX += look.xCoord * DISTANCE; - //this.posY += look.yCoord * DISTANCE; - this.posZ += look.zCoord * DISTANCE; - this.setPosition(this.posX, this.posY, this.posZ); - this.yOffset = 0.0F; + Vec3d look = new Vec3d(DISTANCE, 0, 0); + + this.setLocationAndAngles(owner.posX, owner.posY + owner.getEyeHeight(), owner.posZ, owner.rotationYaw, owner.rotationPitch); + this.posX += look.x * DISTANCE; + //this.posY += look.y * DISTANCE; + this.posZ += look.z * DISTANCE; + this.setPosition(this.posX, this.posY, this.posZ); } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - this.lastTickPosX = this.posX; - this.lastTickPosY = this.posY; - this.lastTickPosZ = this.posZ; - super.onUpdate(); - - - if (this.newPosRotationIncrements > 0) - { - double var1 = this.posX + (this.newPosX - this.posX) / (double)this.newPosRotationIncrements; - double var3 = this.posY + (this.newPosY - this.posY) / (double)this.newPosRotationIncrements; - double var5 = this.posZ + (this.newPosZ - this.posZ) / (double)this.newPosRotationIncrements; - double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - (double)this.rotationYaw); - this.rotationYaw = (float)((double)this.rotationYaw + var7 / this.newPosRotationIncrements); - this.rotationPitch = (float)((double)this.rotationPitch + (this.newRotationPitch - (double)this.rotationPitch) / this.newPosRotationIncrements); - --this.newPosRotationIncrements; - this.setPosition(var1, var3, var5); - this.setRotation(this.rotationYaw, this.rotationPitch); - } - - float rotation = this.ticksExisted / 5.0F + offset; - - if (this.orbiting == null) - { - this.orbiting = getOwner(); - } - - if (this.orbiting != null && !worldObj.isRemote) - { - this.setLocationAndAngles(orbiting.posX, orbiting.posY + orbiting.getEyeHeight(), orbiting.posZ, orbiting.rotationYaw, orbiting.rotationPitch); - - Vec3 look = Vec3.createVectorHelper(DISTANCE, 0, 0); - look.rotateAroundY(rotation); - this.posX += look.xCoord; + + @Override + public void onUpdate() { + this.lastTickPosX = this.posX; + this.lastTickPosY = this.posY; + this.lastTickPosZ = this.posZ; + super.onUpdate(); + + //[VanillaCopy] Beginning of EntityLivingBase.onLivingUpdate + if (this.newPosRotationIncrements > 0) { + double d0 = this.posX + (this.interpTargetX - this.posX) / (double) this.newPosRotationIncrements; + double d1 = this.posY + (this.interpTargetY - this.posY) / (double) this.newPosRotationIncrements; + double d2 = this.posZ + (this.interpTargetZ - this.posZ) / (double) this.newPosRotationIncrements; + double d3 = MathHelper.wrapDegrees(this.interpTargetYaw - (double) this.rotationYaw); + this.rotationYaw = (float) ((double) this.rotationYaw + d3 / (double) this.newPosRotationIncrements); + this.rotationPitch = (float) ((double) this.rotationPitch + (this.interpTargetPitch - (double) this.rotationPitch) / (double) this.newPosRotationIncrements); + --this.newPosRotationIncrements; + this.setPosition(d0, d1, d2); + this.setRotation(this.rotationYaw, this.rotationPitch); + } + + EntityLivingBase orbiting = getOwner(); + + if (orbiting != null) { + this.setLocationAndAngles(orbiting.posX, orbiting.posY + orbiting.getEyeHeight(), orbiting.posZ, orbiting.rotationYaw, orbiting.rotationPitch); + + float rotation = this.ticksExisted / 5.0F + offset; + Vec3d look = new Vec3d(DISTANCE, 0, 0).rotateYaw(rotation); + this.posX += look.x; // this.posY += Math.sin(this.ticksExisted / 3.0F + offset); - this.posZ += look.zCoord; - - this.setPosition(this.posX, this.posY, this.posZ); - - } - - if (this.getItemID() > 0) - { - for (int i = 0; i < 3; i++) { - double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); - - worldObj.spawnParticle("iconcrack_" + this.getItemID(), dx, dy, dz, 0, 0.2, 0); - } - } - - if (this.ticksExisted > 200 || this.orbiting == null || this.orbiting.isDead) - { - this.setDead(); - } - } - - /** - * Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX, - * posY, posZ, yaw, pitch - */ - public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) - { - this.yOffset = 0.0F; - this.newPosX = par1; - this.newPosY = par3; - this.newPosZ = par5; - this.newRotationYaw = par7; - this.newRotationPitch = par8; - this.newPosRotationIncrements = par9; - } - - - protected void entityInit() - { - this.dataWatcher.addObject(DATA_ITEMID, Integer.valueOf(0)); - this.dataWatcher.addObject(DATA_OWNER, ""); - } - - public String getOwnerName() - { - return this.dataWatcher.getWatchableObjectString(DATA_OWNER); - } - - public void setOwner(String par1Str) - { - this.dataWatcher.updateObject(DATA_OWNER, par1Str); - } - - public EntityLivingBase getOwner() - { - return this.worldObj.getPlayerEntityByName(this.getOwnerName()); + this.posZ += look.z; + + this.setPosition(this.posX, this.posY, this.posZ); + } + + if (this.getItemID() > -1) { + for (int i = 0; i < 3; i++) { + double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); + + world.spawnParticle(EnumParticleTypes.ITEM_CRACK, dx, dy, dz, 0, 0.2, 0, getItemID()); + } + } + + if (!this.world.isRemote + && (this.ticksExisted > 200 || (orbiting != null && orbiting.isDead))) { + this.setDead(); + } } - public int getItemID() - { - return this.dataWatcher.getWatchableObjectInt(DATA_ITEMID); - } - - public void setItemID(Item charmOfLife1) - { - //this.dataWatcher.updateObject(DATA_ITEMID, Integer.valueOf(charmOfLife1)); - } - - @Override - protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - par1NBTTagCompound.setString("Owner", this.getOwnerName()); - par1NBTTagCompound.setShort("ItemID", (short) this.getItemID()); + @Override + public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport) { + this.interpTargetX = x; + this.interpTargetY = y; + this.interpTargetZ = z; + this.interpTargetYaw = yaw; + this.interpTargetPitch = pitch; + this.newPosRotationIncrements = posRotationIncrements; } @Override - protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - this.setOwner(par1NBTTagCompound.getString("Owner")); - //this.setItemID(par1NBTTagCompound.getShort("ItemID")); + protected void entityInit() { + dataManager.register(DATA_ITEMID, -1); + dataManager.register(DATA_OWNER, -1); } + public void setOwner(EntityLivingBase owner) { + dataManager.set(DATA_OWNER, owner.getEntityId()); + } + + @Nullable + public EntityLivingBase getOwner() { + Entity e = this.world.getEntityByID(dataManager.get(DATA_OWNER)); + if (e instanceof EntityLivingBase) + return (EntityLivingBase) e; + else return null; + } + + public int getItemID() { + return dataManager.get(DATA_ITEMID); + } + + public void setItemID(Item item) { + dataManager.set(DATA_ITEMID, Item.getIdFromItem(item)); + } + + @Override + protected void readEntityFromNBT(NBTTagCompound cmp) {} + + @Override + protected void writeEntityToNBT(NBTTagCompound cmp) {} + } diff --git a/src/main/java/twilightforest/entity/EntityTFCubeOfAnnihilation.java b/src/main/java/twilightforest/entity/EntityTFCubeOfAnnihilation.java index 74f5d318b6..3614c07964 100644 --- a/src/main/java/twilightforest/entity/EntityTFCubeOfAnnihilation.java +++ b/src/main/java/twilightforest/entity/EntityTFCubeOfAnnihilation.java @@ -1,264 +1,182 @@ package twilightforest.entity; -import java.util.List; - -import twilightforest.TFGenericPacketHandler; -import twilightforest.TwilightForestMod; -import twilightforest.block.TFBlocks; -import twilightforest.item.ItemTFChainBlock; -import twilightforest.item.ItemTFCubeOfAnnihilation; -import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; import net.minecraft.block.Block; -import net.minecraft.entity.Entity; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.IEntityMultiPart; -import net.minecraft.entity.boss.EntityDragonPart; -import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityThrowable; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.EnumDyeColor; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import twilightforest.network.TFPacketHandler; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.TFBlocks; +import twilightforest.item.TFItems; +import twilightforest.network.PacketAnnihilateBlock; +import twilightforest.util.WorldUtil; +import java.util.List; -public class EntityTFCubeOfAnnihilation extends EntityThrowable { - - boolean hasHitObstacle = false; - public EntityTFCubeOfAnnihilation(World par1World) { - super(par1World); - - this.setSize(1.1F, 1F); - this.isImmuneToFire = true; +public class EntityTFCubeOfAnnihilation extends EntityThrowable { - } + private boolean hasHitObstacle = false; - - public EntityTFCubeOfAnnihilation(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); + public EntityTFCubeOfAnnihilation(World world) { + super(world); this.setSize(1F, 1F); this.isImmuneToFire = true; } - - public EntityTFCubeOfAnnihilation(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); - + public EntityTFCubeOfAnnihilation(World world, EntityLivingBase thrower) { + super(world, thrower); this.setSize(1F, 1F); this.isImmuneToFire = true; + this.shoot(thrower, thrower.rotationPitch, thrower.rotationYaw, 0F, 1.5F, 1F); } + @Override + protected float getGravityVelocity() { + return 0F; + } - /** - * How much this entity falls each tick - */ @Override - protected float getGravityVelocity() - { - return 0F; - } + protected void onImpact(RayTraceResult ray) { + if (world.isRemote) + return; + // only hit living things + if (ray.entityHit instanceof EntityLivingBase && ray.entityHit.attackEntityFrom(this.getDamageSource(), 10)) { + this.ticksExisted += 60; + } + if (ray.getBlockPos() != null && !this.world.isAirBlock(ray.getBlockPos())) { + this.affectBlocksInAABB(this.getEntityBoundingBox().grow(0.2F, 0.2F, 0.2F)); + } + } - @Override - protected void onImpact(MovingObjectPosition mop) { - // only hit living things - if (mop.entityHit != null && mop.entityHit instanceof EntityLivingBase) - { - if (mop.entityHit.attackEntityFrom(DamageSource.causePlayerDamage((EntityPlayer) this.getThrower()), 10)) - { - this.ticksExisted += 60; - } - } - - if (!this.worldObj.isAirBlock(mop.blockX, mop.blockY, mop.blockZ)) { - - // demolish some blocks - if (!this.worldObj.isRemote) { - this.affectBlocksInAABB(this.boundingBox.expand(0.2F, 0.2F, 0.2F), this.getThrower()); - } - - } + private DamageSource getDamageSource() { + EntityLivingBase thrower = this.getThrower(); + if (thrower instanceof EntityPlayer) { + return DamageSource.causePlayerDamage((EntityPlayer) thrower); + } else if (thrower != null) { + return DamageSource.causeMobDamage(thrower); + } else { + return DamageSource.causeThrownDamage(this, null); + } + } + private void affectBlocksInAABB(AxisAlignedBB box) { + for (BlockPos pos : WorldUtil.getAllInBB(box)) { + IBlockState state = world.getBlockState(pos); + if (!state.getBlock().isAir(state, world, pos)) { + if (canAnnihilate(pos, state)) { + this.world.setBlockToAir(pos); + this.playSound(SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, 0.125f, this.rand.nextFloat() * 0.25F + 0.75F); + this.sendAnnihilateBlockPacket(world, pos); + } else { + this.hasHitObstacle = true; + } + } + } } - - - /** - * Do our ball and chain effect on blocks we hit. Harvest/destroy/whatevs - * @param entity - */ - private boolean affectBlocksInAABB(AxisAlignedBB par1AxisAlignedBB, EntityLivingBase entity) { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - boolean hitBlock = false; - for (int dx = minX; dx <= maxX; ++dx) { - for (int dy = minY; dy <= maxY; ++dy) { - for (int dz = minZ; dz <= maxZ; ++dz) { - Block block = this.worldObj.getBlock(dx, dy, dz); - int currentMeta = this.worldObj.getBlockMetadata(dx, dy, dz); - - if (block != Blocks.air) { - if (canAnnihilate(dx, dy, dz, block, currentMeta)) { - this.worldObj.setBlockToAir(dx, dy, dz); - - this.worldObj.playSoundAtEntity(this, "random.fizz", 0.125f, this.rand.nextFloat() * 0.25F + 0.75F); - - this.sendAnnihilateBlockPacket(worldObj, dx, dy, dz); - - } else { - // return if we hit an obstacle - this.hasHitObstacle = true; - } - hitBlock = true; - } - } - } - } - - return hitBlock; - } - - - private boolean canAnnihilate(int dx, int dy, int dz, Block block, int meta) { + + private boolean canAnnihilate(BlockPos pos, IBlockState state) { // whitelist many castle blocks - if (block == TFBlocks.deadrock || block == TFBlocks.castleBlock || (block == TFBlocks.castleMagic && meta != 3) || block == TFBlocks.forceField || block == TFBlocks.thorns) { + Block block = state.getBlock(); + if (block == TFBlocks.deadrock || block == TFBlocks.castle_brick || (block == TFBlocks.castle_rune_brick && state.getValue(BlockTFCastleMagic.COLOR) != EnumDyeColor.PURPLE) || block == TFBlocks.force_field || block == TFBlocks.thorns) { return true; } - - return block.getExplosionResistance(this) < 8F && block.getBlockHardness(worldObj, dx, dy, dz) >= 0; + + return block.getExplosionResistance(this) < 8F && state.getBlockHardness(world, pos) >= 0; } - - private void sendAnnihilateBlockPacket(World world, int x, int y, int z) { + private void sendAnnihilateBlockPacket(World world, BlockPos pos) { // send packet - FMLProxyPacket message = TFGenericPacketHandler.makeAnnihilateBlockPacket(x, y, z); + IMessage message = new PacketAnnihilateBlock(pos); + + NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 64); - NetworkRegistry.TargetPoint targetPoint = new NetworkRegistry.TargetPoint(world.provider.dimensionId, x, y, z, 64); - - TwilightForestMod.genericChannel.sendToAllAround(message, targetPoint); + TFPacketHandler.CHANNEL.sendToAllAround(message, targetPoint); + } + + @Override + public void onUpdate() { + super.onUpdate(); + + if (!this.world.isRemote) { + if (this.getThrower() == null) { + this.setDead(); + return; + } + + // always head towards either the point or towards the player + Vec3d destPoint = new Vec3d(this.getThrower().posX, this.getThrower().posY + this.getThrower().getEyeHeight(), this.getThrower().posZ); + + if (this.isReturning()) { + // if we are returning, and are near enough to the player, then we are done + List list = this.world.getEntitiesWithinAABB(EntityLivingBase.class, this.getEntityBoundingBox().offset(this.motionX, this.motionY, this.motionZ).grow(1.0D, 1.0D, 1.0D)); + + if (list.contains(this.getThrower())) { + this.setDead(); + } + } else { + destPoint = destPoint.add(getThrower().getLookVec().scale(16F)); + } + + // set motions + Vec3d velocity = new Vec3d(this.posX - destPoint.x, (this.posY + this.height / 2F) - destPoint.y, this.posZ - destPoint.z); + + this.motionX -= velocity.x; + this.motionY -= velocity.y; + this.motionZ -= velocity.z; + + // normalize speed + float currentSpeed = MathHelper.sqrt(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + + float maxSpeed = 0.5F; + + + if (currentSpeed > maxSpeed) { + this.motionX /= currentSpeed / maxSpeed; + this.motionY /= currentSpeed / maxSpeed; + this.motionZ /= currentSpeed / maxSpeed; + } else { + float slow = 0.5F; + this.motionX *= slow; + this.motionY *= slow; + this.motionZ *= slow; + } + + // demolish some blocks + this.affectBlocksInAABB(this.getEntityBoundingBox().grow(0.2F, 0.2F, 0.2F)); + } + } + + @Override + public void setDead() { + super.setDead(); + EntityLivingBase thrower = this.getThrower(); + if (thrower != null && thrower.getActiveItemStack().getItem() == TFItems.cube_of_annihilation) { + thrower.resetActiveHand(); + } + } + + private boolean isReturning() { + if (this.hasHitObstacle || this.getThrower() == null || !(this.getThrower() instanceof EntityPlayer)) { + return true; + } else { + EntityPlayer player = (EntityPlayer) this.getThrower(); + return !player.isHandActive(); + } } - - /** - * Skip most of the living update things - */ - @Override - public void onUpdate() { - super.onUpdate(); - - // all server side - if (!this.worldObj.isRemote) { - - if (this.getThrower() == null) { - this.setDead(); - return; - } - - if (this.isReturning()) { - // if we are returning, and are near enough to the player, then we are done - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); - - if (list.contains(this.getThrower()) && !this.worldObj.isRemote) { - //System.out.println("we have returned"); - if (this.getThrower() instanceof EntityPlayer) { - ItemTFCubeOfAnnihilation.setCubeAsReturned((EntityPlayer)this.getThrower()); - } - this.setDead(); - } - } - - - - // always head towards either the point or towards the player - Vec3 destPoint = Vec3.createVectorHelper(this.getThrower().posX, this.getThrower().posY + this.getThrower().getEyeHeight(), this.getThrower().posZ); - - if (!this.isReturning()) { - Vec3 look = this.getThrower().getLookVec(); - - - - float dist = 16F; - - look.xCoord *= dist; - look.yCoord *= dist; - look.zCoord *= dist; - - destPoint.xCoord += look.xCoord; - destPoint.yCoord += look.yCoord; - destPoint.zCoord += look.zCoord; - } - - //System.out.println("Dest point = " + destPoint); - - - // set motions - Vec3 velocity = Vec3.createVectorHelper(this.posX - destPoint.xCoord, (this.posY + this.height / 2F) - destPoint.yCoord, this.posZ - destPoint.zCoord); - - this.motionX -= velocity.xCoord; - this.motionY -= velocity.yCoord; - this.motionZ -= velocity.zCoord; - - // normalize speed - float currentSpeed = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); - - float maxSpeed = 0.5F; - - - if (currentSpeed > maxSpeed) { - this.motionX /= currentSpeed / maxSpeed; - this.motionY /= currentSpeed / maxSpeed; - this.motionZ /= currentSpeed / maxSpeed; - } else { - float slow = 0.5F; - this.motionX *= slow; - this.motionY *= slow; - this.motionZ *= slow; - } - - - // demolish some blocks - this.affectBlocksInAABB(this.boundingBox.expand(0.2F, 0.2F, 0.2F), this.getThrower()); - - } - - - - - } - - public boolean isReturning() { - if (this.hasHitObstacle || this.getThrower() == null || !(this.getThrower() instanceof EntityPlayer)) { - return true; - } else { - EntityPlayer player = (EntityPlayer) this.getThrower(); - - return !player.isUsingItem(); - } - } - - - - /** - * Velocity - */ - protected float func_70182_d() - { - return 1.5F; - } - - } diff --git a/src/main/java/twilightforest/entity/EntityTFDeathTome.java b/src/main/java/twilightforest/entity/EntityTFDeathTome.java index ca9063cc2e..d3bfa91826 100644 --- a/src/main/java/twilightforest/entity/EntityTFDeathTome.java +++ b/src/main/java/twilightforest/entity/EntityTFDeathTome.java @@ -1,153 +1,125 @@ package twilightforest.entity; -import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackRanged; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.entity.projectile.EntityThrowable; +import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.entity.ai.EntityAITFMagicAttack; -import twilightforest.item.TFItems; - -public class EntityTFDeathTome extends EntityMob { - - public EntityTFDeathTome(World par1World) { - super(par1World); - //texture = "/item/book.png"; - - //this.attackStrength = 4; - //this.moveSpeed = 0.25F; - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(4, new EntityAITFMagicAttack(this, 1.0F, 2, 60)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0F)); +import net.minecraft.world.WorldServer; +import net.minecraft.world.storage.loot.LootContext; +import twilightforest.TFSounds; +import twilightforest.TwilightForestMod; + +import javax.annotation.Nullable; + +public class EntityTFDeathTome extends EntityMob implements IRangedAttackMob { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/death_tome"); + public static final ResourceLocation HURT_LOOT_TABLE = TwilightForestMod.prefix("entities/death_tome_hurt"); + + public EntityTFDeathTome(World world) { + super(world); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(4, new EntityAIAttackRanged(this, 1, 60, 10)); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(6, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } - public int getAttackStrength(Entity par1Entity) - { - return 4; - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); // movement speed - } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4); + } @Override public void onLivingUpdate() { super.onLivingUpdate(); - - for (int i = 0; i < 1; ++i) - { - this.worldObj.spawnParticle("enchantmenttable", this.posX + (this.rand.nextDouble() - 0.5D) * this.width, this.posY + this.rand.nextDouble() * (this.height - 0.75D) + 0.5D, this.posZ + (this.rand.nextDouble() - 0.5D) * this.width, - 0, 0.5, 0); - } + + for (int i = 0; i < 1; ++i) { + this.world.spawnParticle(EnumParticleTypes.ENCHANTMENT_TABLE, this.posX + (this.rand.nextDouble() - 0.5D) * this.width, this.posY + this.rand.nextDouble() * (this.height - 0.75D) + 0.5D, this.posZ + (this.rand.nextDouble() - 0.5D) * this.width, + 0, 0.5, 0); + } } - - /** - * Called when the entity is attacked. - */ - @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) - { - if (par1DamageSource.isFireDamage()) - { - par2 *= 2; - } - - if (super.attackEntityFrom(par1DamageSource, par2)) - { - // we took damage - if (this.rand.nextInt(2) == 0) - { - func_145778_a(Items.paper, 1, 1.0F); - } - return true; - } - else - { - return false; - } - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - @Override - protected Item getDropItem() - { - return Items.paper; - } - - /** - * Drop 0-2 items of this living's type - */ - @Override - protected void dropFewItems(boolean par1, int par2) - { - int var3 = this.rand.nextInt(3 + par2); - int var4; - - for (var4 = 0; var4 < var3; ++var4) - { - this.dropItem(Items.paper, 1); - } - - if (this.rand.nextInt(5) - par2 <= 0) - { - this.dropItem(Items.writable_book, 1); - } - else - { - this.dropItem(Items.book, 1); - } - } - - @Override - protected void dropRareDrop(int par1) - { - this.dropItem(TFItems.magicMapFocus, 1); - } - - - /** - * Trigger achievement when killed - */ + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); + public boolean attackEntityFrom(DamageSource src, float damage) { + if (src.isFireDamage()) { + damage *= 2; } + + if (super.attackEntityFrom(src, damage)) { + if (!world.isRemote) { + LootContext ctx = new LootContext.Builder((WorldServer) world) + .withDamageSource(src) + .withLootedEntity(this) + .build(); + + for (ItemStack stack : world.getLootTableManager().getLootTableFromLocation(HURT_LOOT_TABLE).generateLootForPools(world.rand, ctx)) { + entityDropItem(stack, 1.0F); + } + } + return true; + } else { + return false; + } + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Nullable + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.TOME_IDLE; + } + + @Override + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return TFSounds.TOME_HURT; } + @Override + protected SoundEvent getDeathSound() { + return TFSounds.TOME_DEATH; + } + + @Override + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) { + EntityThrowable projectile = new EntityTFTomeBolt(this.world, this); + double tx = target.posX - this.posX; + double ty = target.posY + target.getEyeHeight() - 1.100000023841858D - projectile.posY; + double tz = target.posZ - this.posZ; + float heightOffset = MathHelper.sqrt(tx * tx + tz * tz) * 0.2F; + projectile.shoot(tx, ty + heightOffset, tz, 0.6F, 6.0F); + this.world.spawnEntity(projectile); + } + + @Override + public void setSwingingArms(boolean swingingArms) {} // todo 1.12 } diff --git a/src/main/java/twilightforest/entity/EntityTFFireBeetle.java b/src/main/java/twilightforest/entity/EntityTFFireBeetle.java index 97d9550ceb..ed50572f0b 100644 --- a/src/main/java/twilightforest/entity/EntityTFFireBeetle.java +++ b/src/main/java/twilightforest/entity/EntityTFFireBeetle.java @@ -4,270 +4,164 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFBreathAttack; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +public class EntityTFFireBeetle extends EntityMob implements IBreathAttacker { -public class EntityTFFireBeetle extends EntityMob implements IBreathAttacker -{ - - public static final int BREATH_DURATION = 10; - public static final int BREATH_DAMAGE = 2; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/fire_beetle"); + private static final DataParameter BREATHING = EntityDataManager.createKey(EntityTFFireBeetle.class, DataSerializers.BOOLEAN); + private static final int BREATH_DURATION = 10; + private static final int BREATH_DAMAGE = 2; + public EntityTFFireBeetle(World world) { + super(world); + this.isImmuneToFire = true; + setSize(1.1F, .75F); + } - public EntityTFFireBeetle(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "firebeetle.png"; - //moveSpeed = 0.23F; - setSize(1.1F, .75F); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(2, new EntityAITFBreathAttack(this, 1.0F, 5F, 30, 0.1F)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0F, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0F)); - //this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - //this.tasks.addTask(7, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - } - - public EntityTFFireBeetle(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(17, Byte.valueOf((byte)0)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAITFBreathAttack<>(this, 1.0F, 5F, 30, 0.1F)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0F, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); + //this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + //this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(25.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D); // attack damage - } - - - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return null; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return "mob.spider.say"; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return "mob.spider.death"; - } - - /** - * Plays step sound at given x, y, z for the entity - */ - @Override - protected void func_145780_a(int var1, int var2, int var3, Block var4) - { - this.worldObj.playSoundAtEntity(this, "mob.spider.step", 0.15F, 1.0F); - } - - - @Override - protected Item getDropItem() - { - return Items.gunpowder; - } - - /* (non-Javadoc) - * @see twilightforest.entity.IBreathAttacker#isBreathing() - */ - @Override - public boolean isBreathing() - { - return dataWatcher.getWatchableObjectByte(17) != 0; - } - - /* (non-Javadoc) - * @see twilightforest.entity.IBreathAttacker#setBreathing(boolean) - */ - @Override - public void setBreathing(boolean flag) - { - if (flag) - { - dataWatcher.updateObject(17, Byte.valueOf((byte)127)); - } - else - { - dataWatcher.updateObject(17, Byte.valueOf((byte)0)); - } - } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - super.onLivingUpdate(); - - // when breathing fire, spew particles - if (isBreathing()) - { - Vec3 look = this.getLookVec(); + protected void entityInit() { + super.entityInit(); + dataManager.register(BREATHING, false); + } - double dist = 0.9; - double px = this.posX + look.xCoord * dist; - double py = this.posY + 0.25 + look.yCoord * dist; - double pz = this.posZ + look.zCoord * dist; + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(25.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4.0D); + } - for (int i = 0; i < 2; i++) - { - double dx = look.xCoord; - double dy = look.yCoord; - double dz = look.zCoord; + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_SPIDER_HURT; + } - double spread = 5 + this.getRNG().nextDouble() * 2.5; - double velocity = 0.15 + this.getRNG().nextDouble() * 0.15; + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_SPIDER_DEATH; + } - // spread flame - dx += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dy += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dz += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dx *= velocity; - dy *= velocity; - dz *= velocity; + @Override + protected void playStepSound(BlockPos pos, Block block) { + playSound(SoundEvents.ENTITY_SPIDER_STEP, 0.15F, 1.0F); + } - worldObj.spawnParticle(getFlameParticle(), px, py, pz, dx, dy, dz); - } - - playBreathSound(); - } + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } - } + @Override + public boolean isBreathing() { + return dataManager.get(BREATHING); + } - public String getFlameParticle() { - return "flame"; + @Override + public void setBreathing(boolean flag) { + dataManager.set(BREATHING, flag); } - public void playBreathSound() { - worldObj.playSoundEffect(this.posX + 0.5, this.posY + 0.5, this.posZ + 0.5, "mob.ghast.fireball", rand.nextFloat() * 0.5F, rand.nextFloat() * 0.5F); + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + // when breathing fire, spew particles + if (isBreathing()) { + Vec3d look = this.getLookVec(); + + double dist = 0.9; + double px = this.posX + look.x * dist; + double py = this.posY + 0.25 + look.y * dist; + double pz = this.posZ + look.z * dist; + + for (int i = 0; i < 2; i++) { + double dx = look.x; + double dy = look.y; + double dz = look.z; + + double spread = 5 + this.getRNG().nextDouble() * 2.5; + double velocity = 0.15 + this.getRNG().nextDouble() * 0.15; + + // spread flame + dx += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dy += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dz += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dx *= velocity; + dy *= velocity; + dz *= velocity; + + world.spawnParticle(EnumParticleTypes.FLAME, px, py, pz, dx, dy, dz); + } + + playSound(SoundEvents.ENTITY_GHAST_SHOOT, rand.nextFloat() * 0.5F, rand.nextFloat() * 0.5F); + } } - + @Override @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float par1) { - if (isBreathing()) - { + public int getBrightnessForRender() { + if (isBreathing()) { return 15728880; - } - else - { - return super.getBrightnessForRender(par1); + } else { + return super.getBrightnessForRender(); } } - /** - * Trigger achievement when killed - */ - @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } - } - - /** - * Rather than speed, this seems to control how far up or down the heads can tilt? - */ @Override - public int getVerticalFaceSpeed() - { - return 500; - } - - @Override - @SideOnly(Side.CLIENT) - public float getShadowSize() - { - return 1.1F; + public int getVerticalFaceSpeed() { + return 500; } - + @Override public float getEyeHeight() { - return 0.25F; + return this.height * 0.6F; } - /** - * Get this Entity's EnumCreatureAttribute - */ - @Override - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.ARTHROPOD; - } + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } - /* (non-Javadoc) - * @see twilightforest.entity.IBreathAttacker#doBreathAttack(net.minecraft.entity.Entity) - */ @Override - public void doBreathAttack(Entity target) - { - if (!target.isImmuneToFire() && target.attackEntityFrom(DamageSource.inFire, BREATH_DAMAGE)) - { - target.setFire(BREATH_DURATION); - } + public void doBreathAttack(Entity target) { + if (!target.isImmuneToFire() && target.attackEntityFrom(DamageSource.IN_FIRE, BREATH_DAMAGE)) { + target.setFire(BREATH_DURATION); + } } } diff --git a/src/main/java/twilightforest/entity/EntityTFGiantMiner.java b/src/main/java/twilightforest/entity/EntityTFGiantMiner.java index 3830bb0e6b..cc73407e12 100644 --- a/src/main/java/twilightforest/entity/EntityTFGiantMiner.java +++ b/src/main/java/twilightforest/entity/EntityTFGiantMiner.java @@ -1,83 +1,78 @@ package twilightforest.entity; -import twilightforest.entity.ai.EntityAITFGiantAttackOnCollide; -import twilightforest.item.TFItems; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; public class EntityTFGiantMiner extends EntityMob { - public EntityTFGiantMiner(World par1World) { - super(par1World); + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/giant_miner"); + + public EntityTFGiantMiner(World world) { + super(world); this.setSize(this.width * 4.0F, this.height * 4.0F); + for (EntityEquipmentSlot slot : EntityEquipmentSlot.values()) { + setDropChance(slot, 0); + } + } + @Override + protected void initEntityAI() { this.tasks.addTask(1, new EntityAISwimming(this)); - - this.tasks.addTask(4, new EntityAITFGiantAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.0D, false) { + @Override + protected double getAttackReachSqr(EntityLivingBase attackTarget) { + return this.attacker.width * this.attacker.height; + } + }); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(6, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - this.setCurrentItemOrArmor(0, new ItemStack(Items.stone_pickaxe)); - - for (int i = 0; i < this.equipmentDropChances.length; ++i) - { - this.equipmentDropChances[i] = 0F; - } + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } + @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(80.0D); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(10.0D); - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(80.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(2.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(40.0D); } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() { - return true; - } + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) { + IEntityLivingData data = super.onInitialSpawn(difficulty, livingdata); + setEquipmentBasedOnDifficulty(difficulty); + setEnchantmentBasedOnDifficulty(difficulty); + return data; + } - - protected Item getDropItem() - { - return TFItems.giantPick; - } - - /** - * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param - * par2 - Level of Looting used to kill this mob. - */ - protected void dropFewItems(boolean par1, int par2) - { - Item item = this.getDropItem(); - // just drop 1 item every time - if (item != null && par1) { - this.dropItem(item, 1); - } - } - - public void makeNonDespawning() { - this.func_110163_bv(); - } + @Override + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.STONE_PICKAXE)); + } + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFGoblinChain.java b/src/main/java/twilightforest/entity/EntityTFGoblinChain.java index c752cfefc6..7fe558528b 100644 --- a/src/main/java/twilightforest/entity/EntityTFGoblinChain.java +++ b/src/main/java/twilightforest/entity/EntityTFGoblinChain.java @@ -1,86 +1,35 @@ package twilightforest.entity; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.DamageSource; -import net.minecraft.world.World; +import net.minecraft.entity.IEntityMultiPart; +import net.minecraft.entity.MultiPartEntityPart; -public class EntityTFGoblinChain extends Entity { - - Entity goblin; - - public EntityTFGoblinChain(World par1World) { - super(par1World); - setSize(0.1F, 0.1F); +public class EntityTFGoblinChain extends MultiPartEntityPart { + public EntityTFGoblinChain(IEntityMultiPart goblin) { + super(goblin, "chain", 0.1F, 0.1F); } - public EntityTFGoblinChain(Entity goblin) { - this(goblin.worldObj); - this.goblin = goblin; + @Override + public void onUpdate() { + super.onUpdate(); + + this.ticksExisted++; + + lastTickPosX = posX; + lastTickPosY = posY; + lastTickPosZ = posZ; + + for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { + } + for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { + } + for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { + } + for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { + } } - /** - * Don't take damage from attacks - */ @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) { + public boolean canBeCollidedWith() { return false; } - - - /** - * Keep position updated - */ - @Override - public void onUpdate() { - super.onUpdate(); - - this.ticksExisted++; - - - lastTickPosX = posX; - lastTickPosY = posY; - lastTickPosZ = posZ; - - - //System.out.println("Updating " + this + " with angles " + rotationYawHead + ", " + rotationPitch); - - for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } - for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } - for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } - for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } - - } - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - public boolean canBeCollidedWith() - { - return false; - } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - public boolean isEntityEqual(Entity entity) - { - return this == entity || this.goblin == entity; - } - - @Override - protected void entityInit() { } - - @Override - protected void readEntityFromNBT(NBTTagCompound nbttagcompound) { } - - @Override - protected void writeEntityToNBT(NBTTagCompound nbttagcompound) { } - } diff --git a/src/main/java/twilightforest/entity/EntityTFGoblinKnightLower.java b/src/main/java/twilightforest/entity/EntityTFGoblinKnightLower.java index 7909910866..34216503c4 100644 --- a/src/main/java/twilightforest/entity/EntityTFGoblinKnightLower.java +++ b/src/main/java/twilightforest/entity/EntityTFGoblinKnightLower.java @@ -4,287 +4,182 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; import twilightforest.entity.ai.EntityAITFRiderSpearAttack; -import twilightforest.item.TFItems; public class EntityTFGoblinKnightLower extends EntityMob { - - private static final int DATA_EQUIP = 17; - - public EntityTFGoblinKnightLower(World par1World) { - super(par1World); - //texture = TwilightForestMod.MODEL_DIR + "doublegoblin.png"; - //moveSpeed = 0.28F; - setSize(0.7F, 1.1F); - - this.tasks.addTask(0, new EntityAITFRiderSpearAttack(this)); + + private static final DataParameter ARMOR = EntityDataManager.createKey(EntityTFGoblinKnightLower.class, DataSerializers.BOOLEAN); + private static final AttributeModifier ARMOR_MODIFIER = new AttributeModifier("Armor boost", 17, 0).setSaved(false); + + public EntityTFGoblinKnightLower(World world) { + super(world); + setSize(0.7F, 1.1F); + this.setHasArmor(true); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAITFRiderSpearAttack(this)); this.tasks.addTask(1, new EntityAISwimming(this)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(7, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, false)); + } - this.setHasArmor(true); - } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4.0D); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(ARMOR, false); + } + + public boolean hasArmor() { + return dataManager.get(ARMOR); + } + private void setHasArmor(boolean flag) { + dataManager.set(ARMOR, flag); + + if (!world.isRemote) { + if (flag) { + if (!getEntityAttribute(SharedMonsterAttributes.ARMOR).hasModifier(ARMOR_MODIFIER)) { + getEntityAttribute(SharedMonsterAttributes.ARMOR).applyModifier(ARMOR_MODIFIER); + } + } else { + getEntityAttribute(SharedMonsterAttributes.ARMOR).removeModifier(ARMOR_MODIFIER); + } + } + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D); // attack damage - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("hasArmor", this.hasArmor()); + } + @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(DATA_EQUIP, Byte.valueOf((byte)0)); - } - - public boolean hasArmor() - { - return (dataWatcher.getWatchableObjectByte(DATA_EQUIP) & 1) > 0; - } - - public void setHasArmor(boolean flag) - { - byte otherFlags = dataWatcher.getWatchableObjectByte(DATA_EQUIP); - otherFlags &= 126; - - if (flag) - { - dataWatcher.updateObject(DATA_EQUIP, Byte.valueOf((byte) (otherFlags | 1))); - } - else - { - dataWatcher.updateObject(DATA_EQUIP, Byte.valueOf((byte)otherFlags)); - } - } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setHasArmor(compound.getBoolean("hasArmor")); + } + @Override - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setBoolean("hasArmor", this.hasArmor()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingData) { + livingData = super.onInitialSpawn(difficulty, livingData); + + EntityTFGoblinKnightUpper upper = new EntityTFGoblinKnightUpper(this.world); + upper.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + upper.onInitialSpawn(difficulty, null); + this.world.spawnEntity(upper); + upper.startRiding(this); + + return livingData; + } + @Override - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setHasArmor(par1NBTTagCompound.getBoolean("hasArmor")); - } - - - /** - * Initialize this creature. - */ - public void initCreature() - { - // we start with the upper guy riding us - EntityTFGoblinKnightUpper upper = new EntityTFGoblinKnightUpper(this.worldObj); - upper.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); - upper.onSpawnWithEgg((IEntityLivingData)null); - this.worldObj.spawnEntityInWorld(upper); - upper.mountEntity(this); - } - - /** - * Init creature with mount - */ - public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) - { - Object par1EntityLivingData1 = super.onSpawnWithEgg(par1EntityLivingData); - - // we start with the upper guy riding us - EntityTFGoblinKnightUpper upper = new EntityTFGoblinKnightUpper(this.worldObj); - upper.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); - upper.onSpawnWithEgg((IEntityLivingData)null); - this.worldObj.spawnEntityInWorld(upper); - upper.mountEntity(this); - - return (IEntityLivingData)par1EntityLivingData1; - } - - - /** - * Returns the Y offset from the entity's position for any entity riding this one. - */ - public double getMountedYOffset() - { - return 1.0D; - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - if (this.isEntityAlive()) - { - // synch target with lower goblin - if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityLiving && this.getAttackTarget() == null) - { - this.setAttackTarget(((EntityLiving) this.riddenByEntity).getAttackTarget()); - } - } - - super.onUpdate(); - } - - /** - * Do not attack if we have a rider - */ + public double getMountedYOffset() { + return 1.0D; + } + @Override - public boolean attackEntityAsMob(Entity par1Entity) { - - if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityLiving) - { - return ((EntityLiving)this.riddenByEntity).attackEntityAsMob(par1Entity); + public void updateAITasks() { + super.updateAITasks(); + + if (isBeingRidden() && getPassengers().get(0) instanceof EntityLiving && this.getAttackTarget() == null) { + this.setAttackTarget(((EntityLiving) this.getPassengers().get(0)).getAttackTarget()); } - else - { - return super.attackEntityAsMob(par1Entity); + } + + @Override + public boolean attackEntityAsMob(Entity entity) { + + if (isBeingRidden() && getPassengers().get(0) instanceof EntityLiving) { + return ((EntityLiving) this.getPassengers().get(0)).attackEntityAsMob(entity); + } else { + return super.attackEntityAsMob(entity); } } - - /** - * Called when the entity is attacked. - */ + @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float damageAmount) { + public boolean attackEntityFrom(DamageSource source, float amount) { // check the angle of attack, if applicable - Entity attacker = null; - if (par1DamageSource.getSourceOfDamage() != null) - { - attacker = par1DamageSource.getSourceOfDamage(); - } - - if (par1DamageSource.getEntity() != null) - { - attacker = par1DamageSource.getEntity(); - } - - if (attacker != null) - { - // determine angle - - double dx = this.posX - attacker.posX; - double dz = this.posZ - attacker.posZ; - float angle = (float)((Math.atan2(dz, dx) * 180D) / Math.PI) - 90F; - - float difference = MathHelper.abs((this.renderYawOffset - angle) % 360); - - //System.out.println("Difference in angle of approach is " + difference); - - // shield? - EntityTFGoblinKnightUpper upper = null; - - if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityTFGoblinKnightUpper) - { - upper = (EntityTFGoblinKnightUpper) this.riddenByEntity; - } - - if (upper != null && upper.hasShield() && difference > 150 && difference < 230) - { - if (upper.takeHitOnShield(par1DamageSource, damageAmount)) - { - return false; - } - } - - // break armor? - if (this.hasArmor() && (difference > 300 || difference < 60)) - { - breakArmor(); - } - } - - - boolean attackSuccess = super.attackEntityFrom(par1DamageSource, damageAmount); - - // I think we're done - return attackSuccess; + Entity attacker = null; + if (source.getTrueSource() != null) { + attacker = source.getTrueSource(); + } + + if (source.getTrueSource() != null) { + attacker = source.getTrueSource(); + } + + if (attacker != null) { + // determine angle + + double dx = this.posX - attacker.posX; + double dz = this.posZ - attacker.posZ; + float angle = (float) ((Math.atan2(dz, dx) * 180D) / Math.PI) - 90F; + + float difference = MathHelper.abs((this.renderYawOffset - angle) % 360); + + // shield? + EntityTFGoblinKnightUpper upper = null; + + if (isBeingRidden() && getPassengers().get(0) instanceof EntityTFGoblinKnightUpper) { + upper = (EntityTFGoblinKnightUpper) this.getPassengers().get(0); + } + + if (upper != null && upper.hasShield() && difference > 150 && difference < 230) { + if (upper.takeHitOnShield(source, amount)) { + return false; + } + } + + // break armor? + if (this.hasArmor() && (difference > 300 || difference < 60)) { + breakArmor(); + } + } + + return super.attackEntityFrom(source, amount); } - - /** - * Break our armor - */ - public void breakArmor() { - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - + + private void breakArmor() { + this.renderBrokenItemStack(new ItemStack(Items.IRON_CHESTPLATE)); + this.renderBrokenItemStack(new ItemStack(Items.IRON_CHESTPLATE)); + this.renderBrokenItemStack(new ItemStack(Items.IRON_CHESTPLATE)); + this.setHasArmor(false); } - - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - public int getTotalArmorValue() - { - int armor = super.getTotalArmorValue(); - - if (this.hasArmor()) - { - armor += 17; - } - - if (armor > 20) - { - armor = 20; - } - - return armor; - } - - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItemId() - { - return TFItems.armorShard; - } - + } diff --git a/src/main/java/twilightforest/entity/EntityTFGoblinKnightUpper.java b/src/main/java/twilightforest/entity/EntityTFGoblinKnightUpper.java index 29261bb0eb..3acf46cd9c 100644 --- a/src/main/java/twilightforest/entity/EntityTFGoblinKnightUpper.java +++ b/src/main/java/twilightforest/entity/EntityTFGoblinKnightUpper.java @@ -1,493 +1,321 @@ package twilightforest.entity; -import java.util.List; - import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFHeavySpearAttack; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; + +import java.util.List; public class EntityTFGoblinKnightUpper extends EntityMob { - - private static final int SHIELD_DAMAGE_THRESHOLD = 10; - private static final int DATA_EQUIP = 17; - - public int shieldHits; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/goblin_knight"); + private static final int SHIELD_DAMAGE_THRESHOLD = 10; + private static final DataParameter DATA_EQUIP = EntityDataManager.createKey(EntityTFGoblinKnightUpper.class, DataSerializers.BYTE); + private static final AttributeModifier ARMOR_MODIFIER = new AttributeModifier("Armor boost", 20, 0).setSaved(false); + private static final AttributeModifier DAMAGE_MODIFIER = new AttributeModifier("Heavy spear attack boost", 12, 0).setSaved(false); + public static final int HEAVY_SPEAR_TIMER_START = 60; + private int shieldHits = 0; public int heavySpearTimer; - public EntityTFGoblinKnightUpper(World par1World) { - super(par1World); - //texture = TwilightForestMod.MODEL_DIR + "doublegoblin.png"; - //moveSpeed = 0.28F; - setSize(1.1F, 1.3F); + public EntityTFGoblinKnightUpper(World world) { + super(world); + setSize(1.1F, 1.3F); - this.tasks.addTask(0, new EntityAITFHeavySpearAttack(this)); + this.setHasArmor(true); + this.setHasShield(true); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAITFHeavySpearAttack(this)); this.tasks.addTask(1, new EntityAISwimming(this)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(7, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, false)); - - this.setHasArmor(true); - this.setHasShield(true); - - //this.setCurrentItemOrArmor(0, new ItemStack(Items.swordSteel)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, false)); + } - - this.shieldHits = 0; + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(8.0D); } - - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - - /** - * Set monster attributes - */ + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D); // attack damage - } - + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_EQUIP, (byte) 0); + } + + public boolean hasArmor() { + return (dataManager.get(DATA_EQUIP) & 1) > 0; + } + + private void setHasArmor(boolean flag) { + byte otherFlags = dataManager.get(DATA_EQUIP); + dataManager.set(DATA_EQUIP, flag ? (byte) (otherFlags | 1) : (byte) (otherFlags & ~1)); + + if (!world.isRemote) { + if (flag) { + if (!getEntityAttribute(SharedMonsterAttributes.ARMOR).hasModifier(ARMOR_MODIFIER)) { + getEntityAttribute(SharedMonsterAttributes.ARMOR).applyModifier(ARMOR_MODIFIER); + } + } else { + getEntityAttribute(SharedMonsterAttributes.ARMOR).removeModifier(ARMOR_MODIFIER); + } + } + } + + public boolean hasShield() { + return (dataManager.get(DATA_EQUIP) & 2) > 0; + } + + public void setHasShield(boolean flag) { + byte otherFlags = dataManager.get(DATA_EQUIP); + dataManager.set(DATA_EQUIP, flag ? (byte) (otherFlags | 2) : (byte) (otherFlags & ~2)); + } + @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(DATA_EQUIP, Byte.valueOf((byte)0)); - } - - public boolean hasArmor() - { - return (dataWatcher.getWatchableObjectByte(DATA_EQUIP) & 1) > 0; - } - - public void setHasArmor(boolean flag) - { - byte otherFlags = dataWatcher.getWatchableObjectByte(DATA_EQUIP); - otherFlags &= 126; - - if (flag) - { - dataWatcher.updateObject(DATA_EQUIP, Byte.valueOf((byte) (otherFlags | 1))); - } - else - { - dataWatcher.updateObject(DATA_EQUIP, Byte.valueOf((byte)otherFlags)); - } - } - - public boolean hasShield() - { - return (dataWatcher.getWatchableObjectByte(DATA_EQUIP) & 2) > 0; - } - - public void setHasShield(boolean flag) - { - byte otherFlags = dataWatcher.getWatchableObjectByte(DATA_EQUIP); - otherFlags &= 125; - - if (flag) - { - dataWatcher.updateObject(DATA_EQUIP, Byte.valueOf((byte) (otherFlags | 2))); - } - else - { - dataWatcher.updateObject(DATA_EQUIP, Byte.valueOf((byte)otherFlags)); - } - } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("hasArmor", this.hasArmor()); + compound.setBoolean("hasShield", this.hasShield()); + } + @Override - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setBoolean("hasArmor", this.hasArmor()); - par1NBTTagCompound.setBoolean("hasShield", this.hasShield()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setHasArmor(compound.getBoolean("hasArmor")); + this.setHasShield(compound.getBoolean("hasShield")); + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + // Must be decremented on client as well for rendering + if ((world.isRemote || !isAIDisabled()) && heavySpearTimer > 0) { + --heavySpearTimer; + } + } + @Override - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setHasArmor(par1NBTTagCompound.getBoolean("hasArmor")); - this.setHasShield(par1NBTTagCompound.getBoolean("hasShield")); - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - if (this.isEntityAlive()) - { - // synch target with lower goblin - if (this.ridingEntity != null && this.ridingEntity instanceof EntityLiving && this.getAttackTarget() == null) - { - this.setAttackTarget(((EntityLiving) this.ridingEntity).getAttackTarget()); - } - - // keep doing attack timer - if (this.heavySpearTimer > 0) - { - --this.heavySpearTimer; - - if (this.heavySpearTimer == 25) - { - //System.out.println("Landing spear attack in world " + this.worldObj); - - this.landHeavySpearAttack(); - } - } - - // break shield if we're on the ground - if (this.ridingEntity == null && this.hasShield()) - { - this.breakShield(); - } - } - - super.onUpdate(); - } - - @SuppressWarnings("unchecked") - private void landHeavySpearAttack() { - - - // find vector in front of us - Vec3 vector = this.getLookVec(); - + public void updateAITasks() { + super.updateAITasks(); + + if (this.isEntityAlive()) { + // synch target with lower goblin + if (getRidingEntity() instanceof EntityLiving && this.getAttackTarget() == null) { + this.setAttackTarget(((EntityLiving) this.getRidingEntity()).getAttackTarget()); + } + + if (!isRiding() && this.hasShield()) { + this.breakShield(); + } + + if (heavySpearTimer > 0) { + if (!getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).hasModifier(DAMAGE_MODIFIER)) { + getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).applyModifier(DAMAGE_MODIFIER); + } + } else { + getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).removeModifier(DAMAGE_MODIFIER.getID()); + } + } + } + + public void landHeavySpearAttack() { + // find vector in front of us + Vec3d vector = this.getLookVec(); + double dist = 1.25; - double px = this.posX + vector.xCoord * dist; - double py = this.boundingBox.minY - 0.75; - double pz = this.posZ + vector.zCoord * dist; - - - for (int i = 0; i < 50; i++) - { - //worldObj.spawnParticle("crit", px + (rand.nextFloat() - rand.nextFloat()) * 0.5F, py + rand.nextFloat(), pz + (rand.nextFloat() - rand.nextFloat()) * 0.5F, 0, 0.5, 0); - worldObj.spawnParticle("largesmoke", px, py, pz, (rand.nextFloat() - rand.nextFloat()) * 0.25F, 0, (rand.nextFloat() - rand.nextFloat()) * 0.25F); + double px = this.posX + vector.x * dist; + double py = this.getEntityBoundingBox().minY - 0.75; + double pz = this.posZ + vector.z * dist; + + + for (int i = 0; i < 50; i++) { + world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, px, py, pz, (rand.nextFloat() - rand.nextFloat()) * 0.25F, 0, (rand.nextFloat() - rand.nextFloat()) * 0.25F); } - + // damage things in front that aren't us or our "mount" double radius = 1.5D; - AxisAlignedBB spearBB = AxisAlignedBB.getBoundingBox(px - radius, py - radius, pz - radius, px + radius, py + radius, pz + radius); + AxisAlignedBB spearBB = new AxisAlignedBB(px - radius, py - radius, pz - radius, px + radius, py + radius, pz + radius); - List inBox = worldObj.getEntitiesWithinAABB(Entity.class, spearBB); - - for (Entity entity : inBox) - { - if (this.ridingEntity != null && entity != this.ridingEntity && entity != this) - { - super.attackEntityAsMob(entity); - } + List inBox = world.getEntitiesInAABBexcluding(this, spearBB, e -> e != this.getRidingEntity()); + + for (Entity entity : inBox) { + super.attackEntityAsMob(entity); } + if (!inBox.isEmpty()) { + playSound(SoundEvents.ENTITY_PLAYER_ATTACK_CRIT, getSoundVolume(), getSoundPitch()); + } } - - /** - * Returns the amount of damage a mob should deal. - */ - public int getAttackStrength(Entity par1Entity) - { - if (this.heavySpearTimer > 0) - { - return 20; - } - else - { - return 8; - } - } - - - - /** - * Handles updating while being ridden by an entity - */ - public void updateRidden() - { -// if (this.ridingEntity != null) -// { -// this.renderYawOffset = ((EntityLiving)this.ridingEntity).renderYawOffset; -// } + + @Override + public void updateRidden() { super.updateRidden(); - if (this.ridingEntity != null) - { - this.renderYawOffset = ((EntityLiving)this.ridingEntity).renderYawOffset; + if (getRidingEntity() instanceof EntityLiving) { + this.renderYawOffset = ((EntityLiving) this.getRidingEntity()).renderYawOffset; } } - - - @SideOnly(Side.CLIENT) - public void handleHealthUpdate(byte par1) - { - if (par1 == 4) - { - this.heavySpearTimer = 60; - //this.playSound("mob.irongolem.throw", 1.0F, 1.0F); - } - else - { - super.handleHealthUpdate(par1); - } - } - - - /** - * Swing arm when attacking - */ + + @SideOnly(Side.CLIENT) @Override - public boolean attackEntityAsMob(Entity par1Entity) { - - if (this.heavySpearTimer > 0) - { - return false; + public void handleStatusUpdate(byte id) { + if (id == 4) { + this.heavySpearTimer = HEAVY_SPEAR_TIMER_START; + } else if (id == 5) { + ItemStack broken = new ItemStack(Items.IRON_CHESTPLATE); + this.renderBrokenItemStack(broken); + this.renderBrokenItemStack(broken); + this.renderBrokenItemStack(broken); + } else { + super.handleStatusUpdate(id); } - - if (rand.nextInt(2) == 0) - { - // do mega spear attack - this.startHeavySpearAttack(); - - return false; - } - - // normal attack - this.swingItem(); - - //System.out.println("Spear!"); - - return super.attackEntityAsMob(par1Entity); } + @Override + public boolean attackEntityAsMob(Entity entity) { - private void startHeavySpearAttack() { - //System.out.println("Heavy Spear!"); + if (this.heavySpearTimer > 0) { + return false; + } - - this.heavySpearTimer = 60; - this.worldObj.setEntityState(this, (byte)4); - } + if (rand.nextInt(2) == 0) { + this.heavySpearTimer = HEAVY_SPEAR_TIMER_START; + this.world.setEntityState(this, (byte) 4); + return false; + } + this.swingArm(EnumHand.MAIN_HAND); + return super.attackEntityAsMob(entity); + } - /** - * Called when the entity is attacked. - */ @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float damageAmount) { + public boolean attackEntityFrom(DamageSource damageSource, float amount) { // don't take suffocation damage while riding - if (par1DamageSource == DamageSource.inWall && this.ridingEntity != null) - { + if (damageSource == DamageSource.IN_WALL && !this.getPassengers().isEmpty()) { return false; } - - // check the angle of attack, if applicable - Entity attacker = null; - if (par1DamageSource.getSourceOfDamage() != null) - { - attacker = par1DamageSource.getSourceOfDamage(); - } - - if (par1DamageSource.getEntity() != null) - { - attacker = par1DamageSource.getEntity(); - } - - if (attacker != null) - { - // determine angle - - double dx = this.posX - attacker.posX; - double dz = this.posZ - attacker.posZ; - float angle = (float)((Math.atan2(dz, dx) * 180D) / Math.PI) - 90F; - - float difference = MathHelper.abs((this.renderYawOffset - angle) % 360); - - //System.out.println("Difference in angle of approach is " + difference); - - // if we have a shield, the shield will take the damage instead - if (this.hasShield() && difference > 150 && difference < 230) - { - if (takeHitOnShield(par1DamageSource, damageAmount)) - { - return false; - } - } - else - { - // unblocked hits may eventually break shield - if (this.hasShield() && rand.nextBoolean()) - { - damageShield(); - } - } - - // break armor? - if (this.hasArmor() && (difference > 300 || difference < 60)) - { - breakArmor(); - } - } - - boolean attackSuccess = super.attackEntityFrom(par1DamageSource, damageAmount); - - if (attackSuccess && this.ridingEntity != null && this.ridingEntity instanceof EntityLiving && attacker != null) - { - ((EntityLiving)this.ridingEntity).knockBack(attacker, damageAmount, 0.1, 0.1); - } - - // - return attackSuccess; - } + Entity attacker = damageSource.getTrueSource(); + + if (attacker != null) { + double dx = this.posX - attacker.posX; + double dz = this.posZ - attacker.posZ; + float angle = (float) ((Math.atan2(dz, dx) * 180D) / Math.PI) - 90F; + + float difference = MathHelper.abs((this.renderYawOffset - angle) % 360); + + if (this.hasShield() && difference > 150 && difference < 230) { + if (takeHitOnShield(damageSource, amount)) { + return false; + } + } else { + if (this.hasShield() && rand.nextBoolean()) { + damageShield(); + } + } + + if (this.hasArmor() && (difference > 300 || difference < 60)) { + breakArmor(); + } + } + + return super.attackEntityFrom(damageSource, amount); + } - /** - * Break our armor - */ - public void breakArmor() { - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - + private void breakArmor() { + world.setEntityState(this, (byte) 5); this.setHasArmor(false); } - - /** - * Break our shield - */ - public void breakShield() { - - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - this.renderBrokenItemStack(new ItemStack(Items.iron_chestplate)); - + + private void breakShield() { + world.setEntityState(this, (byte) 5); this.setHasShield(false); } - public boolean takeHitOnShield(DamageSource par1DamageSource, float damageAmount) { - //System.out.println("Hit blocked by shield"); - - if (damageAmount > SHIELD_DAMAGE_THRESHOLD && !this.worldObj.isRemote) - { + public boolean takeHitOnShield(DamageSource source, float amount) { + if (amount > SHIELD_DAMAGE_THRESHOLD && !this.world.isRemote) { damageShield(); + } else { + playSound(SoundEvents.ENTITY_ITEM_BREAK, 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); } - else - { - this.worldObj.playSoundAtEntity(this, "random.break", 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); - } - + // knock back slightly - EntityLiving toKnockback = (this.ridingEntity != null && this.ridingEntity instanceof EntityLiving) ? (EntityLiving)this.ridingEntity : this; - - if (par1DamageSource.getEntity() != null) - { - double d0 = par1DamageSource.getEntity().posX - this.posX; - double d1; - - for (d1 = par1DamageSource.getEntity().posZ - this.posZ; d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) - { - d0 = (Math.random() - Math.random()) * 0.01D; - } - - toKnockback.knockBack(par1DamageSource.getEntity(), 0, d0 / 4D, d1 / 4D); - - // also set revenge target - if (par1DamageSource.getEntity() instanceof EntityLiving) - { - this.setRevengeTarget((EntityLiving)par1DamageSource.getEntity()); - } - } - - + EntityLiving toKnockback = (getRidingEntity() instanceof EntityLiving) ? (EntityLiving) getRidingEntity() : this; + + if (source.getTrueSource() != null) { + double d0 = source.getTrueSource().posX - this.posX; + double d1; + + for (d1 = source.getTrueSource().posZ - this.posZ; d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) { + d0 = (Math.random() - Math.random()) * 0.01D; + } + + toKnockback.knockBack(source.getTrueSource(), 0, d0 / 4D, d1 / 4D); + + // also set revenge target + if (source.getTrueSource() instanceof EntityLiving) { + this.setRevengeTarget((EntityLiving) source.getTrueSource()); + } + } + + return true; } private void damageShield() { - // door break noise - //this.worldObj.playAuxSFX(1010, MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 0); - this.worldObj.playSoundAtEntity(this, "mob.zombie.metal", 0.25F, 0.25F); - + playSound(SoundEvents.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 0.25F, 0.25F); + this.shieldHits++; - - if (!worldObj.isRemote && this.shieldHits >= 3) - { + + if (!world.isRemote && this.shieldHits >= 3) { this.breakShield(); } } - - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - public int getTotalArmorValue() - { - int armor = super.getTotalArmorValue(); - - if (this.hasArmor()) - { - armor += 20; - } - - if (armor > 20) - { - armor = 20; - } - - return armor; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return TFItems.armorShard; - } - + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFHarbingerCube.java b/src/main/java/twilightforest/entity/EntityTFHarbingerCube.java index bc8372ff2d..d371b225ea 100644 --- a/src/main/java/twilightforest/entity/EntityTFHarbingerCube.java +++ b/src/main/java/twilightforest/entity/EntityTFHarbingerCube.java @@ -1,49 +1,46 @@ package twilightforest.entity; -import twilightforest.entity.ai.EntityAITFGiantAttackOnCollide; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; -import net.minecraft.entity.monster.EntityZombie; -import net.minecraft.entity.passive.EntityPig; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; - +import twilightforest.TwilightForestMod; public class EntityTFHarbingerCube extends EntityMob { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/harbinger_cube"); + public EntityTFHarbingerCube(World world) { super(world); - - this.setSize(1.9F, 2.4F); - - this.tasks.addTask(1, new EntityAISwimming(this)); + this.setSize(1.9F, 2.4F); + } - this.tasks.addTask(1, new EntityAIWander(this, 1.0D)); + @Override + protected void initEntityAI() { + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(2, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(2, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } - + + @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(40.0D); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23D); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23D); } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() { - return true; - } + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFHedgeSpider.java b/src/main/java/twilightforest/entity/EntityTFHedgeSpider.java index cf657b843a..a367326dea 100644 --- a/src/main/java/twilightforest/entity/EntityTFHedgeSpider.java +++ b/src/main/java/twilightforest/entity/EntityTFHedgeSpider.java @@ -1,80 +1,61 @@ package twilightforest.entity; -import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.monster.EntitySpider; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; - +import twilightforest.TwilightForestMod; /** * The hedge spider is just like a normal spider, but it can spawn in the daytime. - * - * @author Ben * + * @author Ben */ public class EntityTFHedgeSpider extends EntitySpider { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/hedge_spider"); public EntityTFHedgeSpider(World world) { super(world); - //texture = TwilightForestMod.MODEL_DIR + "hedgespider.png"; } - public EntityTFHedgeSpider(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - /** - * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking - * (Animals, Spiders at day, peaceful PigZombies). - */ - @Override - protected Entity findPlayerToAttack() - { - // kill at all times! - double var2 = 16.0D; - return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2); - } - - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ @Override - protected boolean isValidLightLevel() - { - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; + protected void initEntityAI() { + super.initEntityAI(); + + // Remove default spider melee task + this.tasks.taskEntries.removeIf(t -> t.action instanceof EntityAIAttackMelee); + + // Replace with one that doesn't become docile in light + // [VanillaCopy] based on EntitySpider.AISpiderAttack + this.tasks.addTask(4, new EntityAIAttackMelee(this, 1, true) { + @Override + protected double getAttackReachSqr(EntityLivingBase attackTarget) { + return 4.0F + attackTarget.width; + } + }); + + // Remove default spider target player task + this.targetTasks.taskEntries.removeIf(t -> t.priority == 2 && t.action instanceof EntityAINearestAttackableTarget); + // Replace with one that doesn't care about light + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected boolean isValidLightLevel() { + int chunkX = MathHelper.floor(posX) >> 4; + int chunkZ = MathHelper.floor(posZ) >> 4; // We're allowed to spawn in bright light only in hedge mazes. - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hedgeMaze) - { - return true; - } - else - { - return super.isValidLightLevel(); - } - } - - /** - * Trigger achievement when killed - */ + return TFFeature.getNearestFeature(chunkX, chunkZ, world) == TFFeature.HEDGE_MAZE + || super.isValidLightLevel(); + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - // are in a hedge maze? - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hedgeMaze) { - // award hedge maze cheevo - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHedge); - } - } + protected ResourceLocation getLootTable() { + return LOOT_TABLE; } } diff --git a/src/main/java/twilightforest/entity/EntityTFHelmetCrab.java b/src/main/java/twilightforest/entity/EntityTFHelmetCrab.java index d16e09440b..87a3e7d843 100644 --- a/src/main/java/twilightforest/entity/EntityTFHelmetCrab.java +++ b/src/main/java/twilightforest/entity/EntityTFHelmetCrab.java @@ -3,7 +3,7 @@ import net.minecraft.block.Block; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILeapAtTarget; import net.minecraft.entity.ai.EntityAILookIdle; @@ -13,164 +13,76 @@ import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.item.TFItems; - +import twilightforest.TwilightForestMod; public class EntityTFHelmetCrab extends EntityMob { - - public EntityTFHelmetCrab(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "helmetcrab.png"; - //moveSpeed = 0.28F; - setSize(0.8F, 1.1F); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(2, new EntityAILeapAtTarget(this, 0.28F)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(7, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/helmet_crab"); - } - - public EntityTFHelmetCrab(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - @Override - protected void entityInit() - { - super.entityInit(); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } + public EntityTFHelmetCrab(World world) { + super(world); + setSize(0.8F, 1.1F); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(13.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D); // attack damage - } - - - - @Override - protected String getLivingSound() - { - return null; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return "mob.spider.say"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return "mob.spider.death"; - } - - /** - * Plays step sound at given x, y, z for the entity - */ - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - this.playSound("mob.spider.step", 0.15F, 1.0F); - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return TFItems.armorShard; - } - - @Override - protected void dropFewItems(boolean flag, int i) - { - super.dropFewItems(flag, i); - - if (rand.nextInt(2) == 0) - { - this.dropItem(Items.fish, 1 + i); - } - } - + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAILeapAtTarget(this, 0.28F)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } - /** - * Trigger achievement when killed - */ - @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } - } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(13.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0D); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(6.0D); + } + @Override + public float getEyeHeight() { + return this.height * 0.4F; + } - /** - * Will return how many at most can spawn in a chunk at once. - */ - @Override - public int getMaxSpawnedInChunk() - { - return 8; - } + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_SPIDER_HURT; + } + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_SPIDER_DEATH; + } - /** - * Get this Entity's EnumCreatureAttribute - */ - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.ARTHROPOD; - } - - - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - public int getTotalArmorValue() - { - int i = super.getTotalArmorValue() + 6; + @Override + protected void playStepSound(BlockPos pos, Block block) { + this.playSound(SoundEvents.ENTITY_SPIDER_STEP, 0.15F, 1.0F); + } - if (i > 20) - { - i = 20; - } + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } - return i; - } + @Override + public int getMaxSpawnedInChunk() { + return 8; + } + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFHostileWolf.java b/src/main/java/twilightforest/entity/EntityTFHostileWolf.java index d2112480d0..7c0329fecb 100644 --- a/src/main/java/twilightforest/entity/EntityTFHostileWolf.java +++ b/src/main/java/twilightforest/entity/EntityTFHostileWolf.java @@ -1,132 +1,123 @@ package twilightforest.entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.passive.EntityWolf; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; +import twilightforest.TFSounds; +import twilightforest.TwilightForestMod; +import javax.annotation.Nullable; public class EntityTFHostileWolf extends EntityWolf implements IMob { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/hostile_wolf"); public EntityTFHostileWolf(World world) { super(world); setAngry(true); - - this.targetTasks.addTask(4, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); + setCollarColor(EnumDyeColor.BLACK); + setAttributes(); // Must call this again because EntityWolf calls setTamed(false) which messes with our changes } - - public EntityTFHostileWolf(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - - /** - * Set monster attributes - */ + + // Split out from applyEntityAttributes because of above comment + protected void setAttributes() { + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D); // max health - } - - @Override - public void onUpdate() - { - super.onUpdate(); - if(!worldObj.isRemote && worldObj.difficultySetting == EnumDifficulty.PEACEFUL) - { - setDead(); - } - } - - /** - * Trigger achievement when killed - */ + protected final void applyEntityAttributes() { + super.applyEntityAttributes(); + setAttributes(); + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); + protected void initEntityAI() { + super.initEntityAI(); + this.targetTasks.addTask(4, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + public void onUpdate() { + super.onUpdate(); + if (!world.isRemote && world.getDifficulty() == EnumDifficulty.PEACEFUL) { + setDead(); } } - - /** - * Checks if the entity's current position is a valid location to spawn this entity. - */ - @Override - public boolean getCanSpawnHere() - { + + @Override + public boolean getCanSpawnHere() { // are we near a hedge maze? - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hedgeMaze) { - // don't check light level - return worldObj.checkNoEntityCollision(boundingBox) && worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0 && !worldObj.isAnyLiquid(boundingBox); - } - else { - return isValidLightLevel() && worldObj.checkNoEntityCollision(boundingBox) && worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0 && !worldObj.isAnyLiquid(boundingBox); + int chunkX = MathHelper.floor(posX) >> 4; + int chunkZ = MathHelper.floor(posZ) >> 4; + return (TFFeature.getNearestFeature(chunkX, chunkZ, world) == TFFeature.HEDGE_MAZE || isValidLightLevel()) + && world.checkNoEntityCollision(getEntityBoundingBox()) + && world.getCollisionBoxes(this, getEntityBoundingBox()).size() == 0 + && !world.containsAnyLiquid(getEntityBoundingBox()); + } + + // [VanillaCopy] Direct copy of EntityMob.isValidLightLevel + protected boolean isValidLightLevel() { + BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ); + + if (this.world.getLightFor(EnumSkyBlock.SKY, blockpos) > this.rand.nextInt(32)) { + return false; + } else { + int i = this.world.getLightFromNeighbors(blockpos); + + if (this.world.isThundering()) { + int j = this.world.getSkylightSubtracted(); + this.world.setSkylightSubtracted(10); + i = this.world.getLightFromNeighbors(blockpos); + this.world.setSkylightSubtracted(j); + } + + return i <= this.rand.nextInt(8); } - } - - /** - * Checks to make sure the light is not too bright where the mob is spawning - * Copied from EntityMob - */ - protected boolean isValidLightLevel() - { - int var1 = MathHelper.floor_double(this.posX); - int var2 = MathHelper.floor_double(this.boundingBox.minY); - int var3 = MathHelper.floor_double(this.posZ); - - if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, var1, var2, var3) > this.rand.nextInt(32)) - { - return false; - } - else - { - int var4 = this.worldObj.getBlockLightValue(var1, var2, var3); - - if (this.worldObj.isThundering()) - { - int var5 = this.worldObj.skylightSubtracted; - this.worldObj.skylightSubtracted = 10; - var4 = this.worldObj.getBlockLightValue(var1, var2, var3); - this.worldObj.skylightSubtracted = var5; - } - - return var4 <= this.rand.nextInt(8); - } - } - - /** - * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on - * the animal type) - */ - @Override - public boolean isBreedingItem(ItemStack par1ItemStack) - { - return false; - } - - /** - * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. - */ - @Override - public boolean interact(EntityPlayer par1EntityPlayer) - { - return false; - } + } + @Override + public void setAttackTarget(@Nullable EntityLivingBase entity) { + if (entity != null && entity != getAttackTarget()) + playSound(TFSounds.MISTWOLF_TARGET, 4F, getSoundPitch()); + super.setAttackTarget(entity); + } + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.MISTWOLF_IDLE; + } + + @Override + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return TFSounds.MISTWOLF_HURT; + } + + @Override + public boolean isBreedingItem(ItemStack stack) { + return false; + } + + @Override + public boolean processInteract(EntityPlayer player, EnumHand hand) { + return false; + } + + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFIceExploder.java b/src/main/java/twilightforest/entity/EntityTFIceExploder.java index 889f63f892..682023691e 100644 --- a/src/main/java/twilightforest/entity/EntityTFIceExploder.java +++ b/src/main/java/twilightforest/entity/EntityTFIceExploder.java @@ -1,189 +1,118 @@ package twilightforest.entity; import net.minecraft.block.Block; +import net.minecraft.block.BlockColored; +import net.minecraft.block.BlockStainedGlass; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.item.EntityXPOrb; -import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.item.EnumDyeColor; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraftforge.event.ForgeEventFactory; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; import twilightforest.block.TFBlocks; -public class EntityTFIceExploder extends EntityMob { +public class EntityTFIceExploder extends EntityTFIceMob { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/ice_exploder"); private static final float EXPLOSION_RADIUS = 1; + public EntityTFIceExploder(World world) { + super(world); + this.setSize(0.8F, 1.8F); + } - public EntityTFIceExploder(World par1World) { - super(par1World); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(2, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(3, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - this.setSize(0.8F, 1.8F); + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(2, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0D); + } - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D); - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; - } - - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return Items.snowball; - } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - // make snow particles - for (int i = 0; i < 3; i++) { - float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - float py = this.getEyeHeight() + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; - float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowguardian", this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); - } - - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.ice.noise"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.ice.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.ice.death"; - } - - - - public float getEyeHeight() - { - return this.height * 0.6F; - } - - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + public ResourceLocation getLootTable() { + return LOOT_TABLE; } - - /** - * handles entity death timer, experience orb and particle creation - */ - protected void onDeathUpdate() { - ++this.deathTime; - - if (this.deathTime == 60) - { - int i; - - - boolean flag = this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing"); - this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)EntityTFIceExploder.EXPLOSION_RADIUS, flag); - - if (flag) { - this.detonate(); - } - - if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && this.func_146066_aG() && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot")) - { - i = this.getExperiencePoints(this.attackingPlayer); - - while (i > 0) - { - int j = EntityXPOrb.getXPSplit(i); - i -= j; - this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, j)); - } - } - - this.setDead(); - - for (i = 0; i < 20; ++i) - { - double d2 = this.rand.nextGaussian() * 0.02D; - double d0 = this.rand.nextGaussian() * 0.02D; - double d1 = this.rand.nextGaussian() * 0.02D; - this.worldObj.spawnParticle("explode", this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d2, d0, d1); - } - } + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.ICE_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.ICE_HURT; } + @Override + protected SoundEvent getDeathSound() { + return TFSounds.ICE_DEATH; + } + + @Override + public float getEyeHeight() { + return this.height * 0.6F; + } - private void detonate() { + @Override + protected void onDeathUpdate() { + ++this.deathTime; + + if (this.deathTime == 60) // delay until 3 seconds + { + if (!world.isRemote) { + boolean mobGriefing = ForgeEventFactory.getMobGriefingEvent(world, this); + this.world.createExplosion(this, this.posX, this.posY, this.posZ, EntityTFIceExploder.EXPLOSION_RADIUS, mobGriefing); + + if (mobGriefing) { + this.transformBlocks(); + } + } + // Fake to trigger super's behaviour + deathTime = 19; + super.onDeathUpdate(); + deathTime = 60; + } + } + + private void transformBlocks() { int range = 4; - - int sx = MathHelper.floor_double(this.posX); - int sy = MathHelper.floor_double(this.posY); - int sz = MathHelper.floor_double(this.posZ); - + + BlockPos pos = new BlockPos(this); + for (int dx = -range; dx <= range; dx++) { for (int dy = -range; dy <= range; dy++) { for (int dz = -range; dz <= range; dz++) { double distance = Math.sqrt(dx * dx + dy * dy + dz * dz); - + float randRange = range + (rand.nextFloat() - rand.nextFloat()) * 2F; - + if (distance < randRange) { - this.transformBlock(sx + dx, sy + dy, sz + dz); + this.transformBlock(pos.add(dx, dy, dz)); } } } @@ -191,84 +120,69 @@ private void detonate() { } - private void transformBlock(int x, int y, int z) { - Block block = this.worldObj.getBlock(x, y, z); - int meta = this.worldObj.getBlockMetadata(x, y, z); - - // check if we should even explode this - if (block.getExplosionResistance(this) < 8F && block.getBlockHardness(worldObj, x, y, z) >= 0) { - - int blockColor = 16777215; - - //TODO: use a better check than exception handling to determine if we have access to client-side methods or not - try { - // figure out color - blockColor = block.colorMultiplier(worldObj, x, y, z); - } catch (NoSuchMethodError e) { - // fine, we're on a server - } + private void transformBlock(BlockPos pos) { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); - if (blockColor == 16777215) { - blockColor = block.getMapColor(meta).colorValue; - } + // check if we should even explode this + if (block.getExplosionResistance(this) < 8F && state.getBlockHardness(world, pos) >= 0) { + // todo improve for blocks where state is known? or perhaps if a propertycolor is present + int blockColor = state.getMapColor(world, pos).colorValue; // do appropriate transformation - if (this.shouldTransformGlass(block, x, y, z)) { - this.worldObj.setBlock(x, y, z, Blocks.stained_glass, this.getMetaForColor(blockColor), 3); - } else if (this.shouldTransformClay(block, x, y, z)) { - this.worldObj.setBlock(x, y, z, Blocks.stained_hardened_clay, this.getMetaForColor(blockColor), 3); + if (this.shouldTransformGlass(state, pos)) { + this.world.setBlockState(pos, Blocks.STAINED_GLASS.getDefaultState().withProperty(BlockStainedGlass.COLOR, getClosestDyeColor(blockColor))); + } else if (this.shouldTransformClay(state, pos)) { + this.world.setBlockState(pos, Blocks.STAINED_HARDENED_CLAY.getDefaultState().withProperty(BlockColored.COLOR, getClosestDyeColor(blockColor))); } } } - private boolean shouldTransformClay(Block block, int x, int y, int z) { - return block.isNormalCube(this.worldObj, x, y, z); + private boolean shouldTransformClay(IBlockState state, BlockPos pos) { + return state.getBlock().isNormalCube(state, this.world, pos); } - private boolean shouldTransformGlass(Block block, int x, int y, int z) { - return block != Blocks.air && this.isBlockNormalBounds(block, x, y, z) && (!block.getMaterial().isOpaque() || block.isLeaves(this.worldObj, x, y, z) || block == Blocks.ice || block == TFBlocks.auroraBlock); + private boolean shouldTransformGlass(IBlockState state, BlockPos pos) { + return state.getBlock() != Blocks.AIR && this.isBlockNormalBounds(state, pos) && (!state.getMaterial().isOpaque() || state.getBlock().isLeaves(state, this.world, pos) || state.getBlock() == Blocks.ICE || state.getBlock() == TFBlocks.aurora_block); } - private boolean isBlockNormalBounds(Block block, int x, int y, int z) { - return block.getBlockBoundsMaxX() == 1.0F && block.getBlockBoundsMaxY() == 1.0F && block.getBlockBoundsMaxZ() == 1.0F && block.getBlockBoundsMinX() == 0.0F && block.getBlockBoundsMinY() == 0.0F && block.getBlockBoundsMinZ() == 0.0F; + private boolean isBlockNormalBounds(IBlockState state, BlockPos pos) { + return Block.FULL_BLOCK_AABB.equals(state.getBoundingBox(world, pos)); } - private int getMetaForColor(int blockColor) { - int red = (blockColor >> 16) & 255; - int green = (blockColor >> 8) & 255; - int blue = blockColor & 255; - - - int bestColor = 0; + private EnumDyeColor getClosestDyeColor(int blockColor) { + int red = (blockColor >> 16) & 255; + int green = (blockColor >> 8) & 255; + int blue = blockColor & 255; + + + EnumDyeColor bestColor = EnumDyeColor.WHITE; int bestDifference = 1024; - - for (int i = 0; i < 15; i++) { - int iColor = Blocks.wool.getMapColor(i).colorValue; - - int iRed = (iColor >> 16) & 255; - int iGreen = (iColor >> 8) & 255; - int iBlue = iColor & 255; - + + for (EnumDyeColor color : EnumDyeColor.values()) { + float[] iColor = color.getColorComponentValues(); + + int iRed = (int) (iColor[0] * 255F); + int iGreen = (int) (iColor[1] * 255F); + int iBlue = (int) (iColor[2] * 255F); + int difference = Math.abs(red - iRed) + Math.abs(green - iGreen) + Math.abs(blue - iBlue); - + if (difference < bestDifference) { - bestColor = i; + bestColor = color; bestDifference = difference; } } - + return bestColor; } - - /** - * Will return how many at most can spawn in a chunk at once. - */ - public int getMaxSpawnedInChunk() - { - return 8; - } + + @Override + public int getMaxSpawnedInChunk() { + return 8; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFIceMob.java b/src/main/java/twilightforest/entity/EntityTFIceMob.java new file mode 100644 index 0000000000..c8b9a2fd90 --- /dev/null +++ b/src/main/java/twilightforest/entity/EntityTFIceMob.java @@ -0,0 +1,50 @@ +package twilightforest.entity; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; + +public abstract class EntityTFIceMob extends EntityMob { + public EntityTFIceMob(World worldIn) { + super(worldIn); + } + + @Override + public void onLivingUpdate() { + if (!this.onGround && this.motionY < 0.0D) { + this.motionY *= 0.6D; + } + super.onLivingUpdate(); + if (this.world.isRemote) { + // make snow particles + for (int i = 0; i < 3; i++) { + float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; + float py = this.getEyeHeight() + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; + float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.SNOW_GUARDIAN, this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); + if (this.world.getBiome(this.getPosition()).getTemperature(this.getPosition()) > 1.0F || this.isBurning()) { + this.world.spawnParticle(EnumParticleTypes.CLOUD, this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0.1F, 0); + this.world.spawnParticle(EnumParticleTypes.WATER_DROP, this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); + } + } + } + if (this.world.getBiome(this.getPosition()).getTemperature(this.getPosition()) > 1.0F && this.ticksExisted % 20 == 0) { + //BURN!!! + this.attackEntityFrom(DamageSource.ON_FIRE, 1.0F); + } + } + + @Override + public void fall(float distance, float damageMultiplier) { + } + + @Override + protected void updateFallState(double y, boolean onGroundIn, IBlockState state, BlockPos pos) { + } +} diff --git a/src/main/java/twilightforest/entity/EntityTFIceShooter.java b/src/main/java/twilightforest/entity/EntityTFIceShooter.java index 6b01aabd55..f7f8f1c6a9 100644 --- a/src/main/java/twilightforest/entity/EntityTFIceShooter.java +++ b/src/main/java/twilightforest/entity/EntityTFIceShooter.java @@ -3,144 +3,97 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIArrowAttack; +import net.minecraft.entity.ai.EntityAIAttackRanged; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; -public class EntityTFIceShooter extends EntityMob implements IRangedAttackMob { - - public EntityTFIceShooter(World par1World) { - super(par1World); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIArrowAttack(this, 1.25D, 20, 10.0F)); - this.tasks.addTask(2, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(3, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - this.setSize(0.8F, 1.8F); +public class EntityTFIceShooter extends EntityTFIceMob implements IRangedAttackMob { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/ice_shooter"); + + public EntityTFIceShooter(World world) { + super(world); + this.setSize(0.8F, 1.8F); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAttackRanged(this, 1.25D, 20, 10.0F)); + this.tasks.addTask(2, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0D); + } + + @Override + public float getEyeHeight() { + return this.height * 0.6F; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; } + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.ICE_AMBIENT; + } - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D); - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; - } - - - public float getEyeHeight() - { - return this.height * 0.6F; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return Items.snowball; - } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - // make snow particles - for (int i = 0; i < 3; i++) { - float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - float py = this.getEyeHeight() + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; - float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowguardian", this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); - } - - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.ice.noise"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.ice.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.ice.death"; - } - - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.ICE_HURT; } + @Override + protected SoundEvent getDeathSound() { + return TFSounds.ICE_DEATH; + } - /** - * Will return how many at most can spawn in a chunk at once. - */ @Override - public int getMaxSpawnedInChunk() - { - return 8; - } - - /** - * Attack the specified entity using a ranged attack. - */ + public int getMaxSpawnedInChunk() { + return 8; + } + @Override - public void attackEntityWithRangedAttack(EntityLivingBase par1EntityLivingBase, float par2) - { - EntityTFIceSnowball entitysnowball = new EntityTFIceSnowball(this.worldObj, this); - double d0 = par1EntityLivingBase.posX - this.posX; - double d1 = par1EntityLivingBase.posY + (double)par1EntityLivingBase.getEyeHeight() - 1.100000023841858D - entitysnowball.posY; - double d2 = par1EntityLivingBase.posZ - this.posZ; - float f1 = MathHelper.sqrt_double(d0 * d0 + d2 * d2) * 0.2F; - entitysnowball.setThrowableHeading(d0, d1 + (double)f1, d2, 0.6F, 12.0F); - this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); - this.worldObj.spawnEntityInWorld(entitysnowball); - } + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) { + EntityTFIceSnowball snowball = new EntityTFIceSnowball(this.world, this); + + // [VanillaCopy] Adapted from EntitySnowman + double d0 = target.posY + (double) target.getEyeHeight() - 1.4; + double d1 = target.posX - this.posX; + double d2 = d0 - snowball.posY; + double d3 = target.posZ - this.posZ; + float f = MathHelper.sqrt(d1 * d1 + d3 * d3) * 0.2F; + snowball.shoot(d1, d2 + (double) f, d3, 1.6F, 0.0F); + + this.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.world.spawnEntity(snowball); + } + + @Override + public void setSwingingArms(boolean swingingArms) { + } } diff --git a/src/main/java/twilightforest/entity/EntityTFIceSnowball.java b/src/main/java/twilightforest/entity/EntityTFIceSnowball.java index bcd3f58705..5512815291 100644 --- a/src/main/java/twilightforest/entity/EntityTFIceSnowball.java +++ b/src/main/java/twilightforest/entity/EntityTFIceSnowball.java @@ -1,102 +1,78 @@ package twilightforest.entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; -public class EntityTFIceSnowball extends EntityThrowable { +public class EntityTFIceSnowball extends EntityTFThrowable { private static final int DAMAGE = 8; - public EntityTFIceSnowball(World par1World) { - super(par1World); + public EntityTFIceSnowball(World world) { + super(world); } - public EntityTFIceSnowball(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); + public EntityTFIceSnowball(World world, EntityLivingBase thrower) { + super(world, thrower); } - + @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - /** - * How much this entity falls each tick - */ + @Override - protected float getGravityVelocity() - { + protected float getGravityVelocity() { return 0.006F; - } - - /** - * Make slimy trail - */ + } + public void makeTrail() { for (int i = 0; i < 2; i++) { - double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); - worldObj.spawnParticle("snowballpoof", dx, dy, dz, 0.0D, 0.0D, 0.0D); + double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); + world.spawnParticle(EnumParticleTypes.SNOWBALL, dx, dy, dz, 0.0D, 0.0D, 0.0D); } } - - /** - * Reflect! - */ - @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { - - setBeenAttacked(); - - pop(); - return true; - } + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + super.attackEntityFrom(source, amount); + die(); + return true; + } - /** - * What happens when we hit something? - */ + @SideOnly(Side.CLIENT) @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - // only damage living things - if (par1MovingObjectPosition.entityHit != null && par1MovingObjectPosition.entityHit instanceof EntityLivingBase) - { - if (par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), DAMAGE)) - { - // damage armor? - //TODO: + public void handleStatusUpdate(byte id) { + if (id == 3) { + for (int j = 0; j < 8; ++j) { + this.world.spawnParticle(EnumParticleTypes.SNOWBALL, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); } + } else { + super.handleStatusUpdate(id); } - - pop(); - } - /** - * Yeah, do that - */ - protected void pop() { - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D); + @Override + protected void onImpact(RayTraceResult result) { + if (!world.isRemote && result.entityHit instanceof EntityLivingBase) { + result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), DAMAGE); + // TODO: damage armor? } - - // noise - //this.worldObj.playSoundAtEntity(this, "mob.slime.big", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); + die(); + } - if (!this.worldObj.isRemote) - { + private void die() { + if (!this.world.isRemote) { + this.world.setEntityState(this, (byte) 3); this.setDead(); } } - - } diff --git a/src/main/java/twilightforest/entity/EntityTFKingSpider.java b/src/main/java/twilightforest/entity/EntityTFKingSpider.java index e8d53fd0b0..7a39401ec7 100644 --- a/src/main/java/twilightforest/entity/EntityTFKingSpider.java +++ b/src/main/java/twilightforest/entity/EntityTFKingSpider.java @@ -3,121 +3,69 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; -import net.minecraft.entity.ai.EntityAIHurtByTarget; -import net.minecraft.entity.ai.EntityAILeapAtTarget; -import net.minecraft.entity.ai.EntityAILookIdle; -import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.EntityAIWander; -import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntitySpider; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; public class EntityTFKingSpider extends EntitySpider { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/king_spider"); public EntityTFKingSpider(World world) { super(world); - //texture = TwilightForestMod.MODEL_DIR + "kingspider.png"; - this.setSize(1.6F, 1.6F); - //this.moveSpeed = 0.35F; - - this.getNavigator().setAvoidsWater(true); - //this.tasks.addTask(1, new EntityAITFChargeAttack(this, 0.4F)); - this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.3F)); - this.tasks.addTask(6, new EntityAIWander(this, 0.2F)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); - this.targetTasks.addTask(2, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - + this.setSize(1.6F, 1.6F); } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.35D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); // attack damage - } + protected void initEntityAI() { + super.initEntityAI(); + //this.tasks.addTask(1, new EntityAITFChargeAttack(this, 0.4F)); + } - - /** - * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking - * (Animals, Spiders at day, peaceful PigZombies). - */ - @Override - protected Entity findPlayerToAttack() - { - // kill at all times! - double var2 = 16.0D; - return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2); - } - - /** - * How large the spider should be scaled. - */ - //@Override - public float spiderScaleAmount() - { - return 1.9F; - } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.35D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6.0D); + } - /** - * Actually only used for the shadow - */ @Override public float getRenderSizeModifier() { - return 2.0F; + return 2.0F; } - - /** - * returns true if this entity is by a ladder, false otherwise - */ - public boolean isOnLadder() - { - // let's not climb - return false; - } - - /** - * Init creature with mount - */ - public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) - { - Object par1EntityLivingData1 = super.onSpawnWithEgg(par1EntityLivingData); + @Override + public boolean isOnLadder() { + // let's not climb + return false; + } - // always a spider jockey - EntityTFSkeletonDruid druid = new EntityTFSkeletonDruid(this.worldObj); - druid.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); - druid.onSpawnWithEgg((IEntityLivingData)null); - this.worldObj.spawnEntityInWorld(druid); - druid.mountEntity(this); - - return (IEntityLivingData)par1EntityLivingData1; - } + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingData) { + livingData = super.onInitialSpawn(difficulty, livingData); + + // will always have a dryad riding the spider or whatever is riding the spider + EntityTFSkeletonDruid druid = new EntityTFSkeletonDruid(this.world); + druid.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); + druid.onInitialSpawn(difficulty, null); + this.world.spawnEntity(druid); + Entity lastRider = this; + while (!lastRider.getPassengers().isEmpty()) + lastRider = lastRider.getPassengers().get(0); + druid.startRiding(lastRider); + + return livingData; + } - /** - * Returns the Y offset from the entity's position for any entity riding this one. - */ - public double getMountedYOffset() - { - return (double)this.height * 0.5D; - } + @Override + public double getMountedYOffset() { + return (double) this.height * 0.75D; + } + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFKobold.java b/src/main/java/twilightforest/entity/EntityTFKobold.java index a82df12414..afb8787af5 100644 --- a/src/main/java/twilightforest/entity/EntityTFKobold.java +++ b/src/main/java/twilightforest/entity/EntityTFKobold.java @@ -1,187 +1,109 @@ package twilightforest.entity; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILeapAtTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFFlockToSameKind; import twilightforest.entity.ai.EntityAITFPanicOnFlockDeath; - public class EntityTFKobold extends EntityMob { - - - private boolean shy; - - public EntityTFKobold(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "kobold.png"; - //moveSpeed = 0.28F; - setSize(0.8F, 1.1F); - - shy = true; - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAITFPanicOnFlockDeath(this, 2.0F)); - this.tasks.addTask(2, new EntityAILeapAtTarget(this, 0.3F)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(4, new EntityAITFFlockToSameKind(this, 1.0D)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(7, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - } - - public EntityTFKobold(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/kobold"); + private static final DataParameter PANICKED = EntityDataManager.createKey(EntityTFKobold.class, DataSerializers.BOOLEAN); + + public EntityTFKobold(World world) { + super(world); + setSize(0.8F, 1.1F); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAITFPanicOnFlockDeath(this, 2.0F)); + this.tasks.addTask(2, new EntityAILeapAtTarget(this, 0.3F)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(4, new EntityAITFFlockToSameKind(this, 1.0D)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(PANICKED, false); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(13.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4.0D); + } + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.KOBOLD_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.KOBOLD_HURT; + } + @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(17, Byte.valueOf((byte)0)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ + protected SoundEvent getDeathSound() { + return TFSounds.KOBOLD_DEATH; + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(13.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D); // attack damage - } - - - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.kobold.kobold"; - } - - @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.kobold.hurt"; - } - - @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.kobold.die"; - } - - @Override - protected Item getDropItem() - { - return Items.wheat; - } - - @Override - protected void dropFewItems(boolean flag, int i) - { - super.dropFewItems(flag, i); - - if (rand.nextInt(2) == 0) - { - this.dropItem(Items.gold_nugget, 1 + i); - } - } - - public boolean isShy() { - return shy && this.recentlyHit <= 0; - } - - public boolean isPanicked() - { - return dataWatcher.getWatchableObjectByte(17) != 0; - } - - public void setPanicked(boolean flag) - { - if (flag) - { - dataWatcher.updateObject(17, Byte.valueOf((byte)127)); - } - else - { - dataWatcher.updateObject(17, Byte.valueOf((byte)0)); - } - } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - super.onLivingUpdate(); - - //when panicked, spawn tears/sweat - if (isPanicked()) - { - for (int i = 0; i < 2; i++) - { - this.worldObj.spawnParticle("splash", this.posX + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, this.posY + this.getEyeHeight(), this.posZ + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, 0, 0, 0); - } - } - - } - - - /** - * Trigger achievement when killed - */ - @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } - } - - - /** - * Will return how many at most can spawn in a chunk at once. - */ - @Override - public int getMaxSpawnedInChunk() - { - return 8; - } - + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + public boolean isPanicked() { + return dataManager.get(PANICKED); + } + + public void setPanicked(boolean flag) { + dataManager.set(PANICKED, flag); + } + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (world.isRemote && isPanicked()) { + for (int i = 0; i < 2; i++) { + this.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, this.posX + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, this.posY + this.getEyeHeight(), this.posZ + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, 0, 0, 0); + } + } + + } + + @Override + public int getMaxSpawnedInChunk() { + return 8; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFLoyalZombie.java b/src/main/java/twilightforest/entity/EntityTFLoyalZombie.java index 422e2edfc1..6d06657693 100644 --- a/src/main/java/twilightforest/entity/EntityTFLoyalZombie.java +++ b/src/main/java/twilightforest/entity/EntityTFLoyalZombie.java @@ -3,183 +3,134 @@ import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityAgeable; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIFollowOwner; import net.minecraft.entity.ai.EntityAIHurtByTarget; -import net.minecraft.entity.ai.EntityAILeapAtTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget; import net.minecraft.entity.ai.EntityAIOwnerHurtTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.monster.EntityGhast; import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.passive.AbstractHorse; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityTameable; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.potion.Potion; +import net.minecraft.init.MobEffects; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; - public class EntityTFLoyalZombie extends EntityTameable { - public EntityTFLoyalZombie(World par1World) { - super(par1World); - //this.texture = "/mob/zombie.png"; - //this.moveSpeed = 0.3F; - this.setSize(0.6F, 1.8F); - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(1, new EntityAISwimming(this)); - this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F)); - this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true)); - this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F)); - this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(9, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this)); - this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this)); - this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(4, new EntityAINearestAttackableTarget(this, EntityMob.class, 0, true)); + public EntityTFLoyalZombie(World world) { + super(world); + this.setSize(0.6F, 1.8F); + } + @Override + protected void initEntityAI() { + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.0D, true)); + this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F)); + this.tasks.addTask(7, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(9, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this)); + this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this)); + this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(4, new EntityAINearestAttackableTarget<>(this, EntityMob.class, true)); } @Override - public EntityAnimal createChild(EntityAgeable entityanimal) - { + public EntityAnimal createChild(EntityAgeable entityanimal) { return null; } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.3D); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(3.0D); + } + + @Override + public boolean attackEntityAsMob(Entity entity) { + boolean success = entity.attackEntityFrom(DamageSource.causeMobDamage(this), 7); + + if (success) { + entity.motionY += 0.2; + } + + return success; + } + + @Override + public void onLivingUpdate() { + // once our damage boost effect wears out, start to burn + // the effect here is that we die shortly after our 60 second lifespan + if (!this.world.isRemote && this.getActivePotionEffect(MobEffects.STRENGTH) == null) { + this.setFire(100); + } + + super.onLivingUpdate(); + } + + // [VanillaCopy] EntityWolf.shouldAttackEntity, substituting with our class + @Override + public boolean shouldAttackEntity(EntityLivingBase target, EntityLivingBase owner) { + if (!(target instanceof EntityCreeper) && !(target instanceof EntityGhast)) { + if (target instanceof EntityTFLoyalZombie) { + EntityTFLoyalZombie zombie = (EntityTFLoyalZombie) target; + + if (zombie.isTamed() && zombie.getOwner() == owner) { + return false; + } + } + + return target instanceof EntityPlayer && owner instanceof EntityPlayer && !((EntityPlayer) owner).canAttackPlayer((EntityPlayer) target) ? false : !(target instanceof AbstractHorse) || !((AbstractHorse) target).isTame(); + } else { + return false; + } + } + + @Override + protected boolean canDespawn() { + return !this.isTamed(); + } + + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.ENTITY_ZOMBIE_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_ZOMBIE_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_ZOMBIE_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, Block block) { + playSound(SoundEvents.ENTITY_ZOMBIE_STEP, 0.15F, 1.0F); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(40.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3D); // movement speed - } - - /** - * Rawr! - */ - public boolean attackEntityAsMob(Entity par1Entity) - { - int attackpower = 7; - boolean success = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), attackpower); - - // throw some enemies around! - if (success) - { - par1Entity.motionY += 0.2000000059604645D; - } - - return success; - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - // once our damage boost effect wears out, start to burn - // the effect here is that we die shortly after our 60 second lifespan - if (!this.worldObj.isRemote && this.getActivePotionEffect(Potion.damageBoost) == null) - { - this.setFire(100); - } - - super.onLivingUpdate(); - } - - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return !this.isTamed(); - } - - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - @Override - public int getTotalArmorValue() - { - return 3; - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return "mob.zombie.say"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return "mob.zombie.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return "mob.zombie.death"; - } - - /** - * Plays step sound at given x, y, z for the entity - */ - @Override - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - this.worldObj.playSoundAtEntity(this, "mob.zombie.step", 0.15F, 1.0F); - } - - - /** - * Returns the item ID for the item the mob drops on death. - */ - @Override - protected Item getDropItem() - { - return Item.getItemById(0); - } - - /** - * Get this Entity's EnumCreatureAttribute - */ - @Override - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.UNDEAD; - } + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFMazeSlime.java b/src/main/java/twilightforest/entity/EntityTFMazeSlime.java index 8015a771b3..c33a6b4605 100644 --- a/src/main/java/twilightforest/entity/EntityTFMazeSlime.java +++ b/src/main/java/twilightforest/entity/EntityTFMazeSlime.java @@ -1,142 +1,113 @@ package twilightforest.entity; import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.EntitySlime; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; -import twilightforest.item.TFItems; +import twilightforest.enums.MazestoneVariant; -public class EntityTFMazeSlime extends EntitySlime -{ +public class EntityTFMazeSlime extends EntitySlime { - private String slimeParticleString; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/maze_slime"); + private static final AttributeModifier DOUBLE_HEALTH = new AttributeModifier("Maze slime double health", 1, 1).setSaved(false); - public EntityTFMazeSlime(World par1World) { - super(par1World); - //texture = TwilightForestMod.MODEL_DIR + "mazeslime.png"; - this.setSlimeSize(1 << (1 + this.rand.nextInt(2))); + public EntityTFMazeSlime(World world) { + super(world); } - /** - * Make more of meeee - */ - @Override - protected EntitySlime createInstance() - { - return new EntityTFMazeSlime(this.worldObj); - } - - @Override - public void setSlimeSize(int par1) - { - super.setSlimeSize(par1); - this.experienceValue = par1 + 3; - } - - /** - * Checks if the entity's current position is a valid location to spawn this entity. - */ - @Override - public boolean getCanSpawnHere() - { - return this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL && this.worldObj.checkNoEntityCollision(this.boundingBox) - && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() - && !this.worldObj.isAnyLiquid(this.boundingBox) && this.isValidLightLevel(); - } - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - int size = this.getSlimeSize(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(2.0D * size * size); // max health - } - - /** - * Indicates weather the slime is able to damage the player (based upon the slime's size) - */ - @Override - protected boolean canDamagePlayer() - { - return true; - } - - /** - * Gets the amount of damage dealt to the player when "attacked" by the slime. - */ - @Override - protected int getAttackStrength() - { - return super.getAttackStrength() + 3; - } - - - /** - * Returns the name of a particle effect that may be randomly created by EntitySlime.onUpdate() - */ - @Override - protected String getSlimeParticle() - { - if (slimeParticleString == null) - { - slimeParticleString = "blockcrack_" + Block.getIdFromBlock(TFBlocks.mazestone) + "_1"; - } - - return slimeParticleString; - } - - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ - protected boolean isValidLightLevel() - { - int var1 = MathHelper.floor_double(this.posX); - int var2 = MathHelper.floor_double(this.boundingBox.minY); - int var3 = MathHelper.floor_double(this.posZ); - - if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, var1, var2, var3) > this.rand.nextInt(32)) - { - return false; - } - else - { - int var4 = this.worldObj.getBlockLightValue(var1, var2, var3); - - if (this.worldObj.isThundering()) - { - int var5 = this.worldObj.skylightSubtracted; - this.worldObj.skylightSubtracted = 10; - var4 = this.worldObj.getBlockLightValue(var1, var2, var3); - this.worldObj.skylightSubtracted = var5; - } - - return var4 <= this.rand.nextInt(8); - } - } - - - /** - * Returns the volume for the sounds this mob makes. - */ - @Override - protected float getSoundVolume() - { - // OH MY GOD, SHUT UP - return 0.1F * this.getSlimeSize(); - } - - - @Override - protected void dropRareDrop(int par1) - { - this.dropItem(TFItems.charmOfKeeping1, 1); - } + protected EntitySlime createInstance() { + return new EntityTFMazeSlime(this.world); + } + + @Override + public void setSlimeSize(int size, boolean resetHealth) { + super.setSlimeSize(size, resetHealth); + this.experienceValue += 3; + } + + @Override + public boolean getCanSpawnHere() { + return this.world.getDifficulty() != EnumDifficulty.PEACEFUL && this.world.checkNoEntityCollision(getEntityBoundingBox()) + && this.world.getCollisionBoxes(this, getEntityBoundingBox()).isEmpty() + && !this.world.containsAnyLiquid(getEntityBoundingBox()) && this.isValidLightLevel(); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).applyModifier(DOUBLE_HEALTH); + } + + @Override + protected boolean canDamagePlayer() { + return true; + } + + @Override + protected int getAttackStrength() { + return super.getAttackStrength() + 3; + } + + @Override + protected boolean spawnCustomParticles() { + // [VanillaCopy] from super onUpdate with own particles + int i = getSlimeSize(); + for (int j = 0; j < i * 8; ++j) { + float f = this.rand.nextFloat() * ((float) Math.PI * 2F); + float f1 = this.rand.nextFloat() * 0.5F + 0.5F; + float f2 = MathHelper.sin(f) * (float) i * 0.5F * f1; + float f3 = MathHelper.cos(f) * (float) i * 0.5F * f1; + World world = this.world; + // EnumParticleTypes enumparticletypes = this.getParticleType(); + double d0 = this.posX + (double) f2; + double d1 = this.posZ + (double) f3; + IBlockState state = TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BRICK); + world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, d0, this.getEntityBoundingBox().minY, d1, 0.0D, 0.0D, 0.0D, Block.getStateId(state)); + } + return true; + } + + // [VanillaCopy] exact copy from EntityMob.isValidLightLevel + private boolean isValidLightLevel() { + BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ); + + if (this.world.getLightFor(EnumSkyBlock.SKY, blockpos) > this.rand.nextInt(32)) { + return false; + } else { + int i = this.world.getLightFromNeighbors(blockpos); + + if (this.world.isThundering()) { + int j = this.world.getSkylightSubtracted(); + this.world.setSkylightSubtracted(10); + i = this.world.getLightFromNeighbors(blockpos); + this.world.setSkylightSubtracted(j); + } + + return i <= this.rand.nextInt(8); + } + } + + @Override + protected float getSoundVolume() { + // OH MY GOD, SHUT UP + return 0.1F * this.getSlimeSize(); + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFMiniGhast.java b/src/main/java/twilightforest/entity/EntityTFMiniGhast.java index 2d777fc9ed..69a5fab2c0 100644 --- a/src/main/java/twilightforest/entity/EntityTFMiniGhast.java +++ b/src/main/java/twilightforest/entity/EntityTFMiniGhast.java @@ -1,172 +1,119 @@ package twilightforest.entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; -public class EntityTFMiniGhast extends EntityTFTowerGhast -{ - public boolean isMinion = false; - - public EntityTFMiniGhast(World par1World) { - super(par1World); - this.setSize(1.1F, 1.5F); - //this.texture = TwilightForestMod.MODEL_DIR + "towerghast.png"; - - this.aggroRange = 16.0F; - this.stareRange = 8.0F; - - this.wanderFactor = 4.0F; - +public class EntityTFMiniGhast extends EntityTFTowerGhast { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/mini_ghast"); + private boolean isMinion = false; + + public EntityTFMiniGhast(World world) { + super(world); + this.setSize(1.1F, 1.5F); + this.wanderFactor = 4.0F; + } + + @Override + public int getMaxSpawnedInChunk() { + return 16; + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(this.isMinion ? 6 : 10); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(16.0D); } - /** - * Will return how many at most can spawn in a chunk at once. - */ - public int getMaxSpawnedInChunk() - { - return 16; - } - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(this.isMinion ? 6 : 10); // max health - } - - @Override - public void onUpdate() - { - super.onUpdate(); - //byte aggroStatus = this.dataWatcher.getWatchableObjectByte(16); - -// switch (aggroStatus) -// { -// case 0: -// default: -// this.texture = TwilightForestMod.MODEL_DIR + "towerghast.png"; -// break; -// case 1: -// this.texture = TwilightForestMod.MODEL_DIR + "towerghast_openeyes.png"; -// break; -// case 2: -// this.texture = TwilightForestMod.MODEL_DIR + "towerghast_fire.png"; -// break; -// } + public float getEyeHeight() { + return 1.2F; + } + + // Loosely based on EntityEnderman.shouldAttackPlayer + @Override + protected boolean shouldAttack(EntityLivingBase living) { + ItemStack helmet = living.getItemStackFromSlot(EntityEquipmentSlot.HEAD); + if (!helmet.isEmpty() && helmet.getItem() == Item.getItemFromBlock(Blocks.PUMPKIN)) { + return false; + } else if (living.getDistance(this) <= 3.5F) { + return living.canEntityBeSeen(this); + } else { + Vec3d vec3d = living.getLook(1.0F).normalize(); + Vec3d vec3d1 = new Vec3d(this.posX - living.posX, this.getEntityBoundingBox().minY + (double) this.getEyeHeight() - (living.posY + (double) living.getEyeHeight()), this.posZ - living.posZ); + double d0 = vec3d1.length(); + vec3d1 = vec3d1.normalize(); + double d1 = vec3d.dotProduct(vec3d1); + return d1 > 1.0D - 0.025D / d0 ? living.canEntityBeSeen(this) : false; + } + } + + @Override + protected boolean isValidLightLevel() { + if (isMinion) { + return true; + } + + // [VanillaCopy] EntityMob.isValidLightLevel + BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ); + + if (this.world.getLightFor(EnumSkyBlock.SKY, blockpos) > this.rand.nextInt(32)) { + return false; + } else { + int i = this.world.getLightFromNeighbors(blockpos); + + if (this.world.isThundering()) { + int j = this.world.getSkylightSubtracted(); + this.world.setSkylightSubtracted(10); + i = this.world.getLightFromNeighbors(blockpos); + this.world.setSkylightSubtracted(j); + } + + return i <= this.rand.nextInt(8); + } } - /** - * Checks to see if this mini ghast should be attacking this player. - * - * Very similar to endermen code, but we also attack at a certain range - */ - protected boolean shouldAttackPlayer(EntityPlayer par1EntityPlayer) - { - ItemStack playerHeadArmor = par1EntityPlayer.inventory.armorInventory[3]; - - if (playerHeadArmor != null && playerHeadArmor.getItem() == Item.getItemFromBlock(Blocks.pumpkin)) - { - return false; - } - else if (par1EntityPlayer.getDistanceToEntity(this) <= 3.5F && par1EntityPlayer.canEntityBeSeen(this)) - { - return true; - } - else - { - Vec3 var3 = par1EntityPlayer.getLook(1.0F).normalize(); - Vec3 var4 = Vec3.createVectorHelper(this.posX - par1EntityPlayer.posX, this.boundingBox.minY + (double)(this.height / 2.0F) - (par1EntityPlayer.posY + (double)par1EntityPlayer.getEyeHeight()), this.posZ - par1EntityPlayer.posZ); - double var5 = var4.lengthVector(); - var4 = var4.normalize(); - double var7 = var3.dotProduct(var4); - return var7 > 1.0D - 0.025D / var5 ? par1EntityPlayer.canEntityBeSeen(this) : false; - } - } - - - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ - protected boolean isValidLightLevel() - { - if (isMinion) - { - return true; - } - - int myX = MathHelper.floor_double(this.posX); - int myY = MathHelper.floor_double(this.boundingBox.minY); - int myZ = MathHelper.floor_double(this.posZ); - - if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, myX, myY, myZ) > this.rand.nextInt(32)) - { - return false; - } - else - { - int lightLevel = this.worldObj.getBlockLightValue(myX, myY, myZ); - - if (this.worldObj.isThundering()) - { - int var5 = this.worldObj.skylightSubtracted; - this.worldObj.skylightSubtracted = 10; - lightLevel = this.worldObj.getBlockLightValue(myX, myY, myZ); - this.worldObj.skylightSubtracted = var5; - } - - return lightLevel <= this.rand.nextInt(8); - } - } - - /** - * Turn this mini ghast into a boss minion - */ public void makeBossMinion() { this.wanderFactor = 0.005F; this.isMinion = true; - - this.setHealth(this.getMaxHealth()); + + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(6); + this.setHealth(6); + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + public boolean isMinion() { + return isMinion; } - - /** - * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param - * par2 - Level of Looting used to kill this mob. - */ - protected void dropFewItems(boolean par1, int par2) - { - // no loot from minions - if (!this.isMinion) - { - super.dropFewItems(par1, par2); - } - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - nbttagcompound.setBoolean("isMinion", this.isMinion); - super.writeEntityToNBT(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - if (nbttagcompound.getBoolean("isMinion")) - { - makeBossMinion(); - } - } - + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + compound.setBoolean("isMinion", this.isMinion); + super.writeEntityToNBT(compound); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + if (compound.getBoolean("isMinion")) { + makeBossMinion(); + } + } + } diff --git a/src/main/java/twilightforest/entity/EntityTFMinotaur.java b/src/main/java/twilightforest/entity/EntityTFMinotaur.java index c249489fc8..0768a9b736 100644 --- a/src/main/java/twilightforest/entity/EntityTFMinotaur.java +++ b/src/main/java/twilightforest/entity/EntityTFMinotaur.java @@ -2,224 +2,150 @@ import net.minecraft.block.Block; import net.minecraft.entity.Entity; +import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFChargeAttack; +import twilightforest.entity.boss.EntityTFMinoshroom; import twilightforest.item.TFItems; public class EntityTFMinotaur extends EntityMob implements ITFCharger { - - public EntityTFMinotaur(World par1World) { - super(par1World); - //this.texture = TwilightForestMod.MODEL_DIR + "minotaur.png"; - //this.moveSpeed = 0.25F; - + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/minotaur"); + private static final DataParameter CHARGING = EntityDataManager.createKey(EntityTFMinotaur.class, DataSerializers.BOOLEAN); + + public EntityTFMinotaur(World world) { + super(world); + } + + @Override + protected void initEntityAI() { this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(2, new EntityAITFChargeAttack(this, 2.0F)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAITFChargeAttack(this, 2.0F, this instanceof EntityTFMinoshroom)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(7, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, false)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(CHARGING, false); + } + + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) { + IEntityLivingData data = super.onInitialSpawn(difficulty, livingdata); + this.setEquipmentBasedOnDifficulty(difficulty); + this.setEnchantmentBasedOnDifficulty(difficulty); + return data; + } + + @Override + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + int random = this.rand.nextInt(10); + + float additionalDiff = difficulty.getAdditionalDifficulty() + 1; + + int result = (int) (random / additionalDiff); + + if (result == 0) + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.minotaur_axe_gold)); + else + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_AXE)); + } + + @Override + public boolean isCharging() { + return dataManager.get(CHARGING); + } - this.setCurrentItemOrArmor(0, new ItemStack(Items.golden_axe)); + @Override + public void setCharging(boolean flag) { + dataManager.set(CHARGING, flag); } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(7.0D); // attack damage - } - + public boolean attackEntityAsMob(Entity entity) { + boolean success = super.attackEntityAsMob(entity); + if (success && this.isCharging()) { + entity.motionY += 0.4; + playSound(SoundEvents.ENTITY_IRONGOLEM_ATTACK, 1.0F, 1.0F); + } + return success; + } @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(17, Byte.valueOf((byte)0)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - public boolean isCharging() - { - return dataWatcher.getWatchableObjectByte(17) != 0; - } - - public void setCharging(boolean flag) - { - if (flag) - { - dataWatcher.updateObject(17, Byte.valueOf((byte)127)); - } - else - { - dataWatcher.updateObject(17, Byte.valueOf((byte)0)); - } - } - - public boolean attackEntityAsMob(Entity par1Entity) - { - boolean success = super.attackEntityAsMob(par1Entity); - - if (success && this.isCharging()) - { - par1Entity.motionY += 0.4000000059604645D; - this.worldObj.playSoundAtEntity(this, "mob.irongolem.throw", 1.0F, 1.0F); - } - - return success; - } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - super.onLivingUpdate(); - - //when charging, move legs fast - if (isCharging()) - { + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (isCharging()) { this.limbSwingAmount += 0.6; - } - - } - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return "mob.cow.say"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return "mob.cow.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return "mob.cow.hurt"; - } - - /** - * Plays step sound at given x, y, z for the entity - */ - @Override - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - this.worldObj.playSoundAtEntity(this, "mob.cow.step", 0.15F, 0.8F); - } - - /** - * Gets the pitch of living sounds in living entities. - */ - @Override - protected float getSoundPitch() - { - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.7F; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - @Override - protected Item getDropItem() - { - return TFItems.meefRaw; - } - - /** - * Drop 0-2 items of this living's type - */ - @Override - protected void dropFewItems(boolean par1, int par2) - { - int numDrops = this.rand.nextInt(2) + this.rand.nextInt(1 + par2); - - for (int i = 0; i < numDrops; ++i) - { - if (this.isBurning()) - { - this.dropItem(TFItems.meefSteak, 1); - } - else - { - this.dropItem(TFItems.meefRaw, 1); - } - } - } - - @Override - protected void dropRareDrop(int par1) - { - this.dropItem(TFItems.mazeMapFocus, 1); - } - - -// /** -// * Initialize this creature. -// */ -// @Override -// public void initCreature() -// { -// //this.func_82164_bB(); -// this.func_82162_bC(); -// } - - /** - * Trigger achievement when killed - */ - @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } - } + } + } + + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.ENTITY_COW_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_COW_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_COW_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, Block block) { + playSound(SoundEvents.ENTITY_COW_STEP, 0.15F, 0.8F); + } + + @Override + protected float getSoundPitch() { + return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.7F; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFMistWolf.java b/src/main/java/twilightforest/entity/EntityTFMistWolf.java index 0d34aa214a..0901c781dd 100644 --- a/src/main/java/twilightforest/entity/EntityTFMistWolf.java +++ b/src/main/java/twilightforest/entity/EntityTFMistWolf.java @@ -3,83 +3,67 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.potion.Potion; +import net.minecraft.init.MobEffects; +import net.minecraft.item.EnumDyeColor; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.DamageSource; -import net.minecraft.world.EnumDifficulty; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; public class EntityTFMistWolf extends EntityTFHostileWolf { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/mist_wolf"); public EntityTFMistWolf(World world) { super(world); - this.setSize(1.4F, 1.9F); - - //this.texture = TwilightForestMod.MODEL_DIR + "mistwolf.png"; + this.setSize(1.4F, 1.9F); + setCollarColor(EnumDyeColor.GRAY); } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - } + protected void setAttributes() { + super.setAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6); + } + + @Override + public boolean attackEntityAsMob(Entity entity) { + if (super.attackEntityAsMob(entity)) { + float myBrightness = this.getBrightness(); - /** - * Returns the amount of damage a mob should deal. - */ - public int getAttackStrength(Entity par1Entity) - { - return 6; - } - - public boolean attackEntityAsMob(Entity par1Entity) - { - int damage = this.getAttackStrength(par1Entity); - if (par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), damage)) - { - float myBrightness = this.getBrightness(1.0F); - - //System.out.println("Biting and brightness is " + myBrightness); + if (entity instanceof EntityLivingBase && myBrightness < 0.10F) { + int effectDuration; + switch (world.getDifficulty()) { + case EASY: + effectDuration = 0; + break; + default: + case NORMAL: + effectDuration = 7; + break; + case HARD: + effectDuration = 15; + break; + } - if (par1Entity instanceof EntityLivingBase && myBrightness < 0.10F) - { - byte effectDuration = 0; + if (effectDuration > 0) { + ((EntityLivingBase) entity).addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, effectDuration * 20, 0)); + } + } - if (this.worldObj.difficultySetting != EnumDifficulty.EASY) - { - if (this.worldObj.difficultySetting == EnumDifficulty.NORMAL) - { - effectDuration = 7; - } - else if (this.worldObj.difficultySetting == EnumDifficulty.HARD) - { - effectDuration = 15; - } - } + return true; + } else { + return false; + } + } - if (effectDuration > 0) - { - ((EntityLivingBase)par1Entity).addPotionEffect(new PotionEffect(Potion.blindness.id, effectDuration * 20, 0)); - } - } + @Override + protected float getSoundPitch() { + return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.6F; + } - return true; - } - else - { - return false; - } - } - - /** - * Gets the pitch of living sounds in living entities. - */ - protected float getSoundPitch() - { - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.6F; - } + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFMoonwormShot.java b/src/main/java/twilightforest/entity/EntityTFMoonwormShot.java index 26cd8280d3..707d361c75 100644 --- a/src/main/java/twilightforest/entity/EntityTFMoonwormShot.java +++ b/src/main/java/twilightforest/entity/EntityTFMoonwormShot.java @@ -1,72 +1,49 @@ package twilightforest.entity; import net.minecraft.block.Block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.RayTraceResult.Type; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.block.TFBlocks; -import twilightforest.item.TFItems; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +public class EntityTFMoonwormShot extends EntityTFThrowable { -public class EntityTFMoonwormShot extends EntityThrowable { - - public EntityTFMoonwormShot(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); - // TODO Auto-generated constructor stub - } - - public EntityTFMoonwormShot(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); - // TODO Auto-generated constructor stub + public EntityTFMoonwormShot(World world) { + super(world); } - public EntityTFMoonwormShot(World par1World) { - super(par1World); - // TODO Auto-generated constructor stub + public EntityTFMoonwormShot(World world, EntityLivingBase thrower) { + super(world, thrower); + shoot(thrower, thrower.rotationPitch, thrower.rotationYaw, 0F, 1.5F, 1.0F); } - - /** - * projectile speed - */ - protected float func_40077_c() - { - return 0.5F; - } - - @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - /** - * Gets how bright this entity is. - */ + @Override - public float getBrightness(float par1) - { - return 1.0F; - } + public float getBrightness() { + return 1.0F; + } @Override - @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float par1) - { - return 15728880; - } + @SideOnly(Side.CLIENT) + public int getBrightnessForRender() { + return 15728880; + } - - public void makeTrail() { + private void makeTrail() { // for (int i = 0; i < 5; i++) { // double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); // double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); @@ -76,70 +53,58 @@ public void makeTrail() { // double s2 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.80F; // double s3 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.69F; // -// worldObj.spawnParticle("mobSpell", dx, dy, dz, s1, s2, s3); +// world.spawnParticle("mobSpell", dx, dy, dz, s1, s2, s3); // } } - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - @Override - public boolean canBeCollidedWith() - { - return true; - } - - /** - * We need to set this so that the player can attack and reflect the bolt - */ - @Override - public float getCollisionBorderSize() - { - return 1.0F; - } - - /** - * How much this entity falls each tick - */ @Override - protected float getGravityVelocity() - { - return 0.03F; - } + public boolean canBeCollidedWith() { + return true; + } @Override - protected void onImpact(MovingObjectPosition mop) { - - // did we hit a block? Make a worm there! - - if (mop.typeOfHit == MovingObjectType.BLOCK) - { - if (!worldObj.isRemote) - { - TFItems.moonwormQueen.onItemUse(null, (EntityPlayer)this.getThrower(), this.worldObj, mop.blockX, mop.blockY, mop.blockZ, mop.sideHit, 0, 0, 0); - } - else - { - //particles - + public float getCollisionBorderSize() { + return 1.0F; + } + + @Override + protected float getGravityVelocity() { + return 0.03F; + } + + @SideOnly(Side.CLIENT) + @Override + public void handleStatusUpdate(byte id) { + if (id == 3) { + int stateId = Block.getStateId(TFBlocks.moonworm.getDefaultState()); + for (int i = 0; i < 8; ++i) { + this.world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D, stateId); } + } else { + super.handleStatusUpdate(id); } - - if (mop.entityHit != null) - { - mop.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0); - } - - for (int var3 = 0; var3 < 8; ++var3) - { - this.worldObj.spawnParticle("blockcrack_" + Block.getIdFromBlock(TFBlocks.moonworm) + "_0", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); - } - - if (!this.worldObj.isRemote) - { - this.setDead(); - } } + @Override + protected void onImpact(RayTraceResult ray) { + if (!world.isRemote) { + if (ray.typeOfHit == Type.BLOCK) { + + BlockPos pos = ray.getBlockPos().offset(ray.sideHit); + IBlockState currentState = world.getBlockState(pos); + if (currentState.getBlock().isReplaceable(world, pos)) { + world.setBlockState(pos, TFBlocks.moonworm.getDefaultState().withProperty(BlockDirectional.FACING, ray.sideHit)); + // todo sound + } + } + + if (ray.entityHit != null) { + ray.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0); + } + + this.world.setEntityState(this, (byte) 3); + this.setDead(); + } + } } diff --git a/src/main/java/twilightforest/entity/EntityTFMosquitoSwarm.java b/src/main/java/twilightforest/entity/EntityTFMosquitoSwarm.java index 668057aa24..09ff97c057 100644 --- a/src/main/java/twilightforest/entity/EntityTFMosquitoSwarm.java +++ b/src/main/java/twilightforest/entity/EntityTFMosquitoSwarm.java @@ -3,144 +3,100 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.potion.Potion; +import net.minecraft.init.MobEffects; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.world.EnumDifficulty; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; public class EntityTFMosquitoSwarm extends EntityMob { - public EntityTFMosquitoSwarm(World par1World) { - super(par1World); + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/mosquito_swarm"); - setSize(.7F, 1.9F); - this.stepHeight = 2.1f; - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - } + public EntityTFMosquitoSwarm(World world) { + super(world); + setSize(.7F, 1.9F); + this.stepHeight = 2.1f; + } - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(12.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D); // attack damage - } - - - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.mosquito.mosquito"; - } - - - /** - * Like cave spiders, but we add the hunger effect - */ - public boolean attackEntityAsMob(Entity par1Entity) - { - if (super.attackEntityAsMob(par1Entity)) - { - if (par1Entity instanceof EntityLivingBase) - { - byte duration = 7; + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } - if (this.worldObj.difficultySetting != EnumDifficulty.EASY) - { - if (this.worldObj.difficultySetting == EnumDifficulty.NORMAL) - { - duration = 15; - } - else if (this.worldObj.difficultySetting == EnumDifficulty.HARD) - { - duration = 30; - } - } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(12.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0D); + } - if (duration > 0) - { - ((EntityLivingBase)par1Entity).addPotionEffect(new PotionEffect(Potion.hunger.id, duration * 20, 0)); - } - } + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.MOSQUITO; + } - return true; - } - else - { - return false; - } - } + @Override + public boolean attackEntityAsMob(Entity entity) { + if (super.attackEntityAsMob(entity)) { + if (entity instanceof EntityLivingBase) { + int duration; + switch (world.getDifficulty()) { + case EASY: + duration = 7; + break; + default: + case NORMAL: + duration = 15; + break; + case HARD: + duration = 30; + break; + } + + ((EntityLivingBase) entity).addPotionEffect(new PotionEffect(MobEffects.HUNGER, duration * 20, 0)); + } + + return true; + } else { + return false; + } + } - - - /** - * We're allowed to spawn in bright light only in swamps - */ @Override - public boolean getCanSpawnHere() - { - // are we in the swamp - if (worldObj.getBiomeGenForCoords(MathHelper.floor_double(posX), MathHelper.floor_double(posZ)) == TFBiomeBase.tfSwamp) { + public boolean getCanSpawnHere() { + if (world.getBiome(new BlockPos(this)) == TFBiomes.tfSwamp) { // don't check light level - return worldObj.checkNoEntityCollision(boundingBox) && worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0; - } - else { - // normal EntityMob spawn check, checks light level + return world.checkNoEntityCollision(getEntityBoundingBox()) && world.getCollisionBoxes(this, getEntityBoundingBox()).size() == 0; + } else { return super.getCanSpawnHere(); } - } - - /** - * Will return how many at most can spawn in a chunk at once. - */ - @Override - public int getMaxSpawnedInChunk() - { - // we are solitary creatures - return 1; - } + } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + public int getMaxSpawnedInChunk() { + return 1; } + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFNatureBolt.java b/src/main/java/twilightforest/entity/EntityTFNatureBolt.java index a5d6eb73d3..44d2ee3b26 100644 --- a/src/main/java/twilightforest/entity/EntityTFNatureBolt.java +++ b/src/main/java/twilightforest/entity/EntityTFNatureBolt.java @@ -1,140 +1,99 @@ package twilightforest.entity; import net.minecraft.block.Block; +import net.minecraft.block.BlockOldLeaf; +import net.minecraft.block.BlockPlanks; import net.minecraft.block.material.Material; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Blocks; import net.minecraft.init.Items; +import net.minecraft.init.MobEffects; +import net.minecraft.item.ItemDye; import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +public class EntityTFNatureBolt extends EntityTFThrowable implements ITFProjectile { -public class EntityTFNatureBolt extends EntityThrowable { - - - - private EntityPlayer playerTarget; - - public EntityTFNatureBolt(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); + public EntityTFNatureBolt(World world) { + super(world); } - public EntityTFNatureBolt(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); + public EntityTFNatureBolt(World world, EntityLivingBase thrower) { + super(world, thrower); } - public EntityTFNatureBolt(World par1World) { - super(par1World); - } - - @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - /** - * How much this entity falls each tick - */ + @Override - protected float getGravityVelocity() - { + protected float getGravityVelocity() { return 0.003F; - } - - /** - * Make sparkly trail - */ - public void makeTrail() { + } + + private void makeTrail() { for (int i = 0; i < 5; i++) { - double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); - worldObj.spawnParticle("happyVillager", dx, dy, dz, 0.0D, 0.0D, 0.0D); + double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); + world.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, dx, dy, dz, 0.0D, 0.0D, 0.0D); } } - /** - * What happens when we hit something? - */ + @SideOnly(Side.CLIENT) @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - // only damage living things - if (par1MovingObjectPosition.entityHit != null && par1MovingObjectPosition.entityHit instanceof EntityLivingBase) - { - if (par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeIndirectMagicDamage(this, this.getThrower()), 2)) - { - // similar to EntityCaveSpider - byte poisonStrength = (byte) (worldObj.difficultySetting == EnumDifficulty.PEACEFUL ? 0 : worldObj.difficultySetting == EnumDifficulty.NORMAL ? 3 : 7); - if(poisonStrength > 0) - { - ((EntityLivingBase)par1MovingObjectPosition.entityHit).addPotionEffect(new PotionEffect(Potion.poison.id, poisonStrength * 20, 0)); - -// System.out.println("Poisoning entityHit " + par1MovingObjectPosition.entityHit); - } - + public void handleStatusUpdate(byte id) { + if (id == 3) { + int stateId = Block.getStateId(Blocks.LEAVES.getDefaultState()); + for (int i = 0; i < 8; ++i) { + this.world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D, stateId); } + } else { + super.handleStatusUpdate(id); } + } - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("blockcrack_" + Block.getIdFromBlock(Blocks.leaves) + "_0", this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D); - } - - if (!this.worldObj.isRemote) - { - this.setDead(); - - if (par1MovingObjectPosition != null) { - // if we hit a solid block, maybe do our nature burst effect. - int dx = MathHelper.floor_double(par1MovingObjectPosition.blockX); - int dy = MathHelper.floor_double(par1MovingObjectPosition.blockY); - int dz = MathHelper.floor_double(par1MovingObjectPosition.blockZ); + @Override + protected void onImpact(RayTraceResult ray) { + if (!this.world.isRemote) { + if (ray.getBlockPos() != null) { + Material materialHit = world.getBlockState(ray.getBlockPos()).getMaterial(); + + if (materialHit == Material.GRASS) { + ItemStack dummy = new ItemStack(Items.DYE, 1, 15); + if (ItemDye.applyBonemeal(dummy, world, ray.getBlockPos())) { + world.playEvent(2005, ray.getBlockPos(), 0); + } + } else if (materialHit.isSolid() && canReplaceBlock(world, ray.getBlockPos())) { + world.setBlockState(ray.getBlockPos(), Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.BIRCH)); + } + } - Material materialHit = worldObj.getBlock(dx, dy, dz).getMaterial(); - - if (materialHit == Material.grass && this.playerTarget != null) - { - Items.dye.onItemUse(new ItemStack(Items.dye, 1, 15), playerTarget, worldObj, dx, dy, dz, 0, 0, 0, 0); - } - else if (materialHit.isSolid() && canReplaceBlock(worldObj, dx, dy, dz)) - { - worldObj.setBlock(dx, dy, dz, Blocks.leaves, 2, 3); - } + if (ray.entityHit instanceof EntityLivingBase && (thrower == null || (ray.entityHit != thrower && ray.entityHit != thrower.getRidingEntity()))) { + if (ray.entityHit.attackEntityFrom(DamageSource.causeIndirectMagicDamage(this, this.getThrower()), 2) + && world.getDifficulty() != EnumDifficulty.PEACEFUL) { + int poisonTime = world.getDifficulty() == EnumDifficulty.HARD ? 7 : 3; + ((EntityLivingBase) ray.entityHit).addPotionEffect(new PotionEffect(MobEffects.POISON, poisonTime * 20, 0)); + } } - } + this.world.setEntityState(this, (byte) 3); + this.setDead(); + } } - /** - * This is surprisingly difficult to determine - */ - private boolean canReplaceBlock(World worldObj, int dx, int dy, int dz) - { - Block blockID = worldObj.getBlock(dx, dy, dz); - //int meta = worldObj.getBlockMetadata(dx, dy, dz); - Block blockObj = blockID; - float hardness = blockObj == null ? -1 : blockObj.getBlockHardness(worldObj, dx, dy, dz); - + private boolean canReplaceBlock(World world, BlockPos pos) { + float hardness = world.getBlockState(pos).getBlockHardness(world, pos); return hardness >= 0 && hardness < 50F; } - - public void setTarget(EntityLivingBase attackTarget) - { - if (attackTarget instanceof EntityPlayer) - { - this.playerTarget = (EntityPlayer)attackTarget; - } - } - } diff --git a/src/main/java/twilightforest/entity/EntityTFPinchBeetle.java b/src/main/java/twilightforest/entity/EntityTFPinchBeetle.java index 9e303449a0..2e8891ee93 100644 --- a/src/main/java/twilightforest/entity/EntityTFPinchBeetle.java +++ b/src/main/java/twilightforest/entity/EntityTFPinchBeetle.java @@ -2,287 +2,143 @@ import net.minecraft.block.Block; import net.minecraft.entity.Entity; -import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; -import net.minecraft.util.Vec3; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFChargeAttack; -import twilightforest.entity.ai.EntityAITFKidnapRider; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class EntityTFPinchBeetle extends EntityMob -{ +public class EntityTFPinchBeetle extends EntityMob implements IHostileMount { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/pinch_beetle"); + public EntityTFPinchBeetle(World world) { super(world); - //texture = TwilightForestMod.MODEL_DIR + "pinchbeetle.png"; - //moveSpeed = 0.23F; setSize(1.2F, 1.1F); + } + @Override + protected void initEntityAI() { this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAITFKidnapRider(this, 2.0F)); - this.tasks.addTask(2, new EntityAITFChargeAttack(this, 2.0F)); - this.tasks.addTask(4, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAITFChargeAttack(this, 2.0F, false)); + this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - //this.tasks.addTask(8, new EntityAILookIdle(this)); + this.tasks.addTask(8, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4.0D); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(2.0D); + } - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_SPIDER_HURT; + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(40.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D); // attack damage - } + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_SPIDER_DEATH; + } - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - @Override - public int getTotalArmorValue() - { - int var1 = super.getTotalArmorValue() + 2; + @Override + protected void playStepSound(BlockPos pos, Block block) { + playSound(SoundEvents.ENTITY_SPIDER_STEP, 0.15F, 1.0F); + } - if (var1 > 20) - { - var1 = 20; - } + @Override + public void onLivingUpdate() { + if (!this.getPassengers().isEmpty()) { + this.setSize(1.9F, 2.0F); - return var1; - } - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return null; - } + if (this.getPassengers().get(0).isSneaking()) { + this.getPassengers().get(0).setSneaking(false); + } + } else { + this.setSize(1.2F, 1.1F); - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return "mob.spider.say"; - } + } - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return "mob.spider.death"; - } + super.onLivingUpdate(); - /** - * Plays step sound at given x, y, z for the entity - */ - @Override - protected void func_145780_a(int var1, int var2, int var3, Block var4) - { - this.worldObj.playSoundAtEntity(this, "mob.spider.step", 0.15F, 1.0F); - } + if (!this.getPassengers().isEmpty()) { + this.getLookHelper().setLookPositionWithEntity(getPassengers().get(0), 100F, 100F); - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - if (this.riddenByEntity != null) - { - this.setSize(1.9F, 2.0F); - - // stop player sneaking so that they can't dismount! - if (this.riddenByEntity.isSneaking()) - { - //System.out.println("Pinch beetle sneaking detected!"); - - this.riddenByEntity.setSneaking(false); - } - } - else - { - this.setSize(1.2F, 1.1F); + // push out of user in wall + Vec3d riderPos = this.getRiderPosition(); + this.pushOutOfBlocks(riderPos.x, riderPos.y, riderPos.z); + } + } - } - - super.onLivingUpdate(); + @Override + public boolean attackEntityAsMob(Entity entity) { + if (this.getPassengers().isEmpty() && !entity.isRiding()) { + entity.startRiding(this); + } - // look at things in our jaws - if (this.riddenByEntity != null) - { - this.getLookHelper().setLookPositionWithEntity(riddenByEntity, 100F, 100F); - //this.faceEntity(riddenByEntity, 100F, 100F); + return super.attackEntityAsMob(entity); + } - - // push out of user in wall - Vec3 riderPos = this.getRiderPosition(); - this.func_145771_j(riderPos.xCoord, riderPos.yCoord, riderPos.zCoord); // push out of block - + @Override + public float getEyeHeight() { + return 0.25F; + } - } - } - - /** - * Trigger achievement when killed - */ - @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } - } + @Override + public void updatePassenger(Entity passenger) { + if (!this.getPassengers().isEmpty()) { + Vec3d riderPos = this.getRiderPosition(); - /** - * Attack strength - */ - public int getAttackStrength(Entity par1Entity) - { - return 8; - } + this.getPassengers().get(0).setPosition(riderPos.x, riderPos.y, riderPos.z); + } + } @Override - @SideOnly(Side.CLIENT) - public float getShadowSize() - { - return 1.1F; - } - - /** - * Pick up things we attack! - */ - @Override - public boolean attackEntityAsMob(Entity par1Entity) - { - if (this.riddenByEntity == null && par1Entity.ridingEntity == null) - { - par1Entity.mountEntity(this); - } - - return super.attackEntityAsMob(par1Entity); + public double getMountedYOffset() { + return 0.75D; } + private Vec3d getRiderPosition() { + if (!this.getPassengers().isEmpty()) { + float distance = 0.9F; - /** - * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. - */ - @Override - public boolean interact(EntityPlayer par1EntityPlayer) - { - if (super.interact(par1EntityPlayer)) - { - return true; - } -// else if (!this.worldObj.isRemote && (this.riddenByEntity == null || this.riddenByEntity == par1EntityPlayer)) -// { -// par1EntityPlayer.mountEntity(this); -// return true; -// } - else - { - return false; - } - } - - @Override - public float getEyeHeight() { - return 0.25F; - } + double dx = Math.cos((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; + double dz = Math.sin((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; - /** - * Get this Entity's EnumCreatureAttribute - */ - @Override - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.ARTHROPOD; - } - - /** - * Put the player out in front of where we are - */ - @Override - public void updateRiderPosition() - { - if (this.riddenByEntity != null) - { - Vec3 riderPos = this.getRiderPosition(); - - this.riddenByEntity.setPosition(riderPos.xCoord, riderPos.yCoord, riderPos.zCoord); - } - } - - /** - * Returns the Y offset from the entity's position for any entity riding this one. - */ - @Override - public double getMountedYOffset() - { - return 0.75D; - } - - /** - * Used to both get a rider position and to push out of blocks - */ - public Vec3 getRiderPosition() - { - if (this.riddenByEntity != null) - { - float distance = 0.9F; + return new Vec3d(this.posX + dx, this.posY + this.getMountedYOffset() + this.getPassengers().get(0).getYOffset(), this.posZ + dz); + } else { + return new Vec3d(this.posX, this.posY, this.posZ); + } + } - double var1 = Math.cos((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; - double var3 = Math.sin((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; + @Override + public boolean canRiderInteract() { + return true; + } - return Vec3.createVectorHelper(this.posX + var1, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3); - } - else - { - return Vec3.createVectorHelper(this.posX, this.posY, this.posZ); - } - } - - /** - * If a rider of this entity can interact with this entity. Should return true on the - * ridden entity if so. - * - * @return if the entity can be interacted with from a rider - */ - public boolean canRiderInteract() - { - return true; - } + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFProtectionBox.java b/src/main/java/twilightforest/entity/EntityTFProtectionBox.java index 7f2b9122d8..3ae88b3526 100644 --- a/src/main/java/twilightforest/entity/EntityTFProtectionBox.java +++ b/src/main/java/twilightforest/entity/EntityTFProtectionBox.java @@ -3,85 +3,77 @@ import net.minecraft.entity.Entity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; public class EntityTFProtectionBox extends Entity { - public int lifeTime; - public int sizeX; - public int sizeY; - public int sizeZ; - - public EntityTFProtectionBox(World worldObj, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - super(worldObj); - - this.setLocationAndAngles(minX, minY, minZ, 0.0F, 0.0F); - - sizeX = Math.abs(maxX - minX) + 1; - sizeY = Math.abs(maxY - minY) + 1; - sizeZ = Math.abs(maxZ - minZ) + 1; - - this.setSize(Math.max(sizeX, sizeZ), sizeY); - - this.lifeTime = 60; - - //System.out.println("Made new box"); + public int lifeTime = 60; + + public final int sizeX; + public final int sizeY; + public final int sizeZ; + + private final StructureBoundingBox sbb; + + public EntityTFProtectionBox(World world, StructureBoundingBox sbb) { + super(world); + + this.sbb = new StructureBoundingBox(sbb); + + this.setLocationAndAngles(sbb.minX, sbb.minY, sbb.minZ, 0.0F, 0.0F); + sizeX = sbb.getXSize(); + sizeY = sbb.getYSize(); + sizeZ = sbb.getZSize(); + + this.setSize(Math.max(sizeX, sizeZ), sizeY); } - @Override - public void onUpdate() - { - super.onUpdate(); - - if (lifeTime <= 1) { - setDead(); - } else { - lifeTime--; - } - - } - - /** - * Gets how bright this entity is. - */ - public float getBrightness(float par1) - { - return 1.0F; - } - - @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float par1) - { - return 15728880; - } - @Override - protected void entityInit() { - // TODO Auto-generated method stub - + public void onUpdate() { + super.onUpdate(); + + if (lifeTime <= 1) { + setDead(); + } else { + lifeTime--; + } + } + + public boolean matches(StructureBoundingBox sbb) { + return this.sbb.minX == sbb.minX && this.sbb.minY == sbb.minY && this.sbb.minZ == sbb.minZ + && this.sbb.maxX == sbb.maxX && this.sbb.maxY == sbb.maxY && this.sbb.maxZ == sbb.maxZ; + } + + public void resetLifetime() { + lifeTime = 60; } @Override - protected void readEntityFromNBT(NBTTagCompound var1) { - // TODO Auto-generated method stub - + public float getBrightness() { + return 1.0F; } + @SideOnly(Side.CLIENT) @Override - protected void writeEntityToNBT(NBTTagCompound var1) { - // TODO Auto-generated method stub - + public int getBrightnessForRender() { + return 15728880; } - - /** - * Return whether this entity should be rendered as on fire. - */ - @SideOnly(Side.CLIENT) - public boolean canRenderOnFire() - { - return false; - } + @Override + protected void entityInit() {} + + @Override + protected void readEntityFromNBT(NBTTagCompound compound) {} + + @Override + protected void writeEntityToNBT(NBTTagCompound compound) {} + + @SideOnly(Side.CLIENT) + @Override + public boolean canRenderOnFire() { + return false; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFRedcap.java b/src/main/java/twilightforest/entity/EntityTFRedcap.java index 6e742ae8c0..a71a405334 100644 --- a/src/main/java/twilightforest/entity/EntityTFRedcap.java +++ b/src/main/java/twilightforest/entity/EntityTFRedcap.java @@ -1,176 +1,124 @@ package twilightforest.entity; +import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIAvoidEntity; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.item.EntityTNTPrimed; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.TFFeature; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFRedcapLightTNT; import twilightforest.entity.ai.EntityAITFRedcapShy; - public class EntityTFRedcap extends EntityMob { - - - public static ItemStack heldPick = new ItemStack(Items.iron_pickaxe, 1); - public static ItemStack heldTNT = new ItemStack(Blocks.tnt, 1); - public static ItemStack heldFlint = new ItemStack(Items.flint_and_steel, 1); - - private boolean shy; - - private int tntLeft = 0; - - public EntityTFRedcap(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "redcap.png"; - //moveSpeed = 0.28F; - setSize(0.9F, 1.4F); - - shy = true; - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIAvoidEntity(this, EntityTNTPrimed.class, 2.0F, 1.0F, 2.0F)); + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/redcap"); + + public ItemStack heldPick = new ItemStack(Items.IRON_PICKAXE, 1); + public ItemStack heldTNT = new ItemStack(Blocks.TNT, 1); + public ItemStack heldFlint = new ItemStack(Items.FLINT_AND_STEEL, 1); + + public EntityTFRedcap(World world) { + super(world); + setSize(0.9F, 1.4F); + } + + public EntityTFRedcap(World world, double x, double y, double z) { + this(world); + this.setPosition(x, y, z); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAvoidEntity<>(this, EntityTNTPrimed.class, 2.0F, 1.0F, 2.0F)); this.tasks.addTask(2, new EntityAITFRedcapShy(this, 1.0F)); this.tasks.addTask(3, new EntityAITFRedcapLightTNT(this, 1.0F)); // light TNT - this.tasks.addTask(5, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(7, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - this.setCurrentItemOrArmor(0, heldPick); - this.setCurrentItemOrArmor(1, new ItemStack(Items.iron_boots)); - - this.equipmentDropChances[0] = 0.2F; - this.equipmentDropChances[1] = 0.2F; - - } - - public EntityTFRedcap(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ + this.tasks.addTask(5, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + } + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.REDCAP_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.REDCAP_HURT; + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.redcap.redcap"; - } - - @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.redcap.hurt"; - } - - @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.redcap.die"; - } - - @Override - protected Item getDropItem() - { - return Items.coal; - } - - public boolean isShy() - { - return shy && this.recentlyHit <= 0; - } - - public int getTntLeft() { - return tntLeft; + protected SoundEvent getDeathSound() { + return TFSounds.REDCAP_DEATH; } - public void setTntLeft(int tntLeft) { - this.tntLeft = tntLeft; + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; } - - public ItemStack getPick() - { - return heldPick; + + public boolean isShy() { + return this.recentlyHit <= 0; } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ + @Override - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setInteger("TNTLeft", this.getTntLeft()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) { + IEntityLivingData data = super.onInitialSpawn(difficulty, livingdata); + + this.setEquipmentBasedOnDifficulty(difficulty); + this.setEnchantmentBasedOnDifficulty(difficulty); + + this.setDropChance(EntityEquipmentSlot.MAINHAND, 0.2F); + this.setDropChance(EntityEquipmentSlot.FEET, 0.2F); + + return data; + } + @Override - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setTntLeft(par1NBTTagCompound.getInteger("TNTLeft")); - } - - /** - * Trigger achievement when killed - */ + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, heldPick); + this.setItemStackToSlot(EntityEquipmentSlot.FEET, new ItemStack(Items.IRON_BOOTS)); + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - // are we in a level 1 hill? - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hill1) { - // award level 1 hill cheevo - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHill1); - } - - } + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setInteger("TNTLeft", heldTNT.getCount()); } + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + heldTNT.setCount(compound.getInteger("TNTLeft")); + } } diff --git a/src/main/java/twilightforest/entity/EntityTFRedcapSapper.java b/src/main/java/twilightforest/entity/EntityTFRedcapSapper.java index 522f7ee9ab..d144d53a7d 100644 --- a/src/main/java/twilightforest/entity/EntityTFRedcapSapper.java +++ b/src/main/java/twilightforest/entity/EntityTFRedcapSapper.java @@ -1,81 +1,46 @@ package twilightforest.entity; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFRedcapPlantTNT; import twilightforest.item.TFItems; public class EntityTFRedcapSapper extends EntityTFRedcap { - + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/redcap_sapper"); public EntityTFRedcapSapper(World world) { super(world); - - this.tasks.addTask(4, new EntityAITFRedcapPlantTNT(this)); // plant TNT - - //texture = TwilightForestMod.MODEL_DIR + "redcapsapper.png"; - - this.setTntLeft(3); - - this.setCurrentItemOrArmor(1, new ItemStack(TFItems.ironwoodBoots)); - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.ironwoodPick, 1)); + this.heldPick = new ItemStack(TFItems.ironwood_pickaxe); + this.heldTNT.setCount(3); } - - /** - * Set monster attributes - */ - @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - } - - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - @Override - public int getTotalArmorValue() - { - int var1 = super.getTotalArmorValue() + 2; - if (var1 > 20) - { - var1 = 20; - } + @Override + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + super.setEquipmentBasedOnDifficulty(difficulty); + this.setItemStackToSlot(EntityEquipmentSlot.FEET, new ItemStack(TFItems.ironwood_boots)); + } - return var1; - } - - @Override - public ItemStack getPick() - { - return new ItemStack(TFItems.ironwoodPick); + protected void initEntityAI() { + super.initEntityAI(); + this.tasks.addTask(4, new EntityAITFRedcapPlantTNT(this)); } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - // are we in a level 2 hill? - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hill2) { - // award level 2 hill cheevo - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHill2); - } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(2.0D); + } - } + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; } } diff --git a/src/main/java/twilightforest/entity/EntityTFRisingZombie.java b/src/main/java/twilightforest/entity/EntityTFRisingZombie.java new file mode 100644 index 0000000000..87fffb82e9 --- /dev/null +++ b/src/main/java/twilightforest/entity/EntityTFRisingZombie.java @@ -0,0 +1,60 @@ +package twilightforest.entity; + +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.World; + +import javax.annotation.Nullable; + +public class EntityTFRisingZombie extends EntityZombie { + + public EntityTFRisingZombie(World worldIn) { + super(worldIn); + } + + @Override + protected void initEntityAI() { + // NO-OP + } + + @Nullable + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) { + // NO-OP + return livingdata; + } + + @Override + public void onLivingUpdate() { + motionX = 0; + motionY = 0; + motionZ = 0; + super.onLivingUpdate(); + if (!world.isRemote && ticksExisted % 130 == 0) { + setDead(); + EntityZombie zombie = new EntityZombie(world); + zombie.setPositionAndUpdate(posX, posY, posZ); + zombie.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(getMaxHealth()); + zombie.setHealth(getHealth()); + zombie.setChild(isChild()); + world.spawnEntity(zombie); + if (rand.nextBoolean() && world.getBlockState(getPosition().down()).getBlock() == Blocks.GRASS) + world.setBlockState(getPosition().down(), Blocks.DIRT.getDefaultState()); + } + if (world.isRemote && !world.isAirBlock(getPosition().down())) { + for (int i = 0; i < 5; i++) + world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, posX + rand.nextGaussian() * 0.01F, posY + rand.nextGaussian() * 0.01F, posZ + rand.nextGaussian() * 0.01F, 0, 0, 0, Block.getStateId(world.getBlockState(getPosition().down()))); + } + } + + @Override + public void knockBack(Entity entityIn, float strength, double xRatio, double zRatio) { + //NO-OP + } +} diff --git a/src/main/java/twilightforest/entity/EntityTFRovingCube.java b/src/main/java/twilightforest/entity/EntityTFRovingCube.java index 80caee1885..fd43251250 100644 --- a/src/main/java/twilightforest/entity/EntityTFRovingCube.java +++ b/src/main/java/twilightforest/entity/EntityTFRovingCube.java @@ -1,15 +1,17 @@ package twilightforest.entity; -import twilightforest.TwilightForestMod; -import twilightforest.entity.ai.EntityAICubeCenterOnSymbol; -import twilightforest.entity.ai.EntityAICubeMoveToRedstoneSymbols; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.monster.EntityMob; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; +import twilightforest.entity.ai.EntityAICubeCenterOnSymbol; +import twilightforest.entity.ai.EntityAICubeMoveToRedstoneSymbols; + +public class EntityTFRovingCube extends EntityMob { -public class EntityTFRovingCube extends EntityMob { - + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/roving_cube"); // data needed for cube AI // last circle visited @@ -24,48 +26,40 @@ public class EntityTFRovingCube extends EntityMob { public EntityTFRovingCube(World world) { super(world); - setSize(1.2F, 2.1F); - - this.tasks.addTask(0, new EntityAICubeMoveToRedstoneSymbols(this, 1.0D)); - this.tasks.addTask(1, new EntityAICubeCenterOnSymbol(this, 1.0D)); - + setSize(1.2F, 2.1F); } - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5.0D); + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAICubeMoveToRedstoneSymbols(this, 1.0D)); + this.tasks.addTask(1, new EntityAICubeCenterOnSymbol(this, 1.0D)); } - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(5.0D); } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - // make annihilation particles - for (int i = 0; i < 3; i++) { - float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.75F; - float py = this.getEyeHeight() - 0.25F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.75F; - float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.75F; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "annihilate", this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); - } + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); - } + if (this.world.isRemote) { + for (int i = 0; i < 3; i++) { + float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.75F; + float py = this.getEyeHeight() - 0.25F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.75F; + float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.75F; + TwilightForestMod.proxy.spawnParticle(TFParticleType.ANNIHILATE, this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); + } + } + } + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFSkeletonDruid.java b/src/main/java/twilightforest/entity/EntityTFSkeletonDruid.java index f77c08a3ec..4ae275090d 100644 --- a/src/main/java/twilightforest/entity/EntityTFSkeletonDruid.java +++ b/src/main/java/twilightforest/entity/EntityTFSkeletonDruid.java @@ -1,199 +1,102 @@ - package twilightforest.entity; -import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.EnumCreatureAttribute; -import net.minecraft.entity.IRangedAttackMob; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIArrowAttack; -import net.minecraft.entity.ai.EntityAIFleeSun; -import net.minecraft.entity.ai.EntityAIHurtByTarget; -import net.minecraft.entity.ai.EntityAILookIdle; -import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.EntityAIRestrictSun; -import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; -import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.monster.EntityMob; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.ai.EntityAIAttackRanged; +import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.item.TFItems; - +import twilightforest.TwilightForestMod; +public class EntityTFSkeletonDruid extends EntitySkeleton { -public class EntityTFSkeletonDruid extends EntityMob implements IRangedAttackMob -{ + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/skeleton_druid"); - public EntityTFSkeletonDruid(World world) - { + public EntityTFSkeletonDruid(World world) { super(world); - //texture = TwilightForestMod.MODEL_DIR + "skeletondruid.png"; - - //this.moveSpeed = 0.25F; - this.tasks.addTask(1, new EntityAISwimming(this)); - this.tasks.addTask(2, new EntityAIRestrictSun(this)); - this.tasks.addTask(3, new EntityAIFleeSun(this, 1.0D)); - this.tasks.addTask(4, new EntityAIArrowAttack(this, 1.0D, 60, 10.0F)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(6, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - this.setCurrentItemOrArmor(0, new ItemStack(Items.golden_hoe)); - } - /** - * Returns true if the newer Entity AI code should be run - */ @Override - public boolean isAIEnabled() - { - return true; + protected void initEntityAI() { + super.initEntityAI(); + this.tasks.addTask(4, new EntityAIAttackRanged(this, 1.25D, 20, 10.0F) { + @Override + public void startExecuting() { + super.startExecuting(); + setSwingingArms(true); + } + + @Override + public void resetTask() { + super.resetTask(); + setSwingingArms(false); + } + }); } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); // movement speed - } - - /** - * Returns the sound this mob makes while it's alive. - */ - protected String getLivingSound() - { - return "mob.skeleton.say"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return "mob.skeleton.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return "mob.skeleton.death"; - } - - /** - * Plays step sound at given x, y, z for the entity - */ - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - this.playSound("mob.skeleton.step", 0.15F, 1.0F); - } - - @Override - protected Item getDropItem() - { - return TFItems.torchberries; - } - - /** - * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param - * par2 - Level of Looting used to kill this mob. - */ - protected void dropFewItems(boolean par1, int lootingModifier) - { - int numberOfItemsToDrop; - int i; - - numberOfItemsToDrop = this.rand.nextInt(3 + lootingModifier); - - for (i = 0; i < numberOfItemsToDrop; ++i) - { - this.dropItem(TFItems.torchberries, 1); - } - - numberOfItemsToDrop = this.rand.nextInt(3 + lootingModifier); - - for (i = 0; i < numberOfItemsToDrop; ++i) - { - this.dropItem(Items.bone, 1); - } - } - - /** - * Get this Entity's EnumCreatureAttribute - */ - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.UNDEAD; - } + public void setCombatTask() { + if (!(this.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof ItemHoe)) { + super.setCombatTask(); + } + } + @Override + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_HOE)); + } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + public ResourceLocation getLootTable() { + return LOOT_TABLE; } - /** - * Attack the specified entity using a ranged attack. - */ @Override public void attackEntityWithRangedAttack(EntityLivingBase attackTarget, float extraDamage) { - EntityTFNatureBolt natureBolt = new EntityTFNatureBolt(this.worldObj, this); - this.worldObj.playSoundAtEntity(this, "mob.ghast.fireball", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); - - natureBolt.setTarget(attackTarget); - - double tx = attackTarget.posX - this.posX; - double ty = attackTarget.posY + attackTarget.getEyeHeight() - 2.699999988079071D - this.posY; - double tz = attackTarget.posZ - this.posZ; - float heightOffset = MathHelper.sqrt_double(tx * tx + tz * tz) * 0.2F; - natureBolt.setThrowableHeading(tx, ty + heightOffset, tz, 0.6F, 6.0F); // 0.6 speed, 6.0 inaccuracy - this.worldObj.spawnEntityInWorld(natureBolt); - + if (this.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof ItemHoe) { + EntityTFNatureBolt natureBolt = new EntityTFNatureBolt(this.world, this); + playSound(SoundEvents.ENTITY_GHAST_SHOOT, 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); + + double tx = attackTarget.posX - this.posX; + double ty = attackTarget.posY + attackTarget.getEyeHeight() - 2.699999988079071D - this.posY; + double tz = attackTarget.posZ - this.posZ; + float heightOffset = MathHelper.sqrt(tx * tx + tz * tz) * 0.2F; + natureBolt.shoot(tx, ty + heightOffset, tz, 0.6F, 6.0F); + this.world.spawnEntity(natureBolt); + } else { + super.attackEntityWithRangedAttack(attackTarget, extraDamage); + } } - - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ - protected boolean isValidLightLevel() - { - boolean valid = false; - int dx = MathHelper.floor_double(this.posX); - int dy = MathHelper.floor_double(this.boundingBox.minY); - int dz = MathHelper.floor_double(this.posZ); - - if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, dx, dy, dz) > this.rand.nextInt(32)) - { - valid = false; - } - else - { - int light = this.worldObj.getBlockLightValue(dx, dy, dz); - - valid = light <= this.rand.nextInt(12); - } - return valid; - } + // [VanillaCopy] of super. Edits noted. + @Override + protected boolean isValidLightLevel() { + BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ); + + if (this.world.getLightFor(EnumSkyBlock.SKY, blockpos) > this.rand.nextInt(32)) { + return false; + } else { + int i = this.world.getLightFromNeighbors(blockpos); + + // TF - no thunder check + /*if (this.world.isThundering()) + { + int j = this.world.getSkylightSubtracted(); + this.world.setSkylightSubtracted(10); + i = this.world.getLightFromNeighbors(blockpos); + this.world.setSkylightSubtracted(j); + }*/ + + return i <= this.rand.nextInt(12); // TF - rand(8) -> rand(12) + } + } } diff --git a/src/main/java/twilightforest/entity/EntityTFSlideBlock.java b/src/main/java/twilightforest/entity/EntityTFSlideBlock.java index 9b1ce1392b..f1c94036a7 100644 --- a/src/main/java/twilightforest/entity/EntityTFSlideBlock.java +++ b/src/main/java/twilightforest/entity/EntityTFSlideBlock.java @@ -1,384 +1,250 @@ package twilightforest.entity; import io.netty.buffer.ByteBuf; - -import java.util.Iterator; -import java.util.List; - -import twilightforest.TwilightForestMod; -import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; -import net.minecraft.block.BlockFalling; -import net.minecraft.block.ITileEntityProvider; +import net.minecraft.block.BlockRotatedPillar; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityFallingBlock; -import net.minecraft.init.Blocks; +import net.minecraft.entity.MoverType; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFSounds; + +import javax.annotation.Nonnull; +import java.util.List; public class EntityTFSlideBlock extends Entity implements IEntityAdditionalSpawnData { private static final int WARMUP_TIME = 20; - private Block myBlock; - private int myMeta; - private short slideTime; - private boolean canDropItem = true; - - float moveX; - float moveY; - float moveZ; - + private static final DataParameter MOVE_DIRECTION = EntityDataManager.createKey(EntityTFSlideBlock.class, DataSerializers.FACING); + + private IBlockState myState; + private int slideTime; + public EntityTFSlideBlock(World world) { super(world); - this.preventEntitySpawning = true; - this.entityCollisionReduction = 1F; - this.setSize(0.98F, 0.98F); - //this.yOffset = this.height / 2.0F; + this.preventEntitySpawning = true; + this.entityCollisionReduction = 1F; + this.setSize(0.98F, 0.98F); + //this.yOffset = this.height / 2.0F; } - - public EntityTFSlideBlock(World world, double x, double y, double z, Block block, int meta) { + public EntityTFSlideBlock(World world, double x, double y, double z, IBlockState state) { super(world); - this.myBlock = block; - this.myMeta = meta; - this.preventEntitySpawning = true; - this.entityCollisionReduction = 1F; - this.setSize(0.98F, 0.98F); - //this.yOffset = this.height / 2.0F; - this.setPosition(x, y, z); - this.motionX = 0.0D; - this.motionY = 0.0D; - this.motionZ = 0.0D; - this.prevPosX = x; - this.prevPosY = y; - this.prevPosZ = z; - - this.determineMoveDirection(); + this.myState = state; + this.preventEntitySpawning = true; + this.entityCollisionReduction = 1F; + this.setSize(0.98F, 0.98F); + //this.yOffset = this.height / 2.0F; + this.setPosition(x, y, z); + this.motionX = 0.0D; + this.motionY = 0.0D; + this.motionZ = 0.0D; + this.prevPosX = x; + this.prevPosY = y; + this.prevPosZ = z; + + this.determineMoveDirection(); } - /** - * Called when creating the entity to determine which direction the block will slide. The logic here is a little tricky - */ private void determineMoveDirection() { - this.moveX = 0F; - this.moveY = 0F; - this.moveZ = 0F; - - int bx = MathHelper.floor_double(this.posX); - int by = MathHelper.floor_double(this.posY); - int bz = MathHelper.floor_double(this.posZ); - - if ((this.myMeta & 12) == 4) { - // horizontal blocks will go up or down if there is a block on one side and air on the other - if (!this.worldObj.isAirBlock(bx, by + 1, bz) && this.worldObj.isAirBlock(bx, by - 1, bz)) { - this.moveY = -1F; - } else if (!this.worldObj.isAirBlock(bx, by - 1, bz) && this.worldObj.isAirBlock(bx, by + 1, bz)) { - this.moveY = 1F; - } else if (!this.worldObj.isAirBlock(bx, by, bz + 1) && this.worldObj.isAirBlock(bx, by, bz - 1)) { // then try Z - this.moveZ = -1F; - } else if (!this.worldObj.isAirBlock(bx, by, bz - 1) && this.worldObj.isAirBlock(bx, by, bz + 1)) { - this.moveZ = 1F; - } else if (this.worldObj.isAirBlock(bx, by - 1, bz)) { // if no wall, travel towards open air - this.moveY = -1F; - } else if (this.worldObj.isAirBlock(bx, by + 1, bz)) { - this.moveY = 1F; - } else if (this.worldObj.isAirBlock(bx, by, bz - 1)) { - this.moveZ = -1F; - } else if (this.worldObj.isAirBlock(bx, by, bz + 1)) { - this.moveZ = 1F; - } - } else if ((this.myMeta & 12) == 8) { - // horizontal blocks will go up or down if there is a block on one side and air on the other - if (!this.worldObj.isAirBlock(bx, by + 1, bz) && this.worldObj.isAirBlock(bx, by - 1, bz)) { - this.moveY = -1F; - } else if (!this.worldObj.isAirBlock(bx, by - 1, bz) && this.worldObj.isAirBlock(bx, by + 1, bz)) { - this.moveY = 1F; - } else if (!this.worldObj.isAirBlock(bx + 1, by, bz) && this.worldObj.isAirBlock(bx - 1, by, bz)) { // then try X - this.moveX = -1F; - } else if (!this.worldObj.isAirBlock(bx - 1, by, bz) && this.worldObj.isAirBlock(bx + 1, by, bz)) { - this.moveX = 1F; - } else if (this.worldObj.isAirBlock(bx, by - 1, bz)) { // if no wall, travel towards open air - this.moveY = -1F; - } else if (this.worldObj.isAirBlock(bx, by + 1, bz)) { - this.moveY = 1F; - } else if (this.worldObj.isAirBlock(bx - 1, by, bz)) { - this.moveX = -1F; - } else if (this.worldObj.isAirBlock(bx + 1, by, bz)) { - this.moveX = 1F; - } - } else if ((this.myMeta & 12) == 0) { - // vertical blocks priority is -x, +x, -z, +z - if (!this.worldObj.isAirBlock(bx + 1, by, bz) && this.worldObj.isAirBlock(bx - 1, by, bz)) { - this.moveX = -1F; - } else if (!this.worldObj.isAirBlock(bx - 1, by, bz) && this.worldObj.isAirBlock(bx + 1, by, bz)) { - this.moveX = 1F; - } else if (!this.worldObj.isAirBlock(bx, by, bz + 1) && this.worldObj.isAirBlock(bx, by, bz - 1)) { - this.moveZ = -1F; - } else if (!this.worldObj.isAirBlock(bx, by, bz - 1) && this.worldObj.isAirBlock(bx, by, bz + 1)) { - this.moveZ = 1F; - } else if (this.worldObj.isAirBlock(bx - 1, by, bz)) { // if no wall, travel towards open air - this.moveX = -1F; - } else if (this.worldObj.isAirBlock(bx + 1, by, bz)) { - this.moveX = 1F; - } else if (this.worldObj.isAirBlock(bx, by, bz - 1)) { - this.moveZ = -1F; - } else if (this.worldObj.isAirBlock(bx, by, bz + 1)) { - this.moveZ = 1F; - } - - } + BlockPos pos = new BlockPos(this); + + EnumFacing[] toCheck; + + switch (myState.getValue(BlockRotatedPillar.AXIS)) { + case X: // horizontal blocks will go up or down if there is a block on one side and air on the other + toCheck = new EnumFacing[]{EnumFacing.DOWN, EnumFacing.UP, EnumFacing.NORTH, EnumFacing.SOUTH}; + break; + case Z: // horizontal blocks will go up or down if there is a block on one side and air on the other + toCheck = new EnumFacing[]{EnumFacing.DOWN, EnumFacing.UP, EnumFacing.WEST, EnumFacing.EAST}; + break; + default: + case Y: // vertical blocks priority is -x, +x, -z, +z + toCheck = new EnumFacing[]{EnumFacing.WEST, EnumFacing.EAST, EnumFacing.NORTH, EnumFacing.SOUTH}; + break; + } + + for (EnumFacing e : toCheck) { + if (world.isAirBlock(pos.offset(e)) && !world.isAirBlock(pos.offset(e.getOpposite()))) { + dataManager.set(MOVE_DIRECTION, e); + return; + } + } + + // if no wall, travel towards open air + for (EnumFacing e : toCheck) { + if (world.isAirBlock(pos.offset(e))) { + dataManager.set(MOVE_DIRECTION, e); + return; + } + } + } + @Override + protected void entityInit() { + dataManager.register(MOVE_DIRECTION, EnumFacing.DOWN); } + @Override + protected boolean canTriggerWalking() { + return false; + } + + @Override + public boolean canBeCollidedWith() { + return !this.isDead; + } @Override - protected void entityInit() { } - - /** - * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to - * prevent them from trampling crops - */ - protected boolean canTriggerWalking() - { - return false; - } - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - public boolean canBeCollidedWith() - { - return !this.isDead; - } - - - - @SideOnly(Side.CLIENT) - public float getShadowSize() - { - return 0.0F; - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - if (this.myBlock == null || this.myBlock.getMaterial() == Material.air) - { - this.setDead(); - } - else - { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - ++this.slideTime; - // start moving after warmup - if (this.slideTime > WARMUP_TIME) { - this.motionX += this.moveX * 0.03999999910593033D; - this.motionY += this.moveY * 0.03999999910593033D; - this.motionZ += this.moveZ * 0.03999999910593033D; - this.moveEntity(this.motionX, this.motionY, this.motionZ); - } - this.motionX *= 0.9800000190734863D; - this.motionY *= 0.9800000190734863D; - this.motionZ *= 0.9800000190734863D; - - // sound - if (this.slideTime % 5 == 0) { - this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, TwilightForestMod.ID + ":random.slider", 1.0F, 0.9F + (this.rand.nextFloat() * 0.4F)); - } - - - if (!this.worldObj.isRemote) - { - int bx = MathHelper.floor_double(this.posX); - int by = MathHelper.floor_double(this.posY); - int bz = MathHelper.floor_double(this.posZ); - - if (this.slideTime == 1) - { - if (this.worldObj.getBlock(bx, by, bz) != this.myBlock) - { - this.setDead(); - return; - } - - this.worldObj.setBlockToAir(bx, by, bz); - } - - // if we have not hit anything after 2 seconds of movement, reverse direction - if (this.slideTime == WARMUP_TIME + 40) { - this.motionX = 0; - this.motionY = 0; - this.motionZ = 0; - - this.moveX *= -1F; - this.moveY *= -1F; - this.moveZ *= -1F; - } - - //System.out.println("Status! onGround = " + this.onGround + ", isCollided = " + this.isCollided + ", hv = " + this.isCollidedHorizontally + ", " + this.isCollidedVertically); - - if (this.isCollided || this.isStopped()) - { - this.motionX *= 0.699999988079071D; - this.motionZ *= 0.699999988079071D; - this.motionY *= 0.699999988079071D; - - this.setDead(); - - if (this.worldObj.canPlaceEntityOnSide(this.myBlock, bx, by, bz, true, 1, (Entity)null, (ItemStack)null) && this.worldObj.setBlock(bx, by, bz, this.myBlock, this.myMeta, 3)) - { - // successfully set block - } - else if (this.canDropItem ) - { - this.entityDropItem(new ItemStack(this.myBlock, 1, this.myBlock.damageDropped(this.myMeta)), 0.0F); - } - } - else if (this.slideTime > 100 && !this.worldObj.isRemote && (by < 1 || by > 256) || this.slideTime > 600) - { - if (this.canDropItem) - { - this.entityDropItem(new ItemStack(this.myBlock, 1, this.myBlock.damageDropped(this.myMeta)), 0.0F); - } - - this.setDead(); - } - - // push things out and damage them - this.damageKnockbackEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox), this); - } - } - } - - /** - * Pushes all entities inside the list out and damages them - */ - private void damageKnockbackEntities(List par1List, Entity me) - { - for (Entity entity : par1List) - { - if (entity instanceof EntityLivingBase) - { - entity.attackEntityFrom(DamageSource.generic, 5); - - double kx = (this.posX - entity.posX) * 2.0; - double kz = (this.posZ - entity.posZ) * 2.0; - - ((EntityLivingBase) entity).knockBack(this, 5, kx, kz); - } - } - } - - /** - * Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be - * pushable on contact, like boats or minecarts. - */ - public AxisAlignedBB getCollisionBox(Entity p_70114_1_) - { - return null; - } - - private boolean isStopped() { - return this.moveX == 0 && this.moveY == 0 && this.moveZ == 0; + public void onUpdate() { + if (this.myState == null || this.myState.getMaterial() == Material.AIR) { + this.setDead(); + } else { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + ++this.slideTime; + // start moving after warmup + if (this.slideTime > WARMUP_TIME) { + final double moveAcceleration = 0.04; + EnumFacing moveDirection = dataManager.get(MOVE_DIRECTION); + this.motionX += moveDirection.getXOffset() * moveAcceleration; + this.motionY += moveDirection.getYOffset() * moveAcceleration; + this.motionZ += moveDirection.getZOffset() * moveAcceleration; + this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ); + } + this.motionX *= 0.98; + this.motionY *= 0.98; + this.motionZ *= 0.98; + + if (!this.world.isRemote) { + if (this.slideTime % 5 == 0) { + playSound(TFSounds.SLIDER, 1.0F, 0.9F + (this.rand.nextFloat() * 0.4F)); + } + + BlockPos pos = new BlockPos(this); + + if (this.slideTime == 1) { + if (this.world.getBlockState(pos) != this.myState) { + this.setDead(); + return; + } + + this.world.setBlockToAir(pos); + } + + if (this.slideTime == WARMUP_TIME + 40) { + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; + + dataManager.set(MOVE_DIRECTION, dataManager.get(MOVE_DIRECTION).getOpposite()); + } + + if (this.collided) { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= 0.699999988079071D; + + this.setDead(); + + if (this.world.mayPlace(myState.getBlock(), pos, true, EnumFacing.UP, null)) { + world.setBlockState(pos, myState); + } else { + this.entityDropItem(new ItemStack(myState.getBlock(), 1, myState.getBlock().damageDropped(myState)), 0.0F); + } + } else if (this.slideTime > 100 && (pos.getY() < 1 || pos.getY() > 256) || this.slideTime > 600) { + this.entityDropItem(new ItemStack(this.myState.getBlock(), 1, this.myState.getBlock().damageDropped(this.myState)), 0.0F); + this.setDead(); + } + + // push things out and damage them + this.damageKnockbackEntities(this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox())); + } + } } + private void damageKnockbackEntities(List entities) { + for (Entity entity : entities) { + if (entity instanceof EntityLivingBase) { + entity.attackEntityFrom(DamageSource.GENERIC, 5); - /** - * Return whether this entity should be rendered as on fire. - */ - @SideOnly(Side.CLIENT) - public boolean canRenderOnFire() - { - return false; - } + double kx = (this.posX - entity.posX) * 2.0; + double kz = (this.posZ - entity.posZ) * 2.0; + + ((EntityLivingBase) entity).knockBack(this, 2, kx, kz); + } + } + } + + @Override + public AxisAlignedBB getCollisionBox(Entity entity) { + return null; + } - @Override - protected void readEntityFromNBT(NBTTagCompound nbtTagCompound) { - this.myBlock = Block.getBlockById(nbtTagCompound.getInteger("TileID")); - this.myMeta = nbtTagCompound.getByte("Meta"); - this.slideTime = nbtTagCompound.getShort("Time"); - this.moveX = nbtTagCompound.getFloat("MoveX"); - this.moveY = nbtTagCompound.getFloat("MoveY"); - this.moveZ = nbtTagCompound.getFloat("MoveZ"); - + @SideOnly(Side.CLIENT) + public boolean canRenderOnFire() { + return false; } + //Atomic: Suppressed deprecation, Ideally I'd use a state string here, but that is more work than I'm willing to put in right now. + // TODO: use NBTUtil functions + @SuppressWarnings("deprecation") @Override - protected void writeEntityToNBT(NBTTagCompound nbtTagCompound) { - nbtTagCompound.setInteger("TileID", Block.getIdFromBlock(this.myBlock)); - nbtTagCompound.setByte("Meta", (byte)this.myMeta); - nbtTagCompound.setShort("Time", this.slideTime); - nbtTagCompound.setFloat("MoveX", this.moveX); - nbtTagCompound.setFloat("MoveY", this.moveY); - nbtTagCompound.setFloat("MoveZ", this.moveZ); - } - - public Block getBlock() { - return this.myBlock; + protected void readEntityFromNBT(@Nonnull NBTTagCompound compound) { + Block b = Block.REGISTRY.getObject(new ResourceLocation(compound.getString("TileID"))); + int meta = compound.getByte("Meta"); + this.myState = b.getStateFromMeta(meta); + this.slideTime = compound.getInteger("Time"); + dataManager.set(MOVE_DIRECTION, EnumFacing.byIndex(compound.getByte("Direction"))); } - - public int getMeta() { - return this.myMeta; + + @Override + protected void writeEntityToNBT(@Nonnull NBTTagCompound compound) { + compound.setString("TileID", myState.getBlock().getRegistryName().toString()); + compound.setByte("Meta", (byte) this.myState.getBlock().getMetaFromState(myState)); + compound.setInteger("Time", this.slideTime); + compound.setByte("Direction", (byte) dataManager.get(MOVE_DIRECTION).getIndex()); } - - /** - * Called by the server when constructing the spawn packet. - * Data should be added to the provided stream. - * - * @param buffer The packet data stream - */ + @Override public void writeSpawnData(ByteBuf buffer) { - int blockData = Block.getIdFromBlock(this.myBlock) + (this.myMeta << 16); - - buffer.writeInt(blockData); - - //System.out.println("Wrote additional spawn data as " + blockData); + buffer.writeInt(Block.getStateId(myState)); } - - /** - * Called by the client when it receives a Entity spawn packet. - * Data should be read out of the stream in the same way as it was written. - * - * @param data The packet data stream - */ + @Override public void readSpawnData(ByteBuf additionalData) { - int blockData = additionalData.readInt(); - - this.myBlock = Block.getBlockById(blockData & 65535); - this.myMeta = blockData >> 16; - - //System.out.println("Read additional spawn data as " + blockData + " so my block is " + this.myBlock); + myState = Block.getStateById(additionalData.readInt()); + } + @Override + public boolean canBePushed() { + return false; } - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - public boolean isPushedByWater() - { - return false; - } + @Override + public boolean isPushedByWater() { + return false; + } + + public IBlockState getBlockState() { + return myState; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFSlimeBeetle.java b/src/main/java/twilightforest/entity/EntityTFSlimeBeetle.java index 9d59c67f42..2393b4ed5e 100644 --- a/src/main/java/twilightforest/entity/EntityTFSlimeBeetle.java +++ b/src/main/java/twilightforest/entity/EntityTFSlimeBeetle.java @@ -1,171 +1,101 @@ package twilightforest.entity; import net.minecraft.block.Block; -import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackRanged; import net.minecraft.entity.ai.EntityAIAvoidEntity; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.entity.projectile.EntityThrowable; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.entity.ai.EntityAITFMagicAttack; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; -public class EntityTFSlimeBeetle extends EntityMob -{ +public class EntityTFSlimeBeetle extends EntityMob implements IRangedAttackMob { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/slime_beetle"); public EntityTFSlimeBeetle(World world) { super(world); - //texture = TwilightForestMod.MODEL_DIR + "slimebeetle.png"; - //moveSpeed = 0.23F; setSize(0.9F, 1.75F); + } + @Override + protected void initEntityAI() { this.tasks.addTask(0, new EntityAISwimming(this)); - //this.tasks.addTask(2, new EntityAITFFireBreath(this, this.moveSpeed, 5F, 30, 0.1F)); - this.tasks.addTask(2, new EntityAIAvoidEntity(this, EntityPlayer.class, 3.0F, 1.25F, 2.0F)); - this.tasks.addTask(3, new EntityAITFMagicAttack(this, 1.0F, EntityAITFMagicAttack.SLIME, 30)); - //this.tasks.addTask(4, new EntityAIAttackOnCollide(this, EntityPlayer.class, this.moveSpeed, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAIAvoidEntity<>(this, EntityPlayer.class, 3.0F, 1.25F, 2.0F)); + this.tasks.addTask(3, new EntityAIAttackRanged(this, 1, 30, 10)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(8, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(25.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23D); // movement speed - } - - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return null; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return "mob.spider.say"; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return "mob.spider.death"; - } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(25.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4); + } - /** - * Plays step sound at given x, y, z for the entity - */ - @Override - protected void func_145780_a(int var1, int var2, int var3, Block var4) - { - this.worldObj.playSoundAtEntity(this, "mob.spider.step", 0.15F, 1.0F); - } + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_SPIDER_HURT; + } - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - super.onLivingUpdate(); + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_SPIDER_DEATH; + } -// // dribble slime particles out of mouth -// Vec3 look = this.getLookVec(); -// -// double dist = 0.9; -// double px = this.posX + look.xCoord * dist; -// double py = this.posY + 0.25 + look.yCoord * dist; -// double pz = this.posZ + look.zCoord * dist; -// -// worldObj.spawnParticle("slime", px, py, pz, 0, 0, 0); + @Override + protected void playStepSound(BlockPos pos, Block block) { + playSound(SoundEvents.ENTITY_SPIDER_STEP, 0.15F, 1.0F); + } - } - - /** - * Trigger achievement when killed - */ - @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } - } + @Override + public float getEyeHeight() { + return 0.25F; + } - /** - * Attack strength - */ - public int getAttackStrength(Entity par1Entity) - { - return 4; - } + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } @Override - @SideOnly(Side.CLIENT) - public float getShadowSize() - { - return 1.1F; + public ResourceLocation getLootTable() { + return LOOT_TABLE; } @Override - public float getEyeHeight() { - return 0.25F; + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) { + EntityThrowable projectile = new EntityTFSlimeProjectile(this.world, this); + playSound(SoundEvents.ENTITY_SMALL_SLIME_SQUISH, 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + double tx = target.posX - this.posX; + double ty = target.posY + target.getEyeHeight() - 1.100000023841858D - projectile.posY; + double tz = target.posZ - this.posZ; + float heightOffset = MathHelper.sqrt(tx * tx + tz * tz) * 0.2F; + projectile.shoot(tx, ty + heightOffset, tz, 0.6F, 6.0F); + this.world.spawnEntity(projectile); } - /** - * Get this Entity's EnumCreatureAttribute - */ - @Override - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.ARTHROPOD; - } - - @Override - protected Item getDropItem() - { - return Items.slime_ball; - } - + @Override + public void setSwingingArms(boolean swingingArms) {} } diff --git a/src/main/java/twilightforest/entity/EntityTFSlimeProjectile.java b/src/main/java/twilightforest/entity/EntityTFSlimeProjectile.java index e7fe9e235f..4e8acbaa63 100644 --- a/src/main/java/twilightforest/entity/EntityTFSlimeProjectile.java +++ b/src/main/java/twilightforest/entity/EntityTFSlimeProjectile.java @@ -1,101 +1,80 @@ package twilightforest.entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; -public class EntityTFSlimeProjectile extends EntityThrowable { +public class EntityTFSlimeProjectile extends EntityTFThrowable { - public EntityTFSlimeProjectile(World par1World) { - super(par1World); - // TODO Auto-generated constructor stub + public EntityTFSlimeProjectile(World world) { + super(world); } - public EntityTFSlimeProjectile(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); + public EntityTFSlimeProjectile(World world, EntityLivingBase thrower) { + super(world, thrower); } - + @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - /** - * How much this entity falls each tick - */ + @Override - protected float getGravityVelocity() - { + protected float getGravityVelocity() { return 0.006F; - } - - /** - * Make slimy trail - */ - public void makeTrail() { + } + + private void makeTrail() { for (int i = 0; i < 2; i++) { - double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); - worldObj.spawnParticle("slime", dx, dy, dz, 0.0D, 0.0D, 0.0D); + double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); + world.spawnParticle(EnumParticleTypes.SLIME, dx, dy, dz, 0.0D, 0.0D, 0.0D); } } - - /** - * Reflect! - */ - @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { - - setBeenAttacked(); - - pop(); - return true; - } + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + super.attackEntityFrom(source, amount); + die(); + return true; + } - /** - * What happens when we hit something? - */ + @SideOnly(Side.CLIENT) @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - // only damage living things - if (par1MovingObjectPosition.entityHit != null && par1MovingObjectPosition.entityHit instanceof EntityLivingBase) - { - if (par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 8)) - { - // damage armor? - //TODO: + public void handleStatusUpdate(byte id) { + if (id == 3) { + for (int i = 0; i < 8; ++i) { + this.world.spawnParticle(EnumParticleTypes.SLIME, this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D); } + } else { + super.handleStatusUpdate(id); } - - pop(); - } - /** - * Yeah, do that - */ - protected void pop() { - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("slime", this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D); + @Override + protected void onImpact(RayTraceResult target) { + // only damage living things + if (!world.isRemote && target.entityHit instanceof EntityLivingBase) { + target.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 8); + // TODO: damage armor? } - - // noise - this.worldObj.playSoundAtEntity(this, "mob.slime.big", 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); + die(); + } - if (!this.worldObj.isRemote) - { + private void die() { + if (!this.world.isRemote) { + this.playSound(SoundEvents.ENTITY_SLIME_SQUISH, 1.0F, 1.0F / (rand.nextFloat() * 0.4F + 0.8F)); this.setDead(); + this.world.setEntityState(this, (byte) 3); } } - } diff --git a/src/main/java/twilightforest/entity/EntityTFSnowGuardian.java b/src/main/java/twilightforest/entity/EntityTFSnowGuardian.java index b936f202c5..ba3e2f3f10 100644 --- a/src/main/java/twilightforest/entity/EntityTFSnowGuardian.java +++ b/src/main/java/twilightforest/entity/EntityTFSnowGuardian.java @@ -2,217 +2,179 @@ import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; import twilightforest.item.TFItems; -public class EntityTFSnowGuardian extends EntityMob { - - public EntityTFSnowGuardian(World par1World) { - super(par1World); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(2, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(3, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - this.setSize(0.6F, 1.8F); +public class EntityTFSnowGuardian extends EntityTFIceMob { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/snow_guardian"); + + public EntityTFSnowGuardian(World world) { + super(world); + this.setSize(0.6F, 1.8F); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(2, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(3.0D); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + } + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.ICE_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.ICE_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.ICE_DEATH; + } + + @Override + protected float getSoundPitch() { + return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.8F; + } + + @Override + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + int type = rand.nextInt(4); + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(this.makeItemForSlot(EntityEquipmentSlot.MAINHAND, type))); + this.setItemStackToSlot(EntityEquipmentSlot.CHEST, new ItemStack(this.makeItemForSlot(EntityEquipmentSlot.CHEST, type))); + this.setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(this.makeItemForSlot(EntityEquipmentSlot.HEAD, type))); } + private Item makeItemForSlot(EntityEquipmentSlot slot, int type) { + switch (slot) { + case MAINHAND: + default: + switch (type) { + case 0: + default: + return TFItems.ironwood_sword; + case 1: + return TFItems.steeleaf_sword; + case 2: + return TFItems.knightmetal_sword; + case 3: + return TFItems.knightmetal_sword; + } + case FEET: + switch (type) { + case 0: + default: + return TFItems.ironwood_boots; + case 1: + return TFItems.steeleaf_boots; + case 2: + return TFItems.knightmetal_boots; + case 3: + return TFItems.arctic_boots; + } + case LEGS: + switch (type) { + case 0: + default: + return TFItems.ironwood_leggings; + case 1: + return TFItems.steeleaf_leggings; + case 2: + return TFItems.knightmetal_leggings; + case 3: + return TFItems.arctic_leggings; + } + case CHEST: + switch (type) { + case 0: + default: + return TFItems.ironwood_chestplate; + case 1: + return TFItems.steeleaf_chestplate; + case 2: + return TFItems.knightmetal_chestplate; + case 3: + return TFItems.arctic_chestplate; + } + case HEAD: + switch (type) { + case 0: + default: + return TFItems.ironwood_helmet; + case 1: + return TFItems.steeleaf_helmet; + case 2: + return TFItems.knightmetal_helmet; + case 3: + return TFItems.arctic_helmet; + } + } + } - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D); - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.ice.noise"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.ice.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.ice.death"; - } - - /** - * Gets the pitch of living sounds in living entities. - */ - protected float getSoundPitch() - { - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.8F; - } - - /** - * Makes entity wear random armor based on difficulty - */ - protected void addRandomArmor() - { - // always random armor - - // random armor type - int type = rand.nextInt(4); - - this.setCurrentItemOrArmor(0, new ItemStack(this.makeItemForSlot(0, type))); - - this.setCurrentItemOrArmor(3, new ItemStack(this.makeItemForSlot(3, type))); - this.setCurrentItemOrArmor(4, new ItemStack(this.makeItemForSlot(4, type))); - } - - protected Item makeItemForSlot(int slot, int type) { - switch (slot) { - case 0: // sword - default: - switch (type) { - case 0: - default: - return TFItems.ironwoodSword; - case 1: - return TFItems.steeleafSword; - case 2: - return TFItems.knightlySword; - case 3: - return TFItems.knightlySword; - } - case 1: // boots - switch (type) { - case 0: - default: - return TFItems.ironwoodBoots; - case 1: - return TFItems.steeleafBoots; - case 2: - return TFItems.knightlyBoots; - case 3: - return TFItems.arcticBoots; - } - case 2: // legs - switch (type) { - case 0: - default: - return TFItems.ironwoodLegs; - case 1: - return TFItems.steeleafLegs; - case 2: - return TFItems.knightlyLegs; - case 3: - return TFItems.arcticLegs; - } - case 3: // chest - switch (type) { - case 0: - default: - return TFItems.ironwoodPlate; - case 1: - return TFItems.steeleafPlate; - case 2: - return TFItems.knightlyPlate; - case 3: - return TFItems.arcticPlate; - } - case 4: // helm - switch (type) { - case 0: - default: - return TFItems.ironwoodHelm; - case 1: - return TFItems.steeleafHelm; - case 2: - return TFItems.knightlyHelm; - case 3: - return TFItems.arcticHelm; - } - } - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return Items.snowball; - } - - /** - * Enchants the entity's armor and held item based on difficulty - */ - protected void enchantEquipment() - { - super.enchantEquipment(); - } - - public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) - { - IEntityLivingData data = super.onSpawnWithEgg(par1EntityLivingData); - - this.addRandomArmor(); - //this.enchantEquipment(); - - return data; - - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - // make snow particles - for (int i = 0; i < 3; i++) { - float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - float py = this.getEyeHeight() + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; - float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowguardian", this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); - } - - } - - /** - * Will return how many at most can spawn in a chunk at once. - */ - public int getMaxSpawnedInChunk() - { - return 8; - } + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingData) { + IEntityLivingData data = super.onInitialSpawn(difficulty, livingData); + this.setEquipmentBasedOnDifficulty(difficulty); + this.setEnchantmentBasedOnDifficulty(difficulty); + return data; + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.world.isRemote) { + for (int i = 0; i < 3; i++) { + float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; + float py = this.getEyeHeight() + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; + float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.SNOW_GUARDIAN, this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); + } + } + } + + @Override + public int getMaxSpawnedInChunk() { + return 8; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFSpikeBlock.java b/src/main/java/twilightforest/entity/EntityTFSpikeBlock.java index 7d0389a620..ac762ab992 100644 --- a/src/main/java/twilightforest/entity/EntityTFSpikeBlock.java +++ b/src/main/java/twilightforest/entity/EntityTFSpikeBlock.java @@ -6,87 +6,68 @@ import net.minecraft.world.World; public class EntityTFSpikeBlock extends Entity { - - EntityTFBlockGoblin goblin; - - public EntityTFSpikeBlock(World par1World) { - super(par1World); - setSize(0.75F, 0.75F); + + private EntityTFBlockGoblin goblin; + + public EntityTFSpikeBlock(World world) { + super(world); + setSize(0.75F, 0.75F); } public EntityTFSpikeBlock(EntityTFBlockGoblin goblin) { - this(goblin.func_82194_d()); + this(goblin.getWorld()); this.goblin = goblin; } - /** - * Don't take damage from attacks - */ @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) { + public boolean attackEntityFrom(DamageSource source, float amount) { return false; } - - /** - * Skip most of the living update things - */ - @Override - public void onUpdate() { - super.onUpdate(); - - this.ticksExisted++; - - lastTickPosX = posX; - lastTickPosY = posY; - lastTickPosZ = posZ; - - - //System.out.println("Updating " + this + " with angles " + rotationYawHead + ", " + rotationPitch); - - for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } - for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } - for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } - for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } - - } - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - public boolean canBeCollidedWith() - { - return false; - } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - public boolean isEntityEqual(Entity entity) - { - return this == entity || this.goblin == entity; - } + @Override + public void onUpdate() { + super.onUpdate(); + + this.ticksExisted++; + + lastTickPosX = posX; + lastTickPosY = posY; + lastTickPosZ = posZ; + + for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { + } + for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { + } + for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { + } + for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { + } + } @Override - protected void entityInit() { } + public boolean canBeCollidedWith() { + return false; + } @Override - protected void readEntityFromNBT(NBTTagCompound nbttagcompound) { } + public boolean canBePushed() { + return false; + } @Override - protected void writeEntityToNBT(NBTTagCompound nbttagcompound) { } - -// /** -// * Returns the texture's file path as a String. -// */ -// @Override -// public String getTexture() -// { -// return this.texture; -// } + public boolean isEntityEqual(Entity entity) { + return this == entity || this.goblin == entity; + } + + @Override + protected void entityInit() { + } + + @Override + protected void readEntityFromNBT(NBTTagCompound compound) { + } + + @Override + protected void writeEntityToNBT(NBTTagCompound compound) { + } } diff --git a/src/main/java/twilightforest/entity/EntityTFSwarmSpider.java b/src/main/java/twilightforest/entity/EntityTFSwarmSpider.java index 79dd627355..142fecd77f 100644 --- a/src/main/java/twilightforest/entity/EntityTFSwarmSpider.java +++ b/src/main/java/twilightforest/entity/EntityTFSwarmSpider.java @@ -1,83 +1,88 @@ package twilightforest.entity; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.monster.EntitySpider; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; - +import twilightforest.TwilightForestMod; public class EntityTFSwarmSpider extends EntitySpider { - + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/swarm_spider"); + protected boolean shouldSpawn = false; - + public EntityTFSwarmSpider(World world) { this(world, true); } - + public EntityTFSwarmSpider(World world, boolean spawnMore) { super(world); - + setSize(0.8F, 0.4F); setSpawnMore(spawnMore); - //texture = TwilightForestMod.MODEL_DIR + "swarmspider.png"; - experienceValue = 2; // XP value - } - - public EntityTFSwarmSpider(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - /** - * Set monster attributes - */ + experienceValue = 2; + } + + public EntityTFSwarmSpider(World world, double x, double y, double z) { + this(world); + this.setPosition(x, y, z); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(3.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(1.0D); // attack damage - } - - - /** - * How large the spider should be scaled. - */ - //@Override - public float spiderScaleAmount() - { - return 0.5F; - } - - /** - * Actually only used for the shadow - */ + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(3.0D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(1.0D); + } + + @Override + protected void initEntityAI() { + super.initEntityAI(); + + // Remove default spider melee task + this.tasks.taskEntries.removeIf(t -> t.action instanceof EntityAIAttackMelee); + + // Replace with one that doesn't become docile in light + // [VanillaCopy] based on EntitySpider.AISpiderAttack + this.tasks.addTask(4, new EntityAIAttackMelee(this, 1, true) { + @Override + protected double getAttackReachSqr(EntityLivingBase attackTarget) { + return 4.0F + attackTarget.width; + } + }); + + // Remove default spider target player task + this.targetTasks.taskEntries.removeIf(t -> t.priority == 2 && t.action instanceof EntityAINearestAttackableTarget); + // Replace with one that doesn't care about light + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + @Override public float getRenderSizeModifier() { - return 0.5F; + return 0.5F; + } + + @Override + public float getEyeHeight() { + return 0.3F; } - /** - * Spawn more if that flag is set. - */ @Override public void onUpdate() { - if (shouldSpawnMore()) { - // don't spawn if we're connected in multiplayer - if (!worldObj.isRemote) { - int more = 1 + rand.nextInt(2); - for (int i = 0; i < more; i++) { - // try twice to spawn - if (!spawnAnother()) { - spawnAnother(); - } + if (!world.isRemote && shouldSpawnMore()) { + int more = 1 + rand.nextInt(2); + for (int i = 0; i < more; i++) { + // try twice to spawn + if (!spawnAnother()) { + spawnAnother(); } } setSpawnMore(false); @@ -85,134 +90,70 @@ public void onUpdate() { super.onUpdate(); } - - /** - * Only have the spider do damage a fraction of the time - */ - protected void attackEntity(Entity entity, float f) - { - if (this.attackTime <= 0 && (!this.isAirBorne || rand.nextInt(4) != 0)) - { - this.attackTime = 20; - } - else - { - super.attackEntity(entity, f); - } - - } - - /** - * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking - * (Animals, Spiders at day, peaceful PigZombies). - */ - @Override - protected Entity findPlayerToAttack() - { - // kill at all times! - double var2 = 16.0D; - return this.worldObj.getClosestVulnerablePlayerToEntity(this, var2); - } - - /** - * Spawn another spider! - * - * @return - */ + + @Override + public boolean attackEntityAsMob(Entity entity) { + return rand.nextInt(4) == 0 && super.attackEntityAsMob(entity); + } + protected boolean spawnAnother() { - EntityTFSwarmSpider another = new EntityTFSwarmSpider(worldObj, false); + EntityTFSwarmSpider another = new EntityTFSwarmSpider(world, false); double sx = posX + (rand.nextBoolean() ? 0.9 : -0.9); double sy = posY; double sz = posZ + (rand.nextBoolean() ? 0.9 : -0.9); another.setLocationAndAngles(sx, sy, sz, rand.nextFloat() * 360F, 0.0F); - if(!another.getCanSpawnHere()) - { + if (!another.getCanSpawnHere()) { another.setDead(); return false; } - worldObj.spawnEntityInWorld(another); - + world.spawnEntity(another); + another.spawnExplosionParticle(); + return true; } - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ @Override - protected boolean isValidLightLevel() - { - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; + protected boolean isValidLightLevel() { + int chunkX = MathHelper.floor(posX) >> 4; + int chunkZ = MathHelper.floor(posZ) >> 4; // We're allowed to spawn in bright light only in hedge mazes. - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hedgeMaze) - { - return true; - } - else - { - return super.isValidLightLevel(); - } - } - - public boolean shouldSpawnMore() - { - return shouldSpawn; - } - - public void setSpawnMore(boolean flag) - { - this.shouldSpawn = flag; - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - super.writeEntityToNBT(nbttagcompound); - nbttagcompound.setBoolean("SpawnMore", shouldSpawnMore()); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - setSpawnMore(nbttagcompound.getBoolean("SpawnMore")); - } - - /** - * Trigger achievement when killed - */ + return TFFeature.getNearestFeature(chunkX, chunkZ, world) == TFFeature.HEDGE_MAZE || super.isValidLightLevel(); + } + + public boolean shouldSpawnMore() { + return shouldSpawn; + } + + public void setSpawnMore(boolean flag) { + this.shouldSpawn = flag; + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - // are we in a hedge maze? - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hedgeMaze) { - // award hedge maze cheevo - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHedge); - } - } + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("SpawnMore", shouldSpawnMore()); } - - /** - * Gets the pitch of living sounds in living entities. - */ - @Override - protected float getSoundPitch() - { - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.5F; - } - - /** - * Will return how many at most can spawn in a chunk at once. - */ - public int getMaxSpawnedInChunk() - { - return 16; - } + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + setSpawnMore(compound.getBoolean("SpawnMore")); + } + + @Override + protected float getSoundPitch() { + return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.5F; + } + + @Override + public int getMaxSpawnedInChunk() { + return 16; + } + + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFThrowable.java b/src/main/java/twilightforest/entity/EntityTFThrowable.java new file mode 100644 index 0000000000..470279d41b --- /dev/null +++ b/src/main/java/twilightforest/entity/EntityTFThrowable.java @@ -0,0 +1,28 @@ +package twilightforest.entity; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.projectile.EntityThrowable; +import net.minecraft.world.World; + +public abstract class EntityTFThrowable extends EntityThrowable implements ITFProjectile { + + public EntityTFThrowable(World worldIn) { + super(worldIn); + } + + public EntityTFThrowable(World worldIn, double x, double y, double z) { + super(worldIn, x, y, z); + } + + public EntityTFThrowable(World worldIn, EntityLivingBase throwerIn) { + super(worldIn, throwerIn); + } + + @Override + public void setThrower(Entity entity) { + if (entity instanceof EntityLivingBase) { + this.thrower = (EntityLivingBase) entity; + } + } +} diff --git a/src/main/java/twilightforest/entity/EntityTFTomeBolt.java b/src/main/java/twilightforest/entity/EntityTFTomeBolt.java index 2cb271e73b..b94cab9d94 100644 --- a/src/main/java/twilightforest/entity/EntityTFTomeBolt.java +++ b/src/main/java/twilightforest/entity/EntityTFTomeBolt.java @@ -1,95 +1,74 @@ package twilightforest.entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Items; +import net.minecraft.init.MobEffects; import net.minecraft.item.Item; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +public class EntityTFTomeBolt extends EntityTFThrowable { -public class EntityTFTomeBolt extends EntityThrowable { - - public EntityTFTomeBolt(World par1World, double par2, double par4, - double par6) { - super(par1World, par2, par4, par6); - // TODO Auto-generated constructor stub - } - - public EntityTFTomeBolt(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); - // TODO Auto-generated constructor stub + public EntityTFTomeBolt(World world, EntityLivingBase thrower) { + super(world, thrower); } - public EntityTFTomeBolt(World par1World) { - super(par1World); - // TODO Auto-generated constructor stub + public EntityTFTomeBolt(World world) { + super(world); } - @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - /** - * How much this entity falls each tick - */ + @Override - protected float getGravityVelocity() - { + protected float getGravityVelocity() { return 0.003F; - } - - /** - * Make sparkly trail - */ - public void makeTrail() { + } + + private void makeTrail() { for (int i = 0; i < 5; i++) { - double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); - worldObj.spawnParticle("crit", dx, dy, dz, 0.0D, 0.0D, 0.0D); + double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); + world.spawnParticle(EnumParticleTypes.CRIT, dx, dy, dz, 0.0D, 0.0D, 0.0D); } } - /** - * What happens when we hit something? - */ + @SideOnly(Side.CLIENT) @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - // only damage living things - if (par1MovingObjectPosition.entityHit != null && par1MovingObjectPosition.entityHit instanceof EntityLivingBase) - { - if (par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 6)) - { - // inflict move slowdown - byte potionStrength = (byte) (worldObj.difficultySetting == EnumDifficulty.PEACEFUL ? 3 : worldObj.difficultySetting == EnumDifficulty.NORMAL ? 7 : 9); - if(potionStrength > 0) - { - ((EntityLivingBase)par1MovingObjectPosition.entityHit).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, potionStrength * 20, 1)); - } - + public void handleStatusUpdate(byte id) { + if (id == 3) { + int itemId = Item.getIdFromItem(Items.PAPER); + for (int i = 0; i < 8; ++i) { + this.world.spawnParticle(EnumParticleTypes.ITEM_CRACK, this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D, itemId); } + } else { + super.handleStatusUpdate(id); } + } + @Override + protected void onImpact(RayTraceResult result) { + if (!this.world.isRemote) { + if (result.entityHit instanceof EntityLivingBase + && result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 6)) { + // inflict move slowdown + int duration = world.getDifficulty() == EnumDifficulty.PEACEFUL ? 3 : world.getDifficulty() == EnumDifficulty.NORMAL ? 7 : 9; + ((EntityLivingBase) result.entityHit).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, duration * 20, 1)); + } - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(Items.fire_charge), this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D); - } - - if (!this.worldObj.isRemote) - { + this.world.setEntityState(this, (byte) 3); this.setDead(); } - } } diff --git a/src/main/java/twilightforest/entity/EntityTFTowerBroodling.java b/src/main/java/twilightforest/entity/EntityTFTowerBroodling.java index 5a0c9f8aba..e769dfc274 100644 --- a/src/main/java/twilightforest/entity/EntityTFTowerBroodling.java +++ b/src/main/java/twilightforest/entity/EntityTFTowerBroodling.java @@ -1,10 +1,12 @@ package twilightforest.entity; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; -public class EntityTFTowerBroodling extends EntityTFSwarmSpider -{ +public class EntityTFTowerBroodling extends EntityTFSwarmSpider { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/tower_broodling"); public EntityTFTowerBroodling(World world) { this(world, true); @@ -12,41 +14,36 @@ public EntityTFTowerBroodling(World world) { public EntityTFTowerBroodling(World world, boolean spawnMore) { super(world, spawnMore); - experienceValue = 3; // XP value - //texture = TwilightForestMod.MODEL_DIR + "towerbroodling.png"; + experienceValue = 3; } - - /** - * Set monster attributes - */ + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(7.0D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(4.0D); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(7.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D); // attack damage - } - - /** - * Spawn another spider! - * - * @return - */ - protected boolean spawnAnother() - { - EntityTFSwarmSpider another = new EntityTFTowerBroodling(worldObj, false); + protected boolean spawnAnother() { + EntityTFSwarmSpider another = new EntityTFTowerBroodling(world, false); double sx = posX + (rand.nextBoolean() ? 0.9 : -0.9); double sy = posY; double sz = posZ + (rand.nextBoolean() ? 0.9 : -0.9); another.setLocationAndAngles(sx, sy, sz, rand.nextFloat() * 360F, 0.0F); - if(!another.getCanSpawnHere()) - { + if (!another.getCanSpawnHere()) { another.setDead(); return false; } - worldObj.spawnEntityInWorld(another); - + world.spawnEntity(another); + another.spawnExplosionParticle(); + return true; } + + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFTowerGhast.java b/src/main/java/twilightforest/entity/EntityTFTowerGhast.java index 577f099844..0e13a2d8b4 100644 --- a/src/main/java/twilightforest/entity/EntityTFTowerGhast.java +++ b/src/main/java/twilightforest/entity/EntityTFTowerGhast.java @@ -2,540 +2,389 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityMoveHelper; import net.minecraft.entity.monster.EntityGhast; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityLargeFireball; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.init.SoundEvents; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.entity.ai.EntityAITFFindEntityNearestPlayer; +import twilightforest.entity.boss.EntityTFUrGhast; -public class EntityTFTowerGhast extends EntityGhast -{ - - private static final int AGGRO_STATUS = 16; - protected EntityLivingBase targetedEntity; - protected boolean isAggressive; - protected int aggroCooldown; - protected int explosionPower; - protected int aggroCounter; - - protected float aggroRange; - protected float stareRange; - +import java.util.Random; + +public class EntityTFTowerGhast extends EntityGhast { + // 0 = idle, 1 = eyes open / tracking player, 2 = shooting fireball + private static final DataParameter ATTACK_STATUS = EntityDataManager.createKey(EntityTFTowerGhast.class, DataSerializers.BYTE); + private static final DataParameter ATTACK_TIMER = EntityDataManager.createKey(EntityTFTowerGhast.class, DataSerializers.BYTE); + private static final DataParameter ATTACK_PREVTIMER = EntityDataManager.createKey(EntityTFTowerGhast.class, DataSerializers.BYTE); + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/tower_ghast"); + + private AIAttack attackAI; protected float wanderFactor; - - protected int inTrapCounter; + private int inTrapCounter; - private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0); - /** If -1 there is no maximum distance */ - private float maximumHomeDistance = -1.0F; + public EntityTFTowerGhast(World world) { + super(world); + this.setSize(4.0F, 6.0F); - public EntityTFTowerGhast(World par1World) { - super(par1World); - //this.texture = TwilightForestMod.MODEL_DIR + "towerghast.png"; - - this.setSize(4.0F, 6.0F); + this.wanderFactor = 16.0F; + this.inTrapCounter = 0; + } - this.aggroRange = 64.0F; - this.stareRange = 32.0F; + @Override + protected void entityInit() { + super.entityInit(); + this.dataManager.register(ATTACK_STATUS, (byte) 0); + this.dataManager.register(ATTACK_TIMER, (byte) 0); + this.dataManager.register(ATTACK_PREVTIMER, (byte) 0); + } - this.wanderFactor = 16.0F; - - this.inTrapCounter = 0; + @Override + protected void initEntityAI() { + this.tasks.addTask(5, new AIHomedFly(this)); + if (!(this instanceof EntityTFUrGhast)) this.tasks.addTask(5, new AIRandomFly(this)); + this.tasks.addTask(7, new EntityGhast.AILookAround(this)); + this.tasks.addTask(7, attackAI = new AIAttack(this)); + this.targetTasks.addTask(1, new EntityAITFFindEntityNearestPlayer(this)); } -// -// public int getMaxHealth() -// { -// return 30; -// } - - /** - * Set monster attributes - */ + + // [VanillaCopy] from EntityGhast but we use wanderFactor instead, we also stop moving when we have a target + public static class AIRandomFly extends EntityAIBase { + private final EntityTFTowerGhast parentEntity; + + public AIRandomFly(EntityTFTowerGhast ghast) { + this.parentEntity = ghast; + this.setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + EntityMoveHelper entitymovehelper = this.parentEntity.getMoveHelper(); + if (!entitymovehelper.isUpdating()) { + return parentEntity.getAttackTarget() == null; + } else { + double d0 = entitymovehelper.getX() - this.parentEntity.posX; + double d1 = entitymovehelper.getY() - this.parentEntity.posY; + double d2 = entitymovehelper.getZ() - this.parentEntity.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + return parentEntity.getAttackTarget() == null && (d3 < 1.0D || d3 > 3600.0D); + } + } + + @Override + public boolean shouldContinueExecuting() { + return false; + } + + @Override + public void startExecuting() { + Random random = this.parentEntity.getRNG(); + double d0 = this.parentEntity.posX + (double) ((random.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + double d1 = this.parentEntity.posY + (double) ((random.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + double d2 = this.parentEntity.posZ + (double) ((random.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + this.parentEntity.getMoveHelper().setMoveTo(d0, d1, d2, 1.0D); + } + } + + // [VanillaCopy]-ish mixture of EntityGhast.AIFly and EntityAIStayNearHome + public static class AIHomedFly extends EntityAIBase { + private final EntityTFTowerGhast parentEntity; + + AIHomedFly(EntityTFTowerGhast ghast) { + this.parentEntity = ghast; + setMutexBits(1); + } + + // From AIFly, but with extra condition from AIStayNearHome + @Override + public boolean shouldExecute() { + EntityMoveHelper entitymovehelper = this.parentEntity.getMoveHelper(); + + if (!entitymovehelper.isUpdating()) { + return !this.parentEntity.isWithinHomeDistanceCurrentPosition(); + } else { + double d0 = entitymovehelper.getX() - this.parentEntity.posX; + double d1 = entitymovehelper.getY() - this.parentEntity.posY; + double d2 = entitymovehelper.getZ() - this.parentEntity.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + return (d3 < 1.0D || d3 > 3600.0D) + && !this.parentEntity.isWithinHomeDistanceCurrentPosition(); + } + } + + // From AIFly + @Override + public boolean shouldContinueExecuting() { + return false; + } + + // From AIStayNearHome but use move helper instead of PathNavigate + @Override + public void startExecuting() { + Random random = this.parentEntity.getRNG(); + double d0 = this.parentEntity.posX + (double) ((random.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + double d1 = this.parentEntity.posY + (double) ((random.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + double d2 = this.parentEntity.posZ + (double) ((random.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + this.parentEntity.getMoveHelper().setMoveTo(d0, d1, d2, 1.0D); + + if (this.parentEntity.getDistanceSq(this.parentEntity.getHomePosition()) > 256.0D) { + Vec3d vecToHome = new Vec3d(this.parentEntity.getHomePosition()).subtract(this.parentEntity.getPositionVector()).normalize(); + + double targetX = this.parentEntity.posX + vecToHome.x * parentEntity.wanderFactor + (double) ((this.parentEntity.rand.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + double targetY = this.parentEntity.posY + vecToHome.y * parentEntity.wanderFactor + (double) ((this.parentEntity.rand.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + double targetZ = this.parentEntity.posZ + vecToHome.z * parentEntity.wanderFactor + (double) ((this.parentEntity.rand.nextFloat() * 2.0F - 1.0F) * parentEntity.wanderFactor); + + this.parentEntity.getMoveHelper().setMoveTo(targetX, targetY, targetZ, 1.0D); + } else { + this.parentEntity.getMoveHelper().setMoveTo(this.parentEntity.getHomePosition().getX() + 0.5D, this.parentEntity.getHomePosition().getY(), this.parentEntity.getHomePosition().getZ() + 0.5D, 1.0D); + } + } + } + + // [VanillaCopy] EntityGhast.AIFireballAttack, edits noted + public static class AIAttack extends EntityAIBase { + private final EntityTFTowerGhast parentEntity; + public int attackTimer; + public int prevAttackTimer; // TF - add for renderer + + public AIAttack(EntityTFTowerGhast ghast) { + this.parentEntity = ghast; + } + + @Override + public boolean shouldExecute() { + return this.parentEntity.getAttackTarget() != null && parentEntity.shouldAttack(parentEntity.getAttackTarget()); + } + + @Override + public void startExecuting() { + this.attackTimer = this.prevAttackTimer = 0; + } + + @Override + public void resetTask() { + this.parentEntity.setAttacking(false); + } + + @Override + public void updateTask() { + EntityLivingBase entitylivingbase = this.parentEntity.getAttackTarget(); + + if (entitylivingbase.getDistanceSq(this.parentEntity) < 4096.0D && this.parentEntity.getEntitySenses().canSee(entitylivingbase)) { + World world = this.parentEntity.world; + this.prevAttackTimer = attackTimer; + ++this.attackTimer; + + // TF face our target at all times + this.parentEntity.getLookHelper().setLookPositionWithEntity(entitylivingbase, 10F, this.parentEntity.getVerticalFaceSpeed()); + + if (this.attackTimer == 10) { + parentEntity.playSound(SoundEvents.ENTITY_GHAST_WARN, 10.0F, parentEntity.getSoundPitch()); + } + + if (this.attackTimer == 20) { + if (this.parentEntity.shouldAttack(entitylivingbase)) { + // TF - call custom method + parentEntity.playSound(SoundEvents.ENTITY_GHAST_SHOOT, 10.0F, parentEntity.getSoundPitch()); + this.parentEntity.spitFireball(); + this.prevAttackTimer = attackTimer; + } + this.attackTimer = -40; + } + } else if (this.attackTimer > 0) { + this.prevAttackTimer = attackTimer; + --this.attackTimer; + } + + this.parentEntity.setAttacking(this.attackTimer > 10); + } + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - } - - /** - * Returns the volume for the sounds this mob makes. - */ - protected float getSoundVolume() - { - return 0.5F; - } - - /** - * Get number of ticks, at least during which the living entity will be silent. - */ - public int getTalkInterval() - { - return 160; - } - - /** - * Will return how many at most can spawn in a chunk at once. - */ - public int getMaxSpawnedInChunk() - { - return 8; - } - - @Override - public void onUpdate() - { - super.onUpdate(); - //byte aggroStatus = this.dataWatcher.getWatchableObjectByte(AGGRO_STATUS); - -// switch (aggroStatus) -// { -// case 0: -// default: -// this.texture = TwilightForestMod.MODEL_DIR + "towerghast.png"; -// break; -// case 1: -// this.texture = TwilightForestMod.MODEL_DIR + "towerghast_openeyes.png"; -// break; -// case 2: -// this.texture = TwilightForestMod.MODEL_DIR + "towerghast_fire.png"; -// break; -// } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(64.0D); + } + + @Override + protected float getSoundVolume() { + return 0.5F; + } + + @Override + public int getTalkInterval() { + return 160; + } + + @Override + public int getMaxSpawnedInChunk() { + return 8; + } + + @Override + public void onLivingUpdate() { + // age when in light, like mobs + if (getBrightness() > 0.5F) { + this.idleTime += 2; + } + + if (this.rand.nextBoolean()) { + this.world.spawnParticle(EnumParticleTypes.REDSTONE, this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, this.posY + this.rand.nextDouble() * (double) this.height - 0.25D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0, 0, 0); + } + + super.onLivingUpdate(); + } + + @Override + protected void updateAITasks() { + findHome(); + + if (this.inTrapCounter > 0) { + this.inTrapCounter--; + setAttackTarget(null); + } + + int status = getAttackTarget() != null && shouldAttack(getAttackTarget()) ? 1 : 0; + + dataManager.set(ATTACK_STATUS, (byte) status); + dataManager.set(ATTACK_TIMER, (byte) attackAI.attackTimer); + dataManager.set(ATTACK_PREVTIMER, (byte) attackAI.prevAttackTimer); + } + + public int getAttackStatus() { + return dataManager.get(ATTACK_STATUS); + } + + public int getAttackTimer() { + return dataManager.get(ATTACK_TIMER); + } + + public int getPrevAttackTimer() { + return dataManager.get(ATTACK_PREVTIMER); + } + + protected boolean shouldAttack(EntityLivingBase living) { + return true; } - - public int getAttackStatus() { - return this.dataWatcher.getWatchableObjectByte(AGGRO_STATUS); - } - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - // age when in light, like mobs - float var1 = this.getBrightness(1.0F); - - if (var1 > 0.5F) - { - this.entityAge += 2; - } - - if (this.rand.nextBoolean()) - { - this.worldObj.spawnParticle("reddust", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - 0.25D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); - } - - super.onLivingUpdate(); - } - - /** - * Altered Ghast AI - */ - protected void updateEntityActionState() - { - if (!this.worldObj.isRemote && this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL) - { - this.setDead(); - } - - this.despawnEntity(); - - // tower home - checkForTowerHome(); - - // check if in trap - if (this.inTrapCounter > 0) - { - this.inTrapCounter--; - this.targetedEntity = null; - return; // do nothing if in trap; - } - - this.prevAttackCounter = this.attackCounter; - - // target - if (this.targetedEntity != null && this.targetedEntity.isDead) - { - this.targetedEntity = null; - } - - if (this.targetedEntity == null) - { - this.targetedEntity = findPlayerInRange(); - } - else if (!this.isAggressive && this.targetedEntity instanceof EntityPlayer) - { - checkToIncreaseAggro((EntityPlayer) this.targetedEntity); - } - - // check if we are at our waypoint target - double offsetX = this.waypointX - this.posX; - double offsetY = this.waypointY - this.posY; - double offsetZ = this.waypointZ - this.posZ; - double distanceDesired = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; - - if ((distanceDesired < 1.0D || distanceDesired > 3600.0D) && this.wanderFactor > 0) - { - this.waypointX = this.posX + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * wanderFactor); - this.waypointY = this.posY + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * wanderFactor); - this.waypointZ = this.posZ + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * wanderFactor); - } - - - - // move? - if (this.targetedEntity == null && this.wanderFactor > 0) - { - if (this.courseChangeCooldown-- <= 0) - { - this.courseChangeCooldown += this.rand.nextInt(20) + 20; - distanceDesired = (double)MathHelper.sqrt_double(distanceDesired); - - if (!this.isWithinHomeDistance(MathHelper.floor_double(waypointX), MathHelper.floor_double(waypointY), MathHelper.floor_double(waypointZ))) - { - // change waypoint to be more towards home - ChunkCoordinates cc = TFFeature.getNearestCenterXYZ(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posZ), worldObj); - - Vec3 homeVector = Vec3.createVectorHelper(cc.posX - this.posX, cc.posY + 128 - this.posY, cc.posZ - this.posZ); - homeVector = homeVector.normalize(); - - this.waypointX = this.posX + homeVector.xCoord * 16.0F + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); - this.waypointY = this.posY + homeVector.yCoord * 16.0F + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); - this.waypointZ = this.posZ + homeVector.zCoord * 16.0F + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * 16.0F); - - //System.out.println("Setting tower ghast on a course towards home: " + this.waypointX + ", " + this.waypointY + ", " + this.waypointZ); - } - - - if (this.isCourseTraversable(this.waypointX, this.waypointY, this.waypointZ, distanceDesired)) - { - this.motionX += offsetX / distanceDesired * 0.1D; - this.motionY += offsetY / distanceDesired * 0.1D; - this.motionZ += offsetZ / distanceDesired * 0.1D; - } - else - { - this.waypointX = this.posX; - this.waypointY = this.posY; - this.waypointZ = this.posZ; - } - } - } - else - { - this.motionX *= 0.75; - this.motionY *= 0.75; - this.motionZ *= 0.75; - } - - // check if our target is still within range - double targetRange = (this.aggroCounter > 0 || this.isAggressive) ? aggroRange : stareRange; - - if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < targetRange * targetRange && this.canEntityBeSeen(this.targetedEntity)) - { - // turn towards target - this.faceEntity(this.targetedEntity, 10F, this.getVerticalFaceSpeed()); - - // attack if aggressive - if (this.isAggressive) - { - if (this.attackCounter == 10) - { - this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1007, (int)this.posX, (int)this.posY, (int)this.posZ, 0); - } - - ++this.attackCounter; - - if (this.attackCounter == 20) - { - spitFireball(); - this.attackCounter = -40; - } - } - } - else - { - // ignore player, move normally - this.isAggressive = false; - this.targetedEntity = null; - this.renderYawOffset = this.rotationYaw = -((float)Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float)Math.PI; - - // changing the pitch with movement looks goofy and un-ghast-like - //double dist = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); - this.rotationPitch = 0;//(float) (-((Math.atan2(this.motionY, dist) * 180D) / Math.PI));; - - } - - if (this.attackCounter > 0 && !this.isAggressive) - { - --this.attackCounter; - } - - // set aggro status - byte currentAggroStatus = this.dataWatcher.getWatchableObjectByte(AGGRO_STATUS); - byte newAggroStatus = (byte)(this.attackCounter > 10 ? 2 : (this.aggroCounter > 0 || this.isAggressive) ? 1 : 0); - - if (currentAggroStatus != newAggroStatus) - { - this.dataWatcher.updateObject(AGGRO_STATUS, Byte.valueOf(newAggroStatus)); - } - } - - /** * Something is deeply wrong with the calculations based off of this value, so let's set it high enough that it's ignored. */ @Override - public int getVerticalFaceSpeed() - { - return 500; - } - - /** - * Spit a fireball - */ + public int getVerticalFaceSpeed() { + return 500; + } + protected void spitFireball() { - double offsetX = this.targetedEntity.posX - this.posX; - double offsetY = this.targetedEntity.boundingBox.minY + (double)(this.targetedEntity.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); - double offsetZ = this.targetedEntity.posZ - this.posZ; - - // fireball sound effect - this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1008, (int)this.posX, (int)this.posY, (int)this.posZ, 0); - - - EntityLargeFireball entityFireball = new EntityLargeFireball(this.worldObj, this, offsetX, offsetY, offsetZ); - //var17.field_92012_e = this.explosionPower; - double shotSpawnDistance = 0.5D; - Vec3 lookVec = this.getLook(1.0F); - entityFireball.posX = this.posX + lookVec.xCoord * shotSpawnDistance; - entityFireball.posY = this.posY + (double)(this.height / 2.0F) + lookVec.yCoord * shotSpawnDistance; - entityFireball.posZ = this.posZ + lookVec.zCoord * shotSpawnDistance; - this.worldObj.spawnEntityInWorld(entityFireball); - + Vec3d vec3d = this.getLook(1.0F); + double d2 = getAttackTarget().posX - (this.posX + vec3d.x * 4.0D); + double d3 = getAttackTarget().getEntityBoundingBox().minY + (double) (getAttackTarget().height / 2.0F) - (0.5D + this.posY + (double) (this.height / 2.0F)); + double d4 = getAttackTarget().posZ - (this.posZ + vec3d.z * 4.0D); + EntityLargeFireball entitylargefireball = new EntityLargeFireball(world, this, d2, d3, d4); + entitylargefireball.explosionPower = this.getFireballStrength(); + entitylargefireball.posX = this.posX + vec3d.x * 4.0D; + entitylargefireball.posY = this.posY + (double) (this.height / 2.0F) + 0.5D; + entitylargefireball.posZ = this.posZ + vec3d.z * 4.0D; + world.spawnEntity(entitylargefireball); + // when we attack, there is a 1-in-6 chance we decide to stop attacking - if (rand.nextInt(6) == 0) - { - this.isAggressive = false; + if (rand.nextInt(6) == 0) { + setAttackTarget(null); } } - - /** - * Find a player in our aggro range. If we feel the need to become aggressive towards that - * player, or it is within our stare range, return - * - * @return - */ - protected EntityLivingBase findPlayerInRange() { - EntityPlayer closest = this.worldObj.getClosestVulnerablePlayerToEntity(this, aggroRange); - - if (closest != null) - { - float range = this.getDistanceToEntity(closest); - if (range < this.stareRange || this.shouldAttackPlayer(closest)) - { - return closest; - } - } - return null; + + @Override + public boolean getCanSpawnHere() { + return this.world.checkNoEntityCollision(getEntityBoundingBox()) + && this.world.getCollisionBoxes(this, getEntityBoundingBox()).isEmpty() + && !this.world.containsAnyLiquid(getEntityBoundingBox()) + && this.world.getDifficulty() != EnumDifficulty.PEACEFUL + && this.isValidLightLevel(); } - /** - * Check if we should become aggressive towards the player. - * - * @param par1EntityPlayer - */ - protected void checkToIncreaseAggro(EntityPlayer par1EntityPlayer) - { - if (this.shouldAttackPlayer(par1EntityPlayer)) - { - if (this.aggroCounter == 0) - { - this.worldObj.playSoundAtEntity(this, "mob.ghast.moan", 1.0F, 1.0F); - } - - if (this.aggroCounter++ >= 20) - { - this.aggroCounter = 0; - this.isAggressive = true; - } - } - else - { - this.aggroCounter = 0; - } - } - - - - /** - * Checks to see if this tower ghast should be attacking this player. - * Tower ghasts attack if the block above the player is not Tower wood - */ - protected boolean shouldAttackPlayer(EntityPlayer par1EntityPlayer) - { - int dx = MathHelper.floor_double(par1EntityPlayer.posX); - int dy = MathHelper.floor_double(par1EntityPlayer.posY); - int dz = MathHelper.floor_double(par1EntityPlayer.posZ); - - return worldObj.canBlockSeeTheSky(dx, dy, dz) && par1EntityPlayer.canEntityBeSeen(this); - } - - - - /** - * True if the ghast has an unobstructed line of travel to the waypoint. - */ - protected boolean isCourseTraversable(double par1, double par3, double par5, double par7) - { - double var9 = (this.waypointX - this.posX) / par7; - double var11 = (this.waypointY - this.posY) / par7; - double var13 = (this.waypointZ - this.posZ) / par7; - AxisAlignedBB var15 = this.boundingBox.copy(); - - for (int var16 = 1; (double)var16 < par7; ++var16) - { - var15.offset(var9, var11, var13); - - if (!this.worldObj.getCollidingBoundingBoxes(this, var15).isEmpty()) - { - return false; - } - } - - return true; - } - - /** - * Called when the entity is attacked. - */ - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) - { - boolean wasAttacked = super.attackEntityFrom(par1DamageSource, par2); - - if (wasAttacked && par1DamageSource.getSourceOfDamage() instanceof EntityLivingBase) - { - this.targetedEntity = (EntityLivingBase)par1DamageSource.getSourceOfDamage(); - - this.isAggressive = true; - - return true; - } - else - { - return wasAttacked; - } - } - - /** - * Checks if the entity's current position is a valid location to spawn this entity. - */ - public boolean getCanSpawnHere() - { - return this.worldObj.checkNoEntityCollision(this.boundingBox) - && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() - && !this.worldObj.isAnyLiquid(this.boundingBox) - && this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL - && this.isValidLightLevel(); - } - - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ - protected boolean isValidLightLevel() - { - return true; - } - - /** - * Check for our tower home and if we find it, set it - */ - protected void checkForTowerHome() - { - if (!this.hasHome()) - { - // check if we're near a dark forest tower and if so, set that as home - int chunkX = MathHelper.floor_double(this.posX) >> 4; - int chunkZ = MathHelper.floor_double(this.posZ) >> 4; - - TFFeature nearFeature = TFFeature.getFeatureForRegion(chunkX, chunkZ, this.worldObj); - - if (nearFeature != TFFeature.darkTower) - { - this.detachHome(); - - this.entityAge += 5; - - //System.out.println("Tower ghast is lost"); - - } - else - { - // set our home position to the center of the tower - ChunkCoordinates cc = TFFeature.getNearestCenterXYZ(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posZ), worldObj); - this.setHomeArea(cc.posX, cc.posY + 128, cc.posZ, 64); - -// System.out.println("Ghast is at " + this.posX + ", " + this.posY + ", " + this.posZ); -// System.out.println("Set home area to " + cc.posX + ", " + (cc.posY + 128) + ", " + cc.posZ); - } - } - } - - /** - * Towers are so large, a simple radius doesn't really work, so we make it more of a cylinder - */ - public boolean isWithinHomeDistance(int x, int y, int z) - { - if (this.getMaximumHomeDistance() == -1.0F) - { - return true; - } - else - { - ChunkCoordinates home = this.getHomePosition(); - -// System.out.println("Checking home for " + x + ", " + y + ", " + z + " and home is " + home.posX + ", " + home.posY + ", " + home.posZ); -// System.out.println("home.getDistanceSquared(x, home.posY, z) = " + home.getDistanceSquared(x, home.posY, z) + " compared to " + (this.getMaximumHomeDistance() * this.getMaximumHomeDistance())); - - return y > 64 && y < 210 && home.getDistanceSquared(x, home.posY, z) < this.getMaximumHomeDistance() * this.getMaximumHomeDistance(); - } - } - - public void setInTrap() - { - this.inTrapCounter = 10; - } - - public void setHomeArea(int par1, int par2, int par3, int par4) - { - this.homePosition.set(par1, par2, par3); - this.maximumHomeDistance = (float)par4; - } - - public ChunkCoordinates getHomePosition() - { - return this.homePosition; - } - - public float getMaximumHomeDistance() - { - return this.maximumHomeDistance; - } - - public void detachHome() - { - this.maximumHomeDistance = -1.0F; - } - - public boolean hasHome() - { - return this.maximumHomeDistance != -1.0F; - } + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() { + return true; + } + + private void findHome() { + if (!this.hasHome()) { + int chunkX = MathHelper.floor(this.posX) >> 4; + int chunkZ = MathHelper.floor(this.posZ) >> 4; + + TFFeature nearFeature = TFFeature.getFeatureForRegion(chunkX, chunkZ, this.world); + + if (nearFeature != TFFeature.DARK_TOWER) { + this.detachHome(); + this.idleTime += 5; + } else { + BlockPos cc = TFFeature.getNearestCenterXYZ(chunkX, chunkZ, world); + this.setHomePosAndDistance(cc.up(128), 64); + } + } + } + + public void setInTrap() { + this.inTrapCounter = 10; + } + + // [VanillaCopy] Home fields and methods from EntityCreature, changes noted + private BlockPos homePosition = BlockPos.ORIGIN; + private float maximumHomeDistance = -1.0F; + + public boolean isWithinHomeDistanceCurrentPosition() { + return this.isWithinHomeDistanceFromPosition(new BlockPos(this)); + } + + public boolean isWithinHomeDistanceFromPosition(BlockPos pos) { + // TF - restrict valid y levels + // Towers are so large, a simple radius doesn't really work, so we make it more of a cylinder + return this.maximumHomeDistance == -1.0F + ? true + : pos.getY() > 64 && pos.getY() < 210 && this.homePosition.distanceSq(pos) < (double) (this.maximumHomeDistance * this.maximumHomeDistance); + } + + public void setHomePosAndDistance(BlockPos pos, int distance) { + this.homePosition = pos; + this.maximumHomeDistance = (float) distance; + } + + public BlockPos getHomePosition() { + return this.homePosition; + } + + public float getMaximumHomeDistance() { + return this.maximumHomeDistance; + } + + public void detachHome() { + this.maximumHomeDistance = -1.0F; + } + + public boolean hasHome() { + return this.maximumHomeDistance != -1.0F; + } + // End copy + + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFTowerGolem.java b/src/main/java/twilightforest/entity/EntityTFTowerGolem.java index 2481aa0b2e..cd7c72557b 100644 --- a/src/main/java/twilightforest/entity/EntityTFTowerGolem.java +++ b/src/main/java/twilightforest/entity/EntityTFTowerGolem.java @@ -2,229 +2,137 @@ import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; -import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.util.MathHelper; +import net.minecraft.init.SoundEvents; +import net.minecraft.pathfinding.PathNodeType; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class EntityTFTowerGolem extends EntityMob -{ - - private int attackTimer; - - public EntityTFTowerGolem(World par1World) - { - super(par1World); - //this.texture = TwilightForestMod.MODEL_DIR + "carminitegolem.png"; - - this.setSize(1.4F, 2.9F); - //this.moveSpeed = 0.25F; - - - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(2, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); - this.tasks.addTask(3, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; + +public class EntityTFTowerGolem extends EntityMob { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/tower_golem"); + private int attackTimer; + + public EntityTFTowerGolem(World world) { + super(world); + this.setSize(1.4F, 2.9F); + this.setPathPriority(PathNodeType.WATER, -1.0F); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(2, new EntityAIWanderAvoidWater(this, 1.0D, 0.0F)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(9.0D); + this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(2.0D); + } + + @Override + public boolean attackEntityAsMob(Entity entity) { + this.attackTimer = 10; + this.world.setEntityState(this, (byte) 4); + boolean attackSuccess = super.attackEntityAsMob(entity); + + if (attackSuccess) { + entity.motionY += 0.4000000059604645D; + } + + return attackSuccess; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_IRONGOLEM_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_IRONGOLEM_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, Block block) { + this.playSound(SoundEvents.ENTITY_IRONGOLEM_STEP, 1.0F, 1.0F); + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (this.attackTimer > 0) { + --this.attackTimer; + } + + // [VanillaCopy] last half of EntityIronGolem.onLivingUpdate + if (this.motionX * this.motionX + this.motionZ * this.motionZ > 2.500000277905201E-7D && this.rand.nextInt(5) == 0) { + int i = MathHelper.floor(this.posX); + int j = MathHelper.floor(this.posY - 0.20000000298023224D); + int k = MathHelper.floor(this.posZ); + IBlockState iblockstate = this.world.getBlockState(new BlockPos(i, j, k)); + + if (iblockstate.getMaterial() != Material.AIR) { + this.world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, this.posX + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, this.getEntityBoundingBox().minY + 0.1D, this.posZ + ((double) this.rand.nextFloat() - 0.5D) * (double) this.width, 4.0D * ((double) this.rand.nextFloat() - 0.5D), 0.5D, ((double) this.rand.nextFloat() - 0.5D) * 4.0D, Block.getStateId(iblockstate)); + } + } + // End copy + + if (this.rand.nextBoolean()) { + this.world.spawnParticle(EnumParticleTypes.REDSTONE, this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, this.posY + this.rand.nextDouble() * (double) this.height - 0.25D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, 0, 0, 0); + } + } + + @SideOnly(Side.CLIENT) + @Override + public void handleStatusUpdate(byte id) { + if (id == 4) { + this.attackTimer = 10; + this.playSound(SoundEvents.ENTITY_IRONGOLEM_ATTACK, 1.0F, 1.0F); + } else { + super.handleStatusUpdate(id); + } + } + + public int getAttackTimer() { + return this.attackTimer; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(40.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(9.0D); // attack damage - } - - /** - * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue - */ - @Override - public int getTotalArmorValue() - { - int var1 = super.getTotalArmorValue() + 2; - - if (var1 > 20) - { - var1 = 20; - } - - return var1; - } - - public boolean attackEntityAsMob(Entity par1Entity) - { - this.attackTimer = 10; - this.worldObj.setEntityState(this, (byte)4); - boolean attackSuccess = super.attackEntityAsMob(par1Entity); - - if (attackSuccess) - { - par1Entity.motionY += 0.4000000059604645D; - } - - this.playSound("mob.irongolem.throw", 1.0F, 1.0F); - return attackSuccess; - } - - /** - * Returns the sound this mob makes while it's alive. - */ - protected String getLivingSound() - { - return "none"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return "mob.irongolem.hit"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return "mob.irongolem.death"; - } - - /** - * Plays step sound at given x, y, z for the entity - */ - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - this.playSound("mob.irongolem.walk", 1.0F, 1.0F); - } - - - protected void collideWithEntity(Entity par1Entity) - { - if (par1Entity instanceof IMob && this.getRNG().nextInt(10) == 0) - { - this.setAttackTarget((EntityLivingBase)par1Entity); - } - - super.collideWithEntity(par1Entity); - } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - - if (this.attackTimer > 0) - { - --this.attackTimer; - } - - if (this.motionX * this.motionX + this.motionZ * this.motionZ > 2.500000277905201E-7D && this.rand.nextInt(5) == 0) - { - int var1 = MathHelper.floor_double(this.posX); - int var2 = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset); - int var3 = MathHelper.floor_double(this.posZ); - Block block = this.worldObj.getBlock(var1, var2, var3); - - if (block.getMaterial() != Material.air) - { - this.worldObj.spawnParticle("blockcrack_" + Block.getIdFromBlock(block) + "_" + this.worldObj.getBlockMetadata(var1, var2, var3), this.posX + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, this.boundingBox.minY + 0.1D, this.posZ + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, 4.0D * ((double)this.rand.nextFloat() - 0.5D), 0.5D, ((double)this.rand.nextFloat() - 0.5D) * 4.0D); - } - } - - // redstone sparkles? - if (this.rand.nextBoolean()) - { - this.worldObj.spawnParticle("reddust", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - 0.25D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); - } - - } - - - @SideOnly(Side.CLIENT) - public void handleHealthUpdate(byte par1) - { - if (par1 == 4) - { - this.attackTimer = 10; - this.playSound("mob.irongolem.throw", 1.0F, 1.0F); - } - else - { - super.handleHealthUpdate(par1); - } - } - - @SideOnly(Side.CLIENT) - public int getAttackTimer() - { - return this.attackTimer; - } - - /** - * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param - * par2 - Level of Looting used to kill this mob. - */ - protected void dropFewItems(boolean par1, int par2) - { - int var4; - - var4 = this.rand.nextInt(3); - - for (int i = 0; i < var4; ++i) - { - this.dropItem(Items.iron_ingot, 1); - } - - var4 = this.rand.nextInt(3); - - for (int i = 0; i < var4; ++i) - { - this.dropItem(Item.getItemFromBlock(TFBlocks.towerWood), 1); - } - } - - /** - * Will return how many at most can spawn in a chunk at once. - */ - public int getMaxSpawnedInChunk() - { - return 16; - } + public int getMaxSpawnedInChunk() { + return 16; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFTowerTermite.java b/src/main/java/twilightforest/entity/EntityTFTowerTermite.java index 864bb34ad5..1342ef8316 100644 --- a/src/main/java/twilightforest/entity/EntityTFTowerTermite.java +++ b/src/main/java/twilightforest/entity/EntityTFTowerTermite.java @@ -1,10 +1,11 @@ package twilightforest.entity; import net.minecraft.block.Block; -import net.minecraft.entity.Entity; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; @@ -13,254 +14,240 @@ import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; import net.minecraft.util.EntityDamageSource; -import net.minecraft.util.Facing; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; +import twilightforest.TwilightForestMod; import twilightforest.block.BlockTFTowerWood; import twilightforest.block.TFBlocks; -import twilightforest.item.TFItems; - -public class EntityTFTowerTermite extends EntityMob -{ - - private int allySummonCooldown; - - public EntityTFTowerTermite(World par1World) { - super(par1World); - - //this.texture = TwilightForestMod.MODEL_DIR + "towertermite.png"; - this.setSize(0.3F, 0.7F); - //this.moveSpeed = 0.27F; - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(2, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(4, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); +import twilightforest.enums.TowerWoodVariant; + +import java.util.Random; + +public class EntityTFTowerTermite extends EntityMob { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/tower_termite"); + private AISummonSilverfish summonSilverfish; + + public EntityTFTowerTermite(World world) { + super(world); + this.setSize(0.3F, 0.7F); } - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(15.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.27D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5.0D); // attack damage - } - - /** - * returns if this entity triggers Blocks.onEntityWalking on the blocks they walk on. used for spiders and wolves to - * prevent them from trampling crops - */ - protected boolean canTriggerWalking() - { - return false; - } - - /** - * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking - * (Animals, Spiders at day, peaceful PigZombies). - */ - protected Entity findPlayerToAttack() - { - double var1 = 8.0D; - return this.worldObj.getClosestVulnerablePlayerToEntity(this, var1); - } - - /** - * Returns the sound this mob makes while it's alive. - */ - protected String getLivingSound() - { - return "mob.silverfish.say"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return "mob.silverfish.hit"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return "mob.silverfish.kill"; - } - - /** - * Called when the entity is attacked. - */ - public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) - { - if (this.isEntityInvulnerable()) - { - return false; - } - else - { - if (this.allySummonCooldown <= 0 && (par1DamageSource instanceof EntityDamageSource || par1DamageSource == DamageSource.magic)) - { - this.allySummonCooldown = 20; - } - - return super.attackEntityFrom(par1DamageSource, par2); - } - } - - protected void updateAITasks() - { - super.updateAITasks(); - - // if we are summoning allies, do that - if (this.allySummonCooldown > 0) - { - --this.allySummonCooldown; - - if (this.allySummonCooldown == 0) - { - tryToSummonAllies(); - } - } - - - // if we have no target, burrow - if (this.getAttackTarget() == null && this.getNavigator().noPath()) - { - tryToBurrow(); - } - - } - - /** - * Check nearby blocks. If they are infested blocks, pop them! - */ - protected void tryToSummonAllies() { - int sx = MathHelper.floor_double(this.posX); - int sy = MathHelper.floor_double(this.posY); - int sz = MathHelper.floor_double(this.posZ); - boolean stopSummoning = false; - - for (int dy = 0; !stopSummoning && dy <= 5 && dy >= -5; dy = dy <= 0 ? 1 - dy : 0 - dy) - { - for (int dx = 0; !stopSummoning && dx <= 10 && dx >= -10; dx = dx <= 0 ? 1 - dx : 0 - dx) - { - for (int dz = 0; !stopSummoning && dz <= 10 && dz >= -10; dz = dz <= 0 ? 1 - dz : 0 - dz) - { - Block blockID = this.worldObj.getBlock(sx + dx, sy + dy, sz + dz); - int blockMeta = this.worldObj.getBlockMetadata(sx + dx, sy + dy, sz + dz); - - if (blockID == TFBlocks.towerWood && blockMeta == BlockTFTowerWood.META_INFESTED) - { - this.worldObj.playAuxSFX(2001, sx + dx, sy + dy, sz + dz, Block.getIdFromBlock(blockID) + (blockMeta << 12)); - this.worldObj.setBlock(sx + dx, sy + dy, sz + dz, Blocks.air, 0, 3); - TFBlocks.towerWood.onBlockDestroyedByPlayer(this.worldObj, sx + dx, sy + dy, sz + dz, BlockTFTowerWood.META_INFESTED); - - if (this.rand.nextBoolean()) - { - stopSummoning = true; - break; - } - } - } - } - } + protected void initEntityAI() { + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, this.summonSilverfish = new AISummonSilverfish(this)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(4, new AIHideInStone(this)); + this.tasks.addTask(5, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(6, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); } - /** - * Look at a random nearby block. Is it the proper tower wood? If so, burrow. - */ - protected void tryToBurrow() { - int x = MathHelper.floor_double(this.posX); - int y = MathHelper.floor_double(this.posY + 0.5D); - int z = MathHelper.floor_double(this.posZ); - int randomFacing = this.rand.nextInt(6); - - x += Facing.offsetsXForSide[randomFacing]; - y += Facing.offsetsYForSide[randomFacing]; - z += Facing.offsetsZForSide[randomFacing]; - - Block blockIDNearby = this.worldObj.getBlock(x, y, z); - int blockMetaNearby = this.worldObj.getBlockMetadata(x, y, z); - - if (canBurrowIn(blockIDNearby, blockMetaNearby)) - { - this.worldObj.setBlock(x, y, z, TFBlocks.towerWood, BlockTFTowerWood.META_INFESTED, 3); - this.spawnExplosionParticle(); - this.setDead(); + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(15.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.27D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(5.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(8.0D); + } + + @Override + protected boolean canTriggerWalking() { + return false; + } + + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.ENTITY_SILVERFISH_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_SILVERFISH_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_SILVERFISH_DEATH; + } + + // [VanillaCopy] EntitySilverfish.attackEntityFrom + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + if (this.isEntityInvulnerable(source)) { + return false; + } else { + if ((source instanceof EntityDamageSource || source == DamageSource.MAGIC) && this.summonSilverfish != null) { + this.summonSilverfish.notifyHurt(); + } + + return super.attackEntityFrom(source, amount); } } - /** - * @return true if we can burrow in the specified block - */ - protected boolean canBurrowIn(Block blockIDNearby, int blockMetaNearby) - { - return blockIDNearby == TFBlocks.towerWood && blockMetaNearby == 0; + @Override + protected void playStepSound(BlockPos pos, Block block) { + this.playSound(SoundEvents.ENTITY_SILVERFISH_STEP, 0.15F, 1.0F); } - /** - * @return true if the nearby block is infested - */ - protected boolean isInfestedBlock(Block blockIDNearby, int blockMetaNearby) - { - return blockIDNearby == TFBlocks.towerWood && blockMetaNearby == BlockTFTowerWood.META_INFESTED; + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; } - /** - * Plays step sound at given x, y, z for the entity - */ - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - this.playSound("mob.silverfish.step", 0.15F, 1.0F); - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return TFItems.borerEssence; - } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - this.renderYawOffset = this.rotationYaw; - super.onUpdate(); - } - - - /** - * Get this Entity's EnumCreatureAttribute - */ - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.ARTHROPOD; - } + @Override + public void onUpdate() { + this.renderYawOffset = this.rotationYaw; + super.onUpdate(); + } + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.ARTHROPOD; + } + + // [VanillaCopy] EntitySilverfish$AIHideInStone. Changes noted + private static class AIHideInStone extends EntityAIWander { + + private EnumFacing facing; + private boolean doMerge; + + public AIHideInStone(EntityTFTowerTermite silverfishIn) { + super(silverfishIn, 1.0D, 10); + this.setMutexBits(1); + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + @Override + public boolean shouldExecute() { + if (this.entity.getAttackTarget() != null) { + return false; + } else if (!this.entity.getNavigator().noPath()) { + return false; + } else { + Random random = this.entity.getRNG(); + + if (random.nextInt(10) == 0 && ForgeEventFactory.getMobGriefingEvent(this.entity.world, this.entity)) { + this.facing = EnumFacing.random(random); + BlockPos blockpos = (new BlockPos(this.entity.posX, this.entity.posY + 0.5D, this.entity.posZ)).offset(this.facing); + IBlockState iblockstate = this.entity.world.getBlockState(blockpos); + + // TF - Change block check + if (iblockstate == TFBlocks.tower_wood.getDefaultState()) { + this.doMerge = true; + return true; + } + } + + this.doMerge = false; + return super.shouldExecute(); + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + @Override + public boolean shouldContinueExecuting() { + return this.doMerge ? false : super.shouldContinueExecuting(); + } + + /** + * Execute a one shot task or start executing a continuous task + */ + @Override + public void startExecuting() { + if (!this.doMerge) { + super.startExecuting(); + } else { + World world = this.entity.world; + BlockPos blockpos = (new BlockPos(this.entity.posX, this.entity.posY + 0.5D, this.entity.posZ)).offset(this.facing); + IBlockState iblockstate = world.getBlockState(blockpos); + + // TF - Change block check + if (iblockstate == TFBlocks.tower_wood.getDefaultState()) { + // TF - Change block type + world.setBlockState(blockpos, TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.INFESTED), 3); + this.entity.spawnExplosionParticle(); + this.entity.setDead(); + } + } + } + } + + // [VanillaCopy] of EntitySilverfish$AISummonSilverfish. Changes noted + private static class AISummonSilverfish extends EntityAIBase { + + private EntityTFTowerTermite silverfish; // TF - type change + private int lookForFriends; + + public AISummonSilverfish(EntityTFTowerTermite silverfishIn) { + this.silverfish = silverfishIn; + } + + public void notifyHurt() { + if (this.lookForFriends == 0) { + this.lookForFriends = 20; + } + } + + /** + * Returns whether the EntityAIBase should begin execution. + */ + @Override + public boolean shouldExecute() { + return this.lookForFriends > 0; + } + + /** + * Updates the task + */ + @Override + public void updateTask() { + --this.lookForFriends; + + if (this.lookForFriends <= 0) { + + World world = this.silverfish.world; + Random random = this.silverfish.getRNG(); + BlockPos blockpos = new BlockPos(this.silverfish); + + for (int i = 0; i <= 5 && i >= -5; i = i <= 0 ? 1 - i : 0 - i) { + for (int j = 0; j <= 10 && j >= -10; j = j <= 0 ? 1 - j : 0 - j) { + for (int k = 0; k <= 10 && k >= -10; k = k <= 0 ? 1 - k : 0 - k) { + + BlockPos blockpos1 = blockpos.add(j, i, k); + IBlockState iblockstate = world.getBlockState(blockpos1); + + // TF - Change block check + if (iblockstate == TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.INFESTED)) { + if (ForgeEventFactory.getMobGriefingEvent(world, this.silverfish)) { + world.destroyBlock(blockpos1, true); + } else { + // TF - reset to normal tower wood + world.setBlockState(blockpos1, TFBlocks.tower_wood.getDefaultState(), 3); + } + + if (random.nextBoolean()) { + return; + } + } + } + } + } + } + } + } } diff --git a/src/main/java/twilightforest/entity/EntityTFTroll.java b/src/main/java/twilightforest/entity/EntityTFTroll.java index a0142c6561..fc35f46de9 100644 --- a/src/main/java/twilightforest/entity/EntityTFTroll.java +++ b/src/main/java/twilightforest/entity/EntityTFTroll.java @@ -5,339 +5,214 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIArrowAttack; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.ai.EntityAIAttackRanged; import net.minecraft.entity.ai.EntityAIFleeSun; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIRestrictSun; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; +import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.play.server.S0BPacketAnimation; -import net.minecraft.potion.Potion; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import twilightforest.TFAchievementPage; +import twilightforest.TwilightForestMod; import twilightforest.block.TFBlocks; -import twilightforest.entity.ai.EntityAITFCollideAttackFixed; import twilightforest.entity.boss.EntityTFIceBomb; -import twilightforest.item.TFItems; - -public class EntityTFTroll extends EntityMob implements IRangedAttackMob -{ - private static final int ROCK_FLAG = 16; - - private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F); - private EntityAITFCollideAttackFixed aiAttackOnCollide = new EntityAITFCollideAttackFixed(this, EntityPlayer.class, 1.2D, false); - - public EntityTFTroll(World par1World) - { - super(par1World); - this.setSize(1.4F, 2.4F); - - this.tasks.addTask(1, new EntityAISwimming(this)); - this.tasks.addTask(2, new EntityAIRestrictSun(this)); - this.tasks.addTask(3, new EntityAIFleeSun(this, 1.0D)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(6, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - - if (par1World != null && !par1World.isRemote) - { - this.setCombatTask(); - } - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ +import twilightforest.util.WorldUtil; + +public class EntityTFTroll extends EntityMob implements IRangedAttackMob { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/troll"); + private static final DataParameter ROCK_FLAG = EntityDataManager.createKey(EntityTFTroll.class, DataSerializers.BOOLEAN); + private static final AttributeModifier ROCK_MODIFIER = new AttributeModifier("Rock follow boost", 24, 0).setSaved(false); + + private EntityAIAttackRanged aiArrowAttack; + private EntityAIAttackMelee aiAttackOnCollide; + + public EntityTFTroll(World world) { + super(world); + this.setSize(1.4F, 2.4F); + } + + @Override + public void initEntityAI() { + aiArrowAttack = new EntityAIAttackRanged(this, 1.0D, 20, 60, 15.0F); + aiAttackOnCollide = new EntityAIAttackMelee(this, 1.2D, false); + + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIRestrictSun(this)); + this.tasks.addTask(3, new EntityAIFleeSun(this, 1.0D)); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(6, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + + if (world != null && !world.isRemote) { + this.setCombatTask(); + } + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(7.0D); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(ROCK_FLAG, false); + } + + public boolean hasRock() { + return dataManager.get(ROCK_FLAG); + } + + public void setHasRock(boolean rock) { + dataManager.set(ROCK_FLAG, rock); + + if (!world.isRemote) { + if (rock) { + if (!getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).hasModifier(ROCK_MODIFIER)) { + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).applyModifier(ROCK_MODIFIER); + } + } else { + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).removeModifier(ROCK_MODIFIER); + } + this.setCombatTask(); + } + } + + @Override + public boolean attackEntityAsMob(Entity entity) { + swingArm(EnumHand.MAIN_HAND); + return super.attackEntityAsMob(entity); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(7.0D); - } - - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(ROCK_FLAG, Byte.valueOf((byte)0)); - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - super.onLivingUpdate(); - } - - - /** - * Determines whether this troll has a rock or not. - */ - public boolean hasRock() { - return (this.dataWatcher.getWatchableObjectByte(ROCK_FLAG) & 2) != 0; - } - - /** - * Sets whether this troll has a rock or not. - */ - public void setHasRock(boolean rock) { - byte b0 = this.dataWatcher.getWatchableObjectByte(ROCK_FLAG); - - if (rock) { - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(40.0D); - this.dataWatcher.updateObject(ROCK_FLAG, Byte.valueOf((byte)(b0 | 2))); - } else { - this.dataWatcher.updateObject(ROCK_FLAG, Byte.valueOf((byte)(b0 & -3))); - } - - this.setCombatTask(); - } - - /** - * Swing! - */ + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("HasRock", this.hasRock()); + } + @Override - public boolean attackEntityAsMob(Entity par1Entity) { - - this.swingItem(); - - return super.attackEntityAsMob(par1Entity); + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setHasRock(compound.getBoolean("HasRock")); } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setBoolean("HasRock", this.hasRock()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setHasRock(par1NBTTagCompound.getBoolean("HasRock")); - } - - - /** - * sets this entity's combat AI. - */ - public void setCombatTask() - { - this.tasks.removeTask(this.aiAttackOnCollide); - this.tasks.removeTask(this.aiArrowAttack); - - if (this.hasRock()) { - this.tasks.addTask(4, this.aiArrowAttack); - } else { - this.tasks.addTask(4, this.aiAttackOnCollide); - } - } - - /** - * handles entity death timer, experience orb and particle creation - */ + + private void setCombatTask() { + this.tasks.removeTask(this.aiAttackOnCollide); + this.tasks.removeTask(this.aiArrowAttack); + + if (this.hasRock()) { + this.tasks.addTask(4, this.aiArrowAttack); + } else { + this.tasks.addTask(4, this.aiAttackOnCollide); + } + } + + @Override protected void onDeathUpdate() { super.onDeathUpdate(); - + if (this.deathTime % 5 == 0) { this.ripenTrollBerNearby(this.deathTime / 5); } - + if (this.deathTime == 1) { //this.makeTrollStoneInAABB(this.boundingBox); } } - private void ripenTrollBerNearby(int offset) { - int sx = MathHelper.floor_double(this.posX); - int sy = MathHelper.floor_double(this.posY); - int sz = MathHelper.floor_double(this.posZ); - int range = 12; - for (int dx = -range; dx < range; dx++) { - for (int dy = -range; dy < range; dy++) { - for (int dz = -range; dz < range; dz++) { - if (true) { - int cx = sx + dx; - int cy = sy + dy; - int cz = sz + dz; - - ripenBer(offset, cx, cy, cz); - } - } - } + for (BlockPos pos : WorldUtil.getAllAround(new BlockPos(this), range)) { + ripenBer(offset, pos); } } + private void ripenBer(int offset, BlockPos pos) { + if (this.world.getBlockState(pos).getBlock() == TFBlocks.unripe_trollber && this.rand.nextBoolean() && (Math.abs(pos.getX() + pos.getY() + pos.getZ()) % 5 == offset)) { + this.world.setBlockState(pos, TFBlocks.trollber.getDefaultState()); + world.playEvent(2004, pos, 0); + } + } - private void ripenBer(int offset, int cx, int cy, int cz) { - if (this.worldObj.getBlock(cx, cy, cz) == TFBlocks.unripeTrollBer && this.rand.nextBoolean() && (Math.abs(cx + cy + cz) % 5 == offset)) { - this.worldObj.setBlock(cx, cy, cz, TFBlocks.trollBer); - worldObj.playAuxSFX(2004, cx, cy, cz, 0); + private void makeTrollStoneInAABB(AxisAlignedBB aabb) { + int minX = MathHelper.ceil(aabb.minX); + int minY = MathHelper.ceil(aabb.minY); + int minZ = MathHelper.ceil(aabb.minZ); + int maxX = MathHelper.floor(aabb.maxX); + int maxY = MathHelper.floor(aabb.maxY); + int maxZ = MathHelper.floor(aabb.maxZ); + + for (BlockPos pos : BlockPos.getAllInBox(new BlockPos(minX, minY, minZ), new BlockPos(maxX, maxY, maxZ))) { + if (world.isAirBlock(pos)) { + world.setBlockState(pos, TFBlocks.trollsteinn.getDefaultState()); + world.playEvent(2001, pos, Block.getStateId(TFBlocks.trollsteinn.getDefaultState())); + } + } + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + @Override + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) { + if (this.hasRock()) { + EntityTFIceBomb ice = new EntityTFIceBomb(this.world, this); + + // [VanillaCopy] Part of EntitySkeleton.attackEntityWithRangedAttack + double d0 = target.posX - this.posX; + double d1 = target.getEntityBoundingBox().minY + (double) (target.height / 3.0F) - ice.posY; + double d2 = target.posZ - this.posZ; + double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); + ice.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.world.getDifficulty().getId() * 4)); + + this.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.world.spawnEntity(ice); } } + @Override + public void setSwingingArms(boolean swingingArms) {} // todo 1.12 - /** - * Trigger achievement when killed - */ + // [VanillaCopy] super but hardcode swing progress to ignore potions @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); + protected void updateArmSwingProgress() { + int i = 6; + + if (this.isSwingInProgress) { + ++this.swingProgressInt; + + if (this.swingProgressInt >= i) { + this.swingProgressInt = 0; + this.isSwingInProgress = false; + } + } else { + this.swingProgressInt = 0; } - + + this.swingProgress = (float) this.swingProgressInt / (float) i; } - - /** - * Turns blocks to trollstone inside the given bounding box. - */ - private void makeTrollStoneInAABB(AxisAlignedBB par1AxisAlignedBB) - { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.ceiling_double_int(par1AxisAlignedBB.minX); - int minY = MathHelper.ceiling_double_int(par1AxisAlignedBB.minY); - int minZ = MathHelper.ceiling_double_int(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - - for (int dx = minX; dx <= maxX; ++dx) - { - for (int dy = minY; dy <= maxY; ++dy) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - Block currentID = this.worldObj.getBlock(dx, dy, dz); - - if (currentID == Blocks.air) - { - this.worldObj.setBlock(dx, dy, dz, TFBlocks.trollSteinn); - // here, this effect will have to do - worldObj.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(TFBlocks.trollSteinn) + (0 << 12)); - } - } - } - } - } - - protected Item getDropItem() - { - return null; - } - - protected void dropRareDrop(int p_70600_1_) - { - this.dropItem(TFItems.magicBeans, 1); - } - - /** - * Attack the specified entity using a ranged attack. - */ - public void attackEntityWithRangedAttack(EntityLivingBase target, float par2) - { - if (this.hasRock()) { - - EntityTFIceBomb ice = new EntityTFIceBomb(this.worldObj, this); - - double d0 = target.posX - this.posX; - double d1 = target.posY + (double)target.getEyeHeight() - 1.100000023841858D - target.posY; - double d2 = target.posZ - this.posZ; - float f1 = MathHelper.sqrt_double(d0 * d0 + d2 * d2) * 0.2F; - ice.setThrowableHeading(d0, d1 + (double)f1, d2, 0.75F, 12.0F); - - this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); - this.worldObj.spawnEntityInWorld(ice); - } - } - - - /** - * Swings the item the player is holding. - */ - public void swingItem() { - if (!this.isSwingInProgress || this.swingProgressInt >= this.getArmSwingAnimationEnd() / 2 || this.swingProgressInt < 0) { - this.swingProgressInt = -1; - this.isSwingInProgress = true; - - if (this.worldObj instanceof WorldServer) - { - ((WorldServer)this.worldObj).getEntityTracker().func_151247_a(this, new S0BPacketAnimation(this, 0)); - } - } - } - - /** - * Updates the arm swing progress counters and animation progress - */ - protected void updateArmSwingProgress() - { - int maxSwing = this.getArmSwingAnimationEnd(); - - if (this.isSwingInProgress) - { - ++this.swingProgressInt; - - if (this.swingProgressInt >= maxSwing) - { - this.swingProgressInt = 0; - this.isSwingInProgress = false; - } - } - else - { - this.swingProgressInt = 0; - } - - this.swingProgress = (float)this.swingProgressInt / (float)maxSwing; - } - - /** - * Returns an integer indicating the end point of the swing animation, used by {@link #swingProgress} to provide a - * progress indicator. Takes dig speed enchantments into account. - */ - private int getArmSwingAnimationEnd() - { - return 6; - } } diff --git a/src/main/java/twilightforest/entity/EntityTFTwilightWandBolt.java b/src/main/java/twilightforest/entity/EntityTFTwilightWandBolt.java index 81b386c0ee..19cf3f5a29 100644 --- a/src/main/java/twilightforest/entity/EntityTFTwilightWandBolt.java +++ b/src/main/java/twilightforest/entity/EntityTFTwilightWandBolt.java @@ -1,85 +1,98 @@ package twilightforest.entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +public class EntityTFTwilightWandBolt extends EntityTFThrowable { -public class EntityTFTwilightWandBolt extends EntityThrowable { - - public EntityTFTwilightWandBolt(World par1World) { - super(par1World); + @SuppressWarnings("unused") + public EntityTFTwilightWandBolt(World world) { + super(world); } - - public EntityTFTwilightWandBolt(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); - // TODO Auto-generated constructor stub + @SuppressWarnings("unused") + public EntityTFTwilightWandBolt(World world, double x, double y, double z) { + super(world, x, y, z); } - - public EntityTFTwilightWandBolt(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); - // TODO Auto-generated constructor stub + public EntityTFTwilightWandBolt(World world, EntityLivingBase thrower) { + super(world, thrower); + shoot(thrower, thrower.rotationPitch, thrower.rotationYaw, 0, 1.5F, 1.0F); } - + @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - public void makeTrail() { + + private void makeTrail() { for (int i = 0; i < 5; i++) { - double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); - + double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double s1 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.17F; // color double s2 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.80F; // color double s3 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.69F; // color - worldObj.spawnParticle("mobSpell", dx, dy, dz, s1, s2, s3); + world.spawnParticle(EnumParticleTypes.SPELL_MOB, dx, dy, dz, s1, s2, s3); } } - /** - * How much this entity falls each tick - */ @Override - protected float getGravityVelocity() - { - return 0.003F; - } + protected float getGravityVelocity() { + return 0.003F; + } + @SideOnly(Side.CLIENT) + @Override + public void handleStatusUpdate(byte id) { + if (id == 3) { + int itemId = Item.getIdFromItem(Items.ENDER_PEARL); + for (int i = 0; i < 8; ++i) { + this.world.spawnParticle(EnumParticleTypes.ITEM_CRACK, this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D, itemId); + } + } else { + super.handleStatusUpdate(id); + } + } + @Override + protected void onImpact(RayTraceResult result) { + if (!this.world.isRemote) { + if (result.entityHit instanceof EntityLivingBase) { + result.entityHit.attackEntityFrom(DamageSource.causeIndirectMagicDamage(this, this.getThrower()), 6); + } + + this.world.setEntityState(this, (byte) 3); + this.setDead(); + } + } @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - // only hit living things - if (par1MovingObjectPosition.entityHit != null && par1MovingObjectPosition.entityHit instanceof EntityLivingBase) - { - if (par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeIndirectMagicDamage(this, this.getThrower()), 6)) - { - ; - } - } - - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(Items.ender_pearl), this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D); - } - - if (!this.worldObj.isRemote) - { - this.setDead(); - } + public boolean attackEntityFrom(DamageSource source, float amount) { + super.attackEntityFrom(source, amount); + + if (!this.world.isRemote && source.getTrueSource() != null) { + Vec3d vec3d = source.getTrueSource().getLookVec(); + // reflect faster and more accurately + this.shoot(vec3d.x, vec3d.y, vec3d.z, 1.5F, 0.1F); // reflect faster and more accurately + + if (source.getImmediateSource() instanceof EntityLivingBase) { + this.thrower = (EntityLivingBase) source.getImmediateSource(); + } + return true; + } + return false; } - } diff --git a/src/main/java/twilightforest/entity/EntityTFWinterWolf.java b/src/main/java/twilightforest/entity/EntityTFWinterWolf.java index 0bd5c90096..019d16dba7 100644 --- a/src/main/java/twilightforest/entity/EntityTFWinterWolf.java +++ b/src/main/java/twilightforest/entity/EntityTFWinterWolf.java @@ -2,175 +2,137 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; +import twilightforest.client.particle.TFParticleType; import twilightforest.entity.ai.EntityAITFBreathAttack; -import twilightforest.item.TFItems; -public class EntityTFWinterWolf extends EntityTFHostileWolf implements IBreathAttacker { +public class EntityTFWinterWolf extends EntityTFHostileWolf implements IBreathAttacker { - private static final int BREATH_FLAG = 21; - public static final int BREATH_DURATION = 10; - public static final int BREATH_DAMAGE = 2; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/winter_wolf"); + private static final DataParameter BREATH_FLAG = EntityDataManager.createKey(EntityTFWinterWolf.class, DataSerializers.BOOLEAN); + private static final float BREATH_DAMAGE = 2.0F; public EntityTFWinterWolf(World world) { super(world); - this.setSize(1.4F, 1.9F); - - this.tasks.taskEntries.clear(); - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(2, new EntityAITFBreathAttack(this, 1.0F, 5F, 30, 0.1F)); - this.tasks.addTask(3, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0F, false)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0F)); - - this.targetTasks.taskEntries.clear(); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); + this.setSize(1.4F, 1.9F); + setCollarColor(EnumDyeColor.LIGHT_BLUE); } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); // max health - } - - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(BREATH_FLAG, Byte.valueOf((byte)0)); - } - - /** - * Returns the amount of damage a mob should deal. - */ - public int getAttackStrength(Entity par1Entity) - { - return 6; - } - - public boolean attackEntityAsMob(Entity par1Entity) - { - int damage = this.getAttackStrength(par1Entity); - if (par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), damage)) - { - return true; - } - else - { - return false; - } - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - super.onLivingUpdate(); - - // when breathing fire, spew particles - if (isBreathing()) - { - Vec3 look = this.getLookVec(); - - double dist = 0.5; - double px = this.posX + look.xCoord * dist; - double py = this.posY + 1.25 + look.yCoord * dist; - double pz = this.posZ + look.zCoord * dist; - - for (int i = 0; i < 10; i++) - { - double dx = look.xCoord; - double dy = look.yCoord; - double dz = look.zCoord; - - double spread = 5 + this.getRNG().nextDouble() * 2.5; - double velocity = 3.0 + this.getRNG().nextDouble() * 0.15; - - // spread flame - dx += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dy += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dz += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dx *= velocity; - dy *= velocity; - dz *= velocity; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowstuff", px, py, pz, dx, dy, dz); - //worldObj.spawnParticle(getFlameParticle(), px, py, pz, dx, dy, dz); - } - + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAITFBreathAttack<>(this, 1.0F, 5F, 30, 0.1F)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0F, false)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0D)); + + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void setAttributes() { + super.setAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(BREATH_FLAG, false); + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (isBreathing()) { + if (this.world.isRemote) { + spawnBreathParticles(); + } playBreathSound(); - } + } + } + + private void spawnBreathParticles() { + + Vec3d look = this.getLookVec(); - } - - public void playBreathSound() { - worldObj.playSoundEffect(this.posX + 0.5, this.posY + 0.5, this.posZ + 0.5, "mob.ghast.fireball", rand.nextFloat() * 0.5F, rand.nextFloat() * 0.5F); + final double dist = 0.5; + double px = this.posX + look.x * dist; + double py = this.posY + 1.25 + look.y * dist; + double pz = this.posZ + look.z * dist; + + for (int i = 0; i < 10; i++) { + double dx = look.x; + double dy = look.y; + double dz = look.z; + + double spread = 5.0 + this.getRNG().nextDouble() * 2.5; + double velocity = 3.0 + this.getRNG().nextDouble() * 0.15; + + // spread flame + dx += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dy += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dz += this.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dx *= velocity; + dy *= velocity; + dz *= velocity; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.SNOW, px, py, pz, dx, dy, dz); + } } - /** - * Gets the pitch of living sounds in living entities. - */ - protected float getSoundPitch() - { - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.6F; - } + private void playBreathSound() { + playSound(SoundEvents.ENTITY_GHAST_SHOOT, rand.nextFloat() * 0.5F, rand.nextFloat() * 0.5F); + } @Override - public boolean isBreathing() { - return this.getDataWatcher().getWatchableObjectByte(BREATH_FLAG) == 1; + protected float getSoundPitch() { + return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.6F; + } + @Override + public boolean isBreathing() { + return dataManager.get(BREATH_FLAG); } @Override public void setBreathing(boolean flag) { - this.getDataWatcher().updateObject(BREATH_FLAG, Byte.valueOf((byte)(flag ? 1 : 0))); + dataManager.set(BREATH_FLAG, flag); } @Override public void doBreathAttack(Entity target) { -// if (!target.isImmuneToFire() && target.attackEntityFrom(DamageSource.inFire, BREATH_DAMAGE)) -// { -// target.setFire(BREATH_DURATION); -// } + target.attackEntityFrom(DamageSource.causeMobDamage(this), BREATH_DAMAGE); } - - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ + @Override protected boolean isValidLightLevel() { - int x = MathHelper.floor_double(this.posX); - int z = MathHelper.floor_double(this.posZ); - - if (worldObj.getBiomeGenForCoords(x, z) == TFBiomeBase.tfSnow) { - return true; - } else { - return super.isValidLightLevel(); - } + return world.getBiome(new BlockPos(this)) == TFBiomes.snowy_forest + || super.isValidLightLevel(); } - - protected Item getDropItem() - { - return TFItems.arcticFur; - } + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/EntityTFWraith.java b/src/main/java/twilightforest/entity/EntityTFWraith.java index b9966455fb..fab6100683 100644 --- a/src/main/java/twilightforest/entity/EntityTFWraith.java +++ b/src/main/java/twilightforest/entity/EntityTFWraith.java @@ -1,337 +1,315 @@ package twilightforest.entity; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityFlying; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityMoveHelper; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.item.ItemAxe; +import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.TFFeature; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; +import twilightforest.entity.ai.EntityAITFFindEntityNearestPlayer; +import java.util.Random; public class EntityTFWraith extends EntityFlying implements IMob { - public EntityTFWraith(World world) - { - super(world); - } - - public EntityTFWraith(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - /** - * Set monster attributes - */ + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/wraith"); + + public EntityTFWraith(World world) { + super(world); + moveHelper = new NoClipMoveHelper(this); + noClip = true; + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(4, new AIAttack(this)); + this.tasks.addTask(5, new AIFlyTowardsTarget(this)); + this.tasks.addTask(6, new AIRandomFly(this)); + this.tasks.addTask(7, new AILookAround(this)); + this.targetTasks.addTask(1, new EntityAITFFindEntityNearestPlayer(this)); + } + + static class AIFlyTowardsTarget extends EntityAIBase { + private final EntityTFWraith taskOwner; + + AIFlyTowardsTarget(EntityTFWraith wraith) { + this.taskOwner = wraith; + this.setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + return taskOwner.getAttackTarget() != null; + } + + @Override + public boolean shouldContinueExecuting() { + return false; + } + + @Override + public void startExecuting() { + EntityLivingBase target = taskOwner.getAttackTarget(); + if (target != null) + taskOwner.getMoveHelper().setMoveTo(target.posX, target.posY, target.posZ, 0.5F); + } + } + + // Similar to EntityAIAttackMelee but simpler (no pathfinding) + static class AIAttack extends EntityAIBase { + private final EntityTFWraith taskOwner; + private int attackTick = 20; + + AIAttack(EntityTFWraith taskOwner) { + this.taskOwner = taskOwner; + } + + @Override + public boolean shouldExecute() { + EntityLivingBase target = taskOwner.getAttackTarget(); + + return target != null + && target.getEntityBoundingBox().maxY > taskOwner.getEntityBoundingBox().minY + && target.getEntityBoundingBox().minY < taskOwner.getEntityBoundingBox().maxY + && taskOwner.getDistanceSq(target) <= 4.0D; + } + + @Override + public void updateTask() { + if (attackTick > 0) { + attackTick--; + } + } + + @Override + public void resetTask() { + attackTick = 20; + } + + @Override + public void startExecuting() { + if (taskOwner.getAttackTarget() != null) + taskOwner.attackEntityAsMob(taskOwner.getAttackTarget()); + attackTick = 20; + } + } + + // [VanillaCopy] EntityGhast.AIRandomFly + static class AIRandomFly extends EntityAIBase { + private final EntityTFWraith parentEntity; + + public AIRandomFly(EntityTFWraith wraith) { + this.parentEntity = wraith; + this.setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + if (parentEntity.getAttackTarget() != null) + return false; + EntityMoveHelper entitymovehelper = this.parentEntity.getMoveHelper(); + double d0 = entitymovehelper.getX() - this.parentEntity.posX; + double d1 = entitymovehelper.getY() - this.parentEntity.posY; + double d2 = entitymovehelper.getZ() - this.parentEntity.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + return d3 < 1.0D || d3 > 3600.0D; + } + + @Override + public boolean shouldContinueExecuting() { + return false; + } + + @Override + public void startExecuting() { + Random random = this.parentEntity.getRNG(); + double d0 = this.parentEntity.posX + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + double d1 = this.parentEntity.posY + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + double d2 = this.parentEntity.posZ + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + this.parentEntity.getMoveHelper().setMoveTo(d0, d1, d2, 0.5D); + } + } + + // [VanillaCopy] EntityGhast.AILookAround + public static class AILookAround extends EntityAIBase { + private final EntityTFWraith parentEntity; + + public AILookAround(EntityTFWraith wraith) { + this.parentEntity = wraith; + this.setMutexBits(2); + } + + @Override + public boolean shouldExecute() { + return true; + } + + @Override + public void updateTask() { + if (this.parentEntity.getAttackTarget() == null) { + this.parentEntity.rotationYaw = -((float) MathHelper.atan2(this.parentEntity.motionX, this.parentEntity.motionZ)) * (180F / (float) Math.PI); + this.parentEntity.renderYawOffset = this.parentEntity.rotationYaw; + } else { + EntityLivingBase entitylivingbase = this.parentEntity.getAttackTarget(); + + if (entitylivingbase.getDistanceSq(this.parentEntity) < 4096.0D) { + double d1 = entitylivingbase.posX - this.parentEntity.posX; + double d2 = entitylivingbase.posZ - this.parentEntity.posZ; + this.parentEntity.rotationYaw = -((float) MathHelper.atan2(d1, d2)) * (180F / (float) Math.PI); + this.parentEntity.renderYawOffset = this.parentEntity.rotationYaw; + } + } + } + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.5D); + + // need to initialize damage since we're not an EntityMob + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(5.0D); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.5D); // movement speed - - // need to initialize damage since we're not an EntityMob - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5.0D); // attack damage - } - - @Override - public void onLivingUpdate() - { - if(worldObj.isDaytime()) - { - float f = getBrightness(1.0F); - if(f > 0.5F && worldObj.canBlockSeeTheSky(MathHelper.floor_double(posX), MathHelper.floor_double(posY), MathHelper.floor_double(posZ)) && rand.nextFloat() * 30F < (f - 0.4F) * 2.0F) - { -// fire = 300; - } - } - super.onLivingUpdate(); - } - - /** - * Supress walking sounds - */ - @Override - public boolean canTriggerWalking() - { - return false; - } - - /** - * Adapted from the ghast code. The ghost wanders randomly until it targets a player, at which point it moves towards the player. - * - * TODO: pathfinding! - */ - @Override - protected void updateEntityActionState() - { - if(!worldObj.isRemote && worldObj.difficultySetting == EnumDifficulty.PEACEFUL) - { - setDead(); - } - despawnEntity(); - prevAttackCounter = attackCounter; - double d = waypointX - posX; - double d1 = waypointY - posY; - double d2 = waypointZ - posZ; - double d3 = MathHelper.sqrt_double(d * d + d1 * d1 + d2 * d2); - if(d3 < 1.0D || d3 > 60D) - { - waypointX = posX + (rand.nextFloat() * 2.0F - 1.0F) * 16F; - waypointY = posY + (rand.nextFloat() * 2.0F - 1.0F) * 16F; - waypointZ = posZ + (rand.nextFloat() * 2.0F - 1.0F) * 16F; - } - if(courseChangeCooldown-- <= 0) - { - courseChangeCooldown += rand.nextInt(5) + 2; - if(isCourseTraversable(waypointX, waypointY, waypointZ, d3)) - { - motionX += (d / d3) * 0.10000000000000001D; - motionY += (d1 / d3) * 0.10000000000000001D; - motionZ += (d2 / d3) * 0.10000000000000001D; - } else - { - waypointX = posX; - waypointY = posY; - waypointZ = posZ; - - // clear target? - targetedEntity = null; - } - } - if(targetedEntity != null && targetedEntity.isDead) - { - targetedEntity = null; - } - if(targetedEntity == null || aggroCooldown-- <= 0) - { - targetedEntity = findPlayerToAttack(); - if(targetedEntity != null) - { - aggroCooldown = 20; - } - } else { - float f1 = targetedEntity.getDistanceToEntity(this); - if(canEntityBeSeen(targetedEntity)) - { - attackEntity(targetedEntity, f1); - } else - { - attackBlockedEntity(targetedEntity, f1); - } - } - double d4 = 64D; - if(targetedEntity != null && targetedEntity.getDistanceSqToEntity(this) < d4 * d4) - { - double d5 = targetedEntity.posX - posX; - //double d6 = (targetedEntity.boundingBox.minY + (double)(targetedEntity.height / 2.0F)) - (posY + height / 2.0F); - double d7 = targetedEntity.posZ - posZ; - renderYawOffset = rotationYaw = (-(float)Math.atan2(d5, d7) * 180F) / 3.141593F; - if(canEntityBeSeen(targetedEntity)) - { - if(attackCounter == 10) - { - //worldObj.playSoundAtEntity(this, "mob.ghast.charge", getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); - } - attackCounter++; - if(attackCounter == 20) - { - waypointX = targetedEntity.posX; - waypointY = targetedEntity.posY - targetedEntity.height + 0.5; - waypointZ = targetedEntity.posZ; - - - attackCounter = -40; - } - } else - if(attackCounter > 0) - { - attackCounter--; - } - } else - { - renderYawOffset = rotationYaw = (-(float)Math.atan2(motionX, motionZ) * 180F) / 3.141593F; - if(attackCounter > 0) - { - attackCounter--; - } - } - } - - protected void attackEntity(Entity entity, float f) - { - if(attackTime <= 0 && f < 2.0F && entity.boundingBox.maxY > boundingBox.minY && entity.boundingBox.minY < boundingBox.maxY) - { - attackTime = 20; - - float damage = (float)this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getBaseValue(); - - entity.attackEntityFrom(DamageSource.causeMobDamage(this), damage); - } - } - - protected void attackBlockedEntity(Entity entity, float f) - { - } - - - /** - * Adapted from EntityMob - * @return - */ - - @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { - if(super.attackEntityFrom(damagesource, i)) - { - Entity entity = damagesource.getEntity(); - if(riddenByEntity == entity || ridingEntity == entity) - { - return true; - } - if(entity != this) - { - targetedEntity = entity; - } - return true; - } else - { - return false; - } - } - - /** - * Copied from EntityMob - * @return - */ - protected Entity findPlayerToAttack() - { - EntityPlayer entityplayer = worldObj.getClosestVulnerablePlayerToEntity(this, 16D); - if(entityplayer != null && canEntityBeSeen(entityplayer)) - { - return entityplayer; - } else - { - return null; - } - } - - private boolean isCourseTraversable(double d, double d1, double d2, double d3) - { - double d4 = (waypointX - posX) / d3; - double d5 = (waypointY - posY) / d3; - double d6 = (waypointZ - posZ) / d3; - AxisAlignedBB axisalignedbb = boundingBox.copy(); - for(int i = 1; i < d3; i++) - { - axisalignedbb.offset(d4, d5, d6); - if(worldObj.getCollidingBoundingBoxes(this, axisalignedbb).size() > 0) - { - return false; - } - } - - return true; - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.wraith.wraith"; - } - - @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.wraith.wraith"; - } - - @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.wraith.wraith"; - } - - @Override - protected Item getDropItem() - { - return Items.glowstone_dust; - } - - public int courseChangeCooldown; - public double waypointX; - public double waypointY; - public double waypointZ; - private Entity targetedEntity; - private int aggroCooldown; - public int prevAttackCounter; - public int attackCounter; - - /** - * Trigger achievement when killed - */ + public boolean canTriggerWalking() { + return false; + } + + // [VanillaCopy] EntityMob.attackEntityAsMob. This whole inheritance hierarchy makes me sad. @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - // are we in a level 3 hill? - int chunkX = MathHelper.floor_double(posX) >> 4; - int chunkZ = MathHelper.floor_double(posZ) >> 4; - if (TFFeature.getNearestFeature(chunkX, chunkZ, worldObj) == TFFeature.hill3) { - // award level 3 hill cheevo - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHill3); + public boolean attackEntityAsMob(Entity entityIn) { + float f = (float) this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getAttributeValue(); + int i = 0; + + if (entityIn instanceof EntityLivingBase) { + f += EnchantmentHelper.getModifierForCreature(this.getHeldItemMainhand(), ((EntityLivingBase) entityIn).getCreatureAttribute()); + i += EnchantmentHelper.getKnockbackModifier(this); + } + + boolean flag = entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), f); + + if (flag) { + if (i > 0 && entityIn instanceof EntityLivingBase) { + ((EntityLivingBase) entityIn).knockBack(this, (float) i * 0.5F, (double) MathHelper.sin(this.rotationYaw * 0.017453292F), (double) (-MathHelper.cos(this.rotationYaw * 0.017453292F))); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + } + + int j = EnchantmentHelper.getFireAspectModifier(this); + + if (j > 0) { + entityIn.setFire(j * 4); + } + + if (entityIn instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entityIn; + ItemStack itemstack = this.getHeldItemMainhand(); + ItemStack itemstack1 = entityplayer.isHandActive() ? entityplayer.getActiveItemStack() : ItemStack.EMPTY; + + if (!itemstack.isEmpty() && !itemstack1.isEmpty() && itemstack.getItem() instanceof ItemAxe && itemstack1.getItem() == Items.SHIELD) { + float f1 = 0.25F + (float) EnchantmentHelper.getEfficiencyModifier(this) * 0.05F; + + if (this.rand.nextFloat() < f1) { + entityplayer.getCooldownTracker().setCooldown(Items.SHIELD, 100); + this.world.setEntityState(entityplayer, (byte) 30); + } + } } + + this.applyEnchantments(this, entityIn); } + + return flag; + } + + private void despawnIfPeaceful() { + if (!world.isRemote && world.getDifficulty() == EnumDifficulty.PEACEFUL) + setDead(); + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + despawnIfPeaceful(); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + if (super.attackEntityFrom(source, amount)) { + Entity entity = source.getTrueSource(); + if (getRidingEntity() == entity || getPassengers().contains(entity)) { + return true; + } + if (entity != this && entity instanceof EntityLivingBase) { + setAttackTarget((EntityLivingBase) entity); + } + return true; + } else { + return false; + } + } + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.WRAITH; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.WRAITH; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.WRAITH; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + // [VanillaCopy] Direct copy of EntityMob.isValidLightLevel + protected boolean isValidLightLevel() { + BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ); + + if (this.world.getLightFor(EnumSkyBlock.SKY, blockpos) > this.rand.nextInt(32)) { + return false; + } else { + int i = this.world.getLightFromNeighbors(blockpos); + + if (this.world.isThundering()) { + int j = this.world.getSkylightSubtracted(); + this.world.setSkylightSubtracted(10); + i = this.world.getLightFromNeighbors(blockpos); + this.world.setSkylightSubtracted(j); + } + + return i <= this.rand.nextInt(8); + } + } + + @Override + public boolean getCanSpawnHere() { + return this.world.getDifficulty() != EnumDifficulty.PEACEFUL && this.isValidLightLevel() && super.getCanSpawnHere(); } - - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ - protected boolean isValidLightLevel() - { - int i = MathHelper.floor_double(this.posX); - int j = MathHelper.floor_double(this.boundingBox.minY); - int k = MathHelper.floor_double(this.posZ); - - if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, i, j, k) > this.rand.nextInt(32)) - { - return false; - } - else - { - int l = this.worldObj.getBlockLightValue(i, j, k); - - if (this.worldObj.isThundering()) - { - int i1 = this.worldObj.skylightSubtracted; - this.worldObj.skylightSubtracted = 10; - l = this.worldObj.getBlockLightValue(i, j, k); - this.worldObj.skylightSubtracted = i1; - } - - return l <= this.rand.nextInt(8); - } - } - - /** - * Checks if the entity's current position is a valid location to spawn this entity. - */ - public boolean getCanSpawnHere() - { - return this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL && this.isValidLightLevel() && super.getCanSpawnHere(); - } } diff --git a/src/main/java/twilightforest/entity/EntityTFYeti.java b/src/main/java/twilightforest/entity/EntityTFYeti.java index f817dd1f21..f30e6ac570 100644 --- a/src/main/java/twilightforest/entity/EntityTFYeti.java +++ b/src/main/java/twilightforest/entity/EntityTFYeti.java @@ -1,310 +1,224 @@ package twilightforest.entity; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.TFSounds; +import twilightforest.TwilightForestMod; +import twilightforest.biomes.TFBiomes; import twilightforest.entity.ai.EntityAITFThrowRider; -import twilightforest.item.TFItems; - -public class EntityTFYeti extends EntityMob -{ - - - private static final int ANGER_FLAG = 16; - - public EntityTFYeti(World par1World) - { - super(par1World); - this.setSize(1.4F, 2.4F); - - - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(1, new EntityAITFThrowRider(this, 1.0F)); - this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(3, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(4, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(4, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true, false)); - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Set monster attributes - */ + +import javax.annotation.Nullable; + +public class EntityTFYeti extends EntityMob implements IHostileMount { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/yeti"); + private static final DataParameter ANGER_FLAG = EntityDataManager.createKey(EntityTFYeti.class, DataSerializers.BOOLEAN); + private static final AttributeModifier ANGRY_MODIFIER = new AttributeModifier("Angry follow range boost", 24, 0).setSaved(false); + + public EntityTFYeti(World world) { + super(world); + this.setSize(1.4F, 2.4F); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.38D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(0.0D); - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(4.0D); - } - - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(ANGER_FLAG, Byte.valueOf((byte)0)); - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - if (this.riddenByEntity != null) - { - this.setSize(1.4F, 2.4F); - - // stop player sneaking so that they can't dismount! - if (this.riddenByEntity.isSneaking()) - { - //System.out.println("Pinch beetle sneaking detected!"); - - this.riddenByEntity.setSneaking(false); - } - } - else - { - this.setSize(1.4F, 2.4F); - - } - - super.onLivingUpdate(); - - // look at things in our jaws - if (this.riddenByEntity != null) - { - this.getLookHelper().setLookPositionWithEntity(riddenByEntity, 100F, 100F); - //this.faceEntity(riddenByEntity, 100F, 100F); - - - // push out of user in wall - Vec3 riderPos = this.getRiderPosition(); - this.func_145771_j(riderPos.xCoord, riderPos.yCoord, riderPos.zCoord); // push out of block - - - } - } - + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAITFThrowRider(this, 1.0D, false) { + @Override + protected void checkAndPerformAttack(EntityLivingBase p_190102_1_, double p_190102_2_) { + super.checkAndPerformAttack(p_190102_1_, p_190102_2_); + if (!getPassengers().isEmpty()) + playSound(TFSounds.ALPHAYETI_GRAB, 1F, 1.25F + getRNG().nextFloat() * 0.5F); + } + + @Override + public void resetTask() { + if (!getPassengers().isEmpty()) + playSound(TFSounds.ALPHAYETI_THROW, 1F, 1.25F + getRNG().nextFloat() * 0.5F); + super.resetTask(); + } + }); + this.tasks.addTask(2, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.38D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(0.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(4.0D); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(ANGER_FLAG, false); + } + + @Override + public void onLivingUpdate() { + if (!this.getPassengers().isEmpty()) { + // stop player sneaking so that they can't dismount! + if (this.getPassengers().get(0).isSneaking()) { + this.getPassengers().get(0).setSneaking(false); + } + } + + super.onLivingUpdate(); + + // look at things in our jaws + if (!this.getPassengers().isEmpty()) { + this.getLookHelper().setLookPositionWithEntity(getPassengers().get(0), 100F, 100F); + + // push out of user in wall + Vec3d riderPos = this.getRiderPosition(getPassengers().get(0)); + this.pushOutOfBlocks(riderPos.x, riderPos.y, riderPos.z); + } + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + if (source.getTrueSource() != null) { + // become angry + this.setAngry(true); + } + + return super.attackEntityFrom(source, amount); + } + + public boolean isAngry() { + return dataManager.get(ANGER_FLAG); + } + + public void setAngry(boolean anger) { + dataManager.set(ANGER_FLAG, anger); + + if (!world.isRemote) { + if (anger) { + if (!getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).hasModifier(ANGRY_MODIFIER)) { + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).applyModifier(ANGRY_MODIFIER); + } + } else { + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).removeModifier(ANGRY_MODIFIER); + } + } + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("Angry", this.isAngry()); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setAngry(compound.getBoolean("Angry")); + } /** - * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. - */ - @Override - public boolean interact(EntityPlayer par1EntityPlayer) - { - if (super.interact(par1EntityPlayer)) - { - return true; - } -// else if (!this.worldObj.isRemote && (this.riddenByEntity == null || this.riddenByEntity == par1EntityPlayer)) -// { -// par1EntityPlayer.mountEntity(this); -// return true; -// } - else - { - return false; - } - } - - /** - * Pick up things we attack! + * Put the player out in front of where we are */ - @Override - public boolean attackEntityAsMob(Entity par1Entity) - { - if (this.riddenByEntity == null && par1Entity.ridingEntity == null) - { - par1Entity.mountEntity(this); - } - - return super.attackEntityAsMob(par1Entity); + @Override + public void updatePassenger(Entity passenger) { + Vec3d riderPos = this.getRiderPosition(passenger); + passenger.setPosition(riderPos.x, riderPos.y, riderPos.z); } - - /** - * Called when the entity is attacked. - */ - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) - { - if (par1DamageSource.getSourceOfDamage() != null) { - // become angry - this.setAngry(true); - } - - return super.attackEntityFrom(par1DamageSource, par2); - } - - - - /** - * Determines whether this yeti is angry or not. - */ - public boolean isAngry() { - return (this.dataWatcher.getWatchableObjectByte(ANGER_FLAG) & 2) != 0; - } - - /** - * Sets whether this yeti is angry or not. - */ - public void setAngry(boolean anger) { - byte b0 = this.dataWatcher.getWatchableObjectByte(ANGER_FLAG); - - if (anger) { - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(40.0D); - this.dataWatcher.updateObject(ANGER_FLAG, Byte.valueOf((byte)(b0 | 2))); - } else { - this.dataWatcher.updateObject(ANGER_FLAG, Byte.valueOf((byte)(b0 & -3))); - } - } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setBoolean("Angry", this.isAngry()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setAngry(par1NBTTagCompound.getBoolean("Angry")); - } /** - * Put the player out in front of where we are - */ - @Override - public void updateRiderPosition() - { - if (this.riddenByEntity != null) - { - Vec3 riderPos = this.getRiderPosition(); - - this.riddenByEntity.setPosition(riderPos.xCoord, riderPos.yCoord, riderPos.zCoord); - } - } - - /** - * Returns the Y offset from the entity's position for any entity riding this one. - */ - @Override - public double getMountedYOffset() - { - return 2.25D; - } - - /** - * Used to both get a rider position and to push out of blocks - */ - public Vec3 getRiderPosition() - { - if (this.riddenByEntity != null) - { - float distance = 0.4F; - - double var1 = Math.cos((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; - double var3 = Math.sin((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; - - return Vec3.createVectorHelper(this.posX + var1, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3); - } - else - { - return Vec3.createVectorHelper(this.posX, this.posY, this.posZ); - } - } - - /** - * If a rider of this entity can interact with this entity. Should return true on the - * ridden entity if so. - * - * @return if the entity can be interacted with from a rider - */ - public boolean canRiderInteract() - { - return true; - } - - /** - * Trigger achievement when killed - */ + * Returns the Y offset from the entity's position for any entity riding this one. + */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + public double getMountedYOffset() { + return 2.25D; } - + /** - * We're allowed to spawn in bright light only in sniw + * Used to both get a rider position and to push out of blocks */ - @Override - public boolean getCanSpawnHere() - { - // are we in the snow - if (worldObj.getBiomeGenForCoords(MathHelper.floor_double(posX), MathHelper.floor_double(posZ)) == TFBiomeBase.tfSnow) { - // don't check light level - return worldObj.checkNoEntityCollision(boundingBox) && worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0; + private Vec3d getRiderPosition(@Nullable Entity passenger) { + if (passenger != null) { + float distance = 0.4F; + + double dx = Math.cos((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; + double dz = Math.sin((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; + + return new Vec3d(this.posX + dx, this.posY + this.getMountedYOffset() + passenger.getYOffset(), this.posZ + dz); + } else { + return new Vec3d(this.posX, this.posY, this.posZ); } - else { + } + + @Override + public boolean canRiderInteract() { + return true; + } + + @Override + public boolean getCanSpawnHere() { + // don't check light level in the snow + if (world.getBiome(new BlockPos(this)) == TFBiomes.snowy_forest) { + return world.checkNoEntityCollision(getEntityBoundingBox()) && world.getCollisionBoxes(this, getEntityBoundingBox()).size() == 0; + } else { // normal EntityMob spawn check, checks light level return super.getCanSpawnHere(); } - } + } - /** - * Checks to make sure the light is not too bright where the mob is spawning - */ @Override protected boolean isValidLightLevel() { - int x = MathHelper.floor_double(this.posX); - int z = MathHelper.floor_double(this.posZ); - - if (worldObj.getBiomeGenForCoords(x, z) == TFBiomeBase.tfSnow) { - return true; - } else { - return super.isValidLightLevel(); - } + return world.getBiome(new BlockPos(this)) == TFBiomes.snowy_forest || super.isValidLightLevel(); + } + + @Override + protected float getSoundPitch() { + return super.getSoundPitch() + 0.55F; + } + + @Nullable + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.ALPHAYETI_GROWL; + } + + @Override + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return TFSounds.ALPHAYETI_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.ALPHAYETI_DIE; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; } - - protected Item getDropItem() - { - return TFItems.arcticFur; - } - } diff --git a/src/main/java/twilightforest/entity/IBreathAttacker.java b/src/main/java/twilightforest/entity/IBreathAttacker.java index 23e84d6938..d0cd0caebd 100644 --- a/src/main/java/twilightforest/entity/IBreathAttacker.java +++ b/src/main/java/twilightforest/entity/IBreathAttacker.java @@ -10,6 +10,7 @@ public interface IBreathAttacker { /** * Deal damage for our breath attack + * * @param target */ public abstract void doBreathAttack(Entity target); diff --git a/src/main/java/twilightforest/entity/IHostileMount.java b/src/main/java/twilightforest/entity/IHostileMount.java new file mode 100644 index 0000000000..da59032dbf --- /dev/null +++ b/src/main/java/twilightforest/entity/IHostileMount.java @@ -0,0 +1,6 @@ +package twilightforest.entity; + +/** + * Marker interface for entities that can forcefully pick up the player. + */ +public interface IHostileMount {} diff --git a/src/main/java/twilightforest/entity/ITFCharger.java b/src/main/java/twilightforest/entity/ITFCharger.java index a52ea903c5..e0840746a8 100644 --- a/src/main/java/twilightforest/entity/ITFCharger.java +++ b/src/main/java/twilightforest/entity/ITFCharger.java @@ -2,8 +2,8 @@ public interface ITFCharger { - public boolean isCharging(); - - public void setCharging(boolean flag); - + public boolean isCharging(); + + public void setCharging(boolean flag); + } diff --git a/src/main/java/twilightforest/entity/ITFProjectile.java b/src/main/java/twilightforest/entity/ITFProjectile.java new file mode 100644 index 0000000000..da9c5c831b --- /dev/null +++ b/src/main/java/twilightforest/entity/ITFProjectile.java @@ -0,0 +1,8 @@ +package twilightforest.entity; + +import net.minecraftforge.fml.common.registry.IThrowableEntity; + +/** + * Marker interface for our projectiles, used for parrying. + */ +public interface ITFProjectile extends IThrowableEntity {} diff --git a/src/main/java/twilightforest/entity/NoClipMoveHelper.java b/src/main/java/twilightforest/entity/NoClipMoveHelper.java new file mode 100644 index 0000000000..6afb87832b --- /dev/null +++ b/src/main/java/twilightforest/entity/NoClipMoveHelper.java @@ -0,0 +1,34 @@ +package twilightforest.entity; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.ai.EntityMoveHelper; +import net.minecraft.util.math.MathHelper; + +public class NoClipMoveHelper extends EntityMoveHelper { + private final EntityLiving parentEntity; + private int courseChangeCooldown; + + public NoClipMoveHelper(EntityLiving entity) { + super(entity); + this.parentEntity = entity; + } + + @Override + public void onUpdateMoveHelper() { + if (this.action == EntityMoveHelper.Action.MOVE_TO) { + double d0 = this.posX - this.parentEntity.posX; + double d1 = this.posY - this.parentEntity.posY; + double d2 = this.posZ - this.parentEntity.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (this.courseChangeCooldown-- <= 0) { + this.courseChangeCooldown += this.parentEntity.getRNG().nextInt(5) + 2; + d3 = (double) MathHelper.sqrt(d3); + + this.parentEntity.motionX += (d0 / d3 * 0.1D) * speed; + this.parentEntity.motionY += (d1 / d3 * 0.1D) * speed; + this.parentEntity.motionZ += (d2 / d3 * 0.1D) * speed; + } + } + } +} diff --git a/src/main/java/twilightforest/entity/TFCreatures.java b/src/main/java/twilightforest/entity/TFCreatures.java deleted file mode 100644 index aa3f94aca8..0000000000 --- a/src/main/java/twilightforest/entity/TFCreatures.java +++ /dev/null @@ -1,107 +0,0 @@ -package twilightforest.entity; - -import java.util.HashMap; -import java.util.LinkedHashMap; - -import net.minecraft.entity.Entity; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.ModContainer; -import cpw.mods.fml.common.registry.EntityRegistry; -import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; - -public class TFCreatures { - - /** This is a HashMap of the Creative Entity Eggs/Spawners. */ - public static HashMap entityEggs = new LinkedHashMap(); - - - public static void registerTFCreature(Class entityClass, String entityName, int id, int backgroundEggColour, int foregroundEggColour) { - registerTFCreature(entityClass, entityName, id, backgroundEggColour, foregroundEggColour, 80, 3, true); - } - - public static void registerTFCreature(Class entityClass, String entityName, int id, int backgroundEggColour, int foregroundEggColour, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates) { - if (TwilightForestMod.creatureCompatibility) - { - // only register global id if flag is set - EntityRegistry.registerGlobalEntityID(entityClass, entityName, id); - } - EntityRegistry.registerModEntity(entityClass, entityName, id, TwilightForestMod.instance, trackingRange, updateFrequency, sendsVelocityUpdates); - entityEggs.put(Integer.valueOf(id), new TFEntityEggInfo(id, backgroundEggColour, foregroundEggColour)); - } - - public static void registerTFCreature(Class entityClass, String entityName, int id) { - if (TwilightForestMod.creatureCompatibility) - { - // only register global id if flag is set - EntityRegistry.registerGlobalEntityID(entityClass, entityName, id); - } - EntityRegistry.registerModEntity(entityClass, entityName, id, TwilightForestMod.instance, 80, 3, true); - } - - /** - * Create a new instance of an entity in the world by using an entity ID. - * This is the version that creates twilight forest creatures for use by their spawn eggs. - */ - public static Entity createEntityByID(int entityID, World par1World) - { - Entity entity = null; - - try - { - //Class clazz = (Class)IDtoClassMapping.get(Integer.valueOf(entityID)); - ModContainer mc = FMLCommonHandler.instance().findContainerFor(TwilightForestMod.instance); - EntityRegistration er = EntityRegistry.instance().lookupModSpawn(mc, entityID); - Class clazz = er.getEntityClass(); - - if (clazz != null) - { - entity = (Entity)clazz.getConstructor(new Class[] {World.class}).newInstance(new Object[] {par1World}); - } - } - catch (Exception var4) - { - var4.printStackTrace(); - } - - if (entity == null) - { - System.out.println("Skipping Entity with id " + entityID); - } - - return entity; - } - - /** - * Return the name of the monster with that ID. - */ - public static String getStringFromID(int entityID) - { - ModContainer mc = FMLCommonHandler.instance().findContainerFor(TwilightForestMod.instance); - EntityRegistration er = EntityRegistry.instance().lookupModSpawn(mc, entityID); - - if (er != null) { - return er.getEntityName(); - } - - return null; - } - - /** - * Return a string suitable for setting as the mobID in spawners. If the compatibility flag is set, then use the base monster name - * If the flag is false, return TwilightForest.mobName - */ - public static String getSpawnerNameFor(String baseName) { - if (TwilightForestMod.creatureCompatibility) - { - return baseName; - } - else - { - return "TwilightForest." + baseName; - } - } - - -} diff --git a/src/main/java/twilightforest/entity/TFEntities.java b/src/main/java/twilightforest/entity/TFEntities.java new file mode 100644 index 0000000000..2fe4d5ee77 --- /dev/null +++ b/src/main/java/twilightforest/entity/TFEntities.java @@ -0,0 +1,171 @@ +package twilightforest.entity; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntitySpawnPlacementRegistry; +import net.minecraft.init.Blocks; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraft.world.WorldEntitySpawner; +import net.minecraftforge.common.util.EnumHelper; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.EntityEntry; +import net.minecraftforge.fml.common.registry.EntityEntryBuilder; +import net.minecraftforge.registries.IForgeRegistry; +import twilightforest.TwilightForestMod; +import twilightforest.entity.boss.*; +import twilightforest.entity.finalcastle.EntityTFCastleGuardian; +import twilightforest.entity.passive.*; +import twilightforest.util.TFEntityNames; + +import java.util.function.Function; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class TFEntities { + + public static final EntityLiving.SpawnPlacementType ON_ICE = EnumHelper.addSpawnPlacementType("TF_ON_ICE", (world, pos) -> { + + IBlockState state = world.getBlockState(pos.down()); + Block block = state.getBlock(); + Material material = state.getMaterial(); + + return (material == Material.ICE || material == Material.PACKED_ICE) + && block != Blocks.BEDROCK && block != Blocks.BARRIER + && WorldEntitySpawner.isValidEmptySpawnBlock(world.getBlockState(pos)) + && WorldEntitySpawner.isValidEmptySpawnBlock(world.getBlockState(pos.up())); + }); + + static { + EntitySpawnPlacementRegistry.setPlacementType(EntityTFPenguin.class, ON_ICE); + } + + private static class EntityRegistryHelper { + + private final IForgeRegistry registry; + + private int id = 0; + + EntityRegistryHelper(IForgeRegistry registry) { + this.registry = registry; + } + + private static String toString(ResourceLocation registryName) { + return registryName.getNamespace() + "." + registryName.getPath(); + } + + final EntityEntryBuilder builder(ResourceLocation registryName, Class entity, Function factory) { + return EntityEntryBuilder.create().id(registryName, id++).name(toString(registryName)).entity(entity).factory(factory); + } + + final void registerEntity(ResourceLocation registryName, Class entity, Function factory, int backgroundEggColour, int foregroundEggColour) { + registerEntity(registryName, entity, factory, backgroundEggColour, foregroundEggColour, 80, 3, true); + } + + final void registerEntity(ResourceLocation registryName, Class entity, Function factory, int backgroundEggColour, int foregroundEggColour, int trackingRange, int updateInterval, boolean sendVelocityUpdates) { + registry.register(builder(registryName, entity, factory).tracker(trackingRange, updateInterval, sendVelocityUpdates).egg(backgroundEggColour, foregroundEggColour).build()); + } + + final void registerEntity(ResourceLocation registryName, Class entity, Function factory) { + registerEntity(registryName, entity, factory, 80, 3, true); + } + + final void registerEntity(ResourceLocation registryName, Class entity, Function factory, int trackingRange, int updateInterval, boolean sendVelocityUpdates) { + registry.register(builder(registryName, entity, factory).tracker(trackingRange, updateInterval, sendVelocityUpdates).build()); + } + } + + @SubscribeEvent + public static void registerEntities(RegistryEvent.Register event) { + + EntityRegistryHelper helper = new EntityRegistryHelper(event.getRegistry()); + + helper.registerEntity(TFEntityNames.WILD_BOAR, EntityTFBoar.class, EntityTFBoar::new, 0x83653b, 0xffefca); + helper.registerEntity(TFEntityNames.BIGHORN_SHEEP, EntityTFBighorn.class, EntityTFBighorn::new, 0xdbceaf, 0xd7c771); + helper.registerEntity(TFEntityNames.DEER, EntityTFDeer.class, EntityTFDeer::new, 0x7b4d2e, 0x4b241d); + + helper.registerEntity(TFEntityNames.REDCAP, EntityTFRedcap.class, EntityTFRedcap::new, 0x3b3a6c, 0xab1e14); + helper.registerEntity(TFEntityNames.SWARM_SPIDER, EntityTFSwarmSpider.class, EntityTFSwarmSpider::new, 0x32022e, 0x17251e); + helper.registerEntity(TFEntityNames.NAGA, EntityTFNaga.class, EntityTFNaga::new, 0xa4d316, 0x1b380b, 150, 1, true); + helper.registerEntity(TFEntityNames.SKELETON_DRUID, EntityTFSkeletonDruid.class, EntityTFSkeletonDruid::new, 0xa3a3a3, 0x2a3b17); + helper.registerEntity(TFEntityNames.HOSTILE_WOLF, EntityTFHostileWolf.class, EntityTFHostileWolf::new, 0xd7d3d3, 0xab1e14); + helper.registerEntity(TFEntityNames.WRAITH, EntityTFWraith.class, EntityTFWraith::new, 0x505050, 0x838383); + helper.registerEntity(TFEntityNames.HEDGE_SPIDER, EntityTFHedgeSpider.class, EntityTFHedgeSpider::new, 0x235f13, 0x562653); + helper.registerEntity(TFEntityNames.HYDRA, EntityTFHydra.class, EntityTFHydra::new, 0x142940, 0x29806b); + helper.registerEntity(TFEntityNames.LICH, EntityTFLich.class, EntityTFLich::new, 0xaca489, 0x360472); + helper.registerEntity(TFEntityNames.PENGUIN, EntityTFPenguin.class, EntityTFPenguin::new, 0x12151b, 0xf9edd2); + helper.registerEntity(TFEntityNames.LICH_MINION, EntityTFLichMinion.class, EntityTFLichMinion::new); + helper.registerEntity(TFEntityNames.LOYAL_ZOMBIE, EntityTFLoyalZombie.class, EntityTFLoyalZombie::new); + helper.registerEntity(TFEntityNames.TINY_BIRD, EntityTFTinyBird.class, EntityTFTinyBird::new, 0x33aadd, 0x1188ee); + helper.registerEntity(TFEntityNames.SQUIRREL, EntityTFSquirrel.class, EntityTFSquirrel::new, 0x904f12, 0xeeeeee); + helper.registerEntity(TFEntityNames.BUNNY, EntityTFBunny.class, EntityTFBunny::new, 0xfefeee, 0xccaa99); + helper.registerEntity(TFEntityNames.RAVEN, EntityTFRaven.class, EntityTFRaven::new, 0x000011, 0x222233); + helper.registerEntity(TFEntityNames.QUEST_RAM, EntityTFQuestRam.class, EntityTFQuestRam::new, 0xfefeee, 0x33aadd); + helper.registerEntity(TFEntityNames.KOBOLD, EntityTFKobold.class, EntityTFKobold::new, 0x372096, 0x895d1b); + helper.registerEntity(TFEntityNames.MOSQUITO_SWARM, EntityTFMosquitoSwarm.class, EntityTFMosquitoSwarm::new, 0x080904, 0x2d2f21); + helper.registerEntity(TFEntityNames.DEATH_TOME, EntityTFDeathTome.class, EntityTFDeathTome::new, 0x774e22, 0xdbcdbe); + helper.registerEntity(TFEntityNames.MINOTAUR, EntityTFMinotaur.class, EntityTFMinotaur::new, 0x3f3024, 0xaa7d66); + helper.registerEntity(TFEntityNames.MINOSHROOM, EntityTFMinoshroom.class, EntityTFMinoshroom::new, 0xa81012, 0xaa7d66); + helper.registerEntity(TFEntityNames.FIRE_BEETLE, EntityTFFireBeetle.class, EntityTFFireBeetle::new, 0x1d0b00, 0xcb6f25); + helper.registerEntity(TFEntityNames.SLIME_BEETLE, EntityTFSlimeBeetle.class, EntityTFSlimeBeetle::new, 0x0c1606, 0x60a74c); + helper.registerEntity(TFEntityNames.PINCH_BEETLE, EntityTFPinchBeetle.class, EntityTFPinchBeetle::new, 0xbc9327, 0x241609); + helper.registerEntity(TFEntityNames.MAZE_SLIME, EntityTFMazeSlime.class, EntityTFMazeSlime::new, 0xa3a3a3, 0x2a3b17); + helper.registerEntity(TFEntityNames.REDCAP_SAPPER, EntityTFRedcapSapper.class, EntityTFRedcapSapper::new, 0x575d21, 0xab1e14); + helper.registerEntity(TFEntityNames.MIST_WOLF, EntityTFMistWolf.class, EntityTFMistWolf::new, 0x3a1411, 0xe2c88a); + helper.registerEntity(TFEntityNames.KING_SPIDER, EntityTFKingSpider.class, EntityTFKingSpider::new, 0x2c1a0e, 0xffc017); + helper.registerEntity(TFEntityNames.FIREFLY, EntityTFMobileFirefly.class, EntityTFMobileFirefly::new, 0xa4d316, 0xbaee02); + helper.registerEntity(TFEntityNames.MINI_GHAST, EntityTFMiniGhast.class, EntityTFMiniGhast::new, 0xbcbcbc, 0xa74343); + helper.registerEntity(TFEntityNames.TOWER_GHAST, EntityTFTowerGhast.class, EntityTFTowerGhast::new, 0xbcbcbc, 0xb77878); + helper.registerEntity(TFEntityNames.TOWER_GOLEM, EntityTFTowerGolem.class, EntityTFTowerGolem::new, 0x6b3d20, 0xe2ddda); + helper.registerEntity(TFEntityNames.TOWER_TERMITE, EntityTFTowerTermite.class, EntityTFTowerTermite::new, 0x5d2b21, 0xaca03a); + helper.registerEntity(TFEntityNames.TOWER_BROODLING, EntityTFTowerBroodling.class, EntityTFTowerBroodling::new, 0x343c14, 0xbaee02); + helper.registerEntity(TFEntityNames.UR_GHAST, EntityTFUrGhast.class, EntityTFUrGhast::new, 0xbcbcbc, 0xb77878); + helper.registerEntity(TFEntityNames.BLOCKCHAIN_GOBLIN, EntityTFBlockGoblin.class, EntityTFBlockGoblin::new, 0xd3e7bc, 0x1f3fff); + helper.registerEntity(TFEntityNames.GOBLIN_KNIGHT_UPPER, EntityTFGoblinKnightUpper.class, EntityTFGoblinKnightUpper::new); + helper.registerEntity(TFEntityNames.GOBLIN_KNIGHT_LOWER, EntityTFGoblinKnightLower.class, EntityTFGoblinKnightLower::new, 0x566055, 0xd3e7bc); + helper.registerEntity(TFEntityNames.HELMET_CRAB, EntityTFHelmetCrab.class, EntityTFHelmetCrab::new, 0xfb904b, 0xd3e7bc); + helper.registerEntity(TFEntityNames.KNIGHT_PHANTOM, EntityTFKnightPhantom.class, EntityTFKnightPhantom::new, 0xa6673b, 0xd3e7bc); + helper.registerEntity(TFEntityNames.YETI, EntityTFYeti.class, EntityTFYeti::new, 0xdedede, 0x4675bb); + helper.registerEntity(TFEntityNames.YETI_ALPHA, EntityTFYetiAlpha.class, EntityTFYetiAlpha::new, 0xcdcdcd, 0x29486e); + helper.registerEntity(TFEntityNames.WINTER_WOLF, EntityTFWinterWolf.class, EntityTFWinterWolf::new, 0xdfe3e5, 0xb2bcca); + helper.registerEntity(TFEntityNames.SNOW_GUARDIAN, EntityTFSnowGuardian.class, EntityTFSnowGuardian::new, 0xd3e7bc, 0xfefefe); + helper.registerEntity(TFEntityNames.STABLE_ICE_CORE, EntityTFIceShooter.class, EntityTFIceShooter::new, 0xa1bff3, 0x7000f8); + helper.registerEntity(TFEntityNames.UNSTABLE_ICE_CORE, EntityTFIceExploder.class, EntityTFIceExploder::new, 0x9aacf5, 0x9b0fa5); + helper.registerEntity(TFEntityNames.SNOW_QUEEN, EntityTFSnowQueen.class, EntityTFSnowQueen::new, 0xb1b2d4, 0x87006e); + helper.registerEntity(TFEntityNames.TROLL, EntityTFTroll.class, EntityTFTroll::new, 0x9ea98f, 0xb0948e); + helper.registerEntity(TFEntityNames.GIANT_MINER, EntityTFGiantMiner.class, EntityTFGiantMiner::new, 0x211b52, 0x9a9a9a); + helper.registerEntity(TFEntityNames.ARMORED_GIANT, EntityTFArmoredGiant.class, EntityTFArmoredGiant::new, 0x239391, 0x9a9a9a); + helper.registerEntity(TFEntityNames.ICE_CRYSTAL, EntityTFIceCrystal.class, EntityTFIceCrystal::new, 0xdce9fe, 0xadcafb); + helper.registerEntity(TFEntityNames.HARBINGER_CUBE, EntityTFHarbingerCube.class, EntityTFHarbingerCube::new, 0x00000a, 0x8b0000); + helper.registerEntity(TFEntityNames.ADHERENT, EntityTFAdherent.class, EntityTFAdherent::new, 0x0a0000, 0x00008b); + helper.registerEntity(TFEntityNames.ROVING_CUBE, EntityTFRovingCube.class, EntityTFRovingCube::new, 0x0a0000, 0x00009b); + helper.registerEntity(TFEntityNames.CASTLE_GUARDIAN, EntityTFCastleGuardian.class, EntityTFCastleGuardian::new, 80, 3, true); + + helper.registerEntity(TFEntityNames.HYDRA_HEAD, EntityTFHydraHead.class, EntityTFHydraHead::new, 150, 3, false); + + helper.registerEntity(TFEntityNames.NATURE_BOLT, EntityTFNatureBolt.class, EntityTFNatureBolt::new, 150, 5, true); + helper.registerEntity(TFEntityNames.LICH_BOLT, EntityTFLichBolt.class, EntityTFLichBolt::new, 150, 2, true); + helper.registerEntity(TFEntityNames.WAND_BOLT, EntityTFTwilightWandBolt.class, EntityTFTwilightWandBolt::new, 150, 5, true); + helper.registerEntity(TFEntityNames.TOME_BOLT, EntityTFTomeBolt.class, EntityTFTomeBolt::new, 150, 5, true); + helper.registerEntity(TFEntityNames.HYDRA_MORTAR, EntityTFHydraMortar.class, EntityTFHydraMortar::new, 150, 3, true); + helper.registerEntity(TFEntityNames.LICH_BOMB, EntityTFLichBomb.class, EntityTFLichBomb::new, 150, 3, true); + helper.registerEntity(TFEntityNames.MOONWORM_SHOT, EntityTFMoonwormShot.class, EntityTFMoonwormShot::new, 150, 3, true); + helper.registerEntity(TFEntityNames.SLIME_BLOB, EntityTFSlimeProjectile.class, EntityTFSlimeProjectile::new, 150, 3, true); + helper.registerEntity(TFEntityNames.CHARM_EFFECT, EntityTFCharmEffect.class, EntityTFCharmEffect::new, 80, 3, true); + helper.registerEntity(TFEntityNames.THROWN_WEP, EntityTFThrownWep.class, EntityTFThrownWep::new, 80, 3, true); + helper.registerEntity(TFEntityNames.FALLING_ICE, EntityTFFallingIce.class, EntityTFFallingIce::new, 80, 3, true); + helper.registerEntity(TFEntityNames.THROWN_ICE, EntityTFIceBomb.class, EntityTFIceBomb::new, 80, 2, true); + helper.registerEntity(TFEntityNames.SEEKER_ARROW, EntitySeekerArrow.class, EntitySeekerArrow::new, 150, 1, true); + helper.registerEntity(TFEntityNames.ICE_ARROW, EntityIceArrow.class, EntityIceArrow::new, 150, 1, true); + helper.registerEntity(TFEntityNames.ICE_SNOWBALL, EntityTFIceSnowball.class, EntityTFIceSnowball::new, 150, 3, true); + helper.registerEntity(TFEntityNames.CHAIN_BLOCK, EntityTFChainBlock.class, EntityTFChainBlock::new, 80, 1, true); + helper.registerEntity(TFEntityNames.CUBE_OF_ANNIHILATION, EntityTFCubeOfAnnihilation.class, EntityTFCubeOfAnnihilation::new, 80, 1, true); + helper.registerEntity(TFEntityNames.SLIDER, EntityTFSlideBlock.class, EntityTFSlideBlock::new, 80, 1, true); + helper.registerEntity(TFEntityNames.BOGGARD, EntityTFBoggard.class, EntityTFBoggard::new); + helper.registerEntity(TFEntityNames.RISING_ZOMBIE, EntityTFRisingZombie.class, EntityTFRisingZombie::new); + } +} diff --git a/src/main/java/twilightforest/entity/TFEntityEggInfo.java b/src/main/java/twilightforest/entity/TFEntityEggInfo.java deleted file mode 100644 index 64a7620e3a..0000000000 --- a/src/main/java/twilightforest/entity/TFEntityEggInfo.java +++ /dev/null @@ -1,45 +0,0 @@ -package twilightforest.entity; - -import net.minecraft.stats.StatBase; -import net.minecraft.util.ChatComponentTranslation; - -/** - * Very similar to EntityEggInfo, but registers the stat info differently - */ -public class TFEntityEggInfo { - /** - * The entityID of the spawned mob - */ - public final int spawnedID; - /** - * Base color of the egg - */ - public final int primaryColor; - /** - * Color of the egg spots - */ - public final int secondaryColor; - public final StatBase killedStat; - public final StatBase killedByStat; - - public TFEntityEggInfo(int par1, int par2, int par3) - { - this.spawnedID = par1; - this.primaryColor = par2; - this.secondaryColor = par3; - this.killedStat = TFEntityEggInfo.makeEntityKillStat(this); - this.killedByStat = TFEntityEggInfo.makeEntityKilledByStat(this); - } - - public static StatBase makeEntityKillStat(TFEntityEggInfo eggInfo) - { - String s = TFCreatures.getStringFromID(eggInfo.spawnedID); - return s == null ? null : (new StatBase("stat.killEntity." + s, new ChatComponentTranslation("stat.entityKill", new Object[] {new ChatComponentTranslation("entity." + s + ".name", new Object[0])}))).registerStat(); - } - - public static StatBase makeEntityKilledByStat(TFEntityEggInfo p_151176_0_) - { - String s = TFCreatures.getStringFromID(p_151176_0_.spawnedID); - return s == null ? null : (new StatBase("stat.entityKilledBy." + s, new ChatComponentTranslation("stat.entityKilledBy", new Object[] {new ChatComponentTranslation("entity." + s + ".name", new Object[0])}))).registerStat(); - } -} diff --git a/src/main/java/twilightforest/entity/ai/EntityAICubeCenterOnSymbol.java b/src/main/java/twilightforest/entity/ai/EntityAICubeCenterOnSymbol.java index 349c3c0258..69c3dbf335 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAICubeCenterOnSymbol.java +++ b/src/main/java/twilightforest/entity/ai/EntityAICubeCenterOnSymbol.java @@ -1,24 +1,22 @@ package twilightforest.entity.ai; -import twilightforest.entity.EntityTFRovingCube; import net.minecraft.entity.ai.EntityAIBase; +import twilightforest.entity.EntityTFRovingCube; /** - * * This is a task that runs when we are near a symbol and have stopped pathfinding, but are not centered on the symbol. - * + *

* The goal of this task is to center on a symbol. - * - * @author benma_000 * + * @author benma_000 */ public class EntityAICubeCenterOnSymbol extends EntityAIBase { - - private EntityTFRovingCube myCube; - private double xPosition; - private double yPosition; - private double zPosition; - private double speed; + private final EntityTFRovingCube myCube; + private final double speed; + + private double xPosition; + private double yPosition; + private double zPosition; public EntityAICubeCenterOnSymbol(EntityTFRovingCube entityTFRovingCube, double d) { this.myCube = entityTFRovingCube; @@ -26,6 +24,7 @@ public EntityAICubeCenterOnSymbol(EntityTFRovingCube entityTFRovingCube, double this.yPosition = this.myCube.symbolY; this.zPosition = this.myCube.symbolZ; this.speed = d; + this.setMutexBits(1); } @Override @@ -34,55 +33,34 @@ public boolean shouldExecute() { this.yPosition = this.myCube.symbolY; this.zPosition = this.myCube.symbolZ; - + if (!this.myCube.getNavigator().noPath()) { return false; - } else if (this.isCloseToSymbol()) { - - return true; } else { - return false; + return isCloseToSymbol(); } } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - public boolean continueExecuting() - { - - - // inch towards it - double dist = this.distanceFromSymbol(); + @Override + public boolean shouldContinueExecuting() { + // inch towards it + this.myCube.getMoveHelper().setMoveTo(this.xPosition + 0.5F, this.yPosition, this.zPosition + 0.5F, this.speed); + return this.distanceFromSymbol() > 0.1F && this.isCourseTraversable(); + } - this.myCube.getMoveHelper().setMoveTo(this.xPosition + 0.5F, this.yPosition, this.zPosition + 0.5F, this.speed); - - - if (this.myCube.ticksExisted % 5 == 0) { - //System.out.println("Centering cube on symbol. Dist = " + dist); - //System.out.println("heading to " + this.xPosition + ", " + this.yPosition + ", " + this.zPosition); - } - - return dist > 0.1F && this.isCourseTraversable(); - } - - private boolean isCourseTraversable() { - + private boolean isCourseTraversable() { return this.distanceFromSymbol() < 100; } private boolean isCloseToSymbol() { - double dist = this.distanceFromSymbol(); - //System.out.println("are we close? Dist = " + dist); - + double dist = this.distanceFromSymbol(); return dist > 0.25F && dist < 10F; } - - public double distanceFromSymbol() { - double dx = this.xPosition - this.myCube.posX + 0.5F; - double dy = this.yPosition - this.myCube.posY; - double dz = this.zPosition - this.myCube.posZ + 0.5F; + + private double distanceFromSymbol() { + double dx = this.xPosition - this.myCube.posX + 0.5F; + double dy = this.yPosition - this.myCube.posY; + double dz = this.zPosition - this.myCube.posZ + 0.5F; return Math.sqrt(dx * dx + dy * dy + dz * dz); } diff --git a/src/main/java/twilightforest/entity/ai/EntityAICubeMoveToRedstoneSymbols.java b/src/main/java/twilightforest/entity/ai/EntityAICubeMoveToRedstoneSymbols.java index 813151922f..5162623178 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAICubeMoveToRedstoneSymbols.java +++ b/src/main/java/twilightforest/entity/ai/EntityAICubeMoveToRedstoneSymbols.java @@ -1,120 +1,85 @@ package twilightforest.entity.ai; -import twilightforest.entity.EntityTFRovingCube; import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.entity.ai.RandomPositionGenerator; import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import twilightforest.entity.EntityTFRovingCube; public class EntityAICubeMoveToRedstoneSymbols extends EntityAIBase { - private EntityTFRovingCube myCube; - private double xPosition; - private double yPosition; - private double zPosition; - private double speed; - + private final EntityTFRovingCube myCube; + private final double speed; + private BlockPos targetPos; + public EntityAICubeMoveToRedstoneSymbols(EntityTFRovingCube entityTFRovingCube, double d) { this.myCube = entityTFRovingCube; this.speed = d; + this.setMutexBits(1); } @Override public boolean shouldExecute() { - if (this.myCube.getRNG().nextInt(20) != 0) - { - return false; - } - else - { - //System.out.println("Cube scanning for symbol"); - - Vec3 vec3 = this.searchForRedstoneSymbol(this.myCube, 16, 5); + if (this.myCube.getRNG().nextInt(20) != 0) { + return false; + } else { + BlockPos pos = this.searchForRedstoneSymbol(this.myCube, 16, 5); + + if (pos == null) { + return false; + } else { + this.targetPos = pos; + return true; + } + } + } - if (vec3 == null) - { - return false; - } - else - { - this.xPosition = vec3.xCoord; - this.yPosition = vec3.yCoord; - this.zPosition = vec3.zCoord; - return true; - } - } + @Override + public boolean shouldContinueExecuting() { + return !this.myCube.getNavigator().noPath(); + } + + @Override + public void startExecuting() { + this.myCube.getNavigator().tryMoveToXYZ(targetPos.getX(), targetPos.getY(), targetPos.getZ(), this.speed); } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - public boolean continueExecuting() - { - return !this.myCube.getNavigator().noPath(); - } - /** - * Execute a one shot task or start executing a continuous task - */ - public void startExecuting() - { - this.myCube.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed); - } + /** + * Search the area for a redstone circle (8 redstone dust around a blank square) + */ + private BlockPos searchForRedstoneSymbol(EntityTFRovingCube myCube2, int xzRange, int yRange) { + BlockPos curPos = new BlockPos(myCube2); - /** - * Search the area for a redstone circle (8 redstone dust around a blank square) - */ - private Vec3 searchForRedstoneSymbol(EntityTFRovingCube myCube2, int xzRange, int yRange) { - - int curX = MathHelper.floor_double(myCube2.posX); - int curY = MathHelper.floor_double(myCube2.posY); - int curZ = MathHelper.floor_double(myCube2.posZ); - - boolean foundSymbol = false; - - for (int x = curX - xzRange; x < curX + xzRange; x++) { - for (int z = curZ - xzRange; z < curZ + xzRange; z++) { - for (int y = curY - yRange; y < curY + yRange; y++) { - if (this.isRedstoneSymbol(x, y, z)) { - - //System.out.println("Cube found symbol at " + x + ", " + y + ", " + z); - + for (int x = -xzRange; x < xzRange; x++) { + for (int z = -xzRange; z < xzRange; z++) { + for (int y = -yRange; y < yRange; y++) { + if (this.isRedstoneSymbol(curPos.add(x, y, z))) { this.myCube.hasFoundSymbol = true; - this.myCube.symbolX = x; - this.myCube.symbolY = y; - this.myCube.symbolZ = z; - - return Vec3.createVectorHelper(x, y, z); + this.myCube.symbolX = curPos.getX() + x; + this.myCube.symbolY = curPos.getY() + y; + this.myCube.symbolZ = curPos.getZ() + z; + + return curPos.add(x, y, z); } } } } - + return null; } - private boolean isRedstoneSymbol(int x, int y, int z) { - - //System.out.println("Cube checking area at " + x + ", " + y + ", " + z); - - if (!this.myCube.worldObj.blockExists(x, y, z) || !this.myCube.worldObj.isAirBlock(x, y, z)) { + private boolean isRedstoneSymbol(BlockPos pos) { + if (!this.myCube.world.isBlockLoaded(pos) || !this.myCube.world.isAirBlock(pos)) { return false; } else { // we found an air block, is it surrounded by redstone? - if (this.myCube.worldObj.getBlock(x + 1, y, z) == Blocks.redstone_wire - && this.myCube.worldObj.getBlock(x - 1, y, z) == Blocks.redstone_wire - && this.myCube.worldObj.getBlock(x, y, z + 1) == Blocks.redstone_wire - && this.myCube.worldObj.getBlock(x, y, z - 1) == Blocks.redstone_wire - && this.myCube.worldObj.getBlock(x + 1, y, z + 1) == Blocks.redstone_wire - && this.myCube.worldObj.getBlock(x - 1, y, z + 1) == Blocks.redstone_wire - && this.myCube.worldObj.getBlock(x + 1, y, z - 1) == Blocks.redstone_wire - && this.myCube.worldObj.getBlock(x - 1, y, z - 1) == Blocks.redstone_wire) { - - return true; - } else { - return false; + for (EnumFacing e : EnumFacing.VALUES) { + if (this.myCube.world.getBlockState(pos.offset(e)).getBlock() != Blocks.REDSTONE_WIRE) { + return false; + } } + + return true; } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAIPhantomAttackStart.java b/src/main/java/twilightforest/entity/ai/EntityAIPhantomAttackStart.java new file mode 100644 index 0000000000..bc339d0def --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAIPhantomAttackStart.java @@ -0,0 +1,35 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.util.math.BlockPos; +import twilightforest.entity.boss.EntityTFKnightPhantom; + +public class EntityAIPhantomAttackStart extends EntityAIBase { + + private final EntityTFKnightPhantom boss; + + public EntityAIPhantomAttackStart(EntityTFKnightPhantom entity) { + boss = entity; + setMutexBits(2); + } + + @Override + public boolean shouldExecute() { + return boss.getAttackTarget() != null && boss.getCurrentFormation() == EntityTFKnightPhantom.Formation.ATTACK_PLAYER_START; + } + + @Override + public void updateTask() { + EntityLivingBase target = boss.getAttackTarget(); + if (target != null) { + BlockPos targetPos = new BlockPos(target.lastTickPosX, target.lastTickPosY, target.lastTickPosZ); + + if (boss.isWithinHomeDistanceFromPosition(targetPos)) { + boss.setChargePos(targetPos); + } else { + boss.setChargePos(boss.getHomePosition()); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/ai/EntityAIPhantomThrowWeapon.java b/src/main/java/twilightforest/entity/ai/EntityAIPhantomThrowWeapon.java new file mode 100644 index 0000000000..c1bc846855 --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAIPhantomThrowWeapon.java @@ -0,0 +1,85 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; +import twilightforest.entity.boss.EntityTFKnightPhantom; +import twilightforest.entity.boss.EntityTFThrownWep; +import twilightforest.item.TFItems; + +public class EntityAIPhantomThrowWeapon extends EntityAIBase { + + private final EntityTFKnightPhantom boss; + + public EntityAIPhantomThrowWeapon(EntityTFKnightPhantom entity) { + boss = entity; + setMutexBits(2); + } + + @Override + public boolean shouldExecute() { + return boss.getAttackTarget() != null && boss.getCurrentFormation() == EntityTFKnightPhantom.Formation.ATTACK_PLAYER_ATTACK; + } + + @Override + public void updateTask() { + if (boss.getAttackTarget() != null && boss.getTicksProgress() % 4 == 0) { + if (boss.isAxeKnight()) + launchAxeAt(boss.getAttackTarget()); + else if (boss.isPickKnight()) + launchPicks(); + } + } + + private void launchAxeAt(Entity targetedEntity) { + float bodyFacingAngle = ((boss.renderYawOffset * 3.141593F) / 180F); + double sx = boss.posX + (MathHelper.cos(bodyFacingAngle) * 1); + double sy = boss.posY + (boss.height * 0.82); + double sz = boss.posZ + (MathHelper.sin(bodyFacingAngle) * 1); + + double tx = targetedEntity.posX - sx; + double ty = (targetedEntity.getEntityBoundingBox().minY + (double) (targetedEntity.height / 2.0F)) - (boss.posY + boss.height / 2.0F); + double tz = targetedEntity.posZ - sz; + + boss.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 1.0F, (boss.getRNG().nextFloat() - boss.getRNG().nextFloat()) * 0.2F + 0.4F); + EntityTFThrownWep projectile = new EntityTFThrownWep(boss.world, boss).setItem(new ItemStack(TFItems.knightmetal_axe)); + + float speed = 0.75F; + + projectile.shoot(tx, ty, tz, speed, 1.0F); + + projectile.setLocationAndAngles(sx, sy, sz, boss.rotationYaw, boss.rotationPitch); + + boss.world.spawnEntity(projectile); + } + + private void launchPicks() { + boss.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 1.0F, (boss.getRNG().nextFloat() - boss.getRNG().nextFloat()) * 0.2F + 0.4F); + + for (int i = 0; i < 8; i++) { + float throwAngle = i * 3.14159165F / 4F; + + double sx = boss.posX + (MathHelper.cos(throwAngle) * 1); + double sy = boss.posY + (boss.height * 0.82); + double sz = boss.posZ + (MathHelper.sin(throwAngle) * 1); + + double vx = MathHelper.cos(throwAngle); + double vy = 0; + double vz = MathHelper.sin(throwAngle); + + + EntityTFThrownWep projectile = new EntityTFThrownWep(boss.world, boss).setDamage(3).setVelocity(0.015F).setItem(new ItemStack(TFItems.knightmetal_pickaxe)); + + + projectile.setLocationAndAngles(sx, sy, sz, i * 45F, boss.rotationPitch); + + float speed = 0.5F; + + projectile.shoot(vx, vy, vz, speed, 1.0F); + + boss.world.spawnEntity(projectile); + } + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/ai/EntityAIStayNearHome.java b/src/main/java/twilightforest/entity/ai/EntityAIStayNearHome.java index 5608b6b246..30fc7b5192 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAIStayNearHome.java +++ b/src/main/java/twilightforest/entity/ai/EntityAIStayNearHome.java @@ -3,69 +3,39 @@ import net.minecraft.entity.EntityCreature; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.ai.RandomPositionGenerator; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.Vec3d; public class EntityAIStayNearHome extends EntityAIBase { - - private EntityCreature entity; - private float speed; + private final EntityCreature entity; + private final float speed; public EntityAIStayNearHome(EntityCreature entityTFYetiAlpha, float sp) { this.entity = entityTFYetiAlpha; this.speed = sp; - this.setMutexBits(1); - + this.setMutexBits(1); } @Override public boolean shouldExecute() { - boolean isOutOfRange = !this.entity.isWithinHomeDistanceCurrentPosition(); - -// if (isOutOfRange) { -// System.out.println("This creature is outside home range, moving home!"); -// } else { -// System.out.println("This creature is inside home range"); -// } - - return isOutOfRange; + return !this.entity.isWithinHomeDistanceCurrentPosition(); } - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - public boolean continueExecuting() - { + @Override + public boolean shouldContinueExecuting() { return !this.entity.getNavigator().noPath(); } -// /** -// * Execute a one shot task or start executing a continuous task -// */ -// public void startExecuting() -// { -// this.entity.getNavigator().tryMoveToXYZ(this.entity.getHomePosition().posX, this.entity.getHomePosition().posY, this.entity.getHomePosition().posZ, this.speed); -// } - - /** - * Execute a one shot task or start executing a continuous task - */ - public void startExecuting() - { - //this.insidePosX = -1; - - if (this.entity.getDistanceSq(this.entity.getHomePosition().posX, this.entity.getHomePosition().posY, this.entity.getHomePosition().posZ) > 256.0D) - { - Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.entity, 14, 3, Vec3.createVectorHelper(this.entity.getHomePosition().posX + 0.5D, this.entity.getHomePosition().posY, this.entity.getHomePosition().posZ + 0.5D)); - - if (vec3 != null) - { - this.entity.getNavigator().tryMoveToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord, speed); - } - } - else - { - this.entity.getNavigator().tryMoveToXYZ(this.entity.getHomePosition().posX + 0.5D, this.entity.getHomePosition().posY, this.entity.getHomePosition().posZ + 0.5D, speed); - } - } + @Override + public void startExecuting() { + if (this.entity.getDistanceSq(this.entity.getHomePosition()) > 256.0D) { + Vec3d vec3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.entity, 14, 3, new Vec3d(this.entity.getHomePosition().getX() + 0.5D, this.entity.getHomePosition().getY(), this.entity.getHomePosition().getZ() + 0.5D)); + + if (vec3 != null) { + this.entity.getNavigator().tryMoveToXYZ(vec3.x, vec3.y, vec3.z, speed); + } + } else { + this.entity.getNavigator().tryMoveToXYZ(this.entity.getHomePosition().getX() + 0.5D, this.entity.getHomePosition().getY(), this.entity.getHomePosition().getZ() + 0.5D, speed); + } + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFAvoidFrontalAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFAvoidFrontalAttack.java index 23d1de6d22..fd33f6c4c1 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFAvoidFrontalAttack.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFAvoidFrontalAttack.java @@ -4,151 +4,120 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import twilightforest.entity.EntityTFRedcap; public class EntityAITFAvoidFrontalAttack extends EntityAIBase { - EntityLivingBase entityTarget; - EntityLiving me; - float speed; - boolean lefty; - double xPosition; - double yPosition; - double zPosition; - - double minDistance = 3.0; - double maxDistance = 6.0; + private final EntityLiving me; + final float speed; + private final boolean lefty; + + private EntityLivingBase entityTarget; + private double xPosition; + private double yPosition; + private double zPosition; + + private double minDistance = 3.0; + private double maxDistance = 6.0; public EntityAITFAvoidFrontalAttack(EntityTFRedcap entityTFRedcap, float moveSpeed) { this.me = entityTFRedcap; this.speed = moveSpeed; - this.lefty = me.worldObj.rand.nextBoolean(); - this.setMutexBits(1); + this.lefty = me.world.rand.nextBoolean(); + this.setMutexBits(3); } @Override public boolean shouldExecute() { - EntityLivingBase attackTarget = this.me.getAttackTarget(); - - if (attackTarget == null || attackTarget.getDistanceToEntity(me) > maxDistance || attackTarget.getDistanceToEntity(me) < minDistance || !isTargetLookingAtMe(attackTarget)) { - return false; - } - else - { - this.entityTarget = attackTarget; - Vec3 avoidPos = findCirclePoint(me, entityTarget, 5, lefty ? 1 : -1); - - if (avoidPos == null) - { - return false; - } - else - { - this.xPosition = avoidPos.xCoord; - this.yPosition = avoidPos.yCoord; - this.zPosition = avoidPos.zCoord; - return true; - } - } + EntityLivingBase attackTarget = this.me.getAttackTarget(); + + if (attackTarget == null || attackTarget.getDistance(me) > maxDistance || attackTarget.getDistance(me) < minDistance || !isTargetLookingAtMe(attackTarget)) { + return false; + } else { + this.entityTarget = attackTarget; + Vec3d avoidPos = findCirclePoint(me, entityTarget, 5, lefty ? 1 : -1); + + if (avoidPos == null) { + return false; + } else { + this.xPosition = avoidPos.x; + this.yPosition = avoidPos.y; + this.zPosition = avoidPos.z; + return true; + } + } + + } + + @Override + public void startExecuting() { + this.me.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed); + } + + @Override + public boolean shouldContinueExecuting() { + EntityLivingBase attackTarget = this.me.getAttackTarget(); + + if (attackTarget == null) { + return false; + } else if (!this.entityTarget.isEntityAlive()) { + return false; + } else if (this.me.getNavigator().noPath()) { + return false; + } + return attackTarget.getDistance(me) < maxDistance && attackTarget.getDistance(me) > minDistance && isTargetLookingAtMe(attackTarget); } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - //System.out.println("avoid ai starting"); - this.me.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed); - } - - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - EntityLivingBase attackTarget = this.me.getAttackTarget(); - - if (attackTarget == null) { - return false; - } - else if (!this.entityTarget.isEntityAlive()) { - return false; - } - else if (this.me.getNavigator().noPath()) { - return false; - } - - boolean shouldContinue = attackTarget.getDistanceToEntity(me) < maxDistance && attackTarget.getDistanceToEntity(me) > minDistance && isTargetLookingAtMe(attackTarget); - - //System.out.println("ai evaluating should continue to " + shouldContinue); - - return shouldContinue; - } - - /** - * Updates the task - */ - @Override - public void updateTask() - { - this.me.getLookHelper().setLookPositionWithEntity(this.entityTarget, 30.0F, 30.0F); - } - - - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.entityTarget = null; - this.me.getNavigator().clearPathEntity(); - } - - + + @Override + public void updateTask() { + this.me.getLookHelper().setLookPositionWithEntity(this.entityTarget, 30.0F, 30.0F); + } + + @Override + public void resetTask() { + this.entityTarget = null; + this.me.getNavigator().clearPath(); + } + /** - * Finds a point that allows us to circle the player clockwise. - */ - protected Vec3 findCirclePoint(Entity circler, Entity toCircle, double radius, double rotation) { - - // compute angle - double vecx = circler.posX - toCircle.posX; - double vecz = circler.posZ - toCircle.posZ; - float rangle = (float)(Math.atan2(vecz, vecx)); - - // add a little, so he circles - rangle += rotation; - - // figure out where we're headed from the target angle - double dx = MathHelper.cos(rangle) * radius; - double dz = MathHelper.sin(rangle) * radius; - - // add that to the target entity's position, and we have our destination - return Vec3.createVectorHelper(toCircle.posX + dx, circler.boundingBox.minY, toCircle.posZ + dz); - } - - - /** - * Fairly straightforward. Returns true in a 120 degree arc in front of the target's view. - * @return - */ - public boolean isTargetLookingAtMe(EntityLivingBase attackTarget) { - // find angle of approach - double dx = me.posX - attackTarget.posX; - double dz = me.posZ - attackTarget.posZ; - float angle = (float)((Math.atan2(dz, dx) * 180D) / 3.1415927410125732D) - 90F; - - float difference = MathHelper.abs((attackTarget.rotationYaw - angle) % 360); - -// System.out.println("Difference in angle of approach is " + difference); - - return difference < 60 || difference > 300; - } - + * Finds a point that allows us to circle the player clockwise. + */ + protected Vec3d findCirclePoint(Entity circler, Entity toCircle, double radius, double rotation) { + + // compute angle + double vecx = circler.posX - toCircle.posX; + double vecz = circler.posZ - toCircle.posZ; + float rangle = (float) (Math.atan2(vecz, vecx)); + + // add a little, so he circles + rangle += rotation; + + // figure out where we're headed from the target angle + double dx = MathHelper.cos(rangle) * radius; + double dz = MathHelper.sin(rangle) * radius; + + // add that to the target entity's position, and we have our destination + return new Vec3d(toCircle.posX + dx, circler.getEntityBoundingBox().minY, toCircle.posZ + dz); + } + + + /** + * Fairly straightforward. Returns true in a 120 degree arc in front of the target's view. + * + * @return + */ + public boolean isTargetLookingAtMe(EntityLivingBase attackTarget) { + // find angle of approach + double dx = me.posX - attackTarget.posX; + double dz = me.posZ - attackTarget.posZ; + float angle = (float) ((Math.atan2(dz, dx) * 180D) / 3.1415927410125732D) - 90F; + + float difference = MathHelper.abs((attackTarget.rotationYaw - angle) % 360); + + return difference < 60 || difference > 300; + } + } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFBirdFly.java b/src/main/java/twilightforest/entity/ai/EntityAITFBirdFly.java index e3e8368303..950e67bdd0 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFBirdFly.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFBirdFly.java @@ -5,29 +5,15 @@ public class EntityAITFBirdFly extends EntityAIBase { - private EntityTFTinyBird entity; + private EntityTFTinyBird entity; + + public EntityAITFBirdFly(EntityTFTinyBird bird) { + this.entity = bird; + this.setMutexBits(5); + } - public EntityAITFBirdFly(EntityTFTinyBird par1EntityCreature) - { - this.entity = par1EntityCreature; - this.setMutexBits(5); - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ @Override public boolean shouldExecute() { - return !entity.isBirdLanded(); + return !entity.isBirdLanded(); } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return !entity.isBirdLanded(); - } - } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFBreathAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFBreathAttack.java index f96879f289..f7e01a9cfb 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFBreathAttack.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFBreathAttack.java @@ -1,207 +1,171 @@ package twilightforest.entity.ai; -import java.util.List; - import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import twilightforest.entity.IBreathAttacker; -public class EntityAITFBreathAttack extends EntityAIBase { - - private EntityLiving entityHost; - private EntityLivingBase attackTarget; - - protected double breathX; - protected double breathY; - protected double breathZ; - - private int maxDuration; - private float attackChance; - private float breathRange; - +import java.util.List; + +public class EntityAITFBreathAttack extends EntityAIBase { + + private final T entityHost; + private EntityLivingBase attackTarget; + + private double breathX; + private double breathY; + private double breathZ; + + private final int maxDuration; + private final float attackChance; + private final float breathRange; + private int durationLeft; - public EntityAITFBreathAttack(EntityLiving par1EntityLiving, float speed, float range, int time, float chance) - { - this.entityHost = par1EntityLiving; - this.breathRange = range; - this.maxDuration = time; - this.attackChance = chance; - this.setMutexBits(7); - } - - /** - * Breathe when we are within range and line of sight of the target - */ + public EntityAITFBreathAttack(T living, float speed, float range, int time, float chance) { + this.entityHost = living; + this.breathRange = range; + this.maxDuration = time; + this.attackChance = chance; + this.setMutexBits(7); + } + @Override - public boolean shouldExecute() - { - this.attackTarget = this.entityHost.getAttackTarget(); - - if (this.attackTarget == null || this.entityHost.getDistanceToEntity(attackTarget) > this.breathRange || !this.entityHost.canEntityBeSeen(attackTarget)) - { - return false; - } - else - { - breathX = attackTarget.posX; - breathY = attackTarget.posY + attackTarget.getEyeHeight(); - breathZ = attackTarget.posZ; - - return this.entityHost.getRNG().nextFloat() < this.attackChance; - } + public boolean shouldExecute() { + this.attackTarget = this.entityHost.getAttackTarget(); + + if (this.attackTarget == null || this.entityHost.getDistance(attackTarget) > this.breathRange || !this.entityHost.getEntitySenses().canSee(attackTarget)) { + return false; + } else { + breathX = attackTarget.posX; + breathY = attackTarget.posY + attackTarget.getEyeHeight(); + breathZ = attackTarget.posZ; + + return this.entityHost.getRNG().nextFloat() < this.attackChance; + } } /** * Initialize counters */ @Override - public void startExecuting() - { + public void startExecuting() { this.durationLeft = this.maxDuration; - // set breather flag - if (this.entityHost instanceof IBreathAttacker) - { - ((IBreathAttacker) entityHost).setBreathing(true); - } + this.entityHost.setBreathing(true); } /** * Keep breathing until the target dies, or moves out of range or line of sight */ @Override - public boolean continueExecuting() - { - return this.durationLeft > 0 && !this.entityHost.isDead && !this.attackTarget.isDead - && this.entityHost.getDistanceToEntity(attackTarget) <= this.breathRange - && this.entityHost.canEntityBeSeen(attackTarget); + public boolean shouldContinueExecuting() { + return this.durationLeft > 0 && !this.entityHost.isDead && !this.attackTarget.isDead + && this.entityHost.getDistance(attackTarget) <= this.breathRange + && this.entityHost.getEntitySenses().canSee(attackTarget); } /** * Update timers, deal damage */ @Override - public void updateTask() - { + public void updateTask() { this.durationLeft--; // why do we need both of these? - this.entityHost.getLookHelper().setLookPosition(breathX, breathY, breathZ, 100.0F, 100.0F); + this.entityHost.getLookHelper().setLookPosition(breathX, breathY, breathZ, 100.0F, 100.0F); faceVec(breathX, breathY, breathZ, 100.0F, 100.0F); - - if ((this.maxDuration - this.durationLeft) > 5) - { + + if ((this.maxDuration - this.durationLeft) > 5) { // anyhoo, deal damage - Entity target = getHeadLookTarget(); - - if (target != null) - { - ((IBreathAttacker) entityHost).doBreathAttack(target); - } + Entity target = getHeadLookTarget(); + if (target != null) { + this.entityHost.doBreathAttack(target); + } } - } @Override - public void resetTask() - { + public void resetTask() { this.durationLeft = 0; - + this.attackTarget = null; // set breather flag - if (this.entityHost instanceof IBreathAttacker) - { - ((IBreathAttacker) entityHost).setBreathing(false); - } + this.entityHost.setBreathing(false); } - /** * What, if anything, is the head currently looking at? */ - @SuppressWarnings("unchecked") private Entity getHeadLookTarget() { Entity pointedEntity = null; double range = 30.0D; - Vec3 srcVec = Vec3.createVectorHelper(this.entityHost.posX, this.entityHost.posY + 0.25, this.entityHost.posZ); - Vec3 lookVec = this.entityHost.getLook(1.0F); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - float var9 = 3.0F; - List possibleList = this.entityHost.worldObj.getEntitiesWithinAABBExcludingEntity(this.entityHost, this.entityHost.boundingBox.addCoord(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range).expand(var9, var9, var9)); - double hitDist = 0; - - for (Entity possibleEntity : possibleList) - { - if (possibleEntity.canBeCollidedWith() && possibleEntity != this.entityHost) - { - float borderSize = possibleEntity.getCollisionBorderSize(); - AxisAlignedBB collisionBB = possibleEntity.boundingBox.expand((double)borderSize, (double)borderSize, (double)borderSize); - MovingObjectPosition interceptPos = collisionBB.calculateIntercept(srcVec, destVec); - - if (collisionBB.isVecInside(srcVec)) - { - if (0.0D < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = 0.0D; - } - } - else if (interceptPos != null) - { - double possibleDist = srcVec.distanceTo(interceptPos.hitVec); - - if (possibleDist < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = possibleDist; - } - } - } - } + double offset = 3.0D; + Vec3d srcVec = new Vec3d(this.entityHost.posX, this.entityHost.posY + 0.25, this.entityHost.posZ); + Vec3d lookVec = this.entityHost.getLook(1.0F); + Vec3d destVec = srcVec.add(lookVec.x * range, lookVec.y * range, lookVec.z * range); + float var9 = 0.5F; + List possibleList = this.entityHost.world.getEntitiesWithinAABBExcludingEntity(this.entityHost, this.entityHost.getEntityBoundingBox().offset(lookVec.x * offset, lookVec.y * offset, lookVec.z * offset).grow(var9, var9, var9)); + double hitDist = 0; + + for (Entity possibleEntity : possibleList) { + if (possibleEntity.canBeCollidedWith() && possibleEntity != this.entityHost) { + float borderSize = possibleEntity.getCollisionBorderSize(); + AxisAlignedBB collisionBB = possibleEntity.getEntityBoundingBox().grow((double) borderSize, (double) borderSize, (double) borderSize); + RayTraceResult interceptPos = collisionBB.calculateIntercept(srcVec, destVec); + + if (collisionBB.contains(srcVec)) { + if (0.0D < hitDist || hitDist == 0.0D) { + pointedEntity = possibleEntity; + hitDist = 0.0D; + } + } else if (interceptPos != null) { + double possibleDist = srcVec.distanceTo(interceptPos.hitVec); + + if (possibleDist < hitDist || hitDist == 0.0D) { + pointedEntity = possibleEntity; + hitDist = possibleDist; + } + } + } + } return pointedEntity; } - + /** * Face the head towards a specific Vector */ - public void faceVec(double xCoord, double yCoord, double zCoord, float yawConstraint, float pitchConstraint) { - double xOffset = xCoord - entityHost.posX; - double zOffset = zCoord - entityHost.posZ; - double yOffset = (entityHost.posY + 0.25) - yCoord; - - double distance = MathHelper.sqrt_double(xOffset * xOffset + zOffset * zOffset); - float xyAngle = (float)((Math.atan2(zOffset, xOffset) * 180D) / Math.PI) - 90F; - float zdAngle = (float)(-((Math.atan2(yOffset, distance) * 180D) / Math.PI)); + public void faceVec(double x, double y, double z, float yawConstraint, float pitchConstraint) { + double xOffset = x - entityHost.posX; + double zOffset = z - entityHost.posZ; + double yOffset = (entityHost.posY + 0.25) - y; + + double distance = MathHelper.sqrt(xOffset * xOffset + zOffset * zOffset); + float xyAngle = (float) ((Math.atan2(zOffset, xOffset) * 180D) / Math.PI) - 90F; + float zdAngle = (float) (-((Math.atan2(yOffset, distance) * 180D) / Math.PI)); entityHost.rotationPitch = -updateRotation(entityHost.rotationPitch, zdAngle, pitchConstraint); entityHost.rotationYaw = updateRotation(entityHost.rotationYaw, xyAngle, yawConstraint); - + } - /** - * Arguments: current rotation, intended rotation, max increment. - */ - private float updateRotation(float par1, float par2, float par3) - { - float var4 = MathHelper.wrapAngleTo180_float(par2 - par1); + /** + * Arguments: current rotation, intended rotation, max increment. + */ + private float updateRotation(float current, float target, float maxDelta) { + float delta = MathHelper.wrapDegrees(target - current); - if (var4 > par3) - { - var4 = par3; - } + if (delta > maxDelta) { + delta = maxDelta; + } - if (var4 < -par3) - { - var4 = -par3; - } + if (delta < -maxDelta) { + delta = -maxDelta; + } - return par1 + var4; + return current + delta; } - - } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFChargeAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFChargeAttack.java index 400d8706af..9701976750 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFChargeAttack.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFChargeAttack.java @@ -4,184 +4,166 @@ import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; -import twilightforest.entity.EntityTFMinotaur; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.event.ForgeEventFactory; import twilightforest.entity.ITFCharger; +import twilightforest.util.EntityUtil; public class EntityAITFChargeAttack extends EntityAIBase { - protected static final double MIN_RANGE_SQ = 16.0D; - protected static final double MAX_RANGE_SQ = 64.0D; - protected static final int FREQ = 1; - - protected EntityCreature charger; - protected EntityLivingBase chargeTarget; - protected double chargeX; - protected double chargeY; - protected double chargeZ; + private static final double MIN_RANGE_SQ = 16.0D; + private static final double MAX_RANGE_SQ = 64.0D; + private static final int FREQ = 1; + + private EntityCreature charger; + private EntityLivingBase chargeTarget; + private double chargeX; + private double chargeY; + private double chargeZ; protected float speed; - - protected int windup; - - protected boolean hasAttacked; - public EntityAITFChargeAttack(EntityCreature entityLiving, float f) { + private final boolean canBreak; + + private int windup; + + private boolean hasAttacked; + + public EntityAITFChargeAttack(EntityCreature entityLiving, float f, boolean canBreak) { this.charger = entityLiving; this.speed = f; + this.canBreak = canBreak; this.windup = 0; this.hasAttacked = false; this.setMutexBits(3); } - /** - * Returns whether the EntityAIBase should begin execution. - */ @Override public boolean shouldExecute() { - this.chargeTarget = this.charger.getAttackTarget(); - - if (this.chargeTarget == null) - { - return false; - } - else - { - double distance = this.charger.getDistanceSqToEntity(this.chargeTarget); - if (distance < MIN_RANGE_SQ || distance > MAX_RANGE_SQ) { - return false; - } - else if (!this.charger.onGround) { - return false; - } - else { - Vec3 chargePos = findChargePoint(charger, chargeTarget, 2.1); - boolean canSeeTargetFromDest = chargeTarget.worldObj.rayTraceBlocks(Vec3.createVectorHelper(chargeTarget.posX, chargeTarget.posY + chargeTarget.getEyeHeight(), chargeTarget.posZ), chargePos) == null; - if (chargePos == null || !canSeeTargetFromDest) - { - return false; - } - else - { - chargeX = chargePos.xCoord; - chargeY = chargePos.yCoord; - chargeZ = chargePos.zCoord; - - //System.out.println("Setting charge position to " + chargePos.xCoord + ", " + chargePos.yCoord + ", " + chargePos.zCoord); - - return this.charger.getRNG().nextInt(FREQ) == 0; - } - } - - } + this.chargeTarget = this.charger.getAttackTarget(); + + if (this.chargeTarget == null) { + return false; + } else { + double distance = this.charger.getDistanceSq(this.chargeTarget); + if (distance < MIN_RANGE_SQ || distance > MAX_RANGE_SQ) { + return false; + } else if (!this.charger.onGround) { + return false; + } else { + Vec3d chargePos = findChargePoint(charger, chargeTarget, 2.1); + boolean canSeeTargetFromDest = charger.getEntitySenses().canSee(chargeTarget); + if (!canSeeTargetFromDest) { + return false; + } else { + chargeX = chargePos.x; + chargeY = chargePos.y; + chargeZ = chargePos.z; + + return this.charger.getRNG().nextInt(FREQ) == 0; + } + } + + } + } + + @Override + public void startExecuting() { + this.windup = 15 + this.charger.getRNG().nextInt(30); + } + + @Override + public boolean shouldContinueExecuting() { + return windup > 0 || !this.charger.getNavigator().noPath(); + } + + @Override + public void updateTask() { + // look where we're going + this.charger.getLookHelper().setLookPosition(chargeX, chargeY - 1, chargeZ, 10.0F, this.charger.getVerticalFaceSpeed()); + + if (windup > 0) { + if (--windup == 0) { + // actually charge! + + this.charger.getNavigator().tryMoveToXYZ(chargeX, chargeY, chargeZ, this.speed); + } else { + this.charger.limbSwingAmount += 0.8; + + if (this.charger instanceof ITFCharger) { + ((ITFCharger) charger).setCharging(true); + } + } + } else if (canBreak) { + if (!charger.world.isRemote && ForgeEventFactory.getMobGriefingEvent(charger.world, charger)) { + + AxisAlignedBB bb = charger.getEntityBoundingBox(); + int minx = MathHelper.floor(bb.minX - 0.75D); + int miny = MathHelper.floor(bb.minY + 0.0D); + int minz = MathHelper.floor(bb.minZ - 0.75D); + int maxx = MathHelper.floor(bb.maxX + 0.75D); + int maxy = MathHelper.floor(bb.maxY + 0.15D); + int maxz = MathHelper.floor(bb.maxZ + 0.75D); + + BlockPos min = new BlockPos(minx, miny, minz); + BlockPos max = new BlockPos(maxx, maxy, maxz); + + if (charger.world.isAreaLoaded(min, max)) { + for (BlockPos pos : BlockPos.getAllInBox(min, max)) { + if (EntityUtil.canDestroyBlock(charger.world, pos, charger) && charger.world.getTileEntity(pos) == null) { + charger.world.destroyBlock(pos, true); + } + } + } + } + } + + // attack the target when we get in range + double rangeSq = this.charger.width * 2.1F * this.charger.width * 2.1F; + + if (this.charger.getDistanceSq(this.chargeTarget.posX, this.chargeTarget.getEntityBoundingBox().minY, this.chargeTarget.posZ) <= rangeSq) { + if (!this.hasAttacked) { + this.hasAttacked = true; + this.charger.attackEntityAsMob(this.chargeTarget); + } + } + } - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - this.windup = 15 + this.charger.getRNG().nextInt(30); - } - - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return windup > 0 || !this.charger.getNavigator().noPath(); - } - - /** - * Updates the task - */ - @Override - public void updateTask() - { - // look where we're going - this.charger.getLookHelper().setLookPosition(chargeX, chargeY - 1, chargeZ, 10.0F, this.charger.getVerticalFaceSpeed()); - - if (windup > 0) - { - if (--windup == 0) - { - // actually charge! - - this.charger.getNavigator().tryMoveToXYZ(chargeX, chargeY, chargeZ, this.speed); - } - else - { - //System.out.println("charging in " + windup); - this.charger.limbSwingAmount += 0.8; - - if (this.charger instanceof ITFCharger) - { - ((ITFCharger)charger).setCharging(true); - } - } - } - - // attack the target when we get in range - double var1 = this.charger.width * 2.1F * this.charger.width * 2.1F; - - if (this.charger.getDistanceSq(this.chargeTarget.posX, this.chargeTarget.boundingBox.minY, this.chargeTarget.posZ) <= var1) - { - if (!this.hasAttacked) - { - this.hasAttacked = true; - this.charger.attackEntityAsMob(this.chargeTarget); - } - } - - } - - - /** - * Resets the task - */ - @Override - public void resetTask() - { - //System.out.println("Resetting charge task, we're done"); - - this.windup = 0; - this.chargeTarget = null; - this.hasAttacked = false; - - if (this.charger instanceof ITFCharger) - { - ((ITFCharger)charger).setCharging(false); + @Override + public void resetTask() { + this.windup = 0; + this.chargeTarget = null; + this.hasAttacked = false; + + if (this.charger instanceof ITFCharger) { + ((ITFCharger) charger).setCharging(false); } + } - } - /** - * Finds a point that is overshoot blocks "beyond" the target from our position. - */ - protected Vec3 findChargePoint(Entity attacker, Entity target, double overshoot) { - - // compute angle - double vecx = target.posX - attacker.posX; - double vecz = target.posZ - attacker.posZ; - float rangle = (float)(Math.atan2(vecz, vecx)); - - double distance = MathHelper.sqrt_double(vecx * vecx + vecz * vecz); - - // figure out where we're headed from the target angle - double dx = MathHelper.cos(rangle) * (distance + overshoot); - double dz = MathHelper.sin(rangle) * (distance + overshoot); - -// System.out.println("Charge position is " + (attacker.posX + dx) + ", " + (attacker.posZ + dz)); -// System.out.println("Target position is " + target.posX + ", " + target.posZ); - - // add that to the target entity's position, and we have our destination - return Vec3.createVectorHelper(attacker.posX + dx, target.posY, attacker.posZ + dz); - } + * Finds a point that is overshoot blocks "beyond" the target from our position. + */ + protected Vec3d findChargePoint(Entity attacker, Entity target, double overshoot) { + + // compute angle + double vecx = target.posX - attacker.posX; + double vecz = target.posZ - attacker.posZ; + float rangle = (float) (Math.atan2(vecz, vecx)); + + double distance = MathHelper.sqrt(vecx * vecx + vecz * vecz); + + // figure out where we're headed from the target angle + double dx = MathHelper.cos(rangle) * (distance + overshoot); + double dz = MathHelper.sin(rangle) * (distance + overshoot); + + // add that to the target entity's position, and we have our destination + return new Vec3d(attacker.posX + dx, target.posY, attacker.posZ + dz); + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFCollideAttackFixed.java b/src/main/java/twilightforest/entity/ai/EntityAITFCollideAttackFixed.java deleted file mode 100644 index 0814d6785a..0000000000 --- a/src/main/java/twilightforest/entity/ai/EntityAITFCollideAttackFixed.java +++ /dev/null @@ -1,183 +0,0 @@ -package twilightforest.entity.ai; - -import net.minecraft.entity.EntityCreature; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.pathfinding.PathEntity; -import net.minecraft.pathfinding.PathPoint; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; - -/** - * This is a copy of EntityAIAttackOnCollide modified to change a few hardcoded behaviors - * - * @author Mojang - * - */ -public class EntityAITFCollideAttackFixed extends EntityAIBase -{ - World worldObj; - EntityCreature attacker; - /** - * An amount of decrementing ticks that allows the entity to attack once the tick reaches 0. - */ - int attackTick; - /** The speed with which the mob will approach the target */ - double speedTowardsTarget; - /** - * When true, the mob will continue chasing its target, even if it can't find a path to them right now. - */ - boolean longMemory; - /** The PathEntity of our entity. */ - PathEntity entityPathEntity; - Class classTarget; - private int delayTicks; - private double pathX; - private double pathY; - private double pathZ; - private int failedPathFindingPenalty; - - public EntityAITFCollideAttackFixed(EntityCreature par1EntityCreature, Class par2Class, double par3, boolean par5) - { - this(par1EntityCreature, par3, par5); - this.classTarget = par2Class; - } - - public EntityAITFCollideAttackFixed(EntityCreature par1EntityCreature, double par2, boolean par4) - { - this.attacker = par1EntityCreature; - this.worldObj = par1EntityCreature.worldObj; - this.speedTowardsTarget = par2; - this.longMemory = par4; - this.setMutexBits(3); - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ - public boolean shouldExecute() - { - EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); - - if (entitylivingbase == null) - { - return false; - } - else if (!entitylivingbase.isEntityAlive()) - { - return false; - } - else if (this.classTarget != null && !this.classTarget.isAssignableFrom(entitylivingbase.getClass())) - { - return false; - } - else - { - if (-- this.delayTicks <= 0) - { - this.entityPathEntity = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase); - this.delayTicks = 4 + this.attacker.getRNG().nextInt(7); - return this.entityPathEntity != null; - } - else - { - return true; - } - } - } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - public boolean continueExecuting() - { - EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); - return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!this.longMemory ? !this.attacker.getNavigator().noPath() : this.attacker.isWithinHomeDistance(MathHelper.floor_double(entitylivingbase.posX), MathHelper.floor_double(entitylivingbase.posY), MathHelper.floor_double(entitylivingbase.posZ)))); - } - - /** - * Execute a one shot task or start executing a continuous task - */ - public void startExecuting() - { - this.attacker.getNavigator().setPath(this.entityPathEntity, this.speedTowardsTarget); - this.delayTicks = 0; - } - - /** - * Resets the task - */ - public void resetTask() - { - this.attacker.getNavigator().clearPathEntity(); - } - - /** - * Updates the task - */ - public void updateTask() - { - EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); - this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F); - - double distanceToAttacker = this.attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ); - double attackRange = (double)(this.attacker.width * 2.0F * this.attacker.width * 2.0F + entitylivingbase.width); - - --this.delayTicks; - - if ((this.longMemory || this.attacker.getEntitySenses().canSee(entitylivingbase)) && this.delayTicks <= 0 && (this.pathX == 0.0D && this.pathY == 0.0D && this.pathZ == 0.0D || entitylivingbase.getDistanceSq(this.pathX, this.pathY, this.pathZ) >= 1.0D || this.attacker.getRNG().nextFloat() < 0.05F)) - { - this.pathX = entitylivingbase.posX; - this.pathY = entitylivingbase.boundingBox.minY; - this.pathZ = entitylivingbase.posZ; - this.delayTicks = failedPathFindingPenalty + 4 + this.attacker.getRNG().nextInt(7); - - if (this.attacker.getNavigator().getPath() != null) - { - PathPoint finalPathPoint = this.attacker.getNavigator().getPath().getFinalPathPoint(); - if (finalPathPoint != null && entitylivingbase.getDistanceSq(finalPathPoint.xCoord, finalPathPoint.yCoord, finalPathPoint.zCoord) < 1) - { - failedPathFindingPenalty = 0; - } - else - { - failedPathFindingPenalty += 10; - } - } - else - { - failedPathFindingPenalty += 10; - } - - if (distanceToAttacker > 1024.0D) - { - this.delayTicks += 10; - } - else if (distanceToAttacker > 256.0D) - { - this.delayTicks += 5; - } - - if (!this.attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, this.speedTowardsTarget)) - { - this.delayTicks += 15; - } - } - - this.attackTick = Math.max(this.attackTick - 1, 0); - - // fix bug removing any delay from attacks - if (distanceToAttacker <= attackRange && this.attackTick <= 0) - { - // double attack timeout - this.attackTick = 20; - - if (this.attacker.getHeldItem() != null) - { - this.attacker.swingItem(); - } - - this.attacker.attackEntityAsMob(entitylivingbase); - } - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFEatLoose.java b/src/main/java/twilightforest/entity/ai/EntityAITFEatLoose.java index 03f0d0b1b0..8b2494125c 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFEatLoose.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFEatLoose.java @@ -1,29 +1,24 @@ package twilightforest.entity.ai; -import java.util.List; - import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.item.EntityItem; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; import twilightforest.entity.passive.EntityTFQuestRam; +import java.util.List; + /** * This is an AI task for the quest ram. When one of the items it wants comes within a close distance, i - * - * @author Ben * + * @author Ben */ public class EntityAITFEatLoose extends EntityAIBase { - - /** The entity using this AI that is tempted by the player. */ - private EntityTFQuestRam temptedQuestRam; - - private Item temptID; + private final EntityTFQuestRam temptedQuestRam; + private final Item temptID; private int delayTemptCounter; - private EntityItem temptingItem; - public EntityAITFEatLoose(EntityTFQuestRam entityTFQuestRam, Item blockID) { this.temptedQuestRam = entityTFQuestRam; @@ -31,89 +26,58 @@ public EntityAITFEatLoose(EntityTFQuestRam entityTFQuestRam, Item blockID) { this.setMutexBits(0); } - /** - * Returns whether the EntityAIBase should begin execution. - */ - @SuppressWarnings("unchecked") @Override - public boolean shouldExecute() - { - if (this.delayTemptCounter > 0) - { - --this.delayTemptCounter; - return false; - } - else - { - this.temptingItem = null; - - List nearbyItems = this.temptedQuestRam.worldObj.getEntitiesWithinAABB(EntityItem.class, this.temptedQuestRam.boundingBox.expand(2.0D, 2.0D, 2.0D)); - - for (EntityItem itemNearby : nearbyItems) { - if (itemNearby.getEntityItem().getItem() == temptID && !temptedQuestRam.isColorPresent(itemNearby.getEntityItem().getItemDamage()) && itemNearby.isEntityAlive()) { // is a wool block really "alive"? - this.temptingItem = itemNearby; - break; - } - } - - if (this.temptingItem == null) { - return false; - } - else { - return true; - } - } - } - - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return this.shouldExecute(); - } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - ; - } - - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.temptingItem = null; - this.temptedQuestRam.getNavigator().clearPathEntity(); - this.delayTemptCounter = 100; - } - - /** - * Updates the task - */ - @Override - public void updateTask() - { - this.temptedQuestRam.getLookHelper().setLookPositionWithEntity(this.temptingItem, 30.0F, this.temptedQuestRam.getVerticalFaceSpeed()); - - if (this.temptedQuestRam.getDistanceSqToEntity(this.temptingItem) < 6.25D) - { - if (!temptedQuestRam.isColorPresent(temptingItem.getEntityItem().getItemDamage())) { // we did technically already check this, but why not check again - // EAT IT! - this.temptingItem.setDead(); - this.temptedQuestRam.playLivingSound(); - this.temptedQuestRam.setColorPresent(temptingItem.getEntityItem().getItemDamage()); - this.temptedQuestRam.animateAddColor(temptingItem.getEntityItem().getItemDamage(), 50); // TODO: find a better place for this? refactor? - //System.out.println("yum"); - } - } - } + public boolean shouldExecute() { + if (this.delayTemptCounter > 0) { + --this.delayTemptCounter; + return false; + } else { + this.temptingItem = null; + + List nearbyItems = this.temptedQuestRam.world.getEntitiesWithinAABB(EntityItem.class, this.temptedQuestRam.getEntityBoundingBox().grow(2.0D, 2.0D, 2.0D)); + + for (EntityItem itemNearby : nearbyItems) { + EnumDyeColor color = EnumDyeColor.byMetadata(itemNearby.getItem().getItemDamage()); + if (itemNearby.getItem().getItem() == temptID && !temptedQuestRam.isColorPresent(color) && itemNearby.isEntityAlive()) { + this.temptingItem = itemNearby; + break; + } + } + + return temptingItem != null; + } + } + + + @Override + public boolean shouldContinueExecuting() { + return this.shouldExecute(); + } + + @Override + public void startExecuting() { + } + + @Override + public void resetTask() { + this.temptingItem = null; + this.temptedQuestRam.getNavigator().clearPath(); + this.delayTemptCounter = 100; + } + + @Override + public void updateTask() { + this.temptedQuestRam.getLookHelper().setLookPositionWithEntity(this.temptingItem, 30.0F, this.temptedQuestRam.getVerticalFaceSpeed()); + + if (this.temptedQuestRam.getDistanceSq(this.temptingItem) < 6.25D) { + EnumDyeColor color = EnumDyeColor.byMetadata(temptingItem.getItem().getItemDamage()); + if (!temptedQuestRam.isColorPresent(color)) { // we did technically already check this, but why not check again + this.temptingItem.setDead(); + this.temptedQuestRam.playLivingSound(); + this.temptedQuestRam.setColorPresent(color); + this.temptedQuestRam.animateAddColor(color, 50); // TODO: find a better place for this? refactor? + } + } + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFFindEntityNearestPlayer.java b/src/main/java/twilightforest/entity/ai/EntityAITFFindEntityNearestPlayer.java new file mode 100644 index 0000000000..0505c06c3f --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFFindEntityNearestPlayer.java @@ -0,0 +1,94 @@ +package twilightforest.entity.ai; + +import com.google.common.base.Predicate; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIFindEntityNearestPlayer; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAITarget; +import net.minecraft.entity.player.EntityPlayer; + +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; + +/** + * Customized AI that checks more that 4 blocks up/down and also ignores sight + */ +public class EntityAITFFindEntityNearestPlayer extends EntityAIFindEntityNearestPlayer +{ + private final EntityLiving entityLiving; + private final Predicate predicate; + private final EntityAINearestAttackableTarget.Sorter sorter; + private EntityLivingBase entityTarget; + + /** + * VanillaCopy super, but change predicate to not check sight, or bother reducing range for sneaking/invisibility + */ + public EntityAITFFindEntityNearestPlayer(EntityLiving entityLivingIn) + { + super(entityLivingIn); + this.entityLiving = entityLivingIn; + this.predicate = new Predicate() + { + @Override + public boolean apply(@Nullable Entity entity) + { + if (!(entity instanceof EntityPlayer)) + { + return false; + } + else if (((EntityPlayer)entity).capabilities.disableDamage) + { + return false; + } + else + { + double maxRange = EntityAITFFindEntityNearestPlayer.this.maxTargetRange(); + + return (double)entity.getDistance(EntityAITFFindEntityNearestPlayer.this.entityLiving) > maxRange ? false : EntityAITarget.isSuitableTarget(EntityAITFFindEntityNearestPlayer.this.entityLiving, (EntityLivingBase)entity, false, false); + } + } + }; + + this.sorter = new EntityAINearestAttackableTarget.Sorter(entityLivingIn); + } + + /** + * VanillaCopy super, but change bounding box y expansion from 4 to full range + */ + @Override + public boolean shouldExecute() + { + double maxRange = this.maxTargetRange(); + List list = this.entityLiving.world.getEntitiesWithinAABB(EntityPlayer.class, this.entityLiving.getEntityBoundingBox().grow(maxRange), this.predicate); + Collections.sort(list, this.sorter); + + if (list.isEmpty()) + { + return false; + } + else + { + this.entityTarget = list.get(0); + return true; + } + } + + /** + * Use our target instead of super's. + */ + @Override + public void startExecuting() + { + this.entityLiving.setAttackTarget(this.entityTarget); + } + + @Override + public void resetTask() + { + this.entityTarget = null; + super.resetTask(); + } +} diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFFindLoose.java b/src/main/java/twilightforest/entity/ai/EntityAITFFindLoose.java index 857e095c73..6870503832 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFFindLoose.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFFindLoose.java @@ -1,112 +1,81 @@ package twilightforest.entity.ai; -import java.util.List; - import net.minecraft.entity.EntityCreature; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.item.Item; -import twilightforest.entity.passive.EntityTFQuestRam; +import java.util.List; public class EntityAITFFindLoose extends EntityAIBase { - - /** The entity using this AI that is tempted by the player. */ - private EntityCreature temptedEntity; - - private Item temptID; - private float pursueSpeed; + + /** + * The entity using this AI that is tempted by the player. + */ + private final EntityCreature temptedEntity; + + private final Item item; + private final float pursueSpeed; private int delayTemptCounter; private EntityItem temptingItem; - public EntityAITFFindLoose(EntityTFQuestRam entityTFQuestRam, float speed, Item blockID) { - this.temptedEntity = entityTFQuestRam; + public EntityAITFFindLoose(EntityCreature entityCreature, float speed, Item item) { + this.temptedEntity = entityCreature; this.pursueSpeed = speed; - this.temptID = blockID; - this.setMutexBits(3); + this.item = item; + this.setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + if (this.delayTemptCounter > 0) { + --this.delayTemptCounter; + return false; + } else { + this.temptingItem = null; + + List nearbyItems = this.temptedEntity.world.getEntitiesWithinAABB(EntityItem.class, this.temptedEntity.getEntityBoundingBox().grow(16.0D, 4.0D, 16.0D)); + + for (EntityItem itemNearby : nearbyItems) { + if (itemNearby.getItem().getItem() == item && itemNearby.isEntityAlive()) { + this.temptingItem = itemNearby; + break; + } + } + + if (this.temptingItem == null) { + return false; + } else { + return true; + } + } } - /** - * Returns whether the EntityAIBase should begin execution. - */ - @SuppressWarnings("unchecked") @Override - public boolean shouldExecute() - { - if (this.delayTemptCounter > 0) - { - --this.delayTemptCounter; - return false; - } - else - { - this.temptingItem = null; - - List nearbyItems = this.temptedEntity.worldObj.getEntitiesWithinAABB(EntityItem.class, this.temptedEntity.boundingBox.expand(16.0D, 4.0D, 16.0D)); - - for (EntityItem itemNearby : nearbyItems) { - if (itemNearby.getEntityItem().getItem() == temptID && itemNearby.isEntityAlive()) { - this.temptingItem = itemNearby; - break; - } - } - - if (this.temptingItem == null) { - return false; - } - else { - return true; - } - } - } - - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return this.shouldExecute(); - } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - ; - } - - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.temptingItem = null; - this.temptedEntity.getNavigator().clearPathEntity(); - this.delayTemptCounter = 100; - } - - /** - * Updates the task - */ - @Override - public void updateTask() - { - this.temptedEntity.getLookHelper().setLookPositionWithEntity(this.temptingItem, 30.0F, this.temptedEntity.getVerticalFaceSpeed()); - - if (this.temptedEntity.getDistanceSqToEntity(this.temptingItem) < 6.25D) - { - this.temptedEntity.getNavigator().clearPathEntity(); - } - else - { - this.temptedEntity.getNavigator().tryMoveToXYZ(temptingItem.posX, temptingItem.posY, temptingItem.posZ, this.pursueSpeed); - } - } + public boolean shouldContinueExecuting() { + return this.shouldExecute(); + } + + @Override + public void startExecuting() {} + + @Override + public void resetTask() { + this.temptingItem = null; + this.temptedEntity.getNavigator().clearPath(); + this.delayTemptCounter = 100; + } + + @Override + public void updateTask() { + this.temptedEntity.getLookHelper().setLookPositionWithEntity(this.temptingItem, 30.0F, this.temptedEntity.getVerticalFaceSpeed()); + + if (this.temptedEntity.getDistanceSq(this.temptingItem) < 6.25D) { + this.temptedEntity.getNavigator().clearPath(); + } else { + this.temptedEntity.getNavigator().tryMoveToXYZ(temptingItem.posX, temptingItem.posY, temptingItem.posZ, this.pursueSpeed); + } + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFFlockTarget.java b/src/main/java/twilightforest/entity/ai/EntityAITFFlockTarget.java index 4873c96843..c6c17039c2 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFFlockTarget.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFFlockTarget.java @@ -1,63 +1,52 @@ package twilightforest.entity.ai; -import java.util.ArrayList; -import java.util.List; - import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAITarget; -public class EntityAITFFlockTarget extends EntityAITarget -{ - EntityLivingBase flockCreature; - EntityLivingBase flockTarget; - - public EntityAITFFlockTarget(EntityCreature par1EntityLiving, boolean b) - { - super(par1EntityLiving, false); - this.flockCreature = par1EntityLiving; - this.setMutexBits(1); - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ - @SuppressWarnings("unchecked") +import java.util.ArrayList; +import java.util.List; + +public class EntityAITFFlockTarget extends EntityAITarget { + + private final EntityLivingBase flockCreature; + private EntityLivingBase flockTarget; + + public EntityAITFFlockTarget(EntityCreature creature, boolean checkSight) { + super(creature, false); + this.flockCreature = creature; + this.setMutexBits(1); + } + + @Override + public boolean shouldExecute() { + List flockList = this.flockCreature.world.getEntitiesWithinAABB(this.flockCreature.getClass(), this.flockCreature.getEntityBoundingBox().grow(16.0D, 4.0D, 16.0D)); + List targetList = new ArrayList(); + + for (EntityLivingBase flocker : flockList) { + if (flocker.getRevengeTarget() != null) { + targetList.add(flocker.getRevengeTarget()); + } + } + + if (targetList.isEmpty()) { + return false; + } else { + // hmm, just pick a random target? + this.flockTarget = targetList.get(this.flockCreature.world.rand.nextInt(targetList.size())); + return this.isSuitableTarget(this.flockTarget, true); + } + } + + @Override + public void startExecuting() { + this.taskOwner.setAttackTarget(this.flockTarget); + super.startExecuting(); + } + @Override - public boolean shouldExecute() - { - List flockList = this.flockCreature.worldObj.getEntitiesWithinAABB(this.flockCreature.getClass(), this.flockCreature.boundingBox.expand(16.0D, 4.0D, 16.0D)); - List targetList = new ArrayList(); - - for (EntityLivingBase flocker : flockList) - { - if (flocker.getAITarget() != null) { - targetList.add(flocker.getAITarget()); - } - } - - if (targetList.isEmpty()) { - return false; - } - else - { - // hmm, just pick a random target? - EntityLivingBase randomTarget = targetList.get(this.flockCreature.worldObj.rand.nextInt(targetList.size())); - - System.out.println("randomTarget = " + randomTarget); - - this.flockTarget = randomTarget; - return this.isSuitableTarget(this.flockTarget, true); - } - } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - this.taskOwner.setAttackTarget(this.flockTarget); - super.startExecuting(); - } + public void resetTask() { + this.flockTarget = null; + super.resetTask(); + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFFlockToSameKind.java b/src/main/java/twilightforest/entity/ai/EntityAITFFlockToSameKind.java index 73cc05fbae..ba1ef4f22b 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFFlockToSameKind.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFFlockToSameKind.java @@ -1,114 +1,100 @@ package twilightforest.entity.ai; -import java.util.List; - import net.minecraft.entity.EntityLiving; import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.Vec3d; + +import java.util.List; -public class EntityAITFFlockToSameKind extends EntityAIBase -{ - private static final double MAX_DIST = 256.0D; +public class EntityAITFFlockToSameKind extends EntityAIBase { + private static final double MAX_DIST = 256.0D; private static final double MIN_DIST = 25.0D; - /** The child that is following its parent. */ - EntityLiving flockCreature; - Vec3 flockPosition; - double speed; - private int moveTimer; + /** + * The child that is following its parent. + */ + private EntityLiving flockCreature; + private Vec3d flockPosition; + double speed; + private int moveTimer; - public EntityAITFFlockToSameKind(EntityLiving par1EntityLiving, double par2) - { - this.flockCreature = par1EntityLiving; - this.speed = par2; - } + public EntityAITFFlockToSameKind(EntityLiving living, double speed) { + this.flockCreature = living; + this.speed = speed; + } - /** - * Returns whether the EntityAIBase should begin execution. - */ - @SuppressWarnings("unchecked") + /** + * Returns whether the EntityAIBase should begin execution. + */ @Override - public boolean shouldExecute() - { - if (this.flockCreature.getRNG().nextInt(40) != 0) - { - return false; - } - - List flockList = this.flockCreature.worldObj.getEntitiesWithinAABB(this.flockCreature.getClass(), this.flockCreature.boundingBox.expand(16.0D, 4.0D, 16.0D)); + public boolean shouldExecute() { + if (this.flockCreature.getRNG().nextInt(40) != 0) { + return false; + } + + List flockList = this.flockCreature.world.getEntitiesWithinAABB(this.flockCreature.getClass(), this.flockCreature.getEntityBoundingBox().grow(16.0D, 4.0D, 16.0D)); + + int flocknum = 0; + double flockX = 0; + double flockY = 0; + double flockZ = 0; - int flocknum = 0; - double flockX = 0; - double flockY = 0; - double flockZ = 0; - - for (EntityLiving flocker : flockList) - { - flocknum++; - flockX += flocker.posX; - flockY += flocker.posY; - flockZ += flocker.posZ; - } - - flockX /= flocknum; - flockY /= flocknum; - flockZ /= flocknum; + for (EntityLiving flocker : flockList) { + flocknum++; + flockX += flocker.posX; + flockY += flocker.posY; + flockZ += flocker.posZ; + } - - if (flockCreature.getDistanceSq(flockX, flockY, flockZ) < MIN_DIST) { - return false; - } - else - { - this.flockPosition = Vec3.createVectorHelper(flockX, flockY, flockZ); - return true; - } - } + flockX /= flocknum; + flockY /= flocknum; + flockZ /= flocknum; - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - if (flockPosition == null) - { - return false; - } - else - { - double distance = this.flockCreature.getDistanceSq(flockPosition.xCoord, flockPosition.yCoord, flockPosition.zCoord); - return distance >= MIN_DIST && distance <= MAX_DIST; - } - } - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - this.moveTimer = 0; - } + if (flockCreature.getDistanceSq(flockX, flockY, flockZ) < MIN_DIST) { + return false; + } else { + this.flockPosition = new Vec3d(flockX, flockY, flockZ); + return true; + } + } - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.flockPosition = null; - } + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + @Override + public boolean shouldContinueExecuting() { + if (flockPosition == null) { + return false; + } else { + double distance = this.flockCreature.getDistanceSq(flockPosition.x, flockPosition.y, flockPosition.z); + return distance >= MIN_DIST && distance <= MAX_DIST; + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + @Override + public void startExecuting() { + this.moveTimer = 0; + } - /** - * Updates the task - */ - @Override - public void updateTask() - { - if (--this.moveTimer <= 0) - { - this.moveTimer = 10; - this.flockCreature.getNavigator().tryMoveToXYZ(flockPosition.xCoord, flockPosition.yCoord, flockPosition.zCoord, this.speed); - } - } + /** + * Resets the task + */ + @Override + public void resetTask() { + this.flockPosition = null; + } + + /** + * Updates the task + */ + @Override + public void updateTask() { + if (--this.moveTimer <= 0) { + this.moveTimer = 10; + this.flockCreature.getNavigator().tryMoveToXYZ(flockPosition.x, flockPosition.y, flockPosition.z, this.speed); + } + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFGiantAttackOnCollide.java b/src/main/java/twilightforest/entity/ai/EntityAITFGiantAttackOnCollide.java deleted file mode 100644 index 6c9ad613d7..0000000000 --- a/src/main/java/twilightforest/entity/ai/EntityAITFGiantAttackOnCollide.java +++ /dev/null @@ -1,184 +0,0 @@ -package twilightforest.entity.ai; - -import net.minecraft.entity.EntityCreature; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.pathfinding.PathEntity; -import net.minecraft.pathfinding.PathPoint; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; - -/** - * This is a copy of EntityAIAttackOnCollide modified to change a few hardcoded behaviors - * - * @author Mostly Mojang - * - */ -public class EntityAITFGiantAttackOnCollide extends EntityAIBase -{ - World worldObj; - EntityCreature attacker; - /** - * An amount of decrementing ticks that allows the entity to attack once the tick reaches 0. - */ - int attackTick; - /** The speed with which the mob will approach the target */ - double speedTowardsTarget; - /** - * When true, the mob will continue chasing its target, even if it can't find a path to them right now. - */ - boolean longMemory; - /** The PathEntity of our entity. */ - PathEntity entityPathEntity; - Class classTarget; - private int delayTicks; - private double pathX; - private double pathY; - private double pathZ; - private int failedPathFindingPenalty; - - public EntityAITFGiantAttackOnCollide(EntityCreature par1EntityCreature, Class par2Class, double par3, boolean par5) - { - this(par1EntityCreature, par3, par5); - this.classTarget = par2Class; - } - - public EntityAITFGiantAttackOnCollide(EntityCreature par1EntityCreature, double par2, boolean par4) - { - this.attacker = par1EntityCreature; - this.worldObj = par1EntityCreature.worldObj; - this.speedTowardsTarget = par2; - this.longMemory = par4; - this.setMutexBits(3); - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ - public boolean shouldExecute() - { - EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); - - if (entitylivingbase == null) - { - return false; - } - else if (!entitylivingbase.isEntityAlive()) - { - return false; - } - else if (this.classTarget != null && !this.classTarget.isAssignableFrom(entitylivingbase.getClass())) - { - return false; - } - else - { - if (-- this.delayTicks <= 0) - { - this.entityPathEntity = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase); - this.delayTicks = 4 + this.attacker.getRNG().nextInt(7); - return this.entityPathEntity != null; - } - else - { - return true; - } - } - } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - public boolean continueExecuting() - { - EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); - return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!this.longMemory ? !this.attacker.getNavigator().noPath() : this.attacker.isWithinHomeDistance(MathHelper.floor_double(entitylivingbase.posX), MathHelper.floor_double(entitylivingbase.posY), MathHelper.floor_double(entitylivingbase.posZ)))); - } - - /** - * Execute a one shot task or start executing a continuous task - */ - public void startExecuting() - { - this.attacker.getNavigator().setPath(this.entityPathEntity, this.speedTowardsTarget); - this.delayTicks = 0; - } - - /** - * Resets the task - */ - public void resetTask() - { - this.attacker.getNavigator().clearPathEntity(); - } - - /** - * Updates the task - */ - public void updateTask() - { - EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); - this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F); - - double distanceToAttacker = this.attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ); - // lower attack range - double attackRange = (double)(this.attacker.width * this.attacker.height); - - --this.delayTicks; - - if ((this.longMemory || this.attacker.getEntitySenses().canSee(entitylivingbase)) && this.delayTicks <= 0 && (this.pathX == 0.0D && this.pathY == 0.0D && this.pathZ == 0.0D || entitylivingbase.getDistanceSq(this.pathX, this.pathY, this.pathZ) >= 1.0D || this.attacker.getRNG().nextFloat() < 0.05F)) - { - this.pathX = entitylivingbase.posX; - this.pathY = entitylivingbase.boundingBox.minY; - this.pathZ = entitylivingbase.posZ; - this.delayTicks = failedPathFindingPenalty + 4 + this.attacker.getRNG().nextInt(7); - - if (this.attacker.getNavigator().getPath() != null) - { - PathPoint finalPathPoint = this.attacker.getNavigator().getPath().getFinalPathPoint(); - if (finalPathPoint != null && entitylivingbase.getDistanceSq(finalPathPoint.xCoord, finalPathPoint.yCoord, finalPathPoint.zCoord) < 1) - { - failedPathFindingPenalty = 0; - } - else - { - failedPathFindingPenalty += 10; - } - } - else - { - failedPathFindingPenalty += 10; - } - - if (distanceToAttacker > 1024.0D) - { - this.delayTicks += 10; - } - else if (distanceToAttacker > 256.0D) - { - this.delayTicks += 5; - } - - if (!this.attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, this.speedTowardsTarget)) - { - this.delayTicks += 15; - } - } - - this.attackTick = Math.max(this.attackTick - 1, 0); - - // fix bug removing any delay from attacks - if (distanceToAttacker <= attackRange && this.attackTick <= 0) - { - // double attack timeout - this.attackTick = 20; - - if (this.attacker.getHeldItem() != null) - { - this.attacker.swingItem(); - } - - this.attacker.attackEntityAsMob(entitylivingbase); - } - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFGroundAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFGroundAttack.java new file mode 100644 index 0000000000..8607850587 --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFGroundAttack.java @@ -0,0 +1,105 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityMoveHelper; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.AxisAlignedBB; +import twilightforest.entity.boss.EntityTFMinoshroom; + +import java.util.List; + +public class EntityAITFGroundAttack extends EntityAIBase { + private static final double MIN_RANGE_SQ = 2.0D; + private static final double MAX_RANGE_SQ = 48.0D; + private static final int FREQ = 24; + + private EntityTFMinoshroom attacker; + private EntityLivingBase attackTarget; + + private int attackTick; + + public EntityAITFGroundAttack(EntityTFMinoshroom entityTFMinoshroom) { + this.attacker = entityTFMinoshroom; + this.setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + this.attackTarget = this.attacker.getAttackTarget(); + + if (this.attackTarget == null) { + return false; + } else { + double distance = this.attacker.getDistanceSq(this.attackTarget); + if (distance < MIN_RANGE_SQ || distance > MAX_RANGE_SQ) { + return false; + } else if (!this.attacker.onGround) { + return false; + } else { + + if (this.attacker.canEntityBeSeen(attackTarget)) { + return this.attacker.getRNG().nextInt(FREQ) == 0; + } else { + return this.attacker.getRNG().nextInt(FREQ - 4) == 0; + } + + } + + } + } + + @Override + public void startExecuting() { + attackTick = 30 + attacker.getRNG().nextInt(30); + attacker.setMaxCharge(attackTick); + attacker.setGroundAttackCharge(true); + } + + @Override + public boolean shouldContinueExecuting() { + return this.attackTick >= 0; + } + + @Override + public void resetTask() { + this.attackTick = 0; + this.attackTarget = null; + } + + @Override + public void updateTask() { + // look where we're going + this.attacker.getLookHelper().setLookPositionWithEntity(attackTarget, 30.0F, 30.0F); + this.attacker.getMoveHelper().action = EntityMoveHelper.Action.WAIT; + + if (this.attackTick-- <= 0) { + this.attacker.setGroundAttackCharge(false); + this.attacker.playSound(SoundEvents.ENTITY_GENERIC_EXPLODE, 2, 1F + this.attacker.getRNG().nextFloat() * 0.1F); + + AxisAlignedBB selection = new AxisAlignedBB(this.attacker.getPosition().getX() - 7.5F, this.attacker.getPosition().getY(), this.attacker.getPosition().getZ() - 7.5F, this.attacker.getPosition().getX() + 7.5F, this.attacker.getPosition().getY() + 3.0F, this.attacker.getPosition().getZ() + 7.5F); + + List hit = attacker.world.getEntitiesWithinAABB(Entity.class, selection); + for (Entity entity : hit) { + + if (entity == this.attacker) { + + continue; + + } + + if (entity instanceof EntityLivingBase) { + if (entity.onGround) { + entity.motionY += 0.23; + + entity.attackEntityFrom(DamageSource.causeMobDamage(this.attacker).setDamageBypassesArmor(), (float) (this.attacker.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getAttributeValue() * 0.5F)); + } + } + } + + } + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFHeavySpearAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFHeavySpearAttack.java index c954c9ab42..61638d9ea4 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFHeavySpearAttack.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFHeavySpearAttack.java @@ -5,29 +5,23 @@ public class EntityAITFHeavySpearAttack extends EntityAIBase { - private EntityTFGoblinKnightUpper entity; + private EntityTFGoblinKnightUpper entity; + + public EntityAITFHeavySpearAttack(EntityTFGoblinKnightUpper upperKnight) { + this.entity = upperKnight; + this.setMutexBits(3); // Prevent moving + } + + @Override + public void updateTask() { + if (entity.heavySpearTimer == 25) { + entity.landHeavySpearAttack(); + } + } - public EntityAITFHeavySpearAttack(EntityTFGoblinKnightUpper par1EntityCreature) - { - this.entity = par1EntityCreature; - this.setMutexBits(7); - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ @Override public boolean shouldExecute() { - return entity.heavySpearTimer > 0 && entity.heavySpearTimer < 50; + return entity.heavySpearTimer > 0 && entity.heavySpearTimer < EntityTFGoblinKnightUpper.HEAVY_SPEAR_TIMER_START; } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return entity.heavySpearTimer > 0 && entity.heavySpearTimer < 50; - } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFHoverBase.java b/src/main/java/twilightforest/entity/ai/EntityAITFHoverBase.java new file mode 100644 index 0000000000..32321f911e --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFHoverBase.java @@ -0,0 +1,77 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; +import twilightforest.TwilightForestMod; + +public abstract class EntityAITFHoverBase extends EntityAIBase { + + protected final T attacker; + + protected final float hoverHeight; + protected final float hoverRadius; + + protected double hoverPosX; + protected double hoverPosY; + protected double hoverPosZ; + + protected EntityAITFHoverBase(T snowQueen, float hoverHeight, float hoverRadius) { + this.attacker = snowQueen; + this.hoverHeight = hoverHeight; + this.hoverRadius = hoverRadius; + } + + @Override + public void startExecuting() { + EntityLivingBase target = this.attacker.getAttackTarget(); + if (target != null) { + // find a spot above the player + makeNewHoverSpot(target); + } + } + + /** + * Make a new spot to hover at! + */ + protected void makeNewHoverSpot(EntityLivingBase target) { + double hx = 0, hy = 0, hz = 0; + + boolean found = false; + + for (int i = 0; i < 100; i++) { + hx = target.posX + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * hoverRadius; + hy = target.posY + hoverHeight; + hz = target.posZ + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * hoverRadius; + + if (!isPositionOccupied(hx, hy, hz) && this.canEntitySee(this.attacker, hx, hy, hz) && this.canEntitySee(target, hx, hy, hz)) { + found = true; + break; + } + } + + if (!found) { + TwilightForestMod.LOGGER.debug("Found no spots, giving up"); + } + + this.hoverPosX = hx; + this.hoverPosY = hy; + this.hoverPosZ = hz; + } + + protected boolean isPositionOccupied(double hx, double hy, double hz) { + float radius = this.attacker.width / 2F; + AxisAlignedBB aabb = new AxisAlignedBB(hx - radius, hy, hz - radius, hx + radius, hy + this.attacker.height, hz + radius); + return !this.attacker.world.checkNoEntityCollision(aabb, attacker) || !this.attacker.world.getCollisionBoxes(attacker, aabb).isEmpty(); + } + + /** + * Can the specified entity see the specified location? + */ + protected boolean canEntitySee(Entity entity, double dx, double dy, double dz) { + return entity.world.rayTraceBlocks(new Vec3d(entity.posX, entity.posY + (double) entity.getEyeHeight(), entity.posZ), new Vec3d(dx, dy, dz)) == null; + } +} diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFHoverBeam.java b/src/main/java/twilightforest/entity/ai/EntityAITFHoverBeam.java index d0f7764528..aef6989856 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFHoverBeam.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFHoverBeam.java @@ -1,84 +1,65 @@ package twilightforest.entity.ai; -import java.util.List; - -import twilightforest.entity.boss.EntityTFSnowQueen; -import twilightforest.entity.boss.EntityTFSnowQueen.Phase; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; - -public class EntityAITFHoverBeam extends EntityAIBase { - - private static final float HOVER_HEIGHT = 3F; - private static final float HOVER_RADIUS = 4F; - private Class classTarget; - private EntityTFSnowQueen attacker; - - private double hoverPosX; - private double hoverPosY; - private double hoverPosZ; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import twilightforest.entity.boss.EntityTFSnowQueen; +import twilightforest.entity.boss.EntityTFSnowQueen.Phase; + +import java.util.List; + +public class EntityAITFHoverBeam extends EntityAITFHoverBase { + private int hoverTimer; private int beamTimer; - private int maxHoverTime; - private int maxBeamTime; private int seekTimer; - private int maxSeekTime; + + private final int maxHoverTime; + private final int maxBeamTime; + private final int maxSeekTime; + private double beamY; private boolean isInPosition; - - public EntityAITFHoverBeam(EntityTFSnowQueen entityTFSnowQueen, Class class1, int hoverTime, int dropTime) { - this.attacker = entityTFSnowQueen; - this.classTarget = class1; - this.setMutexBits(3); - this.maxHoverTime = hoverTime; - this.maxSeekTime = hoverTime; - this.maxBeamTime = dropTime; + + public EntityAITFHoverBeam(EntityTFSnowQueen snowQueen, int hoverTime, int dropTime) { + super(snowQueen, 3F, 4F); + + this.setMutexBits(3); + this.maxHoverTime = hoverTime; + this.maxSeekTime = hoverTime; + this.maxBeamTime = dropTime; this.hoverTimer = 0; this.isInPosition = false; } - /** - * Returns whether the EntityAIBase should begin execution. - */ @Override public boolean shouldExecute() { - EntityLivingBase target = this.attacker.getAttackTarget(); - - if (target == null) { - return false; - } else if (!target.isEntityAlive()) { - return false; - } else if (this.classTarget != null && !this.classTarget.isAssignableFrom(target.getClass())) { - return false; - } else if (this.attacker.getCurrentPhase() != Phase.BEAM) { - return false; - } else { - //System.out.println("We can hover at target!"); - - return true;//attacker.canEntityBeSeen(target); - } + EntityLivingBase target = this.attacker.getAttackTarget(); + if (target == null) { + return false; + } else if (!target.isEntityAlive()) { + return false; + } else if (this.attacker.getCurrentPhase() != Phase.BEAM) { + return false; + } else { + return true;//attacker.canEntityBeSeen(target); + } } - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ @Override - public boolean continueExecuting() { + public boolean shouldContinueExecuting() { EntityLivingBase target = this.attacker.getAttackTarget(); if (target == null || !target.isEntityAlive()) { return false; } else if (this.attacker.getCurrentPhase() != Phase.BEAM) { - return false; - } else if (this.seekTimer >= this.maxSeekTime) { + return false; + } else if (this.seekTimer >= this.maxSeekTime) { return false; } else if (this.beamTimer >= this.maxBeamTime) { return false; @@ -87,69 +68,47 @@ public boolean continueExecuting() { } } - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() { - EntityLivingBase target = this.attacker.getAttackTarget(); - - if (target != null) { - // find a spot above the player - makeNewHoverSpot(target); - } - } - - /** - * Resets the task - */ @Override public void resetTask() { this.seekTimer = 0; this.hoverTimer = 0; this.beamTimer = 0; this.isInPosition = false; - + this.attacker.setBreathing(false); } - /** - * Updates the task - */ @Override public void updateTask() { - + // check if we're in position if (this.attacker.getDistanceSq(hoverPosX, hoverPosY, hoverPosZ) <= 1.0F) { this.isInPosition = true; } - + // update timers if (this.isInPosition) { this.hoverTimer++; } else { this.seekTimer++; } - + // drop once the hover timer runs out if (this.hoverTimer >= this.maxHoverTime) { this.beamTimer++; this.attacker.setBreathing(true); - + // anyhoo, deal damage - Entity target = getHeadLookTarget(); - if (target != null) { - attacker.doBreathAttack(target); - } - - // descend + doRayAttack(); + + // descend this.hoverPosY -= 0.05F; - + if (this.hoverPosY < this.beamY) { this.hoverPosY = this.beamY; } } - + // check if we are at our waypoint target double offsetX = this.hoverPosX - this.attacker.posX; double offsetY = this.hoverPosY - this.attacker.posY; @@ -157,7 +116,7 @@ public void updateTask() { double distanceDesired = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; - distanceDesired = (double)MathHelper.sqrt_double(distanceDesired); + distanceDesired = (double) MathHelper.sqrt(distanceDesired); if (distanceDesired > 0.5) { @@ -169,117 +128,56 @@ public void updateTask() { // gravity offset velY += 0.02F; - this.attacker.addVelocity(velX, velY, velZ); - //System.out.println("Just set hover velocity, velY = " + velY + " result y = " + this.attacker.motionY); - } - // look at target EntityLivingBase target = this.attacker.getAttackTarget(); if (target != null) { - float tracking = this.isInPosition ? 1F: 20.0F; - + float tracking = this.isInPosition ? 1F : 20.0F; + this.attacker.faceEntity(target, tracking, tracking); this.attacker.getLookHelper().setLookPositionWithEntity(target, tracking, tracking); } - - //System.out.println("Hovering!"); - } - - /** - * What, if anything, is the head currently looking at? - */ - @SuppressWarnings("unchecked") - private Entity getHeadLookTarget() { - Entity pointedEntity = null; - double range = 30.0D; - Vec3 srcVec = Vec3.createVectorHelper(this.attacker.posX, this.attacker.posY + 0.25, this.attacker.posZ); - Vec3 lookVec = this.attacker.getLook(1.0F); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - float var9 = 3.0F; - List possibleList = this.attacker.worldObj.getEntitiesWithinAABBExcludingEntity(this.attacker, this.attacker.boundingBox.addCoord(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range).expand(var9, var9, var9)); - double hitDist = 0; - - for (Entity possibleEntity : possibleList) - { - if (possibleEntity.canBeCollidedWith() && possibleEntity != this.attacker) - { - float borderSize = possibleEntity.getCollisionBorderSize(); - AxisAlignedBB collisionBB = possibleEntity.boundingBox.expand((double)borderSize, (double)borderSize, (double)borderSize); - MovingObjectPosition interceptPos = collisionBB.calculateIntercept(srcVec, destVec); - - if (collisionBB.isVecInside(srcVec)) - { - if (0.0D < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = 0.0D; - } - } - else if (interceptPos != null) - { - double possibleDist = srcVec.distanceTo(interceptPos.hitVec); - - if (possibleDist < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = possibleDist; - } - } - } - } - return pointedEntity; } - - /** - * Make a new spot to hover at! - */ - private void makeNewHoverSpot(EntityLivingBase target) { - double hx = 0, hy = 0, hz = 0; - - int tries = 100; - - for (int i = 0; i < tries; i++) { - hx = target.posX + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * HOVER_RADIUS; - hy = target.posY + HOVER_HEIGHT; - hz = target.posZ + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * HOVER_RADIUS; - - if (!isPositionOccupied(hx, hy, hz) && this.canEntitySee(this.attacker, hx, hy, hz) && this.canEntitySee(target, hx, hy, hz)) { - break; + private void doRayAttack() { + + double range = 20.0D; + double offset = 10.0D; + Vec3d srcVec = new Vec3d(this.attacker.posX, this.attacker.posY + 0.25, this.attacker.posZ); + Vec3d lookVec = this.attacker.getLook(1.0F); + Vec3d destVec = srcVec.add(lookVec.x * range, lookVec.y * range, lookVec.z * range); + List possibleList = this.attacker.world.getEntitiesWithinAABBExcludingEntity(this.attacker, this.attacker.getEntityBoundingBox().offset(lookVec.x * offset, lookVec.y * offset, lookVec.z * offset).grow(range, range, range)); + double hitDist = 0; + + for (Entity possibleEntity : possibleList) { + if (possibleEntity.canBeCollidedWith() && possibleEntity != this.attacker) { + float borderSize = possibleEntity.getCollisionBorderSize(); + AxisAlignedBB collisionBB = possibleEntity.getEntityBoundingBox().grow((double) borderSize, (double) borderSize, (double) borderSize); + RayTraceResult interceptPos = collisionBB.calculateIntercept(srcVec, destVec); + + if (collisionBB.contains(srcVec)) { + if (0.0D < hitDist || hitDist == 0.0D) { + attacker.doBreathAttack(possibleEntity); + hitDist = 0.0D; + } + } else if (interceptPos != null) { + double possibleDist = srcVec.distanceTo(interceptPos.hitVec); + + if (possibleDist < hitDist || hitDist == 0.0D) { + attacker.doBreathAttack(possibleEntity); + hitDist = possibleDist; + } + } } } - - if (tries == 99) { - //System.out.println("Found no spots, giving up"); - } - - this.hoverPosX = hx; - this.hoverPosY = hy; - this.hoverPosZ = hz; - - this.beamY = target.posY; - - // reset seek timer - this.seekTimer = 0; } - private boolean isPositionOccupied(double hx, double hy, double hz) { - float radius = this.attacker.width / 2F; - AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(hx - radius, hy, hz - radius, hx + radius, hy + this.attacker.height, hz + radius); - - boolean isOccupied = this.attacker.worldObj.getCollidingBoundingBoxes(attacker, aabb).isEmpty(); - - return isOccupied; + @Override + protected void makeNewHoverSpot(EntityLivingBase target) { + super.makeNewHoverSpot(target); + this.beamY = target.posY; + this.seekTimer = 0; } - - /** - * Can the specified entity see the specified location? - */ - protected boolean canEntitySee(Entity entity, double dx, double dy, double dz) { - return entity.worldObj.rayTraceBlocks(Vec3.createVectorHelper(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ), Vec3.createVectorHelper(dx, dy, dz)) == null; - - } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFHoverSummon.java b/src/main/java/twilightforest/entity/ai/EntityAITFHoverSummon.java index b45c864e05..07d68f6d42 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFHoverSummon.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFHoverSummon.java @@ -1,124 +1,71 @@ package twilightforest.entity.ai; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; import twilightforest.entity.boss.EntityTFSnowQueen; import twilightforest.entity.boss.EntityTFSnowQueen.Phase; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; -public class EntityAITFHoverSummon extends EntityAIBase { +public class EntityAITFHoverSummon extends EntityAITFHoverBase { - private static final float HOVER_HEIGHT = 6F; - private static final float HOVER_RADIUS = 6F; private static final int MAX_MINIONS_AT_ONCE = 4; - - - private Class classTarget; - private EntityTFSnowQueen attacker; - - private double hoverPosX; - private double hoverPosY; - private double hoverPosZ; + private int seekTimer; - private int maxSeekTime; - - public EntityAITFHoverSummon(EntityTFSnowQueen entityTFSnowQueen, Class class1, double speed) { - this.attacker = entityTFSnowQueen; - this.classTarget = class1; - this.setMutexBits(3); - this.maxSeekTime = 80; - } + private final int maxSeekTime; - /** - * Returns whether the EntityAIBase should begin execution. - */ - @Override - public boolean shouldExecute() { - EntityLivingBase target = this.attacker.getAttackTarget(); - - if (target == null) { - return false; - } else if (!target.isEntityAlive()) { - return false; - } else if (this.classTarget != null && !this.classTarget.isAssignableFrom(target.getClass())) { - return false; - } else if (this.attacker.getCurrentPhase() != Phase.SUMMON) { - return false; - } else { - //System.out.println("We can hover at target!"); - - return attacker.canEntityBeSeen(target); - } + public EntityAITFHoverSummon(EntityTFSnowQueen snowQueen, double speed) { + super(snowQueen, 6F, 6F); + this.setMutexBits(3); + this.maxSeekTime = 80; } - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ @Override - public boolean continueExecuting() { + public boolean shouldExecute() { EntityLivingBase target = this.attacker.getAttackTarget(); - if (target == null || !target.isEntityAlive()) { + if (target == null) { return false; - } else if (this.attacker.getCurrentPhase() != Phase.SUMMON){ + } else if (!target.isEntityAlive()) { return false; - } else if (this.seekTimer > this.maxSeekTime){ + } else if (this.attacker.getCurrentPhase() != Phase.SUMMON) { return false; } else { - // check visibility - boolean isVisible = this.canEntitySee(this.attacker, hoverPosX, hoverPosY, hoverPosZ); - - if (!isVisible) { - //System.out.println("Hover spot is no longer visible"); - } - - return isVisible; + return attacker.getEntitySenses().canSee(target); } } - /** - * Execute a one shot task or start executing a continuous task - */ @Override - public void startExecuting() { - EntityLivingBase target = this.attacker.getAttackTarget(); + public boolean shouldContinueExecuting() { + EntityLivingBase target = this.attacker.getAttackTarget(); - if (target != null) { - // find a spot above the player - makeNewHoverSpot(target); - } + if (target == null || !target.isEntityAlive()) { + return false; + } else if (this.attacker.getCurrentPhase() != Phase.SUMMON) { + return false; + } else if (this.seekTimer > this.maxSeekTime) { + return false; + } else { + return this.canEntitySee(this.attacker, hoverPosX, hoverPosY, hoverPosZ); + } } - /** - * Resets the task - */ @Override public void resetTask() { - // } - /** - * Updates the task - */ @Override public void updateTask() { + this.seekTimer++; EntityLivingBase target = this.attacker.getAttackTarget(); // are we there yet? - if (this.attacker.getDistanceSq(hoverPosX, hoverPosY, hoverPosZ) <= 1.0F){ - //System.out.println("Successful hovering, making new spot"); - + if (this.attacker.getDistanceSq(hoverPosX, hoverPosY, hoverPosZ) <= 1.0F) { this.checkAndSummon(); this.makeNewHoverSpot(target); - } + } // check if we are at our waypoint target double offsetX = this.hoverPosX - this.attacker.posX; @@ -127,83 +74,34 @@ public void updateTask() { double distanceDesired = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; - distanceDesired = (double)MathHelper.sqrt_double(distanceDesired); - + distanceDesired = (double) MathHelper.sqrt(distanceDesired); // add velocity double velX = offsetX / distanceDesired * 0.05D; double velY = offsetY / distanceDesired * 0.1D; double velZ = offsetZ / distanceDesired * 0.05D; - + // gravity offset velY += 0.05F; - + this.attacker.addVelocity(velX, velY, velZ); - - // look at target + + // look at target if (target != null) { - this.attacker.faceEntity(target, 30.0F, 30.0F); + this.attacker.faceEntity(target, 30.0F, 30.0F); this.attacker.getLookHelper().setLookPositionWithEntity(target, 30.0F, 30.0F); } - - //System.out.println("Hovering!"); } - - /** - * Make a new spot to hover at! - */ - private void makeNewHoverSpot(EntityLivingBase target) { - double hx = 0, hy = 0, hz = 0; - - int tries = 100; - - for (int i = 0; i < tries; i++) { - hx = target.posX + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * HOVER_RADIUS; - hy = target.posY + HOVER_HEIGHT; - hz = target.posZ + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * HOVER_RADIUS; - - if (!isPositionOccupied(hx, hy, hz) && this.canEntitySee(this.attacker, hx, hy, hz) && this.canEntitySee(target, hx, hy, hz)) { - break; - } - } - - if (tries == 99) { - System.out.println("Found no spots, giving up"); - } - - this.hoverPosX = hx; - this.hoverPosY = hy; - this.hoverPosZ = hz; - + @Override + protected void makeNewHoverSpot(EntityLivingBase target) { + super.makeNewHoverSpot(target); this.seekTimer = 0; - - } - - private boolean isPositionOccupied(double hx, double hy, double hz) { - float radius = this.attacker.width / 2F; - AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(hx - radius, hy, hz - radius, hx + radius, hy + this.attacker.height, hz + radius); - - boolean isOccupied = this.attacker.worldObj.getCollidingBoundingBoxes(attacker, aabb).isEmpty(); - - return isOccupied; } - /** - * Can the specified entity see the specified location? - */ - protected boolean canEntitySee(Entity entity, double dx, double dy, double dz) { - return entity.worldObj.rayTraceBlocks(Vec3.createVectorHelper(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ), Vec3.createVectorHelper(dx, dy, dz)) == null; - - } - private void checkAndSummon() { if (this.attacker.getSummonsRemaining() > 0 && this.attacker.countMyMinions() < MAX_MINIONS_AT_ONCE) { this.attacker.summonMinionAt(this.attacker.getAttackTarget()); - - //System.out.println("Summoning minion"); - } else { - //System.out.println("Summons full"); } } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFHoverThenDrop.java b/src/main/java/twilightforest/entity/ai/EntityAITFHoverThenDrop.java index f6ded10a8a..b2ac52a583 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFHoverThenDrop.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFHoverThenDrop.java @@ -1,88 +1,63 @@ package twilightforest.entity.ai; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.MathHelper; import twilightforest.entity.boss.EntityTFSnowQueen; import twilightforest.entity.boss.EntityTFSnowQueen.Phase; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; - -public class EntityAITFHoverThenDrop extends EntityAIBase { - - private static final float HOVER_HEIGHT = 6F; - private static final float HOVER_RADIUS = 0; - private Class classTarget; - private EntityTFSnowQueen attacker; - - private double hoverPosX; - private double hoverPosY; - private double hoverPosZ; + +public class EntityAITFHoverThenDrop extends EntityAITFHoverBase { + private int hoverTimer; private int dropTimer; - private int maxHoverTime; - private int maxDropTime; private int seekTimer; - private int maxSeekTime; - + + private final int maxHoverTime; + private final int maxDropTime; + private final int maxSeekTime; + private double dropY; - - public EntityAITFHoverThenDrop(EntityTFSnowQueen entityTFSnowQueen, Class class1, int hoverTime, int dropTime) { - this.attacker = entityTFSnowQueen; - this.classTarget = class1; - this.setMutexBits(3); - this.maxHoverTime = hoverTime; - this.maxSeekTime = hoverTime; - this.maxDropTime = dropTime; + + public EntityAITFHoverThenDrop(EntityTFSnowQueen snowQueen, int hoverTime, int dropTime) { + super(snowQueen, 6F, 0F); + + this.setMutexBits(3); + this.maxHoverTime = hoverTime; + this.maxSeekTime = hoverTime; + this.maxDropTime = dropTime; this.hoverTimer = 0; + } + @Override + public boolean shouldExecute() { + EntityLivingBase target = this.attacker.getAttackTarget(); + + if (target == null) { + return false; + } else if (!target.isEntityAlive()) { + return false; + } else if (this.attacker.getCurrentPhase() != Phase.DROP) { + return false; + } else { + return true;//attacker.canEntityBeSeen(target); + } } - /** - * Returns whether the EntityAIBase should begin execution. - */ - @Override - public boolean shouldExecute() { - EntityLivingBase target = this.attacker.getAttackTarget(); - - if (target == null) { - return false; - } else if (!target.isEntityAlive()) { - return false; - } else if (this.classTarget != null && !this.classTarget.isAssignableFrom(target.getClass())) { - return false; - } else if (this.attacker.getCurrentPhase() != Phase.DROP) { - return false; - } else { - //System.out.println("We can hover at target!"); - - return true;//attacker.canEntityBeSeen(target); - } - - } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ @Override - public boolean continueExecuting() { + public boolean shouldContinueExecuting() { EntityLivingBase target = this.attacker.getAttackTarget(); if (target == null || !target.isEntityAlive()) { return false; } else if (this.attacker.getCurrentPhase() != Phase.DROP) { - return false; - } else if (this.seekTimer > this.maxSeekTime) { return false; - } else if (this.attacker.getDistanceSq(hoverPosX, hoverPosY, hoverPosZ) <= 1.0F){ + } else if (this.seekTimer > this.maxSeekTime) { + return false; + } else if (this.attacker.getDistanceSq(hoverPosX, hoverPosY, hoverPosZ) <= 1.0F) { // are we there yet? - //System.out.println("Successfully in position, beginning drop mode"); this.hoverTimer++; return true; - }else if (this.dropTimer < this.maxDropTime) { + } else if (this.dropTimer < this.maxDropTime) { return true; } else { // max drop time! @@ -91,129 +66,63 @@ public boolean continueExecuting() { } } - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() { - EntityLivingBase target = this.attacker.getAttackTarget(); - - if (target != null) { - // find a spot above the player - makeNewHoverSpot(target); - } - } - - /** - * Resets the task - */ @Override public void resetTask() { this.hoverTimer = 0; this.dropTimer = 0; } - /** - * Updates the task - */ @Override public void updateTask() { - + // if we have hit the drop spot, start dropping if (this.hoverTimer > 0) { this.hoverTimer++; } else { this.seekTimer++; } - + if (this.hoverTimer < this.maxHoverTime) { - - // check if we are at our waypoint target - double offsetX = this.hoverPosX - this.attacker.posX; - double offsetY = this.hoverPosY - this.attacker.posY; - double offsetZ = this.hoverPosZ - this.attacker.posZ; - - double distanceDesired = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; - - distanceDesired = (double)MathHelper.sqrt_double(distanceDesired); - - + + // check if we are at our waypoint target + double offsetX = this.hoverPosX - this.attacker.posX; + double offsetY = this.hoverPosY - this.attacker.posY; + double offsetZ = this.hoverPosZ - this.attacker.posZ; + + double distanceDesired = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; + + distanceDesired = (double) MathHelper.sqrt(distanceDesired); + // add velocity double velX = offsetX / distanceDesired * 0.05D; double velY = offsetY / distanceDesired * 0.1D; double velZ = offsetZ / distanceDesired * 0.05D; - + // gravity offset velY += 0.05F; - + this.attacker.addVelocity(velX, velY, velZ); - - - - // look at target + + // look at target EntityLivingBase target = this.attacker.getAttackTarget(); if (target != null) { - this.attacker.faceEntity(target, 30.0F, 30.0F); + this.attacker.faceEntity(target, 30.0F, 30.0F); this.attacker.getLookHelper().setLookPositionWithEntity(target, 30.0F, 30.0F); } - - //System.out.println("Hovering!"); } else { // drop! - //System.out.println("Dropping!"); this.dropTimer++; - + if (this.attacker.posY > this.dropY) { - this.attacker.destroyBlocksInAABB(this.attacker.boundingBox.expand(1, 0.5F, 1)); + this.attacker.destroyBlocksInAABB(this.attacker.getEntityBoundingBox().grow(1, 0.5F, 1)); } } } - - /** - * Make a new spot to hover at! - */ - private void makeNewHoverSpot(EntityLivingBase target) { - double hx = 0, hy = 0, hz = 0; - - int tries = 100; - - for (int i = 0; i < tries; i++) { - hx = target.posX + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * HOVER_RADIUS; - hy = target.posY + HOVER_HEIGHT; - hz = target.posZ + (this.attacker.getRNG().nextFloat() - this.attacker.getRNG().nextFloat()) * HOVER_RADIUS; - - if (!isPositionOccupied(hx, hy, hz) && this.canEntitySee(this.attacker, hx, hy, hz) && this.canEntitySee(target, hx, hy, hz)) { - break; - } - } - - if (tries == 99) { - System.out.println("Found no spots, giving up"); - } - - this.hoverPosX = hx; - this.hoverPosY = hy; - this.hoverPosZ = hz; - + @Override + protected void makeNewHoverSpot(EntityLivingBase target) { + super.makeNewHoverSpot(target); this.dropY = target.posY - 1F; this.seekTimer = 0; } - - private boolean isPositionOccupied(double hx, double hy, double hz) { - float radius = this.attacker.width / 2F; - AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(hx - radius, hy, hz - radius, hx + radius, hy + this.attacker.height, hz + radius); - - boolean isOccupied = this.attacker.worldObj.getCollidingBoundingBoxes(attacker, aabb).isEmpty(); - - return isOccupied; - } - - /** - * Can the specified entity see the specified location? - */ - protected boolean canEntitySee(Entity entity, double dx, double dy, double dz) { - return entity.worldObj.rayTraceBlocks(Vec3.createVectorHelper(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ), Vec3.createVectorHelper(dx, dy, dz)) == null; - - } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFKidnapRider.java b/src/main/java/twilightforest/entity/ai/EntityAITFKidnapRider.java index 8b6e5570b9..1ae19616a0 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFKidnapRider.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFKidnapRider.java @@ -3,66 +3,46 @@ import net.minecraft.entity.EntityCreature; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.ai.RandomPositionGenerator; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.Vec3d; -public class EntityAITFKidnapRider extends EntityAIBase -{ - private EntityCreature theEntityCreature; - private float speed; - private double randPosX; - private double randPosY; - private double randPosZ; +public class EntityAITFKidnapRider extends EntityAIBase { + private EntityCreature theEntityCreature; + private float speed; + private double randPosX; + private double randPosY; + private double randPosZ; - public EntityAITFKidnapRider(EntityCreature par1EntityCreature, float par2) - { - this.theEntityCreature = par1EntityCreature; - this.speed = par2; - this.setMutexBits(1); - } + public EntityAITFKidnapRider(EntityCreature creature, float speed) { + this.theEntityCreature = creature; + this.speed = speed; + this.setMutexBits(1); + } - /** - * Returns whether the EntityAIBase should begin execution. - */ - @Override - public boolean shouldExecute() - { - if (this.theEntityCreature.riddenByEntity == null || this.theEntityCreature.getRNG().nextInt(5) > 0) - { - return false; - } - else - { - Vec3 var1 = RandomPositionGenerator.findRandomTarget(this.theEntityCreature, 5, 4); + @Override + public boolean shouldExecute() { + if (this.theEntityCreature.getRidingEntity() == null || this.theEntityCreature.getRNG().nextInt(5) > 0) { + return false; + } else { + Vec3d target = RandomPositionGenerator.findRandomTarget(this.theEntityCreature, 5, 4); - if (var1 == null) - { - return false; - } - else - { - this.randPosX = var1.xCoord; - this.randPosY = var1.yCoord; - this.randPosZ = var1.zCoord; - return true; - } - } - } + if (target == null) { + return false; + } else { + this.randPosX = target.x; + this.randPosY = target.y; + this.randPosZ = target.z; + return true; + } + } + } - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - this.theEntityCreature.getNavigator().tryMoveToXYZ(this.randPosX, this.randPosY, this.randPosZ, this.speed); - } + @Override + public void startExecuting() { + this.theEntityCreature.getNavigator().tryMoveToXYZ(this.randPosX, this.randPosY, this.randPosZ, this.speed); + } - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return !this.theEntityCreature.getNavigator().noPath(); - } + @Override + public boolean shouldContinueExecuting() { + return !this.theEntityCreature.getNavigator().noPath(); + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFLichMinions.java b/src/main/java/twilightforest/entity/ai/EntityAITFLichMinions.java new file mode 100644 index 0000000000..f6ceefe7b2 --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFLichMinions.java @@ -0,0 +1,106 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import twilightforest.entity.boss.EntityTFLich; +import twilightforest.entity.boss.EntityTFLichMinion; +import twilightforest.item.TFItems; + +public class EntityAITFLichMinions extends EntityAIBase { + + private final EntityTFLich lich; + + public EntityAITFLichMinions(EntityTFLich boss) { + lich = boss; + setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + return lich.getPhase() == 2 && !lich.isShadowClone(); + } + + @Override + public void startExecuting() { + lich.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.zombie_scepter)); + } + + @Override + public void updateTask() { + EntityLivingBase targetedEntity = lich.getAttackTarget(); + if (targetedEntity == null) + return; + float dist = lich.getDistance(targetedEntity); + // spawn minions every so often + if (lich.getAttackCooldown() % 15 == 0) { + checkAndSpawnMinions(); + } + + if (lich.getAttackCooldown() == 0) { + if (dist < 2.0F) { + // melee attack + lich.attackEntityAsMob(targetedEntity); + lich.setAttackCooldown(20); + } else if (dist < 20F && lich.getEntitySenses().canSee(targetedEntity)) { + if (lich.getNextAttackType() == 0) { + lich.launchBoltAt(); + } else { + lich.launchBombAt(); + } + + if (lich.getRNG().nextInt(2) > 0) { + lich.setNextAttackType(0); + } else { + lich.setNextAttackType(1); + } + lich.setAttackCooldown(60); + } else { + // if not, teleport around + lich.teleportToSightOfEntity(targetedEntity); + lich.setAttackCooldown(20); + + } + } + } + + private void checkAndSpawnMinions() { + if (!lich.world.isRemote && lich.getMinionsToSummon() > 0) { + int minions = lich.countMyMinions(); + + // if not, spawn one! + if (minions < EntityTFLich.MAX_ACTIVE_MINIONS) { + spawnMinionAt(); + lich.setMinionsToSummon(lich.getMinionsToSummon() - 1); + } + } + // if there's no minions left to summon, we should move into phase 3 naturally + } + + private void spawnMinionAt() { + // find a good spot + EntityLivingBase targetedEntity = lich.getAttackTarget(); + Vec3d minionSpot = lich.findVecInLOSOf(targetedEntity); + + if (minionSpot != null) { + // put a clone there + EntityTFLichMinion minion = new EntityTFLichMinion(lich.world, lich); + minion.setPosition(minionSpot.x, minionSpot.y, minionSpot.z); + minion.onInitialSpawn(lich.world.getDifficultyForLocation(new BlockPos(minionSpot)), null); + lich.world.spawnEntity(minion); + + minion.setAttackTarget(targetedEntity); + + minion.spawnExplosionParticle(); + minion.playSound(SoundEvents.ENTITY_ITEM_PICKUP, 1.0F, ((lich.getRNG().nextFloat() - lich.getRNG().nextFloat()) * 0.7F + 1.0F) * 2.0F); + + // make sparkles leading to it + lich.makeBlackMagicTrail(lich.posX, lich.posY + lich.getEyeHeight(), lich.posZ, minionSpot.x, minionSpot.y + minion.height / 2.0, minionSpot.z); + } + } + +} diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFLichShadows.java b/src/main/java/twilightforest/entity/ai/EntityAITFLichShadows.java new file mode 100644 index 0000000000..584cb4ba1b --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFLichShadows.java @@ -0,0 +1,125 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.Vec3d; +import twilightforest.entity.boss.EntityTFLich; +import twilightforest.item.TFItems; + +public class EntityAITFLichShadows extends EntityAIBase { + + private final EntityTFLich lich; + + public EntityAITFLichShadows(EntityTFLich boss) { + lich = boss; + setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + return lich.getPhase() == 1; + } + + @Override + public void startExecuting() { + lich.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.twilight_scepter)); + } + + @Override + public void resetTask() { + despawnClones(); + } + + @Override + public void updateTask() { + if (lich.isShadowClone()) + checkForMaster(); + EntityLivingBase targetedEntity = lich.getAttackTarget(); + if (targetedEntity == null) + return; + float dist = lich.getDistance(targetedEntity); + + if (lich.getAttackCooldown() == 60) { + lich.teleportToSightOfEntity(targetedEntity); + + if (!lich.isShadowClone()) { + checkAndSpawnClones(); + } + } + + if (lich.getEntitySenses().canSee(targetedEntity) && lich.getAttackCooldown() == 0 && dist < 20F) { + if (lich.getNextAttackType() == 0) { + lich.launchBoltAt(); + } else { + lich.launchBombAt(); + } + + if (lich.getRNG().nextInt(3) > 0) { + lich.setNextAttackType(0); + } else { + lich.setNextAttackType(1); + } + lich.setAttackCooldown(100); + } + } + + private void checkForMaster() { + if (lich.getMasterLich() == null) { + findNewMaster(); + } + if (!lich.world.isRemote && (lich.getMasterLich() == null || lich.getMasterLich().isDead)) { + lich.setDead(); + } + } + + private void checkAndSpawnClones() { + // if not, spawn one! + if (lich.countMyClones() < EntityTFLich.MAX_SHADOW_CLONES) + spawnShadowClone(); + } + + private void spawnShadowClone() { + EntityLivingBase targetedEntity = lich.getAttackTarget(); + + // find a good spot + Vec3d cloneSpot = lich.findVecInLOSOf(targetedEntity); + + if (cloneSpot != null) { + // put a clone there + EntityTFLich newClone = new EntityTFLich(lich.world, lich); + newClone.setPosition(cloneSpot.x, cloneSpot.y, cloneSpot.z); + lich.world.spawnEntity(newClone); + + newClone.setAttackTarget(targetedEntity); + newClone.setAttackCooldown(60 + lich.getRNG().nextInt(3) - lich.getRNG().nextInt(3)); + + // make sparkles leading to it + lich.makeTeleportTrail(lich.posX, lich.posY, lich.posZ, cloneSpot.x, cloneSpot.y, cloneSpot.z); + } + } + + private void despawnClones() { + for (EntityTFLich nearbyLich : lich.getNearbyLiches()) { + if (nearbyLich.isShadowClone()) { + nearbyLich.isDead = true; + } + } + } + + private void findNewMaster() { + + for (EntityTFLich nearbyLich : lich.getNearbyLiches()) { + if (!nearbyLich.isShadowClone() && nearbyLich.wantsNewClone(lich)) { + lich.setMaster(nearbyLich); + + // animate our new linkage! + lich.makeTeleportTrail(lich.posX, lich.posY, lich.posZ, nearbyLich.posX, nearbyLich.posY, nearbyLich.posZ); + + lich.setAttackTarget(nearbyLich.getAttackTarget()); + break; + } + } + } +} diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFMagicAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFMagicAttack.java deleted file mode 100644 index b26fc1fab5..0000000000 --- a/src/main/java/twilightforest/entity/ai/EntityAITFMagicAttack.java +++ /dev/null @@ -1,183 +0,0 @@ -package twilightforest.entity.ai; - -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.entity.projectile.EntityThrowable; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; -import twilightforest.entity.EntityTFNatureBolt; -import twilightforest.entity.EntityTFSlimeProjectile; -import twilightforest.entity.EntityTFTomeBolt; -import twilightforest.entity.boss.EntityTFLichBolt; - - -public class EntityAITFMagicAttack extends EntityAIBase -{ - public static final int SLIME = 4; - public static final int LICH = 3; - public static final int TOME = 2; - public static final int NATURE = 1; - - World worldObj; - - /** The entity the AI instance has been applied to */ - EntityLiving entityHost; - EntityLivingBase attackTarget; - - /** - * A decrementing tick that spawns a ranged attack once this value reaches 0. It is then set back to the - * maxRangedAttackTime. - */ - int rangedAttackTime = 0; - float moveSpeed; - int ticksLookingAtTarget = 0; - - /** - * The ID of this ranged attack AI. This chooses which entity is to be used as a ranged attack. - */ - int rangedAttackID; - - /** - * The maximum time the AI has to wait before peforming another ranged attack. - */ - int maxRangedAttackTime; - - float attackChance; - - public EntityAITFMagicAttack(EntityLiving par1EntityLiving, float speed, int id, int time) - { - this(par1EntityLiving, speed, id, time, 1.0F); - } - - public EntityAITFMagicAttack(EntityLiving par1EntityLiving, float speed, int id, int time, float chance) - { - this.entityHost = par1EntityLiving; - this.worldObj = par1EntityLiving.worldObj; - this.moveSpeed = speed; - this.rangedAttackID = id; - this.maxRangedAttackTime = time; - this.attackChance = chance; - this.setMutexBits(3); - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ - @Override - public boolean shouldExecute() - { - EntityLivingBase var1 = this.entityHost.getAttackTarget(); - - if (var1 == null || this.entityHost.getRNG().nextFloat() > attackChance) - { - return false; - } - else - { - this.attackTarget = var1; - return true; - } - } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return this.shouldExecute() || !this.entityHost.getNavigator().noPath(); - } - - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.attackTarget = null; - } - - /** - * Updates the task - */ - @Override - public void updateTask() - { - double maxRange = 100.0D; - double targetDistance = this.entityHost.getDistanceSq(this.attackTarget.posX, this.attackTarget.boundingBox.minY, this.attackTarget.posZ); - boolean canSee = this.entityHost.getEntitySenses().canSee(this.attackTarget); - - if (canSee) - { - ++this.ticksLookingAtTarget; - } - else - { - this.ticksLookingAtTarget = 0; - } - - if (targetDistance <= maxRange && this.ticksLookingAtTarget >= 20) - { - this.entityHost.getNavigator().clearPathEntity(); - } - else - { - this.entityHost.getNavigator().tryMoveToEntityLiving(this.attackTarget, this.moveSpeed); - } - - this.entityHost.getLookHelper().setLookPositionWithEntity(this.attackTarget, 30.0F, 30.0F); - this.rangedAttackTime = Math.max(this.rangedAttackTime - 1, 0); - - if (this.rangedAttackTime <= 0) - { - if (targetDistance <= maxRange && canSee) - { - this.doRangedAttack(); - this.rangedAttackTime = this.maxRangedAttackTime; - } - } - } - - /** - * Performs a ranged attack according to the AI's rangedAttackID. - */ - protected void doRangedAttack() - { - EntityThrowable projectile = null; - - if (this.rangedAttackID == NATURE) - { - projectile = new EntityTFNatureBolt(this.worldObj, this.entityHost); - this.worldObj.playSoundAtEntity(this.entityHost, "mob.ghast.fireball", 1.0F, 1.0F / (this.entityHost.getRNG().nextFloat() * 0.4F + 0.8F)); - } - else if (this.rangedAttackID == TOME) - { - projectile = new EntityTFTomeBolt(this.worldObj, this.entityHost); - this.worldObj.playSoundAtEntity(this.entityHost, "mob.ghast.fireball", 1.0F, 1.0F / (this.entityHost.getRNG().nextFloat() * 0.4F + 0.8F)); - } - else if (this.rangedAttackID == LICH) - { - projectile = new EntityTFLichBolt(this.worldObj, this.entityHost); - this.worldObj.playSoundAtEntity(this.entityHost, "mob.ghast.fireball", 1.0F, 1.0F / (this.entityHost.getRNG().nextFloat() * 0.4F + 0.8F)); - } - else if (this.rangedAttackID == SLIME) - { - projectile = new EntityTFSlimeProjectile(this.worldObj, this.entityHost); - this.worldObj.playSoundAtEntity(this.entityHost, "mob.slime.small", 1.0F, 1.0F / (this.entityHost.getRNG().nextFloat() * 0.4F + 0.8F)); - } - - // launch the projectile - if (projectile != null) - { - double tx = this.attackTarget.posX - this.entityHost.posX; - double ty = this.attackTarget.posY + this.attackTarget.getEyeHeight() - 1.100000023841858D - projectile.posY; - double tz = this.attackTarget.posZ - this.entityHost.posZ; - float heightOffset = MathHelper.sqrt_double(tx * tx + tz * tz) * 0.2F; - projectile.setThrowableHeading(tx, ty + heightOffset, tz, 0.6F, 6.0F); // 0.6 speed, 6.0 inaccuracy - this.worldObj.spawnEntityInWorld(projectile); - } - } - - -} diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFPanicOnFlockDeath.java b/src/main/java/twilightforest/entity/ai/EntityAITFPanicOnFlockDeath.java index 62d43fb7a5..fd4ac0e6b6 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFPanicOnFlockDeath.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFPanicOnFlockDeath.java @@ -1,119 +1,101 @@ package twilightforest.entity.ai; -import java.util.List; - import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.ai.RandomPositionGenerator; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.Vec3d; import twilightforest.entity.EntityTFKobold; -public class EntityAITFPanicOnFlockDeath extends EntityAIBase -{ - private EntityCreature flockCreature; - private float speed; - private double fleeX; - private double fleeY; - private double fleeZ; - - int fleeTimer; - - public EntityAITFPanicOnFlockDeath(EntityCreature par1EntityCreature, float par2) - { - this.flockCreature = par1EntityCreature; - this.speed = par2; - this.setMutexBits(1); - this.fleeTimer = 0; - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ - @SuppressWarnings("unchecked") +import java.util.List; + +public class EntityAITFPanicOnFlockDeath extends EntityAIBase { + private EntityCreature flockCreature; + private float speed; + private double fleeX; + private double fleeY; + private double fleeZ; + + private int fleeTimer; + + public EntityAITFPanicOnFlockDeath(EntityCreature creature, float speed) { + this.flockCreature = creature; + this.speed = speed; + this.setMutexBits(1); + this.fleeTimer = 0; + } + @Override - public boolean shouldExecute() - { - boolean yikes = fleeTimer > 0; - - // check if any of us is dead within 4 squares - List flockList = this.flockCreature.worldObj.getEntitiesWithinAABB(this.flockCreature.getClass(), this.flockCreature.boundingBox.expand(4.0D, 2.0D, 4.0D)); - for (EntityLiving flocker : flockList) - { - if (flocker.deathTime > 0) { - yikes = true; - break; - } - } - - if (!yikes) - { - return false; - } - else - { - Vec3 var1 = RandomPositionGenerator.findRandomTarget(this.flockCreature, 5, 4); - - if (var1 == null) - { - return false; - } - else - { - this.fleeX = var1.xCoord; - this.fleeY = var1.yCoord; - this.fleeZ = var1.zCoord; - return true; - } - } - } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - this.fleeTimer = 40; - this.flockCreature.getNavigator().tryMoveToXYZ(this.fleeX, this.fleeY, this.fleeZ, this.speed); - - // panic flag for kobold animations - if (flockCreature instanceof EntityTFKobold) - { - ((EntityTFKobold)flockCreature).setPanicked(true); - } - } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return fleeTimer > 0 && !this.flockCreature.getNavigator().noPath(); - } - - /** - * Updates the task - */ + public boolean shouldExecute() { + boolean yikes = fleeTimer > 0; + + // check if any of us is dead within 4 squares + List flockList = this.flockCreature.world.getEntitiesWithinAABB(this.flockCreature.getClass(), this.flockCreature.getEntityBoundingBox().grow(4.0D, 2.0D, 4.0D)); + for (EntityLiving flocker : flockList) { + if (flocker.deathTime > 0) { + yikes = true; + break; + } + } + + if (!yikes) { + return false; + } else { + Vec3d target = RandomPositionGenerator.findRandomTarget(this.flockCreature, 5, 4); + + if (target == null) { + return false; + } else { + this.fleeX = target.x; + this.fleeY = target.y; + this.fleeZ = target.z; + return true; + } + } + } + + /** + * Execute a one shot task or start executing a continuous task + */ + @Override + public void startExecuting() { + this.fleeTimer = 40; + this.flockCreature.getNavigator().tryMoveToXYZ(this.fleeX, this.fleeY, this.fleeZ, this.speed); + + // panic flag for kobold animations + if (flockCreature instanceof EntityTFKobold) { + ((EntityTFKobold) flockCreature).setPanicked(true); + } + } + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + @Override + public boolean shouldContinueExecuting() { + return fleeTimer > 0 && !this.flockCreature.getNavigator().noPath(); + } + + /** + * Updates the task + */ @Override public void updateTask() { fleeTimer--; } - /** - * Resets the task - */ - @Override + /** + * Resets the task + */ + @Override public void resetTask() { - fleeTimer -= 20; - - // panic flag for kobold animations - if (flockCreature instanceof EntityTFKobold) - { - ((EntityTFKobold)flockCreature).setPanicked(false); - } - } - - + fleeTimer -= 20; + + // panic flag for kobold animations + if (flockCreature instanceof EntityTFKobold) { + ((EntityTFKobold) flockCreature).setPanicked(false); + } + } + + } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFPhantomUpdateFormationAndMove.java b/src/main/java/twilightforest/entity/ai/EntityAITFPhantomUpdateFormationAndMove.java new file mode 100644 index 0000000000..d5ed127966 --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFPhantomUpdateFormationAndMove.java @@ -0,0 +1,278 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.Vec3d; +import twilightforest.entity.boss.EntityTFKnightPhantom; +import twilightforest.item.TFItems; + +import java.util.List; + +public class EntityAITFPhantomUpdateFormationAndMove extends EntityAIBase { + + private static final float CIRCLE_SMALL_RADIUS = 2.5F; + private static final float CIRCLE_LARGE_RADIUS = 8.5F; + + private final EntityTFKnightPhantom boss; + + public EntityAITFPhantomUpdateFormationAndMove(EntityTFKnightPhantom entity) { + boss = entity; + } + + @Override + public boolean shouldExecute() { + return true; + } + + @Override + public void updateTask() { + boss.noClip = boss.getTicksProgress() % 20 != 0; + boss.setTicksProgress(boss.getTicksProgress() + 1); + if (boss.getTicksProgress() >= boss.getMaxTicksForFormation()) + switchToNextFormation(); + Vec3d dest = getDestination(); + boss.getMoveHelper().setMoveTo(dest.x, dest.y, dest.z, boss.isChargingAtPlayer() ? 2 : 1); + } + + public Vec3d getDestination() { + + if (!boss.hasHome()) + boss.setHomePosAndDistance(boss.getPosition(), 20); + + switch (boss.getCurrentFormation()) { + case LARGE_CLOCKWISE: + return getCirclePosition(CIRCLE_LARGE_RADIUS, true); + case SMALL_CLOCKWISE: + return getCirclePosition(CIRCLE_SMALL_RADIUS, true); + case LARGE_ANTICLOCKWISE: + return getCirclePosition(CIRCLE_LARGE_RADIUS, false); + case SMALL_ANTICLOCKWISE: + return getCirclePosition(CIRCLE_SMALL_RADIUS, false); + case CHARGE_PLUSX: + return getMoveAcrossPosition(true, true); + case CHARGE_MINUSX: + return getMoveAcrossPosition(false, true); + case CHARGE_PLUSZ: + return getMoveAcrossPosition(true, false); + case ATTACK_PLAYER_START: + case HOVER: + return getHoverPosition(CIRCLE_LARGE_RADIUS); + case CHARGE_MINUSZ: + return getMoveAcrossPosition(false, false); + case WAITING_FOR_LEADER: + return getLoiterPosition(); + case ATTACK_PLAYER_ATTACK: + return getAttackPlayerPosition(); + default: + return getLoiterPosition(); + } + } + + /** + * Called each time the current formation ends. + *

+ * If the current knight is the leader knight, it will pick and broadcast a new formation. + */ + private void switchToNextFormation() { + List nearbyKnights = boss.getNearbyKnights(); + + if (boss.getCurrentFormation() == EntityTFKnightPhantom.Formation.ATTACK_PLAYER_START) { + boss.switchToFormation(EntityTFKnightPhantom.Formation.ATTACK_PLAYER_ATTACK); + } else if (boss.getCurrentFormation() == EntityTFKnightPhantom.Formation.ATTACK_PLAYER_ATTACK) { + if (nearbyKnights.size() > 1) { + boss.switchToFormation(EntityTFKnightPhantom.Formation.WAITING_FOR_LEADER); + } else { + // random weapon switch! + switch (boss.getRNG().nextInt(3)) { + case 0: + boss.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.knightmetal_sword)); + break; + case 1: + boss.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.knightmetal_axe)); + break; + case 2: + boss.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.knightmetal_pickaxe)); + break; + } + + boss.switchToFormation(EntityTFKnightPhantom.Formation.ATTACK_PLAYER_START); + } + } else if (boss.getCurrentFormation() == EntityTFKnightPhantom.Formation.WAITING_FOR_LEADER) { + // try to find a nearby knight and do what they're doing + if (nearbyKnights.size() > 1) { + boss.switchToFormation(nearbyKnights.get(1).getCurrentFormation()); + boss.setTicksProgress(nearbyKnights.get(1).getTicksProgress()); + } else { + boss.switchToFormation(EntityTFKnightPhantom.Formation.ATTACK_PLAYER_START); + } + } else { + + if (isThisTheLeader(nearbyKnights)) { + // pick a random formation + pickRandomFormation(); + + // broadcast it + broadcastMyFormation(nearbyKnights); + + // if no one is charging + if (isNobodyCharging(nearbyKnights)) { + makeARandomKnightCharge(nearbyKnights); + } + } + } + } + + /** + * Check within 20ish squares. If this phantom is the lowest numbered one, return true + */ + private boolean isThisTheLeader(List nearbyKnights) { + boolean iAmTheLowest = true; + + // find more knights + for (EntityTFKnightPhantom knight : nearbyKnights) { + if (knight.getNumber() < boss.getNumber()) { + iAmTheLowest = false; + break; // don't bother checking more + } + } + + return iAmTheLowest; + } + + /** + * Pick a random formation. Called by the leader when his current formation duration ends + */ + private void pickRandomFormation() { + switch (boss.getRNG().nextInt(8)) { + case 0: + boss.switchToFormation(EntityTFKnightPhantom.Formation.SMALL_CLOCKWISE); + break; + case 1: + boss.switchToFormation(EntityTFKnightPhantom.Formation.SMALL_ANTICLOCKWISE); + //boss.switchToFormation(EntityTFKnightPhantom.Formation.LARGE_ANTICLOCKWISE); + break; + case 2: + boss.switchToFormation(EntityTFKnightPhantom.Formation.SMALL_ANTICLOCKWISE); + break; + case 3: + boss.switchToFormation(EntityTFKnightPhantom.Formation.CHARGE_PLUSX); + break; + case 4: + boss.switchToFormation(EntityTFKnightPhantom.Formation.CHARGE_MINUSX); + break; + case 5: + boss.switchToFormation(EntityTFKnightPhantom.Formation.CHARGE_PLUSZ); + break; + case 6: + boss.switchToFormation(EntityTFKnightPhantom.Formation.CHARGE_MINUSZ); + break; + case 7: + boss.switchToFormation(EntityTFKnightPhantom.Formation.SMALL_CLOCKWISE); + //boss.switchToFormation(EntityTFKnightPhantom.Formation.LARGE_CLOCKWISE); + break; + } + } + + /** + * Tell a random knight from the list to charge + */ + private void makeARandomKnightCharge(List nearbyKnights) { + int randomNum = boss.getRNG().nextInt(nearbyKnights.size()); + nearbyKnights.get(randomNum).switchToFormation(EntityTFKnightPhantom.Formation.ATTACK_PLAYER_START); + } + + private void broadcastMyFormation(List nearbyKnights) { + // find more knights + for (EntityTFKnightPhantom knight : nearbyKnights) { + if (!knight.isChargingAtPlayer()) { + knight.switchToFormation(boss.getCurrentFormation()); + } + } + } + + private boolean isNobodyCharging(List nearbyKnights) { + boolean noCharge = true; + for (EntityTFKnightPhantom knight : nearbyKnights) { + if (knight.isChargingAtPlayer()) { + noCharge = false; + break; // don't bother checking more + } + } + + return noCharge; + } + + private Vec3d getMoveAcrossPosition(boolean plus, boolean alongX) { + float offset0 = (boss.getNumber() * 3F) - 7.5F; + float offset1; + + if (boss.getTicksProgress() < 60) { + offset1 = -7F; + } else { + offset1 = -7F + (((boss.getTicksProgress() - 60) / 120F) * 14F); + } + + if (!plus) { + offset1 *= -1; + } + + double dx = boss.getHomePosition().getX() + (alongX ? offset0 : offset1); + double dy = boss.getHomePosition().getY() + Math.cos(boss.getTicksProgress() / 7F + boss.getNumber()); + double dz = boss.getHomePosition().getZ() + (alongX ? offset1 : offset0); + return new Vec3d(dx, dy, dz); + } + + private Vec3d getCirclePosition(float distance, boolean clockwise) { + float angle = (boss.getTicksProgress() * 2.0F); + + if (!clockwise) { + angle *= -1; + } + + angle += (60F * boss.getNumber()); + + double dx = boss.getHomePosition().getX() + Math.cos((angle) * Math.PI / 180.0D) * distance; + double dy = boss.getHomePosition().getY() + Math.cos(boss.getTicksProgress() / 7F + boss.getNumber()); + double dz = boss.getHomePosition().getZ() + Math.sin((angle) * Math.PI / 180.0D) * distance; + return new Vec3d(dx, dy, dz); + } + + private Vec3d getHoverPosition(float distance) { + // bound this by distance so we don't hover in walls if we get knocked into them + + double dx = boss.lastTickPosX; + double dy = boss.getHomePosition().getY() + Math.cos(boss.getTicksProgress() / 7F + boss.getNumber()); + double dz = boss.lastTickPosZ; + + // let's just bound this by 2D distance + double ox = (boss.getHomePosition().getX() - dx); + double oz = (boss.getHomePosition().getZ() - dz); + double dDist = Math.sqrt(ox * ox + oz * oz); + + if (dDist > distance) { + // normalize back to boundaries + + dx = boss.getHomePosition().getX() + (ox / dDist * distance); + dz = boss.getHomePosition().getZ() + (oz / dDist * distance); + } + + return new Vec3d(dx, dy, dz); + } + + private Vec3d getLoiterPosition() { + double dx = boss.getHomePosition().getX(); + double dy = boss.getHomePosition().getY() + Math.cos(boss.getTicksProgress() / 7F + boss.getNumber()); + double dz = boss.getHomePosition().getZ(); + return new Vec3d(dx, dy, dz); + } + + private Vec3d getAttackPlayerPosition() { + if (boss.isSwordKnight()) { + return new Vec3d(boss.getChargePos()); + } else { + return getHoverPosition(CIRCLE_LARGE_RADIUS); + } + + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFPhantomWatchAndAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFPhantomWatchAndAttack.java new file mode 100644 index 0000000000..8a371e0091 --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFPhantomWatchAndAttack.java @@ -0,0 +1,63 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.item.ItemShield; +import net.minecraft.util.EnumHand; +import twilightforest.entity.boss.EntityTFKnightPhantom; + +public class EntityAITFPhantomWatchAndAttack extends EntityAIBase { + + private final EntityTFKnightPhantom boss; + private int attackTime; + private int guardCoolDownTime; + private boolean isGuard; + + public EntityAITFPhantomWatchAndAttack(EntityTFKnightPhantom entity) { + boss = entity; + } + + @Override + public boolean shouldExecute() { + return boss.getAttackTarget() != null; + } + + @Override + public void updateTask() { + EntityLivingBase target = boss.getAttackTarget(); + if (target != null) { + boss.faceEntity(target, 10.0F, 500.0F); + + if (target.isEntityAlive()) { + float f1 = target.getDistance(boss); + + if (boss.getEntitySenses().canSee(target)) { + if (attackTime-- <= 0 && f1 < 2.0F && target.getEntityBoundingBox().maxY > boss.getEntityBoundingBox().minY && boss.getAttackTarget().getEntityBoundingBox().minY < boss.getEntityBoundingBox().maxY) { + attackTime = 20; + boss.attackEntityAsMob(target); + } + } + + if (this.boss.getHeldItemOffhand().getItem() instanceof ItemShield && boss.getCurrentFormation() != EntityTFKnightPhantom.Formation.ATTACK_PLAYER_ATTACK && this.isGuard) { + this.boss.setActiveHand(EnumHand.OFF_HAND); + } else { + this.boss.resetActiveHand(); + } + + if(this.isGuard){ + if(this.guardCoolDownTime <= 180) { + ++this.guardCoolDownTime; + }else { + this.isGuard = false; + } + }else { + if (guardCoolDownTime > 0) { + --this.guardCoolDownTime; + }else { + this.isGuard = true; + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapBase.java b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapBase.java index 1a892cf37d..71adff0013 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapBase.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapBase.java @@ -1,81 +1,54 @@ package twilightforest.entity.ai; -import java.util.List; - -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.EntityAIBase; import net.minecraft.entity.item.EntityTNTPrimed; import net.minecraft.init.Blocks; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import twilightforest.entity.EntityTFRedcap; -public abstract class EntityAITFRedcapBase extends EntityAIBase -{ +public abstract class EntityAITFRedcapBase extends EntityAIBase { + + protected final EntityTFRedcap redcap; - protected EntityTFRedcap entityObj; + protected EntityAITFRedcapBase(EntityTFRedcap entity) { + this.redcap = entity; + } /** * Fairly straightforward. Returns true in a 120 degree arc in front of the target's view. - * @return */ public boolean isTargetLookingAtMe(EntityLivingBase attackTarget) { - // find angle of approach - double dx = entityObj.posX - attackTarget.posX; - double dz = entityObj.posZ - attackTarget.posZ; - float angle = (float)((Math.atan2(dz, dx) * 180D) / Math.PI) - 90F; - - float difference = MathHelper.abs((attackTarget.rotationYaw - angle) % 360); - - // System.out.println("Difference in angle of approach is " + difference); - - return difference < 60 || difference > 300; - } + // find angle of approach + double dx = redcap.posX - attackTarget.posX; + double dz = redcap.posZ - attackTarget.posZ; + float angle = (float) ((Math.atan2(dz, dx) * 180D) / Math.PI) - 90F; - /** - * Check within the specified range to see if any of the blocks nearby are TNT - * - * @param range - * @return - */ - public ChunkCoordinates findBlockTNTNearby(int range) { - int entityPosX = MathHelper.floor_double(this.entityObj.posX); - int entityPosY = MathHelper.floor_double(this.entityObj.posY); - int entityPosZ = MathHelper.floor_double(this.entityObj.posZ); - - for (int x = -range; x <= range; x++) - { - for (int y = -range; y <= range; y++) - { - for (int z = -range; z <= range; z++) - { - if (entityObj.worldObj.getBlock(entityPosX + x, entityPosY + y, entityPosZ + z) == Blocks.tnt) - { - return new ChunkCoordinates(entityPosX + x, entityPosY + y, entityPosZ + z); - } - } - } - } - - return null; + float difference = MathHelper.abs((attackTarget.rotationYaw - angle) % 360); + + return difference < 60 || difference > 300; } - /** - * Check within the specified range to see if any of the blocks nearby are TNT - * - * @param range - * @return - */ - @SuppressWarnings("unchecked") - public boolean isLitTNTNearby(int range) - { - AxisAlignedBB expandedBox = entityObj.boundingBox.expand(range, range, range); - - List nearbyTNT = entityObj.worldObj.getEntitiesWithinAABB(EntityTNTPrimed.class, expandedBox); - - return nearbyTNT.size() > 0; + public BlockPos findBlockTNTNearby(int range) { + BlockPos entityPos = new BlockPos(redcap); + + for (int x = -range; x <= range; x++) { + for (int y = -range; y <= range; y++) { + for (int z = -range; z <= range; z++) { + if (redcap.world.getBlockState(entityPos.add(x, y, z)).getBlock() == Blocks.TNT) { + return entityPos.add(x, y, z); + } + } + } + } + + return null; } + public boolean isLitTNTNearby(int range) { + AxisAlignedBB expandedBox = redcap.getEntityBoundingBox().grow(range, range, range); + return !redcap.world.getEntitiesWithinAABB(EntityTNTPrimed.class, expandedBox).isEmpty(); + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapLightTNT.java b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapLightTNT.java index e27743b439..a8922d4d9a 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapLightTNT.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapLightTNT.java @@ -1,102 +1,76 @@ package twilightforest.entity.ai; +import net.minecraft.block.BlockTNT; import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.event.ForgeEventFactory; import twilightforest.entity.EntityTFRedcap; public class EntityAITFRedcapLightTNT extends EntityAITFRedcapBase { - private float pursueSpeed; - private int delayTemptCounter; - private int tntX; - private int tntY; - private int tntZ; + private int delay; + private BlockPos tntPos = null; public EntityAITFRedcapLightTNT(EntityTFRedcap hostEntity, float speed) { - this.entityObj = hostEntity; + super(hostEntity); this.pursueSpeed = speed; - this.setMutexBits(3); + this.setMutexBits(3); } - - /** - * Is there an unlit TNT block nearby? - */ + @Override public boolean shouldExecute() { + if (!ForgeEventFactory.getMobGriefingEvent(redcap.world, redcap)) { + return false; + } + + if (this.delay > 0) { + --this.delay; + return false; + } - ChunkCoordinates nearbyTNT = this.findBlockTNTNearby(8); - - if (this.delayTemptCounter > 0) - { - --this.delayTemptCounter; - return false; - } - - if (nearbyTNT != null) - { - this.tntX = nearbyTNT.posX; - this.tntY = nearbyTNT.posY; - this.tntZ = nearbyTNT.posZ; - + BlockPos nearbyTNT = this.findBlockTNTNearby(8); + if (nearbyTNT != null) { + this.tntPos = nearbyTNT; return true; } - + return false; } - - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return entityObj.worldObj.getBlock(tntX, tntY, tntZ) == Blocks.tnt; - } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - this.entityObj.setCurrentItemOrArmor(0, EntityTFRedcap.heldFlint); - } + @Override + public boolean shouldContinueExecuting() { + return redcap.world.getBlockState(tntPos).getBlock() == Blocks.TNT; + } - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.entityObj.getNavigator().clearPathEntity(); - this.entityObj.setCurrentItemOrArmor(0, entityObj.getPick()); - this.delayTemptCounter = 20; - } + @Override + public void startExecuting() { + this.redcap.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, redcap.heldFlint); + } - /** - * Updates the task - */ - @Override - public void updateTask() - { - this.entityObj.getLookHelper().setLookPosition(tntX, tntY, tntZ, 30.0F, this.entityObj.getVerticalFaceSpeed()); + @Override + public void resetTask() { + this.redcap.getNavigator().clearPath(); + this.redcap.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, redcap.heldPick); + this.delay = 20; + this.tntPos = null; + } - if (this.entityObj.getDistance(tntX, tntY, tntZ) < 2.4D) - { - // light it! - entityObj.playLivingSound(); - - Blocks.tnt.onBlockDestroyedByPlayer(entityObj.worldObj, tntX, tntY, tntZ, 1); - entityObj.worldObj.setBlock(tntX, tntY, tntZ, Blocks.air, 0, 2); - this.entityObj.getNavigator().clearPathEntity(); - } - else - { - this.entityObj.getNavigator().tryMoveToXYZ(tntX, tntY, tntZ, this.pursueSpeed); - } - } + @Override + public void updateTask() { + this.redcap.getLookHelper().setLookPosition(tntPos.getX(), tntPos.getY(), tntPos.getZ(), 30.0F, this.redcap.getVerticalFaceSpeed()); + if (this.redcap.getDistanceSq(tntPos) < 2.4D * 2.4D) { + redcap.playLivingSound(); + + Blocks.TNT.onPlayerDestroy(redcap.world, tntPos, Blocks.TNT.getDefaultState().withProperty(BlockTNT.EXPLODE, true)); + redcap.swingArm(EnumHand.MAIN_HAND); + redcap.world.setBlockState(tntPos, Blocks.AIR.getDefaultState(), 2); + this.redcap.getNavigator().clearPath(); + } else { + this.redcap.getNavigator().tryMoveToXYZ(tntPos.getX(), tntPos.getY(), tntPos.getZ(), this.pursueSpeed); + } + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapPlantTNT.java b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapPlantTNT.java index a4fd785b10..46be1d0259 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapPlantTNT.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapPlantTNT.java @@ -2,61 +2,44 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.event.ForgeEventFactory; import twilightforest.entity.EntityTFRedcap; public class EntityAITFRedcapPlantTNT extends EntityAITFRedcapBase { - public EntityAITFRedcapPlantTNT(EntityTFRedcap entityTFRedcap) - { - this.entityObj = entityTFRedcap; + public EntityAITFRedcapPlantTNT(EntityTFRedcap entityTFRedcap) { + super(entityTFRedcap); } - + @Override public boolean shouldExecute() { - EntityLivingBase attackTarget = this.entityObj.getAttackTarget(); - - if (attackTarget != null && entityObj.getTntLeft() > 0 && entityObj.getDistanceSqToEntity(attackTarget) < 25 && !isTargetLookingAtMe(attackTarget) - && !isLitTNTNearby(8) && findBlockTNTNearby(5) == null) - { - //System.out.println("Redcap can plant TNT"); - return true; - } - else - { - return false; - } + EntityLivingBase attackTarget = this.redcap.getAttackTarget(); + return attackTarget != null + && !redcap.heldTNT.isEmpty() + && redcap.getDistanceSq(attackTarget) < 25 + && !isTargetLookingAtMe(attackTarget) + && ForgeEventFactory.getMobGriefingEvent(redcap.world, redcap) + && !isLitTNTNearby(8) + && findBlockTNTNearby(5) == null; + } + + @Override + public void startExecuting() { + BlockPos entityPos = new BlockPos(redcap); + + this.redcap.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, redcap.heldTNT); + + if (this.redcap.world.isAirBlock(entityPos)) { + redcap.heldTNT.shrink(1); + redcap.playLivingSound(); + redcap.world.setBlockState(entityPos, Blocks.TNT.getDefaultState()); + } + } + + @Override + public void resetTask() { + this.redcap.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, redcap.heldPick); } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - int entityPosX = MathHelper.floor_double(this.entityObj.posX); - int entityPosY = MathHelper.floor_double(this.entityObj.posY); - int entityPosZ = MathHelper.floor_double(this.entityObj.posZ); - - //System.out.println("Redcap trying to plant TNT"); - - this.entityObj.setCurrentItemOrArmor(0, EntityTFRedcap.heldTNT); - - if (this.entityObj.worldObj.isAirBlock(entityPosX, entityPosY, entityPosZ)) - { - entityObj.setTntLeft(entityObj.getTntLeft() - 1); - entityObj.playLivingSound(); - entityObj.worldObj.setBlock(entityPosX, entityPosY, entityPosZ, Blocks.tnt, 0, 3); - } - } - - - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.entityObj.setCurrentItemOrArmor(0, entityObj.getPick()); - } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapShy.java b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapShy.java index e3c59a58e0..aa230308db 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFRedcapShy.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFRedcapShy.java @@ -1,136 +1,100 @@ package twilightforest.entity.ai; -import java.util.Random; - import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import twilightforest.entity.EntityTFRedcap; public class EntityAITFRedcapShy extends EntityAITFRedcapBase { - EntityLivingBase entityTarget; - float speed; - boolean lefty; - double xPosition; - double yPosition; - double zPosition; - - double minDistance = 3.0; - double maxDistance = 6.0; + private EntityLivingBase entityTarget; + private final float speed; + private final boolean lefty = Math.random() < 0.5; + private double targetX; + private double targetY; + private double targetZ; + + private static final double minDistance = 3.0; + private static final double maxDistance = 6.0; public EntityAITFRedcapShy(EntityTFRedcap entityTFRedcap, float moveSpeed) { - this.entityObj = entityTFRedcap; + super(entityTFRedcap); this.speed = moveSpeed; - this.lefty = (new Random()).nextBoolean(); - this.setMutexBits(1); + this.setMutexBits(3); } @Override public boolean shouldExecute() { - EntityLivingBase attackTarget = this.entityObj.getAttackTarget(); - - if (attackTarget == null || !this.entityObj.isShy() || attackTarget.getDistanceToEntity(entityObj) > maxDistance - || attackTarget.getDistanceToEntity(entityObj) < minDistance || !isTargetLookingAtMe(attackTarget)) { - return false; - } - else - { - this.entityTarget = attackTarget; - Vec3 avoidPos = findCirclePoint(entityObj, entityTarget, 5, lefty ? 1 : -1); - - if (avoidPos == null) - { - return false; - } - else - { - this.xPosition = avoidPos.xCoord; - this.yPosition = avoidPos.yCoord; - this.zPosition = avoidPos.zCoord; - return true; - } - } + EntityLivingBase attackTarget = this.redcap.getAttackTarget(); + + if (attackTarget == null + || !this.redcap.isShy() + || attackTarget.getDistance(redcap) > maxDistance + || attackTarget.getDistance(redcap) < minDistance + || !isTargetLookingAtMe(attackTarget)) { + return false; + } else { + this.entityTarget = attackTarget; + Vec3d avoidPos = findCirclePoint(redcap, entityTarget, 5, lefty ? 1 : -1); + + this.targetX = avoidPos.x; + this.targetY = avoidPos.y; + this.targetZ = avoidPos.z; + return true; + } } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - //System.out.println("avoid ai starting"); - this.entityObj.getNavigator().tryMoveToXYZ(this.xPosition, this.yPosition, this.zPosition, this.speed); - } - - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - EntityLivingBase attackTarget = this.entityObj.getAttackTarget(); - - if (attackTarget == null) { - return false; - } - else if (!this.entityTarget.isEntityAlive()) { - return false; - } - else if (this.entityObj.getNavigator().noPath()) { - return false; - } - - boolean shouldContinue = entityObj.isShy() && attackTarget.getDistanceToEntity(entityObj) < maxDistance && attackTarget.getDistanceToEntity(entityObj) > minDistance && isTargetLookingAtMe(attackTarget); - - //System.out.println("ai evaluating should continue to " + shouldContinue); - - return shouldContinue; - } - - /** - * Updates the task - */ - @Override - public void updateTask() - { - this.entityObj.getLookHelper().setLookPositionWithEntity(this.entityTarget, 30.0F, 30.0F); - } - - - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.entityTarget = null; - this.entityObj.getNavigator().clearPathEntity(); - } - - + /** - * Finds a point that allows us to circle the player clockwise. - */ - protected Vec3 findCirclePoint(Entity circler, Entity toCircle, double radius, double rotation) { - - // compute angle - double vecx = circler.posX - toCircle.posX; - double vecz = circler.posZ - toCircle.posZ; - float rangle = (float)(Math.atan2(vecz, vecx)); - - // add a little, so he circles - rangle += rotation; - - // figure out where we're headed from the target angle - double dx = MathHelper.cos(rangle) * radius; - double dz = MathHelper.sin(rangle) * radius; - - // add that to the target entity's position, and we have our destination - return Vec3.createVectorHelper(toCircle.posX + dx, circler.boundingBox.minY, toCircle.posZ + dz); - } - + * Execute a one shot task or start executing a continuous task + */ + @Override + public void startExecuting() { + this.redcap.getNavigator().tryMoveToXYZ(this.targetX, this.targetY, this.targetZ, this.speed); + } + + @Override + public boolean shouldContinueExecuting() { + EntityLivingBase attackTarget = this.redcap.getAttackTarget(); + + if (attackTarget == null) { + return false; + } else if (!this.entityTarget.isEntityAlive()) { + return false; + } else if (this.redcap.getNavigator().noPath()) { + return false; + } + + return redcap.isShy() && attackTarget.getDistance(redcap) < maxDistance && attackTarget.getDistance(redcap) > minDistance && isTargetLookingAtMe(attackTarget); + } + + @Override + public void updateTask() { + this.redcap.getLookHelper().setLookPositionWithEntity(this.entityTarget, 30.0F, 30.0F); + } + + @Override + public void resetTask() { + this.entityTarget = null; + this.redcap.getNavigator().clearPath(); + } + + private Vec3d findCirclePoint(Entity circler, Entity toCircle, double radius, double rotation) { + // compute angle + double vecx = circler.posX - toCircle.posX; + double vecz = circler.posZ - toCircle.posZ; + float rangle = (float) (Math.atan2(vecz, vecx)); + + // add a little, so he circles + rangle += rotation; + + // figure out where we're headed from the target angle + double dx = MathHelper.cos(rangle) * radius; + double dz = MathHelper.sin(rangle) * radius; + + // add that to the target entity's position, and we have our destination + return new Vec3d(toCircle.posX + dx, circler.getEntityBoundingBox().minY, toCircle.posZ + dz); + } + } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFRiderSpearAttack.java b/src/main/java/twilightforest/entity/ai/EntityAITFRiderSpearAttack.java index 6bc6367c09..99b2c28561 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFRiderSpearAttack.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFRiderSpearAttack.java @@ -6,42 +6,21 @@ public class EntityAITFRiderSpearAttack extends EntityAIBase { - private EntityTFGoblinKnightLower entity; + private EntityTFGoblinKnightLower entity; - public EntityAITFRiderSpearAttack(EntityTFGoblinKnightLower par1EntityCreature) - { - this.entity = par1EntityCreature; - this.setMutexBits(7); - } - - /** - * Returns whether the EntityAIBase should begin execution. - */ - @Override - public boolean shouldExecute() { - return isRiderDoingSpearAttack(); + public EntityAITFRiderSpearAttack(EntityTFGoblinKnightLower lowerKnight) { + this.entity = lowerKnight; + this.setMutexBits(3); // Prevent moving } - public boolean isRiderDoingSpearAttack() - { - if (this.entity.riddenByEntity != null && this.entity.riddenByEntity instanceof EntityTFGoblinKnightUpper) - { - int timer = ((EntityTFGoblinKnightUpper)this.entity.riddenByEntity).heavySpearTimer; - return timer > 0 && timer < 50; - } - else - { + @Override + public boolean shouldExecute() { + if (!this.entity.getPassengers().isEmpty() && this.entity.getPassengers().get(0) instanceof EntityTFGoblinKnightUpper) { + int timer = ((EntityTFGoblinKnightUpper) this.entity.getPassengers().get(0)).heavySpearTimer; + return timer > 0 && timer < EntityTFGoblinKnightUpper.HEAVY_SPEAR_TIMER_START; + } else { return false; } } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return isRiderDoingSpearAttack(); - } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFTempt.java b/src/main/java/twilightforest/entity/ai/EntityAITFTempt.java new file mode 100644 index 0000000000..a08005f874 --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAITFTempt.java @@ -0,0 +1,26 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.ai.EntityAITempt; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; + +import java.util.Collections; + +/** + * Same as superclass, but uses an {@code Ingredient} instead of a {@code Set} + */ +public class EntityAITFTempt extends EntityAITempt { + + protected final Ingredient ingredient; + + public EntityAITFTempt(EntityCreature temptedEntity, double speed, boolean scaredByPlayerMovement, Ingredient ingredient) { + super(temptedEntity, speed, scaredByPlayerMovement, Collections.emptySet()); + this.ingredient = ingredient; + } + + @Override + protected boolean isTempting(ItemStack stack) { + return ingredient.apply(stack); + } +} diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFThrowRider.java b/src/main/java/twilightforest/entity/ai/EntityAITFThrowRider.java index a2b9cab01e..ced6cfc62a 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFThrowRider.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFThrowRider.java @@ -1,85 +1,84 @@ package twilightforest.entity.ai; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.Vec3; -import twilightforest.TFGenericPacketHandler; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.common.network.internal.FMLProxyPacket; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import twilightforest.network.TFPacketHandler; +import twilightforest.network.PacketThrowPlayer; -public class EntityAITFThrowRider extends EntityAIBase { +public class EntityAITFThrowRider extends EntityAIAttackMelee { - - private EntityCreature theEntityCreature; private int throwTimer; - - - public EntityAITFThrowRider(EntityCreature par1EntityCreature, float par2) - { - this.theEntityCreature = par1EntityCreature; - this.setMutexBits(1); - } - /** - * Returns whether the EntityAIBase should begin execution. - */ - @Override - public boolean shouldExecute() - { - if (this.theEntityCreature.riddenByEntity == null || this.theEntityCreature.getRNG().nextInt(5) > 0) - { - return false; - } - else - { - return true; - } - } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - EntityLivingBase rider = (EntityLivingBase) this.theEntityCreature.riddenByEntity; - rider.mountEntity(null); - - Vec3 throwVec = this.theEntityCreature.getLookVec(); - throwVec.xCoord *= 2F; - throwVec.yCoord *= 2F; - throwVec.zCoord *= 2F; - - // let's throw the player a fixed value in the air - throwVec.yCoord = 0.9; - - rider.addVelocity(throwVec.xCoord, throwVec.yCoord, throwVec.zCoord); - - // if we're throwing a player (probably!), send a packet with the velocity - if (rider instanceof EntityPlayerMP) { - EntityPlayerMP player = (EntityPlayerMP)rider; - - FMLProxyPacket message = TFGenericPacketHandler.makeThrowPlayerPacket((float)throwVec.xCoord, (float)throwVec.yCoord, (float)throwVec.zCoord); - TwilightForestMod.genericChannel.sendTo(message, player); - - } - - System.out.println("throw!"); - this.throwTimer = 0; - } - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - if (this.theEntityCreature.riddenByEntity == null) { - this.throwTimer++; - } - - return this.throwTimer <= 40; - } - + private int timeout; + + public EntityAITFThrowRider(EntityCreature creature, double speedIn, boolean useLongMemory) { + super(creature, speedIn, useLongMemory); + } + + @Override + public boolean shouldExecute() { + return this.attacker.getPassengers().isEmpty() && super.shouldExecute(); + } + + @Override + public void startExecuting() { + this.throwTimer = 10 + attacker.getRNG().nextInt(30); // Wait 0.5 to 2 seconds before we throw the target + timeout = 80 + attacker.getRNG().nextInt(40); // Lets only try to chase for around 4-6 seconds + super.startExecuting(); + } + + @Override + public void updateTask() { + timeout--; + if (!attacker.getPassengers().isEmpty()) + throwTimer--; + else + super.updateTask(); + } + + // Vanilla Copy with edits + @Override + protected void checkAndPerformAttack(EntityLivingBase p_190102_1_, double p_190102_2_) { + double d0 = this.getAttackReachSqr(p_190102_1_); + + if (p_190102_2_ <= d0 && this.attackTick <= 0) { + this.attackTick = 20; + this.attacker.swingArm(EnumHand.MAIN_HAND); + if (attacker.getPassengers().isEmpty() && p_190102_1_.getRidingEntity() == null) { + p_190102_1_.startRiding(attacker); + } + } + } + + @Override + public void resetTask() { + if (!attacker.getPassengers().isEmpty()) { + Entity rider = attacker.getPassengers().get(0); + rider.dismountRidingEntity(); + + Vec3d throwVec = attacker.getLookVec().scale(2); + throwVec = new Vec3d(throwVec.x, 0.9, throwVec.z); + + rider.addVelocity(throwVec.x, throwVec.y, throwVec.z); + + if (rider instanceof EntityPlayerMP) { + EntityPlayerMP player = (EntityPlayerMP) rider; + + IMessage message = new PacketThrowPlayer((float) throwVec.x, (float) throwVec.y, (float) throwVec.z); + TFPacketHandler.CHANNEL.sendTo(message, player); + } + } + super.resetTask(); + } + + @Override + public boolean shouldContinueExecuting() { + return (throwTimer > 0 && !attacker.getPassengers().isEmpty()) || (timeout > 0 && super.shouldContinueExecuting() && attacker.getPassengers().isEmpty()); + } + } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFYetiRampage.java b/src/main/java/twilightforest/entity/ai/EntityAITFYetiRampage.java index bb55af5615..09cdf7b09f 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFYetiRampage.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFYetiRampage.java @@ -1,6 +1,10 @@ package twilightforest.entity.ai; import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.math.Vec3d; +import twilightforest.TFSounds; +import twilightforest.entity.boss.EntityTFIceBomb; import twilightforest.entity.boss.EntityTFYetiAlpha; public class EntityAITFYetiRampage extends EntityAIBase { @@ -16,7 +20,7 @@ public EntityAITFYetiRampage(EntityTFYetiAlpha entityTFYetiAlpha, int timeout, i this.currentTimeOut = timeout; this.maxTantrumTimeOut = timeout; this.tantrumDuration = duration; - + this.setMutexBits(5); } @@ -26,89 +30,88 @@ public boolean shouldExecute() { if (this.yeti.getAttackTarget() != null && this.yeti.canRampage()) { this.currentTimeOut--; } - - //System.out.println("Tantrum time out = " + this.tantrumTimeOut); - return this.currentTimeOut <= 0; } - - /** - * Execute a one shot task or start executing a continuous task - */ - @Override - public void startExecuting() - { - this.currentDuration = this.tantrumDuration; - this.yeti.setRampaging(true); - } - - - /** - * Returns whether an in-progress EntityAIBase should continue executing - */ - @Override - public boolean continueExecuting() - { - return currentDuration > 0; - } - - /** - * Updates the task - */ - @Override - public void updateTask() - { - this.currentDuration--; - -// int rx = MathHelper.floor_double(this.yeti.posX); -// int ry = MathHelper.floor_double(this.yeti.posY - 1); -// int rz = MathHelper.floor_double(this.yeti.posZ); + + /** + * Execute a one shot task or start executing a continuous task + */ + @Override + public void startExecuting() { + this.currentDuration = this.tantrumDuration; + this.yeti.setRampaging(true); + this.yeti.playSound(TFSounds.ALPHAYETI_ROAR, 4F, 0.5F + yeti.getRNG().nextFloat() * 0.5F); + } + + + /** + * Returns whether an in-progress EntityAIBase should continue executing + */ + @Override + public boolean shouldContinueExecuting() { + return currentDuration > 0; + } + + /** + * Updates the task + */ + @Override + public void updateTask() { + this.currentDuration--; + +// int rx = MathHelper.floor(this.yeti.posX); +// int ry = MathHelper.floor(this.yeti.posY - 1); +// int rz = MathHelper.floor(this.yeti.posZ); // -// this.yeti.worldObj.playAuxSFX(2004, rx, ry, rz, 0); - +// this.yeti.world.playAuxSFX(2004, rx, ry, rz, 0); + if (this.yeti.getAttackTarget() != null) { - this.yeti.getLookHelper().setLookPositionWithEntity(this.yeti.getAttackTarget(), 10.0F, (float)this.yeti.getVerticalFaceSpeed()); + this.yeti.getLookHelper().setLookPositionWithEntity(this.yeti.getAttackTarget(), 10.0F, (float) this.yeti.getVerticalFaceSpeed()); } - + if (this.yeti.onGround) { - this.yeti.motionX = 0; - this.yeti.motionZ = 0; - this.yeti.motionY = 0.4F; + this.yeti.motionX = 0; + this.yeti.motionZ = 0; + this.yeti.motionY = 0.4F; } - - this.yeti.destroyBlocksInAABB(this.yeti.boundingBox.expand(1, 2, 1).offset(0, 2, 0)); - + + this.yeti.destroyBlocksInAABB(this.yeti.getEntityBoundingBox().grow(1, 2, 1).offset(0, 2, 0)); + // regular falling blocks if (this.currentDuration % 20 == 0) { this.yeti.makeRandomBlockFall(); } - + // blocks target players if (this.currentDuration % 40 == 0) { this.yeti.makeBlockAboveTargetFall(); } - + // blocks target players if (this.currentDuration < 40 && this.currentDuration % 10 == 0) { this.yeti.makeNearbyBlockFall(); } - - //System.out.println("Rampage!"); - - } - - - /** - * Resets the task - */ - @Override - public void resetTask() - { - this.currentTimeOut = this.maxTantrumTimeOut; - this.yeti.setRampaging(false); - this.yeti.setTired(true); - - } + + if (currentDuration % 10 == 0) { + EntityTFIceBomb ice = new EntityTFIceBomb(yeti.world, yeti); + Vec3d vec = new Vec3d(0.5F + yeti.getRNG().nextFloat() * 0.5F, 0.5F + yeti.getRNG().nextFloat() * 0.3F, 0).rotateYaw(yeti.getRNG().nextFloat() * 360F); + ice.shoot(vec.x, vec.y, vec.z, 0.4F + yeti.getRNG().nextFloat() * 0.3F, 0); + yeti.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 1.0F, 1.0F / (yeti.getRNG().nextFloat() * 0.4F + 0.8F)); + yeti.world.spawnEntity(ice); + } + } + + + /** + * Resets the task + */ + @Override + public void resetTask() { + this.currentTimeOut = this.maxTantrumTimeOut; + this.yeti.setRampaging(false); + this.yeti.setTired(true); + + } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAITFYetiTired.java b/src/main/java/twilightforest/entity/ai/EntityAITFYetiTired.java index 983d5c9449..6165beeb4e 100644 --- a/src/main/java/twilightforest/entity/ai/EntityAITFYetiTired.java +++ b/src/main/java/twilightforest/entity/ai/EntityAITFYetiTired.java @@ -1,6 +1,7 @@ package twilightforest.entity.ai; import net.minecraft.entity.ai.EntityAIBase; +import twilightforest.TFSounds; import twilightforest.entity.boss.EntityTFYetiAlpha; public class EntityAITFYetiTired extends EntityAIBase { @@ -21,7 +22,7 @@ public boolean shouldExecute() { } @Override - public boolean continueExecuting() { + public boolean shouldContinueExecuting() { return this.tiredTimer < this.tiredDuration; } @@ -43,7 +44,8 @@ public void resetTask() { @Override public void updateTask() { - this.tiredTimer++; + if(++this.tiredTimer % 10 == 0) + this.yeti.playSound(TFSounds.ALPHAYETI_PANT, 4F, 0.5F + yeti.getRNG().nextFloat() * 0.5F); } } diff --git a/src/main/java/twilightforest/entity/ai/EntityAIThrowSpikeBlock.java b/src/main/java/twilightforest/entity/ai/EntityAIThrowSpikeBlock.java new file mode 100644 index 0000000000..3eaee98a35 --- /dev/null +++ b/src/main/java/twilightforest/entity/ai/EntityAIThrowSpikeBlock.java @@ -0,0 +1,39 @@ +package twilightforest.entity.ai; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIBase; +import twilightforest.entity.EntityTFBlockGoblin; +import twilightforest.entity.EntityTFSpikeBlock; + +public class EntityAIThrowSpikeBlock extends EntityAIBase { + + protected EntityTFBlockGoblin attacker; + protected EntityTFSpikeBlock spikeBlock; + + public EntityAIThrowSpikeBlock(EntityTFBlockGoblin entityTFBlockGoblin, EntityTFSpikeBlock entitySpikeBlock) { + this.attacker = entityTFBlockGoblin; + this.spikeBlock = entitySpikeBlock; + this.setMutexBits(3); + } + + @Override + public boolean shouldExecute() { + EntityLivingBase target = this.attacker.getAttackTarget(); + if (target == null || this.attacker.getDistanceSq(target) > 42) { + return false; + } else { + return this.attacker.isEntityAlive() && this.attacker.canEntityBeSeen(target) && this.attacker.world.rand.nextInt(56) == 0; + } + } + + @Override + public boolean shouldContinueExecuting() { + return this.attacker.getChainMoveLength() > 0; + } + + @Override + public void startExecuting() { + this.attacker.setThrowing(true); + } + +} diff --git a/src/main/java/twilightforest/entity/ai/EntityTFRavenLookHelper.java b/src/main/java/twilightforest/entity/ai/EntityTFRavenLookHelper.java deleted file mode 100644 index fb56d6de01..0000000000 --- a/src/main/java/twilightforest/entity/ai/EntityTFRavenLookHelper.java +++ /dev/null @@ -1,138 +0,0 @@ -package twilightforest.entity.ai; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.ai.EntityLookHelper; -import net.minecraft.util.MathHelper; - - -public class EntityTFRavenLookHelper extends EntityLookHelper -{ - private EntityLiving entity; - private float field_46149_b; - private float field_46150_c; - private boolean field_46147_d = false; - private double posX; - private double posY; - private double posZ; - - public EntityTFRavenLookHelper(EntityLiving par1EntityLiving) - { - super(par1EntityLiving); - this.entity = par1EntityLiving; - } - - /** - * Sets position to look at using entity - */ - public void setLookPositionWithEntity(Entity par1Entity, float par2, float par3) - { - this.posX = par1Entity.posX; - - if (par1Entity instanceof EntityLiving) - { - this.posY = par1Entity.posY + (double)((EntityLiving)par1Entity).getEyeHeight(); - } - else - { - this.posY = (par1Entity.boundingBox.minY + par1Entity.boundingBox.maxY) / 2.0D; - } - - this.posZ = par1Entity.posZ; - this.field_46149_b = par2; - this.field_46150_c = par3; - this.field_46147_d = true; - } - - /** - * Sets position to look at - */ - @Override - public void setLookPosition(double par1, double par3, double par5, float par7, float par8) - { - this.posX = par1; - this.posY = par3; - this.posZ = par5; - this.field_46149_b = par7; - this.field_46150_c = par8; - this.field_46147_d = true; - } - - /** - * Updates look - */ - @Override - public void onUpdateLook() - { - this.entity.rotationPitch = 0.0F; - - if (this.field_46147_d) - { - this.field_46147_d = false; - double var1 = this.posX - this.entity.posX; - double var3 = this.posY - (this.entity.posY + this.entity.getEyeHeight()); - double var5 = this.posZ - this.entity.posZ; - double var7 = MathHelper.sqrt_double(var1 * var1 + var5 * var5); - float var9 = (float)(Math.atan2(var5, var1) * 180.0D / Math.PI) - 30.0F; - float var10 = (float)(-(Math.atan2(var3, var7) * 180.0D / Math.PI)); - this.entity.rotationPitch = this.updateRotation(this.entity.rotationPitch, var10, this.field_46150_c); - this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, var9, this.field_46149_b); - } - else - { - this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, this.entity.renderYawOffset, 10.0F); - } - - float var11; - - for (var11 = this.entity.rotationYawHead - this.entity.renderYawOffset; var11 < -180.0F; var11 += 360.0F) - { - ; - } - - while (var11 >= 180.0F) - { - var11 -= 360.0F; - } - - if (!this.entity.getNavigator().noPath()) - { - if (var11 < -75.0F) - { - this.entity.rotationYawHead = this.entity.renderYawOffset - 75.0F; - } - - if (var11 > 75.0F) - { - this.entity.rotationYawHead = this.entity.renderYawOffset + 75.0F; - } - } - } - - private float updateRotation(float par1, float par2, float par3) - { - float var4; - - for (var4 = par2 - par1; var4 < -180.0F; var4 += 360.0F) - { - ; - } - - while (var4 >= 180.0F) - { - var4 -= 360.0F; - } - - if (var4 > par3) - { - var4 = par3; - } - - if (var4 < -par3) - { - var4 = -par3; - } - - return par1 + var4; - } -} diff --git a/src/main/java/twilightforest/entity/boss/EntityTFFallingIce.java b/src/main/java/twilightforest/entity/boss/EntityTFFallingIce.java index b97f4abbf5..0ccf184734 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFFallingIce.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFFallingIce.java @@ -1,224 +1,122 @@ package twilightforest.entity.boss; -import java.util.ArrayList; - import net.minecraft.block.Block; import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityFallingBlock; import net.minecraft.init.Blocks; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.particle.TFParticleType; + +import java.util.List; -public class EntityTFFallingIce extends Entity { +public class EntityTFFallingIce extends EntityFallingBlock { private static final int HANG_TIME = 100; - private int fallTime; - private float hurtAmount; - private int hurtMax; - - public EntityTFFallingIce(World par1World) { - super(par1World); - this.setSize(2.98F, 2.98F); - - this.hurtAmount = 10; - this.hurtMax = 30; + + public EntityTFFallingIce(World world) { + super(world, 0, 0, 0, Blocks.PACKED_ICE.getDefaultState()); // set falling tile on client to prevent crash + this.setSize(2.98F, 2.98F); + } + + public EntityTFFallingIce(World world, int x, int y, int z) { + super(world, x, y, z, Blocks.PACKED_ICE.getDefaultState()); + this.setSize(2.98F, 2.98F); + this.fallHurtAmount = 10.0F; + this.fallHurtMax = 30; + this.setHurtEntities(true); } - public EntityTFFallingIce(World par1World, int x, int y, int z) { - this(par1World); + @Override + public void onUpdate() { + if (fallTime > HANG_TIME) { + setNoGravity(true); + } + + super.onUpdate(); - this.preventEntitySpawning = true; + // kill other nearby blocks if they are not as old as this one + if (!this.world.isRemote) { + List nearby = this.world.getEntitiesWithinAABB(EntityTFFallingIce.class, this.getEntityBoundingBox()); - this.setPosition(x, y, z); - this.motionX = 0.0D; - this.motionY = 0.0D; - this.motionZ = 0.0D; - this.prevPosX = x; - this.prevPosY = y; - this.prevPosZ = z; + for (EntityTFFallingIce entity : nearby) { + if (entity != this) { + if (entity.fallTime < this.fallTime) { + entity.setDead(); + } + } + } + + destroyIceInAABB(this.getEntityBoundingBox().grow(0.5, 0, 0.5)); + } else { + makeTrail(); + } } - - /** - * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to - * prevent them from trampling crops - */ - protected boolean canTriggerWalking() - { - return false; - } - - protected void entityInit() {} - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - public boolean canBeCollidedWith() - { - return !this.isDead; - } - - /** - * Called to update the entity's position/logic. - */ - @SuppressWarnings("unchecked") - public void onUpdate() - { - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - ++this.fallTime; - - if (this.fallTime > HANG_TIME) { - this.motionY -= 0.03999999910593033D; - } - - this.moveEntity(this.motionX, this.motionY, this.motionZ); - this.motionX *= 0.9800000190734863D; - this.motionY *= 0.9800000190734863D; - this.motionZ *= 0.9800000190734863D; - - if (!this.worldObj.isRemote) - { - //int y = MathHelper.floor_double(this.posY); - - if (this.onGround) - { - this.motionX *= 0.699999988079071D; - this.motionZ *= 0.699999988079071D; - this.motionY *= -0.5D; - - this.setDead(); - } -// else if (this.fallTime > 100 && !this.worldObj.isRemote && (y < 1 || y > 256) || this.fallTime > 600) -// { -// // something's wrong -// this.setDead(); -// } - } - - // kill other nearby blocks if they are not as old as this one - if (!this.worldObj.isRemote) { - ArrayList nearby = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox)); - - for (Entity entity : nearby) { - if (entity instanceof EntityTFFallingIce) { - EntityTFFallingIce otherIce = (EntityTFFallingIce)entity; - - if (otherIce.getFallTime() < this.fallTime) { - otherIce.setDead(); - } - } - } - - destroyIceInAABB(this.boundingBox.expand(0.5, 0, 0.5)); - } - - makeTrail(); - } - - public void makeTrail() { + + private void makeTrail() { for (int i = 0; i < 2; i++) { - double dx = this.posX + 2F * (rand.nextFloat() - rand.nextFloat()); - double dy = this.posY - 3F + 3F * (rand.nextFloat() - rand.nextFloat()); - double dz = this.posZ + 2F * (rand.nextFloat() - rand.nextFloat()); + double dx = this.posX + 2F * (rand.nextFloat() - rand.nextFloat()); + double dy = this.posY - 3F + 3F * (rand.nextFloat() - rand.nextFloat()); + double dz = this.posZ + 2F * (rand.nextFloat() - rand.nextFloat()); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowwarning", dx, dy, dz, 0, -1, 0); - - //System.out.println("Trail! " + this.worldObj); + TwilightForestMod.proxy.spawnParticle(TFParticleType.SNOW_WARNING, dx, dy, dz, 0, -1, 0); } } - /** - * Called when the mob is falling. Calculates and applies fall damage. - */ - @SuppressWarnings({ "unchecked" }) - protected void fall(float par1) - { - int distance = MathHelper.ceiling_float_int(par1 - 1.0F); - - if (distance > 0) - { - ArrayList nearby = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(2, 0, 2))); - DamageSource damagesource = DamageSource.fallingBlock; - for (Entity entity : nearby) { - if (!(entity instanceof EntityTFYetiAlpha)) { - entity.attackEntityFrom(damagesource, (float)Math.min(MathHelper.floor_float((float)distance * this.hurtAmount), this.hurtMax)); - } - } - } - + // [VanillaCopy] Like super, but without anvil cases and with extra stuff + @Override + public void fall(float distance, float multiplier) { + if (this.hurtEntities) { + int i = MathHelper.ceil(distance - 1.0F); + + if (i > 0) { + List list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox()); + DamageSource damagesource = DamageSource.FALLING_BLOCK; + + for (Entity entity : list) { + if (!(entity instanceof EntityTFYetiAlpha)) { + entity.attackEntityFrom(damagesource, (float) Math.min(MathHelper.floor((float) i * this.fallHurtAmount), this.fallHurtMax)); + } + } + } + } + + int stateId = Block.getStateId(Blocks.PACKED_ICE.getDefaultState()); for (int i = 0; i < 200; i++) { - double dx = this.posX + 3F * (rand.nextFloat() - rand.nextFloat()); - double dy = this.posY + 2 + 3F * (rand.nextFloat() - rand.nextFloat()); + double dx = this.posX + 3F * (rand.nextFloat() - rand.nextFloat()); + double dy = this.posY + 2 + 3F * (rand.nextFloat() - rand.nextFloat()); double dz = this.posZ + 3F * (rand.nextFloat() - rand.nextFloat()); - - this.worldObj.spawnParticle("blockcrack_" + Block.getIdFromBlock(Blocks.packed_ice) + "_0", dx, dy, dz, 0, 0, 0); - } - - this.playSound(Blocks.anvil.stepSound.getBreakSound(), 3F, 0.5F); - this.playSound(Blocks.packed_ice.stepSound.getBreakSound(), 3F, 0.5F); - } - - /** - * Destroys all blocks that aren't associated with 'The End' inside the given bounding box. - */ - public void destroyIceInAABB(AxisAlignedBB par1AxisAlignedBB) - { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - - for (int dx = minX; dx <= maxX; ++dx) { - for (int dy = minY; dy <= maxY; ++dy) { - for (int dz = minZ; dz <= maxZ; ++dz) { - Block block = this.worldObj.getBlock(dx, dy, dz); - - if (block == Blocks.ice || block == Blocks.packed_ice || block == Blocks.stone) { - this.worldObj.setBlock(dx, dy, dz, Blocks.air, 0, 3); - } - } - } - } - } + this.world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, dx, dy, dz, 0, 0, 0, stateId); + } - @Override - protected void readEntityFromNBT(NBTTagCompound var1) { - // TODO Auto-generated method stub - + this.playSound(Blocks.PACKED_ICE.getSoundType(Blocks.PACKED_ICE.getDefaultState(), world, getPosition(), null).getBreakSound(), 3F, 0.5F); } - @Override - protected void writeEntityToNBT(NBTTagCompound var1) { - // TODO Auto-generated method stub - + private void destroyIceInAABB(AxisAlignedBB aabb) { + int minX = MathHelper.floor(aabb.minX); + int minY = MathHelper.floor(aabb.minY); + int minZ = MathHelper.floor(aabb.minZ); + int maxX = MathHelper.floor(aabb.maxX); + int maxY = MathHelper.floor(aabb.maxY); + int maxZ = MathHelper.floor(aabb.maxZ); + + for (int dx = minX; dx <= maxX; ++dx) { + for (int dy = minY; dy <= maxY; ++dy) { + for (int dz = minZ; dz <= maxZ; ++dz) { + BlockPos pos = new BlockPos(dx, dy, dz); + Block block = this.world.getBlockState(pos).getBlock(); + + if (block == Blocks.ICE || block == Blocks.PACKED_ICE || block == Blocks.STONE) { + this.world.destroyBlock(pos, false); + } + } + } + } } - - /** - * Return whether this entity should be rendered as on fire. - */ - @SideOnly(Side.CLIENT) - public boolean canRenderOnFire() - { - return false; - } - - public Block getBlock() { - return Blocks.packed_ice; - } - - public int getFallTime() { - return this.fallTime; - } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFHydra.java b/src/main/java/twilightforest/entity/boss/EntityTFHydra.java index 9949562da9..992b4c0b00 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFHydra.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFHydra.java @@ -1,537 +1,403 @@ package twilightforest.entity.boss; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityMultiPart; +import net.minecraft.entity.MultiPartEntityPart; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.boss.EntityDragonPart; -import net.minecraft.entity.boss.IBossDisplayData; import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.BossInfo; +import net.minecraft.world.BossInfoServer; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraftforge.event.ForgeEventFactory; import twilightforest.TFFeature; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; -import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; - +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; +import twilightforest.util.EntityUtil; +import twilightforest.util.WorldUtil; +import twilightforest.world.TFWorld; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +public class EntityTFHydra extends EntityLiving implements IEntityMultiPart, IMob { -public class EntityTFHydra extends EntityLiving implements IBossDisplayData, IEntityMultiPart, IMob -{ + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/hydra"); - private static int TICKS_BEFORE_HEALING = 1000; - private static int HEAD_RESPAWN_TICKS = 100; - private static int HEAD_MAX_DAMAGE = 120; - private static float ARMOR_MULTIPLIER = 8.0F; - private static int MAX_HEALTH = 360; + private static final int TICKS_BEFORE_HEALING = 1000; + private static final int HEAD_RESPAWN_TICKS = 100; + private static final int HEAD_MAX_DAMAGE = 120; + private static final float ARMOR_MULTIPLIER = 8.0F; + private static final int MAX_HEALTH = 360; private static float HEADS_ACTIVITY_FACTOR = 0.3F; - private static int SECONDARY_FLAME_CHANCE = 10; - private static int SECONDARY_MORTAR_CHANCE = 16; - - private static final int DATA_SPAWNHEADS = 17; - private static final int DATA_BOSSHEALTH = 18; - - public Entity partArray[]; - public EntityDragonPart body; - - public HydraHeadContainer[] hc; - public int numHeads = 7; - - public EntityDragonPart leftLeg; - public EntityDragonPart rightLeg; - public EntityDragonPart tail; - - Entity currentTarget = null; - - public int ticksSinceDamaged = 0; + private static final int SECONDARY_FLAME_CHANCE = 10; + private static final int SECONDARY_MORTAR_CHANCE = 16; + + private static final DataParameter DATA_SPAWNHEADS = EntityDataManager.createKey(EntityTFHydra.class, DataSerializers.BOOLEAN); + + private final Entity partArray[]; + + public final int numHeads = 7; + public final HydraHeadContainer[] hc = new HydraHeadContainer[numHeads]; + + public final MultiPartEntityPart body = new MultiPartEntityPart(this, "body", 4F, 4F); + private final MultiPartEntityPart leftLeg = new MultiPartEntityPart(this, "leg", 2F, 3F); + private final MultiPartEntityPart rightLeg = new MultiPartEntityPart(this, "leg", 2F, 3F); + private final MultiPartEntityPart tail = new MultiPartEntityPart(this, "tail", 4F, 4F); + private final BossInfoServer bossInfo = new BossInfoServer(getDisplayName(), BossInfo.Color.BLUE, BossInfo.Overlay.PROGRESS); + + private int ticksSinceDamaged = 0; public EntityTFHydra(World world) { super(world); - partArray = (new Entity[] - { - body = new EntityDragonPart(this, "body", 4F, 4F), leftLeg = new EntityDragonPart(this, "leg", 2F, 3F), rightLeg = new EntityDragonPart(this, "leg", 2F, 3F), tail = new EntityDragonPart(this, "tail", 4F, 4F) - }); - - // head array - this.hc = new HydraHeadContainer[this.numHeads]; - for (int i = 0; i < numHeads; i++) - { + List parts = new ArrayList<>(); + parts.add(body); + parts.add(leftLeg); + parts.add(rightLeg); + parts.add(tail); + + for (int i = 0; i < numHeads; i++) { hc[i] = new HydraHeadContainer(this, i, i < 3); + Collections.addAll(parts, hc[i].getNeckArray()); } - // re-do partArray - ArrayList partList = new ArrayList(); - Collections.addAll(partList, partArray); - - for (int i = 0; i < numHeads; i++) - { - Collections.addAll(partList, hc[i].getNeckArray()); - } - - partArray = partList.toArray(partArray); - - setSize(16F, 12F); - this.ignoreFrustumCheck = true; + partArray = parts.toArray(new Entity[0]); - //texture = TwilightForestMod.MODEL_DIR + "hydra4.png"; - isImmuneToFire = true; - + this.ignoreFrustumCheck = true; + this.isImmuneToFire = true; this.experienceValue = 511; - + + setSize(16F, 12F); setSpawnHeads(true); } - - public EntityTFHydra(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } + @Override + public void setCustomNameTag(String name) { + super.setCustomNameTag(name); + this.bossInfo.setName(this.getDisplayName()); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(MAX_HEALTH); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.28D); + } + + @Override + public void addTrackingPlayer(EntityPlayerMP player) { + super.addTrackingPlayer(player); + this.bossInfo.addPlayer(player); + } + + @Override + public void removeTrackingPlayer(EntityPlayerMP player) { + super.removeTrackingPlayer(player); + this.bossInfo.removePlayer(player); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(MAX_HEALTH); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.28D); // movement speed - } - - - @SuppressWarnings("unchecked") + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL) { + world.setBlockState(getPosition().add(0, 2, 0), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.HYDRA)); + setDead(); + for (HydraHeadContainer container : hc) { + if (container.headEntity != null) { + container.headEntity.setDead(); + } + } + } else { + super.despawnEntity(); + } + } + + // [Vanilla Copy] from EntityLivingBase. Hydra doesn't like the one from EntityLiving for whatever reason @Override - public void onLivingUpdate() - { - if (hc[0].headEntity == null || hc[1].headEntity == null || hc[2].headEntity == null) + protected float updateDistance(float p_110146_1_, float p_110146_2_) + { + float f = MathHelper.wrapDegrees(p_110146_1_ - this.renderYawOffset); + this.renderYawOffset += f * 0.3F; + float f1 = MathHelper.wrapDegrees(this.rotationYaw - this.renderYawOffset); + boolean flag = f1 < -90.0F || f1 >= 90.0F; + + if (f1 < -75.0F) + { + f1 = -75.0F; + } + + if (f1 >= 75.0F) + { + f1 = 75.0F; + } + + this.renderYawOffset = this.rotationYaw - f1; + + if (f1 * f1 > 2500.0F) + { + this.renderYawOffset += f1 * 0.2F; + } + + if (flag) { + p_110146_2_ *= -1.0F; + } + + return p_110146_2_; + } + + @Override + public void onLivingUpdate() { + if (hc[0].headEntity == null || hc[1].headEntity == null || hc[2].headEntity == null) { // don't spawn if we're connected in multiplayer - if (shouldSpawnHeads() && !worldObj.isRemote) { - for (int i = 0; i < numHeads; i++) - { + if (!world.isRemote && shouldSpawnHeads()) { + for (int i = 0; i < numHeads; i++) { hc[i].headEntity = new EntityTFHydraHead(this, "head" + i, 3F, 3F); hc[i].headEntity.setPosition(this.posX, this.posY, this.posZ); - worldObj.spawnEntityInWorld(hc[i].headEntity); + hc[i].setHeadPosition(); + world.spawnEntity(hc[i].headEntity); } setSpawnHeads(false); - - //System.out.println("Server is spawning heads"); - } - else - { - // I think the head containers should attempt connection during the update call below } } - + body.onUpdate(); - + // update all heads (maybe we should change to only active ones - for (int i = 0; i < numHeads; i++) - { + for (int i = 0; i < numHeads; i++) { hc[i].onUpdate(); - } - - // update health - if (!this.worldObj.isRemote) - { - this.dataWatcher.updateObject(DATA_BOSSHEALTH, Integer.valueOf((int)this.getHealth())); - } - else - { -// if (this.getBossHealth() != this.getHealth()) -// { -// this.setEntityHealth(this.getBossHealth()); -// } - if (this.getHealth() > 0) - { - // this seems to get set off during creation at some point - this.deathTime = 0; - } - } - - if (this.hurtTime > 0) - { - for (int i = 0; i < numHeads; i++) - { - hc[i].setHurtTime(this.hurtTime); - } - } - - this.ticksSinceDamaged++; - - if (!this.worldObj.isRemote && this.ticksSinceDamaged > TICKS_BEFORE_HEALING && this.ticksSinceDamaged % 5 == 0) - { - this.heal(1); - } - - // update fight variables for difficulty setting - setDifficultyVariables(); - - if (this.newPosRotationIncrements > 0) - { - double var1 = this.posX + (this.newPosX - this.posX) / this.newPosRotationIncrements; - double var3 = this.posY + (this.newPosY - this.posY) / this.newPosRotationIncrements; - double var5 = this.posZ + (this.newPosZ - this.posZ) / this.newPosRotationIncrements; - double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - this.rotationYaw); - this.rotationYaw = (float)(this.rotationYaw + var7 / this.newPosRotationIncrements); - this.rotationPitch = (float)(this.rotationPitch + (this.newRotationPitch - this.rotationPitch) / this.newPosRotationIncrements); - --this.newPosRotationIncrements; - this.setPosition(var1, var3, var5); - this.setRotation(this.rotationYaw, this.rotationPitch); - } - - if (Math.abs(this.motionX) < 0.005D) - { - this.motionX = 0.0D; - } - - if (Math.abs(this.motionY) < 0.005D) - { - this.motionY = 0.0D; - } - - if (Math.abs(this.motionZ) < 0.005D) - { - this.motionZ = 0.0D; - } - - this.worldObj.theProfiler.startSection("ai"); - - if (this.isMovementBlocked()) - { - this.isJumping = false; - this.moveStrafing = 0.0F; - this.moveForward = 0.0F; - this.randomYawVelocity = 0.0F; - } - else if (this.isClientWorld()) - { - this.worldObj.theProfiler.startSection("oldAi"); - this.updateEntityActionState(); - this.worldObj.theProfiler.endSection(); - this.rotationYawHead = this.rotationYaw; - } - - this.worldObj.theProfiler.endSection(); - this.worldObj.theProfiler.startSection("jump"); - - if (this.isJumping) - { - if (!this.isInWater() && !this.handleLavaMovement()) - { - if (this.onGround) - { - this.jump(); - } - } - else - { - this.motionY += 0.03999999910593033D; - } - } - - this.worldObj.theProfiler.endSection(); - this.worldObj.theProfiler.startSection("travel"); - this.moveStrafing *= 0.98F; - this.moveForward *= 0.98F; - this.randomYawVelocity *= 0.9F; -// float var9 = this.landMovementFactor; -// this.landMovementFactor *= this.getSpeedModifier(); - this.moveEntityWithHeading(this.moveStrafing, this.moveForward); -// this.landMovementFactor = var9; - this.worldObj.theProfiler.endSection(); - - body.width = body.height = 6.0F; - tail.width = 6.0F; tail.height = 2.0F; - - // set body part positions - float angle; - double dx, dy, dz; - - // body goes behind the actual position of the hydra - angle = (((renderYawOffset + 180) * 3.141593F) / 180F); - - dx = posX - MathHelper.sin(angle) * 3.0; - dy = posY + 0.1; - dz = posZ + MathHelper.cos(angle) * 3.0; - body.setPosition(dx, dy, dz); - - dx = posX - MathHelper.sin(angle) * 10.5; - dy = posY + 0.1; - dz = posZ + MathHelper.cos(angle) * 10.5; - tail.setPosition(dx, dy, dz); - - //worldObj.spawnParticle("mobSpell", body.posX, body.posY, body.posZ, 0.2, 0.2, 0.2); - - this.worldObj.theProfiler.startSection("push"); - - if (!this.worldObj.isRemote && this.hurtTime == 0) - { - this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.body.boundingBox), this.body); - this.collideWithEntities(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.tail.boundingBox), this.tail); - } - - this.worldObj.theProfiler.endSection(); - - // destroy blocks - if (!this.worldObj.isRemote) - { - this.destroyBlocksInAABB(this.body.boundingBox); - this.destroyBlocksInAABB(this.tail.boundingBox); - - for (int i = 0; i < numHeads; i++) - { - if (hc[i].headEntity != null && hc[i].isActive()) - { - this.destroyBlocksInAABB(this.hc[i].headEntity.boundingBox); - } - } - - // smash blocks beneath us too - if (this.ticksExisted % 20 == 0) - { - // - if (isUnsteadySurfaceBeneath()) - { - this.destroyBlocksInAABB(this.boundingBox.offset(0, -1, 0)); - - } - } - } - - } - - + } + + if (this.hurtTime > 0) { + for (int i = 0; i < numHeads; i++) { + hc[i].setHurtTime(this.hurtTime); + } + } + + this.ticksSinceDamaged++; + + if (!this.world.isRemote && this.ticksSinceDamaged > TICKS_BEFORE_HEALING && this.ticksSinceDamaged % 5 == 0) { + this.heal(1); + } + + // update fight variables for difficulty setting + setDifficultyVariables(); + + super.onLivingUpdate(); + + body.width = body.height = 6.0F; + tail.width = 6.0F; + tail.height = 2.0F; + + // set body part positions + float angle; + double dx, dy, dz; + + // body goes behind the actual position of the hydra + angle = (((renderYawOffset + 180) * 3.141593F) / 180F); + + dx = posX - MathHelper.sin(angle) * 3.0; + dy = posY + 0.1; + dz = posZ + MathHelper.cos(angle) * 3.0; + body.setPosition(dx, dy, dz); + + dx = posX - MathHelper.sin(angle) * 10.5; + dy = posY + 0.1; + dz = posZ + MathHelper.cos(angle) * 10.5; + tail.setPosition(dx, dy, dz); + + // destroy blocks + if (!this.world.isRemote) { + if (hurtTime == 0) { + this.collideWithEntities(this.world.getEntitiesWithinAABBExcludingEntity(this, this.body.getEntityBoundingBox()), this.body); + this.collideWithEntities(this.world.getEntitiesWithinAABBExcludingEntity(this, this.tail.getEntityBoundingBox()), this.tail); + } + + this.destroyBlocksInAABB(this.body.getEntityBoundingBox()); + this.destroyBlocksInAABB(this.tail.getEntityBoundingBox()); + + for (int i = 0; i < numHeads; i++) { + if (hc[i].headEntity != null && hc[i].isActive()) { + this.destroyBlocksInAABB(this.hc[i].headEntity.getEntityBoundingBox()); + } + } + + // smash blocks beneath us too + if (this.ticksExisted % 20 == 0) { + if (isUnsteadySurfaceBeneath()) { + this.destroyBlocksInAABB(this.getEntityBoundingBox().offset(0, -1, 0)); + + } + } + + bossInfo.setPercent(getHealth() / getMaxHealth()); + } + } + @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(DATA_SPAWNHEADS, Byte.valueOf((byte)0)); - this.dataWatcher.addObject(DATA_BOSSHEALTH, new Integer(MAX_HEALTH)); - } - - - public boolean shouldSpawnHeads() - { - return dataWatcher.getWatchableObjectByte(DATA_SPAWNHEADS) != 0; - } - - public void setSpawnHeads(boolean flag) - { - if (flag) - { - dataWatcher.updateObject(DATA_SPAWNHEADS, Byte.valueOf((byte)127)); - } - else - { - dataWatcher.updateObject(DATA_SPAWNHEADS, Byte.valueOf((byte)0)); - } - } - - /** - * Save to disk. - */ - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - super.writeEntityToNBT(nbttagcompound); - nbttagcompound.setBoolean("SpawnHeads", shouldSpawnHeads()); - nbttagcompound.setByte("NumHeads", (byte) countActiveHeads()); - } - - /** - * Load from disk. Return state to roughly where we saved it. - */ - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - setSpawnHeads(nbttagcompound.getBoolean("SpawnHeads")); - activateNumberOfHeads(nbttagcompound.getByte("NumHeads")); - } + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_SPAWNHEADS, false); + } + private boolean shouldSpawnHeads() { + return dataManager.get(DATA_SPAWNHEADS); + } + private void setSpawnHeads(boolean flag) { + dataManager.set(DATA_SPAWNHEADS, flag); + } @Override - protected void updateEntityActionState() - { -// System.out.println("Calling updateEntityActionState"); -// System.out.println("Current target = " + currentTarget); - - entityAge++; - despawnEntity(); + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("SpawnHeads", shouldSpawnHeads()); + compound.setByte("NumHeads", (byte) countActiveHeads()); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + setSpawnHeads(compound.getBoolean("SpawnHeads")); + activateNumberOfHeads(compound.getByte("NumHeads")); + if (this.hasCustomName()) { + this.bossInfo.setName(this.getDisplayName()); + } + } + + + // TODO modernize this more (old AI copypasta still kind of here) + private int numTicksToChaseTarget; + + @Override + protected void updateAITasks() { moveStrafing = 0.0F; moveForward = 0.0F; float f = 48F; - + // kill heads that have taken too much damage - for (int i = 0; i < numHeads; i++) - { - if (hc[i].isActive() && hc[i].getDamageTaken() > HEAD_MAX_DAMAGE) - { - hc[i].setNextState(HydraHeadContainer.STATE_DYING); + for (int i = 0; i < numHeads; i++) { + if (hc[i].isActive() && hc[i].getDamageTaken() > HEAD_MAX_DAMAGE) { + hc[i].setNextState(HydraHeadContainer.State.DYING); hc[i].endCurrentAction(); - + // set this head and a random dead head to respawn hc[i].setRespawnCounter(HEAD_RESPAWN_TICKS); int otherHead = getRandomDeadHead(); - if (otherHead != -1) - { + if (otherHead != -1) { hc[otherHead].setRespawnCounter(HEAD_RESPAWN_TICKS); } } } - if (rand.nextFloat() < 0.7F) - { - EntityPlayer entityplayer1 = worldObj.getClosestVulnerablePlayerToEntity(this, f); - //EntityPlayer entityplayer1 = worldObj.getClosestPlayerToEntity(this, f); + if (rand.nextFloat() < 0.7F) { + EntityPlayer entityplayer1 = world.getNearestAttackablePlayer(this, f, f); - if (entityplayer1 != null) - { - currentTarget = entityplayer1; + if (entityplayer1 != null) { + setAttackTarget(entityplayer1); numTicksToChaseTarget = 100 + rand.nextInt(20); - } - else - { + } else { randomYawVelocity = (rand.nextFloat() - 0.5F) * 20F; } } - if (currentTarget != null) - { - faceEntity(currentTarget, 10F, getVerticalFaceSpeed()); - + if (getAttackTarget() != null) { + faceEntity(getAttackTarget(), 10F, getVerticalFaceSpeed()); + // have any heads not currently attacking switch to the primary target - for (int i = 0; i < numHeads; i++) - { - if (!isHeadAttacking(hc[i]) && !hc[i].isSecondaryAttacking) - { - hc[i].setTargetEntity(currentTarget); - } - } - + for (int i = 0; i < numHeads; i++) { + if (!hc[i].isAttacking() && !hc[i].isSecondaryAttacking) { + hc[i].setTargetEntity(getAttackTarget()); + } + } + // let's pick an attack - if (this.currentTarget.isEntityAlive()) - { - float distance = this.currentTarget.getDistanceToEntity(this); - - if (this.canEntityBeSeen(this.currentTarget)) - { - this.attackEntity(this.currentTarget, distance); - } - } - - if (numTicksToChaseTarget-- <= 0 || currentTarget.isDead || currentTarget.getDistanceSqToEntity(this) > (double)(f * f)) - { - currentTarget = null; + if (this.getAttackTarget().isEntityAlive()) { + float distance = this.getAttackTarget().getDistance(this); + + if (this.getEntitySenses().canSee(this.getAttackTarget())) { + this.attackEntity(this.getAttackTarget(), distance); + } } - } - else - { - if (rand.nextFloat() < 0.05F) - { + + if (numTicksToChaseTarget-- <= 0 || getAttackTarget().isDead || getAttackTarget().getDistanceSq(this) > (double) (f * f)) { + setAttackTarget(null); + } + } else { + if (rand.nextFloat() < 0.05F) { randomYawVelocity = (rand.nextFloat() - 0.5F) * 20F; } rotationYaw += randomYawVelocity; - rotationPitch = defaultPitch; - + rotationPitch = 0; + // TODO: while we are idle, consider having the heads breathe fire on passive mobs - + // set idle heads to no target - for (int i = 0; i < numHeads; i++) - { - if (hc[i].currentState == HydraHeadContainer.STATE_IDLE) - { - hc[i].setTargetEntity(null); - } - } + for (int i = 0; i < numHeads; i++) { + if (hc[i].isIdle()) { + hc[i].setTargetEntity(null); + } + } } - + // heads that are free at this point may consider attacking secondary targets this.secondaryAttacks(); - - boolean flag = isInWater(); - boolean flag1 = handleLavaMovement(); - - if (flag || flag1) - { - isJumping = rand.nextFloat() < 0.8F; - } } - /** - * Make some of the mechanics harder on hard mode - */ private void setDifficultyVariables() { - if (worldObj.difficultySetting != EnumDifficulty.HARD) - { + if (world.getDifficulty() != EnumDifficulty.HARD) { EntityTFHydra.HEADS_ACTIVITY_FACTOR = 0.3F; - } - else - { - // hard mode! + } else { EntityTFHydra.HEADS_ACTIVITY_FACTOR = 0.5F; // higher is harder } - } - /** - * Find a random head to respawn - * - * TODO: make random - */ + // TODO: make random private int getRandomDeadHead() { - for (int i = 0; i < numHeads; i++) - { - if (hc[i].currentState == HydraHeadContainer.STATE_DEAD && hc[i].respawnCounter == -1) - { + for (int i = 0; i < numHeads; i++) { + if (hc[i].canRespawn()) { return i; } } return -1; } - + /** - * Used when re-loading from save. Assumes three heads are active and activates more if necessary. - * - * @param howMany + * Used when re-loading from save. Assumes three heads are active and activates more if necessary. */ - private void activateNumberOfHeads(int howMany) - { + private void activateNumberOfHeads(int howMany) { int moreHeads = howMany - this.countActiveHeads(); - - //System.out.println("Reactivating " + moreHeads + " more heads."); - - for (int i = 0; i < moreHeads; i++) - { + + for (int i = 0; i < moreHeads; i++) { int otherHead = getRandomDeadHead(); - if (otherHead != -1) - { + if (otherHead != -1) { // move directly into not dead - hc[otherHead].currentState = HydraHeadContainer.STATE_IDLE; - hc[otherHead].setNextState(HydraHeadContainer.STATE_IDLE); + hc[otherHead].setNextState(HydraHeadContainer.State.IDLE); hc[otherHead].endCurrentAction(); } } @@ -545,679 +411,393 @@ private void attackEntity(Entity target, float distance) { int BITE_CHANCE = 10; int FLAME_CHANCE = 100; int MORTAR_CHANCE = 160; - - boolean targetAbove = target.boundingBox.minY > this.boundingBox.maxY; + + boolean targetAbove = target.getEntityBoundingBox().minY > this.getEntityBoundingBox().maxY; // three main heads can do these kinds of attacks - for (int i = 0; i < 3; i++) - { - if (hc[i].currentState == HydraHeadContainer.STATE_IDLE && !areTooManyHeadsAttacking(target, i)) - { - if (distance > 4 && distance < 10 && rand.nextInt(BITE_CHANCE) == 0 && this.countActiveHeads() > 2 && !areOtherHeadsBiting(target, i)) - { - hc[i].setNextState(HydraHeadContainer.STATE_BITE_BEGINNING); - } - else if (distance > 0 && distance < 20 && rand.nextInt(FLAME_CHANCE) == 0) - { - hc[i].setNextState(HydraHeadContainer.STATE_FLAME_BEGINNING); - } - else if (distance > 8 && distance < 32 && !targetAbove && rand.nextInt(MORTAR_CHANCE) == 0) - { - hc[i].setNextState(HydraHeadContainer.STATE_MORTAR_BEGINNING); + for (int i = 0; i < 3; i++) { + if (hc[i].isIdle() && !areTooManyHeadsAttacking(i)) { + if (distance > 4 && distance < 10 && rand.nextInt(BITE_CHANCE) == 0 && this.countActiveHeads() > 2 && !areOtherHeadsBiting(i)) { + hc[i].setNextState(HydraHeadContainer.State.BITE_BEGINNING); + } else if (distance > 0 && distance < 20 && rand.nextInt(FLAME_CHANCE) == 0) { + hc[i].setNextState(HydraHeadContainer.State.FLAME_BEGINNING); + } else if (distance > 8 && distance < 32 && !targetAbove && rand.nextInt(MORTAR_CHANCE) == 0) { + hc[i].setNextState(HydraHeadContainer.State.MORTAR_BEGINNING); } } } // heads 4-7 can do everything but bite - for (int i = 3; i < numHeads; i++) - { - if (hc[i].currentState == HydraHeadContainer.STATE_IDLE && !areTooManyHeadsAttacking(target, i)) - { - if (distance > 0 && distance < 20 && rand.nextInt(FLAME_CHANCE) == 0) - { - hc[i].setNextState(HydraHeadContainer.STATE_FLAME_BEGINNING); - } - else if (distance > 8 && distance < 32 && !targetAbove && rand.nextInt(MORTAR_CHANCE) == 0) - { - hc[i].setNextState(HydraHeadContainer.STATE_MORTAR_BEGINNING); + for (int i = 3; i < numHeads; i++) { + if (hc[i].isIdle() && !areTooManyHeadsAttacking(i)) { + if (distance > 0 && distance < 20 && rand.nextInt(FLAME_CHANCE) == 0) { + hc[i].setNextState(HydraHeadContainer.State.FLAME_BEGINNING); + } else if (distance > 8 && distance < 32 && !targetAbove && rand.nextInt(MORTAR_CHANCE) == 0) { + hc[i].setNextState(HydraHeadContainer.State.MORTAR_BEGINNING); } } } } - protected boolean areTooManyHeadsAttacking(Entity target, int testHead) { + private boolean areTooManyHeadsAttacking(int testHead) { int otherAttacks = 0; - for (int i = 0; i < numHeads; i++) - { - if (i != testHead && isHeadAttacking(hc[i])) - { + for (int i = 0; i < numHeads; i++) { + if (i != testHead && hc[i].isAttacking()) { otherAttacks++; - + // biting heads count triple - if (isHeadBiting(hc[i])) - { + if (hc[i].isBiting()) { otherAttacks += 2; } } } - + return otherAttacks >= 1 + (countActiveHeads() * HEADS_ACTIVITY_FACTOR); } - - /** - * How many active heads do we have? - */ - public int countActiveHeads() - { + + private int countActiveHeads() { int count = 0; - - for (int i = 0; i < numHeads; i++) - { - if (hc[i].isActive()) - { + + for (int i = 0; i < numHeads; i++) { + if (hc[i].isActive()) { count++; } } - - return count; - } - - private boolean isHeadAttacking(HydraHeadContainer head) { - return head.currentState == HydraHeadContainer.STATE_BITE_BEGINNING || head.currentState == HydraHeadContainer.STATE_BITE_READY - || head.currentState == HydraHeadContainer.STATE_BITE_BITING || head.currentState == HydraHeadContainer.STATE_FLAME_BEGINNING - || head.currentState == HydraHeadContainer.STATE_FLAME_BREATHING || head.currentState == HydraHeadContainer.STATE_MORTAR_BEGINNING - || head.currentState == HydraHeadContainer.STATE_MORTAR_LAUNCH; + return count; } - protected boolean areOtherHeadsBiting(Entity target, int testHead) - { - for (int i = 0; i < numHeads; i++) - { - if (i != testHead && isHeadBiting(hc[i])) - { + private boolean areOtherHeadsBiting(int testHead) { + for (int i = 0; i < numHeads; i++) { + if (i != testHead && hc[i].isBiting()) { return true; } } - return false; } - protected boolean isHeadBiting(HydraHeadContainer head) - { - return head.currentState == HydraHeadContainer.STATE_BITE_BEGINNING || head.currentState == HydraHeadContainer.STATE_BITE_READY - || head.currentState == HydraHeadContainer.STATE_BITE_BITING || head.nextState == HydraHeadContainer.STATE_BITE_BEGINNING; - } - /** * Called sometime after the main attackEntity routine. Finds a valid secondary target and has an unoccupied head start an attack against it. - * - * The center head (head 0) does not make secondary attacks + *

+ * The center head (head 0) does not make secondary attacks */ private void secondaryAttacks() { - for (int i = 0; i < numHeads; i++) - { - if (hc[i].headEntity == null) - { + for (int i = 0; i < numHeads; i++) { + if (hc[i].headEntity == null) { return; } } - - // find entities nearby that none of the heads are targeting right now - EntityLivingBase secondaryTarget = findSecondaryTarget(20); - - if (secondaryTarget != null) - { - float distance = secondaryTarget.getDistanceToEntity(this); - - //System.out.println("Found a valid secondary target " + distance + " squares away."); - //System.out.println("Secondary target is " + secondaryTarget); - - for (int i = 1; i < numHeads; i++) - { - if (hc[i].isActive() && hc[i].currentState == HydraHeadContainer.STATE_IDLE && isTargetOnThisSide(i, secondaryTarget)) - { - if (distance > 0 && distance < 20 && rand.nextInt(SECONDARY_FLAME_CHANCE) == 0) - { - hc[i].setTargetEntity(secondaryTarget); - hc[i].isSecondaryAttacking = true; - hc[i].setNextState(HydraHeadContainer.STATE_FLAME_BEGINNING); - } - else if (distance > 8 && distance < 32 && rand.nextInt(SECONDARY_MORTAR_CHANCE) == 0) - { - hc[i].setTargetEntity(secondaryTarget); - hc[i].isSecondaryAttacking = true; - hc[i].setNextState(HydraHeadContainer.STATE_MORTAR_BEGINNING); - } - } - - } + EntityLivingBase secondaryTarget = findSecondaryTarget(20); + + if (secondaryTarget != null) { + float distance = secondaryTarget.getDistance(this); + + for (int i = 1; i < numHeads; i++) { + if (hc[i].isActive() && hc[i].isIdle() && isTargetOnThisSide(i, secondaryTarget)) { + if (distance > 0 && distance < 20 && rand.nextInt(SECONDARY_FLAME_CHANCE) == 0) { + hc[i].setTargetEntity(secondaryTarget); + hc[i].isSecondaryAttacking = true; + hc[i].setNextState(HydraHeadContainer.State.FLAME_BEGINNING); + } else if (distance > 8 && distance < 32 && rand.nextInt(SECONDARY_MORTAR_CHANCE) == 0) { + hc[i].setTargetEntity(secondaryTarget); + hc[i].isSecondaryAttacking = true; + hc[i].setNextState(HydraHeadContainer.State.MORTAR_BEGINNING); + } + } + } } } - + /** * Used to make sure heads don't attack across the whole body */ - public boolean isTargetOnThisSide(int headNum, Entity target) - { + private boolean isTargetOnThisSide(int headNum, Entity target) { double headDist = distanceSqXZ(hc[headNum].headEntity, target); double middleDist = distanceSqXZ(this, target); - return headDist < middleDist; } - /** * Square of distance between two entities with y not a factor, just x and z */ - private double distanceSqXZ(Entity headEntity, Entity target) { - double distX = headEntity.posX - target.posX; - double distZ = headEntity.posZ - target.posZ; - return distX * distX + distZ * distZ; - } + private double distanceSqXZ(Entity headEntity, Entity target) { + double distX = headEntity.posX - target.posX; + double distZ = headEntity.posZ - target.posZ; + return distX * distX + distZ * distZ; + } + + @Nullable + private EntityLivingBase findSecondaryTarget(double range) { + return this.world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(this.posX, this.posY, this.posZ, this.posX + 1, this.posY + 1, this.posZ + 1).grow(range, range, range)) + .stream() + .filter(e -> !(e instanceof EntityTFHydra || e instanceof EntityTFHydraPart)) + .filter(e -> e != getAttackTarget() && !isAnyHeadTargeting(e) && getEntitySenses().canSee(e)) + .min(Comparator.comparingDouble(this::getDistanceSq)).orElse(null); + } + + private boolean isAnyHeadTargeting(Entity targetEntity) { + for (int i = 0; i < numHeads; i++) { + if (hc[i].targetEntity != null && hc[i].targetEntity.equals(targetEntity)) { + return true; + } + } + + return false; + } + + // [VanillaCopy] based on EntityDragon.collideWithEntities + private void collideWithEntities(List entities, Entity part) { + double d0 = (part.getEntityBoundingBox().minX + part.getEntityBoundingBox().maxX) / 2.0D; + double d1 = (part.getEntityBoundingBox().minZ + part.getEntityBoundingBox().maxZ) / 2.0D; + + for (Entity entity : entities) { + if (entity instanceof EntityLivingBase) { + double d2 = entity.posX - d0; + double d3 = entity.posZ - d1; + double d4 = d2 * d2 + d3 * d3; + entity.addVelocity(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D); + } + } + } /** - * Find an EntityLiving within the specified range. Exclude our primary target and any head's target. - * - * Right now just finds the closest living entity that is not exluded by our criteria - */ - @SuppressWarnings("unchecked") - public EntityLivingBase findSecondaryTarget(double range) - { - double closestRange = -1.0D; - EntityLivingBase closestEntity = null; - - List nearbyEntities = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(this.posX, this.posY, this.posZ, this.posX + 1, this.posY + 1, this.posZ + 1).expand(range, range, range)); - - for (EntityLivingBase nearbyLiving : nearbyEntities) - { - // exclude me - if (nearbyLiving instanceof EntityTFHydra || nearbyLiving instanceof EntityTFHydraPart) - { - continue; + * Check the surface immediately beneath us, if it is less than 80% solid + */ + private boolean isUnsteadySurfaceBeneath() { + int minX = MathHelper.floor(this.getEntityBoundingBox().minX); + int minZ = MathHelper.floor(this.getEntityBoundingBox().minZ); + int maxX = MathHelper.floor(this.getEntityBoundingBox().maxX); + int maxZ = MathHelper.floor(this.getEntityBoundingBox().maxZ); + int minY = MathHelper.floor(this.getEntityBoundingBox().minY); + + int solid = 0; + int total = 0; + + int dy = minY - 1; + + for (int dx = minX; dx <= maxX; ++dx) { + for (int dz = minZ; dz <= maxZ; ++dz) { + total++; + if (this.world.getBlockState(new BlockPos(dx, dy, dz)).getMaterial().isSolid()) { + solid++; + } } - - // exclude current target and any head's target - if (nearbyLiving == currentTarget || isAnyHeadTargeting(nearbyLiving)) - { - continue; + } + + return ((float) solid / (float) total) < 0.6F; + } + + private void destroyBlocksInAABB(AxisAlignedBB box) { + if (ForgeEventFactory.getMobGriefingEvent(world, this)) { + for (BlockPos pos : WorldUtil.getAllInBB(box)) { + if (EntityUtil.canDestroyBlock(world, pos, this)) { + world.destroyBlock(pos, false); + } } - - // only things we can see - if (!this.canEntityBeSeen(nearbyLiving)) - { - continue; + } + } + + @Override + public int getVerticalFaceSpeed() { + return 500; + } + + @Override + public boolean attackEntityFromPart(MultiPartEntityPart part, DamageSource source, float damage) { + return calculateRange(source) <= 400 && super.attackEntityFrom(source, Math.round(damage / 8.0F)); + } + + public boolean attackEntityFromPart(EntityTFHydraPart part, DamageSource source, float damage) { + // if we're in a wall, kill that wall + if (!world.isRemote && source == DamageSource.IN_WALL) { + destroyBlocksInAABB(part.getEntityBoundingBox()); + } + + HydraHeadContainer headCon = null; + + for (int i = 0; i < numHeads; i++) { + if (hc[i].headEntity == part) { + headCon = hc[i]; } - - double curDist = nearbyLiving.getDistanceSq(this.posX, this.posY, this.posZ); + } - if ((range < 0.0D || curDist < range * range) && (closestRange == -1.0D || curDist < closestRange)) - { - closestRange = curDist; - closestEntity = nearbyLiving; + double range = calculateRange(source); + + if (range > 400) { + return false; + } + + // ignore hits on dying heads, it's weird + if (headCon != null && !headCon.isActive()) { + return false; + } + + boolean tookDamage; + if (headCon != null && headCon.getCurrentMouthOpen() > 0.5) { + tookDamage = super.attackEntityFrom(source, damage); + headCon.addDamage(damage); + } else { + int armoredDamage = Math.round(damage / ARMOR_MULTIPLIER); + tookDamage = super.attackEntityFrom(source, armoredDamage); + + if (headCon != null) { + headCon.addDamage(armoredDamage); } + } + if (tookDamage) { + this.ticksSinceDamaged = 0; } - return closestEntity; - } - - boolean isAnyHeadTargeting(Entity targetEntity) - { - for (int i = 0; i < numHeads; i++) - { - if (hc[i].targetEntity != null && hc[i].targetEntity.equals(targetEntity)) - { - return true; - } - } - - return false; - } - - - /** - * Pushes all entities inside the list away from the enderdragon. - */ - private void collideWithEntities(List par1List, Entity part) - { - double pushPower = 4.0D; - - double centerX = (part.boundingBox.minX + part.boundingBox.maxX) / 2.0D; - double centerY = (part.boundingBox.minZ + part.boundingBox.maxZ) / 2.0D; - - for (Entity entity : par1List) - { - if (entity instanceof EntityLivingBase) - { - double distX = entity.posX - centerX; - double distZ = entity.posZ - centerY; - double sqDist = distX * distX + distZ * distZ; - entity.addVelocity(distX / sqDist * pushPower, 0.20000000298023224D, distZ / sqDist * pushPower); - } - } - } - - /** - * Check the surface immediately beneath us, if it is less than 80% solid - * @return - */ - private boolean isUnsteadySurfaceBeneath() { - - int minX = MathHelper.floor_double(this.boundingBox.minX); - int minZ = MathHelper.floor_double(this.boundingBox.minZ); - int maxX = MathHelper.floor_double(this.boundingBox.maxX); - int maxZ = MathHelper.floor_double(this.boundingBox.maxZ); - int minY = MathHelper.floor_double(this.boundingBox.minY); - - int solid = 0; - int total = 0; - - int dy = minY - 1; - - for (int dx = minX; dx <= maxX; ++dx) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - total++; - if (this.worldObj.getBlock(dx, dy, dz).getMaterial().isSolid()) - { - solid++; - } - } - } - - //System.out.println("Checking solidness. total = " + total + ", solid = " + solid + ", ratio = " + ((float)solid / (float)total)); - - return ((float)solid / (float)total) < 0.6F; + return tookDamage; } - /** - * Destroys all blocks that aren't associated with 'The End' inside the given bounding box. - */ - private boolean destroyBlocksInAABB(AxisAlignedBB par1AxisAlignedBB) - { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - boolean wasBlocked = false; - for (int dx = minX; dx <= maxX; ++dx) - { - for (int dy = minY; dy <= maxY; ++dy) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - Block currentID = this.worldObj.getBlock(dx, dy, dz); - - if (currentID != Blocks.air) - { - int currentMeta = this.worldObj.getBlockMetadata(dx, dy, dz); - - if (currentID != Blocks.obsidian && currentID != Blocks.end_stone && currentID != Blocks.bedrock) - { - this.worldObj.setBlock(dx, dy, dz, Blocks.air, 0, 2); - - // here, this effect will have to do - worldObj.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - } - else - { - wasBlocked = true; - } - } - } - } - } - - return wasBlocked; - } + private double calculateRange(DamageSource damagesource) { + return damagesource.getTrueSource() != null ? getDistanceSq(damagesource.getTrueSource()) : -1; + } + + @Override + public boolean attackEntityFrom(DamageSource src, float damage) { + return src == DamageSource.OUT_OF_WORLD && super.attackEntityFrom(src, damage); + } /** - * Rather than speed, this seems to control how far up or down the heads can tilt? + * We need to do this for the bounding boxes on the parts to become active */ @Override - public int getVerticalFaceSpeed() - { - return 500; - } - - - - @Override - public boolean attackEntityFromPart(EntityDragonPart dragonpart, DamageSource damagesource, float i) - { - // I think only the body parts are EntityDragonPart. - //System.out.println("Taking an attack on part " + dragonpart.name + " of type " + damagesource.damageType); - - // try to find range that damage is coming from - double range = calculateRange(damagesource); - - //System.out.println("We decided the range is " + range); - - if (range > 400) - { - //System.out.println("Ignoring attack from out of range"); - return false; - } - - return superAttackFrom(damagesource, Math.round(i / 8.0F)); - } - - protected boolean superAttackFrom(DamageSource par1DamageSource, float par2) - { - return super.attackEntityFrom(par1DamageSource, par2); - } - - public boolean attackEntityFromPart(EntityTFHydraPart part, DamageSource damagesource, float damageAmount) - { - //System.out.println("Taking an attack on part " + part.getPartName() + " of type " + damagesource.damageType); - - // if we're in a wall, kill that wall - if (!worldObj.isRemote && damagesource == DamageSource.inWall && part.getBoundingBox() != null) - { - destroyBlocksInAABB(part.getBoundingBox()); - } - - HydraHeadContainer headCon = null; - - for (int i = 0; i < numHeads; i++) - { - if (hc[i].headEntity == part) - { - headCon = hc[i]; - } - } - - // try to find range that damage is coming from - double range = calculateRange(damagesource); - - //System.out.println("We decided the range is " + range); - - if (range > 400) - { - //System.out.println("Ignoring attack from out of range"); - return false; - } - - // ignore hits on dying heads, it's weird - if (headCon != null && !headCon.isActive()) - { - return false; - } - - boolean tookDamage; - if (headCon != null && headCon.getCurrentMouthOpen() > 0.5) - { - tookDamage = superAttackFrom(damagesource, damageAmount); - headCon.addDamage(damageAmount); - } - else - { - int armoredDamage = Math.round(damageAmount / ARMOR_MULTIPLIER); - tookDamage = superAttackFrom(damagesource, armoredDamage); - - if (headCon != null) - { - headCon.addDamage(armoredDamage); - } - } - - if (tookDamage) - { - this.ticksSinceDamaged = 0; - } - - return tookDamage; - } - - protected double calculateRange(DamageSource damagesource) { - double range = -1; - - if (damagesource.getSourceOfDamage() != null) - { - range = this.getDistanceSqToEntity(damagesource.getSourceOfDamage()); - } - - if (damagesource.getEntity() != null) - { - range = this.getDistanceSqToEntity(damagesource.getEntity()); - } - return range; + public Entity[] getParts() { + return partArray; } - - /** - * Called when the entity is attacked. - */ - @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) - { -// System.out.println("Taking a direct attack of type " + par1DamageSource.damageType); -// -// return superAttackFrom(par1DamageSource, Math.round(par2 / 8.0F)); - return false; - } - - - /** - * We need to do this for the bounding boxes on the parts to become active - */ - @Override - public Entity[] getParts() - { - return partArray; - } - - /** - * This is set as off for the hydra, which has an enormous bounding box, but set as on for the parts. - */ - @Override - public boolean canBeCollidedWith() - { - return false; - } - - /** - * If this is on, the player pushes us based on our bounding box rather than it going by parts - */ + + /** + * This is set as off for the hydra, which has an enormous bounding box, but set as on for the parts. + */ @Override - public boolean canBePushed() { + public boolean canBeCollidedWith() { return false; } - + /** - * Don't get knocked back + * If this is on, the player pushes us based on our bounding box rather than it going by parts */ - @Override - public void knockBack(Entity entity, float i, double d, double d1) - { - // do nothing? - } - - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.hydra.growl"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.hydra.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.hydra.death"; - } - - /** - * Returns the volume for the sounds this mob makes. - */ - @Override - protected float getSoundVolume() - { - return 2F; - } - - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightKillHydra); - } - + public boolean canBePushed() { + return false; + } + + @Override + protected void collideWithEntity(Entity entity) {} + + @Override + public void knockBack(Entity entity, float strength, double xRatio, double zRatio) {} + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.HYDRA_GROWL; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.HYDRA_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.HYDRA_DEATH; + } + + @Override + protected float getSoundVolume() { + return 2F; + } + + @Override + public void onDeath(DamageSource cause) { + super.onDeath(cause); // mark the lair as defeated - if (!worldObj.isRemote && worldObj.provider instanceof WorldProviderTwilightForest) { - int dx = MathHelper.floor_double(this.posX); - int dy = MathHelper.floor_double(this.posY); - int dz = MathHelper.floor_double(this.posZ); - - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)worldObj.provider).getChunkProvider(); - TFFeature nearbyFeature = ((TFWorldChunkManager)worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, worldObj); - - if (nearbyFeature == TFFeature.hydraLair) { - chunkProvider.setStructureConquered(dx, dy, dz, true); - } + if (!world.isRemote) { + TFWorld.markStructureConquered(world, new BlockPos(this), TFFeature.HYDRA_LAIR); } } - - /** - * EPIC LOOTZ! - */ + @Override - protected void dropFewItems(boolean par1, int par2) { - - // chops - int totalDrops = this.rand.nextInt(3 + par2) + 5; - for (int i = 0; i < totalDrops; ++i) - { - this.dropItem(TFItems.hydraChop, 5); - } - - // blood - totalDrops = this.rand.nextInt(4 + par2) + 7; - for (int i = 0; i < totalDrops; ++i) - { - this.dropItem(TFItems.fieryBlood, 1); - } - - // trophy - this.dropItem(TFItems.trophy, 1); + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + protected boolean canDespawn() { + return false; + } + + @Override + public boolean isBurning() { + return false; } - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - /** - * Returns true if the entity is on fire. Used by render to add the fire effect on rendering. - */ - @Override - public boolean isBurning() - { - // never burn - return false; - } - - /** - * handles entity death timer, experience orb and particle creation - */ @Override - protected void onDeathUpdate() - { - ++this.deathTime; - - // stop any head actions on death - if (deathTime == 1) - { - for (int i = 0; i < numHeads; i++) - { - hc[i].setRespawnCounter(-1); - if (hc[i].isActive()) - { - hc[i].setNextState(HydraHeadContainer.STATE_IDLE); - hc[i].endCurrentAction(); - hc[i].setHurtTime(200); - } - } - } - - // heads die off one by one - if (this.deathTime <= 140 && this.deathTime % 20 == 0) - { - int headToDie = (this.deathTime / 20) - 1; - - if (hc[headToDie].isActive()) - { - hc[headToDie].setNextState(HydraHeadContainer.STATE_DYING); + protected void onDeathUpdate() { + ++this.deathTime; + + // stop any head actions on death + if (deathTime == 1) { + for (int i = 0; i < numHeads; i++) { + hc[i].setRespawnCounter(-1); + if (hc[i].isActive()) { + hc[i].setNextState(HydraHeadContainer.State.IDLE); + hc[i].endCurrentAction(); + hc[i].setHurtTime(200); + } + } + } + + // heads die off one by one + if (this.deathTime <= 140 && this.deathTime % 20 == 0) { + int headToDie = (this.deathTime / 20) - 1; + + if (hc[headToDie].isActive()) { + hc[headToDie].setNextState(HydraHeadContainer.State.DYING); hc[headToDie].endCurrentAction(); } - } - - if (this.deathTime == 200) - { - if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && !this.isChild()) - { - int var1 = this.getExperiencePoints(this.attackingPlayer); - - while (var1 > 0) - { - int var2 = EntityXPOrb.getXPSplit(var1); - var1 -= var2; - this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, var2)); - } - } - - this.setDead(); - - } - - for (int var1 = 0; var1 < 20; ++var1) - { - double var8 = this.rand.nextGaussian() * 0.02D; - double var4 = this.rand.nextGaussian() * 0.02D; - double var6 = this.rand.nextGaussian() * 0.02D; - String particle = rand.nextInt(2) == 0 ? "largeexplode" : "explode"; - this.worldObj.spawnParticle(particle, this.posX + this.rand.nextFloat() * this.body.width * 2.0F - this.body.width, this.posY + this.rand.nextFloat() * this.body.height, this.posZ + this.rand.nextFloat() * this.body.width * 2.0F - this.body.width, var8, var4, var6); - } - } + } + + if (this.deathTime == 200) { + if (!this.world.isRemote && (this.isPlayer() || this.recentlyHit > 0 && this.canDropLoot() && this.world.getGameRules().getBoolean("doMobLoot"))) { + int i = this.getExperiencePoints(this.attackingPlayer); + i = ForgeEventFactory.getExperienceDrop(this, this.attackingPlayer, i); + while (i > 0) { + int j = EntityXPOrb.getXPSplit(i); + i -= j; + this.world.spawnEntity(new EntityXPOrb(this.world, this.posX, this.posY, this.posZ, j)); + } + } + + this.setDead(); + } + + for (int i = 0; i < 20; ++i) { + double vx = this.rand.nextGaussian() * 0.02D; + double vy = this.rand.nextGaussian() * 0.02D; + double vz = this.rand.nextGaussian() * 0.02D; + EnumParticleTypes particle = rand.nextInt(2) == 0 ? EnumParticleTypes.EXPLOSION_LARGE : EnumParticleTypes.EXPLOSION_NORMAL; + this.world.spawnParticle(particle, + this.posX + this.rand.nextFloat() * this.body.width * 2.0F - this.body.width, + this.posY + this.rand.nextFloat() * this.body.height, + this.posZ + this.rand.nextFloat() * this.body.width * 2.0F - this.body.width, + vx, vy, vz + ); + } + } @Override - public World func_82194_d() { - return this.worldObj; + public World getWorld() { + return this.world; } -// @Override -// public int getBossHealth() { -// return this.dataWatcher.getWatchableObjectInt(EntityTFHydra.DATA_BOSSHEALTH); -// } - - + @Override + public boolean isNonBoss() { + return false; + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFHydraHead.java b/src/main/java/twilightforest/entity/boss/EntityTFHydraHead.java index 096b4fbe70..fcdf844a6e 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFHydraHead.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFHydraHead.java @@ -1,81 +1,56 @@ package twilightforest.entity.boss; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.world.World; public class EntityTFHydraHead extends EntityTFHydraPart { - - public EntityTFHydraHead(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "hydra4.png"; - + + private static final DataParameter DATA_MOUTH_POSITION = EntityDataManager.createKey(EntityTFHydraHead.class, DataSerializers.FLOAT); + private static final DataParameter DATA_STATE = EntityDataManager.createKey(EntityTFHydraHead.class, DataSerializers.BYTE); + + public EntityTFHydraHead(World world) { + super(world); // the necks draw with the head, so we just draw the head at all times, sorry this.ignoreFrustumCheck = true; - } + } - public EntityTFHydraHead(EntityTFHydra hydra, String s, float f, float f1) { - super(hydra, s, f, f1); + public EntityTFHydraHead(EntityTFHydra hydra, String name, float width, float height) { + super(hydra, name, width, height); } - - - /** - * Rather than speed, this seems to control how far up or down the heads can tilt? - */ + @Override - public int getVerticalFaceSpeed() - { - return 500; - } - - /** - * We have our own custom death here. In any case, we don't actually ever die, despawn and spew out XP orbs, so don't do that - */ + public int getVerticalFaceSpeed() { + return 500; + } + @Override protected void onDeathUpdate() { - ++this.deathTime; + ++this.deathTime; } @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(18, Byte.valueOf((byte)0)); - dataWatcher.addObject(19, Byte.valueOf((byte)0)); - } - - - public float getMouthOpen() - { - return (dataWatcher.getWatchableObjectByte(18) & 0xFF) / 255.0F; - } + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_MOUTH_POSITION, 0F); + dataManager.register(DATA_STATE, (byte) 0); + } + + public float getMouthOpen() { + return dataManager.get(DATA_MOUTH_POSITION); + } - public int getState() - { - return (dataWatcher.getWatchableObjectByte(19) & 0xFF); - } + public HydraHeadContainer.State getState() { + return HydraHeadContainer.State.values()[dataManager.get(DATA_STATE)]; + } - public void setMouthOpen(float openness) - { - // bounds - if (openness < 0.0F) - { - openness = 0.0F; - } - if (openness > 1.0F) - { - openness = 1.0F; - } - - int openByte = Math.round(openness * 255); - - openByte &= 0xFF; - dataWatcher.updateObject(18, Byte.valueOf((byte)openByte)); - } + public void setMouthOpen(float openness) { + dataManager.set(DATA_MOUTH_POSITION, openness); + } - public void setState(int state) - { - state &= 0xFF; - dataWatcher.updateObject(19, Byte.valueOf((byte)state)); - } + public void setState(HydraHeadContainer.State state) { + dataManager.set(DATA_STATE, (byte) state.ordinal()); + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFHydraMortar.java b/src/main/java/twilightforest/entity/boss/EntityTFHydraMortar.java index 43ba8eae74..71065cc475 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFHydraMortar.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFHydraMortar.java @@ -1,232 +1,172 @@ package twilightforest.entity.boss; -import java.util.ArrayList; -import java.util.List; - -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Blocks; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.EntityDamageSourceIndirect; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.Explosion; import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; +import twilightforest.TwilightForestMod; public class EntityTFHydraMortar extends EntityThrowable { - private static final int BURN_FACTOR = 5; + private static final int BURN_FACTOR = 5; private static final int DIRECT_DAMAGE = 18; - - public EntityLivingBase playerReflects = null; - + public int fuse = 80; - - public boolean megaBlast = false; - - public EntityTFHydraMortar(World par1World) - { - super(par1World); - this.setSize(0.75F, 0.75F); - - } - - public EntityTFHydraMortar(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); - this.setSize(0.75F, 0.75F); + private boolean megaBlast = false; + + public EntityTFHydraMortar(World world) { + super(world); + this.setSize(0.75F, 0.75F); + } + + public EntityTFHydraMortar(World world, EntityTFHydraHead head) { + super(world, head); + this.setSize(0.75F, 0.75F); + + Vec3d vector = head.getLookVec(); + + double dist = 3.5; + double px = head.posX + vector.x * dist; + double py = head.posY + 1 + vector.y * dist; + double pz = head.posZ + vector.z * dist; + + setLocationAndAngles(px, py, pz, 0, 0); + // these are being set to extreme numbers when we get here, why? + head.motionX = 0; + head.motionY = 0; + head.motionZ = 0; + shoot(head, head.rotationPitch, head.rotationYaw, -20.0F, 0.5F, 1F); + + TwilightForestMod.LOGGER.debug("Launching mortar! Current head motion is {}, {}", head.motionX, head.motionZ); + } + + @Override + public void onUpdate() { + super.onUpdate(); + + this.pushOutOfBlocks(this.posX, (this.getEntityBoundingBox().minY + this.getEntityBoundingBox().maxY) / 2.0D, this.posZ); + + if (this.onGround) { + this.motionX *= 0.9D; + this.motionY *= 0.9D; + this.motionZ *= 0.9D; + + if (!world.isRemote && this.fuse-- <= 0) { + detonate(); + } + } } - /** - * Called to update the entity's position/logic. - */ - @Override - public void onUpdate() - { - super.onUpdate(); - - this.func_145771_j(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ); // push out of block - - if (this.onGround) - { - if (!worldObj.isRemote) - { - // slow down - this.motionX *= 0.9D; - this.motionY *= 0.9D; - this.motionZ *= 0.9D; - } - - // eventually explode - if (this.fuse-- <= 0) - { - detonate(); - } - - } - } - - - /** - * Converts this mortar into a blasting one. - */ public void setToBlasting() { this.megaBlast = true; } - - /** - * Called when this EntityThrowable hits a block or entity. - */ @Override - protected void onImpact(MovingObjectPosition mop) { - if (mop.entityHit == null && !megaBlast) - { + protected void onImpact(RayTraceResult ray) { + if (ray.entityHit == null && !megaBlast) { // we hit the ground this.motionY = 0; this.onGround = true; - } - else - { + } else if (!world.isRemote && ray.entityHit != thrower && !isPartOfHydra(ray.entityHit)) { detonate(); + } + } + private boolean isPartOfHydra(Entity entity) { + if (thrower instanceof EntityTFHydraPart) { + EntityTFHydra hydra = ((EntityTFHydraPart) thrower).hydra; + if (hydra == null || hydra.getParts() == null) + return false; + if (entity == hydra) + return true; + for (Entity e : hydra.getParts()) + if (entity == e) + return true; + for (HydraHeadContainer container : hydra.hc) + if (entity == container.headEntity) + return true; } + return false; } - + @Override - public float func_145772_a(Explosion par1Explosion, World par2World, int par3, int par4, int par5, Block par6Block) - { - float var6 = super.func_145772_a(par1Explosion, par2World, par3, par4, par5, par6Block); - - if (this.megaBlast && par6Block != Blocks.bedrock && par6Block != Blocks.end_portal && par6Block != Blocks.end_portal_frame) - { - var6 = Math.min(0.8F, var6); - } - - return var6; - } - - @SuppressWarnings("unchecked") - protected void detonate() - { - //this.worldObj.playAuxSFX(2004, (int)Math.round(this.posX), (int)Math.round(this.posY), (int)Math.round(this.posZ), 32764); - - //this.worldObj.createExplosion((Entity)null, this.posX, this.posY, this.posZ, explosionPower, true); - + public float getExplosionResistance(Explosion explosion, World world, BlockPos pos, IBlockState state) { + float resistance = super.getExplosionResistance(explosion, world, pos, state); + + if (this.megaBlast && state.getBlock() != Blocks.BEDROCK && state.getBlock() != Blocks.END_PORTAL && state.getBlock() != Blocks.END_PORTAL_FRAME) { + resistance = Math.min(0.8F, resistance); + } + + return resistance; + } + + private void detonate() { float explosionPower = megaBlast ? 4.0F : 0.1F; - this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, explosionPower, true, true); + boolean flag = ForgeEventFactory.getMobGriefingEvent(world, this); + this.world.newExplosion(this, this.posX, this.posY, this.posZ, explosionPower, flag, flag); + + DamageSource src = new EntityDamageSourceIndirect("onFire", this, getThrower()).setFireDamage().setProjectile(); + + for (Entity nearby : this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().grow(1.0D, 1.0D, 1.0D))) { + if (nearby.attackEntityFrom(src, DIRECT_DAMAGE) && !nearby.isImmuneToFire()) { + nearby.setFire(BURN_FACTOR); + } + } + this.setDead(); + } - if (!worldObj.isRemote) - { - // damage nearby things - List nearbyList = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(1.0D, 1.0D, 1.0D))); + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + super.attackEntityFrom(source, amount); + + if (source.getTrueSource() != null && !this.world.isRemote) { + Vec3d vec3d = source.getTrueSource().getLookVec(); + if (vec3d != null) { + // reflect faster and more accurately + this.shoot(vec3d.x, vec3d.y, vec3d.z, 1.5F, 0.1F); // reflect faster and more accurately + this.onGround = false; + this.fuse += 20; + } - for (Entity nearby : nearbyList) - { - if (nearby.attackEntityFrom(DamageSource.causeFireballDamage(null, this.getThrower()), DIRECT_DAMAGE) && !nearby.isImmuneToFire()) - { - nearby.setFire(BURN_FACTOR); - } + if (source.getTrueSource() instanceof EntityLivingBase) { + this.thrower = (EntityLivingBase) source.getTrueSource(); } + return true; + } else { + return false; } + } - this.setDead(); - } - - /** - * Reflect! - */ @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { -// System.out.println("Hydra mortar being attacked!"); - - setBeenAttacked(); - if (damagesource.getEntity() != null && !this.worldObj.isRemote) - { - Vec3 vec3d = damagesource.getEntity().getLookVec(); - if (vec3d != null) - { - this.setThrowableHeading(vec3d.xCoord, vec3d.yCoord + 1, vec3d.zCoord, 1.5F, 0.1F); // reflect faster and more accurately - this.onGround = false; - this.fuse += 20; - - } - if (damagesource.getEntity() instanceof EntityLivingBase) - { - this.playerReflects = (EntityLivingBase)damagesource.getEntity(); - } - return true; - } - else - { - return false; - } - } - - - /** - * Return who threw this projectile - */ - @Override - public EntityLivingBase getThrower() - { - if (this.playerReflects != null) - { - return this.playerReflects; - } - else - { - return super.getThrower(); - } - } + public boolean isBurning() { + return true; + } + + @Override + public boolean canBeCollidedWith() { + return true; + } /** - * Always be on fire! + * We need to set this so that the player can attack and reflect the bolt */ @Override - public boolean isBurning() - { - return true; + public float getCollisionBorderSize() { + return 1.5F; } - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - @Override - public boolean canBeCollidedWith() - { - return true; - } - - /** - * We need to set this so that the player can attack and reflect the bolt - */ - @Override - public float getCollisionBorderSize() - { - return 1.5F; - } - - /** - * Gets the amount of gravity to apply to the thrown entity with each tick. - */ - @Override - protected float getGravityVelocity() - { - return 0.05F; - } - - @Override - protected float func_70182_d() - { - return 0.75F; - } - - @Override - protected float func_70183_g() - { - return -20.0F; - } + @Override + protected float getGravityVelocity() { + return 0.05F; + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFHydraNeck.java b/src/main/java/twilightforest/entity/boss/EntityTFHydraNeck.java index 5dc898e1d1..4a1b2b0bcf 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFHydraNeck.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFHydraNeck.java @@ -2,8 +2,8 @@ public class EntityTFHydraNeck extends EntityTFHydraPart { - public EntityTFHydraNeck(EntityTFHydra hydra, String s, float f, float f1) { - super(hydra, s, f, f1); + public EntityTFHydraNeck(EntityTFHydra hydra, String name, float width, float height) { + super(hydra, name, width, height); } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFHydraPart.java b/src/main/java/twilightforest/entity/boss/EntityTFHydraPart.java index 92c6e2a3cd..31fc2fa5b8 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFHydraPart.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFHydraPart.java @@ -4,158 +4,133 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; - public class EntityTFHydraPart extends EntityLiving { - public EntityTFHydra hydraObj; - public EntityTFHydraPart(World world) - { - super(world); + private static final DataParameter PART_NAME = EntityDataManager.createKey(EntityTFHydraPart.class, DataSerializers.STRING); + + public EntityTFHydra hydra; + + public EntityTFHydraPart(World world) { + super(world); isImmuneToFire = true; - } - - public EntityTFHydraPart(EntityTFHydra hydra, String s, float f, float f1) - { - super(hydra.worldObj); - setSize(f, f1); - hydraObj = hydra; - setPartName(s); - + } + + public EntityTFHydraPart(EntityTFHydra hydra, String name, float width, float height) { + super(hydra.world); + setSize(width, height); + this.hydra = hydra; + setPartName(name); //texture = TwilightForestMod.MODEL_DIR + "hydra4.png"; isImmuneToFire = true; + } - } - @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(17, ""); - } - - - public String getPartName() - { - return dataWatcher.getWatchableObjectString(17); - } - - public void setPartName(String name) - { - dataWatcher.updateObject(17, name); - } - - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - super.writeEntityToNBT(nbttagcompound); - nbttagcompound.setString("PartName", getPartName()); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - setPartName(nbttagcompound.getString("PartName")); - } - - /** - * We need this to display bounding boxes - */ - @Override - public void onUpdate() { - if (this.hydraObj != null && this.hydraObj.deathTime > 190) - { - setDead(); - } - - // just die if we've been alive 60 seconds and there's still no body - if (this.hydraObj == null && this.ticksExisted > 1200) - { - setDead(); - } - - super.onEntityUpdate(); - - lastTickPosX = posX; - lastTickPosY = posY; - lastTickPosZ = posZ; - - if (this.newPosRotationIncrements > 0) - { - double var1 = this.posX + (this.newPosX - this.posX) / this.newPosRotationIncrements; - double var3 = this.posY + (this.newPosY - this.posY) / this.newPosRotationIncrements; - double var5 = this.posZ + (this.newPosZ - this.posZ) / this.newPosRotationIncrements; - double var7 = MathHelper.wrapAngleTo180_double(this.newRotationYaw - this.rotationYaw); - this.rotationYaw = (float)(this.rotationYaw + var7 / this.newPosRotationIncrements); - this.rotationPitch = (float)(this.rotationPitch + (this.newRotationPitch - this.rotationPitch) / this.newPosRotationIncrements); - --this.newPosRotationIncrements; - this.setPosition(var1, var3, var5); - this.setRotation(this.rotationYaw, this.rotationPitch); - } - - - - //System.out.println("Updating " + this + " with angles " + rotationYawHead + ", " + rotationPitch); - - - this.rotationYawHead = this.rotationYaw; - this.prevRotationYawHead = this.prevRotationYaw; - - for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } - for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } - for (; renderYawOffset - prevRenderYawOffset < -180F; prevRenderYawOffset -= 360F) { } - for (; renderYawOffset - prevRenderYawOffset >= 180F; prevRenderYawOffset += 360F) { } - for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } - for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } - for (; rotationYawHead - prevRotationYawHead < -180F; prevRotationYawHead -= 360F) { } - for (; rotationYawHead - prevRotationYawHead >= 180F; prevRotationYawHead += 360F) { } - - - - } - - - /** - * Set monster attributes - */ + protected void entityInit() { + super.entityInit(); + dataManager.register(PART_NAME, ""); + } + + public String getPartName() { + return dataManager.get(PART_NAME); + } + + public void setPartName(String name) { + dataManager.set(PART_NAME, name); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(1000D); // max health - } - + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setString("PartName", getPartName()); + } @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { - if (hydraObj != null) - { - return hydraObj.attackEntityFromPart(this, damagesource, i); + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + setPartName(compound.getString("PartName")); + } + + @Override + public void onUpdate() { + if (this.hydra != null && this.hydra.deathTime > 190) { + setDead(); + } + + // just die if we've been alive 60 seconds and there's still no body + if (this.hydra == null && this.ticksExisted > 1200) { + setDead(); } - else - { - return false; + + super.onEntityUpdate(); + + lastTickPosX = posX; + lastTickPosY = posY; + lastTickPosZ = posZ; + + if (this.newPosRotationIncrements > 0) { + double x = this.posX + (this.interpTargetX - this.posX) / this.newPosRotationIncrements; + double y = this.posY + (this.interpTargetY - this.posY) / this.newPosRotationIncrements; + double z = this.posZ + (this.interpTargetZ - this.posZ) / this.newPosRotationIncrements; + double yawDelta = MathHelper.wrapDegrees(this.interpTargetYaw - this.rotationYaw); + this.rotationYaw = (float) (this.rotationYaw + yawDelta / this.newPosRotationIncrements); + this.rotationPitch = (float) (this.rotationPitch + (this.interpTargetPitch - this.rotationPitch) / this.newPosRotationIncrements); + --this.newPosRotationIncrements; + this.setPosition(x, y, z); + this.setRotation(this.rotationYaw, this.rotationPitch); } - } - - public boolean isEntityEqual(Entity entity) - { - return this == entity || hydraObj == entity; - } - - /** - * Sets the rotation of the entity - */ - @Override - protected void setRotation(float par1, float par2) - { - this.rotationYaw = par1 % 360.0F; - this.rotationPitch = par2 % 360.0F; - } + + this.rotationYawHead = this.rotationYaw; + this.prevRotationYawHead = this.prevRotationYaw; + + while (rotationYaw - prevRotationYaw < -180F) prevRotationYaw -= 360F; + while (rotationYaw - prevRotationYaw >= 180F) prevRotationYaw += 360F; + + while (renderYawOffset - prevRenderYawOffset < -180F) prevRenderYawOffset -= 360F; + while (renderYawOffset - prevRenderYawOffset >= 180F) prevRenderYawOffset += 360F; + + while (rotationPitch - prevRotationPitch < -180F) prevRotationPitch -= 360F; + while (rotationPitch - prevRotationPitch >= 180F) prevRotationPitch += 360F; + + while (rotationYawHead - prevRotationYawHead < -180F) prevRotationYawHead -= 360F; + while (rotationYawHead - prevRotationYawHead >= 180F) prevRotationYawHead += 360F; + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(1000D); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + return hydra != null && hydra.attackEntityFromPart(this, source, amount); + } + + @Override + public boolean isEntityEqual(Entity entity) { + return this == entity || hydra == entity; + } + + @Override + protected void setRotation(float yaw, float pitch) { + this.rotationYaw = yaw % 360.0F; + this.rotationPitch = pitch % 360.0F; + } + + @Override + public boolean isNonBoss() { + return false; + } + + @Override + protected boolean canDespawn() { + return hydra == null; + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFIceBomb.java b/src/main/java/twilightforest/entity/boss/EntityTFIceBomb.java index 7f6b5c1443..85216051ce 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFIceBomb.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFIceBomb.java @@ -1,209 +1,154 @@ package twilightforest.entity.boss; -import java.util.ArrayList; - import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.entity.Entity; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Blocks; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFThrowable; import twilightforest.entity.EntityTFYeti; +import twilightforest.potions.TFPotions; + +import java.util.List; + +public class EntityTFIceBomb extends EntityTFThrowable { -public class EntityTFIceBomb extends EntityThrowable { - private int zoneTimer = 80; private boolean hasHit; - public EntityTFIceBomb(World par1World) { - super(par1World); + public EntityTFIceBomb(World world) { + super(world); } - public EntityTFIceBomb(World par1World, EntityLivingBase thrower) { - super(par1World, thrower); + public EntityTFIceBomb(World world, EntityLivingBase thrower) { + super(world, thrower); } - /** - * Called when this EntityThrowable hits a block or entity. - */ @Override - protected void onImpact(MovingObjectPosition mop) { - if (this.getThrower() != null && this.getThrower() instanceof EntityTFYetiAlpha) { - double dist = this.getDistanceSqToEntity(this.getThrower()); - - if (dist <= 100) { - this.setDead(); - } - } - + protected void onImpact(RayTraceResult ray) { this.motionY = 0; this.hasHit = true; - - if (!worldObj.isRemote) { + + if (!world.isRemote) this.doTerrainEffects(); - } } - - /** - * Called when this EntityThrowable hits a block or entity. - */ - private void doTerrainEffects() { - int range = 3; - int ix = MathHelper.floor_double(this.lastTickPosX); - int iy = MathHelper.floor_double(this.lastTickPosY); - int iz = MathHelper.floor_double(this.lastTickPosZ); - + + private void doTerrainEffects() { + + final int range = 3; + + int ix = MathHelper.floor(this.lastTickPosX); + int iy = MathHelper.floor(this.lastTickPosY); + int iz = MathHelper.floor(this.lastTickPosZ); + for (int x = -range; x <= range; x++) { for (int y = -range; y <= range; y++) { for (int z = -range; z <= range; z++) { - this.doTerrainEffect(ix + x, iy + y, iz + z); + this.doTerrainEffect(new BlockPos(ix + x, iy + y, iz + z)); } } } } - /** - * Freeze water, put snow on snowable surfaces - */ - private void doTerrainEffect(int x, int y, int z) { - if (this.worldObj.getBlock(x, y, z).getMaterial() == Material.water) { - this.worldObj.setBlock(x, y, z, Blocks.ice); + /** + * Freeze water, put snow on snowable surfaces + */ + private void doTerrainEffect(BlockPos pos) { + IBlockState state = world.getBlockState(pos); + if (state.getMaterial() == Material.WATER) { + this.world.setBlockState(pos, Blocks.ICE.getDefaultState()); } - if (this.worldObj.getBlock(x, y, z).getMaterial() == Material.lava) { - this.worldObj.setBlock(x, y, z, Blocks.obsidian); + if (state.getMaterial() == Material.LAVA) { + this.world.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState()); } - if (this.worldObj.isAirBlock(x, y, z) && Blocks.snow_layer.canPlaceBlockAt(this.worldObj, x, y, z)) { - this.worldObj.setBlock(x, y, z, Blocks.snow_layer); + if (this.world.isAirBlock(pos) && Blocks.SNOW_LAYER.canPlaceBlockAt(this.world, pos)) { + this.world.setBlockState(pos, Blocks.SNOW_LAYER.getDefaultState()); + } + } + + @Override + public void onUpdate() { + super.onUpdate(); + + if (this.hasHit) { + this.motionX *= 0.1D; + this.motionY *= 0.1D; + this.motionZ *= 0.1D; + + this.zoneTimer--; + makeIceZone(); + + if (!world.isRemote && this.zoneTimer <= 0) { + world.playEvent(2001, new BlockPos(this), Block.getStateId(Blocks.ICE.getDefaultState())); + setDead(); + } + } else { + makeTrail(); } } - /** - * Called to update the entity's position/logic. - */ - @Override - public void onUpdate() - { - super.onUpdate(); - - //this.func_145771_j(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ); // push out of block - - if (this.hasHit) - { - if (!worldObj.isRemote) - { - // slow down - this.motionX *= 0.1D; - this.motionY *= 0.1D; - this.motionZ *= 0.1D; - } - - this.zoneTimer--; - - makeIceZone(); - - // eventually explode - if (this.zoneTimer <= 0) - { - detonate(); - } - - } else { - makeTrail(); - } - } - public void makeTrail() { + int stateId = Block.getStateId(Blocks.SNOW.getDefaultState()); for (int i = 0; i < 10; i++) { - double dx = posX + 0.75F * (rand.nextFloat() - 0.5F); - double dy = posY + 0.75F * (rand.nextFloat() - 0.5F); - double dz = posZ + 0.75F * (rand.nextFloat() - 0.5F); - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowstuff", dx, dy, dz, 0, 0, 0); + double dx = posX + 0.75F * (rand.nextFloat() - 0.5F); + double dy = posY + 0.75F * (rand.nextFloat() - 0.5F); + double dz = posZ + 0.75F * (rand.nextFloat() - 0.5F); + + world.spawnParticle(EnumParticleTypes.FALLING_DUST, dx, dy, dz, -motionX, -motionY, -motionZ, stateId); } } private void makeIceZone() { - // nearby sparkles - if (this.worldObj.isRemote) { + if (this.world.isRemote) { // sparkles + int stateId = Block.getStateId(Blocks.SNOW.getDefaultState()); for (int i = 0; i < 20; i++) { double dx = this.posX + (rand.nextFloat() - rand.nextFloat()) * 3.0F; double dy = this.posY + (rand.nextFloat() - rand.nextFloat()) * 3.0F; double dz = this.posZ + (rand.nextFloat() - rand.nextFloat()) * 3.0F; - - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowstuff", dx, dy, dz, 0.0D, 0.0D, 0.0D); + + world.spawnParticle(EnumParticleTypes.FALLING_DUST, dx, dy, dz, 0, 0, 0, stateId); } } else { - // damage if (this.zoneTimer % 10 == 0) { - hitNearbyEntities(); - + hitNearbyEntities(); } } } - @SuppressWarnings("unchecked") private void hitNearbyEntities() { - ArrayList nearby = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(3, 2, 3))); - - for (Entity entity : nearby) { - if (entity instanceof EntityLivingBase && entity != this.getThrower()) { - + List nearby = this.world.getEntitiesWithinAABB(EntityLivingBase.class, this.getEntityBoundingBox().grow(3, 2, 3)); + + for (EntityLivingBase entity : nearby) { + if (entity != this.getThrower()) { if (entity instanceof EntityTFYeti) { // TODO: make "frozen yeti" entity? + BlockPos pos = new BlockPos(entity.lastTickPosX, entity.lastTickPosY, entity.lastTickPosZ); + world.setBlockState(pos, Blocks.ICE.getDefaultState()); + world.setBlockState(pos.up(), Blocks.ICE.getDefaultState()); + entity.setDead(); - int ix = MathHelper.floor_double(entity.lastTickPosX); - int iy = MathHelper.floor_double(entity.lastTickPosY); - int iz = MathHelper.floor_double(entity.lastTickPosZ); - - worldObj.setBlock(ix, iy, iz, Blocks.ice); - worldObj.setBlock(ix, iy + 1, iz, Blocks.ice); - } else { - entity.attackEntityFrom(DamageSource.magic, 1); - int chillLevel = 2; - ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 20 * 5, chillLevel, true)); + entity.attackEntityFrom(DamageSource.MAGIC, 1); + entity.addPotionEffect(new PotionEffect(TFPotions.frosty, 20 * 5, 2)); } - } } } - private void detonate() { - this.setDead(); + public IBlockState getBlock() { + return Blocks.PACKED_ICE.getDefaultState(); } - public Block getBlock() { - return Blocks.packed_ice; + @Override + protected float getGravityVelocity() { + return this.hasHit ? 0F : 0.025F; } - - @Override - protected float func_70182_d() - { - // velocity - return 0.75F; - } - - /** - * Gets the amount of gravity to apply to the thrown entity with each tick. - */ - @Override - protected float getGravityVelocity() - { - return this.hasHit ? 0F : 0.025F; - } - - @Override - protected float func_70183_g() - { - return -20.0F; - } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFIceCrystal.java b/src/main/java/twilightforest/entity/boss/EntityTFIceCrystal.java index 407e8c31cb..51c617eddf 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFIceCrystal.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFIceCrystal.java @@ -1,133 +1,94 @@ package twilightforest.entity.boss; -import twilightforest.TwilightForestMod; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; import net.minecraft.world.World; +import twilightforest.TFSounds; +import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFIceMob; + +public class EntityTFIceCrystal extends EntityTFIceMob { -public class EntityTFIceCrystal extends EntityMob { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/ice_crystal"); private int crystalAge; - public int maxCrystalAge; - - - public EntityTFIceCrystal(World par1World) { - super(par1World); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); - this.tasks.addTask(2, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(3, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - this.setSize(0.6F, 1.8F); - - this.maxCrystalAge = -1; - - //this.setCurrentItemOrArmor(0, new ItemStack(TFItems.iceSword)); + private int maxCrystalAge = -1; + + public EntityTFIceCrystal(World world) { + super(world); + this.setSize(0.6F, 1.8F); + + //this.setCurrentItemOrArmor(0, new ItemStack(TFItems.iceSword)); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, false)); + this.tasks.addTask(2, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(3, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(5.0D); + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + public int getMaxSpawnedInChunk() { + return 8; + } + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.ICE_AMBIENT; } + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.ICE_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.ICE_DEATH; + } + + public void setToDieIn30Seconds() { + this.maxCrystalAge = 600; + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (!world.isRemote) { + this.crystalAge++; + if (this.maxCrystalAge > 0 && this.crystalAge >= this.maxCrystalAge) { + this.setDead(); + } + } + } - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(5.0D); - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return Items.snowball; - } - - /** - * Will return how many at most can spawn in a chunk at once. - */ - public int getMaxSpawnedInChunk() - { - return 8; - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.ice.noise"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.ice.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.ice.death"; - } - - - /** - * Used by the snow queen when she summons crystals - */ - public void setToDieIn30Seconds() { - this.maxCrystalAge = 600; - } - -// -// /** -// * Get this Entity's EnumCreatureAttribute -// */ -// public EnumCreatureAttribute getCreatureAttribute() -// { -// return EnumCreatureAttribute.UNDEAD; -// } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - - this.crystalAge++; - - //System.out.println("I am a skeleton and my age is " + this.skeletonAge); - - // die after 30 seconds - if (this.maxCrystalAge > 0 && this.crystalAge >= this.maxCrystalAge && !this.worldObj.isRemote) { - this.setDead(); - } - } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFKnightPhantom.java b/src/main/java/twilightforest/entity/boss/EntityTFKnightPhantom.java index f63fc676e1..53339a1e55 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFKnightPhantom.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFKnightPhantom.java @@ -1,998 +1,500 @@ package twilightforest.entity.boss; -import java.util.List; - +import com.google.common.collect.Lists; +import com.google.common.primitives.Ints; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityFlying; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; +import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EntitySelectors; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; -import twilightforest.TFTreasure; -import twilightforest.TwilightForestMod; +import twilightforest.TFSounds; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; +import twilightforest.entity.NoClipMoveHelper; +import twilightforest.entity.ai.EntityAIPhantomAttackStart; +import twilightforest.entity.ai.EntityAIPhantomThrowWeapon; +import twilightforest.entity.ai.EntityAITFFindEntityNearestPlayer; +import twilightforest.entity.ai.EntityAITFPhantomUpdateFormationAndMove; +import twilightforest.entity.ai.EntityAITFPhantomWatchAndAttack; import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; - -public class EntityTFKnightPhantom extends EntityFlying implements IMob -{ - - private static final float CIRCLE_SMALL_RADIUS = 2.5F; - private static final float CIRCLE_LARGE_RADIUS = 8.5F; - private static final int FLAG_CHARGING = 17; - int number; - int ticksProgress; - Formation currentFormation; - - private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0); - /** If -1 there is no maximum distance */ - private float maximumHomeDistance = -1.0F; - - private int chargePosX; - private int chargePosY; - private int chargePosZ; - - public enum Formation { HOVER, LARGE_CLOCKWISE, SMALL_CLOCKWISE, LARGE_ANTICLOCKWISE, SMALL_ANTICLOCKWISE, CHARGE_PLUSX, CHARGE_MINUSX, CHARGE_PLUSZ, CHARGE_MINUSZ, WAITING_FOR_LEADER, ATTACK_PLAYER_START, ATTACK_PLAYER_ATTACK}; - - public EntityTFKnightPhantom(World par1World) { - super(par1World); - - this.setSize(1.5F, 3.0F); - - this.noClip = true; - this.isImmuneToFire = true; - - this.currentFormation = Formation.HOVER; - - this.experienceValue = 93; - - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.knightlySword)); - this.setCurrentItemOrArmor(3, new ItemStack(TFItems.phantomPlate)); - this.setCurrentItemOrArmor(4, new ItemStack(TFItems.phantomHelm)); - - - } - - +import twilightforest.world.TFWorld; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.List; + +public class EntityTFKnightPhantom extends EntityFlying implements IMob { + + private static final DataParameter FLAG_CHARGING = EntityDataManager.createKey(EntityTFKnightPhantom.class, DataSerializers.BOOLEAN); + private static final AttributeModifier CHARGING_MODIFIER = new AttributeModifier("Charging attack boost", 7, 0).setSaved(false); + + private int number; + private int ticksProgress; + private Formation currentFormation; + private BlockPos chargePos = BlockPos.ORIGIN; + + public EntityTFKnightPhantom(World world) { + super(world); + setSize(1.5F, 3.0F); + noClip = true; + isImmuneToFire = true; + currentFormation = Formation.HOVER; + experienceValue = 93; + moveHelper = new NoClipMoveHelper(this); + } + @Override - protected void entityInit() - { - super.entityInit(); - dataWatcher.addObject(FLAG_CHARGING, Byte.valueOf((byte)0)); - } - - /** - * Set monster attributes - */ + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) { + IEntityLivingData data = super.onInitialSpawn(difficulty, livingdata); + setEquipmentBasedOnDifficulty(difficulty); + setEnchantmentBasedOnDifficulty(difficulty); + return data; + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(35.0D); // max health - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); // initialize this value - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(1.0D); // attack damage - } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - /** - * Called when the entity is attacked. - */ - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) - { - if (this.isEntityInvulnerable()) - { - return false; - } - else if (par1DamageSource == DamageSource.inWall) - { - return false; - } - else - { - return super.attackEntityFrom(par1DamageSource, par2); - } - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - - if (this.isChargingAtPlayer()) - { - // make particles - for (int i = 0; i < 4; ++i) - { - Item particleID = this.rand.nextBoolean() ? TFItems.phantomHelm : TFItems.knightlySword; - - worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(particleID), this.posX + (this.rand.nextFloat() * this.rand.nextFloat() - 0.5D) * this.width, this.posY + this.rand.nextFloat() * (this.height - 0.75D) + 0.5D, this.posZ + (this.rand.nextFloat() * this.rand.nextFloat() - 0.5D) * this.width, 0, -0.1, 0); - worldObj.spawnParticle("smoke", this.posX + (this.rand.nextFloat() * this.rand.nextFloat() - 0.5D) * this.width, this.posY + this.rand.nextFloat() * (this.height - 0.75D) + 0.5D, this.posZ + (this.rand.nextFloat() * this.rand.nextFloat() - 0.5D) * this.width, 0, 0.1, 0); - } - } - } - - /** - * handles entity death timer, experience orb and particle creation - */ + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.knightmetal_sword)); + setItemStackToSlot(EntityEquipmentSlot.CHEST, new ItemStack(TFItems.phantom_chestplate)); + setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(TFItems.phantom_helmet)); + } + @Override - protected void onDeathUpdate() - { - super.onDeathUpdate(); - - for (int i = 0; i < 20; ++i) - { - double d0 = this.rand.nextGaussian() * 0.02D; - double d1 = this.rand.nextGaussian() * 0.02D; - double d2 = this.rand.nextGaussian() * 0.02D; - this.worldObj.spawnParticle("explode", this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, d0, d1, d2); - } - - - } - - /** - * Trigger achievement when killed - */ + protected void entityInit() { + super.entityInit(); + dataManager.register(FLAG_CHARGING, false); + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightProgressKnights); - } - - // mark the stronghold as defeated - if (!worldObj.isRemote && worldObj.provider instanceof WorldProviderTwilightForest) { - int dx = getHomePosition().posX; - int dy = getHomePosition().posY; - int dz = getHomePosition().posZ; - - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)worldObj.provider).getChunkProvider(); - TFFeature nearbyFeature = ((TFWorldChunkManager)worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, worldObj); - - if (nearbyFeature == TFFeature.tfStronghold) { - chunkProvider.setStructureConquered(dx, dy, dz, true); + protected void initEntityAI() { + tasks.addTask(0, new EntityAITFPhantomWatchAndAttack(this)); + tasks.addTask(1, new EntityAITFPhantomUpdateFormationAndMove(this)); + tasks.addTask(2, new EntityAIPhantomAttackStart(this)); + tasks.addTask(3, new EntityAIPhantomThrowWeapon(this)); + + targetTasks.addTask(0, new EntityAITFFindEntityNearestPlayer(this)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(35.0D); + getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE); + getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(1.0D); + } + + public Formation getCurrentFormation() { + return currentFormation; + } + + public BlockPos getChargePos() { + return chargePos; + } + + public void setChargePos(BlockPos pos) { + chargePos = pos; + } + + @Override + protected boolean canDespawn() { + return false; + } + + @Override + public boolean isEntityInvulnerable(DamageSource src) { + return src == DamageSource.IN_WALL || super.isEntityInvulnerable(src); + } + + @Override + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL) { + if (hasHome() && getNumber() == 0) { + world.setBlockState(getHomePosition(), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.KNIGHT_PHANTOM)); } - } - - - // make treasure for killing the last knight - if (!this.worldObj.isRemote) { - // am I the last one?!?! - List nearbyKnights = getNearbyKnights(); - if (nearbyKnights.size() <= 1) - { - // make a treasure!' - //System.out.println("I think I'm the last one!"); - this.makeATreasure(); - } - } - - } - - /** - * Make a treasure for when we're dead - */ - private void makeATreasure() { - if (this.getHomePosition().posX != 0) { - // if we have a proper home position, generate the treasure there - TFTreasure.stronghold_boss.generate(worldObj, null, getHomePosition().posX, getHomePosition().posY - 1, getHomePosition().posZ); + setDead(); } else { - // if not, spawn it right where we are - int px = MathHelper.floor_double(this.lastTickPosX); - int py = MathHelper.floor_double(this.lastTickPosY); - int pz = MathHelper.floor_double(this.lastTickPosZ); - - TFTreasure.stronghold_boss.generate(worldObj, null, px, py, pz); + super.despawnEntity(); } } + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (isChargingAtPlayer()) { + // make particles + for (int i = 0; i < 4; ++i) { + Item particleID = rand.nextBoolean() ? TFItems.phantom_helmet : TFItems.knightmetal_sword; - /** - * Formation-based AI - */ - protected void updateEntityActionState() - { - if (!this.worldObj.isRemote && this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL) - { - this.setDead(); - } - - this.despawnEntity(); - - this.noClip = this.ticksProgress % 20 != 0; - - ticksProgress++; - - if (ticksProgress >= getMaxTicksForFormation()) - { - switchToNextFormation(); - } - - float seekRange = this.isChargingAtPlayer() ? 24 : 9; - - EntityPlayer target = this.worldObj.getClosestVulnerablePlayerToEntity(this, seekRange); - //EntityPlayer target = this.worldObj.getClosestPlayerToEntity(this, seekRange); - - if (target != null && this.currentFormation == Formation.ATTACK_PLAYER_START) - { - int targetX = MathHelper.floor_double(target.lastTickPosX); - int targetY = MathHelper.floor_double(target.lastTickPosY); - int targetZ = MathHelper.floor_double(target.lastTickPosZ); - - if (this.isWithinHomeArea(targetX, targetY, targetZ)) - { - this.chargePosX = targetX; - this.chargePosY = targetY; - this.chargePosZ = targetZ; - } - else - { - this.chargePosX = this.getHomePosition().posX; - this.chargePosY = this.getHomePosition().posY; - this.chargePosZ = this.getHomePosition().posZ; - } - } - - Vec3 dest = this.getDestination(); - -// if (this.getNumber() == 0) -// { -// System.out.printf("Knight Phantom %d moving towards %f, %f, %f. Is in formation %s, progress %d.\n", this.getNumber(), dest.xCoord, dest.yCoord, dest.zCoord, this.currentFormation, ticksProgress); -// System.out.printf("Knight Phantom %d at position %f, %f, %f.\n", this.getNumber(), this.posX, this.posY, this.posZ); -// } - - double moveX = dest.xCoord - this.posX; - double moveY = dest.yCoord - this.posY; - double moveZ = dest.zCoord - this.posZ; - - double factor = moveX * moveX + moveY * moveY + moveZ * moveZ; - - factor = (double)MathHelper.sqrt_double(factor); - - double speed = 0.1D;//this.isChargingAtPlayer() ? 0.1D : 0.05D; - - this.motionX += moveX / factor * speed; - this.motionY += moveY / factor * speed; - this.motionZ += moveZ / factor * speed; - - if (target != null) - { - this.faceEntity(target, 10.0F, 500.0F); - - if (target.isEntityAlive()) - { - float f1 = target.getDistanceToEntity(this); - - if (this.canEntityBeSeen(target)) - { - this.attackEntity(target, f1); - } - } - - // launch axe at the appropriate time in our routine - if (isAxeKnight() && this.currentFormation == Formation.ATTACK_PLAYER_ATTACK && (this.ticksProgress % 4) == 0) - { - this.launchAxeAt(target); - } - - // same for picks - if (isPickKnight() && this.currentFormation == Formation.ATTACK_PLAYER_ATTACK && (this.ticksProgress % 4) == 0) - { - this.launchPicks(); - } - - } - - - //this.setPosition(dest.xCoord, dest.yCoord, dest.zCoord); - } - - - /** - * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. - */ - protected void attackEntity(Entity par1Entity, float par2) - { - - if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY) - { - this.attackTime = 20; - this.attackEntityAsMob(par1Entity); - - } - } - - /** - * Copy of EntityMob attack - */ - public boolean attackEntityAsMob(Entity par1Entity) - { - float f = getAttackDamage(); - int i = 0; - - if (par1Entity instanceof EntityLivingBase) - { - f += EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLivingBase)par1Entity); - i += EnchantmentHelper.getKnockbackModifier(this, (EntityLivingBase)par1Entity); - } - - boolean flag = par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), f); - - if (flag) - { - if (i > 0) - { - par1Entity.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F)); - this.motionX *= 0.6D; - this.motionZ *= 0.6D; - } - - int j = EnchantmentHelper.getFireAspectModifier(this); - - if (j > 0) - { - par1Entity.setFire(j * 4); - } - - if (par1Entity instanceof EntityLivingBase) - { - //EnchantmentThorns.func_151367_b(this, (EntityLivingBase)par1Entity, this.rand); - } - } - - return flag; - } - - - /** - * How much damage do we deal, per attack? - * @return - */ - private float getAttackDamage() { - float damage = (float)this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue(); - - if (this.isChargingAtPlayer()) - { - damage += 7; + world.spawnParticle(EnumParticleTypes.ITEM_CRACK, posX + (rand.nextFloat() - 0.5D) * width, posY + rand.nextFloat() * (height - 0.75D) + 0.5D, posZ + (rand.nextFloat() - 0.5D) * width, 0, -0.1, 0, Item.getIdFromItem(particleID)); + world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, posX + (rand.nextFloat() - 0.5D) * width, posY + rand.nextFloat() * (height - 0.75D) + 0.5D, posZ + (rand.nextFloat() - 0.5D) * width, 0, 0.1, 0); + } } - - return damage; - } - - /** - * Fires an axe at the target - * @param targetedEntity - */ - protected void launchAxeAt(Entity targetedEntity) { - float bodyFacingAngle = ((renderYawOffset * 3.141593F) / 180F); - double sx = posX + (MathHelper.cos(bodyFacingAngle) * 1); - double sy = posY + (height * 0.82); - double sz = posZ + (MathHelper.sin(bodyFacingAngle) * 1); - - double tx = targetedEntity.posX - sx; - double ty = (targetedEntity.boundingBox.minY + (double)(targetedEntity.height / 2.0F)) - (posY + height / 2.0F); - double tz = targetedEntity.posZ - sz; - - worldObj.playSoundAtEntity(this, "random.bow", getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 0.4F); - EntityTFThrownAxe projectile = new EntityTFThrownAxe(worldObj, this); - - float speed = 0.75F; - - projectile.setThrowableHeading(tx, ty, tz, speed, 1.0F); - - projectile.setLocationAndAngles(sx, sy, sz, rotationYaw, rotationPitch); - - worldObj.spawnEntityInWorld(projectile); - } - - protected void launchPicks() - { - worldObj.playSoundAtEntity(this, "random.bow", getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 0.4F); - - for (int i = 0; i < 8; i++) - { - float throwAngle = i * 3.14159165F / 4F; - - - double sx = posX + (MathHelper.cos(throwAngle) * 1); - double sy = posY + (height * 0.82); - double sz = posZ + (MathHelper.sin(throwAngle) * 1); - - double vx = MathHelper.cos(throwAngle); - double vy = 0; - double vz = MathHelper.sin(throwAngle); - - - EntityTFThrownPick projectile = new EntityTFThrownPick(worldObj, this); - - - projectile.setLocationAndAngles(sx, sy, sz, i * 45F, rotationPitch); - - float speed = 0.5F; - - projectile.setThrowableHeading(vx, vy, vz, speed, 1.0F); - - worldObj.spawnEntityInWorld(projectile); + } + + @Override + protected void onDeathUpdate() { + super.onDeathUpdate(); + + for (int i = 0; i < 20; ++i) { + double d0 = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + world.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, posX + (double) (rand.nextFloat() * width * 2.0F) - (double) width, posY + (double) (rand.nextFloat() * height), posZ + (double) (rand.nextFloat() * width * 2.0F) - (double) width, d0, d1, d2); } } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return true; - } - - /** - * knocks back this entity - */ - @Override - public void knockBack(Entity par1Entity, float damage, double par3, double par5) - { - this.isAirBorne = true; - float f = MathHelper.sqrt_double(par3 * par3 + par5 * par5); - float distance = 0.2F; - this.motionX /= 2.0D; - this.motionY /= 2.0D; - this.motionZ /= 2.0D; - this.motionX -= par3 / (double)f * (double)distance; - this.motionY += (double)distance; - this.motionZ -= par5 / (double)f * (double)distance; - - if (this.motionY > 0.4000000059604645D) - { - this.motionY = 0.4000000059604645D; - } - } - - /** - * Called each time the current formation ends. - * - * If the current knight is the leader knight, it will pick and broadcast a new formation. - */ - public void switchToNextFormation() { - List nearbyKnights = getNearbyKnights(); - - if (this.currentFormation == Formation.ATTACK_PLAYER_START) - { - this.switchToFormation(Formation.ATTACK_PLAYER_ATTACK); - } - else if (this.currentFormation == Formation.ATTACK_PLAYER_ATTACK) - { - if (nearbyKnights.size() > 1) - { - this.switchToFormation(Formation.WAITING_FOR_LEADER); - } - else - { - // random weapon switch! - switch (rand.nextInt(3)) - { - case 0: - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.knightlySword)); - break; - case 1: - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.knightlyAxe)); - break; - case 2: - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.knightlyPick)); - break; - } - - this.switchToFormation(Formation.ATTACK_PLAYER_START); - } - } - else if (this.currentFormation == Formation.WAITING_FOR_LEADER) - { - //System.out.println("I am done waiting"); - - // try to find a nearby knight and do what they're doing - if (nearbyKnights.size() > 1) - { - this.switchToFormation(nearbyKnights.get(1).currentFormation); - this.ticksProgress = nearbyKnights.get(1).ticksProgress; - } - else - { - this.switchToFormation(Formation.ATTACK_PLAYER_START); - //System.out.println("Can't find nearby knight, charging"); - } - } - else - { - - if (isThisTheLeader(nearbyKnights)) - { - // pick a random formation - pickRandomFormation(); - - // broadcast it - broadcastMyFormation(nearbyKnights); - - // if no one is charging - if (isNobodyCharging(nearbyKnights)) - { - makeARandomKnightCharge(nearbyKnights); - } - } - } - } - - - @SuppressWarnings("unchecked") - private List getNearbyKnights() { - List nearbyKnights = worldObj.getEntitiesWithinAABB(EntityTFKnightPhantom.class, AxisAlignedBB.getBoundingBox(this.posX, this.posY, this.posZ, this.posX + 1, this.posY + 1, this.posZ + 1).expand(32.0D, 8.0D, 32.0D)); - return nearbyKnights; - } - - /** - * Pick a random formation. Called by the leader when his current formation duration ends - */ - protected void pickRandomFormation() { - switch (rand.nextInt(8)) - { - case 0: - currentFormation = Formation.SMALL_CLOCKWISE; - break; - case 1: - currentFormation = Formation.SMALL_ANTICLOCKWISE; - //currentFormation = Formation.LARGE_ANTICLOCKWISE; - break; - case 2: - currentFormation = Formation.SMALL_ANTICLOCKWISE; - break; - case 3: - currentFormation = Formation.CHARGE_PLUSX; - break; - case 4: - currentFormation = Formation.CHARGE_MINUSX; - break; - case 5: - currentFormation = Formation.CHARGE_PLUSZ; - break; - case 6: - currentFormation = Formation.CHARGE_MINUSZ; - break; - case 7: - currentFormation = Formation.SMALL_CLOCKWISE; - //currentFormation = Formation.LARGE_CLOCKWISE; - break; - } - - this.switchToFormation(currentFormation); - } - - /** - * Check within 20ish squares. If this phantom is the lowest numbered one, return true - * @param nearbyKnights - */ - private boolean isThisTheLeader(List nearbyKnights) { - - boolean iAmTheLowest = true; - - //System.out.println("Checking " + nearbyKnights.size() + " knights to see if I'm the leader"); - - - // find more knights - - for (EntityTFKnightPhantom knight : nearbyKnights) - { - if (knight.getNumber() < this.getNumber()) - { - iAmTheLowest = false; - break; // don't bother checking more - } - } - - return iAmTheLowest; - } - - private boolean isNobodyCharging(List nearbyKnights) { - boolean noCharge = true; - for (EntityTFKnightPhantom knight : nearbyKnights) - { - if (knight.isChargingAtPlayer()) - { - noCharge = false; - break; // don't bother checking more - } - } - - return noCharge; - } - - /** - * Tell a random knight from the list to charge - */ - private void makeARandomKnightCharge(List nearbyKnights) { - int randomNum = rand.nextInt(nearbyKnights.size()); - - nearbyKnights.get(randomNum).switchToFormation(Formation.ATTACK_PLAYER_START); - - //System.out.println("Telling knight " + randomNum + " to charge"); - } - - - /** - * Tell all the knights on the list to do something - */ - private void broadcastMyFormation(List nearbyKnights) { - // find more knights - - //System.out.println("Broadcasting to " + nearbyKnights.size() + " knights"); - - for (EntityTFKnightPhantom knight : nearbyKnights) - { - if (!knight.isChargingAtPlayer()) - { - //System.out.println("Telling knight " + knight + " to switch"); - knight.switchToFormation(this.currentFormation); - } - } - - //System.out.println("knight phantom broadcast switch to formation " + this.currentFormation); - } - - public boolean isChargingAtPlayer() - { - return dataWatcher.getWatchableObjectByte(FLAG_CHARGING) != 0; - } - - public void setChargingAtPlayer(boolean flag) - { - if (flag) - { - dataWatcher.updateObject(FLAG_CHARGING, Byte.valueOf((byte)127)); - } - else - { - dataWatcher.updateObject(FLAG_CHARGING, Byte.valueOf((byte)0)); - } - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.wraith.wraith"; - } - - @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.wraith.wraith"; - } - - @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.wraith.wraith"; - } + @Override + public void onDeath(DamageSource cause) { - private void switchToFormationByNumber(int formationNumber) { - - currentFormation = Formation.values()[formationNumber]; - - this.ticksProgress = 0; - } - - public void switchToFormation(Formation formation) - { - //System.out.println("Knight " + this.getNumber() + " now switching to formation " + formation); - - this.currentFormation = formation; - this.ticksProgress = 0; - - this.setChargingAtPlayer(this.currentFormation == Formation.ATTACK_PLAYER_START || this.currentFormation == Formation.ATTACK_PLAYER_ATTACK); - - } - - public int getFormationAsNumber() - { - return this.currentFormation.ordinal(); - } - - - public int getTicksProgress() { - return ticksProgress; - } - - public void setTicksProgress(int ticksProgress) { - this.ticksProgress = ticksProgress; + super.onDeath(cause); + + if (!world.isRemote && getNearbyKnights().isEmpty()) { + + BlockPos treasurePos = hasHome() ? getHomePosition().down() : new BlockPos(this); + + // make treasure for killing the last knight + TFTreasure.stronghold_boss.generateChest(world, treasurePos, false); + + // mark the stronghold as defeated + TFWorld.markStructureConquered(world, treasurePos, TFFeature.KNIGHT_STRONGHOLD); + } } - public int getMaxTicksForFormation() - { - switch (currentFormation) - { - default: - case HOVER: - return 90; - case LARGE_CLOCKWISE: - return 180; - case SMALL_CLOCKWISE: - return 90; - case LARGE_ANTICLOCKWISE: - return 180; - case SMALL_ANTICLOCKWISE: - return 90; - case CHARGE_PLUSX: - return 180; - case CHARGE_MINUSX: - return 180; - case CHARGE_PLUSZ: - return 180; - case CHARGE_MINUSZ: - return 180; - case ATTACK_PLAYER_START: - return 50; - case ATTACK_PLAYER_ATTACK: - return 50; - case WAITING_FOR_LEADER: - return 10; + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + if(this.canBlockDamageSource(source)){ + playSound(SoundEvents.ITEM_SHIELD_BLOCK,1.0F,0.8F + this.world.rand.nextFloat() * 0.4F); } + + return super.attackEntityFrom(source, amount); } - private Vec3 getDestination() { - - if (!this.hasHome()) - { - // hmmm + // [VanillaCopy] Exact copy of EntityMob.attackEntityAsMob + @Override + public boolean attackEntityAsMob(Entity entityIn) { + float f = (float) this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getAttributeValue(); + int i = 0; + + if (entityIn instanceof EntityLivingBase) { + f += EnchantmentHelper.getModifierForCreature(this.getHeldItemMainhand(), ((EntityLivingBase) entityIn).getCreatureAttribute()); + i += EnchantmentHelper.getKnockbackModifier(this); } - switch (currentFormation) - { - case LARGE_CLOCKWISE: - return getCirclePosition(CIRCLE_LARGE_RADIUS, true); - case SMALL_CLOCKWISE: - return getCirclePosition(CIRCLE_SMALL_RADIUS, true); - case LARGE_ANTICLOCKWISE: - return getCirclePosition(CIRCLE_LARGE_RADIUS, false); - case SMALL_ANTICLOCKWISE: - return getCirclePosition(CIRCLE_SMALL_RADIUS, false); - case CHARGE_PLUSX: - return getMoveAcrossPosition(true, true); - case CHARGE_MINUSX: - return getMoveAcrossPosition(false, true); - case CHARGE_PLUSZ: - return getMoveAcrossPosition(true, false); - case ATTACK_PLAYER_START: - case HOVER: - return getHoverPosition(CIRCLE_LARGE_RADIUS); - case CHARGE_MINUSZ: - return getMoveAcrossPosition(false, false); - case WAITING_FOR_LEADER: - return getLoiterPosition(); - case ATTACK_PLAYER_ATTACK: - return getAttackPlayerPosition(); - default: - return getLoiterPosition(); + boolean flag = entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), f); + + if (flag) { + if (i > 0 && entityIn instanceof EntityLivingBase) { + ((EntityLivingBase) entityIn).knockBack(this, (float) i * 0.5F, (double) MathHelper.sin(this.rotationYaw * 0.017453292F), (double) (-MathHelper.cos(this.rotationYaw * 0.017453292F))); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + } + + int j = EnchantmentHelper.getFireAspectModifier(this); + + if (j > 0) { + entityIn.setFire(j * 4); + } + + if (entityIn instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entityIn; + ItemStack itemstack = this.getHeldItemMainhand(); + ItemStack itemstack1 = entityplayer.isHandActive() ? entityplayer.getActiveItemStack() : ItemStack.EMPTY; + + if (!itemstack.isEmpty() && !itemstack1.isEmpty() && itemstack.getItem() instanceof ItemAxe && itemstack1.getItem() == Items.SHIELD) { + float f1 = 0.25F + (float) EnchantmentHelper.getEfficiencyModifier(this) * 0.05F; + + if (this.rand.nextFloat() < f1) { + entityplayer.getCooldownTracker().setCooldown(Items.SHIELD, 100); + this.world.setEntityState(entityplayer, (byte) 30); + } + } + } + + this.applyEnchantments(this, entityIn); } + + return flag; } - private Vec3 getMoveAcrossPosition(boolean plus, boolean alongX) { - - float offset0 = (this.getNumber() * 3F) - 7.5F; - - float offset1; - - if (this.ticksProgress < 60) - { - offset1 = -7F; - } - else - { - offset1 = -7F + (((this.ticksProgress - 60) / 120F) * 14F); + @Override + public boolean canBePushed() { + return true; + } + + @Override + public void knockBack(Entity entity, float damage, double xRatio, double zRatio) { + isAirBorne = true; + float f = MathHelper.sqrt(xRatio * xRatio + zRatio * zRatio); + float distance = 0.2F; + motionX /= 2.0D; + motionY /= 2.0D; + motionZ /= 2.0D; + motionX -= xRatio / (double) f * (double) distance; + motionY += (double) distance; + motionZ -= zRatio / (double) f * (double) distance; + + if (motionY > 0.4000000059604645D) { + motionY = 0.4000000059604645D; } - - if (!plus) - { - offset1 *= -1; + } + + public List getNearbyKnights() { + return world.getEntitiesWithinAABB(EntityTFKnightPhantom.class, new AxisAlignedBB(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).grow(32.0D, 8.0D, 32.0D), EntitySelectors.IS_ALIVE); + } + + private void updateMyNumber() { + List nums = Lists.newArrayList(); + List knights = getNearbyKnights(); + for (EntityTFKnightPhantom knight : knights) { + if (knight == this) + continue; + nums.add(knight.getNumber()); + if (knight.getNumber() == 0) + setHomePosAndDistance(knight.getHomePosition(), 20); } - - - double dx = this.getHomePosition().posX + (alongX ? offset0 : offset1); - double dy = this.getHomePosition().posY + Math.cos(this.ticksProgress / 7F + this.getNumber()); - double dz = this.getHomePosition().posZ + (alongX ? offset1 : offset0); - return Vec3.createVectorHelper(dx, dy, dz); - } - - protected Vec3 getCirclePosition(float distance, boolean clockwise) { - float angle = (this.ticksProgress * 2.0F); - - if (!clockwise) - { - angle *= -1; + if (nums.isEmpty()) + return; + int[] n = Ints.toArray(nums); + Arrays.sort(n); + int smallest = n[0]; + int largest = knights.size() + 1; + int smallestUnused = largest + 1; + if (smallest > 0) { + smallestUnused = 0; + } else { + for (int i = 1; i < largest; i++) { + if (Arrays.binarySearch(n, i) < 0) { + smallestUnused = i; + break; + } + } } - - angle += (60F * this.getNumber()); - - double dx = this.getHomePosition().posX + Math.cos((angle) * Math.PI / 180.0D) * distance; - double dy = this.getHomePosition().posY + Math.cos(this.ticksProgress / 7F + this.getNumber()); - double dz = this.getHomePosition().posZ + Math.sin((angle) * Math.PI / 180.0D) * distance; - return Vec3.createVectorHelper(dx, dy, dz); - } - - private Vec3 getHoverPosition(float distance) { - // bound this by distance so we don't hover in walls if we get knocked into them - - double dx = this.lastTickPosX; - double dy = this.getHomePosition().posY + Math.cos(this.ticksProgress / 7F + this.getNumber()); - double dz = this.lastTickPosZ; - - // let's just bound this by 2D distance - double ox = (this.getHomePosition().posX - dx); - double oz = (this.getHomePosition().posZ - dz); - double dDist = Math.sqrt(ox * ox + oz * oz); - - if (dDist > distance) - { -// System.out.println("Phantom hovering beyond normal bounds"); - - // normalize back to boundaries - - dx = this.getHomePosition().posX + (ox / dDist * distance); - dz = this.getHomePosition().posZ + (oz / dDist * distance); + if (number > smallestUnused || nums.contains(number)) + setNumber(smallestUnused); + } + + public boolean isChargingAtPlayer() { + return dataManager.get(FLAG_CHARGING); + } + + private void setChargingAtPlayer(boolean flag) { + dataManager.set(FLAG_CHARGING, flag); + if (!world.isRemote) { + if (flag) { + if (!getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).hasModifier(CHARGING_MODIFIER)) { + getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).applyModifier(CHARGING_MODIFIER); + } + } else { + getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).removeModifier(CHARGING_MODIFIER); + } } - - return Vec3.createVectorHelper(dx, dy, dz); } - private Vec3 getLoiterPosition() { - double dx = this.getHomePosition().posX; - double dy = this.getHomePosition().posY + Math.cos(this.ticksProgress / 7F + this.getNumber()); - double dz = this.getHomePosition().posZ; - return Vec3.createVectorHelper(dx, dy, dz); + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.WRAITH; } + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.WRAITH; + } - private Vec3 getAttackPlayerPosition() { - if (isSwordKnight()) - { - return Vec3.createVectorHelper(this.chargePosX, this.chargePosY, this.chargePosZ); - } - else - { - return getHoverPosition(CIRCLE_LARGE_RADIUS); - } + @Override + protected SoundEvent getDeathSound() { + return TFSounds.WRAITH; + } + + private void switchToFormationByNumber(int formationNumber) { + currentFormation = Formation.values()[formationNumber]; + ticksProgress = 0; + } + + public void switchToFormation(Formation formation) { + currentFormation = formation; + ticksProgress = 0; + updateMyNumber(); + setChargingAtPlayer(currentFormation == Formation.ATTACK_PLAYER_START || currentFormation == Formation.ATTACK_PLAYER_ATTACK); } + private int getFormationAsNumber() { + return currentFormation.ordinal(); + } + + public int getTicksProgress() { + return ticksProgress; + } + + public void setTicksProgress(int ticksProgress) { + this.ticksProgress = ticksProgress; + } + + public int getMaxTicksForFormation() { + return currentFormation.duration; + } public boolean isSwordKnight() { - return this.getEquipmentInSlot(0) != null && this.getEquipmentInSlot(0).getItem() == TFItems.knightlySword; + return getHeldItemMainhand().getItem() == TFItems.knightmetal_sword; } + public boolean isAxeKnight() { - return this.getEquipmentInSlot(0) != null && this.getEquipmentInSlot(0).getItem() == TFItems.knightlyAxe; + return getHeldItemMainhand().getItem() == TFItems.knightmetal_axe; } + public boolean isPickKnight() { - return this.getEquipmentInSlot(0) != null && this.getEquipmentInSlot(0).getItem() == TFItems.knightlyPick; + return getHeldItemMainhand().getItem() == TFItems.knightmetal_pickaxe; } - public int getNumber() { return number; } public void setNumber(int number) { this.number = number; - + // set weapon per number - switch (number % 3) - { - case 0: - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.knightlySword)); - break; - case 1: - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.knightlyAxe)); - break; - case 2: - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.knightlyPick)); - break; + switch (number % 3) { + case 0: + setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.knightmetal_sword)); + break; + case 1: + setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.knightmetal_axe)); + break; + case 2: + setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.knightmetal_pickaxe)); + break; + } + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + if (hasHome()) { + BlockPos home = getHomePosition(); + compound.setTag("Home", newDoubleNBTList(home.getX(), home.getY(), home.getZ())); + } + compound.setInteger("MyNumber", getNumber()); + compound.setInteger("Formation", getFormationAsNumber()); + compound.setInteger("TicksProgress", getTicksProgress()); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + + if (compound.hasKey("Home", 9)) { + NBTTagList nbttaglist = compound.getTagList("Home", 6); + int hx = (int) nbttaglist.getDoubleAt(0); + int hy = (int) nbttaglist.getDoubleAt(1); + int hz = (int) nbttaglist.getDoubleAt(2); + setHomePosAndDistance(new BlockPos(hx, hy, hz), 20); + } else { + detachHome(); + } + setNumber(compound.getInteger("MyNumber")); + switchToFormationByNumber(compound.getInteger("Formation")); + setTicksProgress(compound.getInteger("TicksProgress")); + } + + public enum Formation { + + HOVER(90), + + LARGE_CLOCKWISE(180), + + SMALL_CLOCKWISE(90), + + LARGE_ANTICLOCKWISE(180), + + SMALL_ANTICLOCKWISE(90), + + CHARGE_PLUSX(180), + + CHARGE_MINUSX(180), + + CHARGE_PLUSZ(180), + + CHARGE_MINUSZ(180), + + WAITING_FOR_LEADER(10), + + ATTACK_PLAYER_START(50), + + ATTACK_PLAYER_ATTACK(50); + + final int duration; + + Formation(int duration) { + this.duration = duration; } } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - super.writeEntityToNBT(nbttagcompound); - ChunkCoordinates home = this.getHomePosition(); - nbttagcompound.setTag("Home", newDoubleNBTList(new double[] { - home.posX, home.posY, home.posZ - })); - nbttagcompound.setBoolean("HasHome", this.hasHome()); - nbttagcompound.setInteger("MyNumber", this.getNumber()); - nbttagcompound.setInteger("Formation", this.getFormationAsNumber()); - nbttagcompound.setInteger("TicksProgress", this.getTicksProgress()); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - - if (nbttagcompound.hasKey("Home", 9)) - { - NBTTagList nbttaglist = nbttagcompound.getTagList("Home", 6); - int hx = (int) nbttaglist.func_150309_d(0); - int hy = (int) nbttaglist.func_150309_d(1); - int hz = (int) nbttaglist.func_150309_d(2); - this.setHomeArea(hx, hy, hz, 20); - } - if (!nbttagcompound.getBoolean("HasHome")) - { - this.detachHome(); - } - this.setNumber(nbttagcompound.getInteger("MyNumber")); - this.switchToFormationByNumber(nbttagcompound.getInteger("Formation")); - this.setTicksProgress(nbttagcompound.getInteger("TicksProgress")); - } - -// public boolean func_110173_bK() -// { -// return this.func_110176_b(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); -// } - - public boolean isWithinHomeArea(int par1, int par2, int par3) - { - return this.maximumHomeDistance == -1.0F ? true : this.homePosition.getDistanceSquared(par1, par2, par3) < this.maximumHomeDistance * this.maximumHomeDistance; - } - - public void setHomeArea(int par1, int par2, int par3, int par4) - { - - this.homePosition.set(par1, par2, par3); - this.maximumHomeDistance = (float)par4; - - } - - public ChunkCoordinates getHomePosition() - { - return this.homePosition; - } - - public float getMaximumHomeDistance() - { - return this.maximumHomeDistance; - } - - public void detachHome() - { - this.maximumHomeDistance = -1.0F; - } - - public boolean hasHome() - { - return this.maximumHomeDistance != -1.0F; - } - - + + @Override + public boolean isNonBoss() { + return false; + } + + // [VanillaCopy] Home fields and methods from EntityCreature, changes noted + private BlockPos homePosition = BlockPos.ORIGIN; + private float maximumHomeDistance = -1.0F; + + public boolean isWithinHomeDistanceCurrentPosition() { + return this.isWithinHomeDistanceFromPosition(new BlockPos(this)); + } + + public boolean isWithinHomeDistanceFromPosition(BlockPos pos) { + return this.maximumHomeDistance == -1.0F ? true : this.homePosition.distanceSq(pos) < (double) (this.maximumHomeDistance * this.maximumHomeDistance); + } + + public void setHomePosAndDistance(BlockPos pos, int distance) { + // set the chargePos here as well so we dont go off flying in some direction when we first spawn + homePosition = chargePos = pos; + this.maximumHomeDistance = (float) distance; + } + + public BlockPos getHomePosition() { + return this.homePosition; + } + + public float getMaximumHomeDistance() { + return this.maximumHomeDistance; + } + + public void detachHome() { + this.maximumHomeDistance = -1.0F; + } + + public boolean hasHome() { + return this.maximumHomeDistance != -1.0F; + } + // End copy } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFLich.java b/src/main/java/twilightforest/entity/boss/EntityTFLich.java index ae4b66581c..8df21b1d74 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFLich.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFLich.java @@ -1,231 +1,178 @@ package twilightforest.entity.boss; -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.EnumCreatureAttribute; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.boss.IBossDisplayData; -import net.minecraft.entity.monster.EntityCreeper; -import net.minecraft.entity.monster.EntityEnderman; -import net.minecraft.entity.monster.EntityMob; -import net.minecraft.entity.monster.EntitySkeleton; -import net.minecraft.entity.monster.EntitySpider; -import net.minecraft.entity.monster.EntityZombie; +import com.google.common.collect.ImmutableSet; +import net.minecraft.entity.*; +import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.monster.*; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.BossInfo; +import net.minecraft.world.BossInfoServer; +import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; import twilightforest.entity.EntityTFSwarmSpider; -import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; - - +import twilightforest.entity.ai.EntityAITFLichMinions; +import twilightforest.entity.ai.EntityAITFLichShadows; +import twilightforest.enums.BossVariant; +import twilightforest.world.TFWorld; +import javax.annotation.Nullable; +import java.util.List; +import java.util.Set; -public class EntityTFLich extends EntityMob implements IBossDisplayData { - +public class EntityTFLich extends EntityMob { - private static final int DATA_ISCLONE = 21; - private static final int DATA_SHIELDSTRENGTH = 17; - private static final int DATA_MINIONSLEFT = 18; - private static final int DATA_BOSSHEALTH = 19; - private static final int DATA_ATTACKTYPE = 20; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/lich"); + private static final Set> POPPABLE = ImmutableSet.of(EntitySkeleton.class, EntityZombie.class, EntityEnderman.class, EntitySpider.class, EntityCreeper.class, EntityTFSwarmSpider.class); - EntityTFLich masterLich; + private static final DataParameter DATA_ISCLONE = EntityDataManager.createKey(EntityTFLich.class, DataSerializers.BOOLEAN); + private static final DataParameter DATA_SHIELDSTRENGTH = EntityDataManager.createKey(EntityTFLich.class, DataSerializers.BYTE); + private static final DataParameter DATA_MINIONSLEFT = EntityDataManager.createKey(EntityTFLich.class, DataSerializers.BYTE); + private static final DataParameter DATA_ATTACKTYPE = EntityDataManager.createKey(EntityTFLich.class, DataSerializers.BYTE); - private static final ItemStack heldItems[] = {new ItemStack(TFItems.scepterTwilight, 1), new ItemStack(TFItems.scepterZombie, 1), new ItemStack(Items.golden_sword, 1)}; public static final int MAX_SHADOW_CLONES = 2; public static final int INITIAL_SHIELD_STRENGTH = 5; public static final int MAX_ACTIVE_MINIONS = 3; public static final int INITIAL_MINIONS_TO_SUMMON = 9; public static final int MAX_HEALTH = 100; - - /** - * Make a new master lich. - */ + private EntityTFLich masterLich; + private int attackCooldown; + private final BossInfoServer bossInfo = new BossInfoServer(getDisplayName(), BossInfo.Color.YELLOW, BossInfo.Overlay.NOTCHED_6); + public EntityTFLich(World world) { super(world); setSize(1.1F, 2.5F); - //texture = TwilightForestMod.MODEL_DIR + "twilightlich64.png"; -// this.yOffset = .25F; - - setShadowClone(false); - this.masterLich = null; - this.isImmuneToFire = true; - setShieldStrength(INITIAL_SHIELD_STRENGTH); - setMinionsToSummon(INITIAL_MINIONS_TO_SUMMON); - - this.experienceValue = 217; + setShadowClone(false); + this.masterLich = null; + this.isImmuneToFire = true; + this.experienceValue = 217; } - - public EntityTFLich(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - /** - * Make a lich shadow clone - */ public EntityTFLich(World world, EntityTFLich otherLich) { this(world); - + setShadowClone(true); this.masterLich = otherLich; } + public EntityTFLich getMasterLich(){ + return masterLich; + } + + public int getAttackCooldown() { + return attackCooldown; + } + + public void setAttackCooldown(int cooldown) { + attackCooldown = cooldown; + } + @Override - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(DATA_ISCLONE, Byte.valueOf((byte)0)); - this.dataWatcher.addObject(DATA_SHIELDSTRENGTH, Byte.valueOf((byte)0)); - this.dataWatcher.addObject(DATA_MINIONSLEFT, Byte.valueOf((byte)0)); - this.dataWatcher.addObject(DATA_BOSSHEALTH, new Integer(EntityTFLich.MAX_HEALTH)); - this.dataWatcher.addObject(DATA_ATTACKTYPE, Byte.valueOf((byte)0)); + public void setCustomNameTag(String name) { + super.setCustomNameTag(name); + this.bossInfo.setName(this.getDisplayName()); } + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAITFLichShadows(this)); + this.tasks.addTask(2, new EntityAITFLichMinions(this)); + this.tasks.addTask(3, new EntityAIAttackMelee(this, 1.0D, true) { + @Override + public boolean shouldExecute() { + return getPhase() == 3 && super.shouldExecute(); + } + + @Override + public void startExecuting() { + super.startExecuting(); + setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); + } + }); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, false)); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(MAX_HEALTH); // max health - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); // attack damage - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.800000011920929D); // movement speed - } - - + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_ISCLONE, false); + dataManager.register(DATA_SHIELDSTRENGTH, (byte) INITIAL_SHIELD_STRENGTH); + dataManager.register(DATA_MINIONSLEFT, (byte) INITIAL_MINIONS_TO_SUMMON); + dataManager.register(DATA_ATTACKTYPE, (byte) 0); + } + @Override - public ItemStack getHeldItem() - { - return heldItems[getPhase() - 1]; - } - + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(MAX_HEALTH); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.45000001788139344D); // Same speed as an angry enderman + } + @Override - protected void dropFewItems(boolean par1, int par2) { - dropScepter(); - - int totalDrops = this.rand.nextInt(3 + par2) + 2; - for (int i = 0; i < totalDrops; ++i) - { - dropGoldThing(); - } - - totalDrops = this.rand.nextInt(4 + par2) + 1; - for (int i = 0; i < totalDrops; ++i) - { - this.dropItem(Items.ender_pearl, 1); - } - - // bones - totalDrops = this.rand.nextInt(5 + par2) + 5; - for (int i = 0; i < totalDrops; ++i) - { - this.dropItem(Items.bone, 1); - } - - // trophy - this.entityDropItem(new ItemStack(TFItems.trophy, 1, 2), 0); + public void addTrackingPlayer(EntityPlayerMP player) { + super.addTrackingPlayer(player); + this.bossInfo.addPlayer(player); } - private void dropScepter() { - int scepterType = rand.nextInt(3); - if (scepterType == 0) { - this.entityDropItem(new ItemStack(TFItems.scepterZombie), 0); - } - else if (scepterType == 1) { - this.entityDropItem(new ItemStack(TFItems.scepterLifeDrain), 0); - } - else { - this.entityDropItem(new ItemStack(TFItems.scepterTwilight), 0); - } + @Override + public void removeTrackingPlayer(EntityPlayerMP player) { + super.removeTrackingPlayer(player); + this.bossInfo.removePlayer(player); } - private void dropGoldThing() { - ItemStack goldThing; - int thingType = rand.nextInt(5); - if (thingType == 0) { - goldThing = new ItemStack(Items.golden_sword); - } - else if (thingType == 1) { - goldThing = new ItemStack(Items.golden_helmet); - } - else if (thingType == 2) { - goldThing = new ItemStack(Items.golden_chestplate); - } - else if (thingType == 3) { - goldThing = new ItemStack(Items.golden_leggings); - } - else { - goldThing = new ItemStack(Items.golden_boots); + @Override + public void setInWeb() { + } + + @Override + protected boolean canDespawn() { + return false; + } + + @Override + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL && !isShadowClone()) { + if (hasHome()) { + world.setBlockState(getHomePosition(), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.LICH)); + } + setDead(); + } else { + super.despawnEntity(); } - // enchant! - EnchantmentHelper.addRandomEnchantment(rand, goldThing, 10 + rand.nextInt(30)); - this.entityDropItem(goldThing, 0); } - /** - * Sets the Entity inside a web block. - * We are immune to webs. - */ - @Override - public void setInWeb() { - // nope! - } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - - /** - * Do not get slowed by lava. - */ - @Override - public boolean handleLavaMovement() - { - return false; - } - - /** - * Do not get slowed by water. - */ - @Override - public boolean isInWater() - { - return false; - } - /** * What phase of the fight are we on? - * + *

* 1 - reflecting bolts, shield up * 2 - summoning minions * 3 - melee @@ -233,855 +180,435 @@ public boolean isInWater() public int getPhase() { if (isShadowClone() || getShieldStrength() > 0) { return 1; - } - else if (getMinionsToSummon() > 0) { + } else if (getMinionsToSummon() > 0) { return 2; - } - else { + } else { return 3; } } - /** - * For now we'll just add some cute particles. - */ - @Override + @Override public void onLivingUpdate() { - // determine the hand position - float angle = ((renderYawOffset * 3.141593F) / 180F); - - double dx = posX + (MathHelper.cos(angle) * 0.65); - double dy = posY + (height * 0.94); - double dz = posZ + (MathHelper.sin(angle) * 0.65); - - - // add particles! - - // how many particles do we want to add?! - int factor = (80 - attackTime) / 10; - int particles = factor > 0 ? rand.nextInt(factor) : 1; - - - for (int j1 = 0; j1 < particles; j1++) - { - float sparkle = 1.0F - (attackTime + 1.0F) / 60.0F; - sparkle *= sparkle; - - float red = 0.37F * sparkle; - float grn = 0.99F * sparkle; - float blu = 0.89F * sparkle; - - // change color for fireball - if (this.getNextAttackType() != 0) - { - red = 0.99F * sparkle; - grn = 0.47F * sparkle; - blu = 0.00F * sparkle; - } - - worldObj.spawnParticle("mobSpell", dx + (rand.nextGaussian() * 0.025), dy + (rand.nextGaussian() * 0.025), dz + (rand.nextGaussian() * 0.025), red, grn, blu); - } - - if (isShadowClone()) { - // clones despawn if they have strayed from the master - checkForMaster(); + // determine the hand position + float angle = ((renderYawOffset * 3.141593F) / 180F); + + double dx = posX + (MathHelper.cos(angle) * 0.65); + double dy = posY + (height * 0.94); + double dz = posZ + (MathHelper.sin(angle) * 0.65); + + + // add particles! + + // how many particles do we want to add?! + int factor = (80 - attackCooldown) / 10; + int particles = factor > 0 ? rand.nextInt(factor) : 1; + + + for (int j1 = 0; j1 < particles; j1++) { + float sparkle = 1.0F - (attackCooldown + 1.0F) / 60.0F; + sparkle *= sparkle; + + float red = 0.37F * sparkle; + float grn = 0.99F * sparkle; + float blu = 0.89F * sparkle; + + // change color for fireball + if (this.getNextAttackType() != 0) { + red = 0.99F * sparkle; + grn = 0.47F * sparkle; + blu = 0.00F * sparkle; + } + + world.spawnParticle(EnumParticleTypes.SPELL_MOB, dx + (rand.nextGaussian() * 0.025), dy + (rand.nextGaussian() * 0.025), dz + (rand.nextGaussian() * 0.025), red, grn, blu); + } + + if (this.getPhase() == 3) + world.spawnParticle(EnumParticleTypes.VILLAGER_ANGRY, + this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.posY + 1.0D + (double) (this.rand.nextFloat() * this.height), + this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, + this.rand.nextGaussian() * 0.02D, this.rand.nextGaussian() * 0.02D, this.rand.nextGaussian() * 0.02D); + + if (!world.isRemote) { + if (this.getPhase() == 1) { + bossInfo.setPercent((float) (getShieldStrength() + 1) / (float) (INITIAL_SHIELD_STRENGTH + 1)); + } else { + bossInfo.setOverlay(BossInfo.Overlay.PROGRESS); + bossInfo.setPercent(getHealth() / getMaxHealth()); + if (this.getPhase() == 2) + bossInfo.setColor(BossInfo.Color.PURPLE); + else + bossInfo.setColor(BossInfo.Color.RED); + } + } + + super.onLivingUpdate(); + } + + @Override + public boolean attackEntityFrom(DamageSource src, float damage) { + // if we're in a wall, teleport for gosh sakes + if ("inWall".equals(src.getDamageType()) && getAttackTarget() != null) { + teleportToSightOfEntity(getAttackTarget()); + } + + if (isShadowClone() && src != DamageSource.OUT_OF_WORLD) { + playSound(SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + return false; } - - // update health - if (!this.worldObj.isRemote) - { - this.dataWatcher.updateObject(DATA_BOSSHEALTH, Integer.valueOf((int)this.getHealth())); - } - - super.onLivingUpdate(); - } - - - /** - * Called when we get attacked. - * - * Never switch targets to any lich. - * - * TODO maybe we could compare masters to make teams or something. - */ - @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float damage) { - // if we're in a wall, teleport for gosh sakes - if (par1DamageSource.getDamageType() == "inWall" && entityToAttack != null) { - teleportToSightOfEntity(entityToAttack); - } - - if (isShadowClone()) { - this.worldObj.playSoundAtEntity(this, "random.fizz", 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); - return false; - } - - Entity prevTarget = this.entityToAttack; - -// System.out.println("Damage source is " + par1DamageSource); -// System.out.println("Damage type is " + par1DamageSource.getDamageType()); -// System.out.println("Damage source source is " + par1DamageSource.getSourceOfDamage()); // ignore all bolts that are not reflected - if (par1DamageSource.getEntity() instanceof EntityTFLich) { + if (src.getTrueSource() instanceof EntityTFLich) { return false; } - + // if our shield is up, ignore any damage that can be blocked. - if (getShieldStrength() > 0) - { - if (par1DamageSource.isUnblockable() && damage > 2) - { + if (src != DamageSource.OUT_OF_WORLD && getShieldStrength() > 0) { + if (src.isMagicDamage() && damage > 2) { // reduce shield for magic damage greater than 1 heart if (getShieldStrength() > 0) { setShieldStrength(getShieldStrength() - 1); - this.worldObj.playSoundAtEntity(this, "random.break", 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + playSound(SoundEvents.ENTITY_ITEM_BREAK, 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); } - } - else - { - this.worldObj.playSoundAtEntity(this, "random.break", 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); - // HACK for creative mode: but get annoyed at what's causing it. - if (par1DamageSource.getEntity() instanceof EntityPlayer) - { - this.entityToAttack = par1DamageSource.getEntity(); + } else { + playSound(SoundEvents.ENTITY_ITEM_BREAK, 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + if (src.getTrueSource() instanceof EntityLivingBase) { + setRevengeTarget((EntityLivingBase) src.getTrueSource()); } } - + return false; } - // never attack another lich? - //TODO: this could better check who is actually attacking against the masterLich variable thing - if (super.attackEntityFrom(par1DamageSource, damage)) - { - if (entityToAttack instanceof EntityTFLich) { - this.entityToAttack = prevTarget; + if (super.attackEntityFrom(src, damage)) { + // Prevent AIHurtByTarget from targeting our own companions + if (getRevengeTarget() instanceof EntityTFLich && ((EntityTFLich) getRevengeTarget()).masterLich == this.masterLich) { + setRevengeTarget(null); } - - // if we were attacked successfully during phase 1 or 2, teleport - // during phase 3, 1 in 4 chance of teleport - if (this.getPhase() < 3 || rand.nextInt(4) == 0) - { - this.teleportToSightOfEntity(this.entityToAttack); + + if (this.getPhase() < 3 || rand.nextInt(4) == 0) { + this.teleportToSightOfEntity(getAttackTarget()); } - + return true; - } - else - { + } else { return false; } } - -// /** -// * Another method to stop the shadow clones from being attacked -// */ -// @Override -// public boolean canAttackWithItem() { -// if (isShadowClone()) { -// return false; -// } -// else { -// return super.canAttackWithItem(); -// } -// } + @Override + protected void updateAITasks() { + super.updateAITasks(); - /** - * Attack! - */ - @Override - protected void attackEntity(Entity targetedEntity, float f) - { - if (!isShadowClone() && attackTime % 15 == 0) { - popNearbyMob(); - } - - if (getPhase() == 1) { - if (attackTime == 60 && !worldObj.isRemote) { - - teleportToSightOfEntity(targetedEntity); - - if (!isShadowClone()) { - // if we are the master, check for clones - checkAndSpawnClones(targetedEntity); - } - } - - if(canEntityBeSeen(targetedEntity) && attackTime == 0 && f < 20F) - { - if (this.getNextAttackType() == 0) - { - // if not, and we can see the target, launch a bolt - launchBoltAt(targetedEntity); - } - else - { - launchBombAt(targetedEntity); - } - - // decide next attack type - if (rand.nextInt(3) > 0) - { - this.setNextAttackType(0); - } - else - { - this.setNextAttackType(1); - } - attackTime = 100; - - } - // do not chase the player - hasAttacked = true; - } - if (getPhase() == 2 && !isShadowClone()) { - despawnClones(); - - // spawn minions every so often - if (attackTime % 15 == 0) { - // spawn minion - checkAndSpawnMinions(targetedEntity); - } - - if (attackTime == 0) { - // if we're in melee, attack - if (f < 2.0F) { - // melee attack - this.attackEntityAsMob(targetedEntity); - attackTime = 20; - } - else if (f < 20F && canEntityBeSeen(targetedEntity)) { - // if not, and we can see the target, launch a bolt - if (this.getNextAttackType() == 0) - { - // if not, and we can see the target, launch a bolt - launchBoltAt(targetedEntity); - } - else - { - launchBombAt(targetedEntity); - } - - // decide next attack type - if (rand.nextInt(2) > 0) - { - this.setNextAttackType(0); - } - else - { - this.setNextAttackType(1); - } - attackTime = 60; - } - else { - // if not, teleport around - teleportToSightOfEntity(targetedEntity); - attackTime = 20; - - } - } - // do not chase - hasAttacked = true; - - } - if (getPhase() == 3) { - // melee! - if (this.attackTime <= 0 && f < 2.0F && targetedEntity.boundingBox.maxY > this.boundingBox.minY && targetedEntity.boundingBox.minY < this.boundingBox.maxY) - { - this.attackTime = 20; - this.attackEntityAsMob(targetedEntity); - hasAttacked = true; - } - } - - - } + if (getAttackTarget() == null) { + return; + } - /** - * Fires a lich bolt at the target - * @param targetedEntity - */ - protected void launchBoltAt(Entity targetedEntity) { + if (attackCooldown > 0) { + attackCooldown--; + } + + // TODO: AI task? + if (!isShadowClone() && attackCooldown % 15 == 0) { + popNearbyMob(); + } + + // always watch our target + // TODO: make into AI task + this.getLookHelper().setLookPositionWithEntity(getAttackTarget(), 100F, 100F); + } + + public void launchBoltAt() { float bodyFacingAngle = ((renderYawOffset * 3.141593F) / 180F); double sx = posX + (MathHelper.cos(bodyFacingAngle) * 0.65); double sy = posY + (height * 0.82); double sz = posZ + (MathHelper.sin(bodyFacingAngle) * 0.65); - - double tx = targetedEntity.posX - sx; - double ty = (targetedEntity.boundingBox.minY + (double)(targetedEntity.height / 2.0F)) - (posY + height / 2.0F); - double tz = targetedEntity.posZ - sz; - - worldObj.playSoundAtEntity(this, "mob.ghast.fireball", getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); - EntityTFLichBolt projectile = new EntityTFLichBolt(worldObj, this); - projectile.setThrowableHeading(tx, ty, tz, projectile.func_70182_d(), 1.0F); - + + double tx = getAttackTarget().posX - sx; + double ty = (getAttackTarget().getEntityBoundingBox().minY + (double) (getAttackTarget().height / 2.0F)) - (posY + height / 2.0F); + double tz = getAttackTarget().posZ - sz; + + playSound(SoundEvents.ENTITY_GHAST_SHOOT, getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); + + EntityTFLichBolt projectile = new EntityTFLichBolt(world, this); projectile.setLocationAndAngles(sx, sy, sz, rotationYaw, rotationPitch); + projectile.shoot(tx, ty, tz, 0.5F, 1.0F); - worldObj.spawnEntityInWorld(projectile); + world.spawnEntity(projectile); } - /** - * Fires a lich bomb at the target - * @param targetedEntity - */ - protected void launchBombAt(Entity targetedEntity) { + public void launchBombAt() { float bodyFacingAngle = ((renderYawOffset * 3.141593F) / 180F); double sx = posX + (MathHelper.cos(bodyFacingAngle) * 0.65); double sy = posY + (height * 0.82); double sz = posZ + (MathHelper.sin(bodyFacingAngle) * 0.65); - - double tx = targetedEntity.posX - sx; - double ty = (targetedEntity.boundingBox.minY + (double)(targetedEntity.height / 2.0F)) - (posY + height / 2.0F); - double tz = targetedEntity.posZ - sz; - - worldObj.playSoundAtEntity(this, "mob.ghast.fireball", getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); - EntityTFLichBomb projectile = new EntityTFLichBomb(worldObj, this); - projectile.setThrowableHeading(tx, ty, tz, projectile.func_40077_c(), 1.0F); - - projectile.setLocationAndAngles(sx, sy, sz, rotationYaw, rotationPitch); - - worldObj.spawnEntityInWorld(projectile); - } - /** - * Check the surrounding area for weaker monsters, and if we find any, magically destroy them. - */ - @SuppressWarnings("unchecked") - protected void popNearbyMob() { - List nearbyMobs = worldObj.getEntitiesWithinAABBExcludingEntity(this, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(32.0D, 16.0D, 32.0D)); + double tx = getAttackTarget().posX - sx; + double ty = (getAttackTarget().getEntityBoundingBox().minY + (double) (getAttackTarget().height / 2.0F)) - (posY + height / 2.0F); + double tz = getAttackTarget().posZ - sz; - for (Entity entity : nearbyMobs) { - if (entity instanceof EntityLiving && canPop(entity) && canEntityBeSeen(entity)) { - EntityLiving mob = (EntityLiving)entity; + playSound(SoundEvents.ENTITY_GHAST_SHOOT, getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); - if (!worldObj.isRemote) { - mob.setDead(); + EntityTFLichBomb projectile = new EntityTFLichBomb(world, this); + projectile.setLocationAndAngles(sx, sy, sz, rotationYaw, rotationPitch); + projectile.shoot(tx, ty, tz, 0.35F, 1.0F); - mob.spawnExplosionParticle(); + world.spawnEntity(projectile); + } - // play death sound -// worldObj.playSoundAtEntity(mob, mob.getDeathSound(), mob.getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); - } + private void popNearbyMob() { + List nearbyMobs = world.getEntitiesWithinAABB(EntityLiving.class, new AxisAlignedBB(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).grow(32.0D, 16.0D, 32.0D), e -> POPPABLE.contains(e.getClass())); + + for (EntityLiving mob : nearbyMobs) { + if (getEntitySenses().canSee(mob)) { + mob.spawnExplosionParticle(); + mob.setDead(); + // play death sound +// world.playSoundAtEntity(mob, mob.getDeathSound(), mob.getSoundVolume(), (rand.nextFloat() - rand.nextFloat()) * 0.2F + 1.0F); // make trail so it's clear that we did it makeRedMagicTrail(mob.posX, mob.posY + mob.height / 2.0, mob.posZ, this.posX, this.posY + this.height / 2.0, this.posZ); - // one per cycle, please break; } } - - } - - /** - * Can we pop the nearby thing? - */ - @SuppressWarnings("rawtypes") - protected boolean canPop(Entity nearby) { - Class[] poppable = {EntitySkeleton.class, EntityZombie.class, EntityEnderman.class, EntitySpider.class, EntityCreeper.class, EntityTFSwarmSpider.class}; - - for (Class pop : poppable) { - if (nearby.getClass() == pop) { - return true; - } - } - return false; + + public boolean wantsNewClone(EntityTFLich clone) { + return clone.isShadowClone() && countMyClones() < EntityTFLich.MAX_SHADOW_CLONES; } - /** - * Look and see if there are enough clones in the surrounding area. If there are not, spawn one. - * @param targetedEntity - */ - protected void checkAndSpawnClones(Entity targetedEntity) { - // if not, spawn one! - if (countMyClones() < EntityTFLich.MAX_SHADOW_CLONES) { - spawnShadowClone(targetedEntity); - } + public void setMaster(EntityTFLich lich) { + masterLich = lich; } - - @SuppressWarnings("unchecked") - protected int countMyClones() { - // check if there are enough clones. we check a 32x16x32 area - List nearbyLiches = worldObj.getEntitiesWithinAABB(EntityTFLich.class, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(32.0D, 16.0D, 32.0D)); + + public int countMyClones() { + // check if there are enough clones. we check a 32x16x32 area int count = 0; - for (EntityTFLich nearbyLich : nearbyLiches) { - if (nearbyLich.isShadowClone() && nearbyLich.masterLich == this) { + for (EntityTFLich nearbyLich : getNearbyLiches()) { + if (nearbyLich.isShadowClone() && nearbyLich.getMasterLich() == this) { count++; } } - + return count; } - - public boolean wantsNewClone(EntityTFLich clone) { - return clone.isShadowClone() && countMyClones() < EntityTFLich.MAX_SHADOW_CLONES; - } + public List getNearbyLiches() { + return world.getEntitiesWithinAABB(getClass(), new AxisAlignedBB(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).grow(32.0D, 16.0D, 32.0D)); + } - protected void spawnShadowClone(Entity targetedEntity) { -// System.out.println("Lich is making a shadow clone!"); - - - // find a good spot - Vec3 cloneSpot = findVecInLOSOf(targetedEntity); - - // put a clone there - EntityTFLich newClone = new EntityTFLich(worldObj, this); - newClone.setPosition(cloneSpot.xCoord, cloneSpot.yCoord, cloneSpot.zCoord); - worldObj.spawnEntityInWorld(newClone); - - newClone.entityToAttack = targetedEntity; - newClone.attackTime = 60 + rand.nextInt(3) - rand.nextInt(3); - - // make sparkles leading to it - makeTeleportTrail(posX, posY, posZ, cloneSpot.xCoord, cloneSpot.yCoord, cloneSpot.zCoord); + public boolean wantsNewMinion(EntityTFLichMinion minion) { + return countMyMinions() < EntityTFLich.MAX_ACTIVE_MINIONS; } - - /** - * Despawn neaby clones - */ - @SuppressWarnings("unchecked") - protected void despawnClones() { - List nearbyLiches = worldObj.getEntitiesWithinAABB(this.getClass(), AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(32.0D, 16.0D, 32.0D)); - - for (EntityTFLich nearbyLich : nearbyLiches) { - if (nearbyLich.isShadowClone()) { - nearbyLich.isDead = true; - } - } + + public int countMyMinions() { + return (int) world.getEntitiesWithinAABB(EntityTFLichMinion.class, new AxisAlignedBB(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).grow(32.0D, 16.0D, 32.0D)) + .stream() + .filter(m -> m.master == this) + .count(); } + public void teleportToSightOfEntity(Entity entity) { + Vec3d dest = findVecInLOSOf(entity); + double srcX = posX; + double srcY = posY; + double srcZ = posZ; + if (dest != null) { + teleportToNoChecks(dest.x, dest.y, dest.z); + this.getLookHelper().setLookPositionWithEntity(entity, 100F, 100F); + this.renderYawOffset = this.rotationYaw; - protected void checkAndSpawnMinions(Entity targetedEntity) { - if (!worldObj.isRemote && this.getMinionsToSummon() > 0) { - int minions = countMyMinions(); - - // if not, spawn one! - if (minions < EntityTFLich.MAX_ACTIVE_MINIONS) { - spawnMinionAt((EntityLivingBase)targetedEntity); - this.setMinionsToSummon(this.getMinionsToSummon() - 1); - } - } - // if there's no minions left to summon, we should move into phase 3 naturally - } - - @SuppressWarnings("unchecked") - protected int countMyMinions() { - // check if there are enough clones. we check a 32x16x32 area - List nearbyMinons = worldObj.getEntitiesWithinAABB(EntityTFLichMinion.class, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(32.0D, 16.0D, 32.0D)); - int count = 0; - - for (EntityTFLichMinion nearbyMinon : nearbyMinons) { - if (nearbyMinon.master == this) { - count++; + if (!this.getEntitySenses().canSee(entity)) { + teleportToNoChecks(srcX, srcY, srcZ); } } - - return count; - } - - protected void spawnMinionAt(EntityLivingBase targetedEntity) { - - // find a good spot - Vec3 minionSpot = findVecInLOSOf(targetedEntity); - - // put a clone there - EntityTFLichMinion minion = new EntityTFLichMinion(worldObj, this); - minion.setPosition(minionSpot.xCoord, minionSpot.yCoord, minionSpot.zCoord); - //minion.initCreature(); - worldObj.spawnEntityInWorld(minion); - - minion.setAttackTarget(targetedEntity); - - minion.spawnExplosionParticle(); - this.worldObj.playSoundAtEntity(minion, "random.pop", 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); - - // make sparkles leading to it - makeBlackMagicTrail(posX, posY + this.getEyeHeight(), posZ, minionSpot.xCoord, minionSpot.yCoord + minion.height / 2.0, minionSpot.zCoord); - } - - public boolean wantsNewMinion(EntityTFLichMinion minion) { - return countMyMinions() < EntityTFLich.MAX_ACTIVE_MINIONS; } /** - * A method on the clones that despawns this clone if we are too far from the master + * Returns coords that would be good to teleport to. + * Returns null if we can't find anything */ - protected void checkForMaster() { - if (masterLich == null) { - findNewMaster(); - } - if (!worldObj.isRemote) { - if (masterLich == null || masterLich.isDead) { - this.isDead = true; - } - else { - //double distance = (this.posX - masterLich.posX) * (this.posX - masterLich.posX) + (this.posY - masterLich.posY) * (this.posY - masterLich.posY) + (this.posZ - masterLich.posZ) * (this.posZ - masterLich.posZ); -// System.out.println("Clone says that distance from master is " + distance); + @Nullable + public Vec3d findVecInLOSOf(Entity targetEntity) { + if (targetEntity == null) return null; + double origX = posX; + double origY = posY; + double origZ = posZ; + + int tries = 100; + for (int i = 0; i < tries; i++) { + // we abuse EntityLivingBase.attemptTeleport, which does all the collision/ground checking for us, then teleport back to our original spot + double tx = targetEntity.posX + rand.nextGaussian() * 16D; + double ty = targetEntity.posY; + double tz = targetEntity.posZ + rand.nextGaussian() * 16D; + + boolean destClear = attemptTeleport(tx, ty, tz); + boolean canSeeTargetAtDest = canEntityBeSeen(targetEntity); // Don't use senses cache because we're in a temporary position + setPositionAndUpdate(origX, origY, origZ); + + if (destClear && canSeeTargetAtDest) { + return new Vec3d(tx, ty, tz); } } + + return null; } /** - * Find a new master for this clone + * Does not check that the teleport destination is valid, we just go there */ - @SuppressWarnings("unchecked") - private void findNewMaster() { - List nearbyLiches = worldObj.getEntitiesWithinAABB(EntityTFLich.class, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(32.0D, 16.0D, 32.0D)); - - for (EntityTFLich nearbyLich : nearbyLiches) { - if (!nearbyLich.isShadowClone() && nearbyLich.wantsNewClone(this)) { - this.masterLich = nearbyLich; - - // animate our new linkage! - makeTeleportTrail(posX, posY, posZ, nearbyLich.posX, nearbyLich.posY, nearbyLich.posZ); - // become angry at our masters target - setAttackTarget(masterLich.getAttackTarget()); - - // quit looking - break; - } - } + private void teleportToNoChecks(double destX, double destY, double destZ) { + // save original position + double srcX = posX; + double srcY = posY; + double srcZ = posZ; + + // change position + setPositionAndUpdate(destX, destY, destZ); + + makeTeleportTrail(srcX, srcY, srcZ, destX, destY, destZ); + this.world.playSound(null, srcX, srcY, srcZ, SoundEvents.ENTITY_ENDERMEN_TELEPORT, this.getSoundCategory(), 1.0F, 1.0F); + this.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0F); + + // sometimes we need to do this + this.isJumping = false; } - - /** - * Teleports to within line of sight of (but not necessarily in view of) the target - */ - protected void teleportToSightOfEntity(Entity entity) - { - Vec3 dest = findVecInLOSOf(entity); - double srcX = posX; - double srcY = posY; - double srcZ = posZ; - - if (dest != null) { - teleportToNoChecks(dest.xCoord, dest.yCoord, dest.zCoord); - faceEntity(entity, 100F, 100F); - this.renderYawOffset = this.rotationYaw; - - if (!this.canEntityBeSeen(entity)) { - // um teleport mishap, return to start -// System.out.println("Teleport fail!!!"); - teleportToNoChecks(srcX, srcY, srcZ); - - } - } - } - - /** - * Returns coords that would be good to teleport to. - * - * Returns null if we can't find anything - */ - protected Vec3 findVecInLOSOf(Entity targetEntity) - { - // for some reason we occasionally get null here - if (targetEntity == null) - { - return null; - } - - double tx = 0, ty = 0, tz = 0; - int tries = 100; - for (int i = 0; i < tries; i++) { - tx = targetEntity.posX + rand.nextGaussian() * 16D; - ty = targetEntity.posY + rand.nextGaussian() * 8D; - tz = targetEntity.posZ + rand.nextGaussian() * 16D; - - // put the y on something solid - boolean groundFlag = false; - // we need to get the integer coordinates for this calculation - int bx = MathHelper.floor_double(tx); - int by = MathHelper.floor_double(ty); - int bz = MathHelper.floor_double(tz); - while (!groundFlag && ty > 0) - { - Block whatsThere = worldObj.getBlock(bx, by - 1, bz); - if (whatsThere == Blocks.air || !whatsThere.getMaterial().isSolid()) - { - ty--; - by--; - } - else - { - groundFlag = true; - } - } - - // did we not find anything at all to stand on? - if (by == 0) { -// System.out.println("teleport find failed to find a block to stand on"); - continue; - } - - // - if (!canEntitySee(targetEntity, tx, ty, tz)) { -// System.out.println("teleport find failed because of lack of LOS"); -// System.out.println("ty = " + ty); - continue; - } - - // check that we're not colliding and not in liquid - float halfWidth = this.width / 2.0F; - AxisAlignedBB destBox = AxisAlignedBB.getBoundingBox(tx - halfWidth, ty - yOffset + ySize, tz - halfWidth, tx + halfWidth, ty - yOffset + ySize + height, tz + halfWidth); - if (worldObj.getCollidingBoundingBoxes(this, destBox).size() > 0) - { -// System.out.println("teleport find failed because of collision"); - continue; - } - - if (worldObj.isAnyLiquid(destBox)) { -// System.out.println("teleport find failed because of liquid at destination"); - continue; - } - - // if we made it this far, we win! - break; - } - - if (tries == 99) { - return null; - } - -// System.out.println("I think we found a good destination at " + tx + ", " + ty + ", " + tz); -// System.out.println("canEntitySee = " + canEntitySee(targetEntity, tx, ty, tz)); - return Vec3.createVectorHelper(tx, ty, tz); - } - - /** - * Can the specified entity see the specified location? - */ - protected boolean canEntitySee(Entity entity, double dx, double dy, double dz) { - return worldObj.rayTraceBlocks(Vec3.createVectorHelper(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ), Vec3.createVectorHelper(dx, dy, dz)) == null; - - } - - /** - * Does not check that the teleport destination is valid, we just go there - */ - protected boolean teleportToNoChecks(double destX, double destY, double destZ) - { - // save original position - double srcX = posX; - double srcY = posY; - double srcZ = posZ; - - // change position - setPosition(destX, destY, destZ); - - makeTeleportTrail(srcX, srcY, srcZ, destX, destY, destZ); - - worldObj.playSoundEffect(srcX, srcY, srcZ, "mob.endermen.portal", 1.0F, 1.0F); - worldObj.playSoundAtEntity(this, "mob.endermen.portal", 1.0F, 1.0F); - - // sometimes we need to do this - this.isJumping = false; - - return true; - } - - /** - * Make a trail of particles from one point to another - */ - protected void makeTeleportTrail(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { + public void makeTeleportTrail(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { // make particle trail - int particles = 128; - for (int i = 0; i < particles; i++) - { - double trailFactor = i / (particles - 1.0D); - float f = (rand.nextFloat() - 0.5F) * 0.2F; - float f1 = (rand.nextFloat() - 0.5F) * 0.2F; - float f2 = (rand.nextFloat() - 0.5F) * 0.2F; - double tx = srcX + (destX - srcX) * trailFactor + (rand.nextDouble() - 0.5D) * width * 2D; - double ty = srcY + (destY - srcY) * trailFactor + rand.nextDouble() * height; - double tz = srcZ + (destZ - srcZ) * trailFactor + (rand.nextDouble() - 0.5D) * width * 2D; - worldObj.spawnParticle("spell", tx, ty, tz, f, f1, f2); - } + int particles = 128; + for (int i = 0; i < particles; i++) { + double trailFactor = i / (particles - 1.0D); + float f = (rand.nextFloat() - 0.5F) * 0.2F; + float f1 = (rand.nextFloat() - 0.5F) * 0.2F; + float f2 = (rand.nextFloat() - 0.5F) * 0.2F; + double tx = srcX + (destX - srcX) * trailFactor + (rand.nextDouble() - 0.5D) * width * 2D; + double ty = srcY + (destY - srcY) * trailFactor + rand.nextDouble() * height; + double tz = srcZ + (destZ - srcZ) * trailFactor + (rand.nextDouble() - 0.5D) * width * 2D; + world.spawnParticle(EnumParticleTypes.SPELL, tx, ty, tz, f, f1, f2); + } } - /** - * Make a trail of particles from one point to another - */ - protected void makeRedMagicTrail(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { - // make particle trail - int particles = 32; - for (int i = 0; i < particles; i++) - { - double trailFactor = i / (particles - 1.0D); - float f = 1.0F; - float f1 = 0.5F; - float f2 = 0.5F; - double tx = srcX + (destX - srcX) * trailFactor + rand.nextGaussian() * 0.005; - double ty = srcY + (destY - srcY) * trailFactor + rand.nextGaussian() * 0.005; - double tz = srcZ + (destZ - srcZ) * trailFactor + rand.nextGaussian() * 0.005; - worldObj.spawnParticle("mobSpell", tx, ty, tz, f, f1, f2); - } + private void makeRedMagicTrail(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { + int particles = 32; + for (int i = 0; i < particles; i++) { + double trailFactor = i / (particles - 1.0D); + float f = 1.0F; + float f1 = 0.5F; + float f2 = 0.5F; + double tx = srcX + (destX - srcX) * trailFactor + rand.nextGaussian() * 0.005; + double ty = srcY + (destY - srcY) * trailFactor + rand.nextGaussian() * 0.005; + double tz = srcZ + (destZ - srcZ) * trailFactor + rand.nextGaussian() * 0.005; + world.spawnParticle(EnumParticleTypes.SPELL_MOB, tx, ty, tz, f, f1, f2); + } } - /** - * Make a trail of particles from one point to another - */ - protected void makeBlackMagicTrail(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { + public void makeBlackMagicTrail(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { // make particle trail - int particles = 32; - for (int i = 0; i < particles; i++) - { - double trailFactor = i / (particles - 1.0D); - float f = 0.2F; - float f1 = 0.2F; - float f2 = 0.2F; - double tx = srcX + (destX - srcX) * trailFactor + rand.nextGaussian() * 0.005; - double ty = srcY + (destY - srcY) * trailFactor + rand.nextGaussian() * 0.005; - double tz = srcZ + (destZ - srcZ) * trailFactor + rand.nextGaussian() * 0.005; - worldObj.spawnParticle("mobSpell", tx, ty, tz, f, f1, f2); - } + int particles = 32; + for (int i = 0; i < particles; i++) { + double trailFactor = i / (particles - 1.0D); + float f = 0.2F; + float f1 = 0.2F; + float f2 = 0.2F; + double tx = srcX + (destX - srcX) * trailFactor + rand.nextGaussian() * 0.005; + double ty = srcY + (destY - srcY) * trailFactor + rand.nextGaussian() * 0.005; + double tz = srcZ + (destZ - srcZ) * trailFactor + rand.nextGaussian() * 0.005; + world.spawnParticle(EnumParticleTypes.SPELL_MOB, tx, ty, tz, f, f1, f2); + } + } + + public boolean isShadowClone() { + return dataManager.get(DATA_ISCLONE); + } + + public void setShadowClone(boolean shadowClone) { + bossInfo.setVisible(!shadowClone); + dataManager.set(DATA_ISCLONE, shadowClone); } - /** - * @return Is this lich a shadow clone or the real one? - */ - public boolean isShadowClone() - { - return (this.dataWatcher.getWatchableObjectByte(DATA_ISCLONE) & 2) != 0; - } - - /** - * sets Is this lich a shadow clone or the real one? - */ - public void setShadowClone(boolean par1) - { - byte var2 = this.dataWatcher.getWatchableObjectByte(DATA_ISCLONE); - - if (par1) - { - this.dataWatcher.updateObject(DATA_ISCLONE, Byte.valueOf((byte)(var2 | 2))); - } - else - { - this.dataWatcher.updateObject(DATA_ISCLONE, Byte.valueOf((byte)(var2 & -3))); - } - } - - public byte getShieldStrength() { - return this.dataWatcher.getWatchableObjectByte(DATA_SHIELDSTRENGTH); + public byte getShieldStrength() { + return dataManager.get(DATA_SHIELDSTRENGTH); } public void setShieldStrength(int shieldStrength) { - this.dataWatcher.updateObject(DATA_SHIELDSTRENGTH, Byte.valueOf((byte) shieldStrength)); + dataManager.set(DATA_SHIELDSTRENGTH, (byte) shieldStrength); } public byte getMinionsToSummon() { - return this.dataWatcher.getWatchableObjectByte(DATA_MINIONSLEFT); + return dataManager.get(DATA_MINIONSLEFT); } public void setMinionsToSummon(int minionsToSummon) { - this.dataWatcher.updateObject(DATA_MINIONSLEFT, Byte.valueOf((byte) minionsToSummon)); + dataManager.set(DATA_MINIONSLEFT, (byte) minionsToSummon); } public byte getNextAttackType() { - return this.dataWatcher.getWatchableObjectByte(DATA_ATTACKTYPE); + return dataManager.get(DATA_ATTACKTYPE); } public void setNextAttackType(int attackType) { - this.dataWatcher.updateObject(DATA_ATTACKTYPE, Byte.valueOf((byte) attackType)); + dataManager.set(DATA_ATTACKTYPE, (byte) attackType); } - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return "mob.blaze.breathe"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return "mob.blaze.hit"; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return "mob.blaze.death"; - } - - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - super.writeEntityToNBT(nbttagcompound); - nbttagcompound.setBoolean("ShadowClone", isShadowClone()); - nbttagcompound.setByte("ShieldStrength", getShieldStrength()); - nbttagcompound.setByte("MinionsToSummon", getMinionsToSummon()); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - setShadowClone(nbttagcompound.getBoolean("ShadowClone")); - setShieldStrength(nbttagcompound.getByte("ShieldStrength")); - setMinionsToSummon(nbttagcompound.getByte("MinionsToSummon")); - } - - - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightKillLich); - + protected SoundEvent getAmbientSound() { + return SoundEvents.ENTITY_BLAZE_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_BLAZE_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_BLAZE_DEATH; + } + + @Override + public ResourceLocation getLootTable() { + return !isShadowClone() ? LOOT_TABLE : null; + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setBoolean("ShadowClone", isShadowClone()); + compound.setByte("ShieldStrength", getShieldStrength()); + compound.setByte("MinionsToSummon", getMinionsToSummon()); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + setShadowClone(compound.getBoolean("ShadowClone")); + setShieldStrength(compound.getByte("ShieldStrength")); + setMinionsToSummon(compound.getByte("MinionsToSummon")); + if (this.hasCustomName()) { + this.bossInfo.setName(this.getDisplayName()); } + } + @Override + public void onDeath(DamageSource cause) { + super.onDeath(cause); // mark the tower as defeated - if (!worldObj.isRemote && !this.isShadowClone()) { - int dx = MathHelper.floor_double(this.posX); - int dy = MathHelper.floor_double(this.posY); - int dz = MathHelper.floor_double(this.posZ); - - if (worldObj.provider instanceof WorldProviderTwilightForest){ - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)worldObj.provider).getChunkProvider(); - TFFeature nearbyFeature = ((TFWorldChunkManager)worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, worldObj); - - if (nearbyFeature == TFFeature.lichTower) { - chunkProvider.setStructureConquered(dx, dy, dz, true); - } - } + if (!world.isRemote && !this.isShadowClone()) { + TFWorld.markStructureConquered(world, new BlockPos(this), TFFeature.LICH_TOWER); } } -// @Override -// public int getBossHealth() { -// return this.dataWatcher.getWatchableObjectInt(EntityTFLich.DATA_BOSSHEALTH); -// } - - - - /** - * Get this Entity's EnumCreatureAttribute - */ - @Override - public EnumCreatureAttribute getCreatureAttribute() - { - return EnumCreatureAttribute.UNDEAD; - } - + @Override + public EnumCreatureAttribute getCreatureAttribute() { + return EnumCreatureAttribute.UNDEAD; + } + + @Override + public boolean isNonBoss() { + return false; + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFLichBolt.java b/src/main/java/twilightforest/entity/boss/EntityTFLichBolt.java index 1880937bdb..b598714942 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFLichBolt.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFLichBolt.java @@ -1,173 +1,108 @@ package twilightforest.entity.boss; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.entity.EntityTFThrowable; +public class EntityTFLichBolt extends EntityTFThrowable { -public class EntityTFLichBolt extends EntityThrowable { - - public EntityLivingBase playerReflects = null; - - public EntityTFLichBolt(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); - } - - public EntityTFLichBolt(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); + @SuppressWarnings("unused") + public EntityTFLichBolt(World world) { + super(world); } - public EntityTFLichBolt(World par1World) { - super(par1World); + public EntityTFLichBolt(World world, EntityLivingBase thrower) { + super(world, thrower); } - - /** - * projectile speed - */ - protected float func_70182_d() - { - return 0.5F; - } - - @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - public void makeTrail() { + private void makeTrail() { for (int i = 0; i < 5; i++) { - double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); - double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); - + double dx = posX + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dy = posY + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double dz = posZ + 0.5 * (rand.nextDouble() - rand.nextDouble()); + double s1 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.17F; double s2 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.80F; double s3 = ((rand.nextFloat() * 0.5F) + 0.5F) * 0.69F; - worldObj.spawnParticle("mobSpell", dx, dy, dz, s1, s2, s3); + world.spawnParticle(EnumParticleTypes.SPELL_MOB, dx, dy, dz, s1, s2, s3); } } - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - @Override - public boolean canBeCollidedWith() - { - return true; - } - - /** - * We need to set this so that the player can attack and reflect the bolt - */ - @Override - public float getCollisionBorderSize() - { - return 1.0F; - } - - - /** - * Reflect! - */ @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { -// System.out.println("Lich bolt being attacked!"); - - setBeenAttacked(); - if (damagesource.getEntity() != null) - { - Vec3 vec3d = damagesource.getEntity().getLookVec(); - if (vec3d != null) - { - this.setThrowableHeading(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord, 1.5F, 0.1F); // reflect faster and more accurately - } - if (damagesource.getEntity() instanceof EntityLivingBase) - { - playerReflects = (EntityLivingBase)damagesource.getEntity(); - } - return true; - } - else - { - return false; - } - } - - /** - * Return who threw this projectile - */ - @Override - public EntityLivingBase getThrower() - { - if (this.playerReflects != null) - { - return this.playerReflects; - } - else - { - return super.getThrower(); - } - } - - /** - * How much this entity falls each tick - */ + public boolean canBeCollidedWith() { + return true; + } + @Override - protected float getGravityVelocity() - { - return 0.001F; - } + public float getCollisionBorderSize() { + return 1.0F; + } @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - boolean passThrough = false; - - // pass through other lich bolts - if (par1MovingObjectPosition.entityHit != null && (par1MovingObjectPosition.entityHit instanceof EntityTFLichBolt || par1MovingObjectPosition.entityHit instanceof EntityTFLichBomb)) { - passThrough = true; + public boolean attackEntityFrom(DamageSource damagesource, float amount) { + super.attackEntityFrom(damagesource, amount); + + if (!this.world.isRemote && damagesource.getTrueSource() != null) { + Vec3d vec3d = damagesource.getTrueSource().getLookVec(); + // reflect faster and more accurately + this.shoot(vec3d.x, vec3d.y, vec3d.z, 1.5F, 0.1F); // reflect faster and more accurately + + if (damagesource.getImmediateSource() instanceof EntityLivingBase) + this.thrower = (EntityLivingBase) damagesource.getImmediateSource(); + + return true; } - - // only damage living things - if (par1MovingObjectPosition.entityHit != null && par1MovingObjectPosition.entityHit instanceof EntityLivingBase) - { - if (par1MovingObjectPosition.entityHit instanceof EntityTFLich) { - EntityTFLich lich = (EntityTFLich)par1MovingObjectPosition.entityHit; - if (lich.isShadowClone()) { - passThrough = true; - } - } - // if we're not set to pass, damage what we hit - if (!passThrough && par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeIndirectMagicDamage(this, this.getThrower()), 6)) - { - ; - } - } - // if we don't pass through, then stop and die - if (!passThrough) { - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(Items.ender_pearl), this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D); - } - - if (!this.worldObj.isRemote) - { - this.setDead(); - } - } + return false; } + @Override + protected float getGravityVelocity() { + return 0.001F; + } + + @SideOnly(Side.CLIENT) + @Override + public void handleStatusUpdate(byte id) { + if (id == 3) { + int itemId = Item.getIdFromItem(Items.ENDER_PEARL); + for (int i = 0; i < 8; ++i) { + this.world.spawnParticle(EnumParticleTypes.ITEM_CRACK, this.posX, this.posY, this.posZ, rand.nextGaussian() * 0.05D, rand.nextDouble() * 0.2D, rand.nextGaussian() * 0.05D, itemId); + } + } else { + super.handleStatusUpdate(id); + } + } + @Override + protected void onImpact(RayTraceResult result) { + if (result.entityHit instanceof EntityTFLichBolt + || result.entityHit instanceof EntityTFLichBomb + || (result.entityHit instanceof EntityTFLich && ((EntityTFLich) result.entityHit).isShadowClone())) { + return; + } + + if (!this.world.isRemote) { + if (result.entityHit instanceof EntityLivingBase) { + result.entityHit.attackEntityFrom(DamageSource.causeIndirectMagicDamage(this, this.getThrower()), 6); + } + this.world.setEntityState(this, (byte) 3); + this.setDead(); + } + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFLichBomb.java b/src/main/java/twilightforest/entity/boss/EntityTFLichBomb.java index dc83eb42a9..85bcb8919e 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFLichBomb.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFLichBomb.java @@ -1,148 +1,91 @@ package twilightforest.entity.boss; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import twilightforest.entity.EntityTFThrowable; +public class EntityTFLichBomb extends EntityTFThrowable { -public class EntityTFLichBomb extends EntityThrowable { - - public EntityTFLichBomb(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); + public EntityTFLichBomb(World world) { + super(world); } - public EntityTFLichBomb(World par1World, EntityLivingBase par2EntityLiving) { - super(par1World, par2EntityLiving); + public EntityTFLichBomb(World world, EntityLivingBase thrower) { + super(world, thrower); } - public EntityTFLichBomb(World par1World) { - super(par1World); - } - - - /** - * projectile speed - */ - protected float func_40077_c() - { - return 0.35F; - } - - @Override public void onUpdate() { super.onUpdate(); - - makeTrail(); + makeTrail(); } - - public void makeTrail() { + private void makeTrail() { for (int i = 0; i < 1; i++) { - double sx = 0.5 * (rand.nextDouble() - rand.nextDouble()) + this.motionX; - double sy = 0.5 * (rand.nextDouble() - rand.nextDouble()) + this.motionY; - double sz = 0.5 * (rand.nextDouble() - rand.nextDouble()) + this.motionZ; - - - double dx = posX + sx; - double dy = posY + sy; - double dz = posZ + sz; - - worldObj.spawnParticle("flame", dx, dy, dz, sx * -0.25, sy * -0.25, sz * -0.25); + double sx = 0.5 * (rand.nextDouble() - rand.nextDouble()) + this.motionX; + double sy = 0.5 * (rand.nextDouble() - rand.nextDouble()) + this.motionY; + double sz = 0.5 * (rand.nextDouble() - rand.nextDouble()) + this.motionZ; + + + double dx = posX + sx; + double dy = posY + sy; + double dz = posZ + sz; + + world.spawnParticle(EnumParticleTypes.FLAME, dx, dy, dz, sx * -0.25, sy * -0.25, sz * -0.25); } } - - /** - * Always be on fire! - */ @Override - public boolean isBurning() - { + public boolean isBurning() { return true; } - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - @Override - public boolean canBeCollidedWith() - { - return true; - } - - /** - * We need to set this so that the player can attack and reflect the bolt - */ - @Override - public float getCollisionBorderSize() - { - return 1.0F; - } - - - /** - * Reflect! - */ @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { -// System.out.println("Lich bolt being attacked!"); - - setBeenAttacked(); - if (damagesource.getEntity() != null) - { - // explode - explode(); - - return true; - } - else - { - return false; - } - } - - protected void explode() { - float explosionPower = 2F; - this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, explosionPower, false, false); - - this.setDead(); + public boolean canBeCollidedWith() { + return true; } - /** - * How much this entity falls each tick - */ @Override - protected float getGravityVelocity() - { - return 0.001F; - } + public float getCollisionBorderSize() { + return 1.0F; + } @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - boolean passThrough = false; - - // pass through other lich bolts - if (par1MovingObjectPosition.entityHit != null && (par1MovingObjectPosition.entityHit instanceof EntityTFLichBolt || par1MovingObjectPosition.entityHit instanceof EntityTFLichBomb)) { - passThrough = true; + public boolean attackEntityFrom(DamageSource source, float amount) { + super.attackEntityFrom(source, amount); + + if (source.getImmediateSource() != null) { + if (!source.isExplosion()) + explode(); + return true; + } else { + return false; } - - // only damage living things - if (par1MovingObjectPosition.entityHit != null && par1MovingObjectPosition.entityHit instanceof EntityTFLich) - { - passThrough = true; + } + + private void explode() { + if (!this.world.isRemote) { + this.world.newExplosion(this, this.posX, this.posY, this.posZ, 2F, false, false); + this.setDead(); } - - // if we're not set to pass, damage what we hit - if (!passThrough) - { - explode(); - } + } + @Override + protected float getGravityVelocity() { + return 0.001F; } + @Override + protected void onImpact(RayTraceResult result) { + if (result.entityHit instanceof EntityTFLichBolt + || result.entityHit instanceof EntityTFLichBomb + || result.entityHit instanceof EntityTFLich) { + return; + } + explode(); + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFLichMinion.java b/src/main/java/twilightforest/entity/boss/EntityTFLichMinion.java index 48a5ecebf4..de5a190faf 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFLichMinion.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFLichMinion.java @@ -1,171 +1,105 @@ package twilightforest.entity.boss; -import java.util.List; - import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.monster.EntityZombie; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; +import net.minecraft.init.MobEffects; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; -import net.minecraft.world.EnumDifficulty; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; - +import java.util.List; public class EntityTFLichMinion extends EntityZombie { - + + private static final DataParameter STRONG = EntityDataManager.createKey(EntityTFLichMinion.class, DataSerializers.BOOLEAN); + EntityTFLich master; - public EntityTFLichMinion(World par1World) { - super(par1World); + public EntityTFLichMinion(World world) { + super(world); this.master = null; } - public EntityTFLichMinion(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - public EntityTFLichMinion(World par1World, EntityTFLich entityTFLich) { - super(par1World); + public EntityTFLichMinion(World world, EntityTFLich entityTFLich) { + super(world); this.master = entityTFLich; } - - /** - * Called when we get attacked. - * - * If we are hit by a lich, still take the damage, but attack stronger and move faster. - */ - @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) { + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(STRONG, false); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { EntityLivingBase prevTarget = getAttackTarget(); - - if (super.attackEntityFrom(par1DamageSource, par2)) { - if (par1DamageSource.getEntity() instanceof EntityTFLich) { - // return to previous target - setAttackTarget(prevTarget); + + if (super.attackEntityFrom(source, amount)) { + if (source.getTrueSource() instanceof EntityTFLich) { + // return to previous target but speed up setRevengeTarget(prevTarget); - // but speed up - addPotionEffect(new PotionEffect(Potion.moveSpeed.id, 200, 4)); - addPotionEffect(new PotionEffect(Potion.damageBoost.id, 200, 1)); + addPotionEffect(new PotionEffect(MobEffects.SPEED, 200, 4)); + addPotionEffect(new PotionEffect(MobEffects.STRENGTH, 200, 1)); } return true; - } - else { + } else { return false; } } - - /** - * Check and see if our master is dead. If so, die - */ - @Override + + @Override public void onLivingUpdate() { - if (master == null) { - findNewMaster(); - } - // if we still don't have a master, or ours is dead, die. - if (master == null || master.isDead) { - this.setHealth(0); - } - super.onLivingUpdate(); - } - - @SuppressWarnings("unchecked") + if (master == null) { + findNewMaster(); + } + // if we still don't have a master, or ours is dead, die. + if (master == null || master.isDead) { + this.setHealth(0); + } + super.onLivingUpdate(); + } + private void findNewMaster() { - List nearbyLiches = worldObj.getEntitiesWithinAABB(EntityTFLich.class, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(32.0D, 16.0D, 32.0D)); - + List nearbyLiches = world.getEntitiesWithinAABB(EntityTFLich.class, new AxisAlignedBB(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).grow(32.0D, 16.0D, 32.0D)); + for (EntityTFLich nearbyLich : nearbyLiches) { if (!nearbyLich.isShadowClone() && nearbyLich.wantsNewMinion(this)) { this.master = nearbyLich; - + // animate our new linkage! master.makeBlackMagicTrail(posX, posY + this.getEyeHeight(), posZ, master.posX, master.posY + master.getEyeHeight(), master.posZ); - + // become angry at our masters target setAttackTarget(master.getAttackTarget()); - + // quit looking break; } } } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); + protected void onNewPotionEffect(PotionEffect effect) { + super.onNewPotionEffect(effect); + if (!world.isRemote && effect.getPotion() == MobEffects.STRENGTH) { + dataManager.set(STRONG, true); } } - - -// /** -// * Initialize this creature. -// */ -// @Override -// public void initCreature() -// { -// this.addRandomArmor(); -// this.func_82162_bC(); -// } - - - @Override - protected void addRandomArmor() - { - float[] equipChances = new float[] {0.0F, 0.25F, 0.75F, 1F}; - - if (this.rand.nextFloat() < equipChances[2]) //this.worldObj.difficultySetting]) - { - int var1 = this.rand.nextInt(2); - float var2 = this.worldObj.difficultySetting == EnumDifficulty.HARD ? 0.1F : 0.25F; - - if (this.rand.nextFloat() < 0.07F) - { - ++var1; - } - - if (this.rand.nextFloat() < 0.07F) - { - ++var1; - } - - if (this.rand.nextFloat() < 0.07F) - { - ++var1; - } - - for (int var3 = 3; var3 >= 0; --var3) - { - ItemStack var4 = this.func_130225_q(var3); - - if (var3 < 3 && this.rand.nextFloat() < var2) - { - break; - } - - if (var4 == null) - { - Item var5 = getArmorItemForSlot(var3 + 1, var1); - - if (var5 != null) - { - this.setCurrentItemOrArmor(var3 + 1, new ItemStack(var5)); - } - } - } - } - } + @Override + protected void onFinishedPotionEffect(PotionEffect effect) { + super.onFinishedPotionEffect(effect); + if (!world.isRemote && effect.getPotion() == MobEffects.STRENGTH) { + dataManager.set(STRONG, false); + } + } + + public boolean isStrong() { + return dataManager.get(STRONG); + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFMinoshroom.java b/src/main/java/twilightforest/entity/boss/EntityTFMinoshroom.java index b4813c1da2..99016b04dc 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFMinoshroom.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFMinoshroom.java @@ -1,76 +1,149 @@ package twilightforest.entity.boss; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.item.Item; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; import twilightforest.entity.EntityTFMinotaur; +import twilightforest.entity.ai.EntityAITFGroundAttack; +import twilightforest.enums.BossVariant; import twilightforest.item.TFItems; +import twilightforest.world.TFWorld; public class EntityTFMinoshroom extends EntityTFMinotaur { - - public EntityTFMinoshroom(World par1World) { - super(par1World); - //this.texture = TwilightForestMod.MODEL_DIR + "minoshroomtaur.png"; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/minoshroom"); + private static final DataParameter GROUND_ATTACK = EntityDataManager.createKey(EntityTFMinoshroom.class, DataSerializers.BOOLEAN); + private static final DataParameter GROUND_CHARGE = EntityDataManager.createKey(EntityTFMinoshroom.class, DataSerializers.VARINT); + private float prevClientSideChargeAnimation; + private float clientSideChargeAnimation; + private boolean groundSmashState = false; + + public EntityTFMinoshroom(World world) { + super(world); this.setSize(1.49F, 2.9F); - - this.experienceValue = 100; - - this.setCurrentItemOrArmor(0, new ItemStack(TFItems.minotaurAxe)); - this.equipmentDropChances[0] = 0.0F; + this.experienceValue = 100; + this.setDropChance(EntityEquipmentSlot.MAINHAND, 1.1F); // > 1 means it is not randomly damaged when dropped + } + + @Override + protected void initEntityAI() { + super.initEntityAI(); + this.tasks.addTask(1, new EntityAITFGroundAttack(this)); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(GROUND_ATTACK, false); + dataManager.register(GROUND_CHARGE, 0); + } + + public boolean isGroundAttackCharge() { + return dataManager.get(GROUND_ATTACK); + } + + public void setGroundAttackCharge(boolean flag) { + dataManager.set(GROUND_ATTACK, flag); } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(120.0D); // max health - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - @Override - protected Item getDropItem() - { - return TFItems.meefStroganoff; - } - - /** - * Drop 0-2 items of this living's type - */ - @Override - protected void dropFewItems(boolean par1, int par2) - { - int numDrops = this.rand.nextInt(4) + 2 + this.rand.nextInt(1 + par2); - - for (int i = 0; i < numDrops; ++i) - { - this.dropItem(TFItems.meefStroganoff, 1); - } - } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - /** - * Drop the equipment for this entity. - */ - protected void dropEquipment(boolean par1, int par2) - { - super.dropEquipment(par1, par2); - this.entityDropItem(new ItemStack(TFItems.minotaurAxe), 0.0F); - - } - - + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(120.0D); + } + + @Override + public void onUpdate() { + super.onUpdate(); + if (this.world.isRemote) { + this.prevClientSideChargeAnimation = this.clientSideChargeAnimation; + if (this.isGroundAttackCharge()) { + this.clientSideChargeAnimation = MathHelper.clamp(this.clientSideChargeAnimation + (1F / ((float) dataManager.get(GROUND_CHARGE)) * 6F), 0.0F, 6.0F); + groundSmashState = true; + } else { + this.clientSideChargeAnimation = MathHelper.clamp(this.clientSideChargeAnimation - 1.0F, 0.0F, 6.0F); + if (groundSmashState) { + IBlockState block = world.getBlockState(getPosition().down()); + int stateId = Block.getStateId(block); + + for (int i = 0; i < 80; i++) { + double cx = getPosition().getX() + world.rand.nextFloat() * 10F - 5F; + double cy = getEntityBoundingBox().minY + 0.1F + world.rand.nextFloat() * 0.3F; + double cz = getPosition().getZ() + world.rand.nextFloat() * 10F - 5F; + + world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, cx, cy, cz, 0D, 0D, 0D, stateId); + } + groundSmashState = false; + } + } + } + } + + @SideOnly(Side.CLIENT) + public float getChargeAnimationScale(float p_189795_1_) { + return (this.prevClientSideChargeAnimation + (this.clientSideChargeAnimation - this.prevClientSideChargeAnimation) * p_189795_1_) / 6.0F; + } + + public void setMaxCharge(int charge) { + dataManager.set(GROUND_CHARGE, charge); + } + + @Override + protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { + super.setEquipmentBasedOnDifficulty(difficulty); + this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(TFItems.minotaur_axe)); + } + + @Override + public void onDeath(DamageSource cause) { + super.onDeath(cause); + if (!world.isRemote) { + TFWorld.markStructureConquered(world, new BlockPos(this), TFFeature.LABYRINTH); + } + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + protected boolean canDespawn() { + return false; + } + + @Override + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL) { + if (hasHome()) { + world.setBlockState(getHomePosition(), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.MINOSHROOM)); + } + setDead(); + } else { + super.despawnEntity(); + } + } + + @Override + public boolean isNonBoss() { + return false; + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFNaga.java b/src/main/java/twilightforest/entity/boss/EntityTFNaga.java index fd278fc451..07652c50c6 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFNaga.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFNaga.java @@ -1,1222 +1,876 @@ package twilightforest.entity.boss; -import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityMultiPart; +import net.minecraft.entity.MultiPartEntityPart; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.boss.EntityDragonPart; -import net.minecraft.entity.boss.IBossDisplayData; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityMoveHelper; +import net.minecraft.entity.ai.RandomPositionGenerator; +import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.monster.EntityMob; -import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.pathfinding.PathEntity; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.nbt.NBTTagIntArray; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.BossInfo; +import net.minecraft.world.BossInfoServer; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.event.ForgeEventFactory; import twilightforest.TFFeature; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFBossSpawner; import twilightforest.block.TFBlocks; -import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; - - -public class EntityTFNaga extends EntityMob -implements IMob, IBossDisplayData, IEntityMultiPart { - - private static int TICKS_BEFORE_HEALING = 600; - - private static int MAX_SEGMENTS = 12; - - int currentSegments = 0; // not including head - - float segmentHealth; - - int LEASH_X = 46; - int LEASH_Y = 7; - int LEASH_Z = 46; - - EntityTFNagaSegment[] body; - - protected PathEntity pathToEntity; - protected Entity targetEntity; - - int circleCount; - int intimidateTimer; - int crumblePlayerTimer; - int chargeCount; - - boolean clockwise; - - public int ticksSinceDamaged = 0; - +import twilightforest.enums.BossVariant; +import twilightforest.network.PacketThrowPlayer; +import twilightforest.network.TFPacketHandler; +import twilightforest.util.EntityUtil; +import twilightforest.world.TFWorld; + +public class EntityTFNaga extends EntityMob implements IEntityMultiPart { + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/naga"); + + private static final int TICKS_BEFORE_HEALING = 600; + private static final int MAX_SEGMENTS = 12; + private static final int LEASH_X = 46; + private static final int LEASH_Y = 7; + private static final int LEASH_Z = 46; + private static final double DEFAULT_SPEED = 0.3; + + private int currentSegmentCount = 0; // not including head + private final float healthPerSegment; + private final EntityTFNagaSegment[] bodySegments = new EntityTFNagaSegment[MAX_SEGMENTS]; + private AIMovementPattern movementAI; + private int ticksSinceDamaged = 0; + + private final BossInfoServer bossInfo = new BossInfoServer(getDisplayName(), BossInfo.Color.GREEN, BossInfo.Overlay.NOTCHED_10); + + private final AttributeModifier slowSpeed = new AttributeModifier("Naga Slow Speed", 0.25F, 0).setSaved(false); + private final AttributeModifier fastSpeed = new AttributeModifier("Naga Fast Speed", 0.50F, 0).setSaved(false); + + private static final DataParameter DATA_DAZE = EntityDataManager.createKey(EntityTFNaga.class, DataSerializers.BOOLEAN); + public EntityTFNaga(World world) { super(world); - - //this.texture = TwilightForestMod.MODEL_DIR + "nagahead.png"; this.setSize(1.75f, 3.0f); - //this.moveSpeed = 0.6f; this.stepHeight = 2; - - this.setHealth(getMaxHealth()); - this.segmentHealth = getMaxHealth() / 10; - setSegmentsPerHealth(); - - this.experienceValue = 217; - + this.healthPerSegment = getMaxHealth() / 10; + this.experienceValue = 217; this.ignoreFrustumCheck = true; - - circleCount = 15; - - // make segments - this.body = new EntityTFNagaSegment[MAX_SEGMENTS]; - for (int i = 0; i < body.length; i++) - { - this.body[i] = new EntityTFNagaSegment(this, i); - world.spawnEntityInWorld(body[i]); + + for (int i = 0; i < bodySegments.length; i++) { + bodySegments[i] = new EntityTFNagaSegment(this, i); } - + this.goNormal(); } - + @Override - protected void entityInit() - { - super.entityInit(); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; - } - - public float getMaxHealthPerDifficulty() { - if (worldObj != null) { - if (worldObj.difficultySetting == EnumDifficulty.EASY) - { + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_DAZE, false); + } + + public boolean isDazed() { + return dataManager.get(DATA_DAZE); + } + + protected void setDazed(boolean daze) { + dataManager.set(DATA_DAZE, daze); + } + + private float getMaxHealthPerDifficulty() { + switch (world.getDifficulty()) { + case EASY: return 120; - } - else if (worldObj.difficultySetting == EnumDifficulty.NORMAL) - { + default: + case NORMAL: return 200; - } - else if (worldObj.difficultySetting == EnumDifficulty.HARD) - { + case HARD: return 250; + } + } + + @Override + public void setCustomNameTag(String name) { + super.setCustomNameTag(name); + this.bossInfo.setName(this.getDisplayName()); + } + + @Override + protected boolean canDespawn() { + return false; + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new AIAttack(this)); + this.tasks.addTask(3, new AISmash(this)); + this.tasks.addTask(4, movementAI = new AIMovementPattern(this)); + this.tasks.addTask(8, new EntityAIWander(this, 1, 1) { + @Override + public void startExecuting() { + EntityTFNaga.this.goNormal(); + super.startExecuting(); } - else + @Override + protected Vec3d getPosition() { - //???? - return 200; + return RandomPositionGenerator.findRandomTarget(this.entity, 30, 7); } + }); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, false)); + + this.moveHelper = new NagaMoveHelper(this); + } + + // Similar to EntityAIAttackMelee but simpler (no pathfinding) + static class AIAttack extends EntityAIBase { + + private final EntityTFNaga taskOwner; + private int attackTick = 20; + + AIAttack(EntityTFNaga taskOwner) { + this.taskOwner = taskOwner; + } + + @Override + public boolean shouldExecute() { + EntityLivingBase target = taskOwner.getAttackTarget(); + + return target != null + && target.getEntityBoundingBox().maxY > taskOwner.getEntityBoundingBox().minY - 2.5 + && target.getEntityBoundingBox().minY < taskOwner.getEntityBoundingBox().maxY + 2.5 + && taskOwner.getDistanceSq(target) <= 4.0D + && taskOwner.getEntitySenses().canSee(target); + } - else { - // why is the world null? - return 200; + + @Override + public void updateTask() { + if (attackTick > 0) { + attackTick--; + } } + @Override + public void resetTask() { + attackTick = 20; + } + + @Override + public void startExecuting() { + taskOwner.attackEntityAsMob(taskOwner.getAttackTarget()); + attackTick = 20; + } } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - protected boolean canDespawn() - { - return false; - } - - /** - * Set monster attributes - */ - @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(getMaxHealthPerDifficulty()); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(2.0D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); // attack damage - } - - - - /** - * Determine how many segments, from 2-12, the naga should have, dependent on its current health - */ - protected int setSegmentsPerHealth() - { - int oldSegments = this.currentSegments; - int newSegments = (int) ((this.getHealth() / segmentHealth) + (getHealth() > 0 ? 2 : 0)); - - // certain types of overkill seem to make this happen by setting health to a negative number - if (newSegments < 0) { - newSegments = 0; + + static class AISmash extends EntityAIBase { + + private final EntityTFNaga taskOwner; + + AISmash(EntityTFNaga taskOwner) { + this.taskOwner = taskOwner; } - - // why is this happening? healing rays? - if (newSegments > MAX_SEGMENTS) - { - newSegments = MAX_SEGMENTS; + + @Override + public boolean shouldExecute() { + return /*taskOwner.getAttackTarget() != null &&*/ taskOwner.collidedHorizontally && ForgeEventFactory.getMobGriefingEvent(taskOwner.world, taskOwner); } - - if (newSegments != oldSegments) { - // detonate unused segments - if (newSegments < oldSegments) { - for (int i = newSegments; i < oldSegments; i++) { - if (body != null && body[i] != null) { - body[i].selfDestruct(); + + @Override + public void startExecuting() { + // NAGA SMASH! + if (taskOwner.world.isRemote) return; + + AxisAlignedBB bb = taskOwner.getEntityBoundingBox(); + + int minx = MathHelper.floor(bb.minX - 0.75D); + int miny = MathHelper.floor(bb.minY + 1.01D); + int minz = MathHelper.floor(bb.minZ - 0.75D); + int maxx = MathHelper.floor(bb.maxX + 0.75D); + int maxy = MathHelper.floor(bb.maxY + 0.0D); + int maxz = MathHelper.floor(bb.maxZ + 0.75D); + + BlockPos min = new BlockPos(minx, miny, minz); + BlockPos max = new BlockPos(maxx, maxy, maxz); + + if (taskOwner.world.isAreaLoaded(min, max)) { + for (BlockPos pos : BlockPos.getAllInBox(min, max)) { + if (EntityUtil.canDestroyBlock(taskOwner.world, pos, taskOwner)) { + taskOwner.world.destroyBlock(pos, true); } } } - else - { - // grow new segments? - this.spawnBodySegments(); + } + } + + enum MovementState { + INTIMIDATE, + CRUMBLE, + CHARGE, + CIRCLE, + DAZE + } + + static class AIMovementPattern extends EntityAIBase { + + private final EntityTFNaga taskOwner; + private MovementState movementState; + private int stateCounter; + private boolean clockwise; + + AIMovementPattern(EntityTFNaga taskOwner) { + this.taskOwner = taskOwner; + setMutexBits(3); + resetTask(); + } + + @Override + public boolean shouldExecute() { + return taskOwner.getAttackTarget() != null; + } + + @Override + public void resetTask() { + movementState = MovementState.CIRCLE; + stateCounter = 15; + clockwise = false; + } + + @Override + public void updateTask() { + if (!taskOwner.getNavigator().noPath()) { + // If we still have an uncompleted path don't run yet + // This isn't in shouldExecute/shouldContinueExecuting because we don't want to reset the task + // todo 1.10 there's a better way to do this I think + taskOwner.setDazed(false); // Since we have a path, we shouldn't be dazed anymore. + return; + } + + switch (movementState) { + case INTIMIDATE: { + taskOwner.getNavigator().clearPath(); + taskOwner.getLookHelper().setLookPositionWithEntity(taskOwner.getAttackTarget(), 30F, 30F); + taskOwner.faceEntity(taskOwner.getAttackTarget(), 30F, 30F); + taskOwner.moveForward = 0.1f; + break; + } + case CRUMBLE: { + taskOwner.getNavigator().clearPath(); + taskOwner.crumbleBelowTarget(2); + taskOwner.crumbleBelowTarget(3); + break; + } + case CHARGE: { + BlockPos tpoint = taskOwner.findCirclePoint(clockwise, 14, Math.PI); + taskOwner.getNavigator().tryMoveToXYZ(tpoint.getX(), tpoint.getY(), tpoint.getZ(), 1); // todo 1.10 check speed + break; + } + case CIRCLE: { + // normal radius is 13 + double radius = stateCounter % 2 == 0 ? 12.0 : 14.0; + double rotation = 1; // in radians + + // hook out slightly before circling + if (stateCounter > 1 && stateCounter < 3) { + radius = 16; + } + + // head almost straight at the player at the end + if (stateCounter == 1) { + rotation = 0.1; + } + + BlockPos tpoint = taskOwner.findCirclePoint(clockwise, radius, rotation); + taskOwner.getNavigator().tryMoveToXYZ(tpoint.getX(), tpoint.getY(), tpoint.getZ(), 1); // todo 1.10 check speed + break; + } + case DAZE: { + taskOwner.setDazed(true); + break; + } + } + + stateCounter--; + if (stateCounter <= 0) { + transitionState(); + } + } + + private void transitionState() { + taskOwner.setDazed(false); + switch (movementState) { + case INTIMIDATE: { + clockwise = !clockwise; + + if (taskOwner.getAttackTarget().getEntityBoundingBox().minY > taskOwner.getEntityBoundingBox().maxY) { + doCrumblePlayer(); + } else { + doCharge(); + } + + break; + } + case CRUMBLE: + doCharge(); + break; + case CHARGE: + doCircle(); + break; + case CIRCLE: + doIntimidate(); + break; + case DAZE: + doCircle(); + break; } } - // change current variables - this.currentSegments = newSegments; - setMovementFactorPerSegments(); + private void doDaze() { + movementState = MovementState.DAZE; + taskOwner.getNavigator().clearPath(); + stateCounter = 60 + taskOwner.rand.nextInt(40); + } + + private void doCircle() { + movementState = MovementState.CIRCLE; + stateCounter += 10 + taskOwner.rand.nextInt(10); + taskOwner.goNormal(); + } + + private void doCrumblePlayer() { + movementState = MovementState.CRUMBLE; + stateCounter = 20 + taskOwner.rand.nextInt(20); + taskOwner.goSlow(); + } + + /** + * Charge the player. Although the count is 3, we actually charge only 2 times. + */ + private void doCharge() { + movementState = MovementState.CHARGE; + stateCounter = 3; + taskOwner.goFast(); + } + + private void doIntimidate() { + movementState = MovementState.INTIMIDATE; + taskOwner.playSound(TFSounds.NAGA_RATTLE, taskOwner.getSoundVolume() * 4F, taskOwner.getSoundPitch()); - return currentSegments; + stateCounter += 15 + taskOwner.rand.nextInt(10); + taskOwner.goSlow(); + } + } + + @Override + public void onLivingUpdate() { + + super.onLivingUpdate(); + + if (world.isRemote || !ForgeEventFactory.getMobGriefingEvent(world, this)) return; + + AxisAlignedBB bb = this.getEntityBoundingBox(); + + int minx = MathHelper.floor(bb.minX - 0.75D); + int miny = MathHelper.floor(bb.minY + 1.01D); + int minz = MathHelper.floor(bb.minZ - 0.75D); + int maxx = MathHelper.floor(bb.maxX + 0.75D); + int maxy = MathHelper.floor(bb.maxY + 0.0D); + int maxz = MathHelper.floor(bb.maxZ + 0.75D); + + BlockPos min = new BlockPos(minx, miny, minz); + BlockPos max = new BlockPos(maxx, maxy, maxz); + + if (world.isAreaLoaded(min, max)) { + for (BlockPos pos : BlockPos.getAllInBox(min, max)) { + IBlockState state = world.getBlockState(pos); + if (state.getMaterial() == Material.LEAVES && EntityUtil.canDestroyBlock(world, pos, state, this)) { + world.destroyBlock(pos, true); + } + } + } } - + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(getMaxHealthPerDifficulty()); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(DEFAULT_SPEED); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(5.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(80.0D); + } + /** - * Sets how fast the naga should be moving, depending on how many segments it has left; + * Determine how many segments, from 2-12, the naga should have, dependent on its current health */ - protected void setMovementFactorPerSegments() { - float movementFactor = 0.6F - (currentSegments / 12f * 0.2f); - - - - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(movementFactor); // movement speed - -// landMovementFactor = 0.6F - (currentSegments / 12f * 0.2f); -// jumpMovementFactor = landMovementFactor / 2F; - -// for (int i = 0; i < currentSegments; i++) { -// if (body != null && body.length > i && body[i] != null) { -// body[i].landMovementFactor = this.landMovementFactor * 1.25F; -// body[i].jumpMovementFactor = this.jumpMovementFactor * 1.25F; -// } -// } + private void setSegmentsPerHealth() { + int oldSegments = this.currentSegmentCount; + int newSegments = MathHelper.clamp((int) ((this.getHealth() / healthPerSegment) + (getHealth() > 0 ? 2 : 0)), 0, MAX_SEGMENTS); + this.currentSegmentCount = newSegments; + if (newSegments < oldSegments) { + for (int i = newSegments; i < oldSegments; i++) { + bodySegments[i].selfDestruct(); + } + } else if (newSegments > oldSegments) { + this.activateBodySegments(); + } + + if (!world.isRemote) { + double newSpeed = DEFAULT_SPEED - newSegments * (-0.2F / 12F); + if (newSpeed < 0) + newSpeed = 0; + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(newSpeed); + } } - /** - * Supress walking sounds - */ - @Override - public boolean canTriggerWalking() - { - return false; - } - - /** - * Do not get slowed by lava. - */ - @Override - public boolean handleLavaMovement() - { - return false; - } - - - - /** - * Die on peaceful - */ - @Override + @Override + public boolean canTriggerWalking() { + return false; + } + + @Override + public boolean isInLava() { + return false; + } + + @Override public void onUpdate() { - despawnIfInvalid(); - if (deathTime > 0) { - for(int k = 0; k < 5; k++) - { - double d = rand.nextGaussian() * 0.02D; - double d1 = rand.nextGaussian() * 0.02D; - double d2 = rand.nextGaussian() * 0.02D; - String explosionType = rand.nextBoolean() ? "hugeexplosion" : "explode"; - - worldObj.spawnParticle(explosionType, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); - } + for (int k = 0; k < 5; k++) { + double d = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + EnumParticleTypes explosionType = rand.nextBoolean() ? EnumParticleTypes.EXPLOSION_HUGE : EnumParticleTypes.EXPLOSION_NORMAL; + + world.spawnParticle(explosionType, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); + } } - + // update health - this.ticksSinceDamaged++; - - if (!this.worldObj.isRemote && this.ticksSinceDamaged > TICKS_BEFORE_HEALING && this.ticksSinceDamaged % 20 == 0) - { - this.heal(1); - } -// -// -// if (!this.worldObj.isRemote) -// { -// this.dataWatcher.updateObject(DATA_BOSSHEALTH, Integer.valueOf((int)this.getHealth())); -// } -// else -// { -//// if (this.getBossHealth() != this.getHealth()) -//// { -//// this.setEntityHealth(this.getBossHealth()); -//// } -// if (this.getHealth() > 0) -// { -// // this seems to get set off during creation at some point -// this.deathTime = 0; -// } -// } - - setSegmentsPerHealth(); - - + this.ticksSinceDamaged++; + + if (!this.world.isRemote && this.ticksSinceDamaged > TICKS_BEFORE_HEALING && this.ticksSinceDamaged % 20 == 0) { + this.heal(1); + } + + setSegmentsPerHealth(); + super.onUpdate(); - -// if (!this.worldObj.isRemote) -// { -// for (int i = 0; i < this.body.length; i++) -// { -// body[i].onUpdate(); -// } -// } - - - // move bodies + + // update bodySegments parts + for (EntityTFNagaSegment segment : bodySegments) { + this.world.updateEntityWithOptionalForce(segment, true); + } + moveSegments(); - - for (int i = 0; i < body.length; i++) - { - if (!body[i].addedToChunk && !worldObj.isRemote) - { - worldObj.spawnEntityInWorld(body[i]); + } + + @Override + protected void updateAITasks() { + super.updateAITasks(); + + if (getAttackTarget() != null && (getDistanceSq(getAttackTarget()) > 80 * 80 || !this.isEntityWithinHomeArea(getAttackTarget()))) { + setAttackTarget(null); + } + + // if we are very close to the path point, go to the next point, unless the path is finished + // TODO 1.10 this runs after the path navigator runs, is that okay? + double d = width * 4.0F; + Vec3d vec3d = hasPath() ? getNavigator().getPath().getPosition(this) : null; + + while (vec3d != null && vec3d.squareDistanceTo(posX, vec3d.y, posZ) < d * d) { + getNavigator().getPath().incrementPathIndex(); + + if (getNavigator().getPath().isFinished()) { + vec3d = null; + } else { + vec3d = getNavigator().getPath().getPosition(this); } } - } - - - /** - * Semi-copied from EntityCreature, but this adds the capability to just path around and not target the player - * - */ - @Override - protected void updateAITasks() - { - super.updateAITasks(); -// super.updateEntityActionState(); - - /* - // Resist fire - if (fire >= 20) { - fire -= 10; - } - */ - - // NAGA SMASH! - if (isCollidedHorizontally && hasTarget()) - { - breakNearbyBlocks(); - } - - // break targeting if our target goes outside the walls - if (targetEntity != null && !this.isEntityWithinHomeArea(targetEntity)) - { - this.targetEntity = null; - } - - // perform target and path maintenance - if (targetEntity == null) - { - targetEntity = findTarget(); - if(targetEntity != null) - { - acquireNewPath(); - } - } - else if (!targetEntity.isEntityAlive()) - { - targetEntity = null; - } - else - { - float targetDistance = targetEntity.getDistanceToEntity(this); - - if (targetDistance > 80) { - targetEntity = null; - } - else { - if(canEntityBeSeen(targetEntity)) - { - attackEntity(targetEntity, targetDistance); - } - else - { - //attackBlockedEntity(entityToAttack, f1); - } - } - } - - if(!hasPath()) - { - acquireNewPath(); - } - - boolean inWater = isInWater(); - boolean inLava = handleLavaMovement(); - - //rotationPitch = 0.0F; - - Vec3 vec3d = hasPath() ? pathToEntity.getPosition(this) : null; - - // if we are very close to the path point, go to the next point, unless the path is finished - for(double d = width * 4.0F; vec3d != null && vec3d.squareDistanceTo(posX, vec3d.yCoord, posZ) < d * d;) - { - pathToEntity.incrementPathIndex(); - if(pathToEntity.isFinished()) - { - vec3d = null; - pathToEntity = null; - } else - { - vec3d = pathToEntity.getPosition(this); - } - } - - isJumping = false; - if(vec3d != null) - { - double d1 = vec3d.xCoord - posX; - double d2 = vec3d.zCoord - posZ; - - double dist = MathHelper.sqrt_double(d1 * d1 + d2 * d2); - - int i = MathHelper.floor_double(boundingBox.minY + 0.5D); - double d3 = vec3d.yCoord - i; - float f2 = (float)((Math.atan2(d2, d1) * 180D) / 3.1415927410125732D) - 90F; - float f3 = f2 - rotationYaw; - moveForward = getMoveSpeed(); - this.setAIMoveSpeed(0.5f); - - //this.moveForward = (float)this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getBaseValue(); - - // slither! - if (dist > 4 && chargeCount == 0) { - moveStrafing = MathHelper.cos(this.ticksExisted * 0.3F) * getMoveSpeed() * 0.6F; - } - - for(; f3 < -180F; f3 += 360F) { } - for(; f3 >= 180F; f3 -= 360F) { } - if(f3 > 30F) - { - f3 = 30F; - } - if(f3 < -30F) - { - f3 = -30F; - } - rotationYaw += f3; - if(d3 > 0.6D) - { - isJumping = true; - } - } - if(intimidateTimer > 0 && hasTarget()) - { - faceEntity(targetEntity, 30F, 30F); - moveForward = 0.1f; - } - if(intimidateTimer > 0 && hasTarget()) - { - faceEntity(targetEntity, 30F, 30F); - moveForward = 0.1f; - } - if(rand.nextFloat() < 0.8F && (inWater || inLava)) - { - isJumping = true; - } - } - - private float getMoveSpeed() { - return 0.5F; + + if (!isWithinHomeDistanceCurrentPosition()) { + setAttackTarget(null); + getNavigator().setPath(getNavigator().getPathToPos(getHomePosition()), 1.0F); + } + + // BOSS BAR! + this.bossInfo.setPercent(this.getHealth() / this.getMaxHealth()); } - /** - * Utility method to set our move speed - */ - private void setMoveSpeed(float f) { - //this.setAIMoveSpeed(0.5f); - this.setAIMoveSpeed(f); + static class NagaMoveHelper extends EntityMoveHelper { + + public NagaMoveHelper(EntityLiving naga) { + super(naga); + } + + @Override + public void onUpdateMoveHelper() { + // TF - slither! + MovementState currentState = ((EntityTFNaga) entity).movementAI.movementState; + if(currentState == MovementState.DAZE) { + this.entity.moveStrafing = 0F; + } else if (currentState != MovementState.CHARGE && currentState != MovementState.INTIMIDATE) { + this.entity.moveStrafing = MathHelper.cos(this.entity.ticksExisted * 0.3F) * 0.6F; + } else { + this.entity.moveStrafing *= 0.8F; + } + + super.onUpdateMoveHelper(); + } } - /** - * Breaks blocks near the naga - */ - protected void breakNearbyBlocks() { - int minx = MathHelper.floor_double(boundingBox.minX - 0.5D); - int miny = MathHelper.floor_double(boundingBox.minY + 1.01D); - int minz = MathHelper.floor_double(boundingBox.minZ - 0.5D); - int maxx = MathHelper.floor_double(boundingBox.maxX + 0.5D); - int maxy = MathHelper.floor_double(boundingBox.maxY + 0.001D); - int maxz = MathHelper.floor_double(boundingBox.maxZ + 0.5D); - if(worldObj.checkChunksExist(minx, miny, minz, maxx, maxy, maxz)) - { - for(int dx = minx; dx <= maxx; dx++) - { - for(int dy = miny; dy <= maxy; dy++) - { - for(int dz = minz; dz <= maxz; dz++) - { - Block i5 = worldObj.getBlock(dx, dy, dz); - if(i5 != Blocks.air) - { - breakBlock(dx, dy, dz); - } - } - - } - - } - - } - } - - - /** - * Returns the sound this mob makes while it's alive. - */ @Override - protected String getLivingSound() - { - return rand.nextInt(3) != 0 ? TwilightForestMod.ID + ":mob.naga.hiss" : TwilightForestMod.ID + ":mob.naga.rattle"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ + protected SoundEvent getAmbientSound() { + return TFSounds.NAGA_HISS; + } + @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.naga.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.NAGA_HURT; + } + @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.naga.hurt"; - } + protected SoundEvent getDeathSound() { + return TFSounds.NAGA_HURT; + } - /** - * Finds a new path. Currently this is designed to circle the target entity - */ - protected void acquireNewPath() { - - // if we don't have a target, do nuffin - if (!hasTarget()) - { - wanderRandomly(); - return; - } - - // if we're supposed to intimidate, don't set a path - if (intimidateTimer > 0) - { - - pathToEntity = null; - intimidateTimer--; - - if (intimidateTimer == 0) - { - clockwise = !clockwise; - - // check to see if we want to charge or crumble blocks around the player - if (targetEntity.boundingBox.minY > boundingBox.maxY) - { - // crumble! - doCrumblePlayer(); - } - else - { - doCharge(); - } - } - - return; - } - - // crumbling is like intimidating, but we just charge after it - if (crumblePlayerTimer > 0) - { - pathToEntity = null; - crumblePlayerTimer--; - - crumbleBelowTarget(2); - crumbleBelowTarget(3); - - if (crumblePlayerTimer == 0) { - doCharge(); - } - } - - // looks like we're charging! - if (chargeCount > 0) - { - chargeCount--; - - Vec3 tpoint = findCirclePoint(targetEntity, 14, Math.PI); - pathToEntity = worldObj.getEntityPathToXYZ(this, MathHelper.floor_double(tpoint.xCoord), MathHelper.floor_double(tpoint.yCoord), MathHelper.floor_double(tpoint.zCoord), 40F, true, true, true, true); - - if (chargeCount == 0) - { - doCircle(); - } - } - - // circle if we're supposed to - if (circleCount > 0) { - - circleCount--; - - // normal radius is 13 - double radius = circleCount % 2 == 0 ? 12.0 : 14.0; - double rotation = 1; // in radians - - // hook out slightly before circling - if (circleCount > 1 && circleCount < 3) { - radius = 16; - } - - // head almost straight at the player at the end - if (circleCount == 1) { - rotation = 0.1; - } - - Vec3 tpoint = findCirclePoint(targetEntity, radius, rotation); - - pathToEntity = worldObj.getEntityPathToXYZ(this, (int)tpoint.xCoord, (int)tpoint.yCoord, (int)tpoint.zCoord, 40F, true, true, true, true); - - if (circleCount == 0) { - doIntimidate(); - } - - - } - - } - - /** - * Crumbles blocks below our current targetEntity. - */ - protected void crumbleBelowTarget(int range) { - int floor = (int) boundingBox.minY; // the block level the naga is standing on. - int targetY = (int) targetEntity.boundingBox.minY; // the block level the target is standing on. - - if (targetY > floor) - { - int dx = (int) targetEntity.posX + rand.nextInt(range) - rand.nextInt(range); - int dz = (int) targetEntity.posZ + rand.nextInt(range) - rand.nextInt(range); + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + private void crumbleBelowTarget(int range) { + if (!ForgeEventFactory.getMobGriefingEvent(world, this)) return; + + int floor = (int) getEntityBoundingBox().minY; + int targetY = (int) getAttackTarget().getEntityBoundingBox().minY; + + if (targetY > floor) { + int dx = (int) getAttackTarget().posX + rand.nextInt(range) - rand.nextInt(range); + int dz = (int) getAttackTarget().posZ + rand.nextInt(range) - rand.nextInt(range); int dy = targetY - rand.nextInt(range) + rand.nextInt(range > 1 ? range - 1 : range); - + if (dy <= floor) { dy = targetY; } -// System.out.println("Crumbling block at " + dx + ", " + dy + ", " + dz); - if (worldObj.getBlock(dx, dy, dz) != Blocks.air) - { - breakBlock(dx, dy, dz); - + BlockPos pos = new BlockPos(dx, dy, dz); + + if (EntityUtil.canDestroyBlock(world, pos, this)) { + // todo limit what can be broken + world.destroyBlock(pos, true); + // sparkle!! - for(int k = 0; k < 20; k++) - { - double d = rand.nextGaussian() * 0.02D; - double d1 = rand.nextGaussian() * 0.02D; - double d2 = rand.nextGaussian() * 0.02D; - - worldObj.spawnParticle("crit", (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); - } + for (int k = 0; k < 20; k++) { + double d = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + + world.spawnParticle(EnumParticleTypes.CRIT, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); + } } } } - - /** - * Breaks a block, no questions asked. - * - * TODO: there should be some limits on what kinds of blocks we can break. - */ - protected void breakBlock(int dx, int dy, int dz) - { - Block whatsThere = worldObj.getBlock(dx, dy, dz); - int whatsMeta = worldObj.getBlockMetadata(dx, dy, dz); - - if (whatsThere != Blocks.air) { - whatsThere.dropBlockAsItem(worldObj, dx, dy, dz, whatsMeta, 0); - this.worldObj.setBlock(dx, dy, dz, Blocks.air, 0, 2); - - worldObj.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(whatsThere) + (whatsMeta << 12)); - } - } /** - * Begin the circle cycle + * Sets the naga to move slowly, such as when he is intimidating the player */ - protected void doCircle() { -// System.out.println("Resuming circle mode"); - circleCount += 10 + rand.nextInt(10); - goNormal(); + private void goSlow() { + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(slowSpeed); // if we apply this twice, we crash, but we can always remove it + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(fastSpeed); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).applyModifier(slowSpeed); } /** - * Crumble blocks around the player. This could use maybe some sort of animation or effect to show it is happening. + * Normal speed, like when he is circling */ - protected void doCrumblePlayer() { -// System.out.println("Crumbling blocks around the player"); - crumblePlayerTimer = 20 + rand.nextInt(20); - goSlow(); + private void goNormal() { + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(slowSpeed); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(fastSpeed); } /** - * Charge the player. Although the count is 4, we actually charge only 3 times. + * Fast, like when he is charging */ - protected void doCharge() { - // charrrrrge! -// System.out.println("Starting to charge!"); - chargeCount = 4; - goFast(); + private void goFast() { + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(slowSpeed); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).removeModifier(fastSpeed); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).applyModifier(fastSpeed); } - - /** - * Intimidate the player. This mostly involves pausing and staring. - */ - protected void doIntimidate() { -// System.out.println("Intimidating!"); - // start the timer - intimidateTimer += 15 + rand.nextInt(10); - goSlow(); - - } - - /** - * Sets the naga to move slowly, such as when he is intimidating the player - */ - protected void goSlow() { - // move slowly -// moveForward = 0f; - moveStrafing = 0; - setMoveSpeed(0.1f); - pathToEntity = null; - } - - /** - * Normal speed, like when he is circling - */ - protected void goNormal() { - setMoveSpeed(0.6F); - } - /** - * Fast, like when he is charging - */ - protected void goFast() { - setMoveSpeed(1.0F); - } - - - /** - * Do not get pushed while we're intimidating. - */ - @Override + @Override public boolean canBePushed() { return false; } /** - * Finds a point that allows us to circle the player clockwise. - */ - protected Vec3 findCirclePoint(Entity toCircle, double radius, double rotation) - { - // compute angle - double vecx = posX - toCircle.posX; - double vecz = posZ - toCircle.posZ; - float rangle = (float)(Math.atan2(vecz, vecx)); - - // add a little, so he circles (clockwise) - rangle += clockwise ? rotation : -rotation; - - // figure out where we're headed from the target angle - double dx = MathHelper.cos(rangle) * radius; - double dz = MathHelper.sin(rangle) * radius; - - double dy = Math.min(boundingBox.minY, toCircle.posY); - - // add that to the target entity's position, and we have our destination - return Vec3.createVectorHelper(toCircle.posX + dx, dy, toCircle.posZ + dz); - } - - public boolean hasTarget() { - return targetEntity != null; - } - - /** - * Copied from EntityMob - */ - protected Entity findTarget() - { - EntityPlayer entityplayer = worldObj.getClosestVulnerablePlayerToEntity(this, 32D); - //EntityPlayer entityplayer = worldObj.getClosestPlayerToEntity(this, 32D); - if (entityplayer != null && canEntityBeSeen(entityplayer) && isEntityWithinHomeArea(entityplayer)) - { - // check range - return entityplayer; - } - else - { - return null; - } - } - - /** - * We take damage from another entity. - */ - @Override - public boolean attackEntityFrom(DamageSource damagesource, float i) - { - // reject damage from outside of our home radius - if (damagesource.getSourceOfDamage() != null) - { - if (!this.isEntityWithinHomeArea(damagesource.getSourceOfDamage())) - { - return false; - } - - } - - if (damagesource.getEntity() != null) - { - if (!this.isEntityWithinHomeArea(damagesource.getEntity())) - { - return false; - } - } - - // normal damage processing - if (super.attackEntityFrom(damagesource, i)) - { - setSegmentsPerHealth(); - - Entity entity = damagesource.getEntity(); - - if(entity != this) - { - targetEntity = entity; - } - - this.ticksSinceDamaged = 0; - - return true; - } - else - { -// System.out.println("Naga rejected damage"); - - return false; - } - } - - /** - * We attempt to attack another entity. Checks y height and attackTime counter - */ - protected void attackEntity(Entity toAttack, float f) - { - if(attackTime <= 0 && f < 4.0F && toAttack.boundingBox.maxY > (boundingBox.minY - 2.5) && toAttack.boundingBox.minY < (boundingBox.maxY + 2.5)) - { - attackTime = 20; - attackEntityAsMob(toAttack); - - if (getMoveSpeed() > 0.8) { - // charging, apply extra pushback - toAttack.addVelocity(-MathHelper.sin((rotationYaw * 3.141593F) / 180F) * 1.0F, 0.10000000000000001D, MathHelper.cos((rotationYaw * 3.141593F) / 180F) * 1.0F); - } - } - } - - /** - * Like it says in the method title, find a random destinaton and set sail. - */ - protected void wanderRandomly() - { - goNormal(); - - boolean flag = false; - int tx = -1; - int ty = -1; - int tz = -1; - float worstweight = -99999F; - for(int l = 0; l < 10; l++) - { - int dx = MathHelper.floor_double((posX + rand.nextInt(21)) - 6D); - int dy = MathHelper.floor_double((posY + rand.nextInt(7)) - 3D); - int dz = MathHelper.floor_double((posZ + rand.nextInt(21)) - 6D); - - // if we are thinking about out of bounds, head back home instead - if (!this.isWithinHomeDistance(dx, dy, dz)) - { -// System.err.println("Naga wants to go out of bounds"); - - dx = this.getHomePosition().posX + rand.nextInt(21) - rand.nextInt(21); - dy = this.getHomePosition().posY + rand.nextInt(7) - rand.nextInt(7); - dz = this.getHomePosition().posZ + rand.nextInt(21) - rand.nextInt(21); - } - - float weight = getBlockPathWeight(dx, dy, dz); - if(weight > worstweight) - { - worstweight = weight; - tx = dx; - ty = dy; - tz = dz; - flag = true; - } - } - - if(flag) - { - pathToEntity = worldObj.getEntityPathToXYZ(this, tx, ty, tz, 80F, true, true, true, true); - } - } - - /** - * Copied from EntityCreature - */ - @Override - public float getBlockPathWeight(int i, int j, int k) - { - // if it's out of bounds, we hate it - if (!this.isWithinHomeDistance(i, j, k)) - { - return Float.MIN_VALUE; + * Finds a point that allows us to circle the target clockwise. + */ + private BlockPos findCirclePoint(boolean clockwise, double radius, double rotation) { + EntityLivingBase toCircle = getAttackTarget(); + + // compute angle + double vecx = posX - toCircle.posX; + double vecz = posZ - toCircle.posZ; + float rangle = (float) (Math.atan2(vecz, vecx)); + + // add a little, so he circles (clockwise) + rangle += clockwise ? rotation : -rotation; + + // figure out where we're headed from the target angle + double dx = MathHelper.cos(rangle) * radius; + double dz = MathHelper.sin(rangle) * radius; + + double dy = Math.min(getEntityBoundingBox().minY, toCircle.posY); + + // add that to the target entity's position, and we have our destination + return new BlockPos(toCircle.posX + dx, dy, toCircle.posZ + dz); + } + + @Override + public boolean isEntityInvulnerable(DamageSource src) { + return src.getTrueSource() != null && !this.isEntityWithinHomeArea(src.getTrueSource()) // reject damage from outside of our home radius + || src.getImmediateSource() != null && !this.isEntityWithinHomeArea(src.getImmediateSource()) + || src.isFireDamage() || src.isExplosion() || super.isEntityInvulnerable(src); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + if (source != DamageSource.FALL && super.attackEntityFrom(source, amount)) { + this.ticksSinceDamaged = 0; + return true; + } else { + return false; } - else - { - return 0.0F; + } + + @Override + public boolean attackEntityAsMob(Entity toAttack) { + if (movementAI.movementState == MovementState.CHARGE && toAttack instanceof EntityLivingBase && ((EntityLivingBase) toAttack).isActiveItemStackBlocking()) { + toAttack.addVelocity(motionX * 1.25D, 0.5D, motionZ * 1.25D); + motionX *= -1.5D; + motionY += 0.5D; + motionZ *= -1.5D; + if (toAttack instanceof EntityPlayerMP) + TFPacketHandler.CHANNEL.sendTo(new PacketThrowPlayer((float) toAttack.motionX, (float) toAttack.motionY, (float) toAttack.motionZ), (EntityPlayerMP) toAttack); + attackEntityFrom(DamageSource.GENERIC, 4F); + world.playSound(null, toAttack.getPosition(), SoundEvents.ITEM_SHIELD_BLOCK, SoundCategory.PLAYERS, 1.0F, 0.8F + this.world.rand.nextFloat() * 0.4F); + movementAI.doDaze(); + return false; } - } - - /** - * Copied from EntityCreature - */ - @Override - public boolean hasPath() - { - return pathToEntity != null; - } - - @Override - protected Item getDropItem() - { - return TFItems.nagaScale; - } - - - - @Override - protected void dropFewItems(boolean flag, int z) { - Item i = getDropItem(); - if(i != null) - { - int j = 6 + rand.nextInt(6); - for(int k = 0; k < j; k++) - { - this.dropItem(i, 1); - } - - } - - // trophy - this.entityDropItem(new ItemStack(TFItems.trophy, 1, 1), 0); - } + boolean result = super.attackEntityAsMob(toAttack); - /** - * Check to make sure all parts exist. If they don't, despawn. - */ - protected void despawnIfInvalid() { - // check to see if we're valid - if(!worldObj.isRemote && worldObj.difficultySetting == EnumDifficulty.PEACEFUL) - { - despawnMe(); - } + if (result) { + // charging, apply extra pushback + toAttack.addVelocity(-MathHelper.sin((rotationYaw * 3.141593F) / 180F) * 2.0F, 0.4F, MathHelper.cos((rotationYaw * 3.141593F) / 180F) * 2.0F); + } + + return result; } - - /** - * Despawn the naga, and restore the boss spawner at our home location, if set - */ - protected void despawnMe() { - if (isLeashed()) - { - ChunkCoordinates home = this.getHomePosition(); - worldObj.setBlock(home.posX, home.posY, home.posZ, TFBlocks.bossSpawner, 0, 2); + + @Override + public float getBlockPathWeight(BlockPos pos) { + if (!this.isWithinHomeDistanceFromPosition(pos)) { + return Float.MIN_VALUE; + } else { + return 0.0F; } - setDead(); } - - /** - * Are there free-roaming nagas out there? Should there be? - */ - public boolean isLeashed() { - return this.getMaximumHomeDistance() > -1; + + @Override + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL) { + if (hasHome()) { + world.setBlockState(getHomePosition(), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.NAGA)); + } + setDead(); + } else { + super.despawnEntity(); + } } - - /** - * The naga does not keep a circular home - */ - //@Override - public boolean isWithinHomeDistance(int x, int y, int z) - { - if (this.getMaximumHomeDistance() == -1) - { - return true; + + @Override + public void setDead() { + super.setDead(); + for (EntityTFNagaSegment seg : bodySegments) { + // must use this instead of setDead + // since multiparts are not added to the world tick list which is what checks isDead + this.world.removeEntityDangerously(seg); } - else - { - int distX = Math.abs(this.getHomePosition().posX - x); - int distY = Math.abs(this.getHomePosition().posY - y); - int distZ = Math.abs(this.getHomePosition().posZ - z); + } + + @Override + public boolean isWithinHomeDistanceFromPosition(BlockPos pos) { + if (this.getMaximumHomeDistance() == -1) { + return true; + } else { + int distX = Math.abs(this.getHomePosition().getX() - pos.getX()); + int distY = Math.abs(this.getHomePosition().getY() - pos.getY()); + int distZ = Math.abs(this.getHomePosition().getZ() - pos.getZ()); return distX <= LEASH_X && distY <= LEASH_Y && distZ <= LEASH_Z; } - } - - /** - * Is the entity within our home area? - */ - public boolean isEntityWithinHomeArea(Entity entity) - { - return isWithinHomeDistance(MathHelper.floor_double(entity.posX), MathHelper.floor_double(entity.posY), MathHelper.floor_double(entity.posZ)); } + private boolean isEntityWithinHomeArea(Entity entity) { + return isWithinHomeDistanceFromPosition(new BlockPos(entity)); + } - /** - * Spawns the body of the naga - */ - protected void spawnBodySegments() - { - if (!worldObj.isRemote) - { - if (body == null) - { - body = new EntityTFNagaSegment[MAX_SEGMENTS]; - } - for (int i = 0; i < currentSegments; i++) - { - if (body[i] == null || body[i].isDead) - { - body[i] = new EntityTFNagaSegment(this, i); - body[i].setLocationAndAngles(posX + 0.1 * i, posY + 0.5D, posZ + 0.1 * i, rand.nextFloat() * 360F, 0.0F); - worldObj.spawnEntityInWorld(body[i]); - } + private void activateBodySegments() { + for (int i = 0; i < currentSegmentCount; i++) { + EntityTFNagaSegment segment = bodySegments[i]; + segment.activate(); + segment.setLocationAndAngles(posX + 0.1 * i, posY + 0.5D, posZ + 0.1 * i, rand.nextFloat() * 360F, 0.0F); + for (int j = 0; j < 20; j++) { + double d0 = this.rand.nextGaussian() * 0.02D; + double d1 = this.rand.nextGaussian() * 0.02D; + double d2 = this.rand.nextGaussian() * 0.02D; + this.world.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, + segment.posX + (double) (this.rand.nextFloat() * segment.width * 2.0F) - (double) segment.width - d0 * 10.0D, + segment.posY + (double) (this.rand.nextFloat() * segment.height) - d1 * 10.0D, + segment.posZ + (double) (this.rand.nextFloat() * segment.width * 2.0F) - (double) segment.width - d2 * 10.0D, + d0, d1, d2); } } } - + /** - * Sets the heading (ha ha) of the body segments + * Sets the heading (ha ha) of the bodySegments segments */ - protected void moveSegments() { - for (int i = 0; i < this.currentSegments; i++) - { - double followX, followY, followZ; - Entity leader; - - if (i == 0) - { - leader = this; - } - else - { - leader = this.body[i - 1]; - } - - followX = leader.posX; - followY = leader.posY; - followZ = leader.posZ; + private void moveSegments() { + for (int i = 0; i < this.bodySegments.length; i++) { + Entity leader = i == 0 ? this : this.bodySegments[i - 1]; + double followX = leader.posX; + double followY = leader.posY; + double followZ = leader.posZ; - // also weight the position so that the segments straighten out a little bit, and the front ones straighten more - float angle = (((leader.rotationYaw + 180) * 3.141593F) / 180F); - - - double straightenForce = 0.05D + (1.0 / (float)(i + 1)) * 0.5D; - - double idealX = -MathHelper.sin(angle) * straightenForce; - double idealZ = MathHelper.cos(angle) * straightenForce; - - - Vec3 diff = Vec3.createVectorHelper(body[i].posX - followX, body[i].posY - followY, body[i].posZ - followZ); + float angle = (((leader.rotationYaw + 180) * 3.141593F) / 180F); + + + double straightenForce = 0.05D + (1.0 / (float) (i + 1)) * 0.5D; + + double idealX = -MathHelper.sin(angle) * straightenForce; + double idealZ = MathHelper.cos(angle) * straightenForce; + + + Vec3d diff = new Vec3d(bodySegments[i].posX - followX, bodySegments[i].posY - followY, bodySegments[i].posZ - followZ); diff = diff.normalize(); // weight so segments drift towards their ideal position - diff = diff.addVector(idealX, 0, idealZ); - diff = diff.normalize(); - -// if (worldObj.isRemote) -// { -// System.out.println("Difference for segment " + i + " is " + diff.xCoord + ", " + diff.yCoord + ", " + diff.zCoord); -// } - + diff = diff.add(idealX, 0, idealZ).normalize(); + double f = 2.0D; - - - double destX = followX + f * diff.xCoord; - double destY = followY + f * diff.yCoord; - double destZ = followZ + f * diff.zCoord; - -// if (body[i].onGround && diff.yCoord > 0) -// { -// destY = body[i].posY; -// } - - - body[i].setPosition(destX, destY, destZ); - - body[i].motionX = f * diff.xCoord; - body[i].motionY = f * diff.yCoord; - body[i].motionZ = f * diff.zCoord; - - double distance = (double)MathHelper.sqrt_double(diff.xCoord * diff.xCoord + diff.zCoord * diff.zCoord); - - if (i == 0) - { - diff.yCoord -= 0.15D; - } - - body[i].setRotation((float) (Math.atan2(diff.zCoord, diff.xCoord) * 180.0D / Math.PI) + 90.0F, -(float)(Math.atan2(diff.yCoord, distance) * 180.0D / Math.PI)); - - - -// if (worldObj.isRemote) -// { -// System.out.println("Client body segment " + i + " to " + body[i].posX + ", " + body[i].posY + ", " + body[i].posZ); -// } -// else -// { -// System.out.println("Server body segment " + i + " to " + body[i].posX + ", " + body[i].posY + ", " + body[i].posZ); -// } - + double destX = followX + f * diff.x; + double destY = followY + f * diff.y; + double destZ = followZ + f * diff.z; + + bodySegments[i].setPosition(destX, destY, destZ); + + double distance = (double) MathHelper.sqrt(diff.x * diff.x + diff.z * diff.z); + + if (i == 0) { + // tilt segment next to head up towards head + diff = diff.add(0, -0.15, 0); + } + + bodySegments[i].setRotation((float) (Math.atan2(diff.z, diff.x) * 180.0D / Math.PI) + 90.0F, -(float) (Math.atan2(diff.y, distance) * 180.0D / Math.PI)); } + } + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + if (hasHome()) { + BlockPos home = this.getHomePosition(); + compound.setTag("Home", new NBTTagIntArray(new int[]{home.getX(), home.getY(), home.getZ()})); + } - + super.writeEntityToNBT(compound); } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - ChunkCoordinates home = this.getHomePosition(); - nbttagcompound.setTag("Home", newDoubleNBTList(new double[] { - home.posX, home.posY, home.posZ - })); - nbttagcompound.setBoolean("HasHome", this.hasHome()); - super.writeEntityToNBT(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - if (nbttagcompound.hasKey("Home", 9)) - { - NBTTagList nbttaglist = nbttagcompound.getTagList("Home", 6); - int hx = (int) nbttaglist.func_150309_d(0); - int hy = (int) nbttaglist.func_150309_d(1); - int hz = (int) nbttaglist.func_150309_d(2); - this.setHomeArea(hx, hy, hz, 20); - } - if (!nbttagcompound.getBoolean("HasHome")) - { - this.detachHome(); - } - - // check health and segments - setSegmentsPerHealth(); - } - - /** - * Trigger achievement when killed - */ + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightKillNaga); + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + + if (compound.hasKey("Home", Constants.NBT.TAG_INT_ARRAY)) { + int[] home = compound.getIntArray("Home"); + this.setHomePosAndDistance(new BlockPos(home[0], home[1], home[2]), 20); + } else { + this.detachHome(); } - + + if (this.hasCustomName()) { + this.bossInfo.setName(this.getDisplayName()); + } + } + + @Override + public void onDeath(DamageSource cause) { + super.onDeath(cause); // mark the courtyard as defeated - if (!worldObj.isRemote && worldObj.provider instanceof WorldProviderTwilightForest) { - int dx = MathHelper.floor_double(this.posX); - int dy = MathHelper.floor_double(this.posY); - int dz = MathHelper.floor_double(this.posZ); - - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)worldObj.provider).getChunkProvider(); - TFFeature nearbyFeature = ((TFWorldChunkManager)worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, worldObj); - - if (nearbyFeature == TFFeature.nagaCourtyard) { - chunkProvider.setStructureConquered(dx, dy, dz, true); - } + if (!world.isRemote) { + TFWorld.markStructureConquered(world, new BlockPos(this), TFFeature.NAGA_COURTYARD); } + } + @Override + public World getWorld() { + return this.world; + } + + @Override + public boolean attackEntityFromPart(MultiPartEntityPart part, DamageSource src, float damage) { + return attackEntityFrom(src, damage); } -// public float getMoveSpeed() { -// return this.moveSpeed; -// } + @Override + public Entity[] getParts() { + return bodySegments; + } -// /** -// * Needed for boss health bar on the client -// */ -// @Override -// public int getBossHealth() { -// return this.dataWatcher.getWatchableObjectInt(EntityTFNaga.DATA_BOSSHEALTH); -// } + @Override + public void addTrackingPlayer(EntityPlayerMP player) { + super.addTrackingPlayer(player); + this.bossInfo.addPlayer(player); + } - @Override - public World func_82194_d() { - return this.worldObj; + public void removeTrackingPlayer(EntityPlayerMP player) { + super.removeTrackingPlayer(player); + this.bossInfo.removePlayer(player); } @Override - public boolean attackEntityFromPart(EntityDragonPart entitydragonpart, DamageSource damagesource, float i) { + public boolean isNonBoss() { return false; } - - - /** - * We need to do this for the bounding boxes on the parts to become active - */ - @Override - public Entity[] getParts() - { - return body; - } - - public float getMaximumHomeDistance() - { - return this.func_110174_bM(); - } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFNagaSegment.java b/src/main/java/twilightforest/entity/boss/EntityTFNagaSegment.java index 17f7d1e046..a653d4acd9 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFNagaSegment.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFNagaSegment.java @@ -1,259 +1,114 @@ package twilightforest.entity.boss; -import java.util.List; - import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.MultiPartEntityPart; import net.minecraft.entity.passive.EntityAnimal; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import java.util.List; -public class EntityTFNagaSegment extends Entity { - - EntityTFNaga naga; - int segment; - - String texture; - - private int deathCounter; +public class EntityTFNagaSegment extends MultiPartEntityPart { - public EntityTFNagaSegment(World par1World) { - super(par1World); - //this.texture = TwilightForestMod.MODEL_DIR + "nagasegment.png"; - setSize(1.8F, 1.8F); - this.stepHeight = 2; - - } + private final EntityTFNaga naga; + private final int segment; + private int deathCounter; public EntityTFNagaSegment(EntityTFNaga myNaga, int segNum) { - this(myNaga.func_82194_d()); + super(myNaga, "segment"+segNum, 0, 0); this.naga = myNaga; this.segment = segNum; + this.stepHeight = 2; + deactivate(); } - /** - * When we're attacked transfer damage to the head. Segments only transfer 2/3 normal damage to the head. - * Segments do not transfer damage from fire, explosions or lava. - */ - @Override - public boolean attackEntityFrom(DamageSource damagesource, float damage) { - // do not transfer (or take) fire, explosion, or lava damage. - if (damagesource.isExplosion() || damagesource.isFireDamage()) { - //hurtTime = 0; -// System.out.println("Prevented damage from fire/explosion/lava. DamageSource == " + damagesource.damageType); - return false; - } - - // do not transfer damage from segments that are disconnected and about to explode - if (naga != null) { - //hurtTime = maxHurtTime = 10; - // System.out.println("transferring damage, world is " + this.worldObj); - - return naga.attackEntityFrom(damagesource, Math.round(damage * 2.0F / 3.0F)); - } - else - { - return false; - } + @Override + public boolean attackEntityFrom(DamageSource src, float damage) { + return super.attackEntityFrom(src, damage * 2F / 3F); } - - /** - * Skip most of the living update things - */ - @Override - public void onUpdate() { - super.onUpdate(); - - // remove if invalid - if (this.naga == null || this.naga.isDead) - { - this.setDead(); - } - - this.ticksExisted++; - - lastTickPosX = posX; - lastTickPosY = posY; - lastTickPosZ = posZ; - - -// System.out.println("Updating " + this + " with angles " + rotationYaw + ", " + rotationPitch); + @Override + public void onUpdate() { + super.onUpdate(); - for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } - for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } - for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } - for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } + ++this.ticksExisted; - - //this.pushOutOfBlocks(posX, posY, posZ); + if (!isInvisible()) + collideWithOthers(); - if (!this.onGround) - { - this.motionY -= 0.08D; - } - else - { - this.motionX *= 0.800000011920929D; -// this.motionY *= 0.800000011920929D; - this.motionZ *= 0.800000011920929D; - } - - this.moveEntity(motionX, motionY, motionZ); - - collideWithOthers(); - -// if (this.segment == 6) -// { -// System.out.println("Updating segment 6"); -// -//// int dx = MathHelper.floor_double(this.posX); -//// int dy = MathHelper.floor_double(this.posY); -//// int dz = MathHelper.floor_double(this.posZ); -//// -//// if (worldObj.isAirBlock(dx, dy, dz)) -//// { -//// worldObj.setBlock(dx, dy, dz, Blocks.torch); -//// } -// -// } - - if (deathCounter > 0) { + if (deathCounter > 0) + { deathCounter--; - - if (deathCounter == 0) { - - for(int k = 0; k < 20; k++) - { - double d = rand.nextGaussian() * 0.02D; - double d1 = rand.nextGaussian() * 0.02D; - double d2 = rand.nextGaussian() * 0.02D; - String explosionType = rand.nextBoolean() ? "largeexplode" : "explode"; - - worldObj.spawnParticle(explosionType, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); - } - - // really explode? -// worldObj.newExplosion(null, posX, posY, posZ, 3.0F, true); + if (deathCounter <= 0) + { + for (int k = 0; k < 20; k++) + { + double d = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + EnumParticleTypes explosionType = rand.nextBoolean() ? EnumParticleTypes.EXPLOSION_LARGE : EnumParticleTypes.EXPLOSION_NORMAL; + + this.world.spawnParticle(explosionType, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); + } + + deactivate(); + } + } + } - setDead(); - worldObj.removeEntity(this); + private void collideWithOthers() { + List list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().grow(0.2D, 0.0D, 0.2D)); + + for (Entity entity : list) { + if (entity.canBePushed()) { + this.collideWithEntity(entity); } } + } - } - - @SuppressWarnings("unchecked") - protected void collideWithOthers() - { - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + private void collideWithEntity(Entity entity) { + entity.applyEntityCollision(this); - for (Entity entity : list) - { - if (entity.canBePushed()) - { - this.collideWithEntity(entity); - } - } - } - - private void collideWithEntity(Entity entity) { - entity.applyEntityCollision(this); - // attack anything that's not us - if ((entity instanceof EntityLivingBase) && !(entity instanceof EntityTFNaga) && !(entity instanceof EntityTFNagaSegment)) - { - naga.attackTime = 10; - int attackStrength = 2; - - // get rid of nearby deer & look impressive - if (entity instanceof EntityAnimal) - { - attackStrength *= 3; - } - + if ((entity instanceof EntityLivingBase) && !(entity instanceof EntityTFNaga) && !(entity instanceof EntityTFNagaSegment)) { + int attackStrength = 2; + + // get rid of nearby deer & look impressive + if (entity instanceof EntityAnimal) { + attackStrength *= 3; + } + entity.attackEntityFrom(DamageSource.causeMobDamage(naga), attackStrength); } - - } - - /** - * Sets the rotation of the entity - */ - public void setRotation(float par1, float par2) - { - this.rotationYaw = MathHelper.wrapAngleTo180_float(par1 % 360.0F); - this.rotationPitch = par2 % 360.0F; - } - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - public boolean canBeCollidedWith() - { - return true; - } - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - protected boolean canDespawn() - { - return false; - } - - public boolean isEntityEqual(Entity entity) - { - return this == entity || this.naga == entity; - } + public void deactivate() { + setSize(0, 0); + setInvisible(true); + } - @Override - protected void entityInit() { } + public void activate() { + setSize(1.8F, 1.8F); + setInvisible(false); + } + // make public @Override - protected void readEntityFromNBT(NBTTagCompound nbttagcompound) { } + public void setRotation(float yaw, float pitch) { + super.setRotation(yaw, pitch); + } @Override - protected void writeEntityToNBT(NBTTagCompound nbttagcompound) { } - - - /** - * Plays step sound at given x, y, z for the entity - */ - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - ; - } - - @SideOnly(Side.CLIENT) + protected void playStepSound(BlockPos pos, Block block) {} - /** - * Returns the texture's file path as a String. - */ - public String getTexture() - { - return this.texture; - } - - /** - * Starts the self destruction process - */ public void selfDestruct() { - this.deathCounter = 30; + this.deathCounter = 10; + } + + @Override + public boolean isNonBoss() { + return false; } - } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFSnowQueen.java b/src/main/java/twilightforest/entity/boss/EntityTFSnowQueen.java index c9379d38b6..b2a3b554cd 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFSnowQueen.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFSnowQueen.java @@ -1,535 +1,389 @@ package twilightforest.entity.boss; -import java.util.List; - -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.IEntityMultiPart; +import net.minecraft.entity.MultiPartEntityPart; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.boss.EntityDragonPart; -import net.minecraft.entity.boss.IBossDisplayData; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.init.SoundEvents; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.BossInfo; +import net.minecraft.world.BossInfoServer; +import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraftforge.event.ForgeEventFactory; import twilightforest.TFFeature; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; +import twilightforest.client.particle.TFParticleType; import twilightforest.entity.IBreathAttacker; import twilightforest.entity.ai.EntityAITFHoverBeam; import twilightforest.entity.ai.EntityAITFHoverSummon; import twilightforest.entity.ai.EntityAITFHoverThenDrop; -import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; +import twilightforest.enums.BossVariant; +import twilightforest.util.WorldUtil; +import twilightforest.world.TFWorld; + +import java.util.List; + +public class EntityTFSnowQueen extends EntityMob implements IEntityMultiPart, IBreathAttacker { -public class EntityTFSnowQueen extends EntityMob implements IBossDisplayData, IEntityMultiPart, IBreathAttacker { - + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/snow_queen"); private static final int MAX_SUMMONS = 6; - private static final int BEAM_FLAG = 21; - private static final int PHASE_FLAG = 22; + private static final DataParameter BEAM_FLAG = EntityDataManager.createKey(EntityTFSnowQueen.class, DataSerializers.BOOLEAN); + private static final DataParameter PHASE_FLAG = EntityDataManager.createKey(EntityTFSnowQueen.class, DataSerializers.BYTE); + private final BossInfoServer bossInfo = new BossInfoServer(getDisplayName(), BossInfo.Color.WHITE, BossInfo.Overlay.PROGRESS); private static final int MAX_DAMAGE_WHILE_BEAMING = 25; private static final float BREATH_DAMAGE = 4.0F; + public enum Phase {SUMMON, DROP, BEAM} - public enum Phase { SUMMON, DROP, BEAM }; + public final Entity[] iceArray = new Entity[7]; - public Entity[] iceArray; - private int summonsRemaining = 0; private int successfulDrops; private int maxDrops; private int damageWhileBeaming; - - public EntityTFSnowQueen(World par1World) { - super(par1World); - - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAITFHoverSummon(this, EntityPlayer.class, 1.0D)); - this.tasks.addTask(2, new EntityAITFHoverThenDrop(this, EntityPlayer.class, 80, 20)); - this.tasks.addTask(3, new EntityAITFHoverBeam(this, EntityPlayer.class, 80, 100)); - this.tasks.addTask(6, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, true)); - this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); - this.setSize(0.7F, 2.2F); - - this.iceArray = new Entity[7]; - for (int i = 0; i < this.iceArray.length; i++) { - this.iceArray[i] = new EntityTFSnowQueenIceShield(this); - } - - this.setCurrentPhase(Phase.SUMMON); - - this.isImmuneToFire = true; - this.experienceValue = 317; - - } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(7.0D); - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(40.0D); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(200.0D); - } - - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(BEAM_FLAG, Byte.valueOf((byte)0)); - this.dataWatcher.addObject(PHASE_FLAG, Byte.valueOf((byte)0)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - protected boolean isAIEnabled() - { - return true; - } - - @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.ice.noise"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.ice.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.ice.death"; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - protected Item getDropItem() - { - return Items.snowball; - } - - /** - * Enchants the entity's armor and held item based on difficulty - */ - protected void enchantEquipment() - { - super.enchantEquipment(); - } - - public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) - { - IEntityLivingData data = super.onSpawnWithEgg(par1EntityLivingData); - - return data; - - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - // make snow particles - for (int i = 0; i < 3; i++) { - float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - float py = this.getEyeHeight() + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; - float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowguardian", this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); - } - - // during drop phase, all the ice blocks should make particles - if (this.getCurrentPhase() == Phase.DROP) { - for (int i = 0; i < this.iceArray.length; i++) { - float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; - float py = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; - float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowwarning", this.iceArray[i].lastTickPosX + px, this.iceArray[i].lastTickPosY + py, this.iceArray[i].lastTickPosZ + pz, 0, 0, 0); - } - } - - // when ice beaming, spew particles - if (isBreathing() && this.isEntityAlive()) - { - Vec3 look = this.getLookVec(); - - double dist = 0.5; - double px = this.posX + look.xCoord * dist; - double py = this.posY + 1.7F + look.yCoord * dist; - double pz = this.posZ + look.zCoord * dist; - - for (int i = 0; i < 10; i++) - { - double dx = look.xCoord; - double dy = 0;//look.yCoord; - double dz = look.zCoord; - - double spread = 2 + this.getRNG().nextDouble() * 2.5; - double velocity = 2.0 + this.getRNG().nextDouble() * 0.15; - - // beeeam - dx += this.getRNG().nextGaussian() * 0.0075D * spread; - dy += this.getRNG().nextGaussian() * 0.0075D * spread; - dz += this.getRNG().nextGaussian() * 0.0075D * spread; - dx *= velocity; - dy *= velocity; - dz *= velocity; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "icebeam", px, py, pz, dx, dy, dz); - //worldObj.spawnParticle(getFlameParticle(), px, py, pz, dx, dy, dz); - } - - //playBreathSound(); - } - -// // am I in a block?!? -// int fx = MathHelper.floor_double(this.posX); -// int fy = MathHelper.floor_double(this.posY); -// int fz = MathHelper.floor_double(this.posZ); -// -// if (this.worldObj.getBlock(fx, fy, fz) != Blocks.air) { -// System.out.println("I am in a block! World =" + this.worldObj); -// this.posY += 1D; -// } - - } - - /** - * Keep ice shield position updated - */ - @Override + + public EntityTFSnowQueen(World world) { + super(world); + this.setSize(0.7F, 2.2F); + + for (int i = 0; i < this.iceArray.length; i++) { + this.iceArray[i] = new EntityTFSnowQueenIceShield(this); + } + + this.setCurrentPhase(Phase.SUMMON); + + this.isImmuneToFire = true; + this.experienceValue = 317; + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAITFHoverSummon(this, 1.0D)); + this.tasks.addTask(2, new EntityAITFHoverThenDrop(this, 80, 20)); + this.tasks.addTask(3, new EntityAITFHoverBeam(this, 80, 100)); + this.tasks.addTask(6, new EntityAIAttackMelee(this, 1.0D, true)); + this.tasks.addTask(7, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(8, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + + @Override + public boolean canBePushed() { + return false; + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(7.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(200.0D); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(BEAM_FLAG, false); + dataManager.register(PHASE_FLAG, (byte) 0); + } + + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.ICE_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.ICE_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.ICE_DEATH; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + if (!world.isRemote) { + bossInfo.setPercent(getHealth() / getMaxHealth()); + } else { + spawnParticles(); + } + } + + private void spawnParticles() { + // make snow particles + for (int i = 0; i < 3; i++) { + float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; + float py = this.getEyeHeight() + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; + float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.3F; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.SNOW_GUARDIAN, this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); + } + + // during drop phase, all the ice blocks should make particles + if (this.getCurrentPhase() == Phase.DROP) { + for (Entity ice : this.iceArray) { + float px = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; + float py = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; + float pz = (this.rand.nextFloat() - this.rand.nextFloat()) * 0.5F; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.SNOW_WARNING, ice.lastTickPosX + px, ice.lastTickPosY + py, ice.lastTickPosZ + pz, 0, 0, 0); + } + } + + // when ice beaming, spew particles + if (isBreathing() && this.isEntityAlive()) { + Vec3d look = this.getLookVec(); + + double dist = 0.5; + double px = this.posX + look.x * dist; + double py = this.posY + 1.7F + look.y * dist; + double pz = this.posZ + look.z * dist; + + for (int i = 0; i < 10; i++) { + double dx = look.x; + double dy = 0;//look.y; + double dz = look.z; + + double spread = 2 + this.getRNG().nextDouble() * 2.5; + double velocity = 2.0 + this.getRNG().nextDouble() * 0.15; + + // beeeam + dx += this.getRNG().nextGaussian() * 0.0075D * spread; + dy += this.getRNG().nextGaussian() * 0.0075D * spread; + dz += this.getRNG().nextGaussian() * 0.0075D * spread; + dx *= velocity; + dy *= velocity; + dz *= velocity; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.ICE_BEAM, px, py, pz, dx, dy, dz); + } + } + } + + @Override public void onUpdate() { - super.onUpdate(); - + for (int i = 0; i < this.iceArray.length; i++) { - + this.iceArray[i].onUpdate(); - + if (i < this.iceArray.length - 1) { - // set block position - Vec3 blockPos = this.getIceShieldPosition(i); - - //System.out.println("Got position for block " + i + " and it is" + blockPos); - - this.iceArray[i].setPosition(blockPos.xCoord, blockPos.yCoord, blockPos.zCoord); + // set block position + Vec3d blockPos = this.getIceShieldPosition(i); + + this.iceArray[i].setPosition(blockPos.x, blockPos.y, blockPos.z); this.iceArray[i].rotationYaw = this.getIceShieldAngle(i); } else { // last block beneath this.iceArray[i].setPosition(this.posX, this.posY - 1, this.posZ); - this.iceArray[i].rotationYaw = this.getIceShieldAngle(i); + this.iceArray[i].rotationYaw = this.getIceShieldAngle(i); } - + // collide things with the block - if (!worldObj.isRemote) { - this.applyShieldCollisions(this.iceArray[i]); - } + if (!world.isRemote) { + this.applyShieldCollisions(this.iceArray[i]); + } } - + // death animation if (deathTime > 0) { - for(int k = 0; k < 5; k++) - { - double d = rand.nextGaussian() * 0.02D; - double d1 = rand.nextGaussian() * 0.02D; - double d2 = rand.nextGaussian() * 0.02D; - String explosionType = rand.nextBoolean() ? "hugeexplosion" : "explode"; - - worldObj.spawnParticle(explosionType, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); - } + for (int k = 0; k < 5; k++) { + double d = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + EnumParticleTypes explosionType = rand.nextBoolean() ? EnumParticleTypes.EXPLOSION_HUGE : EnumParticleTypes.EXPLOSION_NORMAL; + + world.spawnParticle(explosionType, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); + } } - } + } + + @Override + protected boolean canDespawn() { + return false; + } - @Override - protected void dropFewItems(boolean par1, int par2) { - dropBow(); - - // ice cubes - int totalDrops = this.rand.nextInt(4 + par2) + 1; - for (int i = 0; i < totalDrops; ++i) - { - this.dropItem(Item.getItemFromBlock(Blocks.packed_ice), 7); - } - - // snowballs - totalDrops = this.rand.nextInt(5 + par2) + 5; - for (int i = 0; i < totalDrops; ++i) - { - this.dropItem(Items.snowball, 16); - } - - // trophy - this.entityDropItem(new ItemStack(TFItems.trophy, 1, 4), 0); - } - - private void dropBow() { - int bowType = rand.nextInt(2); - if (bowType == 0) { - this.entityDropItem(new ItemStack(TFItems.tripleBow), 0); + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL) { + if (hasHome()) { + world.setBlockState(getHomePosition(), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.SNOW_QUEEN)); + } + setDead(); } else { - this.entityDropItem(new ItemStack(TFItems.seekerBow), 0); + super.despawnEntity(); } } - - /** - * Trigger achievement when killed - */ + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightProgressGlacier); - + public void onDeath(DamageSource cause) { + super.onDeath(cause); + // mark the tower as defeated + if (!world.isRemote) { + TFWorld.markStructureConquered(world, new BlockPos(this), TFFeature.ICE_TOWER); } + } - // mark the tower as defeated - if (!worldObj.isRemote) { - int dx = MathHelper.floor_double(this.posX); - int dy = MathHelper.floor_double(this.posY); - int dz = MathHelper.floor_double(this.posZ); - - if (worldObj.provider instanceof WorldProviderTwilightForest){ - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)worldObj.provider).getChunkProvider(); - TFFeature nearbyFeature = ((TFWorldChunkManager)worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, worldObj); - - if (nearbyFeature == TFFeature.lichTower) { - chunkProvider.setStructureConquered(dx, dy, dz, true); - } + private void applyShieldCollisions(Entity collider) { + List list = this.world.getEntitiesWithinAABBExcludingEntity(collider, collider.getEntityBoundingBox().grow(-0.2F, -0.2F, -0.2F)); + + for (Entity collided : list) { + if (collided.canBePushed()) { + applyShieldCollision(collider, collided); } } } - - @SuppressWarnings("unchecked") - private void applyShieldCollisions(Entity collider) { - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(collider, collider.boundingBox.expand(-0.2F, -0.2F, -0.2F)); - - for (Entity collided : list) { - - if (collided.canBePushed()) { - applyShieldCollision(collider, collided); - } - } - } - - /** - * Do the effect where the shield hits something - */ - protected void applyShieldCollision(Entity collider, Entity collided) - { - if (collided != this) { - collided.applyEntityCollision(collider); - if (collided instanceof EntityLivingBase) { - //FMLLog.info("Spike ball collided with entity %s", collided); - - // do hit and throw - boolean attackSuccess = super.attackEntityAsMob(collided); - if (attackSuccess) { - collided.motionY += 0.4000000059604645D; - this.playSound("mob.irongolem.throw", 1.0F, 1.0F); - - //System.out.println("Spike ball attack success"); + /** + * Do the effect where the shield hits something + */ + private void applyShieldCollision(Entity collider, Entity collided) { + if (collided != this) { + collided.applyEntityCollision(collider); + if (collided instanceof EntityLivingBase && super.attackEntityAsMob(collided)) { + collided.motionY += 0.4; + this.playSound(SoundEvents.ENTITY_IRONGOLEM_ATTACK, 1.0F, 1.0F); + } + } + } - } + @Override + protected void updateAITasks() { + super.updateAITasks(); - } + // switch phases + if (this.getCurrentPhase() == Phase.SUMMON && this.getSummonsRemaining() == 0 && this.countMyMinions() <= 0) { + this.setCurrentPhase(Phase.DROP); } - } + if (this.getCurrentPhase() == Phase.DROP && this.successfulDrops >= this.maxDrops) { + this.setCurrentPhase(Phase.BEAM); + } + if (this.getCurrentPhase() == Phase.BEAM && this.damageWhileBeaming >= MAX_DAMAGE_WHILE_BEAMING) { + this.setCurrentPhase(Phase.SUMMON); + } + } + @Override + public boolean attackEntityFrom(DamageSource source, float damage) { + boolean result = super.attackEntityFrom(source, damage); + if (result && this.getCurrentPhase() == Phase.BEAM) { + this.damageWhileBeaming += damage; + } - protected void updateAITasks() { - super.updateAITasks(); - - // switch phases - if (this.getCurrentPhase() == Phase.SUMMON && this.getSummonsRemaining() == 0 && this.countMyMinions() <= 0) { - this.setCurrentPhase(Phase.DROP); - } - if (this.getCurrentPhase() == Phase.DROP && this.successfulDrops >= this.maxDrops) { - this.setCurrentPhase(Phase.BEAM); - } - if (this.getCurrentPhase() == Phase.BEAM && this.damageWhileBeaming >= MAX_DAMAGE_WHILE_BEAMING) { - this.setCurrentPhase(Phase.SUMMON); - } - } - - /** - * Called when we get attacked. - */ - @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float damage) { - boolean result = super.attackEntityFrom(par1DamageSource, damage); - - if (result && this.getCurrentPhase() == Phase.BEAM) { - this.damageWhileBeaming += damage; - } - return result; - - } - - - private Vec3 getIceShieldPosition(int i) { - return this.getIceShieldPosition(getIceShieldAngle(i), 1F); + + } + + private Vec3d getIceShieldPosition(int idx) { + return this.getIceShieldPosition(getIceShieldAngle(idx), 1F); } + private float getIceShieldAngle(int idx) { + return 60F * idx + (this.ticksExisted * 5F); + } - private float getIceShieldAngle(int i) { - //System.out.println("Getting angle for shield " + i + " and it is " + (((float)Math.PI / 3F) * (float)i)); + private Vec3d getIceShieldPosition(float angle, float distance) { + double dx = Math.cos((angle) * Math.PI / 180.0D) * distance; + double dz = Math.sin((angle) * Math.PI / 180.0D) * distance; - - return 60F * i + (this.ticksExisted * 5F); - + return new Vec3d(this.posX + dx, this.posY + this.getShieldYOffset(), this.posZ + dz); } + private double getShieldYOffset() { + return 0.1F; + } - /** - * Get the ice shield position - */ - public Vec3 getIceShieldPosition(float angle, float distance) - { - double var1 = Math.cos((angle) * Math.PI / 180.0D) * distance; - double var3 = Math.sin((angle) * Math.PI / 180.0D) * distance; - - return Vec3.createVectorHelper(this.posX + var1, this.posY + this.getShieldYOffset(), this.posZ + var3); - } - - - /** - * How high is the shield - */ - public double getShieldYOffset() - { - return 0.1F; - } - - /** - * Called when the mob is falling. Calculates and applies fall damage. - */ @Override - protected void fall(float par1) { - ; // no falling + public void fall(float distance, float damageMultiplier) { } - @Override - public World func_82194_d() { - return this.worldObj; + public World getWorld() { + return this.world; } @Override - public boolean attackEntityFromPart(EntityDragonPart entitydragonpart, DamageSource damagesource, float i) { + public boolean attackEntityFromPart(MultiPartEntityPart part, DamageSource source, float damage) { return false; } - - - /** - * We need to do this for the bounding boxes on the parts to become active - */ - @Override - public Entity[] getParts() { - return iceArray; - } - + /** - * Destroys all ice related blocks in the AABB - */ - public boolean destroyBlocksInAABB(AxisAlignedBB par1AxisAlignedBB) { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - boolean wasBlocked = false; - for (int dx = minX; dx <= maxX; ++dx) { - for (int dy = minY; dy <= maxY; ++dy) { - for (int dz = minZ; dz <= maxZ; ++dz) { - Block block = this.worldObj.getBlock(dx, dy, dz); - - if (block != Blocks.air) { - int currentMeta = this.worldObj.getBlockMetadata(dx, dy, dz); - - if (block == Blocks.ice || block == Blocks.packed_ice) { - this.worldObj.setBlock(dx, dy, dz, Blocks.air, 0, 2); - - // here, this effect will have to do - worldObj.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(block) + (currentMeta << 12)); - } else { - wasBlocked = true; - } - } - } - } - } - - return wasBlocked; - } + * We need to do this for the bounding boxes on the parts to become active + */ + @Override + public Entity[] getParts() { + return iceArray; + } - public boolean isBreathing() { - return this.getDataWatcher().getWatchableObjectByte(BEAM_FLAG) == 1; + public void destroyBlocksInAABB(AxisAlignedBB box) { + if (ForgeEventFactory.getMobGriefingEvent(world, this)) { + for (BlockPos pos : WorldUtil.getAllInBB(box)) { + IBlockState state = world.getBlockState(pos); + if (state.getBlock() == Blocks.ICE || state.getBlock() == Blocks.PACKED_ICE) { + world.destroyBlock(pos, false); + } + } + } + } + @Override + public boolean isBreathing() { + return dataManager.get(BEAM_FLAG); } + @Override public void setBreathing(boolean flag) { - this.getDataWatcher().updateObject(BEAM_FLAG, Byte.valueOf((byte)(flag ? 1 : 0))); + dataManager.set(BEAM_FLAG, flag); } - public Phase getCurrentPhase() { - return Phase.values()[this.getDataWatcher().getWatchableObjectByte(PHASE_FLAG)]; + return Phase.values()[dataManager.get(PHASE_FLAG)]; } - public void setCurrentPhase(Phase currentPhase) { - this.getDataWatcher().updateObject(PHASE_FLAG, Byte.valueOf((byte) currentPhase.ordinal())); - + dataManager.set(PHASE_FLAG, (byte) currentPhase.ordinal()); + // set variables for current phase if (currentPhase == Phase.SUMMON) { this.setSummonsRemaining(MAX_SUMMONS); @@ -543,143 +397,86 @@ public void setCurrentPhase(Phase currentPhase) { } } - public int getSummonsRemaining() { return summonsRemaining; } - public void setSummonsRemaining(int summonsRemaining) { this.summonsRemaining = summonsRemaining; } - + public void summonMinionAt(EntityLivingBase targetedEntity) { - - // find a good spot - Vec3 minionSpot = findVecInLOSOf(targetedEntity); - - // put a minion there - EntityTFIceCrystal minion = new EntityTFIceCrystal(worldObj); - minion.setPosition(minionSpot.xCoord, minionSpot.yCoord, minionSpot.zCoord); - worldObj.spawnEntityInWorld(minion); - + EntityTFIceCrystal minion = new EntityTFIceCrystal(world); + minion.setPositionAndRotation(posX, posY, posZ, 0, 0); + + world.spawnEntity(minion); + + for (int i = 0; i < 100; i++) { + double attemptX; + double attemptY; + double attemptZ; + if (hasHome()) { + BlockPos home = getHomePosition(); + attemptX = home.getX() + rand.nextGaussian() * 7D; + attemptY = home.getY() + rand.nextGaussian() * 2D; + attemptZ = home.getZ() + rand.nextGaussian() * 7D; + } else { + attemptX = targetedEntity.posX + rand.nextGaussian() * 16D; + attemptY = targetedEntity.posY + rand.nextGaussian() * 8D; + attemptZ = targetedEntity.posZ + rand.nextGaussian() * 16D; + } + if (minion.attemptTeleport(attemptX, attemptY, attemptZ)) { + break; + } + } + minion.setAttackTarget(targetedEntity); minion.setToDieIn30Seconds(); // don't stick around - - // reduce summons + this.summonsRemaining--; } - - /** - * Returns coords that would be good to teleport to. - * - * Returns null if we can't find anything - */ - protected Vec3 findVecInLOSOf(Entity targetEntity) - { - // for some reason we occasionally get null here - if (targetEntity == null) - { - return null; - } - - double tx = 0, ty = 0, tz = 0; - int tries = 100; - for (int i = 0; i < tries; i++) { - tx = targetEntity.posX + rand.nextGaussian() * 16D; - ty = targetEntity.posY + rand.nextGaussian() * 8D; - tz = targetEntity.posZ + rand.nextGaussian() * 16D; - - // put the y on something solid - boolean groundFlag = false; - // we need to get the integer coordinates for this calculation - int bx = MathHelper.floor_double(tx); - int by = MathHelper.floor_double(ty); - int bz = MathHelper.floor_double(tz); - while (!groundFlag && ty > 0) - { - Block whatsThere = worldObj.getBlock(bx, by - 1, bz); - if (whatsThere == Blocks.air || !whatsThere.getMaterial().isSolid()) - { - ty--; - by--; - } - else - { - groundFlag = true; - } - } - - // did we not find anything at all to stand on? - if (by == 0) { -// System.out.println("teleport find failed to find a block to stand on"); - continue; - } - - // - if (!canEntitySee(targetEntity, tx, ty, tz)) { -// System.out.println("teleport find failed because of lack of LOS"); -// System.out.println("ty = " + ty); - continue; - } - - // check that we're not colliding and not in liquid - float halfWidth = this.width / 2.0F; - AxisAlignedBB destBox = AxisAlignedBB.getBoundingBox(tx - halfWidth, ty - yOffset + ySize, tz - halfWidth, tx + halfWidth, ty - yOffset + ySize + height, tz + halfWidth); - if (worldObj.getCollidingBoundingBoxes(this, destBox).size() > 0) - { -// System.out.println("teleport find failed because of collision"); - continue; - } - - if (worldObj.isAnyLiquid(destBox)) { -// System.out.println("teleport find failed because of liquid at destination"); - continue; - } - - // if we made it this far, we win! - break; - } - - if (tries == 99) { - //System.out.println("Found no spots, giving up"); - return null; - } - - //System.out.println("I think we found a good destination at " + tx + ", " + ty + ", " + tz); -// System.out.println("canEntitySee = " + canEntitySee(targetEntity, tx, ty, tz)); - return Vec3.createVectorHelper(tx, ty, tz); - } - - /** - * Can the specified entity see the specified location? - */ - protected boolean canEntitySee(Entity entity, double dx, double dy, double dz) { - return worldObj.rayTraceBlocks(Vec3.createVectorHelper(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ), Vec3.createVectorHelper(dx, dy, dz)) == null; - - } - - @SuppressWarnings("unchecked") public int countMyMinions() { - // check if there are enough minions. we check a 32x16x32 area - List nearbyMinons = worldObj.getEntitiesWithinAABB(EntityTFIceCrystal.class, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(32.0D, 16.0D, 32.0D)); - - return nearbyMinons.size(); + return world.getEntitiesWithinAABB(EntityTFIceCrystal.class, new AxisAlignedBB(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).grow(32.0D, 16.0D, 32.0D)).size(); } - public void incrementSuccessfulDrops() { this.successfulDrops++; } - @Override public void doBreathAttack(Entity target) { - if (target.attackEntityFrom(DamageSource.causeMobDamage(this), BREATH_DAMAGE)) { - // slow target? - } + target.attackEntityFrom(DamageSource.causeMobDamage(this), BREATH_DAMAGE); + // TODO: slow target? + } + + @Override + public void setCustomNameTag(String name) { + super.setCustomNameTag(name); + this.bossInfo.setName(this.getDisplayName()); + } + + @Override + public void addTrackingPlayer(EntityPlayerMP player) { + super.addTrackingPlayer(player); + this.bossInfo.addPlayer(player); } - + @Override + public void removeTrackingPlayer(EntityPlayerMP player) { + super.removeTrackingPlayer(player); + this.bossInfo.removePlayer(player); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + if (this.hasCustomName()) + this.bossInfo.setName(this.getDisplayName()); + } + + @Override + public boolean isNonBoss() { + return false; + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFSnowQueenIceShield.java b/src/main/java/twilightforest/entity/boss/EntityTFSnowQueenIceShield.java index b10817a2bb..42c215c2fc 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFSnowQueenIceShield.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFSnowQueenIceShield.java @@ -1,86 +1,38 @@ package twilightforest.entity.boss; -import net.minecraft.entity.Entity; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.entity.MultiPartEntityPart; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; -import net.minecraft.world.World; -public class EntityTFSnowQueenIceShield extends Entity { - - EntityTFSnowQueen queen; - - public EntityTFSnowQueenIceShield(World par1World) { - super(par1World); - setSize(0.75F, 0.75F); - } +public class EntityTFSnowQueenIceShield extends MultiPartEntityPart { - public EntityTFSnowQueenIceShield(EntityTFSnowQueen goblin) { - this(goblin.func_82194_d()); - this.queen = goblin; + public EntityTFSnowQueenIceShield(EntityTFSnowQueen waifu) { + super(waifu, "shield", 0.75F, 0.75F); } - /** - * Don't take damage from attacks - */ @Override - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) { - this.worldObj.playSoundAtEntity(this, "random.break", 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); - + public boolean attackEntityFrom(DamageSource source, float amount) { + playSound(SoundEvents.ENTITY_ITEM_BREAK, 1.0F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); return false; } - - /** - * Skip most of the living update things - */ - @Override - public void onUpdate() { - super.onUpdate(); - - this.ticksExisted++; - - lastTickPosX = posX; - lastTickPosY = posY; - lastTickPosZ = posZ; - - - //System.out.println("Updating " + this + " with angles " + rotationYawHead + ", " + rotationPitch); - - for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { } - for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { } - for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { } - for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { } - - } - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - public boolean canBeCollidedWith() - { - return true; - } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - public boolean isEntityEqual(Entity entity) - { - return this == entity || this.queen == entity; - } - - @Override - protected void entityInit() { } - @Override - protected void readEntityFromNBT(NBTTagCompound nbttagcompound) { } - - @Override - protected void writeEntityToNBT(NBTTagCompound nbttagcompound) { } - + public void onUpdate() { + super.onUpdate(); + + this.ticksExisted++; + + lastTickPosX = posX; + lastTickPosY = posY; + lastTickPosZ = posZ; + + for (; rotationYaw - prevRotationYaw < -180F; prevRotationYaw -= 360F) { + } + for (; rotationYaw - prevRotationYaw >= 180F; prevRotationYaw += 360F) { + } + for (; rotationPitch - prevRotationPitch < -180F; prevRotationPitch -= 360F) { + } + for (; rotationPitch - prevRotationPitch >= 180F; prevRotationPitch += 360F) { + } + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFThrownAxe.java b/src/main/java/twilightforest/entity/boss/EntityTFThrownAxe.java deleted file mode 100644 index db0fc7ae81..0000000000 --- a/src/main/java/twilightforest/entity/boss/EntityTFThrownAxe.java +++ /dev/null @@ -1,87 +0,0 @@ -package twilightforest.entity.boss; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.World; - -public class EntityTFThrownAxe extends EntityThrowable { - - private static final float PROJECTILE_DAMAGE = 6; - - public EntityTFThrownAxe(World par1World, EntityLivingBase par2EntityLivingBase) { - super(par1World, par2EntityLivingBase); - this.setSize(0.5F, 0.5F); - } - - public EntityTFThrownAxe(World par1World) { - super(par1World); - this.setSize(0.5F, 0.5F); - } - - - - @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - boolean passThru = false; - - if (par1MovingObjectPosition.entityHit != null) - { - if (par1MovingObjectPosition.entityHit instanceof EntityTFKnightPhantom) - { - passThru = true; - } - - // if we're not set to pass, damage what we hit - if (!passThru) - { - par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), PROJECTILE_DAMAGE); - } - } - - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("largesmoke", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); - } - - if (!passThru && !this.worldObj.isRemote) - { - this.setDead(); - } - } - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - @Override - public boolean canBeCollidedWith() - { - return true; - } - - /** - * We need to set this so that the player can attack and reflect the bolt - */ - @Override - public float getCollisionBorderSize() - { - return 1.0F; - } - - /** - * Projectile speed - */ - protected float func_70182_d() - { - return 0.1F; - } - - /** - * Gets the amount of gravity to apply to the thrown entity with each tick. - */ - protected float getGravityVelocity() - { - return 0.001F; - } -} diff --git a/src/main/java/twilightforest/entity/boss/EntityTFThrownPick.java b/src/main/java/twilightforest/entity/boss/EntityTFThrownPick.java deleted file mode 100644 index d3b6382cd0..0000000000 --- a/src/main/java/twilightforest/entity/boss/EntityTFThrownPick.java +++ /dev/null @@ -1,87 +0,0 @@ -package twilightforest.entity.boss; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityThrowable; -import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.world.World; - -public class EntityTFThrownPick extends EntityThrowable { - - private static final float PROJECTILE_DAMAGE = 3; - - public EntityTFThrownPick(World par1World, EntityLivingBase par2EntityLivingBase) { - super(par1World, par2EntityLivingBase); - this.setSize(0.5F, 0.5F); - } - - public EntityTFThrownPick(World par1World) { - super(par1World); - this.setSize(0.5F, 0.5F); - } - - - - @Override - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - boolean passThru = false; - - if (par1MovingObjectPosition.entityHit != null) - { - if (par1MovingObjectPosition.entityHit instanceof EntityTFKnightPhantom) - { - passThru = true; - } - - // if we're not set to pass, damage what we hit - if (!passThru) - { - par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), PROJECTILE_DAMAGE); - } - } - - for (int i = 0; i < 8; ++i) - { - this.worldObj.spawnParticle("largesmoke", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); - } - - if (!passThru && !this.worldObj.isRemote) - { - this.setDead(); - } - } - - /** - * Returns true if other Entities should be prevented from moving through this Entity. - */ - @Override - public boolean canBeCollidedWith() - { - return true; - } - - /** - * We need to set this so that the player can attack and reflect the bolt - */ - @Override - public float getCollisionBorderSize() - { - return 1.0F; - } - - /** - * Projectile speed - */ - protected float func_70182_d() - { - return 1.0F; - } - - /** - * Gets the amount of gravity to apply to the thrown entity with each tick. - */ - protected float getGravityVelocity() - { - return 0.015F; - } -} diff --git a/src/main/java/twilightforest/entity/boss/EntityTFThrownWep.java b/src/main/java/twilightforest/entity/boss/EntityTFThrownWep.java new file mode 100644 index 0000000000..bc004c5f11 --- /dev/null +++ b/src/main/java/twilightforest/entity/boss/EntityTFThrownWep.java @@ -0,0 +1,99 @@ +package twilightforest.entity.boss; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.entity.EntityTFThrowable; + +public class EntityTFThrownWep extends EntityTFThrowable { + + private static final DataParameter DATA_ITEMSTACK = EntityDataManager.createKey(EntityTFThrownWep.class, DataSerializers.ITEM_STACK); + private static final DataParameter DATA_VELOCITY = EntityDataManager.createKey(EntityTFThrownWep.class, DataSerializers.FLOAT); + + private float projectileDamage = 6; + + public EntityTFThrownWep(World world, EntityLivingBase thrower) { + super(world, thrower); + this.setSize(0.5F, 0.5F); + } + + public EntityTFThrownWep(World world) { + super(world); + this.setSize(0.5F, 0.5F); + } + + public EntityTFThrownWep setDamage(float damage) { + projectileDamage = damage; + return this; + } + + @Override + protected void entityInit() { + dataManager.register(DATA_ITEMSTACK, ItemStack.EMPTY); + dataManager.register(DATA_VELOCITY, 0.001F); + } + + public EntityTFThrownWep setItem(ItemStack stack) { + dataManager.set(DATA_ITEMSTACK, stack); + return this; + } + + public ItemStack getItem() { + return dataManager.get(DATA_ITEMSTACK); + } + + public EntityTFThrownWep setVelocity(float velocity) { + dataManager.set(DATA_VELOCITY, velocity); + return this; + } + + @SideOnly(Side.CLIENT) + @Override + public void handleStatusUpdate(byte id) { + if (id == 3) { + for (int i = 0; i < 8; ++i) { + this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); + } + } else { + super.handleStatusUpdate(id); + } + } + + @Override + protected void onImpact(RayTraceResult result) { + if (result.entityHit instanceof EntityTFKnightPhantom || result.entityHit == this.getThrower()) { + return; + } + + if (!world.isRemote) { + if (result.entityHit != null) { + result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), projectileDamage); + } + world.setEntityState(this, (byte) 3); + setDead(); + } + } + + @Override + public boolean canBeCollidedWith() { + return true; + } + + @Override + public float getCollisionBorderSize() { + return 1.0F; + } + + @Override + protected float getGravityVelocity() { + return dataManager.get(DATA_VELOCITY); + } +} diff --git a/src/main/java/twilightforest/entity/boss/EntityTFUrGhast.java b/src/main/java/twilightforest/entity/boss/EntityTFUrGhast.java index 0bba892f06..b0746459d9 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFUrGhast.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFUrGhast.java @@ -1,911 +1,610 @@ package twilightforest.entity.boss; -import java.util.ArrayList; -import java.util.List; - +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.boss.IBossDisplayData; +import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.ai.EntityMoveHelper; import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.BossInfo; +import net.minecraft.world.BossInfoServer; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; import net.minecraft.world.storage.WorldInfo; -import twilightforest.TFAchievementPage; import twilightforest.TFFeature; -import twilightforest.TFTreasure; import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFBossSpawner; import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.TFBlocks; +import twilightforest.client.particle.TFParticleType; import twilightforest.entity.EntityTFMiniGhast; import twilightforest.entity.EntityTFTowerGhast; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; -import cpw.mods.fml.common.FMLLog; +import twilightforest.entity.NoClipMoveHelper; +import twilightforest.enums.BossVariant; +import twilightforest.enums.TowerDeviceVariant; +import twilightforest.loot.TFTreasure; +import twilightforest.world.TFWorld; -public class EntityTFUrGhast extends EntityTFTowerGhast implements IBossDisplayData { +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; -// private static final int DATA_BOSSHEALTH = 17; - private static final int DATA_TANTRUM = 18; +public class EntityTFUrGhast extends EntityTFTowerGhast { + private static final DataParameter DATA_TANTRUM = EntityDataManager.createKey(EntityTFUrGhast.class, DataSerializers.BOOLEAN); //private static final int CRUISING_ALTITUDE = 235; // absolute cruising altitude private static final int HOVER_ALTITUDE = 20; // how far, relatively, do we hover over ghast traps? + private List trapLocations; + private int nextTantrumCry; + + private float damageUntilNextPhase = 10; // how much damage can we take before we toggle tantrum mode + private boolean noTrapMode; // are there no traps nearby? just float around + private final BossInfoServer bossInfo = new BossInfoServer(getDisplayName(), BossInfo.Color.RED, BossInfo.Overlay.PROGRESS); + + public EntityTFUrGhast(World world) { + super(world); + this.setSize(14.0F, 18.0F); + this.wanderFactor = 32.0F; + this.noClip = true; + this.setInTantrum(false); + this.experienceValue = 317; + this.moveHelper = new NoClipMoveHelper(this); + } - public double courseX; - public double courseY; - public double courseZ; - - ArrayList trapLocations; - ArrayList travelCoords; - - int currentTravelCoordIndex; - - int travelPathRepetitions; - int desiredRepetitions; - - int nextTantrumCry; - - float damageUntilNextPhase; // how much damage can we take before we toggle tantrum mode - - boolean noTrapMode; // are there no traps nearby? just float around - - public EntityTFUrGhast(World par1World) - { - super(par1World); - - this.setSize(14.0F, 18.0F); - this.aggroRange = 128.0F; - this.wanderFactor = 32.0F; - - //this.texture = TwilightForestMod.MODEL_DIR + "towerboss.png"; - - - this.noClip = true; - - this.trapLocations = new ArrayList(); - this.travelCoords = new ArrayList(); - - this.setInTantrum(false); - - this.damageUntilNextPhase = 45; - - this.experienceValue = 317; - - this.noTrapMode = false; - - } - -// public int getMaxHealth() -// { -// return 250; -// } - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(250); // max health - } - + public void setCustomNameTag(String name) { + super.setCustomNameTag(name); + this.bossInfo.setName(this.getDisplayName()); + } + @Override - protected void entityInit() - { - super.entityInit(); -// this.dataWatcher.addObject(DATA_BOSSHEALTH, new Integer(this.getMaxHealth())); - this.dataWatcher.addObject(DATA_TANTRUM, Byte.valueOf((byte) 0)); - } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - /** - * Keep health updated - */ - @Override - public void onUpdate() { - - super.onUpdate(); - - // extra death explosions - if (deathTime > 0) { - for(int k = 0; k < 5; k++) - { - double d = rand.nextGaussian() * 0.02D; - double d1 = rand.nextGaussian() * 0.02D; - double d2 = rand.nextGaussian() * 0.02D; - String explosionType = rand.nextBoolean() ? "hugeexplosion" : "explode"; - - worldObj.spawnParticle(explosionType, (posX + rand.nextFloat() * width * 2.0F) - width, posY + rand.nextFloat() * height, (posZ + rand.nextFloat() * width * 2.0F) - width, d, d1, d2); - } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(250); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(128.0D); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_TANTRUM, false); + } + + @Override + protected void initEntityAI() { + super.initEntityAI(); + trapLocations = new ArrayList(); + this.tasks.taskEntries.removeIf(e -> e.action instanceof EntityTFTowerGhast.AIHomedFly); + this.tasks.addTask(5, new AIWaypointFly(this)); + } + + static class AIWaypointFly extends EntityAIBase { + private final EntityTFUrGhast taskOwner; + + private final List pointsToVisit; + private int currentPoint = 0; + + AIWaypointFly(EntityTFUrGhast ghast) { + this.taskOwner = ghast; + pointsToVisit = createPath(); + setMutexBits(1); + } + + // [VanillaCopy] EntityGhast.AIRandomFly + @Override + public boolean shouldExecute() { + EntityMoveHelper entitymovehelper = this.taskOwner.getMoveHelper(); + + if (!entitymovehelper.isUpdating()) { + return true; + } else { + double d0 = entitymovehelper.getX() - this.taskOwner.posX; + double d1 = entitymovehelper.getY() - this.taskOwner.posY; + double d2 = entitymovehelper.getZ() - this.taskOwner.posZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + return d3 < 1.0D || d3 > 3600.0D; + } + } + + @Override + public boolean shouldContinueExecuting() { + return false; + } + + @Override + public void startExecuting() { + if (this.pointsToVisit.isEmpty()) { + pointsToVisit.addAll(createPath()); + } else { + if (this.currentPoint >= pointsToVisit.size()) { + this.currentPoint = 0; + + // when we're in tantrum mode, this is a good time to check if we need to spawn more ghasts + if (!taskOwner.checkGhastsAtTraps()) { + taskOwner.spawnGhastsAtTraps(); + } + } + + // TODO reintrodue wanderFactor somehow? Would need to change move helper or add extra fields here + + double x = pointsToVisit.get(currentPoint).getX(); + double y = pointsToVisit.get(currentPoint).getY() + HOVER_ALTITUDE; + double z = pointsToVisit.get(currentPoint).getZ(); + taskOwner.getMoveHelper().setMoveTo(x, y, z, 1.0F); + this.currentPoint++; + + // we have reached cruising altitude, time to turn noClip off + taskOwner.noClip = false; + } + } + + private List createPath() { + List potentialPoints = new ArrayList<>(); + BlockPos pos = new BlockPos(this.taskOwner); + + if (!this.taskOwner.noTrapMode) { + // make a copy of the trap locations list + potentialPoints.addAll(this.taskOwner.trapLocations); + } else { + potentialPoints.add(pos.add(20, -HOVER_ALTITUDE, 0)); + potentialPoints.add(pos.add(0, -HOVER_ALTITUDE, -20)); + potentialPoints.add(pos.add(-20, -HOVER_ALTITUDE, 0)); + potentialPoints.add(pos.add(0, -HOVER_ALTITUDE, 20)); + } + + Collections.shuffle(potentialPoints); + + if (this.taskOwner.noTrapMode) { + // if in no trap mode, head back to the middle when we're done + potentialPoints.add(pos.down(HOVER_ALTITUDE)); + } + + return potentialPoints; } - } - - /** - * Called when the entity is attacked. - */ - public boolean attackEntityFrom(DamageSource source, float damage) - { - // ignore suffocation - if (source == DamageSource.inWall) - { - return false; - } - - boolean attackSuccessful = false; - - // in tantrum mode take only 1/4 damage - if (this.isInTantrum()) - { - damage /= 4; - } - - if ("fireball".equals(source.getDamageType()) && source.getEntity() instanceof EntityPlayer) - { - // 'hide' fireball attacks so that we don't take 1000 damage. - attackSuccessful = super.attackEntityFrom(DamageSource.causeThrownDamage(source.getSourceOfDamage(), source.getEntity()), damage); - } - else - { - attackSuccessful = super.attackEntityFrom(source, damage); - } - - if (!worldObj.isRemote) - { - if (this.hurtTime == this.maxHurtTime) - { - this.damageUntilNextPhase -= this.getLastDamage(); - - FMLLog.info("[Urghast] Attack successful, %f damage until phase switch.", this.damageUntilNextPhase); - - if (this.damageUntilNextPhase <= 0) - { - this.switchPhase(); - } - } - else - { - FMLLog.info("[Urghast] Attack fail with %s type attack for %f damage", source.damageType, damage); - } - } - - return attackSuccessful; - } - - private float getLastDamage() { - - - return this.prevHealth - this.getHealth(); } - /** - * Move to the next phase of our behavior - */ + @Override + protected boolean canDespawn() { + return false; + } + + @Override + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL) { + if (hasHome()) { + world.setBlockState(getHomePosition(), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.UR_GHAST)); + } + setDead(); + } else { + super.despawnEntity(); + } + } + + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (!world.isRemote) { + bossInfo.setPercent(getHealth() / getMaxHealth()); + } else { + if (this.isInTantrum()) { + TwilightForestMod.proxy.spawnParticle(TFParticleType.BOSS_TEAR, + this.posX + (this.rand.nextDouble() - 0.5D) * (double) this.width, + this.posY + this.rand.nextDouble() * (double) this.height - 0.25D, + this.posZ + (this.rand.nextDouble() - 0.5D) * (double) this.width, + 0, 0, 0 + ); + } + + // extra death explosions + if (deathTime > 0) { + for (int k = 0; k < 5; k++) { + + double d = rand.nextGaussian() * 0.02D; + double d1 = rand.nextGaussian() * 0.02D; + double d2 = rand.nextGaussian() * 0.02D; + + world.spawnParticle(rand.nextBoolean() ? EnumParticleTypes.EXPLOSION_HUGE : EnumParticleTypes.EXPLOSION_NORMAL, + (posX + rand.nextFloat() * width * 2.0F) - width, + posY + rand.nextFloat() * height, + (posZ + rand.nextFloat() * width * 2.0F) - width, + d, d1, d2 + ); + } + } + } + } + + @Override + public boolean isEntityInvulnerable(DamageSource src) { + return src == DamageSource.IN_WALL || super.isEntityInvulnerable(src); + } + + @Override + public void knockBack(Entity entityIn, float strength, double xRatio, double zRatio) { + // Don't take knockback + } + + @Override + public boolean attackEntityFrom(DamageSource source, float damage) { + // in tantrum mode take only 1/10 damage + if (this.isInTantrum()) { + damage /= 10; + } + + float oldHealth = getHealth(); + boolean attackSuccessful; + + if ("fireball".equals(source.getDamageType()) && source.getTrueSource() instanceof EntityPlayer) { + // 'hide' fireball attacks so that we don't take 1000 damage. + attackSuccessful = super.attackEntityFrom(DamageSource.causeThrownDamage(source.getTrueSource(), source.getImmediateSource()), damage); + } else { + attackSuccessful = super.attackEntityFrom(source, damage); + } + + float lastDamage = oldHealth - getHealth(); + + if (!world.isRemote) { + if (this.hurtTime == this.maxHurtTime) { + this.damageUntilNextPhase -= lastDamage; + + TwilightForestMod.LOGGER.debug("Urghast Attack successful, {} damage until phase switch.", this.damageUntilNextPhase); + + if (this.damageUntilNextPhase <= 0) { + this.switchPhase(); + } + } else { + TwilightForestMod.LOGGER.debug("Urghast Attack fail with {} type attack for {} damage", source.damageType, damage); + } + } + + return attackSuccessful; + } + private void switchPhase() { if (this.isInTantrum()) { - this.stopTantrum(); + this.setInTantrum(false); } else { this.startTantrum(); } - - this.damageUntilNextPhase = 48; + + resetDamageUntilNextPhase(); } - /** - * Start throwing a tantrum - */ - protected void startTantrum() { + public void resetDamageUntilNextPhase() { + damageUntilNextPhase = 18; + } + + private void startTantrum() { this.setInTantrum(true); - + // start raining int rainTime = 300 * 20; - - WorldInfo worldInfo = MinecraftServer.getServer().worldServers[0].getWorldInfo(); - - //System.out.println("Starting rain and thunder. world = " + worldObj); - - worldInfo.setRaining(true); - worldInfo.setThundering(true); + + WorldInfo worldInfo = world.getMinecraftServer().worlds[0].getWorldInfo(); // grab the overworld to set weather properly + + worldInfo.setCleanWeatherTime(0); worldInfo.setRainTime(rainTime); worldInfo.setThunderTime(rainTime); - + worldInfo.setRaining(true); + worldInfo.setThundering(true); + spawnGhastsAtTraps(); } /** * Spawn ghasts at two of the traps */ - protected void spawnGhastsAtTraps() { + private void spawnGhastsAtTraps() { // spawn ghasts around two of the traps - ArrayList ghastSpawns = new ArrayList(this.trapLocations); - + List ghastSpawns = new ArrayList(this.trapLocations); + Collections.shuffle(ghastSpawns); + int numSpawns = Math.min(2, ghastSpawns.size()); - for (int i = 0; i < numSpawns; i++) - { - int index = this.rand.nextInt(ghastSpawns.size()); - - ChunkCoordinates spawnCoord = ghastSpawns.get(index); - ghastSpawns.remove(index); - - spawnMinionGhastsAt(spawnCoord.posX, spawnCoord.posY, spawnCoord.posZ); + for (int i = 0; i < numSpawns; i++) { + BlockPos spawnCoord = ghastSpawns.get(i); + spawnMinionGhastsAt(spawnCoord.getX(), spawnCoord.getY(), spawnCoord.getZ()); } } - - public void stopTantrum() - { - this.setInTantrum(false); - - } /** * Spawn up to 6 minon ghasts around the indicated area */ - private void spawnMinionGhastsAt(int x, int y, int z) { - int tries = 24; - int spawns = 0; - int maxSpawns = 6; - - int rangeXZ = 4; - int rangeY = 8; - - //System.out.printf("Spawning minions near %d, %d, %d.\n", x, y, z); - + private void spawnMinionGhastsAt(int x, int y, int z) { + int tries = 24; + int spawns = 0; + int maxSpawns = 6; + + int rangeXZ = 4; + int rangeY = 8; + // lightning strike - this.worldObj.addWeatherEffect(new EntityLightningBolt(worldObj, x, y + 4, z)); - - - for (int i = 0; i < tries; i++) - { - EntityTFMiniGhast minion = new EntityTFMiniGhast(worldObj); - - double sx = x + ((rand.nextDouble() - rand.nextDouble()) * rangeXZ); - double sy = y + (rand.nextDouble() * rangeY); - double sz = z + ((rand.nextDouble() - rand.nextDouble()) * rangeXZ); - - minion.setLocationAndAngles(sx, sy, sz, this.worldObj.rand.nextFloat() * 360.0F, 0.0F); - minion.makeBossMinion(); - - if (minion.getCanSpawnHere()) - { - //System.out.println("Spawned minion!"); - - this.worldObj.spawnEntityInWorld(minion); - minion.spawnExplosionParticle(); - } - else - { - //System.out.println("Minion can't spawn!"); - } - - // limit the total number of successful spawns - if (++spawns >= maxSpawns) - { - //System.out.println("Spawned maxiumum minions."); - break; - } - } + this.world.addWeatherEffect(new EntityLightningBolt(world, x, y + 4, z, true)); - } - /** - * Altered Ghast AI - */ - @SuppressWarnings("unchecked") - protected void updateEntityActionState() - { - if (!this.worldObj.isRemote && this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL) - { - this.setDead(); - } - - this.despawnEntity(); - - // despawn mini ghasts that are in our AABB - List nearbyGhasts = worldObj.getEntitiesWithinAABB(EntityTFMiniGhast.class, this.boundingBox.expand(1, 1, 1)); - for (EntityTFMiniGhast ghast : nearbyGhasts) - { - ghast.setDead(); - this.heal(2); - } - - - // trap locations? - if (this.trapLocations.isEmpty() && !this.noTrapMode) - { - //System.out.println("Tower boss scannning for traps."); - - this.scanForTrapsTwice(); - - //System.out.println("Traps found: " + this.trapLocations.size()); - } - - // did we find any traps? - if (this.trapLocations.isEmpty() && !this.noTrapMode) - { - FMLLog.info("[TwilightForest] Ur-ghast cannot find traps nearby, entering trap-less mode"); - this.noTrapMode = true; - } - - // check if in trap - if (this.inTrapCounter > 0) - { - this.inTrapCounter--; - this.targetedEntity = null; - return; // do nothing if in trap; - } - - this.prevAttackCounter = this.attackCounter; - - // target - if (this.targetedEntity != null && this.targetedEntity.isDead) - { - this.targetedEntity = null; - } - - if (this.targetedEntity == null) - { - this.targetedEntity = findPlayerInRange(); - } - else if (!this.isAggressive && this.targetedEntity instanceof EntityPlayer) - { - checkToIncreaseAggro((EntityPlayer) this.targetedEntity); - } - - - // tantrum? - if (this.isInTantrum()) - { - shedTear(); - - this.targetedEntity = null; - - // cry? - if (--this.nextTantrumCry <= 0) - { - this.playSound(getHurtSound(), this.getSoundVolume(), this.getSoundPitch()); - this.nextTantrumCry = 20 + rand.nextInt(30); - } - - if (this.ticksExisted % 10 == 0) - { - doTantrumDamageEffects(); - } - - } - - - // do this - checkAndChangeCourse(); - - - // check if we are at our waypoint target - double offsetX = this.waypointX - this.posX; - double offsetY = this.waypointY - this.posY; - double offsetZ = this.waypointZ - this.posZ; - double distanceToWaypoint = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; - - if (distanceToWaypoint < 1.0D || distanceToWaypoint > 3600.0D) - { - makeNewWaypoint(); - } - - - - // move? - if (this.courseChangeCooldown-- <= 0) - { - this.courseChangeCooldown += this.rand.nextInt(5) + 0; - distanceToWaypoint = (double)MathHelper.sqrt_double(distanceToWaypoint); - - double speed = 0.05D; - this.motionX += offsetX / distanceToWaypoint * speed; - this.motionY += offsetY / distanceToWaypoint * speed; - this.motionZ += offsetZ / distanceToWaypoint * speed; - } - - // check if our target is still within range - double targetRange = (this.aggroCounter > 0 || this.isAggressive) ? aggroRange : stareRange; - - if (this.targetedEntity != null && this.targetedEntity.getDistanceSqToEntity(this) < targetRange * targetRange && this.canEntityBeSeen(this.targetedEntity)) - { - // turn towards target - this.faceEntity(this.targetedEntity, 10F, this.getVerticalFaceSpeed()); - - // attack if aggressive - if (this.isAggressive) - { - if (this.attackCounter == 10) - { - //this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1007, (int)this.posX, (int)this.posY, (int)this.posZ, 0); - this.playSound("mob.ghast.charge", this.getSoundVolume(), this.getSoundPitch()); - } - - ++this.attackCounter; - - if (this.attackCounter == 20) - { - spitFireball(); - this.attackCounter = -40; - } - } - } - else - { - // ignore player, move normally - this.isAggressive = false; - this.targetedEntity = null; - this.rotationYaw = -((float)Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float)Math.PI; - - // changing the pitch with movement looks goofy and un-ghast-like - //double dist = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); - this.rotationPitch = 0;//(float) (-((Math.atan2(this.motionY, dist) * 180D) / Math.PI));; - - } - - if (this.attackCounter > 0 && !this.isAggressive) - { - --this.attackCounter; - } - - // set aggro status - byte currentAggroStatus = this.dataWatcher.getWatchableObjectByte(16); - byte newAggroStatus = (byte)(this.attackCounter > 10 ? 2 : (this.aggroCounter > 0 || this.isAggressive) ? 1 : 0); - - if (currentAggroStatus != newAggroStatus) - { - this.dataWatcher.updateObject(16, Byte.valueOf(newAggroStatus)); - } - } - - @SuppressWarnings("unchecked") - private void doTantrumDamageEffects() { - // harm player below - AxisAlignedBB below = this.boundingBox.getOffsetBoundingBox(0, -16, 0).expand(0, 16, 0); + for (int i = 0; i < tries; i++) { + EntityTFMiniGhast minion = new EntityTFMiniGhast(world); - List playersBelow = worldObj.getEntitiesWithinAABB(EntityPlayer.class, below); + double sx = x + ((rand.nextDouble() - rand.nextDouble()) * rangeXZ); + double sy = y + (rand.nextDouble() * rangeY); + double sz = z + ((rand.nextDouble() - rand.nextDouble()) * rangeXZ); - for (EntityPlayer player : playersBelow) - { - int dx = MathHelper.floor_double(player.posX); - int dy = MathHelper.floor_double(player.posY); - int dz = MathHelper.floor_double(player.posZ); + minion.setLocationAndAngles(sx, sy, sz, this.world.rand.nextFloat() * 360.0F, 0.0F); + minion.makeBossMinion(); - if (worldObj.canBlockSeeTheSky(dx, dy, dz)) - { - player.attackEntityFrom(DamageSource.anvil, 3); + if (minion.getCanSpawnHere()) { + this.world.spawnEntity(minion); + minion.spawnExplosionParticle(); } - } - - // also suck up mini ghasts - List ghastsBelow = worldObj.getEntitiesWithinAABB(EntityTFMiniGhast.class, below); - for (EntityTFMiniGhast ghast : ghastsBelow) - { - ghast.motionY += 1; + if (++spawns >= maxSpawns) { + break; + } } } - /** - * Make a tear particle fall off the ghast - */ - private void shedTear() - { - TwilightForestMod.proxy.spawnParticle(this.worldObj, "bosstear", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - 0.25D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); - } + @Override + protected void updateAITasks() { + super.updateAITasks(); + this.detachHome(); - /** - * Waypoints should be closer to our course than we are now. Try 50 times and take the closest - */ - protected void makeNewWaypoint() - { - - double closestDistance = this.getDistanceSq(this.courseX, this.courseY, this.courseZ); - - for (int i = 0; i < 50; i++) - { - double potentialX = this.posX + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * wanderFactor); - double potentialY = this.courseY + this.rand.nextFloat() * 8.0F - 4.0F; - double potentialZ = this.posZ + (double)((this.rand.nextFloat() * 2.0F - 1.0F) * wanderFactor); - - double offsetX = this.courseX - potentialX; - double offsetY = this.courseY - potentialY; - double offsetZ = this.courseZ - potentialZ; - - double potentialDistanceToCourse = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; - - if (potentialDistanceToCourse < closestDistance) - { - this.waypointX = potentialX; - this.waypointY = potentialY; - this.waypointZ = potentialZ; - - closestDistance = potentialDistanceToCourse; - } + // despawn mini ghasts that are in our AABB + for (EntityTFMiniGhast ghast : world.getEntitiesWithinAABB(EntityTFMiniGhast.class, this.getEntityBoundingBox().grow(1, 1, 1))) { + ghast.spawnExplosionParticle(); + ghast.setDead(); + this.heal(2); } - - - } - - protected void checkAndChangeCourse() { - // check course. - if (courseX == 0 && courseY == 0 && courseZ == 0) - { - changeCourse(); - } - - double offsetX = this.courseX - this.posX; - double offsetY = this.courseY - this.posY; - double offsetZ = this.courseZ - this.posZ; - double distanceToCourse = offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ; - - if (distanceToCourse < 100.0D) - { - changeCourse(); - } - } - - /** - * Change to a new course target - */ - private void changeCourse() { - //System.out.println("Boss changing course"); - - if (this.travelCoords.isEmpty()) - { - //System.out.println("Boss travel coords is empty, making a new list"); - makeTravelPath(); - } - - if (!this.travelCoords.isEmpty()) - { - if (this.currentTravelCoordIndex >= travelCoords.size()) - { - this.currentTravelCoordIndex = 0; - this.travelPathRepetitions++; - - //System.out.println("Tower boss has repeated path " + travelPathRepetitions + " times."); - - // when we're in tantrum mode, this is a good time to check if we need to spawn more ghasts - if (!checkGhastsAtTraps()) - { - this.spawnGhastsAtTraps(); - } + // trap locations? + if (this.trapLocations.isEmpty() && !this.noTrapMode) { + this.scanForTrapsTwice(); + + if (this.trapLocations.isEmpty()) { + this.noTrapMode = true; } - - this.courseX = travelCoords.get(currentTravelCoordIndex).posX; - this.courseY = travelCoords.get(currentTravelCoordIndex).posY + HOVER_ALTITUDE; - this.courseZ = travelCoords.get(currentTravelCoordIndex).posZ; - - this.currentTravelCoordIndex++; } - - } + if (this.isInTantrum()) { + setAttackTarget(null); - /** - * Check if there are at least 4 ghasts near at least 2 traps. Return false if not. - */ - @SuppressWarnings("unchecked") - private boolean checkGhastsAtTraps() { - int trapsWithEnoughGhasts = 0; - - for (ChunkCoordinates trap : this.trapLocations) - { - AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(trap.posX, trap.posY, trap.posZ, trap.posX + 1, trap.posY + 1, trap.posZ + 1).expand(8D, 16D, 8D); - - List nearbyGhasts = worldObj.getEntitiesWithinAABB(EntityTFMiniGhast.class, aabb); - - //System.out.println("Checking for ghasts. There are " + nearbyGhasts.size() + " ghasts near this trap."); - - - if (nearbyGhasts.size() >= 4) - { - trapsWithEnoughGhasts++; + // cry? + if (--this.nextTantrumCry <= 0) { + this.playSound(getHurtSound(null), this.getSoundVolume(), this.getSoundPitch()); + this.nextTantrumCry = 20 + rand.nextInt(30); + } + + if (this.ticksExisted % 10 == 0) { + doTantrumDamageEffects(); } } - - //System.out.println("Checking traps for ghasts. There are " + trapsWithEnoughGhasts + " traps with enough ghasts."); - - return trapsWithEnoughGhasts >= 1; - } - private void makeTravelPath() - { - ArrayList potentialPoints; + private void doTantrumDamageEffects() { + // harm player below + AxisAlignedBB below = this.getEntityBoundingBox().offset(0, -16, 0).grow(0, 16, 0); - int px = MathHelper.floor_double(this.posX); - int py = MathHelper.floor_double(this.posY); - int pz = MathHelper.floor_double(this.posZ); - - if (!this.noTrapMode) - { - // make a copy of the trap locations list - potentialPoints = new ArrayList(this.trapLocations); + for (EntityPlayer player : world.getEntitiesWithinAABB(EntityPlayer.class, below)) { + if (world.canSeeSky(new BlockPos(player))) { + player.attackEntityFrom(DamageSource.ANVIL, 3); + } } - else - { - potentialPoints = new ArrayList(); - potentialPoints.add(new ChunkCoordinates(px + 20, py - HOVER_ALTITUDE, pz)); - potentialPoints.add(new ChunkCoordinates(px, py - HOVER_ALTITUDE, pz - 20)); - potentialPoints.add(new ChunkCoordinates(px - 20, py - HOVER_ALTITUDE, pz)); - potentialPoints.add(new ChunkCoordinates(px, py - HOVER_ALTITUDE, pz + 20)); - - //System.out.println("Adding fake points to the potentials list"); + + // also suck up mini ghasts + for (EntityTFMiniGhast ghast : world.getEntitiesWithinAABB(EntityTFMiniGhast.class, below)) { + ghast.motionY += 1; } - - // put the potential points on our travel coords list in random order - travelCoords.clear(); + } + + /** + * Check if there are at least 4 ghasts near at least 2 traps. Return false if not. + */ + private boolean checkGhastsAtTraps() { + int trapsWithEnoughGhasts = 0; - while (!potentialPoints.isEmpty()) - { - int index = rand.nextInt(potentialPoints.size()); + for (BlockPos trap : this.trapLocations) { + AxisAlignedBB aabb = new AxisAlignedBB(trap, trap.add(1, 1, 1)).grow(8D, 16D, 8D); - travelCoords.add(potentialPoints.get(index)); + List nearbyGhasts = world.getEntitiesWithinAABB(EntityTFMiniGhast.class, aabb); - potentialPoints.remove(index); - } - - if (this.noTrapMode) - { - // if in no trap mode, head back to the middle when we're done - travelCoords.add(new ChunkCoordinates(px, py - HOVER_ALTITUDE, pz)); + if (nearbyGhasts.size() >= 4) { + trapsWithEnoughGhasts++; + } } + + return trapsWithEnoughGhasts >= 1; } - /** - * Spit a fireball - */ + @Override protected void spitFireball() { - double offsetX = this.targetedEntity.posX - this.posX; - double offsetY = this.targetedEntity.boundingBox.minY + (double)(this.targetedEntity.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); - double offsetZ = this.targetedEntity.posZ - this.posZ; - - // fireball sound effect - this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1008, (int)this.posX, (int)this.posY, (int)this.posZ, 0); - - EntityTFUrGhastFireball entityFireball = new EntityTFUrGhastFireball(this.worldObj, this, offsetX, offsetY, offsetZ); - entityFireball.field_92057_e = 1; + double offsetX = this.getAttackTarget().posX - this.posX; + double offsetY = this.getAttackTarget().getEntityBoundingBox().minY + (double) (this.getAttackTarget().height / 2.0F) - (this.posY + (double) (this.height / 2.0F)); + double offsetZ = this.getAttackTarget().posZ - this.posZ; + + EntityTFUrGhastFireball entityFireball = new EntityTFUrGhastFireball(this.world, this, offsetX, offsetY, offsetZ); + entityFireball.explosionPower = 1; double shotSpawnDistance = 8.5D; - Vec3 lookVec = this.getLook(1.0F); - entityFireball.posX = this.posX + lookVec.xCoord * shotSpawnDistance; - entityFireball.posY = this.posY + (double)(this.height / 2.0F) + lookVec.yCoord * shotSpawnDistance; - entityFireball.posZ = this.posZ + lookVec.zCoord * shotSpawnDistance; - this.worldObj.spawnEntityInWorld(entityFireball); - - for (int i = 0; i < 2; i++) - { - entityFireball = new EntityTFUrGhastFireball(this.worldObj, this, offsetX + (rand.nextFloat() - rand.nextFloat()) * 8, offsetY, offsetZ + (rand.nextFloat() - rand.nextFloat()) * 8); - entityFireball.field_92057_e = 1; - entityFireball.posX = this.posX + lookVec.xCoord * shotSpawnDistance; - entityFireball.posY = this.posY + (double)(this.height / 2.0F) + lookVec.yCoord * shotSpawnDistance; - entityFireball.posZ = this.posZ + lookVec.zCoord * shotSpawnDistance; - this.worldObj.spawnEntityInWorld(entityFireball); + Vec3d lookVec = this.getLook(1.0F); + entityFireball.posX = this.posX + lookVec.x * shotSpawnDistance; + entityFireball.posY = this.posY + (double) (this.height / 2.0F) + lookVec.y * shotSpawnDistance; + entityFireball.posZ = this.posZ + lookVec.z * shotSpawnDistance; + this.world.spawnEntity(entityFireball); + + for (int i = 0; i < 2; i++) { + entityFireball = new EntityTFUrGhastFireball(this.world, this, offsetX + (rand.nextFloat() - rand.nextFloat()) * 8, offsetY, offsetZ + (rand.nextFloat() - rand.nextFloat()) * 8); + entityFireball.explosionPower = 1; + entityFireball.posX = this.posX + lookVec.x * shotSpawnDistance; + entityFireball.posY = this.posY + (double) (this.height / 2.0F) + lookVec.y * shotSpawnDistance; + entityFireball.posZ = this.posZ + lookVec.z * shotSpawnDistance; + this.world.spawnEntity(entityFireball); } } - + /** * Scan a few chunks around us for ghast trap blocks and if we find any, add them to our list */ - private void scanForTrapsTwice() - { + private void scanForTrapsTwice() { int scanRangeXZ = 48; int scanRangeY = 32; - int px = MathHelper.floor_double(this.posX); - int py = MathHelper.floor_double(this.posY); - int pz = MathHelper.floor_double(this.posZ); + scanForTraps(scanRangeXZ, scanRangeY, new BlockPos(this)); - scanForTraps(scanRangeXZ, scanRangeY, px, py, pz); - - if (trapLocations.size() > 0) - { + if (trapLocations.size() > 0) { // average the location of the traps we've found, and scan again from there int ax = 0, ay = 0, az = 0; - for(ChunkCoordinates trapCoords : trapLocations) - { - ax += trapCoords.posX; - ay += trapCoords.posY; - az += trapCoords.posZ; + for (BlockPos trapCoords : trapLocations) { + ax += trapCoords.getX(); + ay += trapCoords.getY(); + az += trapCoords.getZ(); } ax /= trapLocations.size(); ay /= trapLocations.size(); az /= trapLocations.size(); - scanForTraps(scanRangeXZ, scanRangeY, ax, ay, az); + scanForTraps(scanRangeXZ, scanRangeY, new BlockPos(ax, ay, az)); } } - /** - * Scan in the specified range for traps - */ - protected void scanForTraps(int scanRangeXZ, int scanRangeY, int px, int py, int pz) { + private void scanForTraps(int scanRangeXZ, int scanRangeY, BlockPos pos) { for (int sx = -scanRangeXZ; sx <= scanRangeXZ; sx++) { for (int sz = -scanRangeXZ; sz <= scanRangeXZ; sz++) { for (int sy = -scanRangeY; sy <= scanRangeY; sy++) { - if (isTrapAt(px + sx, py + sy, pz + sz)) { - // add to list - ChunkCoordinates trapCoords = new ChunkCoordinates(px + sx, py + sy, pz + sz); - if (!trapLocations.contains(trapCoords)) - { - trapLocations.add(trapCoords); - } + BlockPos trapCoords = pos.add(sx, sy, sz); + if (isTrapAt(trapCoords)) { + trapLocations.add(trapCoords); } } } } } - - private boolean isTrapAt(int x, int y, int z) - { - return worldObj.blockExists(x, y, z) - && worldObj.getBlock(x, y, z) == TFBlocks.towerDevice - && (worldObj.getBlockMetadata(x, y, z) == BlockTFTowerDevice.META_GHASTTRAP_INACTIVE || worldObj.getBlockMetadata(x, y, z) == BlockTFTowerDevice.META_GHASTTRAP_ACTIVE); - } - - /** - * Returns true if the entity is on fire. Used by render to add the fire effect on rendering. - */ - @Override - public boolean isBurning() - { - // never burn - return false; - } - - /** - * No point in ever being pushed - */ + + private boolean isTrapAt(BlockPos pos) { + IBlockState inactive = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.GHASTTRAP_INACTIVE); + IBlockState active = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.GHASTTRAP_ACTIVE); + return world.isBlockLoaded(pos) + && (world.getBlockState(pos) == inactive || world.getBlockState(pos) == active); + } + + @Override + public void addTrackingPlayer(EntityPlayerMP player) { + super.addTrackingPlayer(player); + this.bossInfo.addPlayer(player); + } + + @Override + public void removeTrackingPlayer(EntityPlayerMP player) { + super.removeTrackingPlayer(player); + this.bossInfo.removePlayer(player); + } + + @Override + public boolean isBurning() { + return false; + } + @Override public boolean canBePushed() { return false; } - - /** - * Are we throwing a tantrum? - */ - public boolean isInTantrum() - { - return this.dataWatcher.getWatchableObjectByte(DATA_TANTRUM) != (byte)0; - } - - /** - * Sets whether we are throwing a tantrum - */ - public void setInTantrum(boolean par1) - { - this.dataWatcher.updateObject(DATA_TANTRUM, par1 ? Byte.valueOf((byte)-1) : Byte.valueOf((byte)0)); - - // can we just reset this each time it is called? - this.damageUntilNextPhase = 48; - } - - /** - * Returns the volume for the sounds this mob makes. - */ - protected float getSoundVolume() - { - return 16F; - } - - /** - * Gets the pitch of living sounds in living entities. - */ - protected float getSoundPitch() - { - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.5F; - } - /** - * Needed for boss health bar on the client - */ -// @Override -// public int getBossHealth() { -// return this.dataWatcher.getWatchableObjectInt(DATA_BOSSHEALTH); -// } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - nbttagcompound.setBoolean("inTantrum", this.isInTantrum()); - super.writeEntityToNBT(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - this.setInTantrum(nbttagcompound.getBoolean("inTantrum")); - } - - /** - * handles entity death timer, experience orb and particle creation - */ - protected void onDeathUpdate() - { - super.onDeathUpdate(); - - if (this.deathTime == 20 && !worldObj.isRemote) - { - // make chest - ChunkCoordinates chestCoords = this.findChestCoords(); - TFTreasure.darktower_boss.generate(worldObj, null, chestCoords.posX, chestCoords.posY, chestCoords.posZ); - } - } - - /** - * Trigger achievement when killed - */ + public boolean isInTantrum() { + return dataManager.get(DATA_TANTRUM); + } + + public void setInTantrum(boolean inTantrum) { + dataManager.set(DATA_TANTRUM, inTantrum); + resetDamageUntilNextPhase(); + } + + @Override + protected float getSoundVolume() { + return 16F; + } + + @Override + protected float getSoundPitch() { + return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.5F; + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + compound.setBoolean("inTantrum", this.isInTantrum()); + super.writeEntityToNBT(compound); + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightProgressUrghast); - + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setInTantrum(compound.getBoolean("inTantrum")); + if (this.hasCustomName()) { + this.bossInfo.setName(this.getDisplayName()); } + } + @Override + protected void onDeathUpdate() { + super.onDeathUpdate(); + if (this.deathTime == 20 && !world.isRemote) { + TFTreasure.darktower_boss.generateChest(world, findChestCoords(), false); + } + } + + @Override + public void onDeath(DamageSource cause) { + super.onDeath(cause); // mark the tower as defeated - if (!worldObj.isRemote && worldObj.provider instanceof WorldProviderTwilightForest) { - ChunkCoordinates chestCoords = this.findChestCoords(); - int dx = chestCoords.posX; - int dy = chestCoords.posY; - int dz = chestCoords.posZ; + if (!world.isRemote) { + TFWorld.markStructureConquered(world, findChestCoords(), TFFeature.DARK_TOWER); + } + } - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)worldObj.provider).getChunkProvider(); - TFFeature nearbyFeature = ((TFWorldChunkManager)worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, worldObj); + private BlockPos findChestCoords() { + if (trapLocations.size() > 0) { + // average the location of the traps we've found, and scan again from there + int ax = 0, ay = 0, az = 0; - if (nearbyFeature == TFFeature.darkTower) { - chunkProvider.setStructureConquered(dx, dy, dz, true); + for (BlockPos trapCoords : trapLocations) { + ax += trapCoords.getX(); + ay += trapCoords.getY(); + az += trapCoords.getZ(); } - } - } - private ChunkCoordinates findChestCoords() { - if (trapLocations.size() > 0) - { - // average the location of the traps we've found, and scan again from there - int ax = 0, ay = 0, az = 0; + ax /= trapLocations.size(); + ay /= trapLocations.size(); + az /= trapLocations.size(); - for(ChunkCoordinates trapCoords : trapLocations) - { - ax += trapCoords.posX; - ay += trapCoords.posY; - az += trapCoords.posZ; - } - ax /= trapLocations.size(); - ay /= trapLocations.size(); - az /= trapLocations.size(); + return new BlockPos(ax, ay + 2, az); + } else { + return new BlockPos(this); + } + } + // Don't attack (or even think about attacking) things while we're throwing a tantrum + @Override + protected boolean shouldAttack(EntityLivingBase living) { + return !this.isInTantrum(); + } - return new ChunkCoordinates(ax, ay + 2, az); - } - else - { - return new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); - } + @Override + public boolean isNonBoss() { + return false; } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFUrGhastFireball.java b/src/main/java/twilightforest/entity/boss/EntityTFUrGhastFireball.java index 8bca4dedb7..15e776a7a8 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFUrGhastFireball.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFUrGhastFireball.java @@ -1,34 +1,47 @@ package twilightforest.entity.boss; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.projectile.EntityFireball; import net.minecraft.entity.projectile.EntityLargeFireball; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; +import twilightforest.entity.ITFProjectile; -public class EntityTFUrGhastFireball extends EntityLargeFireball { +public class EntityTFUrGhastFireball extends EntityLargeFireball implements ITFProjectile { - public EntityTFUrGhastFireball(World worldObj, EntityTFUrGhast entityTFTowerBoss, double x, double y, double z) - { - super(worldObj, entityTFTowerBoss, x, y, z); + public EntityTFUrGhastFireball(World world, EntityTFUrGhast entityTFTowerBoss, double x, double y, double z) { + super(world, entityTFTowerBoss, x, y, z); } - - /** - * Called when this EntityFireball hits a block or entity. - */ - protected void onImpact(MovingObjectPosition par1MovingObjectPosition) - { - if (!this.worldObj.isRemote && !(par1MovingObjectPosition.entityHit instanceof EntityFireball)) - { - if (par1MovingObjectPosition.entityHit != null) - { - par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 16); - } + // [VanillaCopy] super, edits noted + @Override + protected void onImpact(RayTraceResult result) { + // TF - don't collide with other fireballs + if (!this.world.isRemote && !(result.entityHit instanceof EntityFireball)) { + if (result.entityHit != null) { + // TF - up damage by 10 + result.entityHit.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 16.0F); + this.applyEnchantments(this.shootingEntity, result.entityHit); + } - this.worldObj.newExplosion((Entity)null, this.posX, this.posY, this.posZ, (float)this.field_92057_e, true, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); - this.setDead(); - } - } + boolean flag = ForgeEventFactory.getMobGriefingEvent(this.world, this.shootingEntity); + this.world.newExplosion(null, this.posX, this.posY, this.posZ, (float) this.explosionPower, flag, flag); + this.setDead(); + } + } + + @Override + public Entity getThrower() { + return this.shootingEntity; + } + + @Override + public void setThrower(Entity entity) { + if (entity instanceof EntityLivingBase) { + this.shootingEntity = (EntityLivingBase) entity; + } + } } diff --git a/src/main/java/twilightforest/entity/boss/EntityTFYetiAlpha.java b/src/main/java/twilightforest/entity/boss/EntityTFYetiAlpha.java index 875546d1ef..396abe3745 100644 --- a/src/main/java/twilightforest/entity/boss/EntityTFYetiAlpha.java +++ b/src/main/java/twilightforest/entity/boss/EntityTFYetiAlpha.java @@ -1,599 +1,446 @@ package twilightforest.entity.boss; -import java.util.ArrayList; - import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIArrowAttack; +import net.minecraft.entity.ai.EntityAIAttackRanged; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.item.Item; +import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.BossInfo; +import net.minecraft.world.BossInfoServer; +import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraftforge.event.ForgeEventFactory; import twilightforest.TFFeature; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; +import twilightforest.client.particle.TFParticleType; +import twilightforest.entity.IHostileMount; import twilightforest.entity.ai.EntityAIStayNearHome; import twilightforest.entity.ai.EntityAITFThrowRider; import twilightforest.entity.ai.EntityAITFYetiRampage; import twilightforest.entity.ai.EntityAITFYetiTired; -import twilightforest.item.TFItems; -import twilightforest.world.ChunkProviderTwilightForest; -import twilightforest.world.TFWorldChunkManager; -import twilightforest.world.WorldProviderTwilightForest; +import twilightforest.enums.BossVariant; +import twilightforest.util.EntityUtil; +import twilightforest.util.WorldUtil; +import twilightforest.world.TFWorld; + +import javax.annotation.Nullable; -public class EntityTFYetiAlpha extends EntityMob implements IRangedAttackMob -{ +public class EntityTFYetiAlpha extends EntityMob implements IRangedAttackMob, IHostileMount { - - private static final int RAMPAGE_FLAG = 16; - private static final int TIRED_FLAG = 17; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/yeti_alpha"); + private static final DataParameter RAMPAGE_FLAG = EntityDataManager.createKey(EntityTFYetiAlpha.class, DataSerializers.BYTE); + private static final DataParameter TIRED_FLAG = EntityDataManager.createKey(EntityTFYetiAlpha.class, DataSerializers.BYTE); + private final BossInfoServer bossInfo = new BossInfoServer(getDisplayName(), BossInfo.Color.WHITE, BossInfo.Overlay.PROGRESS); private int collisionCounter; private boolean canRampage; + public EntityTFYetiAlpha(World world) { + super(world); + this.setSize(3.8F, 5.0F); + this.experienceValue = 317; + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAITFYetiTired(this, 100)); + this.tasks.addTask(2, new EntityAIStayNearHome(this, 2.0F)); + this.tasks.addTask(3, new EntityAITFYetiRampage(this, 10, 180)); + this.tasks.addTask(4, new EntityAIAttackRanged(this, 1.0D, 40, 40, 40.0F){ + @Override + public boolean shouldExecute() { + return getRNG().nextInt(50) > 0 && getAttackTarget() != null && getDistanceSq(getAttackTarget()) >= 16D && super.shouldExecute(); // Give us a chance to move to the next AI + } + }); + this.tasks.addTask(4, new EntityAITFThrowRider(this, 1.0D, false) { + @Override + protected void checkAndPerformAttack(EntityLivingBase p_190102_1_, double p_190102_2_) { + super.checkAndPerformAttack(p_190102_1_, p_190102_2_); + if (!getPassengers().isEmpty()) + playSound(TFSounds.ALPHAYETI_GRAB, 4F, 0.75F + getRNG().nextFloat() * 0.25F); + } + + @Override + public void resetTask() { + if (!getPassengers().isEmpty()) + playSound(TFSounds.ALPHAYETI_THROW, 4F, 0.75F + getRNG().nextFloat() * 0.25F); + super.resetTask(); + } + }); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 2.0D)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true)); + } + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(RAMPAGE_FLAG, (byte) 0); + dataManager.register(TIRED_FLAG, (byte) 0); + } - public EntityTFYetiAlpha(World par1World) - { - super(par1World); - this.setSize(3.8F, 5.0F); + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(200.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.38D); + this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(1.0D); + this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(40.0D); + } - - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(1, new EntityAITFYetiTired(this, 100)); - this.tasks.addTask(2, new EntityAITFThrowRider(this, 1.0F)); - this.tasks.addTask(3, new EntityAIStayNearHome(this, 2.0F)); - this.tasks.addTask(4, new EntityAITFYetiRampage(this, 10, 180)); - - this.tasks.addTask(5, new EntityAIArrowAttack(this, 1.0D, 40, 40, 40.0F)); - this.tasks.addTask(6, new EntityAIWander(this, 2.0F)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, false)); - - this.experienceValue = 317; - - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(RAMPAGE_FLAG, Byte.valueOf((byte)0)); - this.dataWatcher.addObject(TIRED_FLAG, Byte.valueOf((byte)0)); - } - - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(200.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.38D); // movement speed - this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(1.0D); - this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(40.0D); - } - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - if (this.riddenByEntity != null) - { - - // stop player sneaking so that they can't dismount! - if (this.riddenByEntity.isSneaking()) - { - //System.out.println("Pinch beetle sneaking detected!"); - - this.riddenByEntity.setSneaking(false); - } - } - else - { - - } - - super.onLivingUpdate(); - - // look at things we are holding - if (this.riddenByEntity != null) - { - this.getLookHelper().setLookPositionWithEntity(riddenByEntity, 100F, 100F); - } - - if (this.isCollided) { - this.collisionCounter++; - } - - if (this.collisionCounter >= 15) { - if (!this.worldObj.isRemote) { - this.destroyBlocksInAABB(this.boundingBox); - } - this.collisionCounter = 0; - } - - // add rampage snow effects - if (this.isRampaging()) { - - float rotation = this.ticksExisted / 10F; - - - for (int i = 0; i < 20; i++) { - addSnowEffect(rotation + (i * 50), i + rotation); - } - - // also swing limbs - this.limbSwingAmount += 0.6; - } - - //when tired, spawn tears/sweat - if (this.isTired()) - { - for (int i = 0; i < 20; i++) - { - this.worldObj.spawnParticle("splash", this.posX + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, this.posY + this.getEyeHeight(), this.posZ + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, (rand.nextFloat() - 0.5F) * 0.75F, 0, (rand.nextFloat() - 0.5F) * 0.75F); - } - } - - } + public void onLivingUpdate() { + if (!this.getPassengers().isEmpty() && this.getPassengers().get(0).isSneaking()) { + this.getPassengers().get(0).setSneaking(false); + } + + super.onLivingUpdate(); + + if (this.isBeingRidden()) { + this.getLookHelper().setLookPositionWithEntity(getPassengers().get(0), 100F, 100F); + } + + if (!world.isRemote) { + bossInfo.setPercent(getHealth() / getMaxHealth()); + + if (this.collided) { + this.collisionCounter++; + } + + if (this.collisionCounter >= 15) { + this.destroyBlocksInAABB(this.getEntityBoundingBox()); + this.collisionCounter = 0; + } + } else { + if (this.isRampaging()) { + float rotation = this.ticksExisted / 10F; + for (int i = 0; i < 20; i++) { + addSnowEffect(rotation + (i * 50), i + rotation); + } + + // also swing limbs + this.limbSwingAmount += 0.6; + } + + if (this.isTired()) { + for (int i = 0; i < 20; i++) { + this.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, this.posX + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, this.posY + this.getEyeHeight(), this.posZ + (this.rand.nextDouble() - 0.5D) * this.width * 0.5, (rand.nextFloat() - 0.5F) * 0.75F, 0, (rand.nextFloat() - 0.5F) * 0.75F); + } + } + } + } private void addSnowEffect(float rotation, float hgt) { double px = 3F * Math.cos(rotation); double py = hgt % 5F; double pz = 3F * Math.sin(rotation); - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "snowstuff", this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); + + TwilightForestMod.proxy.spawnParticle(TFParticleType.SNOW, this.lastTickPosX + px, this.lastTickPosY + py, this.lastTickPosZ + pz, 0, 0, 0); + } + + @Override + public void setAttackTarget(@Nullable EntityLivingBase entity) { + if (entity != null && entity != getAttackTarget()) + playSound(TFSounds.ALPHAYETI_ALERT, 4F, 0.5F + getRNG().nextFloat() * 0.5F); + super.setAttackTarget(entity); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float amount) { + // no arrow damage when in ranged mode + if (!this.canRampage && !this.isTired() && source.isProjectile()) { + return false; + } + + this.canRampage = true; + return super.attackEntityFrom(source, amount); + } + + @Nullable + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.ALPHAYETI_GROWL; + } + + @Override + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return TFSounds.ALPHAYETI_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.ALPHAYETI_DIE; + } + + @Override + protected float getSoundPitch() { + return 0.5F + getRNG().nextFloat() * 0.5F; + } + + @Override + protected float getSoundVolume() { + return 4F; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + public void updatePassenger(Entity passenger) { + Vec3d riderPos = this.getRiderPosition(); + passenger.setPosition(riderPos.x, riderPos.y, riderPos.z); + } + + @Override + public double getMountedYOffset() { + return 5.75D; } - /** - * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. - */ - @Override - public boolean interact(EntityPlayer par1EntityPlayer) - { - if (super.interact(par1EntityPlayer)) - { - return true; - } - else if (!this.worldObj.isRemote && (this.riddenByEntity == null || this.riddenByEntity == par1EntityPlayer)) - { - par1EntityPlayer.mountEntity(this); - return true; - } - else - { - return false; - } - } - - /** - * Pick up things we attack! + * Used to both get a rider position and to push out of blocks */ - @Override - public boolean attackEntityAsMob(Entity par1Entity) - { - if (this.riddenByEntity == null && par1Entity.ridingEntity == null) - { - par1Entity.mountEntity(this); - } - - return super.attackEntityAsMob(par1Entity); - } - - - /** - * Called when the entity is attacked. - */ - public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) - { - // no arrow damage when in ranged mode - if (!this.canRampage && !this.isTired() && par1DamageSource.isProjectile()) { - return false; - } - - boolean success = super.attackEntityFrom(par1DamageSource, par2); - - this.canRampage = true; - - return success; - } - - /** - * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param - * par2 - Level of Looting used to kill this mob. - */ - @Override - protected void dropFewItems(boolean flag, int looting) { - Item fur = getDropItem(); - if(fur != null) - { - int drops = 6 + rand.nextInt(6 + looting); - for(int d = 0; d < drops; d++) - { - this.dropItem(fur, 1); - } - - } - - Item bombs = TFItems.iceBomb; - int drops = 6 + rand.nextInt(6 + looting); - for(int d = 0; d < drops; d++) - { - this.dropItem(bombs, 1); + private Vec3d getRiderPosition() { + if (isBeingRidden()) { + float distance = 0.4F; + + double dx = Math.cos((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; + double dz = Math.sin((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; + + return new Vec3d(this.posX + dx, this.posY + this.getMountedYOffset() + this.getPassengers().get(0).getYOffset(), this.posZ + dz); + } else { + return new Vec3d(this.posX, this.posY, this.posZ); } + } - } - - @Override - protected Item getDropItem() - { - return TFItems.alphaFur; - } - - /** - * Put the player out in front of where we are - */ - @Override - public void updateRiderPosition() - { - if (this.riddenByEntity != null) - { - Vec3 riderPos = this.getRiderPosition(); - - this.riddenByEntity.setPosition(riderPos.xCoord, riderPos.yCoord, riderPos.zCoord); - } - } - - /** - * Returns the Y offset from the entity's position for any entity riding this one. - */ - @Override - public double getMountedYOffset() - { - return 5.75D; - } - - /** - * Used to both get a rider position and to push out of blocks - */ - public Vec3 getRiderPosition() - { - if (this.riddenByEntity != null) - { - float distance = 0.4F; - - double var1 = Math.cos((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; - double var3 = Math.sin((this.rotationYaw + 90) * Math.PI / 180.0D) * distance; - - return Vec3.createVectorHelper(this.posX + var1, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3); - } - else - { - return Vec3.createVectorHelper(this.posX, this.posY, this.posZ); - } - } - - /** - * If a rider of this entity can interact with this entity. Should return true on the - * ridden entity if so. - * - * @return if the entity can be interacted with from a rider - */ - public boolean canRiderInteract() - { - return true; - } - - /** - * Destroys all blocks that aren't associated with 'The End' inside the given bounding box. - */ - public boolean destroyBlocksInAABB(AxisAlignedBB par1AxisAlignedBB) - { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - boolean wasBlocked = false; - for (int dx = minX; dx <= maxX; ++dx) - { - for (int dy = minY; dy <= maxY; ++dy) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - Block currentID = this.worldObj.getBlock(dx, dy, dz); - - if (currentID != Blocks.air) - { - int currentMeta = this.worldObj.getBlockMetadata(dx, dy, dz); - - if (currentID != Blocks.obsidian && currentID != Blocks.end_stone && currentID != Blocks.bedrock) - { - this.worldObj.setBlock(dx, dy, dz, Blocks.air, 0, 2); - - // here, this effect will have to do - worldObj.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - } - else - { - wasBlocked = true; - } - } - } - } - } - - return wasBlocked; - } - - - - public void makeRandomBlockFall() { - // begin turning blocks into falling blocks - makeRandomBlockFall(30); - } + @Override + public boolean canRiderInteract() { + return true; + } + + public void destroyBlocksInAABB(AxisAlignedBB box) { + if (ForgeEventFactory.getMobGriefingEvent(world, this)) { + for (BlockPos pos : WorldUtil.getAllInBB(box)) { + if (EntityUtil.canDestroyBlock(world, pos, this)) { + world.destroyBlock(pos, false); + } + } + } + } + public void makeRandomBlockFall() { + // begin turning blocks into falling blocks + makeRandomBlockFall(30); + } private void makeRandomBlockFall(int range) { // find a block nearby - int bx = MathHelper.floor_double(this.posX) + this.getRNG().nextInt(range) - this.getRNG().nextInt(range); - int bz = MathHelper.floor_double(this.posZ) + this.getRNG().nextInt(range) - this.getRNG().nextInt(range); - int by = MathHelper.floor_double(this.posY + this.getEyeHeight()); + int bx = MathHelper.floor(this.posX) + this.getRNG().nextInt(range) - this.getRNG().nextInt(range); + int bz = MathHelper.floor(this.posZ) + this.getRNG().nextInt(range) - this.getRNG().nextInt(range); + int by = MathHelper.floor(this.posY + this.getEyeHeight()); - makeBlockFallAbove(bx, bz, by); + makeBlockFallAbove(new BlockPos(bx, bz, by)); } - - private void makeBlockFallAbove(int bx, int bz, int by) { - if (worldObj.isAirBlock(bx, by, bz)) { - for (int i = 1; i < 30; i++) { - if (!worldObj.isAirBlock(bx, by + i, bz)) { - makeBlockFall(bx, by + i, bz); - break; - } - } - } + private void makeBlockFallAbove(BlockPos pos) { + if (world.isAirBlock(pos)) { + for (int i = 1; i < 30; i++) { + BlockPos up = pos.up(i); + if (!world.isAirBlock(up)) { + makeBlockFall(up); + break; + } + } + } } - public void makeNearbyBlockFall() { - makeRandomBlockFall(15); + makeRandomBlockFall(15); } - public void makeBlockAboveTargetFall() { if (this.getAttackTarget() != null) { - - int bx = MathHelper.floor_double(this.getAttackTarget().posX); - int bz = MathHelper.floor_double(this.getAttackTarget().posZ); - int by = MathHelper.floor_double(this.getAttackTarget().posY + this.getAttackTarget().getEyeHeight()); - makeBlockFallAbove(bx, bz, by); + int bx = MathHelper.floor(this.getAttackTarget().posX); + int bz = MathHelper.floor(this.getAttackTarget().posZ); + int by = MathHelper.floor(this.getAttackTarget().posY + this.getAttackTarget().getEyeHeight()); + + makeBlockFallAbove(new BlockPos(bx, bz, by)); } } + private void makeBlockFall(BlockPos pos) { + world.setBlockState(pos, Blocks.PACKED_ICE.getDefaultState()); + world.playEvent(2001, pos, Block.getStateId(Blocks.PACKED_ICE.getDefaultState())); - private void makeBlockFall(int bx, int by, int bz) { - //worldObj.setBlock(bx, by, bz, Blocks.gravel); - - //EntityFallingBlock sand; - - Block currentID = this.worldObj.getBlock(bx, by, bz); - int currentMeta = this.worldObj.getBlockMetadata(bx, by, bz); - - // just set it to ice for now - worldObj.setBlock(bx, by, bz, Blocks.packed_ice); - - worldObj.playAuxSFX(2001, bx, by, bz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - - - EntityTFFallingIce ice = new EntityTFFallingIce(worldObj, bx, by - 3, bz); - worldObj.spawnEntityInWorld(ice); - - - } - - - - /** - * Attack the specified entity using a ranged attack. - */ - public void attackEntityWithRangedAttack(EntityLivingBase target, float par2) - { - if (!this.canRampage) { - - EntityTFIceBomb ice = new EntityTFIceBomb(this.worldObj, this); - - double d0 = target.posX - this.posX; - double d1 = target.posY + (double)target.getEyeHeight() - 1.100000023841858D - target.posY; - double d2 = target.posZ - this.posZ; - float f1 = MathHelper.sqrt_double(d0 * d0 + d2 * d2) * 0.2F; - ice.setThrowableHeading(d0, d1 + (double)f1, d2, 0.75F, 12.0F); - - this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); - this.worldObj.spawnEntityInWorld(ice); - } - } - - public boolean canDespawn() { - return false; - } - - public boolean canRampage() { - return this.canRampage; - } - - /** - * Set whether this yeti is currently in rampage mode. - */ - public void setRampaging(boolean par1) - { - this.getDataWatcher().updateObject(RAMPAGE_FLAG, Byte.valueOf((byte)(par1 ? 1 : 0))); - } - - /** - * Return whether this yeti is currently in rampage mode. - */ - public boolean isRampaging() - { - return this.getDataWatcher().getWatchableObjectByte(RAMPAGE_FLAG) == 1; - } - - /** - * Set whether this yeti is currently tired. - */ - public void setTired(boolean par1) - { - this.getDataWatcher().updateObject(TIRED_FLAG, Byte.valueOf((byte)(par1 ? 1 : 0))); - this.canRampage = false; - } - - /** - * Return whether this yeti is currently tired. - */ - public boolean isTired() - { - return this.getDataWatcher().getWatchableObjectByte(TIRED_FLAG) == 1; - } - - /** - * Called when the mob is falling. Calculates and applies fall damage. - */ - protected void fall(float par1) - { - super.fall(par1); - - if (this.isRampaging()) { - // make jump effects - this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); - - int i = MathHelper.floor_double(this.posX); - int j = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset); - int k = MathHelper.floor_double(this.posZ); - - this.worldObj.playAuxSFX(2006, i, j, k, 20); - this.worldObj.playAuxSFX(2006, i, j, k, 30); - - // hit everything around - if (!this.worldObj.isRemote) { - hitNearbyEntities(); - } - - } - } - - - @SuppressWarnings("unchecked") - private void hitNearbyEntities() { - ArrayList nearby = new ArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(5, 0, 5))); - - for (Entity entity : nearby) { - if (entity instanceof EntityLivingBase) { - - boolean hit = entity.attackEntityFrom(DamageSource.causeMobDamage(this), 5F); - - if (hit) - { - entity.motionY += 0.4000000059604645D; - } + EntityTFFallingIce ice = new EntityTFFallingIce(world, pos.getX(), pos.getY() - 3, pos.getZ()); + world.spawnEntity(ice); + } + + @Override + public void attackEntityWithRangedAttack(EntityLivingBase target, float distanceFactor) { + if (!this.canRampage) { + EntityTFIceBomb ice = new EntityTFIceBomb(this.world, this); + + // [VanillaCopy] Part of EntitySkeleton.attackEntityWithRangedAttack + double d0 = target.posX - this.posX; + double d1 = target.getEntityBoundingBox().minY + (double) (target.height / 3.0F) - ice.posY; + double d2 = target.posZ - this.posZ; + double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); + ice.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.world.getDifficulty().getId() * 4)); + + this.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.world.spawnEntity(ice); + } + } + + @Override + public void setSwingingArms(boolean swingingArms) {} // todo 1.12 + + @Override + public boolean canDespawn() { + return false; + } + + @Override + protected void despawnEntity() { + if (world.getDifficulty() == EnumDifficulty.PEACEFUL) { + if (hasHome()) { + world.setBlockState(getHomePosition(), TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.ALPHA_YETI)); } + setDead(); + } else { + super.despawnEntity(); } } - - /** - * Trigger achievement when killed - */ + public boolean canRampage() { + return this.canRampage; + } + + public void setRampaging(boolean rampaging) { + dataManager.set(RAMPAGE_FLAG, (byte) (rampaging ? 1 : 0)); + } + + public boolean isRampaging() { + return dataManager.get(RAMPAGE_FLAG) == 1; + } + + public void setTired(boolean tired) { + dataManager.set(TIRED_FLAG, (byte) (tired ? 1 : 0)); + this.canRampage = false; + } + + public boolean isTired() { + return dataManager.get(TIRED_FLAG) == 1; + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightProgressYeti); + public void fall(float distance, float multiplier) { + super.fall(distance, multiplier); + + if (!this.world.isRemote && isRampaging()) { + this.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + hitNearbyEntities(); } - - // mark the lair as defeated - if (!worldObj.isRemote) { - int dx = MathHelper.floor_double(this.posX); - int dy = MathHelper.floor_double(this.posY); - int dz = MathHelper.floor_double(this.posZ); - - if (worldObj.provider instanceof WorldProviderTwilightForest){ - ChunkProviderTwilightForest chunkProvider = ((WorldProviderTwilightForest)worldObj.provider).getChunkProvider(); - TFFeature nearbyFeature = ((TFWorldChunkManager)worldObj.provider.worldChunkMgr).getFeatureAt(dx, dz, worldObj); - - if (nearbyFeature == TFFeature.yetiCave) { - chunkProvider.setStructureConquered(dx, dy, dz, true); - } + } + + private void hitNearbyEntities() { + for (EntityLivingBase entity : this.world.getEntitiesWithinAABB(EntityLivingBase.class, this.getEntityBoundingBox().grow(5, 0, 5))) { + if (entity != this && entity.attackEntityFrom(DamageSource.causeMobDamage(this), 5F)) { + entity.motionY += 0.4; } } } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound) - { - ChunkCoordinates home = this.getHomePosition(); - nbttagcompound.setTag("Home", newDoubleNBTList(new double[] { - home.posX, home.posY, home.posZ - })); - nbttagcompound.setBoolean("HasHome", this.hasHome()); - super.writeEntityToNBT(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound) - { - super.readEntityFromNBT(nbttagcompound); - if (nbttagcompound.hasKey("Home", 9)) - { - NBTTagList nbttaglist = nbttagcompound.getTagList("Home", 6); - int hx = (int) nbttaglist.func_150309_d(0); - int hy = (int) nbttaglist.func_150309_d(1); - int hz = (int) nbttaglist.func_150309_d(2); - this.setHomeArea(hx, hy, hz, 30); - } - if (!nbttagcompound.getBoolean("HasHome")) - { - this.detachHome(); - } - } + @Override + public void onDeath(DamageSource cause) { + super.onDeath(cause); + // mark the lair as defeated + if (!world.isRemote) { + TFWorld.markStructureConquered(world, new BlockPos(this), TFFeature.YETI_CAVE); + } + } + + @Override + public void setCustomNameTag(String name) { + super.setCustomNameTag(name); + this.bossInfo.setName(this.getDisplayName()); + } + + @Override + public void addTrackingPlayer(EntityPlayerMP player) { + super.addTrackingPlayer(player); + this.bossInfo.addPlayer(player); + } + + @Override + public void removeTrackingPlayer(EntityPlayerMP player) { + super.removeTrackingPlayer(player); + this.bossInfo.removePlayer(player); + } + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + BlockPos home = this.getHomePosition(); + compound.setTag("Home", newDoubleNBTList(home.getX(), home.getY(), home.getZ())); + compound.setBoolean("HasHome", this.hasHome()); + super.writeEntityToNBT(compound); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + if (compound.hasKey("Home", 9)) { + NBTTagList nbttaglist = compound.getTagList("Home", 6); + int hx = (int) nbttaglist.getDoubleAt(0); + int hy = (int) nbttaglist.getDoubleAt(1); + int hz = (int) nbttaglist.getDoubleAt(2); + this.setHomePosAndDistance(new BlockPos(hx, hy, hz), 30); + } + if (!compound.getBoolean("HasHome")) { + this.detachHome(); + } + if (this.hasCustomName()) { + this.bossInfo.setName(this.getDisplayName()); + } + } + + @Override + public boolean isNonBoss() { + return false; + } } diff --git a/src/main/java/twilightforest/entity/boss/HydraHeadContainer.java b/src/main/java/twilightforest/entity/boss/HydraHeadContainer.java index 41931e643a..4fcaf2bf70 100644 --- a/src/main/java/twilightforest/entity/boss/HydraHeadContainer.java +++ b/src/main/java/twilightforest/entity/boss/HydraHeadContainer.java @@ -1,398 +1,365 @@ package twilightforest.entity.boss; -import java.util.List; - +import com.google.common.collect.ImmutableMap; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.boss.EntityDragonPart; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.entity.MultiPartEntityPart; +import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.EnumDifficulty; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; + +import javax.annotation.Nullable; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; /** * This class holds the state data for a single hydra head - * - * @author Ben * + * @author Ben */ public class HydraHeadContainer { - + // balancing factors - private static int FLAME_BURN_FACTOR = 3; - private static int FLAME_DAMAGE = 19; - private static int BITE_DAMAGE = 48; + private static final int FLAME_BURN_FACTOR = 3; + private static final int FLAME_DAMAGE = 19; + private static final int BITE_DAMAGE = 48; private static double FLAME_BREATH_TRACKING_SPEED = 0.04D; - - public static final int NEXT_AUTOMATIC = -1; - - public static final int STATE_IDLE = 0; - public static final int STATE_BITE_BEGINNING = 1; - public static final int STATE_BITE_READY = 2; - public static final int STATE_BITE_BITING = 3; - public static final int STATE_BITE_ENDING = 4; - public static final int STATE_FLAME_BEGINNING = 5; - public static final int STATE_FLAME_BREATHING = 6; - public static final int STATE_FLAME_ENDING = 7; - public static final int STATE_MORTAR_BEGINNING = 8; - public static final int STATE_MORTAR_LAUNCH = 9; - public static final int STATE_MORTAR_ENDING = 10; - public static final int STATE_DYING = 11; - public static final int STATE_DEAD = 12; - public static final int STATE_ATTACK_COOLDOWN = 13; - public static final int STATE_BORN = 14; - public static final int STATE_ROAR_START = 15; - public static final int STATE_ROAR_RAWR = 16; - - - public static final int NUM_STATES = 17; + + private static final State NEXT_AUTOMATIC = null; + + enum State { + IDLE(10), + + BITE_BEGINNING(40), + BITE_READY(80), + BITING(7), + BITE_ENDING(40), + + FLAME_BEGINNING(40), + FLAMING(100), + FLAME_ENDING(30), + + MORTAR_BEGINNING(40), + MORTAR_SHOOTING(25), + MORTAR_ENDING(30), + + DYING(70), + DEAD(20), + + ATTACK_COOLDOWN(80), + + BORN(20), + ROAR_START(10), + ROAR_RAWR(50); + + private static final Map NEXT_STATE; + public final int duration; + + State(int duration) { + this.duration = duration; + } + + static { + EnumMap b = new EnumMap<>(State.class); + b.put(IDLE, IDLE); + + b.put(BITE_BEGINNING, BITE_READY); + b.put(BITE_READY, BITING); + b.put(BITING, BITE_ENDING); + b.put(BITE_ENDING, ATTACK_COOLDOWN); + + b.put(FLAME_BEGINNING, FLAMING); + b.put(FLAMING, FLAME_ENDING); + b.put(FLAME_ENDING, ATTACK_COOLDOWN); + + b.put(MORTAR_BEGINNING, MORTAR_SHOOTING); + b.put(MORTAR_SHOOTING, MORTAR_ENDING); + b.put(MORTAR_ENDING, ATTACK_COOLDOWN); + + b.put(ATTACK_COOLDOWN, IDLE); + + b.put(DYING, DEAD); + + b.put(DEAD, DEAD); + + b.put(BORN, ROAR_START); + b.put(ROAR_START, ROAR_RAWR); + b.put(ROAR_RAWR, IDLE); + NEXT_STATE = ImmutableMap.copyOf(b); + } + } public EntityTFHydraHead headEntity; - public EntityTFHydraNeck necka; - public EntityTFHydraNeck neckb; - public EntityTFHydraNeck neckc; - public EntityTFHydraNeck neckd; - public EntityTFHydraNeck necke; - + public final EntityTFHydraNeck necka; + public final EntityTFHydraNeck neckb; + public final EntityTFHydraNeck neckc; + public final EntityTFHydraNeck neckd; + public final EntityTFHydraNeck necke; + public Entity targetEntity; - public double targetX; - public double targetY; - public double targetZ; + private double targetX; + private double targetY; + private double targetZ; + + private State prevState; + private State currentState; + private State nextState = NEXT_AUTOMATIC; - public int prevState; - public int currentState; - public int nextState = NEXT_AUTOMATIC; - - public boolean didRoar; - public boolean isSecondaryAttacking; - - public int ticksNeeded; - public int ticksProgress; - - public final int headNum; - - public int damageTaken; - public int respawnCounter; - - public final EntityTFHydra hydraObj; - - public int[] nextStates; - public int[] stateDurations; - public float[][] stateNeckLength; - public float[][] stateXRotations; - public float[][] stateYRotations; - public float[][] stateMouthOpen; - - - public HydraHeadContainer(EntityTFHydra hydra, int number, boolean startActive) - { + + private int ticksNeeded; + private int ticksProgress; + + private final int headNum; + + private int damageTaken; + private int respawnCounter; + + private final EntityTFHydra hydra; + + private final Map[] stateNeckLength; + private final Map[] stateXRotations; + private final Map[] stateYRotations; + private final Map[] stateMouthOpen; + + @SuppressWarnings("unchecked") + public HydraHeadContainer(EntityTFHydra hydra, int number, boolean startActive) { this.headNum = number; - this.hydraObj = hydra; - + this.hydra = hydra; + this.damageTaken = 0; this.respawnCounter = -1; - this.didRoar = false; - - // is this a good place to initialize the necks? - necka = new EntityTFHydraNeck(hydraObj, "neck" + headNum + "a", 2F, 2F); - neckb = new EntityTFHydraNeck(hydraObj, "neck" + headNum + "b", 2F, 2F); - neckc = new EntityTFHydraNeck(hydraObj, "neck" + headNum + "c", 2F, 2F); - neckd = new EntityTFHydraNeck(hydraObj, "neck" + headNum + "d", 2F, 2F); - necke = new EntityTFHydraNeck(hydraObj, "neck" + headNum + "e", 2F, 2F); - - // state variables, what state is next in the chain - nextStates = new int[NUM_STATES]; - - nextStates[STATE_IDLE] = STATE_IDLE; - - nextStates[STATE_BITE_BEGINNING] = STATE_BITE_READY; - nextStates[STATE_BITE_READY] = STATE_BITE_BITING; - nextStates[STATE_BITE_BITING] = STATE_BITE_ENDING; - nextStates[STATE_BITE_ENDING] = STATE_ATTACK_COOLDOWN; - - nextStates[STATE_FLAME_BEGINNING] = STATE_FLAME_BREATHING; - nextStates[STATE_FLAME_BREATHING] = STATE_FLAME_ENDING; - nextStates[STATE_FLAME_ENDING] = STATE_ATTACK_COOLDOWN; - - nextStates[STATE_MORTAR_BEGINNING] = STATE_MORTAR_LAUNCH; - nextStates[STATE_MORTAR_LAUNCH] = STATE_MORTAR_ENDING; - nextStates[STATE_MORTAR_ENDING] = STATE_ATTACK_COOLDOWN; - - nextStates[STATE_ATTACK_COOLDOWN] = STATE_IDLE; - - nextStates[STATE_DYING] = STATE_DEAD; - - nextStates[STATE_DEAD] = STATE_DEAD; - - nextStates[STATE_BORN] = STATE_ROAR_START; - nextStates[STATE_ROAR_START] = STATE_ROAR_RAWR; - nextStates[STATE_ROAR_RAWR] = STATE_IDLE; - - // state durations, how long in each state - stateDurations = new int[NUM_STATES]; - - setupStateDurations(); - + + necka = new EntityTFHydraNeck(this.hydra, "neck" + headNum + "a", 2F, 2F); + neckb = new EntityTFHydraNeck(this.hydra, "neck" + headNum + "b", 2F, 2F); + neckc = new EntityTFHydraNeck(this.hydra, "neck" + headNum + "c", 2F, 2F); + neckd = new EntityTFHydraNeck(this.hydra, "neck" + headNum + "d", 2F, 2F); + necke = new EntityTFHydraNeck(this.hydra, "neck" + headNum + "e", 2F, 2F); + // state positions, where is each state positioned? - stateNeckLength = new float[hydraObj.numHeads][NUM_STATES]; - stateXRotations = new float[hydraObj.numHeads][NUM_STATES]; - stateYRotations = new float[hydraObj.numHeads][NUM_STATES]; - stateMouthOpen = new float[hydraObj.numHeads][NUM_STATES]; - + stateNeckLength = new Map[this.hydra.numHeads]; + stateXRotations = new Map[this.hydra.numHeads]; + stateYRotations = new Map[this.hydra.numHeads]; + stateMouthOpen = new Map[this.hydra.numHeads]; + + for (int i = 0; i < this.hydra.numHeads; i++) { + stateNeckLength[i] = new EnumMap<>(State.class); + stateXRotations[i] = new EnumMap<>(State.class); + stateYRotations[i] = new EnumMap<>(State.class); + stateMouthOpen[i] = new EnumMap<>(State.class); + } + setupStateRotations(); - - if (startActive) - { - this.prevState = STATE_IDLE; - this.currentState = STATE_IDLE; + + if (startActive) { + this.prevState = State.IDLE; + this.currentState = State.IDLE; this.nextState = NEXT_AUTOMATIC; this.ticksNeeded = 60; this.ticksProgress = 60; - } - else - { - this.prevState = STATE_DEAD; - this.currentState = STATE_DEAD; + } else { + this.prevState = State.DEAD; + this.currentState = State.DEAD; this.nextState = NEXT_AUTOMATIC; this.ticksNeeded = 20; this.ticksProgress = 20; } } - protected void setupStateDurations() { - stateDurations[STATE_IDLE] = 10; - - stateDurations[STATE_BITE_BEGINNING] = 40; - stateDurations[STATE_BITE_READY] = 80; - stateDurations[STATE_BITE_BITING] = 7; - stateDurations[STATE_BITE_ENDING] = 40; - - stateDurations[STATE_FLAME_BEGINNING] = 40; - stateDurations[STATE_FLAME_BREATHING] = 100; - stateDurations[STATE_FLAME_ENDING] = 30; - - stateDurations[STATE_MORTAR_BEGINNING] = 40; - stateDurations[STATE_MORTAR_LAUNCH] = 25; - stateDurations[STATE_MORTAR_ENDING] = 30; - - stateDurations[STATE_ATTACK_COOLDOWN] = 80; - - stateDurations[STATE_DYING] = 70; - stateDurations[STATE_DEAD] = 20; - - stateDurations[STATE_BORN] = 20; - - stateDurations[STATE_ROAR_START] = 10; - stateDurations[STATE_ROAR_RAWR] = 50; - - } - protected void setupStateRotations() { - setAnimation(0, STATE_IDLE, 60, 0, 7, 0); - setAnimation(1, STATE_IDLE, 10, 60, 9, 0); - setAnimation(2, STATE_IDLE, 10, -60, 9, 0); - setAnimation(3, STATE_IDLE, 50, 90, 8, 0); - setAnimation(4, STATE_IDLE, 50, -90, 8, 0); - setAnimation(5, STATE_IDLE, -10, 90, 9, 0); - setAnimation(6, STATE_IDLE, -10, -90, 9, 0); - - setAnimation(0, STATE_ATTACK_COOLDOWN, 60, 0, 7, 0); - setAnimation(1, STATE_ATTACK_COOLDOWN, 10, 60, 9, 0); - setAnimation(2, STATE_ATTACK_COOLDOWN, 10, -60, 9, 0); - setAnimation(3, STATE_ATTACK_COOLDOWN, 50, 90, 8, 0); - setAnimation(4, STATE_ATTACK_COOLDOWN, 50, -90, 8, 0); - setAnimation(5, STATE_ATTACK_COOLDOWN, -10, 90, 9, 0); - setAnimation(6, STATE_ATTACK_COOLDOWN, -10, -90, 9, 0); - - setAnimation(0, STATE_FLAME_BEGINNING, 50, 0, 8, 0.75F); - setAnimation(1, STATE_FLAME_BEGINNING, 30, 45, 9, 0.75F); - setAnimation(2, STATE_FLAME_BEGINNING, 30, -45, 9, 0.75F); - setAnimation(3, STATE_FLAME_BEGINNING, 50, 90, 8, 0.75F); - setAnimation(4, STATE_FLAME_BEGINNING, 50, -90, 8, 0.75F); - setAnimation(5, STATE_FLAME_BEGINNING, -10, 90, 9, 0.75F); - setAnimation(6, STATE_FLAME_BEGINNING, -10, -90, 9, 0.75F); - - setAnimation(0, STATE_FLAME_BREATHING, 45, 0, 8, 1); - setAnimation(1, STATE_FLAME_BREATHING, 30, 60, 9, 1); - setAnimation(2, STATE_FLAME_BREATHING, 30, -60, 9, 1); - setAnimation(3, STATE_FLAME_BREATHING, 50, 90, 8, 1); - setAnimation(4, STATE_FLAME_BREATHING, 50, -90, 8, 1); - setAnimation(5, STATE_FLAME_BREATHING, -10, 90, 9, 1); - setAnimation(6, STATE_FLAME_BREATHING, -10, -90, 9, 1); - - setAnimation(0, STATE_FLAME_ENDING, 60, 0, 7, 0); - setAnimation(1, STATE_FLAME_ENDING, 10, 45, 9, 0); - setAnimation(2, STATE_FLAME_ENDING, 10, -45, 9, 0); - setAnimation(3, STATE_FLAME_ENDING, 50, 90, 8, 0); - setAnimation(4, STATE_FLAME_ENDING, 50, -90, 8, 0); - setAnimation(5, STATE_FLAME_ENDING, -10, 90, 9, 0); - setAnimation(6, STATE_FLAME_ENDING, -10, -90, 9, 0); - - setAnimation(0, STATE_BITE_BEGINNING, -5, 60, 5, 0.25f); - setAnimation(1, STATE_BITE_BEGINNING, -10, 60, 9, 0.25f); - setAnimation(2, STATE_BITE_BEGINNING, -10, -60, 9, 0.25f); - - setAnimation(0, STATE_BITE_READY, -5, 60, 5, 1); - setAnimation(1, STATE_BITE_READY, -10, 60, 9, 1); - setAnimation(2, STATE_BITE_READY, -10, -60, 9, 1); - - setAnimation(0, STATE_BITE_BITING, -5, -30, 5, 0.2F); - setAnimation(1, STATE_BITE_BITING, -10, -30, 5, 0.2F); - setAnimation(2, STATE_BITE_BITING, -10, 30, 5, 0.2F); - - setAnimation(0, STATE_BITE_ENDING, 60, 0, 7, 0); - setAnimation(1, STATE_BITE_ENDING, -10, 60, 9, 0); - setAnimation(2, STATE_BITE_ENDING, -10, -60, 9, 0); - - setAnimation(0, STATE_MORTAR_BEGINNING, 50, 0, 8, 0.75F); - setAnimation(1, STATE_MORTAR_BEGINNING, 30, 45, 9, 0.75F); - setAnimation(2, STATE_MORTAR_BEGINNING, 30, -45, 9, 0.75F); - setAnimation(3, STATE_MORTAR_BEGINNING, 50, 90, 8, 0.75F); - setAnimation(4, STATE_MORTAR_BEGINNING, 50, -90, 8, 0.75F); - setAnimation(5, STATE_MORTAR_BEGINNING, -10, 90, 9, 0.75F); - setAnimation(6, STATE_MORTAR_BEGINNING, -10, -90, 9, 0.75F); - - setAnimation(0, STATE_MORTAR_LAUNCH, 45, 0, 8, 1); - setAnimation(1, STATE_MORTAR_LAUNCH, 30, 60, 9, 1); - setAnimation(2, STATE_MORTAR_LAUNCH, 30, -60, 9, 1); - setAnimation(3, STATE_MORTAR_LAUNCH, 50, 90, 8, 1); - setAnimation(4, STATE_MORTAR_LAUNCH, 50, -90, 8, 1); - setAnimation(5, STATE_MORTAR_LAUNCH, -10, 90, 9, 1); - setAnimation(6, STATE_MORTAR_LAUNCH, -10, -90, 9, 1); - - setAnimation(0, STATE_MORTAR_ENDING, 60, 0, 7, 0); - setAnimation(1, STATE_MORTAR_ENDING, 10, 45, 9, 0); - setAnimation(2, STATE_MORTAR_ENDING, 10, -45, 9, 0); - setAnimation(3, STATE_MORTAR_ENDING, 50, 90, 8, 0); - setAnimation(4, STATE_MORTAR_ENDING, 50, -90, 8, 0); - setAnimation(5, STATE_MORTAR_ENDING, -10, 90, 9, 0); - setAnimation(6, STATE_MORTAR_ENDING, -10, -90, 9, 0); - - setAnimation(0, STATE_DYING, -20, 0, 7, 0); - setAnimation(1, STATE_DYING, -20, 60, 9, 0); - setAnimation(2, STATE_DYING, -20, -60, 9, 0); - setAnimation(3, STATE_DYING, -20, 90, 8, 0); - setAnimation(4, STATE_DYING, -20, -90, 8, 0); - setAnimation(5, STATE_DYING, -10, 90, 9, 0); - setAnimation(6, STATE_DYING, -10, -90, 9, 0); - - setAnimation(0, STATE_DEAD, 0, 179, 4, 0); - setAnimation(1, STATE_DEAD, 0, 179, 4, 0); - setAnimation(2, STATE_DEAD, 0, -180, 4, 0); - setAnimation(3, STATE_DEAD, 0, 179, 4, 0); - setAnimation(4, STATE_DEAD, 0, -180, 4, 0); - setAnimation(5, STATE_DEAD, 0, 179, 4, 0); - setAnimation(6, STATE_DEAD, 0, -180, 4, 0); - - setAnimation(0, STATE_BORN, 60, 0, 7, 0); - setAnimation(1, STATE_BORN, 10, 60, 9, 0); - setAnimation(2, STATE_BORN, 10, -60, 9, 0); - setAnimation(3, STATE_BORN, 50, 90, 8, 0); - setAnimation(4, STATE_BORN, 50, -90, 8, 0); - setAnimation(5, STATE_BORN, -10, 90, 9, 0); - setAnimation(6, STATE_BORN, -10, -90, 9, 0); - - setAnimation(0, STATE_ROAR_START, 60, 0, 7, 0.25F); - setAnimation(1, STATE_ROAR_START, 10, 60, 9, 0.25F); - setAnimation(2, STATE_ROAR_START, 10, -60, 9, 0.25F); - setAnimation(3, STATE_ROAR_START, 50, 90, 8, 0.25F); - setAnimation(4, STATE_ROAR_START, 50, -90, 8, 0.25F); - setAnimation(5, STATE_ROAR_START, -10, 90, 9, 0.25F); - setAnimation(6, STATE_ROAR_START, -10, -90, 9, 0.25F); - - setAnimation(0, STATE_ROAR_RAWR, 60, 0, 9, 1); - setAnimation(1, STATE_ROAR_RAWR, 10, 60, 11, 1); - setAnimation(2, STATE_ROAR_RAWR, 10, -60, 11, 1); - setAnimation(3, STATE_ROAR_RAWR, 50, 90, 10, 1); - setAnimation(4, STATE_ROAR_RAWR, 50, -90, 10, 1); - setAnimation(5, STATE_ROAR_RAWR, -10, 90, 11, 1); - setAnimation(6, STATE_ROAR_RAWR, -10, -90, 11, 1); - - - } - - protected void setAnimation(int head, int state, float xRotation, float yRotation, float neckLength, float mouthOpen) - { - this.stateXRotations[head][state] = xRotation; - this.stateYRotations[head][state] = yRotation; - this.stateNeckLength[head][state] = neckLength; - this.stateMouthOpen[head][state] = mouthOpen; // this doesn't really need to be set per-head, more per-state - } - - public EntityTFHydraNeck[] getNeckArray() - { - return new EntityTFHydraNeck[] { necka, neckb, neckc, neckd, necke }; + setAnimation(0, State.IDLE, 60, 0, 7, 0); + setAnimation(1, State.IDLE, 10, 60, 9, 0); + setAnimation(2, State.IDLE, 10, -60, 9, 0); + setAnimation(3, State.IDLE, 50, 90, 8, 0); + setAnimation(4, State.IDLE, 50, -90, 8, 0); + setAnimation(5, State.IDLE, -10, 90, 9, 0); + setAnimation(6, State.IDLE, -10, -90, 9, 0); + + setAnimation(0, State.ATTACK_COOLDOWN, 60, 0, 7, 0); + setAnimation(1, State.ATTACK_COOLDOWN, 10, 60, 9, 0); + setAnimation(2, State.ATTACK_COOLDOWN, 10, -60, 9, 0); + setAnimation(3, State.ATTACK_COOLDOWN, 50, 90, 8, 0); + setAnimation(4, State.ATTACK_COOLDOWN, 50, -90, 8, 0); + setAnimation(5, State.ATTACK_COOLDOWN, -10, 90, 9, 0); + setAnimation(6, State.ATTACK_COOLDOWN, -10, -90, 9, 0); + + setAnimation(0, State.FLAME_BEGINNING, 50, 0, 8, 0.75F); + setAnimation(1, State.FLAME_BEGINNING, 30, 45, 9, 0.75F); + setAnimation(2, State.FLAME_BEGINNING, 30, -45, 9, 0.75F); + setAnimation(3, State.FLAME_BEGINNING, 50, 90, 8, 0.75F); + setAnimation(4, State.FLAME_BEGINNING, 50, -90, 8, 0.75F); + setAnimation(5, State.FLAME_BEGINNING, -10, 90, 9, 0.75F); + setAnimation(6, State.FLAME_BEGINNING, -10, -90, 9, 0.75F); + + setAnimation(0, State.FLAMING, 45, 0, 8, 1); + setAnimation(1, State.FLAMING, 30, 60, 9, 1); + setAnimation(2, State.FLAMING, 30, -60, 9, 1); + setAnimation(3, State.FLAMING, 50, 90, 8, 1); + setAnimation(4, State.FLAMING, 50, -90, 8, 1); + setAnimation(5, State.FLAMING, -10, 90, 9, 1); + setAnimation(6, State.FLAMING, -10, -90, 9, 1); + + setAnimation(0, State.FLAME_ENDING, 60, 0, 7, 0); + setAnimation(1, State.FLAME_ENDING, 10, 45, 9, 0); + setAnimation(2, State.FLAME_ENDING, 10, -45, 9, 0); + setAnimation(3, State.FLAME_ENDING, 50, 90, 8, 0); + setAnimation(4, State.FLAME_ENDING, 50, -90, 8, 0); + setAnimation(5, State.FLAME_ENDING, -10, 90, 9, 0); + setAnimation(6, State.FLAME_ENDING, -10, -90, 9, 0); + + setAnimation(0, State.BITE_BEGINNING, -5, 60, 5, 0.25f); + setAnimation(1, State.BITE_BEGINNING, -10, 60, 9, 0.25f); + setAnimation(2, State.BITE_BEGINNING, -10, -60, 9, 0.25f); + + setAnimation(0, State.BITE_READY, -5, 60, 5, 1); + setAnimation(1, State.BITE_READY, -10, 60, 9, 1); + setAnimation(2, State.BITE_READY, -10, -60, 9, 1); + + setAnimation(0, State.BITING, -5, -30, 5, 0.2F); + setAnimation(1, State.BITING, -10, -30, 5, 0.2F); + setAnimation(2, State.BITING, -10, 30, 5, 0.2F); + + setAnimation(0, State.BITE_ENDING, 60, 0, 7, 0); + setAnimation(1, State.BITE_ENDING, -10, 60, 9, 0); + setAnimation(2, State.BITE_ENDING, -10, -60, 9, 0); + + setAnimation(0, State.MORTAR_BEGINNING, 50, 0, 8, 0.75F); + setAnimation(1, State.MORTAR_BEGINNING, 30, 45, 9, 0.75F); + setAnimation(2, State.MORTAR_BEGINNING, 30, -45, 9, 0.75F); + setAnimation(3, State.MORTAR_BEGINNING, 50, 90, 8, 0.75F); + setAnimation(4, State.MORTAR_BEGINNING, 50, -90, 8, 0.75F); + setAnimation(5, State.MORTAR_BEGINNING, -10, 90, 9, 0.75F); + setAnimation(6, State.MORTAR_BEGINNING, -10, -90, 9, 0.75F); + + setAnimation(0, State.MORTAR_SHOOTING, 45, 0, 8, 1); + setAnimation(1, State.MORTAR_SHOOTING, 30, 60, 9, 1); + setAnimation(2, State.MORTAR_SHOOTING, 30, -60, 9, 1); + setAnimation(3, State.MORTAR_SHOOTING, 50, 90, 8, 1); + setAnimation(4, State.MORTAR_SHOOTING, 50, -90, 8, 1); + setAnimation(5, State.MORTAR_SHOOTING, -10, 90, 9, 1); + setAnimation(6, State.MORTAR_SHOOTING, -10, -90, 9, 1); + + setAnimation(0, State.MORTAR_ENDING, 60, 0, 7, 0); + setAnimation(1, State.MORTAR_ENDING, 10, 45, 9, 0); + setAnimation(2, State.MORTAR_ENDING, 10, -45, 9, 0); + setAnimation(3, State.MORTAR_ENDING, 50, 90, 8, 0); + setAnimation(4, State.MORTAR_ENDING, 50, -90, 8, 0); + setAnimation(5, State.MORTAR_ENDING, -10, 90, 9, 0); + setAnimation(6, State.MORTAR_ENDING, -10, -90, 9, 0); + + setAnimation(0, State.DYING, -20, 0, 7, 0); + setAnimation(1, State.DYING, -20, 60, 9, 0); + setAnimation(2, State.DYING, -20, -60, 9, 0); + setAnimation(3, State.DYING, -20, 90, 8, 0); + setAnimation(4, State.DYING, -20, -90, 8, 0); + setAnimation(5, State.DYING, -10, 90, 9, 0); + setAnimation(6, State.DYING, -10, -90, 9, 0); + + setAnimation(0, State.DEAD, 0, 179, 4, 0); + setAnimation(1, State.DEAD, 0, 179, 4, 0); + setAnimation(2, State.DEAD, 0, -180, 4, 0); + setAnimation(3, State.DEAD, 0, 179, 4, 0); + setAnimation(4, State.DEAD, 0, -180, 4, 0); + setAnimation(5, State.DEAD, 0, 179, 4, 0); + setAnimation(6, State.DEAD, 0, -180, 4, 0); + + setAnimation(0, State.BORN, 60, 0, 7, 0); + setAnimation(1, State.BORN, 10, 60, 9, 0); + setAnimation(2, State.BORN, 10, -60, 9, 0); + setAnimation(3, State.BORN, 50, 90, 8, 0); + setAnimation(4, State.BORN, 50, -90, 8, 0); + setAnimation(5, State.BORN, -10, 90, 9, 0); + setAnimation(6, State.BORN, -10, -90, 9, 0); + + setAnimation(0, State.ROAR_START, 60, 0, 7, 0.25F); + setAnimation(1, State.ROAR_START, 10, 60, 9, 0.25F); + setAnimation(2, State.ROAR_START, 10, -60, 9, 0.25F); + setAnimation(3, State.ROAR_START, 50, 90, 8, 0.25F); + setAnimation(4, State.ROAR_START, 50, -90, 8, 0.25F); + setAnimation(5, State.ROAR_START, -10, 90, 9, 0.25F); + setAnimation(6, State.ROAR_START, -10, -90, 9, 0.25F); + + setAnimation(0, State.ROAR_RAWR, 60, 0, 9, 1); + setAnimation(1, State.ROAR_RAWR, 10, 60, 11, 1); + setAnimation(2, State.ROAR_RAWR, 10, -60, 11, 1); + setAnimation(3, State.ROAR_RAWR, 50, 90, 10, 1); + setAnimation(4, State.ROAR_RAWR, 50, -90, 10, 1); + setAnimation(5, State.ROAR_RAWR, -10, 90, 11, 1); + setAnimation(6, State.ROAR_RAWR, -10, -90, 11, 1); + } + + private void setAnimation(int head, State state, float xRotation, float yRotation, float neckLength, float mouthOpen) { + this.stateXRotations[head].put(state, xRotation); + this.stateYRotations[head].put(state, yRotation); + this.stateNeckLength[head].put(state, neckLength); + this.stateMouthOpen[head].put(state, mouthOpen); // this doesn't really need to be set per-head, more per-state + } + + public EntityTFHydraNeck[] getNeckArray() { + return new EntityTFHydraNeck[]{necka, neckb, neckc, neckd, necke}; } /** * Called once per tick as part of the hydra entity update loop. */ public void onUpdate() { - + // neck updates necka.onUpdate(); neckb.onUpdate(); neckc.onUpdate(); neckd.onUpdate(); necke.onUpdate(); - + // check if the head is here - if (headEntity == null) - { + if (headEntity == null) { headEntity = findNearbyHead("head" + headNum); } - + // adjust for difficulty setDifficultyVariables(); - if (headEntity != null) - { + if (headEntity != null) { // make sure this is set up headEntity.width = headEntity.height = this.isActive() ? 4.0F : 1.0F; - - // only actually do these things on the server - if (!hydraObj.worldObj.isRemote) - { - advanceRespawnCounter(); - - advanceHeadState(); - - setHeadPosition(); - - setHeadFacing(); - - executeAttacks(); - } - else - { - clientAnimateHeadDeath(); - } - - setNeckPosition(); - - addMouthParticles(); - - playSounds(); + // only actually do these things on the server + if (!hydra.world.isRemote) { + advanceRespawnCounter(); + advanceHeadState(); + setHeadPosition(); + setHeadFacing(); + executeAttacks(); + playSounds(); + } else { + clientAnimateHeadDeath(); + addMouthParticles(); + } + + setNeckPosition(); } } - /** - * If we are dead, decrement the respawn counter and respawn when it is empty. - */ - protected void advanceRespawnCounter() { - if (this.currentState == STATE_DEAD && respawnCounter > -1) - { - if (--this.respawnCounter <= 0) - { - this.setNextState(STATE_BORN); + public boolean canRespawn() { + return this.currentState == State.DEAD && this.respawnCounter == -1; + } + + private void advanceRespawnCounter() { + if (this.currentState == State.DEAD && respawnCounter > -1) { + if (--this.respawnCounter <= 0) { + this.setNextState(State.BORN); this.damageTaken = 0; this.endCurrentAction(); this.respawnCounter = -1; @@ -400,768 +367,566 @@ protected void advanceRespawnCounter() { } } - /** - * We need to animate head death on the client - */ - protected void clientAnimateHeadDeath() { - // this will start the animation - if (headEntity.getState() == HydraHeadContainer.STATE_DYING) - { - // several things, like head visibility animate off this - this.headEntity.deathTime++; - - // make explosion particles and stuff - if (headEntity.deathTime > 0) - { - if (headEntity.deathTime < 20) - { - doExplosionOn(headEntity, true); - } - else if (headEntity.deathTime < 30) - { - doExplosionOn(necka, false); - } - else if (headEntity.deathTime < 40) - { - doExplosionOn(neckb, false); - } - else if (headEntity.deathTime < 50) - { - doExplosionOn(neckc, false); - } - else if (headEntity.deathTime < 60) - { - doExplosionOn(neckd, false); - } - else if (headEntity.deathTime < 70) - { - doExplosionOn(necke, false); - } - } - - // turn necks red - necka.hurtTime = 20; - neckb.hurtTime = 20; - neckc.hurtTime = 20; - neckd.hurtTime = 20; - necke.hurtTime = 20; - - } - else - { - this.headEntity.deathTime = 0; - this.headEntity.setHealth((float) this.headEntity.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue()); - } + private void clientAnimateHeadDeath() { + // this will start the animation + if (headEntity.getState() == State.DYING) { + // several things, like head visibility animate off this + this.headEntity.deathTime++; + + // make explosion particles and stuff + if (headEntity.deathTime > 0) { + if (headEntity.deathTime < 20) { + doExplosionOn(headEntity, true); + } else if (headEntity.deathTime < 30) { + doExplosionOn(necka, false); + } else if (headEntity.deathTime < 40) { + doExplosionOn(neckb, false); + } else if (headEntity.deathTime < 50) { + doExplosionOn(neckc, false); + } else if (headEntity.deathTime < 60) { + doExplosionOn(neckd, false); + } else if (headEntity.deathTime < 70) { + doExplosionOn(necke, false); + } + } + + // turn necks red + necka.hurtTime = 20; + neckb.hurtTime = 20; + neckc.hurtTime = 20; + neckd.hurtTime = 20; + necke.hurtTime = 20; + + } else { + this.headEntity.deathTime = 0; + this.headEntity.setHealth((float) this.headEntity.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).getBaseValue()); + } } private void doExplosionOn(EntityTFHydraPart part, boolean large) { - for (int i = 0; i < 10; ++i) - { - double var8 = part.getRNG().nextGaussian() * 0.02D; - double var4 = part.getRNG().nextGaussian() * 0.02D; - double var6 = part.getRNG().nextGaussian() * 0.02D; - String particle = large && part.getRNG().nextInt(5) == 0 ? "largeexplode" : "explode"; - part.worldObj.spawnParticle(particle, part.posX + part.getRNG().nextFloat() * part.width * 2.0F - part.width, part.posY + part.getRNG().nextFloat() * part.height, part.posZ + part.getRNG().nextFloat() * part.width * 2.0F - part.width, var8, var4, var6); - } - + for (int i = 0; i < 10; ++i) { + double vx = part.getRNG().nextGaussian() * 0.02D; + double vy = part.getRNG().nextGaussian() * 0.02D; + double vz = part.getRNG().nextGaussian() * 0.02D; + EnumParticleTypes particle = large && part.getRNG().nextInt(5) == 0 ? EnumParticleTypes.EXPLOSION_LARGE : EnumParticleTypes.EXPLOSION_NORMAL; + part.world.spawnParticle(particle, part.posX + part.getRNG().nextFloat() * part.width * 2.0F - part.width, part.posY + part.getRNG().nextFloat() * part.height, part.posZ + part.getRNG().nextFloat() * part.width * 2.0F - part.width, vx, vy, vz); + } } - /** - * Move the state counter along - * This is only called on the server, the client just receives the resulting data - */ - protected void advanceHeadState() { + private void advanceHeadState() { // check head state - if (++ticksProgress >= this.ticksNeeded) - { - int myNext; - + if (++ticksProgress >= this.ticksNeeded) { + State myNext; + // advance state - if (this.nextState == NEXT_AUTOMATIC) - { - myNext = nextStates[this.currentState]; - if (myNext != currentState) - { - //System.out.println("Automatically advancing head " + this.headNum + " to state " + myNext); - + if (this.nextState == NEXT_AUTOMATIC) { + myNext = State.NEXT_STATE.get(this.currentState); + if (myNext != currentState) { // when returning from a secondary attack, no attack cooldown - if (this.isSecondaryAttacking && myNext == HydraHeadContainer.STATE_ATTACK_COOLDOWN) - { + if (this.isSecondaryAttacking && myNext == State.ATTACK_COOLDOWN) { this.isSecondaryAttacking = false; - myNext = HydraHeadContainer.STATE_IDLE; + myNext = State.IDLE; } } - } - else - { + } else { myNext = this.nextState; this.nextState = NEXT_AUTOMATIC; - //System.out.println("Manually advancing head " + this.headNum + " to state " + myNext); } - - this.ticksNeeded = this.ticksProgress = stateDurations[myNext]; + + this.ticksNeeded = this.ticksProgress = myNext.duration; this.ticksProgress = 0; - + this.prevState = this.currentState; this.currentState = myNext; } // set datawatcher so client can properly animate - if (headEntity.getState() != this.currentState) - { + if (headEntity.getState() != this.currentState) { headEntity.setState(this.currentState); } - } - /** - * Set the direction the head is facing. It mostly faces the targetEntity, but that depends on the state - */ - protected void setHeadFacing() { - if (this.currentState == HydraHeadContainer.STATE_BITE_READY) - { + private void setHeadFacing() { + if (this.currentState == State.BITE_READY) { // face target within certain constraints - this.faceEntity(targetEntity, 5F, hydraObj.getVerticalFaceSpeed()); - + this.faceEntity(targetEntity, 5F, hydra.getVerticalFaceSpeed()); + // head 0 and 1 max yaw float biteMaxYaw = -60; float biteMinYaw = -90; - - if (headNum == 2) - { + + if (headNum == 2) { // head 2 max/min yaw biteMaxYaw = 60; biteMinYaw = 90; } - float yawOffOffset = MathHelper.wrapAngleTo180_float(headEntity.rotationYaw - hydraObj.renderYawOffset); - - //System.out.println("biting head yaw = " + yawOffOffset); - - if (yawOffOffset > biteMaxYaw) - { - headEntity.rotationYaw = hydraObj.renderYawOffset + biteMaxYaw; + float yawOffOffset = MathHelper.wrapDegrees(headEntity.rotationYaw - hydra.renderYawOffset); + + if (yawOffOffset > biteMaxYaw) { + headEntity.rotationYaw = hydra.renderYawOffset + biteMaxYaw; } - if (yawOffOffset < biteMinYaw) - { - headEntity.rotationYaw = hydraObj.renderYawOffset + biteMinYaw; + if (yawOffOffset < biteMinYaw) { + headEntity.rotationYaw = hydra.renderYawOffset + biteMinYaw; } - + // make the target vector be a point off in the distance in the direction we're already facing - Vec3 look = this.headEntity.getLookVec(); + Vec3d look = this.headEntity.getLookVec(); double distance = 16.0D; - this.targetX = headEntity.posX + look.xCoord * distance; - this.targetY = headEntity.posY + 1.5 + look.yCoord * distance; - this.targetZ = headEntity.posZ + look.zCoord * distance; - } - else if (this.currentState == HydraHeadContainer.STATE_BITE_BITING || this.currentState == HydraHeadContainer.STATE_BITE_ENDING) - { - this.faceEntity(targetEntity, 5F, hydraObj.getVerticalFaceSpeed()); + this.targetX = headEntity.posX + look.x * distance; + this.targetY = headEntity.posY + 1.5 + look.y * distance; + this.targetZ = headEntity.posZ + look.z * distance; + + } else if (this.currentState == State.BITING || this.currentState == State.BITE_ENDING) { + this.faceEntity(targetEntity, 5F, hydra.getVerticalFaceSpeed()); headEntity.rotationPitch += Math.PI / 4; - } - else if (this.currentState == HydraHeadContainer.STATE_ROAR_RAWR) - { + + } else if (this.currentState == State.ROAR_RAWR) { // keep facing target vector, don't move - this.faceVec(this.targetX, this.targetY, this.targetZ, 10F, hydraObj.getVerticalFaceSpeed()); - } - else if (this.currentState == HydraHeadContainer.STATE_FLAME_BREATHING || (this.currentState == HydraHeadContainer.STATE_FLAME_BEGINNING)) - { + this.faceVec(this.targetX, this.targetY, this.targetZ, 10F, hydra.getVerticalFaceSpeed()); + + } else if (this.currentState == State.FLAMING || this.currentState == State.FLAME_BEGINNING) { // move flame breath slowly towards the player moveTargetCoordsTowardsTargetEntity(FLAME_BREATH_TRACKING_SPEED); // face the target coordinates - this.faceVec(this.targetX, this.targetY, this.targetZ, 5F, hydraObj.getVerticalFaceSpeed()); - } - else { - if (this.isActive()) - { - if (this.targetEntity != null) - { + this.faceVec(this.targetX, this.targetY, this.targetZ, 5F, hydra.getVerticalFaceSpeed()); + + } else { + if (this.isActive()) { + if (this.targetEntity != null) { // watch the target entity - this.faceEntity(targetEntity, 5F, hydraObj.getVerticalFaceSpeed()); - } - else - { + this.faceEntity(targetEntity, 5F, hydra.getVerticalFaceSpeed()); + } else { // while idle, look where the body is looking? - faceIdle(1.5F, hydraObj.getVerticalFaceSpeed()); + faceIdle(1.5F, hydra.getVerticalFaceSpeed()); } } } } - /** - * Slowly track our target coords towards the target entity - */ - protected void moveTargetCoordsTowardsTargetEntity(double distance) - { - if (this.targetEntity != null) - { - Vec3 vect = Vec3.createVectorHelper(this.targetEntity.posX - this.targetX, this.targetEntity.posY - this.targetY, this.targetEntity.posZ - this.targetZ); + private void moveTargetCoordsTowardsTargetEntity(double distance) { + if (this.targetEntity != null) { + Vec3d vect = new Vec3d(this.targetEntity.posX - this.targetX, this.targetEntity.posY - this.targetY, this.targetEntity.posZ - this.targetZ); vect = vect.normalize(); - this.targetX += vect.xCoord * distance; - this.targetY += vect.yCoord * distance; - this.targetZ += vect.zCoord * distance; + this.targetX += vect.x * distance; + this.targetY += vect.y * distance; + this.targetZ += vect.z * distance; } } - /** - * During certain states, animate particles coming out of the mouth - */ - protected void addMouthParticles() { - Vec3 vector = headEntity.getLookVec(); - + private void addMouthParticles() { + Vec3d vector = headEntity.getLookVec(); + double dist = 3.5; - double px = headEntity.posX + vector.xCoord * dist; - double py = headEntity.posY + 1 + vector.yCoord * dist; - double pz = headEntity.posZ + vector.zCoord * dist; - - //hydraObj.worldObj.spawnParticle("mobSpell", px, py, pz, 0.3, 0.9, 0.1); - - if (headEntity.getState() == STATE_FLAME_BEGINNING) - { - headEntity.worldObj.spawnParticle("flame", px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); - headEntity.worldObj.spawnParticle("smoke", px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); + double px = headEntity.posX + vector.x * dist; + double py = headEntity.posY + 1 + vector.y * dist; + double pz = headEntity.posZ + vector.z * dist; + + if (headEntity.getState() == State.FLAME_BEGINNING) { + headEntity.world.spawnParticle(EnumParticleTypes.FLAME, px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); + headEntity.world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); } - - if (headEntity.getState() == STATE_FLAME_BREATHING) - { - Vec3 look = headEntity.getLookVec(); - for (int i = 0; i < 5; i++) - { - double dx = look.xCoord; - double dy = look.yCoord; - double dz = look.zCoord; - + + if (headEntity.getState() == State.FLAMING) { + Vec3d look = headEntity.getLookVec(); + for (int i = 0; i < 5; i++) { + double dx = look.x; + double dy = look.y; + double dz = look.z; + double spread = 5 + headEntity.getRNG().nextDouble() * 2.5; double velocity = 1.0 + headEntity.getRNG().nextDouble(); - + // spread flame - dx += headEntity.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dy += headEntity.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dz += headEntity.getRNG().nextGaussian() * 0.007499999832361937D * spread; - dx *= velocity; - dy *= velocity; - dz *= velocity; - - TwilightForestMod.proxy.spawnParticle(headEntity.worldObj, "largeflame", px, py, pz, dx, dy, dz); + dx += headEntity.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dy += headEntity.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dz += headEntity.getRNG().nextGaussian() * 0.007499999832361937D * spread; + dx *= velocity; + dy *= velocity; + dz *= velocity; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, px, py, pz, dx, dy, dz); } } - - if (headEntity.getState() == STATE_BITE_BEGINNING || headEntity.getState() == STATE_BITE_READY) - { - headEntity.worldObj.spawnParticle("splash", px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); + + if (headEntity.getState() == State.BITE_BEGINNING || headEntity.getState() == State.BITE_READY) { + headEntity.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); } - - if (headEntity.getState() == STATE_MORTAR_BEGINNING) - { - headEntity.worldObj.spawnParticle("largesmoke", px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); + + if (headEntity.getState() == State.MORTAR_BEGINNING) { + headEntity.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, px + headEntity.getRNG().nextDouble() - 0.5, py + headEntity.getRNG().nextDouble() - 0.5, pz + headEntity.getRNG().nextDouble() - 0.5, 0, 0, 0); } } - /** - * Generate any sounds we need to go along with head animations - */ - protected void playSounds() { - if (headEntity.getState() == STATE_FLAME_BREATHING && headEntity.ticksExisted % 5 == 0) - { + private void playSounds() { + if (headEntity.getState() == State.FLAMING && headEntity.ticksExisted % 5 == 0) { // fire breathing! - headEntity.worldObj.playSoundEffect(headEntity.posX + 0.5, headEntity.posY + 0.5, headEntity.posZ + 0.5, "mob.ghast.fireball", 0.5F + headEntity.getRNG().nextFloat(), headEntity.getRNG().nextFloat() * 0.7F + 0.3F); - } - if (headEntity.getState() == STATE_ROAR_RAWR) - { - headEntity.worldObj.playSoundEffect(headEntity.posX + 0.5, headEntity.posY + 0.5, headEntity.posZ + 0.5, TwilightForestMod.ID + ":mob.hydra.roar", 1.25F, headEntity.getRNG().nextFloat() * 0.3F + 0.7F); + headEntity.playSound(SoundEvents.ENTITY_GHAST_SHOOT, 0.5F + headEntity.getRNG().nextFloat(), headEntity.getRNG().nextFloat() * 0.7F + 0.3F); } - if (headEntity.getState() == STATE_BITE_READY && this.ticksProgress == 60) - { - headEntity.worldObj.playSoundEffect(headEntity.posX + 0.5, headEntity.posY + 0.5, headEntity.posZ + 0.5, TwilightForestMod.ID + ":mob.hydra.warn", 2.0F, headEntity.getRNG().nextFloat() * 0.3F + 0.7F); + if (headEntity.getState() == State.ROAR_RAWR) { + headEntity.playSound(TFSounds.HYDRA_ROAR, 1.25F, headEntity.getRNG().nextFloat() * 0.3F + 0.7F); } - if (headEntity.getState() == STATE_IDLE) - { - this.didRoar = false; + if (headEntity.getState() == State.BITE_READY && this.ticksProgress == 60) { + headEntity.playSound(TFSounds.HYDRA_WARN, 2.0F, headEntity.getRNG().nextFloat() * 0.3F + 0.7F); } } - /** - * Put the neck entities into the proper place, based on the body and head positions - * Done on both server and client. - */ - protected void setNeckPosition() { + private void setNeckPosition() { // set neck positions - Vec3 vector = null; + Vec3d vector = null; float neckRotation = 0; - - if (headNum == 0) - { - vector = Vec3.createVectorHelper(0, 3, -1); + + if (headNum == 0) { + vector = new Vec3d(0, 3, -1); neckRotation = 0; } - if (headNum == 1) - { - vector = Vec3.createVectorHelper(-1, 3, 3); + if (headNum == 1) { + vector = new Vec3d(-1, 3, 3); neckRotation = 90; } - if (headNum == 2) - { - vector = Vec3.createVectorHelper(1, 3, 3); + if (headNum == 2) { + vector = new Vec3d(1, 3, 3); neckRotation = -90; } - if (headNum == 3) - { - vector = Vec3.createVectorHelper(-1, 3, 3); + if (headNum == 3) { + vector = new Vec3d(-1, 3, 3); neckRotation = 135; } - if (headNum == 4) - { - vector = Vec3.createVectorHelper(1, 3, 3); + if (headNum == 4) { + vector = new Vec3d(1, 3, 3); neckRotation = -135; } - - if (headNum == 5) - { - vector = Vec3.createVectorHelper(-1, 3, 5); + + if (headNum == 5) { + vector = new Vec3d(-1, 3, 5); neckRotation = 135; } - if (headNum == 6) - { - vector = Vec3.createVectorHelper(1, 3, 5); + if (headNum == 6) { + vector = new Vec3d(1, 3, 5); neckRotation = -135; } - - - vector.rotateAroundY((-(hydraObj.renderYawOffset + neckRotation) * 3.141593F) / 180F); - setNeckPositon(hydraObj.posX + vector.xCoord, hydraObj.posY + vector.yCoord, hydraObj.posZ + vector.zCoord, hydraObj.renderYawOffset, 0); + + vector = vector.rotateYaw((-(hydra.renderYawOffset + neckRotation) * 3.141593F) / 180F); + setNeckPosition(hydra.posX + vector.x, hydra.posY + vector.y, hydra.posZ + vector.z, hydra.renderYawOffset, 0); } - /** - * Position the head object appropriately - * This is only called on the server, the client just receives the resulting data - */ protected void setHeadPosition() { // set head positions - Vec3 vector; + Vec3d vector; double dx, dy, dz; // head1 is above // head2 is to the right // head3 is to the left - setupStateDurations(); setupStateRotations(); // temporary, for debugging - + float neckLength = getCurrentNeckLength(); float xRotation = getCurrentHeadXRotation(); float yRotation = getCurrentHeadYRotation(); - - + + float periodX = (headNum == 0 || headNum == 3) ? 20F : ((headNum == 1 || headNum == 4) ? 5.0f : 7.0F); float periodY = (headNum == 0 || headNum == 4) ? 10F : ((headNum == 1 || headNum == 6) ? 6.0f : 5.0F); - - float xSwing = MathHelper.sin(hydraObj.ticksExisted / periodX) * 3.0F; - float ySwing = MathHelper.sin(hydraObj.ticksExisted / periodY) * 5.0F; - - if (!this.isActive()) - { + + float xSwing = MathHelper.sin(hydra.ticksExisted / periodX) * 3.0F; + float ySwing = MathHelper.sin(hydra.ticksExisted / periodY) * 5.0F; + + if (!this.isActive()) { xSwing = ySwing = 0; } - - vector = Vec3.createVectorHelper(0, 0, neckLength); // -53 = 3.3125 - vector.rotateAroundX((xRotation * 3.141593F + xSwing) / 180F); - vector.rotateAroundY((-(hydraObj.renderYawOffset + yRotation + ySwing) * 3.141593F) / 180F); - dx = hydraObj.posX + vector.xCoord; - dy = hydraObj.posY + vector.yCoord + 3; - dz = hydraObj.posZ + vector.zCoord; + vector = new Vec3d(0, 0, neckLength); // -53 = 3.3125 + vector = vector.rotatePitch((xRotation * 3.141593F + xSwing) / 180F); + vector = vector.rotateYaw((-(hydra.renderYawOffset + yRotation + ySwing) * 3.141593F) / 180F); + + dx = hydra.posX + vector.x; + dy = hydra.posY + vector.y + 3; + dz = hydra.posZ + vector.z; headEntity.setPosition(dx, dy, dz); headEntity.setMouthOpen(getCurrentMouthOpen()); - } - /** - * Execute whatever effect we need. Deal damage with the bite, the breath weapon, or launch mortars when appropriate - */ - @SuppressWarnings("unchecked") - protected void executeAttacks() - { - if (this.currentState == HydraHeadContainer.STATE_MORTAR_LAUNCH && this.ticksProgress % 10 == 0) - { + private void executeAttacks() { + if (this.currentState == State.MORTAR_SHOOTING && this.ticksProgress % 10 == 0) { Entity lookTarget = getHeadLookTarget(); - if (lookTarget != null && (lookTarget instanceof EntityTFHydraPart || lookTarget instanceof EntityDragonPart)) - { + if (lookTarget instanceof EntityTFHydraPart || lookTarget instanceof MultiPartEntityPart) { // stop hurting yourself! this.endCurrentAction(); - } - else - { - EntityTFHydraMortar mortar = new EntityTFHydraMortar(headEntity.worldObj, this.headEntity); - - Vec3 vector = headEntity.getLookVec(); - - double dist = 3.5; - double px = headEntity.posX + vector.xCoord * dist; - double py = headEntity.posY + 1 + vector.yCoord * dist; - double pz = headEntity.posZ + vector.zCoord * dist; + } else { + EntityTFHydraMortar mortar = new EntityTFHydraMortar(headEntity.world, this.headEntity); - mortar.setLocationAndAngles(px, py, pz, 0, 0); - // launch blasting mortars if the player is hiding - if (this.targetEntity != null && !headEntity.canEntityBeSeen(this.targetEntity)) - { - //System.out.println("Launching blasting mortar at hiding target."); + if (this.targetEntity != null && !headEntity.getEntitySenses().canSee(this.targetEntity)) { mortar.setToBlasting(); } - headEntity.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1008, (int)headEntity.posX, (int)headEntity.posY, (int)headEntity.posZ, 0); + headEntity.world.playEvent(1016, new BlockPos(headEntity), 0); - headEntity.worldObj.spawnEntityInWorld(mortar); + headEntity.world.spawnEntity(mortar); } } - if (headEntity.getState() == STATE_BITE_BITING) - { - // damage nearby things - List nearbyList = headEntity.worldObj.getEntitiesWithinAABBExcludingEntity(headEntity, headEntity.boundingBox.expand(0.0, 1.0, 0.0)); - - for (Entity nearby : nearbyList) - { - if (nearby instanceof EntityLivingBase && !(nearby instanceof EntityTFHydraPart) && !(nearby instanceof EntityTFHydra) && !(nearby instanceof EntityDragonPart)) - { - // bite it! - nearby.attackEntityFrom(DamageSource.causeMobDamage(hydraObj), BITE_DAMAGE); - } - } - } - - if (headEntity.getState() == STATE_FLAME_BREATHING) - { - Entity target = getHeadLookTarget(); - - if (target != null) - { - if (target instanceof EntityTFHydraPart || target instanceof EntityDragonPart) - { - // stop hurting yourself! - this.endCurrentAction(); - - //System.out.println("Stopping breath from head " + headNum + " because I am about to hit" + target); - } - else if (!target.isImmuneToFire() && target.attackEntityFrom(DamageSource.inFire, FLAME_DAMAGE)) - { - target.setFire(FLAME_BURN_FACTOR); - } - } + if (headEntity.getState() == State.BITING) { + // damage nearby things + List nearbyList = headEntity.world.getEntitiesWithinAABBExcludingEntity(headEntity, headEntity.getEntityBoundingBox().grow(0.0, 1.0, 0.0)); + + for (Entity nearby : nearbyList) { + if (nearby instanceof EntityLivingBase && !(nearby instanceof EntityTFHydraPart) && !(nearby instanceof EntityTFHydra) && !(nearby instanceof MultiPartEntityPart)) { + // bite it! + nearby.attackEntityFrom(DamageSource.causeMobDamage(hydra), BITE_DAMAGE); + } + } } + if (headEntity.getState() == State.FLAMING) { + Entity target = getHeadLookTarget(); + + if (target != null) { + if (target instanceof EntityTFHydraPart || target instanceof MultiPartEntityPart) { + // stop hurting yourself! + this.endCurrentAction(); + } else if (!target.isImmuneToFire() && target.attackEntityFrom(DamageSource.IN_FIRE, FLAME_DAMAGE)) { + target.setFire(FLAME_BURN_FACTOR); + } + } + } } - - protected void setDifficultyVariables() { - if (this.hydraObj.worldObj.difficultySetting != EnumDifficulty.HARD) - { + private void setDifficultyVariables() { + if (this.hydra.world.getDifficulty() != EnumDifficulty.HARD) { HydraHeadContainer.FLAME_BREATH_TRACKING_SPEED = 0.04D; - - } - else - { + } else { // hard mode! HydraHeadContainer.FLAME_BREATH_TRACKING_SPEED = 0.1D; // higher is harder } - } - /** - * What, if anything, is the head currently looking at? - */ - @SuppressWarnings("unchecked") + // TODO this seems copied from somewhere? + @Nullable private Entity getHeadLookTarget() { Entity pointedEntity = null; double range = 30.0D; - Vec3 srcVec = Vec3.createVectorHelper(headEntity.posX, headEntity.posY + 1.0, headEntity.posZ); - Vec3 lookVec = headEntity.getLook(1.0F); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - float var9 = 3.0F; - List possibleList = headEntity.worldObj.getEntitiesWithinAABBExcludingEntity(headEntity, headEntity.boundingBox.addCoord(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range).expand(var9, var9, var9)); - double hitDist = 0; - - for (Entity possibleEntity : possibleList) - { - if (possibleEntity.canBeCollidedWith() && possibleEntity != headEntity && possibleEntity != necka && possibleEntity != neckb && possibleEntity != neckc) - { - float borderSize = possibleEntity.getCollisionBorderSize(); - AxisAlignedBB collisionBB = possibleEntity.boundingBox.expand((double)borderSize, (double)borderSize, (double)borderSize); - MovingObjectPosition interceptPos = collisionBB.calculateIntercept(srcVec, destVec); - - if (collisionBB.isVecInside(srcVec)) - { - if (0.0D < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = 0.0D; - } - } - else if (interceptPos != null) - { - double possibleDist = srcVec.distanceTo(interceptPos.hitVec); - - if (possibleDist < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = possibleDist; - } - } - } - } + Vec3d srcVec = new Vec3d(headEntity.posX, headEntity.posY + 1.0, headEntity.posZ); + Vec3d lookVec = headEntity.getLook(1.0F); + RayTraceResult raytrace = headEntity.world.rayTraceBlocks(srcVec, srcVec.add(lookVec.x * range, lookVec.y * range, lookVec.z * range)); + BlockPos hitpos = raytrace != null ? raytrace.getBlockPos() : null; + double rx = hitpos == null ? range : Math.min(range, Math.abs(headEntity.posX - hitpos.getX())); + double ry = hitpos == null ? range : Math.min(range, Math.abs(headEntity.posY - hitpos.getY())); + double rz = hitpos == null ? range : Math.min(range, Math.abs(headEntity.posZ - hitpos.getZ())); + Vec3d destVec = srcVec.add(lookVec.x * range, lookVec.y * range, lookVec.z * range); + float var9 = 3.0F; + List possibleList = headEntity.world.getEntitiesWithinAABBExcludingEntity(headEntity, headEntity.getEntityBoundingBox().offset(lookVec.x * rx, lookVec.y * ry, lookVec.z * rz).grow(var9, var9, var9)); + double hitDist = 0; + + for (Entity possibleEntity : possibleList) { + if (possibleEntity.canBeCollidedWith() && possibleEntity != headEntity && possibleEntity != necka && possibleEntity != neckb && possibleEntity != neckc) { + float borderSize = possibleEntity.getCollisionBorderSize(); + AxisAlignedBB collisionBB = possibleEntity.getEntityBoundingBox().grow((double) borderSize, (double) borderSize, (double) borderSize); + RayTraceResult interceptPos = collisionBB.calculateIntercept(srcVec, destVec); + + if (collisionBB.contains(srcVec)) { + if (0.0D < hitDist || hitDist == 0.0D) { + pointedEntity = possibleEntity; + hitDist = 0.0D; + } + } else if (interceptPos != null) { + double possibleDist = srcVec.distanceTo(interceptPos.hitVec); + + if (possibleDist < hitDist || hitDist == 0.0D) { + pointedEntity = possibleEntity; + hitDist = possibleDist; + } + } + } + } return pointedEntity; } - - /** - * What state should we go to next? - */ - public void setNextState(int next) - { + + public void setNextState(State next) { this.nextState = next; } - - /** - * - */ - public void endCurrentAction() - { + + public void endCurrentAction() { this.ticksProgress = this.ticksNeeded; } - + /** * Search for nearby heads with the string as their name */ - @SuppressWarnings("unchecked") - private EntityTFHydraHead findNearbyHead(String string) - { - - List nearbyHeads = hydraObj.worldObj.getEntitiesWithinAABB(EntityTFHydraHead.class, AxisAlignedBB.getBoundingBox(hydraObj.posX, hydraObj.posY, hydraObj.posZ, hydraObj.posX + 1, hydraObj.posY + 1, hydraObj.posZ + 1).expand(16.0D, 16.0D, 16.0D)); - - for (EntityTFHydraHead nearbyHead : nearbyHeads) - { - + @Nullable + private EntityTFHydraHead findNearbyHead(String string) { + List nearbyHeads = hydra.world.getEntitiesWithinAABB(EntityTFHydraHead.class, new AxisAlignedBB(hydra.posX, hydra.posY, hydra.posZ, hydra.posX + 1, hydra.posY + 1, hydra.posZ + 1).grow(16.0D, 16.0D, 16.0D)); + + for (EntityTFHydraHead nearbyHead : nearbyHeads) { if (nearbyHead.getPartName().equals(string)) { - nearbyHead.hydraObj = hydraObj; - - //System.out.println("Reconnected hydra with head named " + string + " in world " + hydraObj.worldObj); - + nearbyHead.hydra = hydra; return nearbyHead; } - } - //System.out.println("Did not find head named " + string); return null; } - - /** - * The current neck length depends on the current state, and how far along are we from the previous state - * Other factors include which head it is. - */ - protected float getCurrentNeckLength() - { - float prevLength = stateNeckLength[this.headNum][this.prevState]; - float curLength = stateNeckLength[this.headNum][this.currentState]; - float progress = (float)ticksProgress / (float)ticksNeeded; - return prevLength + (curLength - prevLength) * progress; - } - - /** - * The current x rotation depends on the current state, and how far along are we from the previous state - * Other factors include which head it is. - */ - protected float getCurrentHeadXRotation() - { - float prevRotation = stateXRotations[this.headNum][this.prevState]; - float currentRotation = stateXRotations[this.headNum][this.currentState]; - float progress = (float)ticksProgress / (float)ticksNeeded; + private float getCurrentNeckLength() { + float prevLength = stateNeckLength[this.headNum].get(prevState); + float curLength = stateNeckLength[this.headNum].get(currentState); + float progress = (float) ticksProgress / (float) ticksNeeded; - return prevRotation + (currentRotation - prevRotation) * progress; + return (float) MathHelper.clampedLerp(prevLength, curLength, progress); } - - protected float getCurrentHeadYRotation() - { - float prevRotation = stateYRotations[this.headNum][this.prevState]; - float currentRotation = stateYRotations[this.headNum][this.currentState]; - float progress = (float)ticksProgress / (float)ticksNeeded; + private float getCurrentHeadXRotation() { + float prevRotation = stateXRotations[this.headNum].get(prevState); + float currentRotation = stateXRotations[this.headNum].get(currentState); + float progress = (float) ticksProgress / (float) ticksNeeded; - return prevRotation + (currentRotation - prevRotation) * progress; + return (float) MathHelper.clampedLerp(prevRotation, currentRotation, progress); } + private float getCurrentHeadYRotation() { + float prevRotation = stateYRotations[this.headNum].get(prevState); + float currentRotation = stateYRotations[this.headNum].get(currentState); + float progress = (float) ticksProgress / (float) ticksNeeded; - protected float getCurrentMouthOpen() - { - float prevOpen = stateMouthOpen[this.headNum][this.prevState]; - float curOpen = stateMouthOpen[this.headNum][this.currentState]; - float progress = (float)ticksProgress / (float)ticksNeeded; + return (float) MathHelper.clampedLerp(prevRotation, currentRotation, progress); + } - return prevOpen + (curOpen - prevOpen) * progress; + protected float getCurrentMouthOpen() { + float prevOpen = stateMouthOpen[this.headNum].get(prevState); + float curOpen = stateMouthOpen[this.headNum].get(currentState); + float progress = (float) ticksProgress / (float) ticksNeeded; + + return (float) MathHelper.clampedLerp(prevOpen, curOpen, progress); } /** * Sets the four neck positions ranging from the start position to the head position. - * - * @param hi head index - * @param startX - * @param startY - * @param startZ - * @param startYaw - * @param startPitch */ - protected void setNeckPositon(double startX, double startY, double startZ, float startYaw, float startPitch) { + protected void setNeckPosition(double startX, double startY, double startZ, float startYaw, float startPitch) { double endX = headEntity.posX; double endY = headEntity.posY; double endZ = headEntity.posZ; float endYaw = headEntity.rotationYaw; float endPitch = headEntity.rotationPitch; - - for (; startYaw - endYaw < -180F; endYaw -= 360F) { } - for (; startYaw - endYaw >= 180F; endYaw += 360F) { } - for (; startPitch - endPitch < -180F; endPitch -= 360F) { } - for (; startPitch - endPitch >= 180F; endPitch += 360F) { } - + for (; startYaw - endYaw < -180F; endYaw -= 360F) { + } + for (; startYaw - endYaw >= 180F; endYaw += 360F) { + } + for (; startPitch - endPitch < -180F; endPitch -= 360F) { + } + for (; startPitch - endPitch >= 180F; endPitch += 360F) { + } + // translate the end position back 1 unit - if (endPitch > 0) - { + if (endPitch > 0) { // if we are looking down, don't raise the first neck position, it looks weird - Vec3 vector = Vec3.createVectorHelper(0, 0, -1.0); - vector.rotateAroundY((-endYaw * 3.141593F) / 180F); - endX += vector.xCoord; - endY += vector.yCoord; - endZ += vector.zCoord; - } - else - { + Vec3d vector = new Vec3d(0, 0, -1.0).rotateYaw((-endYaw * 3.141593F) / 180F); + endX += vector.x; + endY += vector.y; + endZ += vector.z; + } else { // but if we are looking up, lower it or it goes through the crest - Vec3 vector = headEntity.getLookVec(); + Vec3d vector = headEntity.getLookVec(); float dist = 1.0f; - - endX -= vector.xCoord * dist; - endY -= vector.yCoord * dist; - endZ -= vector.zCoord * dist; + + endX -= vector.x * dist; + endY -= vector.y * dist; + endZ -= vector.z * dist; } - float factor = 0F; - factor = 0.00F; + factor = 0.00F; necka.setPosition(endX + (startX - endX) * factor, endY + (startY - endY) * factor, endZ + (startZ - endZ) * factor); necka.rotationYaw = endYaw + (startYaw - endYaw) * factor; necka.rotationPitch = endPitch + (startPitch - endPitch) * factor; - factor = 0.25F; + factor = 0.25F; neckb.setPosition(endX + (startX - endX) * factor, endY + (startY - endY) * factor, endZ + (startZ - endZ) * factor); neckb.rotationYaw = endYaw + (startYaw - endYaw) * factor; neckb.rotationPitch = endPitch + (startPitch - endPitch) * factor; - factor = 0.50F; + factor = 0.50F; neckc.setPosition(endX + (startX - endX) * factor, endY + (startY - endY) * factor, endZ + (startZ - endZ) * factor); neckc.rotationYaw = endYaw + (startYaw - endYaw) * factor; neckc.rotationPitch = endPitch + (startPitch - endPitch) * factor; - factor = 0.75F; + factor = 0.75F; neckd.setPosition(endX + (startX - endX) * factor, endY + (startY - endY) * factor, endZ + (startZ - endZ) * factor); neckd.rotationYaw = endYaw + (startYaw - endYaw) * factor; neckd.rotationPitch = endPitch + (startPitch - endPitch) * factor; - factor = 1.0F; + factor = 1.0F; necke.setPosition(endX + (startX - endX) * factor, endY + (startY - endY) * factor, endZ + (startZ - endZ) * factor); necke.rotationYaw = endYaw + (startYaw - endYaw) * factor; necke.rotationPitch = endPitch + (startPitch - endPitch) * factor; - } - - /** - * Face a vector in front of the hydra entity. - * This is used to give the heads something to look at when we don't have an acutal target. - */ - protected void faceIdle(float yawConstraint, float pitchConstraint) { - //headEntity.rotationPitch = hydraObj.rotationPitch; - //headEntity.rotationYaw = hydraObj.rotationYaw; - - float angle = (((hydraObj.rotationYaw) * 3.141593F) / 180F); + + private void faceIdle(float yawConstraint, float pitchConstraint) { + float angle = (((hydra.rotationYaw) * 3.141593F) / 180F); float distance = 30.0F; - double dx = hydraObj.posX - MathHelper.sin(angle) * distance; - double dy = hydraObj.posY + 3.0; - double dz = hydraObj.posZ + MathHelper.cos(angle) * distance; - - faceVec(dx, dy, dz, yawConstraint, pitchConstraint); + double dx = hydra.posX - MathHelper.sin(angle) * distance; + double dy = hydra.posY + 3.0; + double dz = hydra.posZ + MathHelper.cos(angle) * distance; + + faceVec(dx, dy, dz, yawConstraint, pitchConstraint); } - /** - * Face this head towards an entity - */ public void faceEntity(Entity entity, float yawConstraint, float pitchConstraint) { double yTarget; - if (entity instanceof EntityLivingBase) - { - EntityLivingBase entityliving = (EntityLivingBase)entity; - yTarget = entityliving.posY + entityliving.getEyeHeight(); - } - else - { - yTarget = (entity.boundingBox.minY + entity.boundingBox.maxY) / 2D; - } - - faceVec(entity.posX, yTarget, entity.posZ, yawConstraint, pitchConstraint); - - // let's just set the target vector here - this.targetX = entity.posX; - this.targetY = entity.posY; - this.targetZ = entity.posZ; + if (entity instanceof EntityLivingBase) { + EntityLivingBase entityliving = (EntityLivingBase) entity; + yTarget = entityliving.posY + entityliving.getEyeHeight(); + } else { + yTarget = (entity.getEntityBoundingBox().minY + entity.getEntityBoundingBox().maxY) / 2D; + } + + faceVec(entity.posX, yTarget, entity.posZ, yawConstraint, pitchConstraint); + + // let's just set the target vector here + this.targetX = entity.posX; + this.targetY = entity.posY; + this.targetZ = entity.posZ; } - - /** - * Face this head towards a specific Vector - */ - public void faceVec(double xCoord, double yCoord, double zCoord, float yawConstraint, float pitchConstraint) { - double xOffset = xCoord - headEntity.posX; - double zOffset = zCoord - headEntity.posZ; - double yOffset = (headEntity.posY + 1.0) - yCoord; - - double distance = MathHelper.sqrt_double(xOffset * xOffset + zOffset * zOffset); - float xyAngle = (float)((Math.atan2(zOffset, xOffset) * 180D) / Math.PI) - 90F; - float zdAngle = (float)(-((Math.atan2(yOffset, distance) * 180D) / Math.PI)); + + private void faceVec(double x, double y, double z, float yawConstraint, float pitchConstraint) { + double xOffset = x - headEntity.posX; + double zOffset = z - headEntity.posZ; + double yOffset = (headEntity.posY + 1.0) - y; + + double distance = MathHelper.sqrt(xOffset * xOffset + zOffset * zOffset); + float xyAngle = (float) ((Math.atan2(zOffset, xOffset) * 180D) / Math.PI) - 90F; + float zdAngle = (float) (-((Math.atan2(yOffset, distance) * 180D) / Math.PI)); headEntity.rotationPitch = -updateRotation(headEntity.rotationPitch, zdAngle, pitchConstraint); headEntity.rotationYaw = updateRotation(headEntity.rotationYaw, xyAngle, yawConstraint); - -// System.out.println("Updating head " + head + " with rotationPitch " + head.rotationPitch); -// System.out.println("Updating head " + head + " with rotationYaw " + head.rotationYaw); + } + + private float updateRotation(float current, float intended, float increment) { + float delta = MathHelper.wrapDegrees(intended - current); + if (delta > increment) { + delta = increment; + } + + if (delta < -increment) { + delta = -increment; + } + + return MathHelper.wrapDegrees(current + delta); } - - /** - * Arguments: current rotation, intended rotation, max increment. - */ - private float updateRotation(float current, float intended, float increment) - { - float delta = MathHelper.wrapAngleTo180_float(intended - current); - - if (delta > increment) - { - delta = increment; - } - - if (delta < -increment) - { - delta = -increment; - } - - return MathHelper.wrapAngleTo180_float(current + delta); - } - + + @Nullable public Entity getTargetEntity() { return targetEntity; } - public void setTargetEntity(Entity targetEntity) { + public void setTargetEntity(@Nullable Entity targetEntity) { this.targetEntity = targetEntity; } @@ -1175,29 +940,43 @@ public void setHurtTime(int hurtTime) { neckd.hurtTime = hurtTime; necke.hurtTime = hurtTime; } - + /** * At certain times, some of the heads are "dead" and hidden */ - public boolean shouldRenderHead() - { - return this.headEntity.getState() != STATE_DEAD && this.headEntity.deathTime < 20; + public boolean shouldRenderHead() { + return this.headEntity.getState() != State.DEAD && this.headEntity.deathTime < 20; } /** * Same with the neck parts */ - public boolean shouldRenderNeck(int neckNum) - { - int time = 30 + 10 * neckNum; - return this.headEntity.getState() != STATE_DEAD && this.headEntity.deathTime < time; + public boolean shouldRenderNeck(int neckNum) { + int time = 30 + 10 * neckNum; + return this.headEntity.getState() != State.DEAD && this.headEntity.deathTime < time; } /** * Is this head active, that is, not dying or dead? */ public boolean isActive() { - return this.currentState != STATE_DYING && this.currentState != STATE_DEAD; + return this.currentState != State.DYING && this.currentState != State.DEAD; + } + + public boolean isIdle() { + return this.currentState == State.IDLE && (this.nextState == NEXT_AUTOMATIC || this.nextState == State.IDLE); + } + + public boolean isAttacking() { + return this.currentState == State.BITE_BEGINNING || this.currentState == State.BITE_READY + || this.currentState == State.BITING || this.currentState == State.FLAME_BEGINNING + || this.currentState == State.FLAMING || this.currentState == State.MORTAR_BEGINNING + || this.currentState == State.MORTAR_SHOOTING; + } + + public boolean isBiting() { + return this.currentState == State.BITE_BEGINNING || this.currentState == State.BITE_READY + || this.currentState == State.BITING || this.nextState == State.BITE_BEGINNING; } /** diff --git a/src/main/java/twilightforest/entity/boss/package-info.java b/src/main/java/twilightforest/entity/boss/package-info.java new file mode 100644 index 0000000000..dad4735e87 --- /dev/null +++ b/src/main/java/twilightforest/entity/boss/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.entity.boss; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/finalcastle/EntityTFCastleGuardian.java b/src/main/java/twilightforest/entity/finalcastle/EntityTFCastleGuardian.java new file mode 100644 index 0000000000..2aa1920710 --- /dev/null +++ b/src/main/java/twilightforest/entity/finalcastle/EntityTFCastleGuardian.java @@ -0,0 +1,83 @@ +package twilightforest.entity.finalcastle; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCreature; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; + +public class EntityTFCastleGuardian extends EntityCreature { // Not exactly living but requires the logic >.> + public EntityTFCastleGuardian(World worldIn) { + super(worldIn); + + this.setSize(1.8f, 2.4f); + } + + @Override + protected void initEntityAI() { + //this.tasks.addTask(0, new EntityAIAvoidEntity<>(this, EntityPlayer.class, 10.0F, 0.5F, 0.5F)); + //this.tasks.addTask(1, new EntityAIWanderAvoidWater(this, 0.5, 0.5f)); + //this.tasks.addTask(2, new EntityAILookIdle(this)); + } + + @Override + protected float updateDistance(float renderYawOffset, float p_110146_2_) { + float f = MathHelper.wrapDegrees(renderYawOffset - this.renderYawOffset); + this.renderYawOffset += f * 0.5F; + float f1 = MathHelper.wrapDegrees(this.rotationYaw - this.renderYawOffset); + boolean flag = f1 < -90.0F || f1 >= 90.0F; + + if (f1 < -75.0F) + f1 = -75.0F; + + if (f1 >= 75.0F) + f1 = 75.0F; + + this.renderYawOffset = this.rotationYaw - f1; + + if (f1 * f1 > 2500.0F) + this.renderYawOffset += f1 * 0.5F; + + if (flag) + p_110146_2_ *= -1.0F; + + return p_110146_2_; + } + + @Override + public AxisAlignedBB getCollisionBoundingBox() { + return this.getEntityBoundingBox(); + } + + @Override + public boolean canBeCollidedWith() { + return true; + } + + @Override + protected boolean canBeRidden(Entity entityIn) { + return false; + } + + @Override // So it won't be allowed to be duplicated by Mod mob spawners + public boolean isNonBoss() { + return false; + } + + @Override + public boolean isPushedByWater() { + return false; + } + + @Override + public float getEyeHeight() { + return 1.865f; + } + + @Override + public boolean canBreatheUnderwater() { + return false; + } + + +} diff --git a/src/main/java/twilightforest/entity/package-info.java b/src/main/java/twilightforest/entity/package-info.java new file mode 100644 index 0000000000..22d74745cc --- /dev/null +++ b/src/main/java/twilightforest/entity/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.entity; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/passive/EntityTFBighorn.java b/src/main/java/twilightforest/entity/passive/EntityTFBighorn.java index 621277fed6..8e0b3c4ca6 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFBighorn.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFBighorn.java @@ -1,90 +1,66 @@ package twilightforest.entity.passive; -import java.util.Random; - import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.passive.EntitySheep; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.DamageSource; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import twilightforest.TwilightForestMod; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.EnumMap; +import java.util.Map; +import java.util.Random; +public class EntityTFBighorn extends EntitySheep { -public class EntityTFBighorn extends EntitySheep -{ + public static final ResourceLocation SHEARED_LOOT_TABLE = TwilightForestMod.prefix("entities/bighorn_sheep/sheared"); + public static final Map COLORED_LOOT_TABLES; - public EntityTFBighorn(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "bighorn.png"; - setSize(0.9F, 1.3F); - } - - public EntityTFBighorn(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } + static { + Map map = new EnumMap<>(EnumDyeColor.class); + for (EnumDyeColor color : EnumDyeColor.values()) { + map.put(color, TwilightForestMod.prefix("entities/bighorn_sheep/" + color.getName())); + } + COLORED_LOOT_TABLES = Collections.unmodifiableMap(map); + } - /** - * 50% brown, 50% any other color - * - * @param random - * @return - */ - public static int getRandomFleeceColor(Random random) - { - if (random.nextInt(2) == 0) - { - return 12; - } - else - { - return random.nextInt(15); - } - } - + public EntityTFBighorn(World world) { + super(world); + setSize(0.9F, 1.3F); + } - /** - * Entity init, set our fleece color - */ - @Override - public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) - { - par1EntityLivingData = super.onSpawnWithEgg(par1EntityLivingData); - this.setFleeceColor(getRandomFleeceColor(this.worldObj.rand)); - return par1EntityLivingData; - } - - /** - * What is our baby?! - */ - @Override - public EntitySheep createChild(EntityAgeable entityanimal) - { - EntityTFBighorn otherParent = (EntityTFBighorn)entityanimal; - EntityTFBighorn babySheep = new EntityTFBighorn(worldObj); - if(rand.nextBoolean()) - { - babySheep.setFleeceColor(getFleeceColor()); - } else - { - babySheep.setFleeceColor(otherParent.getFleeceColor()); - } - return babySheep; - } + public EntityTFBighorn(World world, double x, double y, double z) { + this(world); + this.setPosition(x, y, z); + } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + public ResourceLocation getLootTable() { + return this.getSheared() ? SHEARED_LOOT_TABLE : COLORED_LOOT_TABLES.get(this.getFleeceColor()); } + private static EnumDyeColor getRandomFleeceColor(Random random) { + return random.nextBoolean() + ? EnumDyeColor.BROWN + : EnumDyeColor.byMetadata(random.nextInt(16)); + } + + @Override + public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) { + livingdata = super.onInitialSpawn(difficulty, livingdata); + this.setFleeceColor(getRandomFleeceColor(this.world.rand)); + return livingdata; + } + + @Override + public EntitySheep createChild(EntityAgeable ageable) { + EntityTFBighorn otherParent = (EntityTFBighorn) ageable; + EntityTFBighorn babySheep = new EntityTFBighorn(world); + babySheep.setFleeceColor(getDyeColorMixFromParents(this, otherParent)); + return babySheep; + } } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFBird.java b/src/main/java/twilightforest/entity/passive/EntityTFBird.java index efd22c99b4..096cccb376 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFBird.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFBird.java @@ -1,68 +1,62 @@ package twilightforest.entity.passive; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import twilightforest.TwilightForestMod; +import javax.annotation.Nonnull; public abstract class EntityTFBird extends EntityAnimal { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/bird"); + + // same items as EntityChicken / EntityParrot + protected static final Ingredient SEEDS = Ingredient.fromItems(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); + public float flapLength = 0.0F; public float flapIntensity = 0.0F; public float lastFlapIntensity; public float lastFlapLength; public float flapSpeed = 1.0F; - public EntityTFBird(World par1World) { - super(par1World); - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - public boolean isAIEnabled() { - return true; + public EntityTFBird(World world) { + super(world); } - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ @Override public void onLivingUpdate() { - super.onLivingUpdate(); - this.lastFlapLength = this.flapLength; - this.lastFlapIntensity = this.flapIntensity; - this.flapIntensity = (float)(this.flapIntensity + (this.onGround ? -1 : 4) * 0.3D); - - if (this.flapIntensity < 0.0F) - { - this.flapIntensity = 0.0F; - } - - if (this.flapIntensity > 1.0F) - { - this.flapIntensity = 1.0F; - } - - if (!this.onGround && this.flapSpeed < 1.0F) - { - this.flapSpeed = 1.0F; - } - - this.flapSpeed = (float)(this.flapSpeed * 0.9D); - - // don't fall as fast - if (!this.onGround && this.motionY < 0.0D) - { - this.motionY *= 0.6D; - } - - this.flapLength += this.flapSpeed * 2.0F; - + super.onLivingUpdate(); + this.lastFlapLength = this.flapLength; + this.lastFlapIntensity = this.flapIntensity; + this.flapIntensity = (float) (this.flapIntensity + (this.onGround ? -1 : 4) * 0.3D); + + if (this.flapIntensity < 0.0F) { + this.flapIntensity = 0.0F; + } + + if (this.flapIntensity > 1.0F) { + this.flapIntensity = 1.0F; + } + + if (!this.onGround && this.flapSpeed < 1.0F) { + this.flapSpeed = 1.0F; + } + + this.flapSpeed = (float) (this.flapSpeed * 0.9D); + + // don't fall as fast + if (!this.onGround && this.motionY < 0.0D) { + this.motionY *= 0.6D; + } + + this.flapLength += this.flapSpeed * 2.0F; + // // rise up when we go fast? // if (this.getMoveHelper().getSpeed() > 0.39F && this.moveForward > 0.1F) // { @@ -71,45 +65,34 @@ public void onLivingUpdate() { // } } - /** - * Called when the mob is falling. Calculates and applies fall damage. - */ @Override - protected void fall(float par1) {} - - /** - * returns if this entity triggers Blocks.onEntityWalking on the blocks they walk on. used for spiders and wolves to - * prevent them from trampling crops - */ - @Override - protected boolean canTriggerWalking() - { - return false; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ + protected void updateFallState(double y, boolean onGroundIn, @Nonnull IBlockState state, @Nonnull BlockPos pos) { + } + @Override - protected Item getDropItem() { - return Items.feather; + public void fall(float dist, float damageMultiplier) { } - /** - * This function is used when two same-species animals in 'love mode' breed to generate the new baby animal. - */ @Override - public EntityAnimal createChild(EntityAgeable entityanimal) - { + protected boolean canTriggerWalking() { + return false; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + public EntityAnimal createChild(EntityAgeable entityanimal) { return null; } /** * Overridden by flying birds */ - public boolean isBirdLanded() - { - return true; - } + public boolean isBirdLanded() { + return true; + } } \ No newline at end of file diff --git a/src/main/java/twilightforest/entity/passive/EntityTFBoar.java b/src/main/java/twilightforest/entity/passive/EntityTFBoar.java index 787cd4d72e..eb51f8d80c 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFBoar.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFBoar.java @@ -2,45 +2,32 @@ import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.passive.EntityPig; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; - +import twilightforest.TwilightForestMod; public class EntityTFBoar extends EntityPig { - - public EntityTFBoar(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "wildboar.png"; - setSize(0.9F, 0.9F); - } - - public EntityTFBoar(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } - - /** - * What is our baby?! - */ - @Override - public EntityPig createChild(EntityAgeable entityanimal) - { - return new EntityTFBoar(worldObj); - } - - /** - * Trigger achievement when killed - */ + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/boar"); + + public EntityTFBoar(World world) { + super(world); + setSize(0.9F, 0.9F); + } + + public EntityTFBoar(World world, double x, double y, double z) { + this(world); + this.setPosition(x, y, z); + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + public EntityPig createChild(EntityAgeable entityanimal) { + return new EntityTFBoar(world); } } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFBunny.java b/src/main/java/twilightforest/entity/passive/EntityTFBunny.java index fdbcd1a371..cc16c3dc6e 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFBunny.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFBunny.java @@ -3,180 +3,117 @@ import net.minecraft.block.material.Material; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAvoidEntity; -import net.minecraft.entity.ai.EntityAILookIdle; -import net.minecraft.entity.ai.EntityAIPanic; -import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAITempt; -import net.minecraft.entity.ai.EntityAIWander; -import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.ai.*; import net.minecraft.entity.passive.IAnimals; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.init.Items; +import net.minecraft.item.Item; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.DamageSource; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; - +import twilightforest.TwilightForestMod; public class EntityTFBunny extends EntityCreature implements IAnimals { - public EntityTFBunny(World par1World) { - super(par1World); - //texture = TwilightForestMod.MODEL_DIR + "bunnydutch.png"; - - this.setSize(0.3F, 0.7F); - + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/bunny"); + private static final DataParameter DATA_TYPE = EntityDataManager.createKey(EntityTFBunny.class, DataSerializers.BYTE); + + public EntityTFBunny(World world) { + super(world); + this.setSize(0.3F, 0.6F); + // maybe this will help them move cuter? this.stepHeight = 1; - - // squirrel AI - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIPanic(this, 2.0F)); - this.tasks.addTask(2, new EntityAITempt(this, 1.0F, Items.wheat_seeds, true)); - this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityPlayer.class, 2.0F, 0.8F, 1.33F)); - this.tasks.addTask(5, new EntityAIWander(this, 0.8F)); - this.tasks.addTask(6, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); - - // random color - setBunnyType(rand.nextInt(4)); + setBunnyType(rand.nextInt(4)); + } + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 2.0F)); + this.tasks.addTask(2, new EntityAITempt(this, 1.0F, Items.CARROT, true)); + this.tasks.addTask(2, new EntityAITempt(this, 1.0F, Items.GOLDEN_CARROT, true)); + this.tasks.addTask(2, new EntityAITempt(this, 1.0F, Item.getItemFromBlock(Blocks.YELLOW_FLOWER), true)); + this.tasks.addTask(3, new EntityAIAvoidEntity<>(this, EntityPlayer.class, 2.0F, 0.8F, 1.33F)); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 0.8F)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.0F)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); + this.tasks.addTask(8, new EntityAILookIdle(this)); } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(3.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.3D); + } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(3.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3D); - } - + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_TYPE, (byte) 0); + } + @Override - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(16, Byte.valueOf((byte)0)); - } - - /** - * Returns true if the newer Entity AI code should be run - */ + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setInteger("BunnyType", this.getBunnyType()); + } + @Override - public boolean isAIEnabled() { - return true; + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setBunnyType(compound.getInteger("BunnyType")); } - -// /** -// * Returns the texture's file path as a String. -// */ -// @Override -// public String getTexture() -// { -// switch (this.getBunnyType()) -// { -// case 0: -// return TwilightForestMod.MODEL_DIR + "bunnydutch.png"; -// -// case 1: -// return TwilightForestMod.MODEL_DIR + "bunnydutch.png"; -// -// case 2: -// return TwilightForestMod.MODEL_DIR + "bunnywhite.png"; -// -// case 3: -// return TwilightForestMod.MODEL_DIR + "bunnybrown.png"; -// -// default: -// return super.getTexture(); -// } -// } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ + @Override - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setInteger("BunnyType", this.getBunnyType()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + public int getBunnyType() { + return dataManager.get(DATA_TYPE); + } + + public void setBunnyType(int type) { + dataManager.set(DATA_TYPE, (byte) type); + } + @Override - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setBunnyType(par1NBTTagCompound.getInteger("BunnyType")); - } - - public int getBunnyType() - { - return this.dataWatcher.getWatchableObjectByte(16); - } - - public void setBunnyType(int par1) - { - this.dataWatcher.updateObject(16, Byte.valueOf((byte)par1)); - } - - - /** - * Actually only used for the shadow - */ + public float getEyeHeight() { + return this.height * 0.5F; + } + @Override public float getRenderSizeModifier() { - return 0.3F; + return 0.3F; } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ + @Override - protected boolean canDespawn() - { - return false; - } - - - /** - * Takes a coordinate in and returns a weight to determine how likely this creature will try to path to the block. - * Args: x, y, z - */ + protected boolean canDespawn() { + return false; + } + @Override - public float getBlockPathWeight(int par1, int par2, int par3) - { - // avoid leaves & wood - Material underMaterial = this.worldObj.getBlock(par1, par2 - 1, par3).getMaterial(); - if (underMaterial == Material.leaves) { + public float getBlockPathWeight(BlockPos pos) { + // avoid leaves & wood + Material underMaterial = this.world.getBlockState(pos.down()).getMaterial(); + if (underMaterial == Material.LEAVES) { return -1.0F; } - if (underMaterial == Material.wood) { + if (underMaterial == Material.WOOD) { return -1.0F; } - if (underMaterial == Material.grass) { + if (underMaterial == Material.GRASS) { return 10.0F; } // default to just prefering lighter areas - return this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; - } - - /** - * Trigger achievement when killed - */ - @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + return this.world.getLightBrightness(pos) - 0.5F; } + } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFDeer.java b/src/main/java/twilightforest/entity/passive/EntityTFDeer.java index 6f7396759e..4076df1f1c 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFDeer.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFDeer.java @@ -2,136 +2,89 @@ import net.minecraft.block.Block; import net.minecraft.entity.EntityAgeable; +import net.minecraft.entity.ai.EntityAIAvoidEntity; import net.minecraft.entity.passive.EntityCow; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.item.TFItems; - +import twilightforest.TFSounds; +import twilightforest.TwilightForestMod; /** * Deer are like quiet, non-milkable cows! - * + *

* Also they look like deer - * - * @author Ben * + * @author Ben */ -public class EntityTFDeer extends EntityCow -{ +public class EntityTFDeer extends EntityCow { - public EntityTFDeer(World world) - { - super(world); - //texture = TwilightForestMod.MODEL_DIR + "wilddeer.png"; - setSize(0.7F, 2.3F); - -// this.tasks.taskEntries.clear(); -// -// this.tasks.addTask(0, new EntityAISwimming(this)); -// this.tasks.addTask(1, new EntityAITFPanicOnFlockDeath(this, 0.38F)); -// this.tasks.addTask(2, new EntityAIMate(this, 0.2F)); -// this.tasks.addTask(3, new EntityAITempt(this, 0.25F, Items.wheat, false)); -// this.tasks.addTask(4, new EntityAIFollowParent(this, 0.25F)); -// this.tasks.addTask(5, new EntityAIWander(this, 0.2F)); -// this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); -// this.tasks.addTask(7, new EntityAILookIdle(this)); - } - - public EntityTFDeer(World world, double x, double y, double z) - { - this(world); - this.setPosition(x, y, z); - } + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/deer"); + public EntityTFDeer(World world) { + super(world); + setSize(0.7F, 2.3F); + } - /** - * No sounds when idle - */ - @Override - protected String getLivingSound() - { - return null; - } + public EntityTFDeer(World world, double x, double y, double z) { + this(world); + this.setPosition(x, y, z); + } - /** - * Plays step sound at given x, y, z for the entity - */ - @Override - protected void func_145780_a(int par1, int par2, int par3, Block par4) - { - //this.worldObj.playSoundAtEntity(this, "mob.cow.step", 0.15F, 1.0F); - } - - /** - * Not milkable - */ - @Override - public boolean interact(EntityPlayer entityplayer) - { - ItemStack itemstack = entityplayer.inventory.getCurrentItem(); - if(itemstack != null && itemstack.getItem() == Items.bucket) - { - // specifically do not respond to this - return false; - } else - { - return super.interact(entityplayer); - } - } - + @Override + protected void initEntityAI() { + super.initEntityAI(); + tasks.addTask(4, new EntityAIAvoidEntity<>(this, EntityPlayer.class, 16.0F, 1.5D, 1.8D)); + } - /** - * Drop 0-2 items of this living's type - */ - @Override - protected void dropFewItems(boolean par1, int par2) - { - int var3 = this.rand.nextInt(3) + this.rand.nextInt(1 + par2); - int var4; + @Override + public float getEyeHeight() { + return this.height * 0.7F; + } - for (var4 = 0; var4 < var3; ++var4) - { - this.dropItem(Items.leather, 1); - } + @Override + protected SoundEvent getAmbientSound() { + return TFSounds.DEER_IDLE; + } - var3 = this.rand.nextInt(3) + 1 + this.rand.nextInt(1 + par2); + @Override + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return TFSounds.DEER_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.DEER_DEATH; + } - for (var4 = 0; var4 < var3; ++var4) - { - if (this.isBurning()) - { - this.dropItem(TFItems.venisonCooked, 1); - } - else - { - this.dropItem(TFItems.venisonRaw, 1); - } - } - } + @Override + protected void playStepSound(BlockPos pos, Block block) { + } - - /** - * What is our baby going to be? Another deer?! - */ - @Override - public EntityCow createChild(EntityAgeable entityanimal) - { - return new EntityTFDeer(worldObj); - } - - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); + public boolean processInteract(EntityPlayer entityplayer, EnumHand hand) { + ItemStack itemstack = entityplayer.getHeldItem(hand); + if (itemstack.getItem() == Items.BUCKET) { + // specifically do not respond to this + return false; + } else { + return super.processInteract(entityplayer, hand); } } + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + public EntityCow createChild(EntityAgeable entityanimal) { + return new EntityTFDeer(world); + } } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFMobileFirefly.java b/src/main/java/twilightforest/entity/passive/EntityTFMobileFirefly.java index 0e8b4461e8..19c81fc2ca 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFMobileFirefly.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFMobileFirefly.java @@ -1,197 +1,139 @@ package twilightforest.entity.passive; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.passive.EntityAmbientCreature; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class EntityTFMobileFirefly extends EntityAmbientCreature -{ - /** - * randomly selected ChunkCoordinates in a 7x6x7 box around the bat (y offset -2 to 4) towards which it will fly. - * upon getting close a new target will be selected - */ - private ChunkCoordinates currentFlightTarget; - - public EntityTFMobileFirefly(World par1World) - { - super(par1World); - this.setSize(0.5F, 0.5F); - } - /** - * Returns the volume for the sounds this mob makes. - */ - @Override - protected float getSoundVolume() - { - return 0.1F; - } - - /** - * Gets the pitch of living sounds in living entities. - */ - @Override - protected float getSoundPitch() - { - return super.getSoundPitch() * 0.95F; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - @Override - protected String getHurtSound() - { - return "mob.bat.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ - @Override - protected String getDeathSound() - { - return "mob.bat.death"; - } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - @Override - public boolean canBePushed() - { - return false; - } - - protected void collideWithEntity(Entity par1Entity) {} - - /** - * Set monster attributes - */ - @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(6.0D); // max health - } - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - protected boolean isAIEnabled() - { - return true; - } - - /** - * Called to update the entity's position/logic. - */ - @Override - public void onUpdate() - { - super.onUpdate(); - - this.motionY *= 0.6000000238418579D; - } - - @Override - protected void updateAITasks() - { - super.updateAITasks(); - - - if (this.currentFlightTarget != null && (!this.worldObj.isAirBlock(this.currentFlightTarget.posX, this.currentFlightTarget.posY, this.currentFlightTarget.posZ) || this.currentFlightTarget.posY < 1)) - { - this.currentFlightTarget = null; - } - - if (this.currentFlightTarget == null || this.rand.nextInt(30) == 0 || this.currentFlightTarget.getDistanceSquared((int)this.posX, (int)this.posY, (int)this.posZ) < 4.0F) - { - this.currentFlightTarget = new ChunkCoordinates((int)this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int)this.posY + this.rand.nextInt(6) - 2, (int)this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); - } - - double var1 = this.currentFlightTarget.posX + 0.5D - this.posX; - double var3 = this.currentFlightTarget.posY + 0.1D - this.posY; - double var5 = this.currentFlightTarget.posZ + 0.5D - this.posZ; - double speed = 0.05000000149011612D; - this.motionX += (Math.signum(var1) * 0.5D - this.motionX) * speed; - this.motionY += (Math.signum(var3) * 0.699999988079071D - this.motionY) * speed * 2; - this.motionZ += (Math.signum(var5) * 0.5D - this.motionZ) * speed; - float var7 = (float)(Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F; - float var8 = MathHelper.wrapAngleTo180_float(var7 - this.rotationYaw); - this.moveForward = 0.5F; - this.rotationYaw += var8; - } - - /** - * returns if this entity triggers Blocks.onEntityWalking on the blocks they walk on. used for spiders and wolves to - * prevent them from trampling crops - */ - @Override - protected boolean canTriggerWalking() - { - return false; - } - - /** - * Called when the mob is falling. Calculates and applies fall damage. - */ - @Override - protected void fall(float par1) {} - - /** - * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance - * and deal fall damage if landing on the ground. Args: distanceFallenThisTick, onGround - */ - @Override - protected void updateFallState(double par1, boolean par3) {} - - /** - * Return whether this entity should NOT trigger a pressure plate or a tripwire. - */ - @Override - public boolean doesEntityNotTriggerPressurePlate() - { - return true; - } - - /** - * Checks if the entity's current position is a valid location to spawn this entity. - */ - @Override - public boolean getCanSpawnHere() - { - int var1 = MathHelper.floor_double(this.boundingBox.minY); - - if (var1 >= 63) - { - return false; - } - else - { - int var2 = MathHelper.floor_double(this.posX); - int var3 = MathHelper.floor_double(this.posZ); - int var4 = this.worldObj.getBlockLightValue(var2, var1, var3); - byte var5 = 4; - - return var4 > this.rand.nextInt(var5) ? false : super.getCanSpawnHere(); - } - } - - @Override +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; + +public class EntityTFMobileFirefly extends EntityAmbientCreature { + private BlockPos spawnPosition; + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/mobile_firefly"); + + public EntityTFMobileFirefly(World world) { + super(world); + this.setSize(0.5F, 0.5F); + } + + @Override + protected float getSoundVolume() { + return 0.1F; + } + + @Override + protected float getSoundPitch() { + return super.getSoundPitch() * 0.95F; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_BAT_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_BAT_DEATH; + } + + @Override + public boolean canBePushed() { + return false; + } + + @Override + protected void collideWithEntity(Entity entity) { + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(6.0D); + } + + @Override + public void onUpdate() { + super.onUpdate(); + + this.motionY *= 0.6000000238418579D; + } + + @Override + protected void updateAITasks() { + super.updateAITasks(); + + // [VanillaCopy] direct from last half of EntityBat.updateAITasks + if (this.spawnPosition != null && (!this.world.isAirBlock(this.spawnPosition) || this.spawnPosition.getY() < 1)) { + this.spawnPosition = null; + } + + if (this.spawnPosition == null || this.rand.nextInt(30) == 0 || this.spawnPosition.distanceSq((double) ((int) this.posX), (double) ((int) this.posY), (double) ((int) this.posZ)) < 4.0D) { + this.spawnPosition = new BlockPos((int) this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int) this.posY + this.rand.nextInt(6) - 2, (int) this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); + } + + double d0 = (double) this.spawnPosition.getX() + 0.5D - this.posX; + double d1 = (double) this.spawnPosition.getY() + 0.1D - this.posY; + double d2 = (double) this.spawnPosition.getZ() + 0.5D - this.posZ; + this.motionX += (Math.signum(d0) * 0.5D - this.motionX) * 0.10000000149011612D; + this.motionY += (Math.signum(d1) * 0.699999988079071D - this.motionY) * 0.10000000149011612D; + this.motionZ += (Math.signum(d2) * 0.5D - this.motionZ) * 0.10000000149011612D; + float f = (float) (MathHelper.atan2(this.motionZ, this.motionX) * (180D / Math.PI)) - 90.0F; + float f1 = MathHelper.wrapDegrees(f - this.rotationYaw); + this.moveForward = 0.5F; + this.rotationYaw += f1; + // End copy + } + + @Override + protected boolean canTriggerWalking() { + return false; + } + + @Override + public void fall(float dist, float mult) { + } + + @Override + protected void updateFallState(double y, boolean onGround, IBlockState state, BlockPos pos) { + } + + @Override + public boolean doesEntityNotTriggerPressurePlate() { + return true; + } + + // [VanillaCopy] EntityBat.getCanSpawnHere. Edits noted. + @Override + public boolean getCanSpawnHere() { + BlockPos blockpos = new BlockPos(this.posX, this.getEntityBoundingBox().minY, this.posZ); + + return blockpos.getY() < this.world.getSeaLevel() + && !this.rand.nextBoolean() + && this.world.getLightFromNeighbors(blockpos) <= this.rand.nextInt(4) + && super.getCanSpawnHere(); + } + + @Override @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float par1) - { - return 15728880; - } - - public float getGlowBrightness() - { - return (float)Math.sin(this.ticksExisted / 7.0) + 1F; - } + public int getBrightnessForRender() { + return 15728880; + } + + public float getGlowBrightness() { + return (float) Math.sin(this.ticksExisted / 7.0) + 1F; + } + + @Override + protected ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFPenguin.java b/src/main/java/twilightforest/entity/passive/EntityTFPenguin.java index 1db58913d2..9e2aba13d4 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFPenguin.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFPenguin.java @@ -15,81 +15,51 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; - +import twilightforest.TwilightForestMod; public class EntityTFPenguin extends EntityTFBird { + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/penguin"); + public EntityTFPenguin(World world) { super(world); - //texture = TwilightForestMod.MODEL_DIR + "penguin.png"; - - this.setSize(0.5F, 0.9F); - - // reset tasks for fish - tasks.addTask(0, new EntityAISwimming(this)); - tasks.addTask(1, new EntityAIPanic(this, 1.75F)); - tasks.addTask(2, new EntityAIMate(this, 1.0F)); - tasks.addTask(3, new EntityAITempt(this, 0.75F, Items.fish, false)); - tasks.addTask(4, new EntityAIFollowParent(this, 1.15F)); - tasks.addTask(5, new EntityAIWander(this, 1.0F)); - tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); - tasks.addTask(7, new EntityAIWatchClosest2(this, twilightforest.entity.passive.EntityTFPenguin.class, 5F, 0.02F)); - tasks.addTask(8, new EntityAILookIdle(this)); - + this.setSize(0.5F, 0.9F); } - - /** - * Returns the sound this mob makes while it's alive. - */ - @Override - protected String getLivingSound() - { - return null;//"mob.chicken"; - } - - - /** - * [This function is used when two same-species animals in 'love mode' breed to generate the new baby animal.] - */ + @Override - public EntityAnimal createChild(EntityAgeable entityanimal) - { - return new EntityTFPenguin(worldObj); - } - - /** - * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on - * the animal type) - */ + protected void initEntityAI() { + tasks.addTask(0, new EntityAISwimming(this)); + tasks.addTask(1, new EntityAIPanic(this, 1.75F)); + tasks.addTask(2, new EntityAIMate(this, 1.0F)); + tasks.addTask(3, new EntityAITempt(this, 0.75F, Items.FISH, false)); + tasks.addTask(4, new EntityAIFollowParent(this, 1.15F)); + tasks.addTask(5, new EntityAIWander(this, 1.0F)); + tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); + tasks.addTask(7, new EntityAIWatchClosest2(this, twilightforest.entity.passive.EntityTFPenguin.class, 5F, 0.02F)); + tasks.addTask(8, new EntityAILookIdle(this)); + } + @Override - public boolean isBreedingItem(ItemStack par1ItemStack) - { - return par1ItemStack != null && par1ItemStack.getItem() == Items.fish; - } + public EntityAnimal createChild(EntityAgeable entityanimal) { + return new EntityTFPenguin(world); + } + @Override + public boolean isBreedingItem(ItemStack stack) { + return stack.getItem() == Items.FISH; + } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.2D); } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.2D); - } + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFQuestRam.java b/src/main/java/twilightforest/entity/passive/EntityTFQuestRam.java index 5e1c281d79..98339632e7 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFQuestRam.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFQuestRam.java @@ -1,397 +1,241 @@ package twilightforest.entity.passive; -import java.util.List; - import net.minecraft.block.Block; import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAILookIdle; -import net.minecraft.entity.ai.EntityAIPanic; -import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAITempt; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.*; import net.minecraft.entity.passive.EntityAnimal; -import net.minecraft.entity.passive.EntitySheep; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.util.*; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; +import net.minecraft.world.WorldServer; +import net.minecraft.world.storage.loot.LootContext; +import twilightforest.TwilightForestMod; +import twilightforest.advancements.TFAdvancements; import twilightforest.TFFeature; import twilightforest.entity.ai.EntityAITFEatLoose; import twilightforest.entity.ai.EntityAITFFindLoose; -import twilightforest.item.TFItems; - public class EntityTFQuestRam extends EntityAnimal { - - private int randomTickDivider; + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/quest_ram"); + public static final ResourceLocation REWARD_LOOT_TABLE = TwilightForestMod.prefix("entities/questing_ram_rewards"); + private static final DataParameter DATA_COLOR = EntityDataManager.createKey(EntityTFQuestRam.class, DataSerializers.VARINT); + private static final DataParameter DATA_REWARDED = EntityDataManager.createKey(EntityTFQuestRam.class, DataSerializers.BOOLEAN); + + private int randomTickDivider; - public EntityTFQuestRam(World par1World) { - super(par1World); - //this.texture = TwilightForestMod.MODEL_DIR + "questram.png"; + public EntityTFQuestRam(World world) { + super(world); this.setSize(1.25F, 2.9F); this.randomTickDivider = 0; - - - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIPanic(this, 1.38F)); - this.tasks.addTask(2, new EntityAITempt(this, 1.0F, Item.getItemFromBlock(Blocks.wool), false)); - this.tasks.addTask(3, new EntityAITFEatLoose(this, Item.getItemFromBlock(Blocks.wool))); - this.tasks.addTask(4, new EntityAITFFindLoose(this, 1.0F, Item.getItemFromBlock(Blocks.wool))); - this.tasks.addTask(5, new EntityAIWander(this, 1.0F)); -// this.tasks.addTask(4, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); - this.tasks.addTask(6, new EntityAILookIdle(this)); } @Override - public EntityAnimal createChild(EntityAgeable entityanimal) - { + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 1.38F)); + this.tasks.addTask(2, new EntityAITempt(this, 1.0F, Item.getItemFromBlock(Blocks.WOOL), false)); + this.tasks.addTask(3, new EntityAITFEatLoose(this, Item.getItemFromBlock(Blocks.WOOL))); + this.tasks.addTask(4, new EntityAITFFindLoose(this, 1.0F, Item.getItemFromBlock(Blocks.WOOL))); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0F)); + this.tasks.addTask(6, new EntityAILookIdle(this)); + } + + @Override + public EntityAnimal createChild(EntityAgeable entityanimal) { return null; } + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(70.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D); + } + + @Override + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_COLOR, 0); + dataManager.register(DATA_REWARDED, false); + } + + @Override + protected boolean canDespawn() { + return false; + } + + @Override + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + protected void updateAITasks() { + if (--this.randomTickDivider <= 0) { + this.randomTickDivider = 70 + this.rand.nextInt(50); + + // check if we're near a quest grove and if so, set that as home + int chunkX = MathHelper.floor(this.posX) / 16; + int chunkZ = MathHelper.floor(this.posZ) / 16; + + TFFeature nearFeature = TFFeature.getNearestFeature(chunkX, chunkZ, this.world); + + if (nearFeature != TFFeature.QUEST_GROVE) { + this.detachHome(); + } else { + // set our home position to the center of the quest grove + BlockPos cc = TFFeature.getNearestCenterXYZ(MathHelper.floor(this.posX), MathHelper.floor(this.posZ), world); + this.setHomePosAndDistance(cc, 13); + } + + if (countColorsSet() > 15 && !getRewarded()) { + rewardQuest(); + setRewarded(true); + } + + } + + super.updateAITasks(); + } + /** - * Set monster attributes + * Pay out! */ + private void rewardQuest() { + LootContext ctx = new LootContext.Builder((WorldServer) world).withLootedEntity(this).build(); + for (ItemStack s : world.getLootTableManager().getLootTableFromLocation(REWARD_LOOT_TABLE).generateLootForPools(world.rand, ctx)) { + entityDropItem(s, 1.0F); + } + + for (EntityPlayerMP player : this.world.getEntitiesWithinAABB(EntityPlayerMP.class, getEntityBoundingBox().grow(16.0D, 16.0D, 16.0D))) { + TFAdvancements.QUEST_RAM_COMPLETED.trigger(player); + } + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(70.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); - } - - @Override - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(16, Integer.valueOf(0)); - this.dataWatcher.addObject(17, Byte.valueOf((byte)0)); - } - - - /** - * Returns true if the newer Entity AI code should be run - */ - @Override - public boolean isAIEnabled() - { - return true; - } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - - /** - * main AI tick function, replaces updateEntityActionState - */ - @Override - protected void updateAITick() - { - if (--this.randomTickDivider <= 0) - { - this.randomTickDivider = 70 + this.rand.nextInt(50); - - // check if we're near a quest grove and if so, set that as home - int chunkX = MathHelper.floor_double(this.posX) / 16; - int chunkZ = MathHelper.floor_double(this.posZ) / 16; - - TFFeature nearFeature = TFFeature.getNearestFeature(chunkX, chunkZ, this.worldObj); - - if (nearFeature != TFFeature.questGrove) - { - this.detachHome(); - } - else - { - // set our home position to the center of the quest grove - ChunkCoordinates cc = TFFeature.getNearestCenterXYZ(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posZ), worldObj); - this.setHomeArea(cc.posX, cc.posY, cc.posZ, 13); - - //System.out.println("Set home area to " + cc.posX + ", " + cc.posY + ", " + cc.posZ); - } - - // do we need to reward the player? - if (countColorsSet() > 15 && !getRewarded()) { - rewardQuest(); - setRewarded(true); - } - - } - - super.updateAITick(); - } - - /** - * Pay out! - */ - private void rewardQuest() { - func_145778_a(Item.getItemFromBlock(Blocks.diamond_block), 1, 1.0F); - func_145778_a(Item.getItemFromBlock(Blocks.iron_block), 1, 1.0F); - func_145778_a(Item.getItemFromBlock(Blocks.emerald_block), 1, 1.0F); - func_145778_a(Item.getItemFromBlock(Blocks.gold_block), 1, 1.0F); - func_145778_a(Item.getItemFromBlock(Blocks.lapis_block), 1, 1.0F); - func_145778_a(TFItems.crumbleHorn, 1, 1.0F); - - rewardNearbyPlayers(this.worldObj, this.posX, this.posY, this.posZ); + public boolean processInteract(EntityPlayer player, EnumHand hand) { + ItemStack currentItem = player.getHeldItem(hand); + + if (!currentItem.isEmpty() && currentItem.getItem() == Item.getItemFromBlock(Blocks.WOOL) && !isColorPresent(EnumDyeColor.byMetadata(currentItem.getItemDamage()))) { + this.setColorPresent(EnumDyeColor.byMetadata(currentItem.getItemDamage())); + this.animateAddColor(EnumDyeColor.byMetadata(currentItem.getItemDamage()), 50); + + if (!player.capabilities.isCreativeMode) { + currentItem.shrink(1); + } + + return true; + } else { + return super.processInteract(player, hand); + } } - /** - * Give achievement to nearby players - */ - @SuppressWarnings("unchecked") - private void rewardNearbyPlayers(World world, double posX, double posY, double posZ) { - // scan for players nearby to give the achievement - List nearbyPlayers = world.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(posX, posY, posZ, posX + 1, posY + 1, posZ + 1).expand(16.0D, 16.0D, 16.0D)); - - for (EntityPlayer player : nearbyPlayers) { - player.triggerAchievement(TFAchievementPage.twilightQuestRam); + @Override + public void onLivingUpdate() { + super.onLivingUpdate(); + + if (world.isRemote && countColorsSet() > 15 && !getRewarded()) { + animateAddColor(EnumDyeColor.byMetadata(this.rand.nextInt(16)), 5); } } - - /** - * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. - */ - @Override - public boolean interact(EntityPlayer par1EntityPlayer) - { - ItemStack currentItem = par1EntityPlayer.inventory.getCurrentItem(); - - if (currentItem != null && currentItem.getItem() == Item.getItemFromBlock(Blocks.wool) && !isColorPresent(currentItem.getItemDamage())) - { -// par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, new ItemStack(Items.bucketMilk)); - this.setColorPresent(currentItem.getItemDamage()); - this.animateAddColor(currentItem.getItemDamage(), 50); - - if (!par1EntityPlayer.capabilities.isCreativeMode) - { - --currentItem.stackSize; - - if (currentItem.stackSize <= 0) - { - par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null); - } - } - - //par1EntityPlayer.addChatMessage("Successfully used color " + currentItem.getItemDamage()); - //par1EntityPlayer.addChatMessage("Color flags are now " + Integer.toBinaryString(this.getColorFlags())); - return true; - } - else - { - return super.interact(par1EntityPlayer); - } - } - - - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - @Override - public void onLivingUpdate() - { - super.onLivingUpdate(); - -// for (int var1 = 0; var1 < 2; ++var1) -// { -// this.worldObj.spawnParticle("mobSpell", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.44, 0.625, this.rand.nextDouble()); -// } - checkAndAnimateColors(); - } - - - /** - * Called every tick. If we have got all the colors and have not paid out the reward yet, do a colorful animation. - */ - public void checkAndAnimateColors() { - if (countColorsSet() > 15 && !getRewarded()) { - animateAddColor(this.rand.nextInt(16), 5); + + @Override + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setInteger("ColorFlags", this.getColorFlags()); + compound.setBoolean("Rewarded", this.getRewarded()); + } + + @Override + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setColorFlags(compound.getInteger("ColorFlags")); + this.setRewarded(compound.getBoolean("Rewarded")); + } + + public int getColorFlags() { + return dataManager.get(DATA_COLOR); + } + + public void setColorFlags(int flags) { + dataManager.set(DATA_COLOR, flags); + } + + public boolean isColorPresent(EnumDyeColor color) { + return (getColorFlags() & (1 << color.getMetadata())) > 0; + } + + public void setColorPresent(EnumDyeColor color) { + setColorFlags(getColorFlags() | (1 << color.getMetadata())); + } + + public boolean getRewarded() { + return dataManager.get(DATA_REWARDED); + } + + public void setRewarded(boolean rewarded) { + dataManager.set(DATA_REWARDED, rewarded); + } + + public void animateAddColor(EnumDyeColor color, int iterations) { + float[] colorVal = color.getColorComponentValues(); + int red = (int) (colorVal[0] * 255F); + int green = (int) (colorVal[1] * 255F); + int blue = (int) (colorVal[2] * 255F); + + for (int i = 0; i < iterations; i++) { + this.world.spawnParticle(EnumParticleTypes.SPELL_MOB, this.posX + (this.rand.nextDouble() - 0.5D) * this.width * 1.5, this.posY + this.rand.nextDouble() * this.height * 1.5, this.posZ + (this.rand.nextDouble() - 0.5D) * this.width * 1.5, red, green, blue); } + + //TODO: it would be nice to play a custom sound + playLivingSound(); } - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ - @Override - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setInteger("ColorFlags", this.getColorFlags()); - par1NBTTagCompound.setBoolean("Rewarded", this.getRewarded()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ - @Override - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setColorFlags(par1NBTTagCompound.getInteger("ColorFlags")); - this.setRewarded(par1NBTTagCompound.getBoolean("Rewarded")); - } - - /** - * Returns an int representing which of the 16 colors this ram currently has - */ - public int getColorFlags() - { - return this.dataWatcher.getWatchableObjectInt(16); - } - - /** - * Sets the color flags int - */ - public void setColorFlags(int par1) - { - this.dataWatcher.updateObject(16, Integer.valueOf(par1)); - } - - /** - * @param color - * @return true if the specified color is marked present - */ - public boolean isColorPresent(int color) { - int flags = this.getColorFlags(); - - return (flags & (int)Math.pow(2, color)) > 0; - } - - public void setColorPresent(int color) { - int flags = this.getColorFlags(); - -// System.out.println("Setting color flag for color " + color); -// System.out.println("Color int is " + flags); -// System.out.println("ORing that with " + Math.pow(2, color) + " which is " + Integer.toBinaryString((int) Math.pow(2, color))); - - setColorFlags(flags | (int)Math.pow(2, color)); - } - - /** - * Have we paid out the reward yet? - */ - public boolean getRewarded() - { - return this.dataWatcher.getWatchableObjectByte(17) != (byte)0; - } - - /** - * Sets whether we have paid the quest reward yet - */ - public void setRewarded(boolean par1) - { - this.dataWatcher.updateObject(17, par1 ? Byte.valueOf((byte)1) : Byte.valueOf((byte)0)); - } - - - - /** - * Do a little animation for when we successfully add a new color - * @param color - */ - public void animateAddColor(int color, int iterations) { - //EntitySheep.fleeceColorTable[i][0] - - for (int i = 0; i < iterations; i++) { - this.worldObj.spawnParticle("mobSpell", this.posX + (this.rand.nextDouble() - 0.5D) * this.width * 1.5, this.posY + this.rand.nextDouble() * this.height * 1.5, this.posZ + (this.rand.nextDouble() - 0.5D) * this.width * 1.5, EntitySheep.fleeceColorTable[color][0], EntitySheep.fleeceColorTable[color][1], EntitySheep.fleeceColorTable[color][2]); - } - - //TODO: it would be nice to play a custom sound - playLivingSound(); - } - - /** - * - * @return how many colors are present currently - */ - public int countColorsSet() { - int count = 0; - - for (int i = 0; i < 16; i++) { - if (isColorPresent(i)) { - count++; - } - } - - return count; - } - - - - - /** - * Plays living's sound at its position - */ - @Override - public void playLivingSound() - { - this.worldObj.playSoundAtEntity(this, "mob.sheep.say", this.getSoundVolume(), this.getSoundPitch()); - } - - /** - * Returns the volume for the sounds this mob makes. - */ - @Override - protected float getSoundVolume() - { - return 5.0F; - } - - /** - * Gets the pitch of living sounds in living entities. - */ - @Override - protected float getSoundPitch() - { - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.7F; - } - - /** - * Returns the sound this mob makes while it's alive. - */ - protected String getLivingSound() - { - return "mob.sheep.say"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ - protected String getHurtSound() - { - return "mob.sheep.say"; - } - - /** - * Returns the sound this mob makes on death. - */ - protected String getDeathSound() - { - return "mob.sheep.say"; - } - - protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_) - { - this.playSound("mob.sheep.step", 0.15F, 1.0F); - } - - public float getMaximumHomeDistance() - { - return this.func_110174_bM(); - } + public int countColorsSet() { + return Integer.bitCount(getColorFlags()); + } + + @Override + protected float getSoundVolume() { + return 5.0F; + } + + @Override + protected float getSoundPitch() { + return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.7F; + } + + @Override + protected SoundEvent getAmbientSound() { + return SoundEvents.ENTITY_SHEEP_AMBIENT; + } + + @Override + protected SoundEvent getHurtSound(DamageSource source) { + return SoundEvents.ENTITY_SHEEP_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return SoundEvents.ENTITY_SHEEP_DEATH; + } + + @Override + protected void playStepSound(BlockPos pos, Block block) { + this.playSound(SoundEvents.ENTITY_SHEEP_STEP, 0.15F, 1.0F); + } } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFRaven.java b/src/main/java/twilightforest/entity/passive/EntityTFRaven.java index b9d5d3545f..c89304b8ee 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFRaven.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFRaven.java @@ -4,123 +4,79 @@ import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAIPanic; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAITempt; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.ai.EntityLookHelper; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; +import net.minecraft.util.DamageSource; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; import net.minecraft.world.World; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; -import twilightforest.entity.ai.EntityTFRavenLookHelper; -import twilightforest.item.TFItems; - +import twilightforest.entity.ai.EntityAITFTempt; public class EntityTFRaven extends EntityTFTinyBird { - - EntityTFRavenLookHelper ravenLook = new EntityTFRavenLookHelper(this); - public EntityTFRaven(World par1World) { - super(par1World); - //texture = TwilightForestMod.MODEL_DIR + "raven.png"; - - this.setSize(0.3F, 0.7F); - + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/raven"); + + public EntityTFRaven(World world) { + super(world); + this.setSize(0.3F, 0.5F); + // maybe this will help them move cuter? this.stepHeight = 1; - - // bird AI - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIPanic(this, 1.5F)); - this.tasks.addTask(2, new EntityAITempt(this, 0.85F, Items.wheat_seeds, true)); -// this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityPlayer.class, 2.0F, 0.23F, 0.4F)); -// this.tasks.addTask(4, new EntityAITFBirdFly(this, 0.25F)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); - this.tasks.addTask(7, new EntityAILookIdle(this)); - } - - /** - * Set monster attributes - */ + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 1.5F)); + this.tasks.addTask(2, new EntityAITFTempt(this, 0.85F, true, SEEDS)); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0F)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + } + + @Override + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(10.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000001192092896D); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(10.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.20000001192092896D); - } - - /** - * We have our own getLookHelper - */ - @Override - protected void updateAITasks() { - super.updateAITasks(); - this.ravenLook.onUpdateLook(); + protected SoundEvent getAmbientSound() { + return TFSounds.RAVEN_CAW; } - /** - * We have our own getLookHelper - */ @Override - public EntityLookHelper getLookHelper() - { - return this.ravenLook; - } - - /** - * Returns the sound this mob makes while it's alive. - */ + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.RAVEN_SQUAWK; + } + @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.raven.caw"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ + protected SoundEvent getDeathSound() { + return TFSounds.RAVEN_SQUAWK; + } + @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.raven.squawk"; - } + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } - /** - * Returns the sound this mob makes on death. - */ @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.raven.squawk"; - } - - /** - * Returns the item ID for the item the mob drops on death. - */ - @Override - protected Item getDropItem() - { - return TFItems.feather; - } + public float getEyeHeight() { + return this.height * 0.75F; + } - /** - * Actually only used for the shadow - */ @Override public float getRenderSizeModifier() { - return 0.3F; + return 0.3F; } - - /** - * Return true if the bird is spooked - */ + @Override public boolean isSpooked() { return this.hurtTime > 0; } - + } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFSquirrel.java b/src/main/java/twilightforest/entity/passive/EntityTFSquirrel.java index 34d53efdf0..e40240126d 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFSquirrel.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFSquirrel.java @@ -7,113 +7,92 @@ import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAIPanic; import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.ai.EntityAITempt; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.passive.IAnimals; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.util.DamageSource; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; - +import twilightforest.TwilightForestMod; +import twilightforest.entity.ai.EntityAITFTempt; public class EntityTFSquirrel extends EntityCreature implements IAnimals { - public EntityTFSquirrel(World par1World) { - super(par1World); - - this.setSize(0.3F, 0.7F); - + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/squirrel"); + protected static final Ingredient SEEDS = Ingredient.fromItems(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); + + public EntityTFSquirrel(World world) { + super(world); + this.setSize(0.3F, 0.5F); + // maybe this will help them move cuter? this.stepHeight = 1; - - // squirrel AI - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIPanic(this, 1.38F)); - this.tasks.addTask(2, new EntityAITempt(this, 1.0F, Items.wheat_seeds, true)); - this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityPlayer.class, 2.0F, 0.8F, 1.4F)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(6, new EntityAIWander(this, 1.25F)); - this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); + } + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 1.38F)); + this.tasks.addTask(2, new EntityAITFTempt(this, 1.0F, true, SEEDS)); + this.tasks.addTask(3, new EntityAIAvoidEntity<>(this, EntityPlayer.class, 2.0F, 0.8F, 1.4F)); + this.tasks.addTask(5, new EntityAIWanderAvoidWater(this, 1.0F)); + this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 1.25F)); + this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); + this.tasks.addTask(8, new EntityAILookIdle(this)); } - /** - * Set monster attributes - */ @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(1.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3D); - } - + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(1.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.3D); + } + /** - * Called when the mob is falling. Calculates and applies fall damage. * TODO: maybe they should just take less damage? */ @Override - protected void fall(float par1) {} + public void fall(float distance, float multiplier) { + } - /** - * Returns true if the newer Entity AI code should be run - */ @Override - public boolean isAIEnabled() { - return true; + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + + @Override + public float getEyeHeight() { + return this.height * 0.7F; } - /** - * Actually only used for the shadow - */ @Override public float getRenderSizeModifier() { - return 0.3F; + return 0.3F; } - - /** - * Takes a coordinate in and returns a weight to determine how likely this creature will try to path to the block. - * Args: x, y, z - */ + @Override - public float getBlockPathWeight(int par1, int par2, int par3) - { - // prefer standing on leaves - Material underMaterial = this.worldObj.getBlock(par1, par2 - 1, par3).getMaterial(); - if (underMaterial == Material.leaves) { + public float getBlockPathWeight(BlockPos pos) { + // prefer standing on leaves + Material underMaterial = this.world.getBlockState(pos.down()).getMaterial(); + if (underMaterial == Material.LEAVES) { return 12.0F; } - if (underMaterial == Material.wood) { + if (underMaterial == Material.WOOD) { return 15.0F; } - if (underMaterial == Material.grass) { + if (underMaterial == Material.GRASS) { return 10.0F; } // default to just prefering lighter areas - return this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; - } - - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - /** - * Trigger achievement when killed - */ + return this.world.getLightBrightness(pos) - 0.5F; + } + @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); - } + protected boolean canDespawn() { + return false; } + } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFTinyBird.java b/src/main/java/twilightforest/entity/passive/EntityTFTinyBird.java index 0fc2b2ee2e..ac7f846025 100644 --- a/src/main/java/twilightforest/entity/passive/EntityTFTinyBird.java +++ b/src/main/java/twilightforest/entity/passive/EntityTFTinyBird.java @@ -2,352 +2,242 @@ import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAILookIdle; -import net.minecraft.entity.ai.EntityAITempt; -import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIPanic; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWanderAvoidWater; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.util.DamageSource; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import twilightforest.TFAchievementPage; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; import twilightforest.entity.ai.EntityAITFBirdFly; - +import twilightforest.entity.ai.EntityAITFTempt; public class EntityTFTinyBird extends EntityTFBird { - - private static final int DATA_BIRDTYPE = 16; - private static final int DATA_BIRDFLAGS = 17; - - /** - * randomly selected ChunkCoordinates in a 7x6x7 box around the bat (y offset -2 to 4) towards which it will fly. - * upon getting close a new target will be selected - */ - private ChunkCoordinates currentFlightTarget; - private int currentFlightTime; - - public EntityTFTinyBird(World par1World) { - super(par1World); - //texture = TwilightForestMod.MODEL_DIR + "tinybirdbrown.png"; - - this.setSize(0.5F, 0.9F); - - // maybe this will help them move cuter? - //this.stepHeight = 2; - - // bird AI - this.getNavigator().setAvoidsWater(true); - this.tasks.addTask(0, new EntityAITFBirdFly(this)); - this.tasks.addTask(1, new EntityAITempt(this, 1.0F, Items.wheat_seeds, true)); - this.tasks.addTask(2, new EntityAIWander(this, 1.0F)); - this.tasks.addTask(3, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); - this.tasks.addTask(4, new EntityAILookIdle(this)); - - // random color - setBirdType(rand.nextInt(4)); - - setIsBirdLanded(true); + + public static final ResourceLocation LOOT_TABLE = TwilightForestMod.prefix("entities/tiny_bird"); + private static final DataParameter DATA_BIRDTYPE = EntityDataManager.createKey(EntityTFTinyBird.class, DataSerializers.BYTE); + private static final DataParameter DATA_BIRDFLAGS = EntityDataManager.createKey(EntityTFTinyBird.class, DataSerializers.BYTE); + + // [VanillaCopy] EntityBat field + private BlockPos spawnPosition; + private int currentFlightTime; + + public EntityTFTinyBird(World world) { + super(world); + this.setSize(0.3F, 0.3F); + setBirdType(rand.nextInt(4)); + setIsBirdLanded(true); + } + + @Override + protected void initEntityAI() { + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 1.5F)); + this.tasks.addTask(2, new EntityAITFBirdFly(this)); + this.tasks.addTask(3, new EntityAITFTempt(this, 1.0F, true, SEEDS)); + this.tasks.addTask(4, new EntityAIWanderAvoidWater(this, 1.0D)); + this.tasks.addTask(5, new EntityAIWatchClosest(this, EntityPlayer.class, 6F)); + this.tasks.addTask(6, new EntityAILookIdle(this)); } - + @Override - protected void entityInit() - { - super.entityInit(); - this.dataWatcher.addObject(DATA_BIRDTYPE, Byte.valueOf((byte)0)); - this.dataWatcher.addObject(DATA_BIRDFLAGS, Byte.valueOf((byte)0)); - } - - /** - * Set monster attributes - */ + protected void entityInit() { + super.entityInit(); + dataManager.register(DATA_BIRDTYPE, (byte) 0); + dataManager.register(DATA_BIRDFLAGS, (byte) 0); + } + @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(1.0D); // max health - this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.20000001192092896D); - } - -// /** -// * Returns the texture's file path as a String. -// */ -// @Override -// public String getTexture() -// { -// switch (this.getBirdType()) -// { -// case 0: -// return TwilightForestMod.MODEL_DIR + "tinybirdbrown.png"; -// -// case 1: -// return TwilightForestMod.MODEL_DIR + "tinybirdblue.png"; -// -// case 2: -// return TwilightForestMod.MODEL_DIR + "tinybirdred.png"; -// -// case 3: -// return TwilightForestMod.MODEL_DIR + "tinybirdgold.png"; -// -// default: -// return super.getTexture(); -// } -// } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(1.0D); + this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.20000001192092896D); + } + @Override - public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeEntityToNBT(par1NBTTagCompound); - par1NBTTagCompound.setInteger("BirdType", this.getBirdType()); - } - - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ + public void writeEntityToNBT(NBTTagCompound compound) { + super.writeEntityToNBT(compound); + compound.setInteger("BirdType", this.getBirdType()); + } + @Override - public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readEntityFromNBT(par1NBTTagCompound); - this.setBirdType(par1NBTTagCompound.getInteger("BirdType")); - } - - public int getBirdType() - { - return this.dataWatcher.getWatchableObjectByte(16); - } - - public void setBirdType(int par1) - { - this.dataWatcher.updateObject(DATA_BIRDTYPE, Byte.valueOf((byte)par1)); - } - - /** - * Returns the sound this mob makes while it's alive. - */ + public void readEntityFromNBT(NBTTagCompound compound) { + super.readEntityFromNBT(compound); + this.setBirdType(compound.getInteger("BirdType")); + } + + public int getBirdType() { + return dataManager.get(DATA_BIRDTYPE); + } + + public void setBirdType(int type) { + dataManager.set(DATA_BIRDTYPE, (byte) type); + } + @Override - protected String getLivingSound() - { - return TwilightForestMod.ID + ":mob.tinybird.chirp"; - } - - /** - * Returns the sound this mob makes when it is hurt. - */ + public ResourceLocation getLootTable() { + return LOOT_TABLE; + } + @Override - protected String getHurtSound() - { - return TwilightForestMod.ID + ":mob.tinybird.hurt"; - } - - /** - * Returns the sound this mob makes on death. - */ + protected SoundEvent getAmbientSound() { + return TFSounds.TINYBIRD_CHIRP; + } + @Override - protected String getDeathSound() - { - return TwilightForestMod.ID + ":mob.tinybird.hurt"; - } - - /** - * Actually only used for the shadow - */ + protected SoundEvent getHurtSound(DamageSource source) { + return TFSounds.TINYBIRD_HURT; + } + + @Override + protected SoundEvent getDeathSound() { + return TFSounds.TINYBIRD_HURT; + } + + @Override + public float getEyeHeight() { + return this.height * 0.7F; + } + @Override public float getRenderSizeModifier() { - return 0.3F; + return 0.3F; + } + + @Override + protected boolean canDespawn() { + return false; } - /** - * Determines if an entity can be despawned, used on idle far away entities - */ - @Override - protected boolean canDespawn() - { - return false; - } - - /** - * Takes a coordinate in and returns a weight to determine how likely this creature will try to path to the block. - * Args: x, y, z - */ @Override - public float getBlockPathWeight(int par1, int par2, int par3) - { - // prefer standing on leaves - Material underMaterial = this.worldObj.getBlock(par1, par2 - 1, par3).getMaterial(); - if (underMaterial == Material.leaves) { + public float getBlockPathWeight(BlockPos pos) { + // prefer standing on leaves + Material underMaterial = this.world.getBlockState(pos.down()).getMaterial(); + if (underMaterial == Material.LEAVES) { return 200.0F; } - if (underMaterial == Material.wood) { + if (underMaterial == Material.WOOD) { return 15.0F; } - if (underMaterial == Material.grass) { + if (underMaterial == Material.GRASS) { return 9.0F; } - // default to just prefering lighter areas - return this.worldObj.getLightBrightness(par1, par2, par3) - 0.5F; - } + // default to just preferring lighter areas + return this.world.getLightBrightness(pos) - 0.5F; + } - /** - * Trigger achievement when killed - */ @Override - public void onDeath(DamageSource par1DamageSource) { - super.onDeath(par1DamageSource); - if (par1DamageSource.getSourceOfDamage() instanceof EntityPlayer) { - ((EntityPlayer)par1DamageSource.getSourceOfDamage()).triggerAchievement(TFAchievementPage.twilightHunter); + public void onUpdate() { + super.onUpdate(); + // while we are flying, try to level out somewhat + if (!this.isBirdLanded()) { + this.motionY *= 0.6000000238418579D; } } - - /** - * Called to update the entity's position/logic. - */ - public void onUpdate() - { - super.onUpdate(); - - // while we are flying, try to level out somewhat - if (!this.isBirdLanded()) - { - this.motionY *= 0.6000000238418579D; - } - - - } - - protected void updateAITasks() - { - super.updateAITasks(); - - if (this.isBirdLanded()) - { - this.currentFlightTime = 0; - - if (this.rand.nextInt(200) == 0 && !isLandableBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY - 1), MathHelper.floor_double(this.posZ))) - { - this.setIsBirdLanded(false); - this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1015, (int)this.posX, (int)this.posY, (int)this.posZ, 0); - this.motionY = 0.4; - //FMLLog.info("bird taking off because it is no longer on land"); - } - else - { - if (isSpooked()) - { - this.setIsBirdLanded(false); - this.motionY = 0.4; - this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1015, (int)this.posX, (int)this.posY, (int)this.posZ, 0); - //FMLLog.info("bird taking off because it was spooked"); - } - } - } - else - { - this.currentFlightTime++; - - if (this.currentFlightTarget != null && (!this.worldObj.isAirBlock(this.currentFlightTarget.posX, this.currentFlightTarget.posY, this.currentFlightTarget.posZ) || this.currentFlightTarget.posY < 1)) - { - this.currentFlightTarget = null; - } - - if (this.currentFlightTarget == null || this.rand.nextInt(30) == 0 || this.currentFlightTarget.getDistanceSquared((int)this.posX, (int)this.posY, (int)this.posZ) < 4.0F) - { - int yTarget = this.currentFlightTime < 100 ? 2 : 4; - - this.currentFlightTarget = new ChunkCoordinates((int)this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int)this.posY + this.rand.nextInt(6) - yTarget, (int)this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); - } - - double d0 = (double)this.currentFlightTarget.posX + 0.5D - this.posX; - double d1 = (double)this.currentFlightTarget.posY + 0.1D - this.posY; - double d2 = (double)this.currentFlightTarget.posZ + 0.5D - this.posZ; - this.motionX += (Math.signum(d0) * 0.5D - this.motionX) * 0.10000000149011612D; - this.motionY += (Math.signum(d1) * 0.699999988079071D - this.motionY) * 0.10000000149011612D; - this.motionZ += (Math.signum(d2) * 0.5D - this.motionZ) * 0.10000000149011612D; - float f = (float)(Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F; - float f1 = MathHelper.wrapAngleTo180_float(f - this.rotationYaw); - this.moveForward = 0.5F; - this.rotationYaw += f1; - - - if (this.rand.nextInt(10) == 0 && isLandableBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY - 1), MathHelper.floor_double(this.posZ))) - { - - - this.setIsBirdLanded(true); - - this.motionY = 0; - - //this.posY = MathHelper.floor_double(posY); - //FMLLog.info("bird landing"); - } - } - } - - /** - * Return true if the bird is spooked - */ + + @Override + protected void updateAITasks() { + super.updateAITasks(); + + if (this.isBirdLanded()) { + this.currentFlightTime = 0; + + if (isSpooked() || isInWater() || world.containsAnyLiquid(getEntityBoundingBox()) || (this.rand.nextInt(200) == 0 && !isLandableBlock(new BlockPos(posX, posY - 1, posZ)))) { + this.setIsBirdLanded(false); + this.world.playEvent(1025, new BlockPos(this), 0); + this.motionY = 0.4; + } + } else { + this.currentFlightTime++; + + // [VanillaCopy] Modified version of last half of EntityBat.updateAITasks. Edits noted + if (this.spawnPosition != null && (!this.world.isAirBlock(this.spawnPosition) || this.spawnPosition.getY() < 1)) { + this.spawnPosition = null; + } + + if (isInWater() || world.containsAnyLiquid(getEntityBoundingBox())) { + currentFlightTime = 0; // reset timer for MAX FLIGHT :v + motionY = 0.1F; + } + + if (this.spawnPosition == null || this.rand.nextInt(30) == 0 || this.spawnPosition.distanceSq((double) ((int) this.posX), (double) ((int) this.posY), (double) ((int) this.posZ)) < 4.0D) { + // TF - modify shift factor of Y + int yTarget = this.currentFlightTime < 100 ? 2 : 4; + this.spawnPosition = new BlockPos((int) this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int) this.posY + this.rand.nextInt(6) - yTarget, (int) this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7)); + } + + double d0 = (double) this.spawnPosition.getX() + 0.5D - this.posX; + double d1 = (double) this.spawnPosition.getY() + 0.1D - this.posY; + double d2 = (double) this.spawnPosition.getZ() + 0.5D - this.posZ; + + this.motionX += (Math.signum(d0) * 0.5D - this.motionX) * 0.10000000149011612D; + this.motionY += (Math.signum(d1) * 0.699999988079071D - this.motionY) * 0.10000000149011612D; + this.motionZ += (Math.signum(d2) * 0.5D - this.motionZ) * 0.10000000149011612D; + + float f = (float) (MathHelper.atan2(this.motionZ, this.motionX) * (180D / Math.PI)) - 90.0F; + float f1 = MathHelper.wrapDegrees(f - this.rotationYaw); + this.moveForward = 0.5F; + this.rotationYaw += f1; + + // TF - change chance 100 -> 10; change check to isLandable + if (this.rand.nextInt(100) == 0 && isLandableBlock(new BlockPos(posX, posY - 1, posZ))) //this.world.getBlockState(blockpos1).isNormalCube()) + { + // this.setIsBatHanging(true); TF - land the bird + setIsBirdLanded(true); + motionY = 0; + } + // End copy + } + } + public boolean isSpooked() { - EntityPlayer closestPlayer = this.worldObj.getClosestPlayerToEntity(this, 4.0D); - - return this.hurtTime > 0 || (closestPlayer != null && (closestPlayer.inventory.getCurrentItem() == null || closestPlayer.inventory.getCurrentItem().getItem() != Items.wheat_seeds)); + if (this.hurtTime > 0) return true; + EntityPlayer closestPlayer = this.world.getClosestPlayerToEntity(this, 4.0D); + return closestPlayer != null + && !SEEDS.apply(closestPlayer.getHeldItemMainhand()) + && !SEEDS.apply(closestPlayer.getHeldItemOffhand()); } - - - /** - * Can the bird land here? - */ - public boolean isLandableBlock(int x, int y, int z) - { - Block block = this.worldObj.getBlock(x, y, z); - - if (block == Blocks.air) - { - return false; - } - else - { - return block.isLeaves(worldObj, x, y, z) || block.isSideSolid(worldObj, x, y, z, ForgeDirection.UP); - } - } - - - public boolean isBirdLanded() - { - return (this.dataWatcher.getWatchableObjectByte(DATA_BIRDFLAGS) & 1) != 0; - } - - public void setIsBirdLanded(boolean par1) - { - byte b0 = this.dataWatcher.getWatchableObjectByte(DATA_BIRDFLAGS); - - if (par1) - { - this.dataWatcher.updateObject(DATA_BIRDFLAGS, Byte.valueOf((byte)(b0 | 1))); - } - else - { - this.dataWatcher.updateObject(DATA_BIRDFLAGS, Byte.valueOf((byte)(b0 & -2))); - } - } - - /** - * Returns true if this entity should push and be pushed by other entities when colliding. - */ - public boolean canBePushed() - { - return false; - } - - protected void collideWithEntity(Entity par1Entity) {} - - protected void func_85033_bc() {} + + public boolean isLandableBlock(BlockPos pos) { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + return !block.isAir(state, world, pos) + && (block.isLeaves(state, world, pos) || state.isSideSolid(world, pos, EnumFacing.UP)); + } + + @Override + public boolean isBirdLanded() { + return (dataManager.get(DATA_BIRDFLAGS) & 1) != 0; + } + + public void setIsBirdLanded(boolean landed) { + byte flags = dataManager.get(DATA_BIRDFLAGS); + dataManager.set(DATA_BIRDFLAGS, (byte) (landed ? flags | 1 : flags & ~1)); + } + + @Override + public boolean canBePushed() { + return false; + } + + @Override + protected void collideWithEntity(Entity entity) {} + + @Override + protected void collideWithNearbyEntities() {} } diff --git a/src/main/java/twilightforest/entity/passive/EntityTFTinyFirefly.java b/src/main/java/twilightforest/entity/passive/EntityTFTinyFirefly.java deleted file mode 100644 index bde7f53122..0000000000 --- a/src/main/java/twilightforest/entity/passive/EntityTFTinyFirefly.java +++ /dev/null @@ -1,66 +0,0 @@ -package twilightforest.entity.passive; - -import net.minecraft.entity.effect.EntityWeatherEffect; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; - - -public class EntityTFTinyFirefly extends EntityWeatherEffect { - - int lifeTime; - int halfLife; - - public float glowSize; - - public EntityTFTinyFirefly(World world, double d, double d1, double d2) { - super(world); - setLocationAndAngles(d, d1, d2, 0.0F, 0.0F); - - lifeTime = 10 + rand.nextInt(21); - halfLife = lifeTime / 2; - - glowSize = 0.2f + (rand.nextFloat() * 0.6f); - } - - @Override - public void onUpdate() - { - super.onUpdate(); - - if (lifeTime <= 1) { - setDead(); - } else { - lifeTime--; - } - - } - - public float getGlowBrightness() { - if (lifeTime <= halfLife) { - return (float)lifeTime / (float)halfLife; - } else { - return 1.0f - (((float)lifeTime - halfLife) / halfLife); - } - } - - - - @Override - protected void entityInit() { - // TODO Auto-generated method stub - - } - - @Override - protected void readEntityFromNBT(NBTTagCompound nbttagcompound) { - // TODO Auto-generated method stub - - } - - @Override - protected void writeEntityToNBT(NBTTagCompound nbttagcompound) { - // TODO Auto-generated method stub - - } - -} diff --git a/src/main/java/twilightforest/enums/BossVariant.java b/src/main/java/twilightforest/enums/BossVariant.java new file mode 100644 index 0000000000..cfdca7eb22 --- /dev/null +++ b/src/main/java/twilightforest/enums/BossVariant.java @@ -0,0 +1,79 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; +import twilightforest.tileentity.spawner.TileEntityTFAlphaYetiSpawner; +import twilightforest.tileentity.spawner.TileEntityTFBossSpawner; +import twilightforest.tileentity.spawner.TileEntityTFFinalBossSpawner; +import twilightforest.tileentity.spawner.TileEntityTFHydraSpawner; +import twilightforest.tileentity.spawner.TileEntityTFKnightPhantomsSpawner; +import twilightforest.tileentity.spawner.TileEntityTFLichSpawner; +import twilightforest.tileentity.spawner.TileEntityTFMinoshroomSpawner; +import twilightforest.tileentity.spawner.TileEntityTFNagaSpawner; +import twilightforest.tileentity.spawner.TileEntityTFSnowQueenSpawner; +import twilightforest.tileentity.spawner.TileEntityTFTowerBossSpawner; + +import javax.annotation.Nullable; +import java.util.Locale; +import java.util.function.Supplier; + +public enum BossVariant implements IStringSerializable { + + NAGA (TrophyType.GOLD , TileEntityTFNagaSpawner::new), + LICH (TrophyType.GOLD , TileEntityTFLichSpawner::new), + HYDRA (TrophyType.GOLD , TileEntityTFHydraSpawner::new), + UR_GHAST (TrophyType.GOLD , TileEntityTFTowerBossSpawner::new), + KNIGHT_PHANTOM(TrophyType.IRON , TileEntityTFKnightPhantomsSpawner::new), + SNOW_QUEEN (TrophyType.GOLD , TileEntityTFSnowQueenSpawner::new), + MINOSHROOM (TrophyType.IRON , TileEntityTFMinoshroomSpawner::new), + ALPHA_YETI (TrophyType.IRON , TileEntityTFAlphaYetiSpawner::new), + QUEST_RAM (TrophyType.IRONWOOD, null), + FINAL_BOSS (TrophyType.GOLD , TileEntityTFFinalBossSpawner::new); + + private final Supplier factory; + private final TrophyType trophyType; + + public static final BossVariant[] VARIANTS = values(); + + BossVariant(TrophyType trophyType, @Nullable Supplier factory) { + this.factory = factory; + this.trophyType = trophyType; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + public TrophyType getTrophyType() { + return this.trophyType; + } + + public boolean hasSpawner() { + return factory != null; + } + + @Nullable + public TileEntityTFBossSpawner getSpawner() { + return factory != null ? factory.get() : null; + } + + public static BossVariant getVariant(int id) { + return id >= 0 && id < VARIANTS.length ? VARIANTS[id] : NAGA; + } + + public enum TrophyType { + GOLD("trophy"), + IRON("trophy_minor"), + IRONWOOD("trophy_quest"); + + private final String modelName; + + TrophyType(String modelName) { + this.modelName = modelName; + } + + public String getModelName() { + return this.modelName; + } + } +} diff --git a/src/main/java/twilightforest/enums/CastleBrickVariant.java b/src/main/java/twilightforest/enums/CastleBrickVariant.java new file mode 100644 index 0000000000..19d3c86fde --- /dev/null +++ b/src/main/java/twilightforest/enums/CastleBrickVariant.java @@ -0,0 +1,19 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum CastleBrickVariant implements IStringSerializable { + NORMAL, + WORN, + CRACKED, + ROOF, + MOSSY, + FRAME; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/CastlePillarVariant.java b/src/main/java/twilightforest/enums/CastlePillarVariant.java new file mode 100644 index 0000000000..8f9394b85e --- /dev/null +++ b/src/main/java/twilightforest/enums/CastlePillarVariant.java @@ -0,0 +1,15 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum CastlePillarVariant implements IStringSerializable { + ENCASED, + BOLD; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/CompressedVariant.java b/src/main/java/twilightforest/enums/CompressedVariant.java new file mode 100644 index 0000000000..ea9a256ffb --- /dev/null +++ b/src/main/java/twilightforest/enums/CompressedVariant.java @@ -0,0 +1,36 @@ +package twilightforest.enums; + +import net.minecraft.block.SoundType; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum CompressedVariant implements IStringSerializable { + + IRONWOOD(Material.WOOD, SoundType.WOOD), + FIERY(Material.IRON, SoundType.METAL, MapColor.BLACK_STAINED_HARDENED_CLAY), + STEELLEAF(Material.LEAVES, SoundType.PLANT), + ARCTIC_FUR(Material.CLOTH, SoundType.CLOTH), + CARMINITE(Material.CLAY, SoundType.SLIME, MapColor.RED); + + public final Material material; + public final SoundType soundType; + public final MapColor mapColor; + + CompressedVariant(Material material, SoundType soundType) { + this(material, soundType, material.getMaterialMapColor()); + } + + CompressedVariant(Material material, SoundType soundType, MapColor mapColor) { + this.material = material; + this.soundType = soundType; + this.mapColor = mapColor; + } + + @Override + public String getName() { + return this.name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/DeadrockVariant.java b/src/main/java/twilightforest/enums/DeadrockVariant.java new file mode 100644 index 0000000000..23f93595ef --- /dev/null +++ b/src/main/java/twilightforest/enums/DeadrockVariant.java @@ -0,0 +1,16 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum DeadrockVariant implements IStringSerializable { + SURFACE, + CRACKED, + SOLID; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/Diagonals.java b/src/main/java/twilightforest/enums/Diagonals.java new file mode 100644 index 0000000000..697c4da49b --- /dev/null +++ b/src/main/java/twilightforest/enums/Diagonals.java @@ -0,0 +1,143 @@ +package twilightforest.enums; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; + +import java.util.Locale; + +public enum Diagonals implements IStringSerializable { + TOP_RIGHT ((x, rX) -> rX - x, (y, rY) -> y , true , false), + BOTTOM_RIGHT((x, rX) -> rX - x, (y, rY) -> rY - y, false, false), + BOTTOM_LEFT ((x, rX) -> x , (y, rY) -> rY - y, false, true ), + TOP_LEFT ((x, rX) -> x , (y, rY) -> y , true , true ); + + public final Inversion operationX; + public final Inversion operationY; + private final boolean isTop; + private final boolean isLeft; + + Diagonals(Inversion operationX, Inversion operationY, boolean isTop, boolean isLeft) { + this.operationX = operationX; + this.operationY = operationY; + this.isTop = isTop; + this.isLeft = isLeft; + } + + public static Diagonals getDiagonalFromUpDownLeftRight(boolean isLeft, boolean isTop) { + if (isLeft) + return isTop ? TOP_LEFT : BOTTOM_LEFT; + else + return isTop ? TOP_RIGHT : BOTTOM_RIGHT; + } + + public static Diagonals rotate(Diagonals diagonal, Rotation rotation) { + return Diagonals.values()[(diagonal.ordinal() + rotation.ordinal()) % 4]; + } + + public static Diagonals mirrorOn(EnumFacing.Axis axis, Diagonals diagonal, Mirror mirror) { + switch (axis) { + case X: + return mirrorOnX(diagonal, mirror); + case Z: + return mirrorOnZ(diagonal, mirror); + default: + return mirror(diagonal, mirror); + } + } + + public static Diagonals mirrorOnX(Diagonals diagonal, Mirror mirror) { + switch (mirror) { + case FRONT_BACK: + switch (diagonal) { + case TOP_RIGHT: + return BOTTOM_RIGHT; + case BOTTOM_RIGHT: + return TOP_RIGHT; + case BOTTOM_LEFT: + return TOP_LEFT; + case TOP_LEFT: + return BOTTOM_LEFT; + } + default: + return diagonal; + } + } + + public static Diagonals mirrorLeftRight(Diagonals diagonal) { + switch (diagonal) { + case TOP_RIGHT: + return TOP_LEFT; + case BOTTOM_RIGHT: + return BOTTOM_LEFT; + case BOTTOM_LEFT: + return BOTTOM_RIGHT; + case TOP_LEFT: + return TOP_RIGHT; + } + + return diagonal; + } + + public static Diagonals mirrorUpDown(Diagonals diagonal) { + switch (diagonal) { + case TOP_RIGHT: + return BOTTOM_RIGHT; + case BOTTOM_RIGHT: + return TOP_RIGHT; + case BOTTOM_LEFT: + return TOP_LEFT; + case TOP_LEFT: + return BOTTOM_LEFT; + } + + return diagonal; + } + + public static Diagonals mirror(Diagonals diagonal, Mirror mirror) { + switch (mirror) { + case LEFT_RIGHT: + return mirrorLeftRight(diagonal); + case FRONT_BACK: + return mirrorUpDown(diagonal); + default: + return diagonal; + } + } + + public static Diagonals mirrorOnZ(Diagonals diagonal, Mirror mirror) { + switch (mirror) { + case LEFT_RIGHT: + switch (diagonal) { + case TOP_RIGHT: + return TOP_LEFT; + case BOTTOM_RIGHT: + return BOTTOM_LEFT; + case BOTTOM_LEFT: + return BOTTOM_RIGHT; + case TOP_LEFT: + return TOP_RIGHT; + } + default: + return diagonal; + } + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + public boolean isTop() { + return isTop; + } + + public boolean isLeft() { + return isLeft; + } + + public interface Inversion { + int convert(int numberIn, int range); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/enums/FireJetVariant.java b/src/main/java/twilightforest/enums/FireJetVariant.java new file mode 100644 index 0000000000..5a3f6cc7e5 --- /dev/null +++ b/src/main/java/twilightforest/enums/FireJetVariant.java @@ -0,0 +1,28 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum FireJetVariant implements IStringSerializable { + SMOKER(true), + ENCASED_SMOKER_OFF(false), + ENCASED_SMOKER_ON(false), + JET_IDLE(true), + JET_POPPING(true), + JET_FLAME(true), + ENCASED_JET_IDLE(false), + ENCASED_JET_POPPING(false), + ENCASED_JET_FLAME(false); + + FireJetVariant(boolean hasGrassColor) { + this.hasGrassColor = hasGrassColor; + } + + public final boolean hasGrassColor; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/HedgeVariant.java b/src/main/java/twilightforest/enums/HedgeVariant.java new file mode 100644 index 0000000000..640456dc58 --- /dev/null +++ b/src/main/java/twilightforest/enums/HedgeVariant.java @@ -0,0 +1,15 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum HedgeVariant implements IStringSerializable { + HEDGE, + DARKWOOD_LEAVES; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/HugeLilypadPiece.java b/src/main/java/twilightforest/enums/HugeLilypadPiece.java new file mode 100644 index 0000000000..3b3a237361 --- /dev/null +++ b/src/main/java/twilightforest/enums/HugeLilypadPiece.java @@ -0,0 +1,17 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum HugeLilypadPiece implements IStringSerializable { + NW, + NE, + SE, + SW; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/Leaves3Variant.java b/src/main/java/twilightforest/enums/Leaves3Variant.java new file mode 100644 index 0000000000..432ff022d2 --- /dev/null +++ b/src/main/java/twilightforest/enums/Leaves3Variant.java @@ -0,0 +1,15 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum Leaves3Variant implements IStringSerializable { + THORN, + BEANSTALK; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/LeavesVariant.java b/src/main/java/twilightforest/enums/LeavesVariant.java new file mode 100644 index 0000000000..b0514d767f --- /dev/null +++ b/src/main/java/twilightforest/enums/LeavesVariant.java @@ -0,0 +1,17 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum LeavesVariant implements IStringSerializable { + OAK, + CANOPY, + MANGROVE, + RAINBOAK; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/MagicWoodVariant.java b/src/main/java/twilightforest/enums/MagicWoodVariant.java new file mode 100644 index 0000000000..42e55a35d3 --- /dev/null +++ b/src/main/java/twilightforest/enums/MagicWoodVariant.java @@ -0,0 +1,31 @@ +package twilightforest.enums; + +import net.minecraft.block.BlockPlanks; +import net.minecraft.util.IStringSerializable; +import twilightforest.util.IMapColorSupplier; + +import java.util.Locale; + +public enum MagicWoodVariant implements IStringSerializable, IMapColorSupplier { + + TIME(BlockPlanks.EnumType.JUNGLE), + TRANS(BlockPlanks.EnumType.OAK), + MINE(BlockPlanks.EnumType.BIRCH), + SORT(BlockPlanks.EnumType.SPRUCE); + + private final BlockPlanks.EnumType plankType; + + MagicWoodVariant(BlockPlanks.EnumType plankType) { + this.plankType = plankType; + } + + @Override + public BlockPlanks.EnumType supplyPlankColor() { + return plankType; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/MazestoneVariant.java b/src/main/java/twilightforest/enums/MazestoneVariant.java new file mode 100644 index 0000000000..77484deb70 --- /dev/null +++ b/src/main/java/twilightforest/enums/MazestoneVariant.java @@ -0,0 +1,21 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum MazestoneVariant implements IStringSerializable { + PLAIN, + BRICK, + CHISELED, + DECORATIVE, + CRACKED, + MOSSY, + MOSAIC, + BORDER; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/NagastoneVariant.java b/src/main/java/twilightforest/enums/NagastoneVariant.java new file mode 100644 index 0000000000..50e383a769 --- /dev/null +++ b/src/main/java/twilightforest/enums/NagastoneVariant.java @@ -0,0 +1,178 @@ +package twilightforest.enums; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; + +import java.util.Locale; + +public enum NagastoneVariant implements IStringSerializable { + + NORTH_HEAD, + SOUTH_HEAD, + WEST_HEAD, + EAST_HEAD, + NORTH_DOWN, + SOUTH_DOWN, + WEST_DOWN, + EAST_DOWN, + NORTH_UP, + SOUTH_UP, + EAST_UP, + WEST_UP, + AXIS_X, + AXIS_Y, + AXIS_Z, + SOLID; // This can act as null + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + public static boolean isHead(NagastoneVariant variant) { + return variant.ordinal() < 4; + } + + public static NagastoneVariant rotate(NagastoneVariant variant, Rotation rotation) { + if (!isHead(variant)) return variant; + + switch (rotation) { + case CLOCKWISE_90: + switch (variant) { + case NORTH_HEAD: + return EAST_HEAD; + case SOUTH_HEAD: + return WEST_HEAD; + case WEST_HEAD: + return NORTH_HEAD; + case EAST_HEAD: + return SOUTH_HEAD; + default: + return variant; + } + case CLOCKWISE_180: + switch (variant) { + case NORTH_HEAD: + return SOUTH_HEAD; + case SOUTH_HEAD: + return NORTH_HEAD; + case WEST_HEAD: + return EAST_HEAD; + case EAST_HEAD: + return WEST_HEAD; + default: + return variant; + } + case COUNTERCLOCKWISE_90: + switch (variant) { + case NORTH_HEAD: + return WEST_HEAD; + case SOUTH_HEAD: + return EAST_HEAD; + case WEST_HEAD: + return SOUTH_HEAD; + case EAST_HEAD: + return NORTH_HEAD; + default: + return variant; + } + default: + return variant; + } + } + + public static NagastoneVariant mirror(NagastoneVariant variant, Mirror mirror) { + if (!isHead(variant)) return variant; + + switch (mirror) { + case LEFT_RIGHT: + switch (variant) { + case WEST_HEAD: + return EAST_HEAD; + case EAST_HEAD: + return WEST_HEAD; + default: + return variant; + } + case FRONT_BACK: + switch (variant) { + case NORTH_HEAD: + return SOUTH_HEAD; + case SOUTH_HEAD: + return NORTH_HEAD; + default: + return variant; + } + default: + return variant; + } + } + + public static NagastoneVariant getHeadFromFacing(EnumFacing facing) { + switch (facing) { + case NORTH: + return NORTH_HEAD; + case SOUTH: + return SOUTH_HEAD; + case WEST: + return WEST_HEAD; + case EAST: + return EAST_HEAD; + default: + return SOLID; + } + } + + public static NagastoneVariant getVariantFromAxis(EnumFacing.Axis axis) { + switch (axis) { + case X: + return AXIS_X; + case Y: + return AXIS_Y; + case Z: + return AXIS_Z; + default: + return SOLID; + } + } + + public static NagastoneVariant getVariantFromDoubleFacing(EnumFacing facing1, EnumFacing facing2) { + if (facing1.getAxis() == facing2.getAxis()) // Pairs of 6 dirs and axes + return getVariantFromAxis(facing1.getAxis()); // Both faces are on same axis + else if (facing1.getAxis() != EnumFacing.Axis.Y && facing2.getAxis() != EnumFacing.Axis.Y) + return SOLID; // Elbow connection doesn't have Y + + EnumFacing facingYAxis = facing1.getAxis() == EnumFacing.Axis.Y ? facing1 : facing2; + EnumFacing otherFace = facing1.getAxis() != EnumFacing.Axis.Y ? facing1 : facing2; + + if (facingYAxis == EnumFacing.UP) { + switch (otherFace) { + case NORTH: + return NORTH_UP; + case SOUTH: + return SOUTH_UP; + case WEST: + return WEST_UP; + case EAST: + return EAST_UP; + default: + return SOLID; + } + } else { + switch (otherFace) { + case NORTH: + return NORTH_DOWN; + case SOUTH: + return SOUTH_DOWN; + case WEST: + return WEST_DOWN; + case EAST: + return EAST_DOWN; + default: + return SOLID; + } + } + } +} diff --git a/src/main/java/twilightforest/enums/PlantVariant.java b/src/main/java/twilightforest/enums/PlantVariant.java new file mode 100644 index 0000000000..b15e4820a5 --- /dev/null +++ b/src/main/java/twilightforest/enums/PlantVariant.java @@ -0,0 +1,39 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum PlantVariant implements IStringSerializable { + MOSSPATCH(), + MAYAPPLE(), + CLOVERPATCH(), + FIDDLEHEAD(true), + MUSHGLOOM(), + FORESTGRASS(true), + DEADBUSH(), + TORCHBERRY(), + ROOT_STRAND(), + FALLEN_LEAVES(true, true); + + public final boolean isColored; + public final boolean isLeaves; + + PlantVariant() { + this(false); + } + + PlantVariant(boolean isColored) { + this(isColored, false); + } + + PlantVariant(boolean isColored, boolean isLeaves) { + this.isColored = isColored; + this.isLeaves = isLeaves; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/RootVariant.java b/src/main/java/twilightforest/enums/RootVariant.java new file mode 100644 index 0000000000..f39d4c7874 --- /dev/null +++ b/src/main/java/twilightforest/enums/RootVariant.java @@ -0,0 +1,15 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum RootVariant implements IStringSerializable { + ROOT, + LIVEROOT; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/SaplingVariant.java b/src/main/java/twilightforest/enums/SaplingVariant.java new file mode 100644 index 0000000000..acf3da8cd6 --- /dev/null +++ b/src/main/java/twilightforest/enums/SaplingVariant.java @@ -0,0 +1,23 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum SaplingVariant implements IStringSerializable { + OAK, + CANOPY, + MANGROVE, + DARKWOOD, + HOLLOW_OAK, + TIME, + TRANSFORMATION, + MINING, + SORTING, + RAINBOW; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/StructureVariant.java b/src/main/java/twilightforest/enums/StructureVariant.java new file mode 100644 index 0000000000..6e36f121cd --- /dev/null +++ b/src/main/java/twilightforest/enums/StructureVariant.java @@ -0,0 +1,28 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum StructureVariant implements IStringSerializable { + TWILIGHT_PORTAL, + HEDGE_MAZE, + HOLLOW_HILL, + QUEST_GROVE, + MUSHROOM_TOWER, + NAGA_COURTYARD, + LICH_TOWER, + MINOTAUR_LABYRINTH, + HYDRA_LAIR, + GOBLIN_STRONGHOLD, + DARK_TOWER, + YETI_CAVE, + AURORA_PALACE, + TROLL_CAVE_AND_CLOUD_CASTLE, + FINAL_CASTLE; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/StructureWoodVariant.java b/src/main/java/twilightforest/enums/StructureWoodVariant.java new file mode 100644 index 0000000000..f2f497bca4 --- /dev/null +++ b/src/main/java/twilightforest/enums/StructureWoodVariant.java @@ -0,0 +1,260 @@ +package twilightforest.enums; + +import net.minecraft.block.*; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; +import twilightforest.block.*; + +import javax.annotation.Nullable; +import java.util.Locale; + +public enum StructureWoodVariant implements IStringSerializable { + + OAK ( Blocks .PLANKS , Blocks .OAK_STAIRS , Blocks .WOODEN_SLAB , Blocks .DOUBLE_WOODEN_SLAB , Blocks .WOODEN_BUTTON , Blocks .OAK_FENCE , Blocks .OAK_FENCE_GATE , Blocks .WOODEN_PRESSURE_PLATE ), + SPRUCE ( Blocks .PLANKS , Blocks .SPRUCE_STAIRS , Blocks .WOODEN_SLAB , Blocks .DOUBLE_WOODEN_SLAB , Blocks .WOODEN_BUTTON , Blocks .SPRUCE_FENCE , Blocks .SPRUCE_FENCE_GATE , Blocks .WOODEN_PRESSURE_PLATE ), + BIRCH ( Blocks .PLANKS , Blocks .BIRCH_STAIRS , Blocks .WOODEN_SLAB , Blocks .DOUBLE_WOODEN_SLAB , Blocks .WOODEN_BUTTON , Blocks .BIRCH_FENCE , Blocks .BIRCH_FENCE_GATE , Blocks .WOODEN_PRESSURE_PLATE ), + JUNGLE ( Blocks .PLANKS , Blocks .JUNGLE_STAIRS , Blocks .WOODEN_SLAB , Blocks .DOUBLE_WOODEN_SLAB , Blocks .WOODEN_BUTTON , Blocks .JUNGLE_FENCE , Blocks .JUNGLE_FENCE_GATE , Blocks .WOODEN_PRESSURE_PLATE ), + ACACIA ( Blocks .PLANKS , Blocks .ACACIA_STAIRS , Blocks .WOODEN_SLAB , Blocks .DOUBLE_WOODEN_SLAB , Blocks .WOODEN_BUTTON , Blocks .ACACIA_FENCE , Blocks .ACACIA_FENCE_GATE , Blocks .WOODEN_PRESSURE_PLATE ), + DARK_OAK ( Blocks .PLANKS , Blocks .DARK_OAK_STAIRS , Blocks .WOODEN_SLAB , Blocks .DOUBLE_WOODEN_SLAB , Blocks .WOODEN_BUTTON , Blocks .DARK_OAK_FENCE , Blocks .DARK_OAK_FENCE_GATE, Blocks .WOODEN_PRESSURE_PLATE ), + + TWILIGHT_OAK ( TFBlocks.twilight_oak_planks, TFBlocks.twilight_oak_stairs, TFBlocks.twilight_oak_slab , TFBlocks.twilight_oak_doubleslab, TFBlocks.twilight_oak_button, TFBlocks.twilight_oak_fence, TFBlocks.twilight_oak_gate , TFBlocks.twilight_oak_plate ), + CANOPY ( TFBlocks.canopy_planks , TFBlocks.canopy_stairs , TFBlocks.canopy_slab , TFBlocks.canopy_doubleslab , TFBlocks.canopy_button , TFBlocks.canopy_fence , TFBlocks.canopy_gate , TFBlocks.canopy_plate ), + MANGROVE ( TFBlocks.mangrove_planks , TFBlocks.mangrove_stairs , TFBlocks.mangrove_slab , TFBlocks.mangrove_doubleslab , TFBlocks.mangrove_button , TFBlocks.mangrove_fence , TFBlocks.mangrove_gate , TFBlocks.mangrove_plate ), + DARK ( TFBlocks.dark_planks , TFBlocks.dark_stairs , TFBlocks.dark_slab , TFBlocks.dark_doubleslab , TFBlocks.dark_button , TFBlocks.dark_fence , TFBlocks.dark_gate , TFBlocks.dark_plate ), + TIME ( TFBlocks.time_planks , TFBlocks.time_stairs , TFBlocks.time_slab , TFBlocks.time_doubleslab , TFBlocks.time_button , TFBlocks.time_fence , TFBlocks.time_gate , TFBlocks.time_plate ), + TRANS ( TFBlocks.trans_planks , TFBlocks.trans_stairs , TFBlocks.trans_slab , TFBlocks.trans_doubleslab , TFBlocks.trans_button , TFBlocks.trans_fence , TFBlocks.trans_gate , TFBlocks.trans_plate ), + MINE ( TFBlocks.mine_planks , TFBlocks.mine_stairs , TFBlocks.mine_slab , TFBlocks.mine_doubleslab , TFBlocks.mine_button , TFBlocks.mine_fence , TFBlocks.mine_gate , TFBlocks.mine_plate ), + SORT ( TFBlocks.sort_planks , TFBlocks.sort_stairs , TFBlocks.sort_slab , TFBlocks.sort_doubleslab , TFBlocks.sort_button , TFBlocks.sort_fence , TFBlocks.sort_gate , TFBlocks.sort_plate ); + + StructureWoodVariant( + Block planks , + Block stairs , + Block slab , + Block doubleSlab, + Block button , + Block fence , + Block gate , + Block plate + ) { + this.planks = planks ; + this.stairs = stairs ; + this.slab = slab ; + this.doubleSlab = doubleSlab; + this.button = button ; + this.fence = fence ; + this.gate = gate ; + this.plate = plate ; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + private final Block planks ; + private final Block stairs ; + private final Block slab ; + private final Block doubleSlab; + private final Block button ; + private final Block fence ; + private final Block gate ; + private final Block plate ; + + @Nullable + public static BlockPlanks.EnumType getTypeFromBlockState(IBlockState stateIn) { + Block block = stateIn.getBlock(); + + if (!"minecraft".equals(block.getRegistryName().getNamespace())) return null; + + switch (getWoodShapeFromBlock(block)) { + case BLOCK: + if (stateIn.getBlock() instanceof BlockPlanks) + return stateIn.getValue(BlockPlanks.VARIANT); + else + return null; + case SLAB: + case DOUBLESLAB: + if (stateIn.getBlock() instanceof BlockWoodSlab) + return stateIn.getValue(BlockPlanks.VARIANT); + else + return null; + case STAIRS: + if (block == Blocks.OAK_STAIRS ) + return BlockPlanks.EnumType.OAK; + else if (block == Blocks.SPRUCE_STAIRS ) + return BlockPlanks.EnumType.SPRUCE; + else if (block == Blocks.BIRCH_STAIRS ) + return BlockPlanks.EnumType.BIRCH; + else if (block == Blocks.JUNGLE_STAIRS ) + return BlockPlanks.EnumType.JUNGLE; + else if (block == Blocks.ACACIA_STAIRS ) + return BlockPlanks.EnumType.ACACIA; + else if (block == Blocks.DARK_OAK_STAIRS ) + return BlockPlanks.EnumType.DARK_OAK; + else + return null; + case FENCE: + if (block == Blocks.OAK_FENCE ) + return BlockPlanks.EnumType.OAK; + else if (block == Blocks.SPRUCE_FENCE ) + return BlockPlanks.EnumType.SPRUCE; + else if (block == Blocks.BIRCH_FENCE ) + return BlockPlanks.EnumType.BIRCH; + else if (block == Blocks.JUNGLE_FENCE ) + return BlockPlanks.EnumType.JUNGLE; + else if (block == Blocks.ACACIA_FENCE ) + return BlockPlanks.EnumType.ACACIA; + else if (block == Blocks.DARK_OAK_FENCE ) + return BlockPlanks.EnumType.DARK_OAK; + else + return null; + case GATE: + if (block == Blocks.OAK_FENCE_GATE ) + return BlockPlanks.EnumType.OAK; + else if (block == Blocks.SPRUCE_FENCE_GATE ) + return BlockPlanks.EnumType.SPRUCE; + else if (block == Blocks.BIRCH_FENCE_GATE ) + return BlockPlanks.EnumType.BIRCH; + else if (block == Blocks.JUNGLE_FENCE_GATE ) + return BlockPlanks.EnumType.JUNGLE; + else if (block == Blocks.ACACIA_FENCE_GATE ) + return BlockPlanks.EnumType.ACACIA; + else if (block == Blocks.DARK_OAK_FENCE_GATE ) + return BlockPlanks.EnumType.DARK_OAK; + else + return null; + case BUTTON: + case PLATE: + return BlockPlanks.EnumType.OAK; + default: + return null; + } + } + + public static IBlockState modifyBlockWithType(IBlockState stateIn, StructureWoodVariant target) { + // get all data from stateIn + Block block = stateIn.getBlock(); + WoodShapes shape = getWoodShapeFromBlock(block); + + ResourceLocation blockRegName = block.getRegistryName(); + + if (blockRegName == null) return stateIn; + + if ("minecraft".equals(blockRegName.getNamespace()) && block instanceof BlockPlanks) { + shape = WoodShapes.BLOCK; + } + + if (shape == WoodShapes.INVALID || !("minecraft".equals(blockRegName.getNamespace()) || TwilightForestMod.ID.equals(blockRegName.getNamespace()))) { + return stateIn; // Can't deal with this. + } + + switch (shape) { + case BLOCK: + switch (target) { + case OAK: + return target.planks.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.OAK); + case SPRUCE: + return target.planks.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.SPRUCE); + case BIRCH: + return target.planks.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + case JUNGLE: + return target.planks.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.JUNGLE); + case ACACIA: + return target.planks.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.ACACIA); + case DARK_OAK: + return target.planks.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.DARK_OAK); + default: + return target.planks.getDefaultState(); + } + case STAIRS: + return transferStateKeys(stateIn, target.stairs.getDefaultState(), BlockStairs.FACING, BlockStairs.HALF, BlockStairs.SHAPE); + case SLAB: + switch (target) { + case OAK: + return transferStateKey(stateIn, target.slab.getDefaultState(), BlockSlab.HALF).withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.OAK); + case SPRUCE: + return transferStateKey(stateIn, target.slab.getDefaultState(), BlockSlab.HALF).withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.SPRUCE); + case BIRCH: + return transferStateKey(stateIn, target.slab.getDefaultState(), BlockSlab.HALF).withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.BIRCH); + case JUNGLE: + return transferStateKey(stateIn, target.slab.getDefaultState(), BlockSlab.HALF).withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.JUNGLE); + case ACACIA: + return transferStateKey(stateIn, target.slab.getDefaultState(), BlockSlab.HALF).withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.ACACIA); + case DARK_OAK: + return transferStateKey(stateIn, target.slab.getDefaultState(), BlockSlab.HALF).withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.DARK_OAK); + default: + return transferStateKey(stateIn, target.slab.getDefaultState(), BlockSlab.HALF); + } + case DOUBLESLAB: + switch (target) { + case OAK: + return target.doubleSlab.getDefaultState().withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.OAK); + case SPRUCE: + return target.doubleSlab.getDefaultState().withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.SPRUCE); + case BIRCH: + return target.doubleSlab.getDefaultState().withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.BIRCH); + case JUNGLE: + return target.doubleSlab.getDefaultState().withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.JUNGLE); + case ACACIA: + return target.doubleSlab.getDefaultState().withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.ACACIA); + case DARK_OAK: + return target.doubleSlab.getDefaultState().withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.DARK_OAK); + default: + return target.doubleSlab.getDefaultState(); + } + case FENCE: + return transferStateKeys(stateIn, target.fence .getDefaultState(), BlockFence.NORTH, BlockFence.EAST, BlockFence.WEST, BlockFence.SOUTH); + case GATE: + return transferStateKeys(stateIn, target.gate .getDefaultState(), BlockFenceGate.FACING, BlockFenceGate.OPEN, BlockFenceGate.POWERED, BlockFenceGate.IN_WALL); + case BUTTON: + return transferStateKeys(stateIn, target.button.getDefaultState(), BlockButton.FACING, BlockButton.POWERED); + case PLATE: + return transferStateKey (stateIn, target.plate .getDefaultState(), BlockPressurePlate.POWERED); + default: + return stateIn; // Can't deal with this. + } + } + + public static IBlockState transferStateKeys(IBlockState stateIn, IBlockState stateOut, IProperty... properties) { + for (IProperty property : properties) { + stateOut = transferStateKey(stateIn, stateOut, property); + } + return stateOut; + } + + public static > IBlockState transferStateKey(IBlockState stateIn, IBlockState stateOut, IProperty property) { + return stateOut.withProperty(property, stateIn.getValue(property)); + } + + public static WoodShapes getWoodShapeFromBlock(Block b) { + if (b instanceof BlockTF || b instanceof BlockPlanks) + return WoodShapes.BLOCK; + if (b instanceof BlockStairs ) return WoodShapes.STAIRS; + if (b instanceof BlockSlab ) { + if (((BlockSlab) b).isDouble()) return WoodShapes.DOUBLESLAB; + else return WoodShapes.SLAB; + } + if (b instanceof BlockButton ) return WoodShapes.BUTTON; + if (b instanceof BlockFence ) return WoodShapes.FENCE; + if (b instanceof BlockFenceGate ) return WoodShapes.GATE; + if (b instanceof BlockPressurePlate ) return WoodShapes.PLATE; + + return WoodShapes.INVALID; + } + + public enum WoodShapes { + BLOCK, + STAIRS, + SLAB, + DOUBLESLAB, + BUTTON, + FENCE, + GATE, + PLATE, + INVALID + } +} diff --git a/src/main/java/twilightforest/enums/ThornVariant.java b/src/main/java/twilightforest/enums/ThornVariant.java new file mode 100644 index 0000000000..53e50df363 --- /dev/null +++ b/src/main/java/twilightforest/enums/ThornVariant.java @@ -0,0 +1,15 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum ThornVariant implements IStringSerializable { + BROWN, + GREEN; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/TowerDeviceVariant.java b/src/main/java/twilightforest/enums/TowerDeviceVariant.java new file mode 100644 index 0000000000..63b813ea12 --- /dev/null +++ b/src/main/java/twilightforest/enums/TowerDeviceVariant.java @@ -0,0 +1,27 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum TowerDeviceVariant implements IStringSerializable { + REAPPEARING_INACTIVE, + REAPPEARING_ACTIVE, + VANISH_INACTIVE, + VANISH_ACTIVE, + VANISH_LOCKED, + VANISH_UNLOCKED, + BUILDER_INACTIVE, + BUILDER_ACTIVE, + BUILDER_TIMEOUT, + ANTIBUILDER, + GHASTTRAP_INACTIVE, + GHASTTRAP_ACTIVE, + REACTOR_INACTIVE, + REACTOR_ACTIVE; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/TowerTranslucentVariant.java b/src/main/java/twilightforest/enums/TowerTranslucentVariant.java new file mode 100644 index 0000000000..1e84d42016 --- /dev/null +++ b/src/main/java/twilightforest/enums/TowerTranslucentVariant.java @@ -0,0 +1,21 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum TowerTranslucentVariant implements IStringSerializable { + REAPPEARING_INACTIVE, + REAPPEARING_ACTIVE, + BUILT_INACTIVE, + BUILT_ACTIVE, + REVERTER_REPLACEMENT, + REACTOR_DEBRIS, + FAKE_GOLD, + FAKE_DIAMOND; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/TowerWoodVariant.java b/src/main/java/twilightforest/enums/TowerWoodVariant.java new file mode 100644 index 0000000000..fa15feaf8b --- /dev/null +++ b/src/main/java/twilightforest/enums/TowerWoodVariant.java @@ -0,0 +1,18 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum TowerWoodVariant implements IStringSerializable { + PLAIN, + ENCASED, + CRACKED, + MOSSY, + INFESTED; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/UnderBrickVariant.java b/src/main/java/twilightforest/enums/UnderBrickVariant.java new file mode 100644 index 0000000000..347c9a056c --- /dev/null +++ b/src/main/java/twilightforest/enums/UnderBrickVariant.java @@ -0,0 +1,17 @@ +package twilightforest.enums; + +import net.minecraft.util.IStringSerializable; + +import java.util.Locale; + +public enum UnderBrickVariant implements IStringSerializable { + NORMAL, + MOSSY, + CRACKED, + FLOOR; + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/WoodVariant.java b/src/main/java/twilightforest/enums/WoodVariant.java new file mode 100644 index 0000000000..8b01e7c3b7 --- /dev/null +++ b/src/main/java/twilightforest/enums/WoodVariant.java @@ -0,0 +1,31 @@ +package twilightforest.enums; + +import net.minecraft.block.BlockPlanks; +import net.minecraft.util.IStringSerializable; +import twilightforest.util.IMapColorSupplier; + +import java.util.Locale; + +public enum WoodVariant implements IStringSerializable, IMapColorSupplier { + + OAK(BlockPlanks.EnumType.OAK), + CANOPY(BlockPlanks.EnumType.SPRUCE), + MANGROVE(BlockPlanks.EnumType.JUNGLE), + DARK(BlockPlanks.EnumType.ACACIA); + + private final BlockPlanks.EnumType plankType; + + WoodVariant(BlockPlanks.EnumType plankType) { + this.plankType = plankType; + } + + @Override + public BlockPlanks.EnumType supplyPlankColor() { + return plankType; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/twilightforest/enums/package-info.java b/src/main/java/twilightforest/enums/package-info.java new file mode 100644 index 0000000000..79bb162c1f --- /dev/null +++ b/src/main/java/twilightforest/enums/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.enums; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/features/GenDruidHut.java b/src/main/java/twilightforest/features/GenDruidHut.java new file mode 100644 index 0000000000..fd020720bc --- /dev/null +++ b/src/main/java/twilightforest/features/GenDruidHut.java @@ -0,0 +1,278 @@ +package twilightforest.features; + +import com.google.common.math.StatsAccumulator; + +import net.minecraft.block.*; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityList; +import net.minecraft.init.Blocks; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntityMobSpawner; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.PlacementSettings; +import net.minecraft.world.gen.structure.template.Template; +import net.minecraft.world.gen.structure.template.TemplateManager; + +import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFSkeletonDruid; +import twilightforest.enums.StructureWoodVariant; +import twilightforest.loot.TFTreasure; +import twilightforest.structures.RandomizedTemplateProcessor; +import twilightforest.world.feature.TFGenerator; + +import javax.annotation.Nullable; +import java.util.Map; +import java.util.Random; + +public class GenDruidHut extends TFGenerator { + + @Override // Loosely based on WorldGenFossils + public boolean generate(World world, Random rand, BlockPos pos) { + Random random = world.getChunk(pos).getRandomWithSeed(987234911L); + + MinecraftServer minecraftserver = world.getMinecraftServer(); + TemplateManager templatemanager = world.getSaveHandler().getStructureTemplateManager(); + Template template = templatemanager.getTemplate(minecraftserver, HutType.values()[random.nextInt(HutType.size)].RL); + + Rotation[] rotations = Rotation.values(); + Rotation rotation = rotations[random.nextInt(rotations.length)]; + + Mirror[] mirrors = Mirror.values(); + Mirror mirror = mirrors[random.nextInt(mirrors.length+1) % mirrors.length]; + + ChunkPos chunkpos = new ChunkPos(pos.add(-8, 0, -8)); + StructureBoundingBox structureboundingbox = new StructureBoundingBox(chunkpos.getXStart() + 8, 0, chunkpos.getZStart() + 8, chunkpos.getXEnd() + 8, 255, chunkpos.getZEnd() + 8); + PlacementSettings placementsettings = (new PlacementSettings()).setMirror(mirror).setRotation(rotation).setBoundingBox(structureboundingbox).setRandom(random); + + BlockPos posSnap = chunkpos.getBlock(8, pos.getY() - 1, 8); + + BlockPos transformedSize = template.transformedSize(rotation); + int dx = random.nextInt(17 - transformedSize.getX()); + int dz = random.nextInt(17 - transformedSize.getZ()); + + BlockPos.MutableBlockPos startPos = new BlockPos.MutableBlockPos(posSnap.add(dx, 0, dz)); + + if (!offsetToAverageGroundLevel(world, startPos, transformedSize)) { + return false; + } + + BlockPos placementPos = template.getZeroPositionWithTransform(startPos, mirror, rotation); + template.addBlocksToWorld(world, placementPos, new HutTemplateProcessor(placementPos, placementsettings, random.nextInt(), random.nextInt(), random.nextInt()), placementsettings, 20); + + Map data = template.getDataBlocks(placementPos, placementsettings); + + if (random.nextBoolean()) { + template = templatemanager.getTemplate(minecraftserver, BasementType.values()[random.nextInt(BasementType.size)].getBasement(random.nextBoolean())); + placementPos = placementPos.down(12).offset(rotation.rotate(mirror.mirror(EnumFacing.NORTH)), 1).offset(rotation.rotate(mirror.mirror(EnumFacing.EAST)), 1); + + template.addBlocksToWorld(world, placementPos, new HutTemplateProcessor(placementPos, placementsettings, random.nextInt(), random.nextInt(), random.nextInt()), placementsettings, 20); + + data.putAll(template.getDataBlocks(placementPos, placementsettings)); + } + + data.forEach((blockPos, s) -> { + /* + `spawner` will place a Druid spawner. + + `loot` will place a chest facing the was-North. + + `lootT` will place a trapped chest facing the was-North. + + `lootW` will place a chest facing the was-West. + `lootS` will place a chest facing the was-South. + + `lootET` will place a trapped chest facing the was-East. + `lootNT` will place a trapped chest facing the was-North. + */ + if ("spawner".equals(s)) { + if (world.setBlockState(blockPos, Blocks.MOB_SPAWNER.getDefaultState(), 16 | 2)) { + TileEntityMobSpawner ms = (TileEntityMobSpawner) world.getTileEntity(blockPos); + + if (ms != null) { + ms.getSpawnerBaseLogic().setEntityId(EntityList.getKey(EntityTFSkeletonDruid.class)); + } + } + } else if (s.startsWith("loot")) { + IBlockState chest = s.endsWith("T") ? Blocks.TRAPPED_CHEST.getDefaultState() : Blocks.CHEST.getDefaultState(); + + switch (s.substring(4, 5)) { + case "W": + chest = chest.withProperty(BlockHorizontal.FACING, rotation.rotate(mirror.mirror(EnumFacing.WEST))); + break; + case "E": + chest = chest.withProperty(BlockHorizontal.FACING, rotation.rotate(mirror.mirror(EnumFacing.EAST))); + break; + case "S": + chest = chest.withProperty(BlockHorizontal.FACING, rotation.rotate(mirror.mirror(EnumFacing.SOUTH))); + break; + default: + chest = chest.withProperty(BlockHorizontal.FACING, rotation.rotate(mirror.mirror(EnumFacing.NORTH))); + break; + } + + if (world.setBlockState(blockPos, chest, 16 | 2)) { + TFTreasure.basement.generateChestContents(world, blockPos); + } + } + }); + + return true; + } + + private static boolean offsetToAverageGroundLevel(World world, BlockPos.MutableBlockPos startPos, BlockPos size) { + StatsAccumulator heights = new StatsAccumulator(); + + for (int dx = 0; dx < size.getX(); dx++) { + for (int dz = 0; dz < size.getZ(); dz++) { + + int x = startPos.getX() + dx; + int z = startPos.getZ() + dz; + + int y = world.getHeight(x, z); + + while (y >= 0) { + IBlockState state = world.getBlockState(new BlockPos(x, y, z)); + if (isBlockNotOk(state)) return false; + if (isBlockOk(state)) break; + y--; + } + + if (y < 0) return false; + + heights.add(y); + } + } + + if (heights.populationStandardDeviation() > 2.0) { + return false; + } + + int baseY = (int) Math.round(heights.mean()); + int maxY = (int) heights.max(); + + startPos.setY(baseY); + + return isAreaClear(world, startPos.up(maxY - baseY + 1), startPos.add(size)); + } + + private static boolean isAreaClear(IBlockAccess world, BlockPos min, BlockPos max) { + for (BlockPos pos : BlockPos.getAllInBoxMutable(min, max)) { + if (!world.getBlockState(pos).getBlock().isReplaceable(world, pos)) { + return false; + } + } + return true; + } + + private static boolean isBlockOk(IBlockState state) { + Material material = state.getMaterial(); + return material == Material.ROCK || material == Material.GROUND || material == Material.GRASS || material == Material.SAND; + } + + private static boolean isBlockNotOk(IBlockState state) { + Material material = state.getMaterial(); + return material == Material.WATER || material == Material.LAVA || state.getBlock() == Blocks.BEDROCK; + } + + private enum HutType { + + REGULAR (TwilightForestMod.prefix("landscape/druid_hut/druid_hut" )), + SIDEWAYS (TwilightForestMod.prefix("landscape/druid_hut/druid_sideways" )), + DOUBLE_DECK(TwilightForestMod.prefix("landscape/druid_hut/druid_doubledeck")); + + private final ResourceLocation RL; + + HutType(ResourceLocation rl) { + this.RL = rl; + increment(); + } + + private static int size; + + private static void increment() { + ++size; + } + } + + private enum BasementType { + + STUDY (TwilightForestMod.prefix("landscape/druid_hut/basement_study" ), TwilightForestMod.prefix("landscape/druid_hut/basement_study_trap" )), + SHELVES(TwilightForestMod.prefix("landscape/druid_hut/basement_shelves"), TwilightForestMod.prefix("landscape/druid_hut/basement_shelves_trap")), + GALLERY(TwilightForestMod.prefix("landscape/druid_hut/basement_gallery"), TwilightForestMod.prefix("landscape/druid_hut/basement_gallery_trap")); + + private final ResourceLocation RL; + private final ResourceLocation RL_TRAP; + + BasementType(ResourceLocation rl, ResourceLocation rlTrap) { + this.RL = rl; + this.RL_TRAP = rlTrap; + increment(); + } + + private static int size; + + private static void increment() { + ++size; + } + + private ResourceLocation getBasement(boolean trapped) { + return trapped ? RL_TRAP : RL; + } + } + + public class HutTemplateProcessor extends RandomizedTemplateProcessor { + + private final StructureWoodVariant OAK_SWIZZLE; + private final StructureWoodVariant SPRUCE_SWIZZLE; + private final StructureWoodVariant BIRCH_SWIZZLE; + + public HutTemplateProcessor(BlockPos pos, PlacementSettings settings, int oakSwizzle, int spruceSwizzle, int birchSwizzle) { + super(pos, settings); + int limit = StructureWoodVariant.values().length; + this.OAK_SWIZZLE = StructureWoodVariant.values()[ Math.floorMod(oakSwizzle , limit) ]; + this.SPRUCE_SWIZZLE = StructureWoodVariant.values()[ Math.floorMod(spruceSwizzle, limit) ]; + this.BIRCH_SWIZZLE = StructureWoodVariant.values()[ Math.floorMod(birchSwizzle , limit) ]; + } + + @Nullable + @Override + public Template.BlockInfo processBlock(World worldIn, BlockPos pos, Template.BlockInfo blockInfo) { + //if (!shouldPlaceBlock()) return null; + + IBlockState state = blockInfo.blockState; + Block block = state.getBlock(); + + if (block == Blocks.COBBLESTONE) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, Blocks.MOSSY_COBBLESTONE.getDefaultState(), null); + + if (block == Blocks.COBBLESTONE_WALL) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, state.withProperty(BlockWall.VARIANT, BlockWall.EnumType.MOSSY), null); + + if (block == Blocks.STONEBRICK && state != Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CHISELED)) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, state.withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.values()[random.nextInt(3)]), null); + + BlockPlanks.EnumType type = StructureWoodVariant.getTypeFromBlockState(state); + if (type != null) { + switch (type) { + case OAK: + return new Template.BlockInfo(pos, StructureWoodVariant.modifyBlockWithType(state, OAK_SWIZZLE ), null); + case SPRUCE: + return new Template.BlockInfo(pos, StructureWoodVariant.modifyBlockWithType(state, SPRUCE_SWIZZLE), null); + case BIRCH: + return new Template.BlockInfo(pos, StructureWoodVariant.modifyBlockWithType(state, BIRCH_SWIZZLE ), null); + } + } + + return blockInfo; + } + } +} diff --git a/src/main/java/twilightforest/features/TFGenGraveyard.java b/src/main/java/twilightforest/features/TFGenGraveyard.java new file mode 100644 index 0000000000..a310f86cd5 --- /dev/null +++ b/src/main/java/twilightforest/features/TFGenGraveyard.java @@ -0,0 +1,228 @@ +package twilightforest.features; + +import com.google.common.collect.ImmutableSet; +import com.google.common.math.StatsAccumulator; +import net.minecraft.block.BlockChest; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.monster.EntityZombieVillager; +import net.minecraft.init.Blocks; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntityMobSpawner; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.PlacementSettings; +import net.minecraft.world.gen.structure.template.Template; +import net.minecraft.world.gen.structure.template.TemplateManager; +import org.apache.commons.lang3.tuple.Pair; +import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFRisingZombie; +import twilightforest.entity.EntityTFWraith; +import twilightforest.loot.TFTreasure; +import twilightforest.structures.RandomizedTemplateProcessor; +import twilightforest.world.feature.TFGenerator; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class TFGenGraveyard extends TFGenerator { + + private static final ResourceLocation GRAVEYARD = TwilightForestMod.prefix("landscape/graveyard/graveyard"); + private static final ResourceLocation TRAP = TwilightForestMod.prefix("landscape/graveyard/grave_trap"); + private static final ImmutableSet MATERIAL_WHITELIST = ImmutableSet.of(Material.GROUND, Material.GRASS, Material.LEAVES, Material.WOOD, Material.PLANTS, Material.ROCK); + + private static boolean offsetToAverageGroundLevel(World world, BlockPos.MutableBlockPos startPos, BlockPos size) { + StatsAccumulator heights = new StatsAccumulator(); + + for (int dx = 0; dx < size.getX(); dx++) { + for (int dz = 0; dz < size.getZ(); dz++) { + + int x = startPos.getX() + dx; + int z = startPos.getZ() + dz; + + int y = world.getHeight(x, z); + + while (y >= 0) { + IBlockState state = world.getBlockState(new BlockPos(x, y, z)); + if (isBlockNotOk(state)) + return false; + if (isBlockOk(state)) + break; + y--; + } + + if (y < 0) + return false; + + heights.add(y); + } + } + + if (heights.populationStandardDeviation() > 2.0) { + return false; + } + + int baseY = (int) Math.round(heights.mean()); + int maxY = (int) heights.max(); + + startPos.setY(baseY); + + return isAreaClear(world, startPos.up(maxY - baseY + 1), startPos.add(size)); + } + + private static boolean isAreaClear(IBlockAccess world, BlockPos min, BlockPos max) { + for (BlockPos pos : BlockPos.getAllInBoxMutable(min, max)) { + Material material = world.getBlockState(pos).getMaterial(); + if (!material.isReplaceable() && !MATERIAL_WHITELIST.contains(material) && !material.isLiquid()) { + return false; + } + } + return true; + } + + private static boolean isBlockOk(IBlockState state) { + Material material = state.getMaterial(); + return material == Material.ROCK || material == Material.GROUND || material == Material.GRASS || material == Material.SAND; + } + + private static boolean isBlockNotOk(IBlockState state) { + Material material = state.getMaterial(); + return material == Material.WATER || material == Material.LAVA || state.getBlock() == Blocks.BEDROCK; + } + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + int flags = 0b10100; + Random random = world.getChunk(pos).getRandomWithSeed(987234911L); + + MinecraftServer minecraftserver = world.getMinecraftServer(); + TemplateManager templatemanager = world.getSaveHandler().getStructureTemplateManager(); + Template base = templatemanager.getTemplate(minecraftserver, GRAVEYARD); + List> graves = new ArrayList<>(); + Template trap = templatemanager.getTemplate(minecraftserver, TRAP); + for (GraveType type : GraveType.VALUES) + graves.add(Pair.of(type, templatemanager.getTemplate(minecraftserver, type.RL))); + + Rotation[] rotations = Rotation.values(); + Rotation rotation = rotations[random.nextInt(rotations.length)]; + + Mirror[] mirrors = Mirror.values(); + Mirror mirror = mirrors[random.nextInt(mirrors.length + 1) % mirrors.length]; + + BlockPos transformedSize = base.transformedSize(rotation); + BlockPos transformedGraveSize = graves.get(0).getValue().transformedSize(rotation); + + ChunkPos chunkpos = new ChunkPos(pos.add(-8, 0, -8)); + ChunkPos chunkendpos = new ChunkPos(pos.add(-8, 0, -8).add(transformedSize)); + StructureBoundingBox structureboundingbox = new StructureBoundingBox(chunkpos.getXStart() + 8, 0, chunkpos.getZStart() + 8, chunkendpos.getXEnd() + 8, 255, chunkendpos.getZEnd() + 8); + PlacementSettings placementsettings = (new PlacementSettings()).setMirror(mirror).setRotation(rotation).setBoundingBox(structureboundingbox).setRandom(random); + + BlockPos posSnap = chunkpos.getBlock(8, pos.getY() - 1, 8); + BlockPos.MutableBlockPos startPos = new BlockPos.MutableBlockPos(posSnap); + + if (!offsetToAverageGroundLevel(world, startPos, transformedSize)) { + return false; + } + + BlockPos placementPos = base.getZeroPositionWithTransform(startPos, mirror, rotation).add(1, -1, 0); + BlockPos size = transformedSize.add(-1, 0, -1); + BlockPos graveSize = transformedGraveSize.add(-1, 0, -1); + + base.addBlocksToWorld(world, placementPos, new WebTemplateProcessor(placementPos, placementsettings), placementsettings, flags); + + BlockPos start = startPos.add(1, 1, 0); + BlockPos end = start.add(size.getX(), 0, size.getZ()); + + for (int x = 1; x <= size.getX() - 1; x++) + for (int z = 1; z <= size.getZ() - 1; z++) + if (world.isAirBlock(start.add(x, 0, z)) && rand.nextInt(12) == 0) + world.setBlockState(start.add(x, 0, z), Blocks.WEB.getDefaultState(), flags); + + BlockPos inner = start.add(2, 0, 2); + BlockPos bound = end.add(-2, 0, -2); + BlockPos innerSize = new BlockPos(bound.getX() - inner.getX(), bound.getY() - inner.getY(), bound.getZ() - inner.getZ()); + BlockPos fixed = inner.add( + + (rotation == Rotation.CLOCKWISE_180 ? graveSize.getX() : 0) + (mirror == Mirror.FRONT_BACK ? transformedGraveSize.getX() - 1 : 0) * (rotation == Rotation.CLOCKWISE_180 ? -1 : 1), + + 0, + + (rotation == Rotation.COUNTERCLOCKWISE_90 ? graveSize.getZ() : 0) + (mirror == Mirror.FRONT_BACK ? transformedGraveSize.getZ() - 1 : 0) * (rotation == Rotation.COUNTERCLOCKWISE_90 ? -1 : 1) + + ); + BlockPos fixedSize = innerSize.add(-graveSize.getX(), 0, -graveSize.getZ()); + BlockPos chestloc = new BlockPos(random.nextInt(2) - (mirror == Mirror.FRONT_BACK ? 1 : 0), 1, 0).rotate(rotation); + + for (int x = 0; x <= fixedSize.getX(); x += (rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90 ? 2 : 5)) + for (int z = 0; z <= fixedSize.getZ(); z += (rotation == Rotation.NONE || rotation == Rotation.CLOCKWISE_180 ? 2 : 5)) { + if (x == innerSize.getX() / 2 || z == innerSize.getZ() / 2) + continue; + BlockPos placement = fixed.add(x, -2, z); + Pair grave = graves.get(rand.nextInt(graves.size())); + grave.getValue().addBlocksToWorld(world, placement, placementsettings, flags); + if (grave.getKey() == GraveType.Full) { + if (random.nextBoolean()) { + if (random.nextInt(3) == 0) + trap.addBlocksToWorld(world, placement.add(new BlockPos(mirror == Mirror.FRONT_BACK ? 1 : -1, 0, mirror == Mirror.LEFT_RIGHT ? 1 : -1).rotate(rotation)), placementsettings, flags); + if (world.setBlockState(placement.add(chestloc), Blocks.TRAPPED_CHEST.getDefaultState().withProperty(BlockChest.FACING, EnumFacing.WEST).withRotation(rotation).withMirror(mirror), flags)) + TFTreasure.graveyard.generateChestContents(world, placement.add(chestloc)); + EntityTFWraith wraith = new EntityTFWraith(world); + wraith.setPositionAndUpdate(placement.getX(), placement.getY(), placement.getZ()); + world.spawnEntity(wraith); + } + } + grave.getValue().getDataBlocks(placement, placementsettings).forEach((p, s) -> { + if ("spawner".equals(s)) + if (random.nextInt(4) == 0) { + if (world.setBlockState(p, Blocks.MOB_SPAWNER.getDefaultState(), flags)) { + TileEntityMobSpawner ms = (TileEntityMobSpawner) world.getTileEntity(p); + if (ms != null) + ms.getSpawnerBaseLogic().setEntityId(EntityList.getKey(EntityTFRisingZombie.class)); + } + } else + world.setBlockToAir(p); + }); + } + + return true; + } + + private enum GraveType { + + Full(TwilightForestMod.prefix("landscape/graveyard/grave_full")), + + Upper(TwilightForestMod.prefix("landscape/graveyard/grave_upper")), + + Lower(TwilightForestMod.prefix("landscape/graveyard/grave_lower")); + + private static final GraveType[] VALUES = values(); + private final ResourceLocation RL; + + GraveType(ResourceLocation rl) { + this.RL = rl; + } + } + + public class WebTemplateProcessor extends RandomizedTemplateProcessor { + + public WebTemplateProcessor(BlockPos pos, PlacementSettings settings) { + super(pos, settings); + } + + @Nullable + @Override + public Template.BlockInfo processBlock(World worldIn, BlockPos pos, Template.BlockInfo blockInfo) { + return blockInfo.blockState.getBlock() == Blocks.GRASS ? blockInfo : random.nextInt(5) == 0 ? new Template.BlockInfo(pos, Blocks.WEB.getDefaultState(), null) : blockInfo; + } + } +} diff --git a/src/main/java/twilightforest/features/package-info.java b/src/main/java/twilightforest/features/package-info.java new file mode 100644 index 0000000000..865456befe --- /dev/null +++ b/src/main/java/twilightforest/features/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.features; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/inventory/ContainerTFCinderFurnace.java b/src/main/java/twilightforest/inventory/ContainerTFCinderFurnace.java deleted file mode 100644 index aff42cbc71..0000000000 --- a/src/main/java/twilightforest/inventory/ContainerTFCinderFurnace.java +++ /dev/null @@ -1,188 +0,0 @@ -package twilightforest.inventory; - -import twilightforest.tileentity.TileEntityTFCinderFurnace; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.inventory.Container; -import net.minecraft.inventory.ICrafting; -import net.minecraft.inventory.Slot; -import net.minecraft.inventory.SlotFurnace; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.FurnaceRecipes; -import net.minecraft.tileentity.TileEntityFurnace; -import net.minecraft.world.World; - -public class ContainerTFCinderFurnace extends Container -{ - private TileEntityTFCinderFurnace tileFurnace; - private int lastCookTime; - private int lastBurnTime; - private int lastItemBurnTime; - - public ContainerTFCinderFurnace(InventoryPlayer inventory, World world, int x, int y, int z) { - this(inventory, (TileEntityTFCinderFurnace)world.getTileEntity(x, y, z)); - } - - public ContainerTFCinderFurnace(InventoryPlayer p_i1812_1_, TileEntityTFCinderFurnace p_i1812_2_) - { - this.tileFurnace = p_i1812_2_; - this.addSlotToContainer(new Slot(p_i1812_2_, 0, 56, 17)); - this.addSlotToContainer(new Slot(p_i1812_2_, 1, 56, 53)); - this.addSlotToContainer(new SlotFurnace(p_i1812_1_.player, p_i1812_2_, 2, 116, 35)); - int i; - - for (i = 0; i < 3; ++i) - { - for (int j = 0; j < 9; ++j) - { - this.addSlotToContainer(new Slot(p_i1812_1_, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); - } - } - - for (i = 0; i < 9; ++i) - { - this.addSlotToContainer(new Slot(p_i1812_1_, i, 8 + i * 18, 142)); - } - } - - public void addCraftingToCrafters(ICrafting p_75132_1_) - { - super.addCraftingToCrafters(p_75132_1_); - p_75132_1_.sendProgressBarUpdate(this, 0, this.tileFurnace.furnaceCookTime); - p_75132_1_.sendProgressBarUpdate(this, 1, this.tileFurnace.furnaceBurnTime); - p_75132_1_.sendProgressBarUpdate(this, 2, this.tileFurnace.currentItemBurnTime); - } - - /** - * Looks for changes made in the container, sends them to every listener. - */ - public void detectAndSendChanges() - { - super.detectAndSendChanges(); - - for (int i = 0; i < this.crafters.size(); ++i) - { - ICrafting icrafting = (ICrafting)this.crafters.get(i); - - if (this.lastCookTime != this.tileFurnace.furnaceCookTime) - { - icrafting.sendProgressBarUpdate(this, 0, this.tileFurnace.furnaceCookTime); - } - - if (this.lastBurnTime != this.tileFurnace.furnaceBurnTime) - { - icrafting.sendProgressBarUpdate(this, 1, this.tileFurnace.furnaceBurnTime); - } - - if (this.lastItemBurnTime != this.tileFurnace.currentItemBurnTime) - { - icrafting.sendProgressBarUpdate(this, 2, this.tileFurnace.currentItemBurnTime); - } - } - - this.lastCookTime = this.tileFurnace.furnaceCookTime; - this.lastBurnTime = this.tileFurnace.furnaceBurnTime; - this.lastItemBurnTime = this.tileFurnace.currentItemBurnTime; - } - - @SideOnly(Side.CLIENT) - public void updateProgressBar(int p_75137_1_, int p_75137_2_) - { - if (p_75137_1_ == 0) - { - this.tileFurnace.furnaceCookTime = p_75137_2_; - } - - if (p_75137_1_ == 1) - { - this.tileFurnace.furnaceBurnTime = p_75137_2_; - } - - if (p_75137_1_ == 2) - { - this.tileFurnace.currentItemBurnTime = p_75137_2_; - } - } - - public boolean canInteractWith(EntityPlayer p_75145_1_) - { - return this.tileFurnace.isUseableByPlayer(p_75145_1_); - } - - /** - * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that. - */ - public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int p_82846_2_) - { - ItemStack itemstack = null; - Slot slot = (Slot)this.inventorySlots.get(p_82846_2_); - - if (slot != null && slot.getHasStack()) - { - ItemStack itemstack1 = slot.getStack(); - itemstack = itemstack1.copy(); - - if (p_82846_2_ == 2) - { - if (!this.mergeItemStack(itemstack1, 3, 39, true)) - { - return null; - } - - slot.onSlotChange(itemstack1, itemstack); - } - else if (p_82846_2_ != 1 && p_82846_2_ != 0) - { - if (FurnaceRecipes.smelting().getSmeltingResult(itemstack1) != null) - { - if (!this.mergeItemStack(itemstack1, 0, 1, false)) - { - return null; - } - } - else if (TileEntityFurnace.isItemFuel(itemstack1)) - { - if (!this.mergeItemStack(itemstack1, 1, 2, false)) - { - return null; - } - } - else if (p_82846_2_ >= 3 && p_82846_2_ < 30) - { - if (!this.mergeItemStack(itemstack1, 30, 39, false)) - { - return null; - } - } - else if (p_82846_2_ >= 30 && p_82846_2_ < 39 && !this.mergeItemStack(itemstack1, 3, 30, false)) - { - return null; - } - } - else if (!this.mergeItemStack(itemstack1, 3, 39, false)) - { - return null; - } - - if (itemstack1.stackSize == 0) - { - slot.putStack((ItemStack)null); - } - else - { - slot.onSlotChanged(); - } - - if (itemstack1.stackSize == itemstack.stackSize) - { - return null; - } - - slot.onPickupFromSlot(p_82846_1_, itemstack1); - } - - return itemstack; - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/inventory/ContainerTFUncrafting.java b/src/main/java/twilightforest/inventory/ContainerTFUncrafting.java index f4f922dbd0..a90411870c 100644 --- a/src/main/java/twilightforest/inventory/ContainerTFUncrafting.java +++ b/src/main/java/twilightforest/inventory/ContainerTFUncrafting.java @@ -1,14 +1,12 @@ package twilightforest.inventory; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Items; +import net.minecraft.inventory.ClickType; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; @@ -24,846 +22,658 @@ import net.minecraft.item.ItemSword; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.nbt.NBTTagByte; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.oredict.ShapedOreRecipe; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.common.ObfuscationReflectionHelper; - +import net.minecraftforge.common.crafting.IShapedRecipe; +import net.minecraftforge.oredict.OreDictionary; +import twilightforest.TFConfig; +import twilightforest.block.TFBlocks; +import twilightforest.util.TFItemStackUtils; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class ContainerTFUncrafting extends Container { - /** The crafting matrix inventory (3x3). */ - public InventoryTFGoblinUncrafting uncraftingMatrix = new InventoryTFGoblinUncrafting(this); - public InventoryCrafting assemblyMatrix = new InventoryCrafting(this, 3, 3); - public InventoryCrafting combineMatrix = new InventoryCrafting(this, 3, 3); - public IInventory tinkerInput = new InventoryTFGoblinInput(this); - public IInventory tinkerResult = new InventoryCraftResult(); - private World worldObj; - - public ContainerTFUncrafting(InventoryPlayer inventory, World world, int x, int y, int z) { - this.worldObj = world; + private static final String TAG_MARKER = "TwilightForestMarker"; + + // Inaccessible grid, for uncrafting logic + private final InventoryTFGoblinUncrafting uncraftingMatrix = new InventoryTFGoblinUncrafting(this); + // Accessible grid, for actual crafting + public final InventoryCrafting assemblyMatrix = new InventoryCrafting(this, 3, 3); + // Inaccessible grid, for recrafting logic + private final InventoryCrafting combineMatrix = new InventoryCrafting(this, 3, 3); + + // Input slot for uncrafting + public final IInventory tinkerInput = new InventoryTFGoblinInput(this); + // Crafting Output + private final InventoryCraftResult tinkerResult = new InventoryCraftResult(); + + // Other Data, to kick the player from GUI if they stray too far from table + private final World world; + private final BlockPos pos; + private final EntityPlayer player; + + // Conflict resolution + public int unrecipeInCycle = 0; + public int ingredientsInCycle = 0; + public int recipeInCycle = 0; + + public ContainerTFUncrafting(InventoryPlayer inventory, World world, int x, int y, int z) { + + this.world = world; + this.pos = new BlockPos(x, y, z); + this.player = inventory.player; + this.addSlotToContainer(new Slot(this.tinkerInput, 0, 13, 35)); - this.addSlotToContainer(new SlotTFGoblinCraftResult(inventory.player, this.tinkerInput, this.uncraftingMatrix, this.assemblyMatrix, this.tinkerResult, 0, 147, 35)); - - int invX; - int invY; - - for (invX = 0; invX < 3; ++invX) - { - for (invY = 0; invY < 3; ++invY) - { - this.addSlotToContainer(new SlotTFGoblinUncrafting(inventory.player, this.tinkerInput, this.uncraftingMatrix, this.assemblyMatrix, invY + invX * 3, 300000 + invY * 18, 17 + invX * 18)); - } - } - for (invX = 0; invX < 3; ++invX) - { - for (invY = 0; invY < 3; ++invY) - { - this.addSlotToContainer(new SlotTFGoblinAssembly(inventory.player, this.tinkerInput, this.assemblyMatrix, this.uncraftingMatrix, invY + invX * 3, 62 + invY * 18, 17 + invX * 18)); - } - } - - for (invX = 0; invX < 3; ++invX) - { - for (invY = 0; invY < 9; ++invY) - { - this.addSlotToContainer(new Slot(inventory, invY + invX * 9 + 9, 8 + invY * 18, 84 + invX * 18)); - } - } - - for (invX = 0; invX < 9; ++invX) - { - this.addSlotToContainer(new Slot(inventory, invX, 8 + invX * 18, 142)); - } - - this.onCraftMatrixChanged(this.assemblyMatrix); + this.addSlotToContainer(new SlotTFGoblinCraftResult(inventory.player, this.tinkerInput, this.uncraftingMatrix, this.assemblyMatrix, this.tinkerResult, 0, 147, 35)); + + int invX; + int invY; + + for (invX = 0; invX < 3; ++invX) { + for (invY = 0; invY < 3; ++invY) { + this.addSlotToContainer(new SlotTFGoblinUncrafting(inventory.player, this.tinkerInput, this.uncraftingMatrix, this.assemblyMatrix, invY + invX * 3, 300000 + invY * 18, 17 + invX * 18)); + } + } + for (invX = 0; invX < 3; ++invX) { + for (invY = 0; invY < 3; ++invY) { + this.addSlotToContainer(new SlotTFGoblinAssembly(inventory.player, this.tinkerInput, this.assemblyMatrix, this.uncraftingMatrix, invY + invX * 3, 62 + invY * 18, 17 + invX * 18)); + } + } + + for (invX = 0; invX < 3; ++invX) { + for (invY = 0; invY < 9; ++invY) { + this.addSlotToContainer(new Slot(inventory, invY + invX * 9 + 9, 8 + invY * 18, 84 + invX * 18)); + } + } + + for (invX = 0; invX < 9; ++invX) { + this.addSlotToContainer(new Slot(inventory, invX, 8 + invX * 18, 142)); + } + + this.onCraftMatrixChanged(this.assemblyMatrix); } - - /** - * Callback for when the crafting matrix is changed. - */ - @SuppressWarnings("rawtypes") + @Override - public void onCraftMatrixChanged(IInventory par1IInventory) - { - // we need to see what inventory is calling this, and update appropriately - if (par1IInventory == this.tinkerInput) { - // see if there is a recipe for the input - ItemStack inputStack = tinkerInput.getStackInSlot(0); - IRecipe recipe = getRecipeFor(inputStack); - - if (recipe != null) { - int recipeWidth = getRecipeWidth(recipe); - int recipeHeight = getRecipeHeight(recipe); - ItemStack[] recipeItems = getRecipeItems(recipe); - - // empty whole grid to start with - // let's not get leftovers if something changes like the recipe size - for (int i = 0; i < this.uncraftingMatrix.getSizeInventory(); i++) - { - this.uncraftingMatrix.setInventorySlotContents(i, null); - } - - // set uncrafting grid - for (int invY = 0; invY < recipeHeight; invY++) { - for (int invX = 0; invX < recipeWidth; invX++) { - ItemStack ingredient = ItemStack.copyItemStack(recipeItems[invX + invY * recipeWidth]); - // fix weird recipe for diamond/ingot blocks - if (ingredient != null && ingredient.stackSize > 1) - { - ingredient.stackSize = 1; - } - if (ingredient != null && (ingredient.getItemDamageForDisplay() == -1 || ingredient.getItemDamageForDisplay() == Short.MAX_VALUE)) - { - ingredient.setItemDamage(0); - } - this.uncraftingMatrix.setInventorySlotContents(invX + invY * 3, ingredient); - } - } - - // mark the appropriate number of components damaged - if (inputStack.isItemDamaged()) { - int damagedParts = countDamagedParts(inputStack); - - for (int i = 0; i < 9 && damagedParts > 0; i++) { - if (isDamageableComponent(this.uncraftingMatrix.getStackInSlot(i))) { - this.uncraftingMatrix.getStackInSlot(i).stackSize = 0; - damagedParts--; - } - } - } - - // mark banned items damaged - for (int i = 0; i < 9; i++) - { - ItemStack ingredient = this.uncraftingMatrix.getStackInSlot(i); - - if (isIngredientProblematic(ingredient)) - { - ingredient.stackSize = 0; - } - } - - // store number of items this recipe produces (and thus how many input items are required for uncrafting) - this.uncraftingMatrix.numberOfInputItems = recipe.getRecipeOutput().stackSize; - this.uncraftingMatrix.uncraftingCost = calculateUncraftingCost(); - this.uncraftingMatrix.recraftingCost = 0; - } - else { - //System.out.println("Could not find a recipe for input " + this.tinkerInput.getStackInSlot(0)); - - for (int i = 0; i < 9; i++) { - this.uncraftingMatrix.setInventorySlotContents(i, null); - } - this.uncraftingMatrix.numberOfInputItems = 0; - this.uncraftingMatrix.uncraftingCost = 0; - } - } - - if (par1IInventory == this.assemblyMatrix || par1IInventory == this.tinkerInput) { - if (isMatrixEmpty(this.tinkerInput)) { - // display the output - this.tinkerResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.assemblyMatrix, this.worldObj)); - this.uncraftingMatrix.recraftingCost = 0; - } - else { + public void onCraftMatrixChanged(IInventory inventory) { + // we need to see what inventory is calling this, and update appropriately + if (inventory == this.tinkerInput) { + + // empty whole grid to start with + this.uncraftingMatrix.clear(); + + // see if there is a recipe for the input + ItemStack inputStack = tinkerInput.getStackInSlot(0); + IRecipe[] recipes = getRecipesFor(inputStack); + + int size = recipes.length; + + if (size > 0) { + + IRecipe recipe = recipes[Math.floorMod(this.unrecipeInCycle, size)]; + ItemStack[] recipeItems = getIngredients(recipe); + + if (recipe instanceof IShapedRecipe) { + + int recipeWidth = getRecipeWidth ((IShapedRecipe) recipe); + int recipeHeight = getRecipeHeight((IShapedRecipe) recipe); + + // set uncrafting grid + for (int invY = 0; invY < recipeHeight; invY++) { + for (int invX = 0; invX < recipeWidth; invX++) { + + int index = invX + invY * recipeWidth; + if (index >= recipeItems.length) continue; + + ItemStack ingredient = normalizeIngredient(recipeItems[index].copy()); + this.uncraftingMatrix.setInventorySlotContents(invX + invY * 3, ingredient); + } + } + } else { + for (int i = 0; i < this.uncraftingMatrix.getSizeInventory(); i++) { + if (i < recipeItems.length) { + ItemStack ingredient = normalizeIngredient(recipeItems[i].copy()); + this.uncraftingMatrix.setInventorySlotContents(i, ingredient); + } + } + } + + // mark the appropriate number of damaged components + if (inputStack.isItemDamaged()) { + int damagedParts = countDamagedParts(inputStack); + + for (int i = 0; i < 9 && damagedParts > 0; i++) { + ItemStack stack = this.uncraftingMatrix.getStackInSlot(i); + if (isDamageableComponent(stack)) { + markStack(stack); + damagedParts--; + } + } + } + + // mark banned items + for (int i = 0; i < 9; i++) { + ItemStack ingredient = this.uncraftingMatrix.getStackInSlot(i); + if (isIngredientProblematic(ingredient)) { + markStack(ingredient); + } + } + + // store number of items this recipe produces (and thus how many input items are required for uncrafting) + this.uncraftingMatrix.numberOfInputItems = recipe.getRecipeOutput().getCount(); + this.uncraftingMatrix.uncraftingCost = calculateUncraftingCost(); + this.uncraftingMatrix.recraftingCost = 0; + + } else { + this.uncraftingMatrix.numberOfInputItems = 0; + this.uncraftingMatrix.uncraftingCost = 0; + } + } + // Now we've got the uncrafting logic set in, currently we don't modify the uncraftingMatrix. That's fine. + if (inventory == this.assemblyMatrix || inventory == this.tinkerInput) { + if (this.tinkerInput.isEmpty()) { + // display the output + chooseRecipe(this.assemblyMatrix); + this.uncraftingMatrix.recraftingCost = 0; + } else { // if (isMatrixEmpty(this.assemblyMatrix)) { // // we just emptied the assembly matrix and need to re-prepare for uncrafting -// this.tinkerResult.setInventorySlotContents(0, null); +// this.tinkerResult.setInventorySlotContents(0, ItemStack.EMPTY); // this.uncraftingMatrix.uncraftingCost = calculateUncraftingCost(); // this.uncraftingMatrix.recraftingCost = 0; // } // else { - // we placed an item in the assembly matrix, the next step will re-initialize these with correct values - this.tinkerResult.setInventorySlotContents(0, null); - this.uncraftingMatrix.uncraftingCost = calculateUncraftingCost(); - this.uncraftingMatrix.recraftingCost = 0; + // we placed an item in the assembly matrix, the next step will re-initialize these with correct values + this.tinkerResult.setInventorySlotContents(0, ItemStack.EMPTY); + this.uncraftingMatrix.uncraftingCost = calculateUncraftingCost(); + this.uncraftingMatrix.recraftingCost = 0; // } - } - } - - // repairing / recrafting: if there is an input item, and items in both grids, can we combine them to produce an output item that is the same type as the input item? - if (par1IInventory != this.combineMatrix && !isMatrixEmpty(this.uncraftingMatrix) && !isMatrixEmpty(this.assemblyMatrix)) { - // combine the two matrixen - for (int i = 0; i < 9; i++) { - if (this.assemblyMatrix.getStackInSlot(i) != null) { - this.combineMatrix.setInventorySlotContents(i, this.assemblyMatrix.getStackInSlot(i)); - } - else if (this.uncraftingMatrix.getStackInSlot(i) != null && this.uncraftingMatrix.getStackInSlot(i).stackSize > 0) { - this.combineMatrix.setInventorySlotContents(i, this.uncraftingMatrix.getStackInSlot(i)); - } - else { - this.combineMatrix.setInventorySlotContents(i, null); - } - } - // is there a result from this combined thing? - ItemStack result = CraftingManager.getInstance().findMatchingRecipe(this.combineMatrix, this.worldObj); - ItemStack input = this.tinkerInput.getStackInSlot(0); - - if (result != null && isValidMatchForInput(input, result)) { - // copy the tag compound - // or should we only copy enchantments? - NBTTagCompound inputTags = input.getTagCompound(); - if (inputTags != null) - { - inputTags = (NBTTagCompound) inputTags.copy(); - } - - // if the result has innate enchantments, add them on to our enchantment map - Map resultInnateEnchantments = null; - if (result.isItemEnchanted()) - { - resultInnateEnchantments = EnchantmentHelper.getEnchantments(result); - } - - // check if the input enchantments can even go onto the result item - Map inputEnchantments = null; - if (input.isItemEnchanted()) - { - inputEnchantments = EnchantmentHelper.getEnchantments(input); - for (Object key : inputEnchantments.keySet()) - { - int enchID = ((Integer)key).intValue(); - //int level = ((Integer)inputEnchantments.get(key)).intValue(); - Enchantment ench = Enchantment.enchantmentsList[enchID]; - - // remove enchantments that won't work - if (!ench.canApply(result)) - { - inputEnchantments.remove(key); - } - } - } - - if (inputTags != null) { - // remove enchantments, copy tags, re-add filtered enchantments - inputTags.removeTag("ench"); - result.setTagCompound((NBTTagCompound) inputTags.copy()); - if (inputEnchantments != null) - { - EnchantmentHelper.setEnchantments(inputEnchantments, result); - } - } - - - this.tinkerResult.setInventorySlotContents(0, result); - this.uncraftingMatrix.uncraftingCost = 0; - this.uncraftingMatrix.recraftingCost = calculateRecraftingCost(); - - // if there is a recrafting cost, increment the repair cost of the output - if (this.uncraftingMatrix.recraftingCost > 0 && !result.hasDisplayName()) - { - result.setRepairCost(input.getRepairCost() + 2); - } - - // finally, add any innate enchantments back onto the result - if (resultInnateEnchantments != null && resultInnateEnchantments.size() > 0) - { - for (Object key : resultInnateEnchantments.keySet()) - { - int enchID = ((Integer)key).intValue(); - int level = ((Integer)resultInnateEnchantments.get(key)).intValue(); - Enchantment ench = Enchantment.enchantmentsList[enchID]; - - if (EnchantmentHelper.getEnchantmentLevel(enchID, result) > level) - { - level = EnchantmentHelper.getEnchantmentLevel(enchID, result); - } - - if (EnchantmentHelper.getEnchantmentLevel(enchID, result) < level) - { - result.addEnchantment(ench, level); - } - } - } - } - } - } - - /** - * Problematic ingredients are not allowed to be uncrafted in the uncrafting table. - */ - protected boolean isIngredientProblematic(ItemStack ingredient) { - return ingredient != null && (ingredient.getItem().hasContainerItem(ingredient) || ingredient.getUnlocalizedName().contains("itemMatter")); + } + } + + // repairing / recrafting: if there is an input item, and items in both grids, can we combine them to produce an output item that is the same type as the input item? + if (inventory != this.combineMatrix && !this.uncraftingMatrix.isEmpty() && !this.assemblyMatrix.isEmpty()) { + // combine the two matrices + for (int i = 0; i < 9; i++) { + + ItemStack assembly = this.assemblyMatrix.getStackInSlot(i); + ItemStack uncrafting = this.uncraftingMatrix.getStackInSlot(i); + + if (!assembly.isEmpty()) { + this.combineMatrix.setInventorySlotContents(i, assembly); + } else if (!uncrafting.isEmpty() && !isMarked(uncrafting)) { + this.combineMatrix.setInventorySlotContents(i, uncrafting); + } else { + this.combineMatrix.setInventorySlotContents(i, ItemStack.EMPTY); + } + } + // is there a result from this combined thing? + chooseRecipe(this.combineMatrix); + + ItemStack input = this.tinkerInput.getStackInSlot(0); + ItemStack result = this.tinkerResult.getStackInSlot(0); + + if (!result.isEmpty() && isValidMatchForInput(input, result)) { + // copy the tag compound + // or should we only copy enchantments? + NBTTagCompound inputTags = null; + if (input.getTagCompound() != null) { + inputTags = input.getTagCompound().copy(); + } + + // if the result has innate enchantments, add them on to our enchantment map + Map resultInnateEnchantments = EnchantmentHelper.getEnchantments(result); + + Map inputEnchantments = EnchantmentHelper.getEnchantments(input); + // check if the input enchantments can even go onto the result item + inputEnchantments.keySet().removeIf(enchantment -> enchantment == null || !enchantment.canApply(result)); + + if (inputTags != null) { + // remove enchantments, copy tags, re-add filtered enchantments + inputTags.removeTag("ench"); + result.setTagCompound(inputTags); + EnchantmentHelper.setEnchantments(inputEnchantments, result); + } + + // finally, add any innate enchantments back onto the result + for (Map.Entry entry : resultInnateEnchantments.entrySet()) { + + Enchantment ench = entry.getKey(); + int level = entry.getValue(); + + // only apply enchants that are better than what we already have + if (EnchantmentHelper.getEnchantmentLevel(ench, result) < level) { + result.addEnchantment(ench, level); + } + } + + this.tinkerResult.setInventorySlotContents(0, result); + this.uncraftingMatrix.uncraftingCost = 0; + this.uncraftingMatrix.recraftingCost = calculateRecraftingCost(); + + // if there is a recrafting cost, increment the repair cost of the output + if (this.uncraftingMatrix.recraftingCost > 0 && !result.hasDisplayName()) { + result.setRepairCost(input.getRepairCost() + 2); + } + } + } } - /** - * Get the first valid shaped recipe for the item in the input - * - * @param inputStack - * @return - */ - @SuppressWarnings("unchecked") - public IRecipe getRecipeFor(ItemStack inputStack) { - if (inputStack != null) { - for (IRecipe recipe : (List)(CraftingManager.getInstance().getRecipeList())) { - if ((recipe instanceof ShapedRecipes || recipe instanceof ShapedOreRecipe) - && recipe.getRecipeOutput().getItem() == inputStack.getItem() && inputStack.stackSize >= recipe.getRecipeOutput().stackSize - && (!recipe.getRecipeOutput().getHasSubtypes() || recipe.getRecipeOutput().getItemDamage() == inputStack.getItemDamage())) { - return recipe; - } - } - } - return null; - } - - /** - * Checks if the result is a valid match for the input. Currently only accepts armor or tools that are the same type as the input - * - * @param resultStack - */ - public boolean isValidMatchForInput(ItemStack inputStack, ItemStack resultStack) { - if (inputStack.getItem() instanceof ItemPickaxe && resultStack.getItem() instanceof ItemPickaxe) { - return true; - } - if (inputStack.getItem() instanceof ItemAxe && resultStack.getItem() instanceof ItemAxe) { - return true; - } - if (inputStack.getItem() instanceof ItemSpade && resultStack.getItem() instanceof ItemSpade) { - return true; - } - if (inputStack.getItem() instanceof ItemHoe && resultStack.getItem() instanceof ItemHoe) { - return true; - } - if (inputStack.getItem() instanceof ItemSword && resultStack.getItem() instanceof ItemSword) { - return true; - } - if (inputStack.getItem() instanceof ItemBow && resultStack.getItem() instanceof ItemBow) { - return true; - } - - if (inputStack.getItem() instanceof ItemArmor && resultStack.getItem() instanceof ItemArmor) { - ItemArmor inputArmor = (ItemArmor)inputStack.getItem(); - ItemArmor resultArmor = (ItemArmor)resultStack.getItem(); - - return inputArmor.armorType == resultArmor.armorType; - } - - // nope! - return false; - } - - public int getUncraftingCost() { - return this.uncraftingMatrix.uncraftingCost; - } - - public int getRecraftingCost() { - return this.uncraftingMatrix.recraftingCost; + public static void markStack(ItemStack stack) { + stack.setTagInfo(TAG_MARKER, new NBTTagByte((byte) 1)); } - - /** - * Calculate the cost of uncrafting, if any. Return 0 if uncrafting is not available at this time - * - * @return - */ - public int calculateUncraftingCost() { - // we don't want to display anything if there is anything in the assembly grid - if (!isMatrixEmpty(this.assemblyMatrix)) { - return 0; - } - else { - return countDamageableParts(this.uncraftingMatrix); - } - } - - - /** - * Return the cost of recrafting, if any. Return 0 if recrafting is not available at this time - * - * @return - */ - public int calculateRecraftingCost() { - if (tinkerInput.getStackInSlot(0) == null || !tinkerInput.getStackInSlot(0).isItemEnchanted() || tinkerResult.getStackInSlot(0) == null) { - return 0; + public static boolean isMarked(ItemStack stack) { + NBTTagCompound stackTag = stack.getTagCompound(); + return stackTag != null && stackTag.getBoolean(TAG_MARKER); + } + + public static void unmarkStack(ItemStack stack) { + TFItemStackUtils.clearInfoTag(stack, TAG_MARKER); + } + + private static boolean isIngredientProblematic(ItemStack ingredient) { + return !ingredient.isEmpty() && ingredient.getItem().hasContainerItem(ingredient); + } + + private static ItemStack normalizeIngredient(ItemStack ingredient) { + if (!ingredient.isEmpty()) { + // OLD: fix weird recipe for diamond/ingot blocks + // Leaving this in, in case some modder does weird crap with an IRecipe + if (ingredient.getCount() > 1) { + ingredient.setCount(1); + } + if (ingredient.getItemDamage() == OreDictionary.WILDCARD_VALUE) { + ingredient.setItemDamage(0); + } + } + return ingredient; + } + + private static IRecipe[] getRecipesFor(ItemStack inputStack) { + + List recipes = new ArrayList<>(); + + if (!inputStack.isEmpty()) { + for (IRecipe recipe : CraftingManager.REGISTRY) { + if (recipe.canFit(3, 3) && !recipe.getIngredients().isEmpty() && matches(inputStack, recipe.getRecipeOutput())) { + recipes.add(recipe); + } + } + } + + return recipes.toArray(new IRecipe[0]); + } + + private static boolean matches(ItemStack input, ItemStack output) { + return input.getItem() == output.getItem() && input.getCount() >= output.getCount() + && (!output.getHasSubtypes() || input.getItemDamage() == output.getItemDamage()); + } + + private static IRecipe[] getRecipesFor(InventoryCrafting matrix, World world) { + + List recipes = new ArrayList<>(); + + for (IRecipe recipe : CraftingManager.REGISTRY) { + if (recipe.matches(matrix, world)) { + recipes.add(recipe); + } + } + + return recipes.toArray(new IRecipe[0]); + } + + private void chooseRecipe(InventoryCrafting inventory) { + + IRecipe[] recipes = getRecipesFor(inventory, world); + + if (recipes.length == 0) { + this.tinkerResult.setInventorySlotContents(0, ItemStack.EMPTY); + return; + } + + IRecipe recipe = recipes[Math.floorMod(this.recipeInCycle, recipes.length)]; + + if (recipe != null && (recipe.isDynamic() || !this.world.getGameRules().getBoolean("doLimitedCrafting") || ((EntityPlayerMP) this.player).getRecipeBook().isUnlocked(recipe))) { + this.tinkerResult.setRecipeUsed(recipe); + this.tinkerResult.setInventorySlotContents(0, recipe.getCraftingResult(inventory)); + } else { + this.tinkerResult.setInventorySlotContents(0, ItemStack.EMPTY); + } + } + + /** + * Checks if the result is a valid match for the input. Currently only accepts armor or tools that are the same type as the input + */ + // TODO Should we also check the slot the armors can go into, in case they don't extend armor class..? + private static boolean isValidMatchForInput(ItemStack inputStack, ItemStack resultStack) { + if (inputStack.getItem() instanceof ItemPickaxe && resultStack.getItem() instanceof ItemPickaxe) { + return true; + } + if (inputStack.getItem() instanceof ItemAxe && resultStack.getItem() instanceof ItemAxe) { + return true; + } + if (inputStack.getItem() instanceof ItemSpade && resultStack.getItem() instanceof ItemSpade) { + return true; + } + if (inputStack.getItem() instanceof ItemHoe && resultStack.getItem() instanceof ItemHoe) { + return true; } - else { - // okay, if we're here the input item must be enchanted, and we are repairing or recrafting it - ItemStack input = tinkerInput.getStackInSlot(0); - ItemStack output = tinkerResult.getStackInSlot(0); - - int cost = 0; - - // add innate repair cost - //System.out.println("Innate repair cost is " + input.getRepairCost()); - cost += input.getRepairCost(); - - // look at the input's enchantments and total them up - int enchantCost = countTotalEnchantmentCost(input); - //System.out.println("Enchantment cost is " + enchantCost); - cost += enchantCost; - - // broken pieces cost - int damagedCost = (1 + countDamagedParts(input)) * EnchantmentHelper.getEnchantments(output).size(); - //System.out.println("damagedCost is " + damagedCost); - cost += damagedCost; - - // factor in enchantibility difference - int enchantabilityDifference = input.getItem().getItemEnchantability() - output.getItem().getItemEnchantability(); - //System.out.println("enchantabilityDifference cost is " + enchantabilityDifference); - cost += enchantabilityDifference; - - // minimum cost of 1 if we're even calling this part - cost = Math.max(1, cost); - - return cost; + if (inputStack.getItem() instanceof ItemSword && resultStack.getItem() instanceof ItemSword) { + return true; } + if (inputStack.getItem() instanceof ItemBow && resultStack.getItem() instanceof ItemBow) { + return true; + } + + if (inputStack.getItem() instanceof ItemArmor && resultStack.getItem() instanceof ItemArmor) { + ItemArmor inputArmor = (ItemArmor) inputStack.getItem(); + ItemArmor resultArmor = (ItemArmor) resultStack.getItem(); + + return inputArmor.armorType == resultArmor.armorType; + } + + return false; + } + + public int getUncraftingCost() { + return this.uncraftingMatrix.uncraftingCost; + } + + public int getRecraftingCost() { + return this.uncraftingMatrix.recraftingCost; + } + + /** + * Calculate the cost of uncrafting, if any. Return 0 if uncrafting is not available at this time + */ + private int calculateUncraftingCost() { + // we don't want to display anything if there is anything in the assembly grid + return !this.assemblyMatrix.isEmpty() ? 0 : countDamageableParts(this.uncraftingMatrix); } /** - * - * - * @param itemStack - * @return + * Return the cost of recrafting, if any. Return 0 if recrafting is not available at this time */ - public int countHighestEnchantmentCost(ItemStack itemStack) { + private int calculateRecraftingCost() { + + ItemStack input = tinkerInput.getStackInSlot(0); + ItemStack output = tinkerResult.getStackInSlot(0); + + if (input.isEmpty() || !input.isItemEnchanted() || output.isEmpty()) { + return 0; + } + + // okay, if we're here the input item must be enchanted, and we are repairing or recrafting it + int cost = 0; + + // add innate repair cost + cost += input.getRepairCost(); + + // look at the input's enchantments and total them up + int enchantCost = countTotalEnchantmentCost(input); + cost += enchantCost; + + // broken pieces cost + int damagedCost = (1 + countDamagedParts(input)) * EnchantmentHelper.getEnchantments(output).size(); + cost += damagedCost; + + // factor in enchantibility difference + int enchantabilityDifference = input.getItem().getItemEnchantability() - output.getItem().getItemEnchantability(); + cost += enchantabilityDifference; + + // minimum cost of 1 if we're even calling this part + cost = Math.max(1, cost); + + return cost; + } + + public static int countHighestEnchantmentCost(ItemStack stack) { + int count = 0; - - // go through all 256 enchantment IDs, and see if the item has that enchantment, and at what level - for (Enchantment ench : Enchantment.enchantmentsList) { - if (ench != null) { - int level = EnchantmentHelper.getEnchantmentLevel(ench.effectId, itemStack); - if (level > count) { - //count = ench.getMinEnchantability(level); OLD - count += getWeightModifier(ench) * level; - } + + for (Map.Entry entry : EnchantmentHelper.getEnchantments(stack).entrySet()) { + + Enchantment ench = entry.getKey(); + int level = entry.getValue(); + + if (ench != null && level > count) { + //count = ench.getMinEnchantability(level); OLD + count += getWeightModifier(ench) * level; } } - + return count; } - /** - * - * - * @param itemStack - * @return - */ - public int countTotalEnchantmentCost(ItemStack itemStack) { + + private static int countTotalEnchantmentCost(ItemStack stack) { + int count = 0; - - // go through all 256 enchantment IDs, and see if the item has that enchantment, and at what level - for (Enchantment ench : Enchantment.enchantmentsList) { - if (ench != null) { - int level = EnchantmentHelper.getEnchantmentLevel(ench.effectId, itemStack); - if (level > 0) { - //count = ench.getMinEnchantability(level); OLD - count += getWeightModifier(ench) * level; - count += 1; - } + + for (Map.Entry entry : EnchantmentHelper.getEnchantments(stack).entrySet()) { + + Enchantment ench = entry.getKey(); + int level = entry.getValue(); + + if (ench != null && level > 0) { + count += getWeightModifier(ench) * level; + count += 1; } } - + return count; } - - public int getWeightModifier(Enchantment ench) - { - switch (ench.getWeight()) - { - case 1: - return 8; - case 2: - return 4; - case 3: - case 4: - case 5: - return 2; - case 6: - case 7: - case 8: - case 9: - default: - case 10: - return 1; - } + + private static int getWeightModifier(Enchantment ench) { + switch (ench.getRarity().getWeight()) { + case 1: + return 8; + case 2: + return 4; + case 3: + case 4: + case 5: + return 2; + case 6: + case 7: + case 8: + case 9: + default: + case 10: + return 1; + } } - - /** - * Override the SlotClick method to get what we want - */ - @Override - public ItemStack slotClick(int slotNum, int mouseButton, int shiftHeld, EntityPlayer par4EntityPlayer) { - - // if the player is trying to take an item out of the assembly grid, and the assembly grid is empty, take the item from the uncrafting grid. - if (slotNum > 0 && par4EntityPlayer.inventory.getItemStack() == null && ((Slot)this.inventorySlots.get(slotNum)).inventory == this.assemblyMatrix && !((Slot)this.inventorySlots.get(slotNum)).getHasStack()) { - // is the assembly matrix empty? - if(isMatrixEmpty(this.assemblyMatrix)) { - slotNum -= 9; - } - } - - // if the player is trying to take the result item and they don't have the XP to pay for it, reject them - if (slotNum > 0 &&((Slot)this.inventorySlots.get(slotNum)).inventory == this.tinkerResult - && calculateRecraftingCost() > par4EntityPlayer.experienceLevel && !par4EntityPlayer.capabilities.isCreativeMode) { - return null; - } - - // similarly, reject uncrafting if they can't do that either - if (slotNum > 0 &&((Slot)this.inventorySlots.get(slotNum)).inventory == this.uncraftingMatrix - && calculateUncraftingCost() > par4EntityPlayer.experienceLevel && !par4EntityPlayer.capabilities.isCreativeMode) { - return null; - } - - // don't allow uncrafting if the server option is turned off - if (slotNum > 0 &&((Slot)this.inventorySlots.get(slotNum)).inventory == this.uncraftingMatrix && TwilightForestMod.disableUncrafting) { - // send the player a message - //par4EntityPlayer.sendChatToPlayer("Uncrafting is disabled in the server configuration."); - return null; - } - - // finally, don't give them damaged goods - if (slotNum > 0 &&((Slot)this.inventorySlots.get(slotNum)).inventory == this.uncraftingMatrix - && (((Slot)this.inventorySlots.get(slotNum)).getStack() == null || ((Slot)this.inventorySlots.get(slotNum)).getStack().stackSize == 0)) { - return null; - } - - // also we may need to detect here when the player is increasing the stack size of the input slot - ItemStack ret = super.slotClick(slotNum, mouseButton, shiftHeld, par4EntityPlayer); - + @Override + public ItemStack slotClick(int slotNum, int mouseButton, ClickType clickType, EntityPlayer player) { + + // if the player is trying to take an item out of the assembly grid, and the assembly grid is empty, take the item from the uncrafting grid. + if (slotNum > 0 && this.inventorySlots.get(slotNum).inventory == this.assemblyMatrix + && player.inventory.getItemStack().isEmpty() && !this.inventorySlots.get(slotNum).getHasStack()) { + + // is the assembly matrix empty? + if (this.assemblyMatrix.isEmpty()) { + slotNum -= 9; + } + } + + // if the player is trying to take the result item and they don't have the XP to pay for it, reject them + if (slotNum > 0 && this.inventorySlots.get(slotNum).inventory == this.tinkerResult + && calculateRecraftingCost() > player.experienceLevel && !player.capabilities.isCreativeMode) { + + return ItemStack.EMPTY; + } + + if (slotNum > 0 && this.inventorySlots.get(slotNum).inventory == this.uncraftingMatrix) { + + // similarly, reject uncrafting if they can't do that either + if (calculateUncraftingCost() > player.experienceLevel && !player.capabilities.isCreativeMode) { + return ItemStack.EMPTY; + } + + // don't allow uncrafting if the server option is turned off + if (TFConfig.disableUncrafting) { + return ItemStack.EMPTY; + } + + // finally, don't give them damaged goods + ItemStack stackInSlot = this.inventorySlots.get(slotNum).getStack(); + if (stackInSlot.isEmpty() || isMarked(stackInSlot)) { + return ItemStack.EMPTY; + } + } + + // also we may need to detect here when the player is increasing the stack size of the input slot + ItemStack ret = super.slotClick(slotNum, mouseButton, clickType, player); + // just trigger this event whenever the input slot is clicked for any reason - if (slotNum > 0 && ((Slot)this.inventorySlots.get(slotNum)).inventory instanceof InventoryTFGoblinInput) { - this.onCraftMatrixChanged(this.tinkerInput); - } + if (slotNum > 0 && this.inventorySlots.get(slotNum).inventory == this.tinkerInput) { + this.onCraftMatrixChanged(this.tinkerInput); + } - return ret; + return ret; } - - @Override - protected void retrySlotClick(int slotNum, int mouseButton, boolean par3, EntityPlayer par4EntityPlayer) - { - // if they are taking something out of the uncrafting matrix, bump the slot number back to the assembly matrix - // otherwise we lose the stuff in the uncrafting matrix when we shift-click to take multiple things - if (((Slot)this.inventorySlots.get(slotNum)).inventory == this.uncraftingMatrix) - { - slotNum += 9; - } - - this.slotClick(slotNum, mouseButton, 1, par4EntityPlayer); - } - - /** - * Checks if an inventory has any items in it - * @param matrix - * @return - */ - private boolean isMatrixEmpty(IInventory matrix) { - boolean matrixEmpty = true; - for (int i = 0; i < matrix.getSizeInventory(); i++) { - if (matrix.getStackInSlot(i) != null) { - matrixEmpty = false; - } + + // todo 1.12 evaluate if this logic needs to be moved elsewhere (method removed in 1.12) + protected void retrySlotClick(int slotNum, int mouseButton, boolean par3, EntityPlayer player) { + // if they are taking something out of the uncrafting matrix, bump the slot number back to the assembly matrix + // otherwise we lose the stuff in the uncrafting matrix when we shift-click to take multiple things + if (this.inventorySlots.get(slotNum).inventory == this.uncraftingMatrix) { + slotNum += 9; } - return matrixEmpty; + + this.slotClick(slotNum, mouseButton, ClickType.QUICK_MOVE, player); } - - + /** * Should the specified item count for taking damage? - * - * @param itemStack - * @return */ - public boolean isDamageableComponent(ItemStack itemStack) { - return itemStack != null && itemStack.getItem() != Items.stick; - } - - /** - * Count how many items in an inventory can take damage - * - * @param matrix - * @return - */ - public int countDamageableParts(IInventory matrix) { - int count = 0; - for (int i = 0; i < matrix.getSizeInventory(); i++) { - if (isDamageableComponent(matrix.getStackInSlot(i))) { - count++; - } - } - return count; - } - - /** - * Determine, based on the item damage, how many parts are damaged. We're already - * assuming that the item is loaded into the uncrafing matrix. - */ - public int countDamagedParts(ItemStack input) { - int totalMax4 = Math.max(4, countDamageableParts(this.uncraftingMatrix)); - float damage = (float)input.getItemDamage() / (float)input.getMaxDamage(); - int damagedParts = (int) Math.ceil(totalMax4 * damage); - return damagedParts; - } - - /** - * Called to transfer a stack from one inventory to the other eg. when shift clicking. - */ - @Override - public ItemStack transferStackInSlot(EntityPlayer player, int slotNum) - { - ItemStack copyItem = null; - Slot transferSlot = (Slot)this.inventorySlots.get(slotNum); - - if (transferSlot != null && transferSlot.getHasStack()) - { - ItemStack transferStack = transferSlot.getStack(); - copyItem = transferStack.copy(); - - if (slotNum == 0 || slotNum == 1) - { - // result or input goes to inventory or hotbar - if (!this.mergeItemStack(transferStack, 20, 56, true)) - { - return null; - } - - transferSlot.onSlotChange(transferStack, copyItem); // what does this do? - } - else if (slotNum >= 20 && slotNum < 47) - { - // inventory goes to hotbar - if (!this.mergeItemStack(transferStack, 47, 56, false)) - { - return null; - } - } - else if (slotNum >= 47 && slotNum < 56) - { - // hotbar goes to inventory - if (!this.mergeItemStack(transferStack, 20, 47, false)) - { - return null; - } - } - else if (!this.mergeItemStack(transferStack, 20, 56, false)) - { - // crafting area goes to inventory or hotbar - return null; - } - - if (transferStack.stackSize == 0) - { - transferSlot.putStack((ItemStack)null); - } - else - { - transferSlot.onSlotChanged(); - } - - if (transferStack.stackSize == copyItem.stackSize) - { - return null; - } - - transferSlot.onPickupFromSlot(player, transferStack); - } - - return copyItem; - } - - - - - /** - * Callback for when the crafting gui is closed. - */ - @Override - public void onContainerClosed(EntityPlayer par1EntityPlayer) - { - super.onContainerClosed(par1EntityPlayer); - - if (!this.worldObj.isRemote) - { - // drop items in assembly grid - for (int i = 0; i < 9; ++i) - { - ItemStack assemblyStack = this.assemblyMatrix.getStackInSlotOnClosing(i); - - if (assemblyStack != null) - { - par1EntityPlayer.dropPlayerItemWithRandomChoice(assemblyStack, false); - } - } - - // drop input - ItemStack inputStack = this.tinkerInput.getStackInSlotOnClosing(0); - if (inputStack != null) - { - par1EntityPlayer.dropPlayerItemWithRandomChoice(inputStack, false); - } - } - } + private static boolean isDamageableComponent(ItemStack itemStack) { + return !itemStack.isEmpty() && itemStack.getItem() != Items.STICK; + } /** - * If we can determine this recipe's items, return it. + * Count how many items in an inventory can take damage */ - public ItemStack[] getRecipeItems(IRecipe recipe) { - if (recipe instanceof ShapedRecipes) - { - return getRecipeItemsShaped((ShapedRecipes) recipe); - } - if (recipe instanceof ShapedOreRecipe) - { - return getRecipeItemsOre((ShapedOreRecipe) recipe); + private static int countDamageableParts(IInventory matrix) { + int count = 0; + for (int i = 0; i < matrix.getSizeInventory(); i++) { + if (isDamageableComponent(matrix.getStackInSlot(i))) { + count++; + } } - return null; + return count; } - - /** - * Uses ModLoader.getPrivateValue to get the items associated with a recipe. - * @param shaped - * @return - */ - public ItemStack[] getRecipeItemsShaped(ShapedRecipes shaped) { - return shaped.recipeItems; - -// try { -// return (ItemStack[])(ObfuscationReflectionHelper.getPrivateValue(ShapedRecipes.class, shaped, 2)); -// } catch (IllegalArgumentException e) { -// e.printStackTrace(); -// } catch (SecurityException e) { -// e.printStackTrace(); -// } -// return null; - } - - /** - * Uses ModLoader.getPrivateValue to get the items associated with a recipe. - * @param shaped - * @return - */ - @SuppressWarnings("unchecked") - public ItemStack[] getRecipeItemsOre(ShapedOreRecipe shaped) { - try { - // ShapedOreRecipes can have either an ItemStack or an ArrayList of ItemStacks - Object[] objects = ObfuscationReflectionHelper.getPrivateValue(ShapedOreRecipe.class, shaped, 3); - ItemStack[] items = new ItemStack[objects.length]; - - for (int i = 0; i < objects.length; i++) - { - if (objects[i] instanceof ItemStack) - { - items[i] = (ItemStack)objects[i]; - } - if (objects[i] instanceof ArrayList && ((ArrayList)objects[i]).size() > 0) - { - items[i] = ((ArrayList)objects[i]).get(0); - } - } - - return items; - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (SecurityException e) { - e.printStackTrace(); - } - return null; - } - + /** - * If we can determine this recipe's width, return it. + * Determine, based on the item damage, how many parts are damaged. We're already + * assuming that the item is loaded into the uncrafing matrix. */ - public int getRecipeWidth(IRecipe recipe) { - if (recipe instanceof ShapedRecipes) - { - return getRecipeWidthShaped((ShapedRecipes) recipe); - } - if (recipe instanceof ShapedOreRecipe) - { - return getRecipeWidthOre((ShapedOreRecipe) recipe); - } - return -1; + private int countDamagedParts(ItemStack input) { + int totalMax4 = Math.max(4, countDamageableParts(this.uncraftingMatrix)); + float damage = (float) input.getItemDamage() / (float) input.getMaxDamage(); + return (int) Math.ceil(totalMax4 * damage); } /** - * Uses ModLoader.getPrivateValue to get the recipe width - * @param shaped - * @return - */ - public int getRecipeWidthShaped(ShapedRecipes shaped) { - return shaped.recipeWidth; - -// try { -// return ((Integer)(ObfuscationReflectionHelper.getPrivateValue(ShapedRecipes.class, shaped, 0))).intValue(); -// } catch (IllegalArgumentException e) { -// e.printStackTrace(); -// } catch (SecurityException e) { -// e.printStackTrace(); -// } -// return 0; - } - - /** - * Uses ModLoader.getPrivateValue to get the recipe width - * @param shaped - * @return - */ - public int getRecipeWidthOre(ShapedOreRecipe shaped) { - try { - return ((Integer)(ObfuscationReflectionHelper.getPrivateValue(ShapedOreRecipe.class, shaped, 4))).intValue(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (SecurityException e) { - e.printStackTrace(); - } - return 0; - } - - /** - * If we can determine this recipe's width, return it. + * Called to transfer a stack from one inventory to the other eg. when shift clicking. */ - public int getRecipeHeight(IRecipe recipe) { - if (recipe instanceof ShapedRecipes) - { - return getRecipeHeightShaped((ShapedRecipes) recipe); + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int slotNum) { + + Slot transferSlot = this.inventorySlots.get(slotNum); + + if (transferSlot == null || !transferSlot.getHasStack()) { + return ItemStack.EMPTY; + } + + ItemStack transferStack = transferSlot.getStack(); + ItemStack copyItem = transferStack.copy(); + + if (slotNum == 0) { + // result or input goes to inventory or hotbar + if (!this.mergeItemStack(transferStack, 20, 56, true)) { + return ItemStack.EMPTY; + } + + transferSlot.onSlotChange(transferStack, copyItem); // what does this do? + } else if (slotNum == 1) { + transferStack.getItem().onCreated(transferStack, this.world, player); + + if (!this.mergeItemStack(transferStack, 20, 56, true)) + return ItemStack.EMPTY; + + transferSlot.onSlotChange(transferStack, copyItem); + } else if (slotNum >= 20 && slotNum < 47) { + // Checks uncrafting input slot first + if (!this.mergeItemStack(transferStack, 0, 1, false)) { + // inventory goes to hotbar + if (!this.mergeItemStack(transferStack, 47, 56, false)) { + return ItemStack.EMPTY; + } + } + } else if (slotNum >= 47 && slotNum < 56) { + // Checks uncrafting input slot first + if (!this.mergeItemStack(transferStack, 0, 1, false)) { + // hotbar goes to inventory + if (!this.mergeItemStack(transferStack, 20, 47, false)) { + return ItemStack.EMPTY; + } + } + } else if (!this.mergeItemStack(transferStack, 20, 56, false)) { + // crafting area goes to inventory or hotbar + return ItemStack.EMPTY; } - if (recipe instanceof ShapedOreRecipe) - { - return getRecipeHeightOre((ShapedOreRecipe) recipe); + + if (transferStack.getCount() == 0) { + transferSlot.putStack(ItemStack.EMPTY); + } else { + transferSlot.onSlotChanged(); + } + + if (transferStack.getCount() == copyItem.getCount()) { + return ItemStack.EMPTY; } - return -1; - } - - /** - * Uses ModLoader.getPrivateValue to get the recipe height - * @param shaped - * @return - */ - public int getRecipeHeightShaped(ShapedRecipes shaped) { - return shaped.recipeHeight; -// try { -// return ((Integer)(ObfuscationReflectionHelper.getPrivateValue(ShapedRecipes.class, shaped, 1))).intValue(); -// } catch (IllegalArgumentException e) { -// e.printStackTrace(); -// } catch (SecurityException e) { -// e.printStackTrace(); -// } -// return 0; - } - - /** - * Uses ModLoader.getPrivateValue to get the recipe height - * @param shaped - * @return - */ - public int getRecipeHeightOre(ShapedOreRecipe shaped) { - try { - return ((Integer)(ObfuscationReflectionHelper.getPrivateValue(ShapedOreRecipe.class, shaped, 5))).intValue(); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (SecurityException e) { - e.printStackTrace(); - } - return 0; - } + return transferSlot.onTake(player, transferStack); + } @Override - public boolean canInteractWith(EntityPlayer var1) { - return true; + public void onContainerClosed(EntityPlayer player) { + super.onContainerClosed(player); + + if (!player.world.isRemote) { + clearContainer(player, world, assemblyMatrix); + clearContainer(player, world, tinkerInput); + } + } + + private ItemStack[] getIngredients(IRecipe recipe) { + // todo 1.12 recheck + ItemStack[] stacks = new ItemStack[recipe.getIngredients().size()]; + + for (int i = 0; i < recipe.getIngredients().size(); i++) { + ItemStack[] matchingStacks = recipe.getIngredients().get(i).getMatchingStacks(); + stacks[i] = matchingStacks.length > 0 ? matchingStacks[Math.floorMod(this.ingredientsInCycle, matchingStacks.length)] : ItemStack.EMPTY; + } + + return stacks; + } + + private static int getRecipeWidth(IShapedRecipe recipe) { + return recipe.getRecipeWidth(); } + private static int getRecipeHeight(IShapedRecipe recipe) { + return recipe.getRecipeHeight(); + } + + @Override + public boolean canInteractWith(EntityPlayer player) { + return player.getDistanceSqToCenter(this.pos) <= 64.0D && this.world.getBlockState(this.pos).getBlock() == TFBlocks.uncrafting_table; + } } diff --git a/src/main/java/twilightforest/inventory/InventoryTFGoblinInput.java b/src/main/java/twilightforest/inventory/InventoryTFGoblinInput.java index 2e48d0aa8e..0043211076 100644 --- a/src/main/java/twilightforest/inventory/InventoryTFGoblinInput.java +++ b/src/main/java/twilightforest/inventory/InventoryTFGoblinInput.java @@ -3,157 +3,132 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; - +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; public class InventoryTFGoblinInput implements IInventory { - - private ItemStack[] stackInput = new ItemStack[1]; - private ContainerTFUncrafting craftingContainer; - public InventoryTFGoblinInput(ContainerTFUncrafting containerTFGoblinCrafting) { + private ItemStack stackInput = ItemStack.EMPTY; + private final ContainerTFUncrafting craftingContainer; + + public InventoryTFGoblinInput(ContainerTFUncrafting containerTFGoblinCrafting) { this.craftingContainer = containerTFGoblinCrafting; } - /** - * Returns the number of slots in the inventory. - */ - @Override - public int getSizeInventory() - { - return 1; - } - - /** - * Returns the stack in slot i - */ - @Override - public ItemStack getStackInSlot(int par1) - { - return this.stackInput[par1]; - } - - /** - * Returns the name of the inventory. - */ - @Override - public String getInventoryName() - { - return "Input"; - } - - /** - * Decrease the size of the stack in slot (first int arg) by the amount of the second int arg. Returns the new - * stack. - */ - @Override - public ItemStack decrStackSize(int slotNum, int amount) - { - - if (this.stackInput[slotNum] != null) - { - ItemStack takenStack; - - if (this.stackInput[slotNum].stackSize <= amount) - { - takenStack = this.stackInput[slotNum]; - this.stackInput[slotNum] = null; - this.craftingContainer.onCraftMatrixChanged(this); - return takenStack; - } - else - { - takenStack = this.stackInput[slotNum].splitStack(amount); - - if (this.stackInput[slotNum].stackSize == 0) - { - this.stackInput[slotNum] = null; - } - - this.craftingContainer.onCraftMatrixChanged(this); - return takenStack; - } - } - else - { - return null; - } - } - - /** - * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - - * like when you close a workbench GUI. - */ - @Override - public ItemStack getStackInSlotOnClosing(int par1) - { - if (this.stackInput[par1] != null) - { - ItemStack var2 = this.stackInput[par1]; - this.stackInput[par1] = null; - return var2; - } - else - { - return null; - } - } - - /** - * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). - */ - @Override - public void setInventorySlotContents(int par1, ItemStack par2ItemStack) - { - this.stackInput[par1] = par2ItemStack; - this.craftingContainer.onCraftMatrixChanged(this); - } - - /** - * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't - * this more of a set than a get?* - */ - @Override - public int getInventoryStackLimit() - { - return 64; - } - - /** - * Called when an the contents of an Inventory change, usually - */ - @Override + @Override + public int getSizeInventory() { + return 1; + } + + @Override + public boolean isEmpty() { + return stackInput.isEmpty(); + } + + @Override + public ItemStack getStackInSlot(int index) { + return index == 0 ? stackInput : ItemStack.EMPTY; + } + + @Override + public String getName() { + return "Input"; + } + + @Override + public ItemStack decrStackSize(int index, int amount) { + if (index == 0 && !this.stackInput.isEmpty()) { + ItemStack takenStack; + + if (this.stackInput.getCount() <= amount) { + takenStack = this.stackInput; + this.stackInput = ItemStack.EMPTY; + this.craftingContainer.onCraftMatrixChanged(this); + return takenStack; + } else { + takenStack = this.stackInput.splitStack(amount); + this.craftingContainer.onCraftMatrixChanged(this); + return takenStack; + } + } else { + return ItemStack.EMPTY; + } + } + + @Override + public ItemStack removeStackFromSlot(int index) { + if (index == 0 && !this.stackInput.isEmpty()) { + ItemStack stack = this.stackInput; + this.stackInput = ItemStack.EMPTY; + return stack; + } else { + return ItemStack.EMPTY; + } + } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) { + if (index == 0) { + this.stackInput = stack; + this.craftingContainer.onCraftMatrixChanged(this); + } + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override public void markDirty() { - this.craftingContainer.onCraftMatrixChanged(this); - } - - /** - * Do not make give this method the name canInteractWith because it clashes with Container - */ - @Override - public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) - { - return true; - } - - @Override - public void openInventory() {} - - @Override - public void closeInventory() {} - - /** - * Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. - */ - @Override - public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack) - { - return true; - } - - @Override - public boolean hasCustomInventoryName() { - return false; + this.craftingContainer.onCraftMatrixChanged(this); + } + + @Override + public boolean isUsableByPlayer(EntityPlayer player) { + return true; + } + + @Override + public void openInventory(EntityPlayer player) { + } + + @Override + public void closeInventory(EntityPlayer player) { } + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) { + return true; + } + + @Override + public int getField(int id) { + return 0; + } + + @Override + public void setField(int id, int value) { + } + + @Override + public int getFieldCount() { + return 0; + } + + @Override + public void clear() { + stackInput = ItemStack.EMPTY; + } + + @Override + public boolean hasCustomName() { + return false; + } + + @Override + public ITextComponent getDisplayName() { + return new TextComponentString(getName()); + } } diff --git a/src/main/java/twilightforest/inventory/InventoryTFGoblinUncrafting.java b/src/main/java/twilightforest/inventory/InventoryTFGoblinUncrafting.java index 172b10f975..1ecc261716 100644 --- a/src/main/java/twilightforest/inventory/InventoryTFGoblinUncrafting.java +++ b/src/main/java/twilightforest/inventory/InventoryTFGoblinUncrafting.java @@ -1,24 +1,22 @@ package twilightforest.inventory; -import twilightforest.TwilightForestMod; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; - +import net.minecraft.util.NonNullList; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import twilightforest.TFConfig; public class InventoryTFGoblinUncrafting implements IInventory { - private ItemStack[] contents = new ItemStack[9]; + private final NonNullList contents = NonNullList.withSize(9, ItemStack.EMPTY); + public int numberOfInputItems; public int uncraftingCost; public int recraftingCost; - - public InventoryTFGoblinUncrafting(ContainerTFUncrafting containerTFGoblinCrafting) { - // TODO Auto-generated constructor stub - } - - + public InventoryTFGoblinUncrafting(ContainerTFUncrafting container) {} @Override public int getSizeInventory() { @@ -26,75 +24,54 @@ public int getSizeInventory() { } @Override - public ItemStack getStackInSlot(int var1) { - return contents[var1]; + public boolean isEmpty() { + for (ItemStack stack : contents) { + if (!stack.isEmpty()) { + return false; + } + } + return true; } @Override - public ItemStack decrStackSize(int slotNum, int amount) { - if (this.contents[slotNum] != null) - { - ItemStack takenStack; - - if (this.contents[slotNum].stackSize <= amount) - { - takenStack = this.contents[slotNum]; - this.contents[slotNum] = null; - - //this.eventHandler.onCraftMatrixChanged(this); - return takenStack; - } - else - { - takenStack = this.contents[slotNum].splitStack(amount); - - //System.out.println("Stack size in slot " + slotNum + " is now " + this.contents[slotNum].stackSize); - - if (this.contents[slotNum].stackSize == 0) - { - this.contents[slotNum] = null; - } + public ItemStack getStackInSlot(int index) { + return contents.get(index); + } - //this.eventHandler.onCraftMatrixChanged(this); - return takenStack; - } - } - else - { - return null; + @Override + public ItemStack decrStackSize(int index, int amount) { + ItemStack stack = this.contents.get(index); + if (stack.isEmpty()) return ItemStack.EMPTY; + if (stack.getCount() <= amount) { + this.contents.set(index, ItemStack.EMPTY); + //this.eventHandler.onCraftMatrixChanged(this); + return stack; + } else { + return stack.splitStack(amount); } - } @Override - public ItemStack getStackInSlotOnClosing(int par1) { - if (this.contents[par1] != null) - { - ItemStack var2 = this.contents[par1]; - this.contents[par1] = null; - return var2; - } - else - { - return null; - } + public ItemStack removeStackFromSlot(int index) { + ItemStack stack = this.contents.get(index); + if (stack.isEmpty()) return ItemStack.EMPTY; + this.contents.set(index, ItemStack.EMPTY); + return stack; } @Override - public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { - this.contents[par1] = par2ItemStack; + public void setInventorySlotContents(int index, ItemStack stack) { + this.contents.set(index, stack); - if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) - { - par2ItemStack.stackSize = this.getInventoryStackLimit(); + if (!stack.isEmpty() && stack.getCount() > this.getInventoryStackLimit()) { + stack.setCount(this.getInventoryStackLimit()); } this.markDirty(); } @Override - public String getInventoryName() { - // TODO Auto-generated method stub + public String getName() { return "twilightforest.goblincrafting"; } @@ -104,31 +81,55 @@ public int getInventoryStackLimit() { } @Override - public void markDirty() { } + public void markDirty() { + } @Override - public boolean isUseableByPlayer(EntityPlayer var1) { - return !TwilightForestMod.disableUncrafting; + public boolean isUsableByPlayer(EntityPlayer player) { + return !TFConfig.disableUncrafting; } @Override - public void openInventory() { } + public void openInventory(EntityPlayer player) { + } + + @Override + public void closeInventory(EntityPlayer player) { + } + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) { + return false; + } + + @Override + public int getField(int id) { + return 0; + } + + @Override + public void setField(int id, int value) { + + } @Override - public void closeInventory() { } + public int getFieldCount() { + return 0; + } - /** - * Returns true if automation is allowed to insert the given stack (ignoring stack size) into the given slot. - */ @Override - public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack) - { - return false; - } + public void clear() { + contents.clear(); + } @Override - public boolean hasCustomInventoryName() { + public boolean hasCustomName() { return false; } + @Override + public ITextComponent getDisplayName() { + return new TextComponentString(this.getName()); + } + } diff --git a/src/main/java/twilightforest/inventory/SlotTFGoblinAssembly.java b/src/main/java/twilightforest/inventory/SlotTFGoblinAssembly.java index 8f71a97e2c..b62d0183d6 100644 --- a/src/main/java/twilightforest/inventory/SlotTFGoblinAssembly.java +++ b/src/main/java/twilightforest/inventory/SlotTFGoblinAssembly.java @@ -4,16 +4,9 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; - public class SlotTFGoblinAssembly extends Slot { - - public SlotTFGoblinAssembly(EntityPlayer par1EntityPlayer, IInventory inputSlot, IInventory assemblyMatrix, IInventory uncraftingMatrix, int slotNum, int x, int y) - { - super(assemblyMatrix, slotNum, x, y); - } - - - - + public SlotTFGoblinAssembly(EntityPlayer player, IInventory inputSlot, IInventory assemblyMatrix, IInventory uncraftingMatrix, int slotNum, int x, int y) { + super(assemblyMatrix, slotNum, x, y); + } } diff --git a/src/main/java/twilightforest/inventory/SlotTFGoblinCraftResult.java b/src/main/java/twilightforest/inventory/SlotTFGoblinCraftResult.java index c2189e77a9..01eefa1a63 100644 --- a/src/main/java/twilightforest/inventory/SlotTFGoblinCraftResult.java +++ b/src/main/java/twilightforest/inventory/SlotTFGoblinCraftResult.java @@ -7,55 +7,43 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; - public class SlotTFGoblinCraftResult extends SlotCrafting { - - /** The player that is using the GUI where this slot resides. */ - protected EntityPlayer thePlayer; - protected IInventory inputSlot; - protected InventoryTFGoblinUncrafting uncraftingMatrix; - protected InventoryCrafting assemblyMatrix; - protected IInventory resultSlot; - - public SlotTFGoblinCraftResult(EntityPlayer player, IInventory input, IInventory uncraftingMatrix, IInventory assemblyMatrix, IInventory result, int slotIndex, int x, int y) { - super(player, assemblyMatrix, result, slotIndex, x, y); - this.thePlayer = player; + + private final EntityPlayer player; + private final IInventory inputSlot; + private final InventoryTFGoblinUncrafting uncraftingMatrix; + private final InventoryCrafting assemblyMatrix; + + public SlotTFGoblinCraftResult(EntityPlayer player, IInventory input, IInventory uncraftingMatrix, IInventory assemblyMatrix, IInventory result, int slotIndex, int x, int y) { + super(player, (InventoryCrafting) assemblyMatrix, result, slotIndex, x, y); + this.player = player; this.inputSlot = input; this.uncraftingMatrix = (InventoryTFGoblinUncrafting) uncraftingMatrix; this.assemblyMatrix = (InventoryCrafting) assemblyMatrix; } - /** - * Called when the player picks up an item from an inventory slot - */ @Override - public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par1ItemStack) { + public ItemStack onTake(EntityPlayer player, ItemStack stack) { // let's see, if the assembly matrix can produce this item, then it's a normal recipe, if not, it's combined. Will that work? boolean combined = true; - - if (ItemStack.areItemStacksEqual(CraftingManager.getInstance().findMatchingRecipe(this.assemblyMatrix, this.thePlayer.worldObj), par1ItemStack)) { + + if (ItemStack.areItemStacksEqual(CraftingManager.findMatchingResult(this.assemblyMatrix, this.player.world), stack)) { combined = false; } - + if (combined) { // charge the player before the stacks empty if (this.uncraftingMatrix.recraftingCost > 0) { - this.thePlayer.addExperienceLevel(-this.uncraftingMatrix.recraftingCost); - - //System.out.println("Charging the player " + this.uncraftingMatrix.recraftingCost + " experience for recrafting"); + this.player.addExperienceLevel(-this.uncraftingMatrix.recraftingCost); } // if we are using a combined recipe, wipe the uncrafting matrix and decrement the input appropriately for (int i = 0; i < uncraftingMatrix.getSizeInventory(); i++) { - this.uncraftingMatrix.setInventorySlotContents(i, null); + this.uncraftingMatrix.setInventorySlotContents(i, ItemStack.EMPTY); this.inputSlot.decrStackSize(0, this.uncraftingMatrix.numberOfInputItems); } } - - super.onPickupFromSlot(par1EntityPlayer, par1ItemStack); - } - - - + return super.onTake(player, stack); + } } diff --git a/src/main/java/twilightforest/inventory/SlotTFGoblinUncrafting.java b/src/main/java/twilightforest/inventory/SlotTFGoblinUncrafting.java index 44d4f4970f..5ded1ffb5c 100644 --- a/src/main/java/twilightforest/inventory/SlotTFGoblinUncrafting.java +++ b/src/main/java/twilightforest/inventory/SlotTFGoblinUncrafting.java @@ -1,102 +1,102 @@ package twilightforest.inventory; -import twilightforest.TwilightForestMod; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; - +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; public class SlotTFGoblinUncrafting extends Slot { - - protected EntityPlayer thePlayer; - protected IInventory inputSlot; - protected InventoryTFGoblinUncrafting uncraftingMatrix; - protected IInventory assemblyMatrix; - - public SlotTFGoblinUncrafting(EntityPlayer par1EntityPlayer, IInventory inputSlot, InventoryTFGoblinUncrafting uncraftingMatrix, IInventory assemblyMatrix, int slotNum, int x, int y) - { - super(uncraftingMatrix, slotNum, x, y); - this.thePlayer = par1EntityPlayer; - this.inputSlot = inputSlot; - this.uncraftingMatrix = uncraftingMatrix; - this.assemblyMatrix = assemblyMatrix; - } - - - /** - * Check if the stack is a valid item for this slot. Always true beside for the armor slots. - */ - @Override - public boolean isItemValid(ItemStack par1ItemStack) - { - // don't put things in this matrix - return false; - } - - /** - * Return whether this slot's stack can be taken from this slot. - */ - public boolean canTakeStack(EntityPlayer par1EntityPlayer) - { - // if there is anything in the assembly matrix, then you cannot have these items - for (int i = 0; i < this.assemblyMatrix.getSizeInventory(); i++) - { - if (this.assemblyMatrix.getStackInSlot(i) != null) - { - return false; - } - } - - // if uncrafting is disabled, no! - if (TwilightForestMod.disableUncrafting) { - return false; - } - - // if you don't have enough XP, no - if (this.uncraftingMatrix.uncraftingCost > par1EntityPlayer.experienceLevel && !par1EntityPlayer.capabilities.isCreativeMode) { - return false; - } - - return true; - } - - /** - * Called when the player picks up an item from an inventory slot - */ + protected final EntityPlayer player; + protected final IInventory inputSlot; + protected final InventoryTFGoblinUncrafting uncraftingMatrix; + protected final IInventory assemblyMatrix; + + public SlotTFGoblinUncrafting(EntityPlayer player, IInventory inputSlot, InventoryTFGoblinUncrafting uncraftingMatrix, IInventory assemblyMatrix, int slotNum, int x, int y) { + super(uncraftingMatrix, slotNum, x, y); + this.player = player; + this.inputSlot = inputSlot; + this.uncraftingMatrix = uncraftingMatrix; + this.assemblyMatrix = assemblyMatrix; + } + + /** + * Check if the stack is a valid item for this slot. Always true beside for the armor slots. + */ + @Override + public boolean isItemValid(ItemStack stack) { + // don't put things in this matrix + return false; + } + + /** + * Return whether this slot's stack can be taken from this slot. + */ @Override - public void onPickupFromSlot(EntityPlayer par1EntityPlayer, ItemStack par1ItemStack) { - super.onPickupFromSlot(par1EntityPlayer, par1ItemStack); - - // charge the player for this + public boolean canTakeStack(EntityPlayer player) { + // if there is anything in the assembly matrix, then you cannot have these items + if (!this.assemblyMatrix.isEmpty()) { + return false; + } + + // can't take a marked stack + if (ContainerTFUncrafting.isMarked(this.getStack())) { + return false; + } + + // if uncrafting is disabled, no! + if (TFConfig.disableUncrafting) { + return false; + } + + // if you don't have enough XP, no + if (this.uncraftingMatrix.uncraftingCost > player.experienceLevel && !player.capabilities.isCreativeMode) { + return false; + } + + return true; + } + + /** + * Called when the player picks up an item from an inventory slot + */ + @Override + public ItemStack onTake(EntityPlayer player, ItemStack stack) { + // charge the player for this if (this.uncraftingMatrix.uncraftingCost > 0) { - this.thePlayer.addExperienceLevel(-this.uncraftingMatrix.uncraftingCost); - - //System.out.println("Charging the player " + this.uncraftingMatrix.uncraftingCost + " experience for uncrafting"); + this.player.addExperienceLevel(-this.uncraftingMatrix.uncraftingCost); } - // move all remaining items from the uncrafting grid to the assembly grid - // the assembly grid should be empty for this to even happen, so just plop the items right in - for (int i = 0; i < 9; i++) { - ItemStack transferStack = this.uncraftingMatrix.getStackInSlot(i); - if (transferStack != null && transferStack.stackSize > 0) { - this.assemblyMatrix.setInventorySlotContents(i, transferStack.copy()); - } - } - + // the assembly grid should be empty for this to even happen, so just plop the items right in + for (int i = 0; i < 9; i++) { + ItemStack transferStack = this.uncraftingMatrix.getStackInSlot(i); + if (!transferStack.isEmpty() && !ContainerTFUncrafting.isMarked(transferStack)) { + this.assemblyMatrix.setInventorySlotContents(i, transferStack.copy()); + } + } + // decrement the inputslot by 1 - // do this second so that it doesn't change the contents of the uncrafting grid - ItemStack inputStack = this.inputSlot.getStackInSlot(0); - if (inputStack != null) - { - this.inputSlot.decrStackSize(0, uncraftingMatrix.numberOfInputItems); - } - - + // do this second so that it doesn't change the contents of the uncrafting grid + ItemStack inputStack = this.inputSlot.getStackInSlot(0); + if (!inputStack.isEmpty()) { + this.inputSlot.decrStackSize(0, uncraftingMatrix.numberOfInputItems); + } + return super.onTake(player, stack); + } + + @Override + @SideOnly(Side.CLIENT) + public boolean isEnabled() { + return false; + } + + @Override + public boolean isHere(IInventory inv, int slotIn) { + return false; } - - } diff --git a/src/main/java/twilightforest/inventory/package-info.java b/src/main/java/twilightforest/inventory/package-info.java new file mode 100644 index 0000000000..7cc71d91de --- /dev/null +++ b/src/main/java/twilightforest/inventory/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.inventory; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/item/BehaviorTFMobEggDispense.java b/src/main/java/twilightforest/item/BehaviorTFMobEggDispense.java deleted file mode 100644 index 33d4a1dfd2..0000000000 --- a/src/main/java/twilightforest/item/BehaviorTFMobEggDispense.java +++ /dev/null @@ -1,32 +0,0 @@ -package twilightforest.item; - -import net.minecraft.dispenser.BehaviorDefaultDispenseItem; -import net.minecraft.dispenser.IBlockSource; -import net.minecraft.item.ItemStack; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.EnumFacing; - -public class BehaviorTFMobEggDispense extends BehaviorDefaultDispenseItem -{ - /** Reference to the MinecraftServer object. */ - final MinecraftServer mcServer; - - public BehaviorTFMobEggDispense(MinecraftServer par1) - { - this.mcServer = par1; - } - - /** - * Dispense the specified stack, play the dispense sound and spawn particles. - */ - public ItemStack dispenseStack(IBlockSource par1IBlockSource, ItemStack par2ItemStack) - { - EnumFacing facing = EnumFacing.getFront(par1IBlockSource.getBlockMetadata()); - double x = par1IBlockSource.getX() + (double)facing.getFrontOffsetX(); - double y = (double)((float)par1IBlockSource.getYInt() + 0.2F); - double z = par1IBlockSource.getZ() + (double)facing.getFrontOffsetZ(); - ItemTFSpawnEgg.spawnCreature(par1IBlockSource.getWorld(), par2ItemStack.getItemDamage(), x, y, z); - par2ItemStack.splitStack(1); - return par2ItemStack; - } -} diff --git a/src/main/java/twilightforest/item/CreativeTabTwilightForest.java b/src/main/java/twilightforest/item/CreativeTabTwilightForest.java index 1342446be5..206e0a1720 100644 --- a/src/main/java/twilightforest/item/CreativeTabTwilightForest.java +++ b/src/main/java/twilightforest/item/CreativeTabTwilightForest.java @@ -1,22 +1,17 @@ package twilightforest.item; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import twilightforest.block.TFBlocks; -public class CreativeTabTwilightForest extends CreativeTabs -{ +public class CreativeTabTwilightForest extends CreativeTabs { public CreativeTabTwilightForest(String label) { super(label); } - - /** - * Get the ItemStack that will be rendered to the tab. - */ + @Override - public Item getTabIconItem() - { - return Item.getItemFromBlock(TFBlocks.fireflyJar); - } + public ItemStack createIcon() { + return new ItemStack(TFBlocks.miniature_structure); + } } diff --git a/src/main/java/twilightforest/item/GiantItemIcon.java b/src/main/java/twilightforest/item/GiantItemIcon.java deleted file mode 100644 index fc81cdb39d..0000000000 --- a/src/main/java/twilightforest/item/GiantItemIcon.java +++ /dev/null @@ -1,67 +0,0 @@ -package twilightforest.item; - -import net.minecraft.util.IIcon; - -public class GiantItemIcon implements IIcon { - - private IIcon baseIcon; - private float myX; - private float myY; - - public GiantItemIcon(IIcon blockIcon, float x, float y) { - this.baseIcon = blockIcon; - this.myX = x; - this.myY = y; - } - - @Override - public int getIconWidth() { - return this.baseIcon.getIconWidth() / 2; - } - - @Override - public int getIconHeight() { - return this.baseIcon.getIconHeight() / 2; - } - - @Override - public float getMinU() { - float f = this.baseIcon.getMaxU() - this.baseIcon.getMinU(); - return this.baseIcon.getMinU() + (f * myX); - } - - @Override - public float getMaxU() { - float f = this.baseIcon.getMaxU() - this.baseIcon.getMinU(); - return this.baseIcon.getMinU() + (f * (myX + 0.5F)); - } - - @Override - public float getInterpolatedU(double par1) { - float f = this.getMaxU() - this.getMinU(); - return this.getMinU() + f * (float)par1 / 16.0F; - } - - @Override - public float getMinV() { - float f = this.baseIcon.getMaxV() - this.baseIcon.getMinV(); - return this.baseIcon.getMinV() + (f * myY); - } - - @Override - public float getMaxV() { - float f = this.baseIcon.getMaxV() - this.baseIcon.getMinV(); - return this.baseIcon.getMinV() + (f * (myY + 0.5F)); - } - - @Override - public float getInterpolatedV(double par1) { - float f = this.getMaxV() - this.getMinV(); - return this.getMinV() + f * ((float)par1 / 16.0F); - } - - @Override - public String getIconName() { - return this.baseIcon.getIconName(); - } -} diff --git a/src/main/java/twilightforest/item/ItemBlockNagastone.java b/src/main/java/twilightforest/item/ItemBlockNagastone.java deleted file mode 100644 index ef98b2fbe5..0000000000 --- a/src/main/java/twilightforest/item/ItemBlockNagastone.java +++ /dev/null @@ -1,38 +0,0 @@ -package twilightforest.item; - -import net.minecraft.block.Block; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; -import twilightforest.block.TFBlocks; - -public class ItemBlockNagastone extends ItemBlock { - - public ItemBlockNagastone(Block block) { - super(block); - setHasSubtypes(true); - setMaxDamage(0); - } - - @Override - public IIcon getIconFromDamage(int i) - { - int j = MathHelper.clamp_int(i, 0, 15); - return TFBlocks.nagastone.getIcon(2, j); - - } - - @Override - public String getUnlocalizedName(ItemStack itemstack) - { - int meta = itemstack.getItemDamage(); - return (new StringBuilder()).append(super.getUnlocalizedName()).append(".").append(meta).toString(); - } - - @Override - public int getMetadata(int i) - { - return i; - } -} diff --git a/src/main/java/twilightforest/item/ItemBlockTFAuroraSlab.java b/src/main/java/twilightforest/item/ItemBlockTFAuroraSlab.java deleted file mode 100644 index ee1bc90a26..0000000000 --- a/src/main/java/twilightforest/item/ItemBlockTFAuroraSlab.java +++ /dev/null @@ -1,12 +0,0 @@ -package twilightforest.item; - -import net.minecraft.block.Block; -import twilightforest.block.BlockTFAuroraSlab; - -public class ItemBlockTFAuroraSlab extends net.minecraft.item.ItemSlab { - - public ItemBlockTFAuroraSlab(Block block, BlockTFAuroraSlab singleSlab, BlockTFAuroraSlab doubleSlab, Boolean isDouble) { - super(block, singleSlab, doubleSlab, isDouble); - } - -} diff --git a/src/main/java/twilightforest/item/ItemBlockTFDeadrock.java b/src/main/java/twilightforest/item/ItemBlockTFDeadrock.java deleted file mode 100644 index 0e3390048f..0000000000 --- a/src/main/java/twilightforest/item/ItemBlockTFDeadrock.java +++ /dev/null @@ -1,13 +0,0 @@ -package twilightforest.item; - -import net.minecraft.block.Block; -import net.minecraft.item.ItemMultiTexture; -import twilightforest.block.BlockTFDeadrock; - -public class ItemBlockTFDeadrock extends ItemMultiTexture { - - public ItemBlockTFDeadrock(Block p_i45346_1_, BlockTFDeadrock p_i45346_2_, String[] p_i45346_3_) { - super(p_i45346_1_, p_i45346_2_, p_i45346_3_); - } - -} diff --git a/src/main/java/twilightforest/item/ItemBlockTFHugeLilyPad.java b/src/main/java/twilightforest/item/ItemBlockTFHugeLilyPad.java index 80ec19f5ee..28aff1d1fc 100644 --- a/src/main/java/twilightforest/item/ItemBlockTFHugeLilyPad.java +++ b/src/main/java/twilightforest/item/ItemBlockTFHugeLilyPad.java @@ -1,84 +1,99 @@ package twilightforest.item; -import java.util.Random; - -import twilightforest.block.TFBlocks; +import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemLilyPad; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemColored; import net.minecraft.item.ItemStack; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.stats.StatList; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import twilightforest.block.TFBlocks; +import static twilightforest.block.BlockTFHugeLilyPad.FACING; +import static twilightforest.block.BlockTFHugeLilyPad.PIECE; +import static twilightforest.enums.HugeLilypadPiece.NE; +import static twilightforest.enums.HugeLilypadPiece.NW; +import static twilightforest.enums.HugeLilypadPiece.SE; +import static twilightforest.enums.HugeLilypadPiece.SW; -public class ItemBlockTFHugeLilyPad extends ItemLilyPad { - - Random rand = new Random(); + +public class ItemBlockTFHugeLilyPad extends ItemColored { public ItemBlockTFHugeLilyPad(Block block) { - super(block); + super(block, false); } - - /** - * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer - */ - public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) { - MovingObjectPosition movingobjectposition = this.getMovingObjectPositionFromPlayer(world, player, true); + // [VanillaCopy] ItemLilyPad.onItemRightClick, with special logic + @Override + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand hand) { + ItemStack itemstack = playerIn.getHeldItem(hand); + RayTraceResult raytraceresult = this.rayTrace(worldIn, playerIn, true); + + if (raytraceresult == null) { + return new ActionResult<>(EnumActionResult.PASS, itemstack); + } else { + if (raytraceresult.typeOfHit == RayTraceResult.Type.BLOCK) { + BlockPos blockpos = raytraceresult.getBlockPos(); + BlockPos blockpos1 = blockpos.up(); - if (movingobjectposition == null) { - return itemStack; - } else { - if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) - { - int x = movingobjectposition.blockX; - int y = movingobjectposition.blockY; - int z = movingobjectposition.blockZ; - - // 2x2 lily pads go in a larger grid - int bx = (x >> 1) << 1; - int by = y; - int bz = (z >> 1) << 1; - - if (this.canPlacePadOn(itemStack, world, player, bx, by, bz) && this.canPlacePadOn(itemStack, world, player, bx + 1, by, bz) - && this.canPlacePadOn(itemStack, world, player, bx, by, bz + 1) && this.canPlacePadOn(itemStack, world, player, bx + 1, by, bz + 1)) { - - // this seems like a difficult way to generate 2 pseudorandom bits - rand.setSeed(8890919293L); - rand.setSeed((bx * rand.nextLong()) ^ (bz * rand.nextLong()) ^ 8890919293L); - int orient = rand.nextInt(4) << 2; - - world.setBlock(bx, by + 1, bz, TFBlocks.hugeLilyPad, 0 | orient, 2); - world.setBlock(bx + 1, by + 1, bz, TFBlocks.hugeLilyPad, 1 | orient, 2); - world.setBlock(bx + 1, by + 1, bz + 1, TFBlocks.hugeLilyPad, 2 | orient, 2); - world.setBlock(bx, by + 1, bz + 1, TFBlocks.hugeLilyPad, 3 | orient, 2); - - if (!player.capabilities.isCreativeMode) - { - --itemStack.stackSize; - } + // TF - check the other 3 spots we touch as well + if (!worldIn.isBlockModifiable(playerIn, blockpos) || !playerIn.canPlayerEdit(blockpos.offset(raytraceresult.sideHit), raytraceresult.sideHit, itemstack) + || !worldIn.isBlockModifiable(playerIn, blockpos.east()) || !playerIn.canPlayerEdit(blockpos.offset(raytraceresult.sideHit).east(), raytraceresult.sideHit, itemstack) + || !worldIn.isBlockModifiable(playerIn, blockpos.south()) || !playerIn.canPlayerEdit(blockpos.offset(raytraceresult.sideHit).south(), raytraceresult.sideHit, itemstack) + || !worldIn.isBlockModifiable(playerIn, blockpos.east().south()) || !playerIn.canPlayerEdit(blockpos.offset(raytraceresult.sideHit).east().south(), raytraceresult.sideHit, itemstack)) { + return new ActionResult<>(EnumActionResult.FAIL, itemstack); + } - } - } - return itemStack; - } - } - - public boolean canPlacePadOn(ItemStack itemStack, World world, EntityPlayer player, int x, int y, int z) { - if (!world.canMineBlock(player, x, y, z)) { - return false; - } - - if (!player.canPlayerEdit(x, y, z, 1, itemStack)) { - return false; - } - - return world.getBlock(x, y, z).getMaterial() == Material.water && world.getBlockMetadata(x, y, z) == 0 && world.isAirBlock(x, y + 1, z); - - } + // TF check 4 blocks here + IBlockState iblockstate = worldIn.getBlockState(blockpos); + IBlockState iblockstatee = worldIn.getBlockState(blockpos.east()); + IBlockState iblockstatese = worldIn.getBlockState(blockpos.east().south()); + IBlockState iblockstates = worldIn.getBlockState(blockpos.south()); + if (iblockstate.getMaterial() == Material.WATER && iblockstate.getValue(BlockLiquid.LEVEL) == 0 + && iblockstatee.getMaterial() == Material.WATER && iblockstatee.getValue(BlockLiquid.LEVEL) == 0 + && iblockstatee.getMaterial() == Material.WATER && iblockstatee.getValue(BlockLiquid.LEVEL) == 0 + && iblockstatese.getMaterial() == Material.WATER && iblockstatee.getValue(BlockLiquid.LEVEL) == 0 + && iblockstates.getMaterial() == Material.WATER && iblockstatee.getValue(BlockLiquid.LEVEL) == 0 + && worldIn.isAirBlock(blockpos1) && worldIn.isAirBlock(blockpos1.east()) && worldIn.isAirBlock(blockpos1.east().south()) && worldIn.isAirBlock(blockpos1.south())) { + // TF - set 4 of them + EnumFacing direction = playerIn.getHorizontalFacing(); + final IBlockState lilypad = TFBlocks.huge_lilypad.getDefaultState().withProperty(FACING, direction); + worldIn.setBlockState(blockpos1, lilypad.withProperty(PIECE, NW), 10); + worldIn.setBlockState(blockpos1.east(), lilypad.withProperty(PIECE, NE), 10); + worldIn.setBlockState(blockpos1.east().south(), lilypad.withProperty(PIECE, SE), 10); + worldIn.setBlockState(blockpos1.south(), lilypad.withProperty(PIECE, SW), 11); + + if (playerIn instanceof EntityPlayerMP) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)playerIn, blockpos1, itemstack); + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)playerIn, blockpos1.east(), itemstack); + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)playerIn, blockpos1.east().south(), itemstack); + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)playerIn, blockpos1.south(), itemstack); + } + + if (!playerIn.capabilities.isCreativeMode) { + itemstack.shrink(1); + } + + playerIn.addStat(StatList.getObjectUseStats(this)); + worldIn.playSound(playerIn, blockpos, TFBlocks.huge_lilypad.getSoundType(iblockstate, worldIn, blockpos, playerIn).getPlaceSound(), SoundCategory.BLOCKS, 1.0F, 1.0F); + return new ActionResult<>(EnumActionResult.SUCCESS, itemstack); + } + } + + return new ActionResult<>(EnumActionResult.FAIL, itemstack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemBlockTFHugeWaterLily.java b/src/main/java/twilightforest/item/ItemBlockTFHugeWaterLily.java index ec005d7fe0..24c3e7fe40 100644 --- a/src/main/java/twilightforest/item/ItemBlockTFHugeWaterLily.java +++ b/src/main/java/twilightforest/item/ItemBlockTFHugeWaterLily.java @@ -1,14 +1,24 @@ package twilightforest.item; -import twilightforest.block.TFBlocks; +import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; -import net.minecraft.util.MovingObjectPosition; +import net.minecraft.stats.StatList; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; +import twilightforest.block.TFBlocks; public class ItemBlockTFHugeWaterLily extends ItemBlock { @@ -16,57 +26,52 @@ public ItemBlockTFHugeWaterLily(Block block) { super(block); } - /** - * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer - * - * Copied from ItemWaterlily - */ - public ItemStack onItemRightClick(ItemStack p_77659_1_, World p_77659_2_, EntityPlayer p_77659_3_) - { - MovingObjectPosition movingobjectposition = this.getMovingObjectPositionFromPlayer(p_77659_2_, p_77659_3_, true); + // [VanillaCopy] ItemLilyPad.onItemRightClick, edits noted + @Override + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand hand) { + ItemStack itemstack = playerIn.getHeldItem(hand); + RayTraceResult raytraceresult = this.rayTrace(worldIn, playerIn, true); + + if (raytraceresult == null) { + return new ActionResult<>(EnumActionResult.PASS, itemstack); + } else { + if (raytraceresult.typeOfHit == RayTraceResult.Type.BLOCK) { + BlockPos blockpos = raytraceresult.getBlockPos(); - if (movingobjectposition == null) - { - return p_77659_1_; - } - else - { - if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) - { - int i = movingobjectposition.blockX; - int j = movingobjectposition.blockY; - int k = movingobjectposition.blockZ; + if (!worldIn.isBlockModifiable(playerIn, blockpos) || !playerIn.canPlayerEdit(blockpos.offset(raytraceresult.sideHit), raytraceresult.sideHit, itemstack)) { + return new ActionResult<>(EnumActionResult.FAIL, itemstack); + } - if (!p_77659_2_.canMineBlock(p_77659_3_, i, j, k)) - { - return p_77659_1_; - } + BlockPos blockpos1 = blockpos.up(); + IBlockState iblockstate = worldIn.getBlockState(blockpos); - if (!p_77659_3_.canPlayerEdit(i, j, k, movingobjectposition.sideHit, p_77659_1_)) - { - return p_77659_1_; - } + if (iblockstate.getMaterial() == Material.WATER && iblockstate.getValue(BlockLiquid.LEVEL) == 0 && worldIn.isAirBlock(blockpos1)) { + // special case for handling block placement with water lilies + net.minecraftforge.common.util.BlockSnapshot blocksnapshot = net.minecraftforge.common.util.BlockSnapshot.getBlockSnapshot(worldIn, blockpos1); + worldIn.setBlockState(blockpos1, TFBlocks.huge_waterlily.getDefaultState()); // TF - our block + if (net.minecraftforge.event.ForgeEventFactory.onPlayerBlockPlace(playerIn, blocksnapshot, net.minecraft.util.EnumFacing.UP, hand).isCanceled()) { + blocksnapshot.restore(true, false); + return new ActionResult(EnumActionResult.FAIL, itemstack); + } - if (p_77659_2_.getBlock(i, j, k).getMaterial() == Material.water && p_77659_2_.getBlockMetadata(i, j, k) == 0 && p_77659_2_.isAirBlock(i, j + 1, k)) - { - // special case for handling block placement with water lilies - net.minecraftforge.common.util.BlockSnapshot blocksnapshot = net.minecraftforge.common.util.BlockSnapshot.getBlockSnapshot(p_77659_2_, i, j + 1, k); - p_77659_2_.setBlock(i, j + 1, k, TFBlocks.hugeWaterLily); - if (net.minecraftforge.event.ForgeEventFactory.onPlayerBlockPlace(p_77659_3_, blocksnapshot, net.minecraftforge.common.util.ForgeDirection.UP).isCanceled()) - { - blocksnapshot.restore(true, false); - return p_77659_1_; - } + // TF - our block + worldIn.setBlockState(blockpos1, TFBlocks.huge_waterlily.getDefaultState(), 11); - if (!p_77659_3_.capabilities.isCreativeMode) - { - --p_77659_1_.stackSize; - } - } - } + if (playerIn instanceof EntityPlayerMP) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)playerIn, blockpos1, itemstack); + } - return p_77659_1_; - } - } + if (!playerIn.capabilities.isCreativeMode) { + itemstack.shrink(1); + } + playerIn.addStat(StatList.getObjectUseStats(this)); + worldIn.playSound(playerIn, blockpos, SoundEvents.BLOCK_WATERLILY_PLACE, SoundCategory.BLOCKS, 1.0F, 1.0F); + return new ActionResult<>(EnumActionResult.SUCCESS, itemstack); + } + } + + return new ActionResult<>(EnumActionResult.FAIL, itemstack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemBlockTFLeaves.java b/src/main/java/twilightforest/item/ItemBlockTFLeaves.java index 32531c4a24..035704aa25 100644 --- a/src/main/java/twilightforest/item/ItemBlockTFLeaves.java +++ b/src/main/java/twilightforest/item/ItemBlockTFLeaves.java @@ -1,38 +1,15 @@ package twilightforest.item; import net.minecraft.block.Block; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import twilightforest.block.TFBlocks; -public class ItemBlockTFLeaves extends ItemBlock { - - public ItemBlockTFLeaves(Block par1) { - super(par1); - setHasSubtypes(true); - setMaxDamage(0); +public class ItemBlockTFLeaves extends ItemBlockTFMeta { + public ItemBlockTFLeaves(Block block) { + super(block); } - - /** - * Gets an icon index based on an item's damage value - */ - @Override - public IIcon getIconFromDamage(int par1) - { - return TFBlocks.leaves.getIcon(2, par1); - } - - @Override - public String getUnlocalizedName(ItemStack itemstack) - { - int meta = itemstack.getItemDamage(); - return (new StringBuilder()).append(super.getUnlocalizedName()).append(".").append(meta).toString(); - } - @Override - public int getMetadata(int i) - { - return i; - } + @Override + public int getMetadata(int stackMeta) { + // set meta 4 on placed leaves, which sets the DECAYABLE property to false + return stackMeta | 4; + } } diff --git a/src/main/java/twilightforest/item/ItemBlockTFLog.java b/src/main/java/twilightforest/item/ItemBlockTFLog.java deleted file mode 100644 index 76110a4472..0000000000 --- a/src/main/java/twilightforest/item/ItemBlockTFLog.java +++ /dev/null @@ -1,67 +0,0 @@ -package twilightforest.item; - -import net.minecraft.block.Block; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; -import twilightforest.block.TFBlocks; - - - -public class ItemBlockTFLog extends ItemBlock { - - public static final String woodNames[] = { - "oak", "canopy", "mangrove", "darkwood", "x", "root", "oreroot", "rotten" - }; - - public ItemBlockTFLog(Block log) - { - super(log); - setHasSubtypes(true); - setMaxDamage(0); - } - - /** - * Gets an icon index based on an item's damage value - */ - @Override - public IIcon getIconFromDamage(int par1) - { - return TFBlocks.log.getIcon(2, par1); - } - - @Override - public String getUnlocalizedName(ItemStack itemstack) - { - int meta = itemstack.getItemDamage(); - if ((meta & 8) == 0) { - // wood - int i = MathHelper.clamp_int(meta, 0, 7); - return (new StringBuilder()).append(super.getUnlocalizedName()).append(".").append(woodNames[i]).toString(); - } - else { - // log - meta &= 7; - int i = MathHelper.clamp_int(meta, 0, 7); - return (new StringBuilder()).append(super.getUnlocalizedName()).append(".").append(woodNames[i]).append(".log").toString(); - } - } - - @Override - public int getMetadata(int i) - { - return i; - } - - -// /** -// * Display meta in tooltip -// */ -// @Override -// public void addInformation(ItemStack par1ItemStack, List par2List) { -// par2List.add("Meta = " + par1ItemStack.getItemDamage()); -// } - - -} diff --git a/src/main/java/twilightforest/item/ItemBlockTFMeta.java b/src/main/java/twilightforest/item/ItemBlockTFMeta.java index 2d25a68d51..72eec5e796 100644 --- a/src/main/java/twilightforest/item/ItemBlockTFMeta.java +++ b/src/main/java/twilightforest/item/ItemBlockTFMeta.java @@ -1,74 +1,56 @@ package twilightforest.item; -import java.util.List; - import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; -public class ItemBlockTFMeta extends ItemBlock { +import javax.annotation.Nullable; +import java.util.List; - private final Block myBlock; +public class ItemBlockTFMeta extends ItemBlock { + private boolean appendNumber = true; public ItemBlockTFMeta(Block block) { super(block); - setHasSubtypes(true); - setMaxDamage(0); - - this.myBlock = block; + setHasSubtypes(true); } - @Override - public int getMetadata(int i) - { - return i; - } - + public ItemBlockTFMeta setAppend(boolean doAppend) { + this.appendNumber = doAppend; + return this; + } - @Override - public String getUnlocalizedName(ItemStack itemstack) - { - int meta = itemstack.getItemDamage(); - return (new StringBuilder()).append(super.getUnlocalizedName()).append(".").append(meta).toString(); - } + @Override + public int getMetadata(int i) { + return i; + } - /** - * Gets an icon index based on an item's damage value - */ - @Override - public IIcon getIconFromDamage(int par1) - { - return this.myBlock.getIcon(2, par1); - } + @Override + public String getTranslationKey(ItemStack itemstack) { + if (appendNumber) { + return super.getTranslationKey() + "." + itemstack.getMetadata(); + } else return super.getTranslationKey(); + } - /** - * allows items to add custom lines of information to the mouseover description - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) - { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + // add warning for [WIP] tag - if (par1ItemStack.getDisplayName().contains("[WIP]")) - { - par3List.add("This block is a work in progress"); - par3List.add("and may have bugs or unintended"); - par3List.add("effects that may damage your world."); - par3List.add("Use with caution."); - } + if (stack.getDisplayName().contains("[WIP]")) { + tooltip.add(I18n.format("twilightforest.misc.wip0")); + tooltip.add(I18n.format("twilightforest.misc.wip1")); + } // add warning for [NYI] tag - if (par1ItemStack.getDisplayName().contains("[NYI]")) - { - par3List.add("This block has effects"); - par3List.add("that are not yet implemented."); + if (stack.getDisplayName().contains("[NYI]")) { + tooltip.add(I18n.format("twilightforest.misc.nyi")); } } } diff --git a/src/main/java/twilightforest/item/ItemBlockTFPlant.java b/src/main/java/twilightforest/item/ItemBlockTFPlant.java index b4e7418989..3caa90d1fd 100644 --- a/src/main/java/twilightforest/item/ItemBlockTFPlant.java +++ b/src/main/java/twilightforest/item/ItemBlockTFPlant.java @@ -3,138 +3,35 @@ import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; -import net.minecraft.util.Facing; -import net.minecraft.util.IIcon; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import twilightforest.block.BlockTFPlant; -import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.enums.PlantVariant; -public class ItemBlockTFPlant extends ItemBlock { +public class ItemBlockTFPlant extends ItemBlockTFMeta { public ItemBlockTFPlant(Block block) { super(block); - setHasSubtypes(true); - setMaxDamage(0); } - /** - * Gets an icon index based on an item's damage value - */ - @Override - public IIcon getIconFromDamage(int par1) - { - return TFBlocks.plant.getIcon(2, par1); - } - - @SideOnly(Side.CLIENT) - @Override - public int getColorFromItemStack(ItemStack par1ItemStack, int par2) - { - return TFBlocks.plant.getRenderColor(par1ItemStack.getItemDamage()); - } - - @Override - public String getUnlocalizedName(ItemStack itemstack) { - int meta = itemstack.getItemDamage(); - return (new StringBuilder()).append(super.getUnlocalizedName()).append(".").append(meta).toString(); - } - - /** - * Returns the metadata of the block which this Item (ItemBlock) can place - */ - @Override - public int getMetadata(int i) { - return i; - } - - @SideOnly(Side.CLIENT) - - /** - * Returns true if the given ItemBlock can be placed on the given side of the given block position. - */ - @Override - public boolean func_150936_a(World par1World, int x, int y, int z, int direction, EntityPlayer par6EntityPlayer, ItemStack par7ItemStack) - { - int meta = par7ItemStack.getItemDamage(); - - if ((meta == BlockTFPlant.META_ROOT_STRAND || meta == BlockTFPlant.META_TORCHBERRY) - && direction == 0 && BlockTFPlant.canPlaceRootBelow(par1World, x, y, z)) - { - return true; - } - else - { - return super.func_150936_a(par1World, x, y, z, direction, par6EntityPlayer, par7ItemStack); - } - } - - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS ! - */ - @Override - public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int direction, float par8, float par9, float par10) - { - int meta = itemStack.getItemDamage(); - - if (meta == BlockTFPlant.META_ROOT_STRAND || meta == BlockTFPlant.META_TORCHBERRY) { - // hanging - return onItemUseRoot(itemStack, player, world, x, y, z, direction); - } - else { - // regular flower type behavior - return super.onItemUse(itemStack, player, world, x, y, z, direction, par8, par9, par10); - } - } - - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS ! - */ - public boolean onItemUseRoot(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int direction) - { - Block blockThereId = world.getBlock(x, y, z); - - if (blockThereId == Blocks.snow) { - direction = 1; - } - else if (!blockThereId.getMaterial().isReplaceable()) { - //int var11 = par3World.getBlockId(par4, par5, par6); - x += Facing.offsetsXForSide[direction]; - y += Facing.offsetsYForSide[direction]; - z += Facing.offsetsZForSide[direction]; - } - - if (!player.canPlayerEdit(x, y, z, direction, itemStack)) { - return false; - } - else if (itemStack.stackSize == 0) - { - return false; - } - else - { - if (BlockTFPlant.canPlaceRootBelow(world, x, y + 1, z)) { - Block plantBlock = TFBlocks.plant; - - if (world.setBlock(x, y, z, plantBlock, itemStack.getItem().getMetadata(itemStack.getItemDamage()), 3)) { - if (world.getBlock(x, y, z) == plantBlock) - { -// plantBlock.onBlockPlaced(world, x, y, z, direction); - plantBlock.onBlockPlacedBy(world, x, y, z, player, itemStack); - } - - world.playSoundEffect((double)(x + 0.5F), (double)(y + 0.5F), (double)(z + 0.5F), plantBlock.stepSound.getBreakSound(), (plantBlock.stepSound.getVolume() + 1.0F) / 2.0F, plantBlock.stepSound.getPitch() * 0.8F); - --itemStack.stackSize; - } - } - - return true; - } - } - + @Override + public boolean canPlaceBlockOnSide(World world, BlockPos pos, EnumFacing side, EntityPlayer player, ItemStack stack) { + int meta = stack.getItemDamage(); + if (meta == PlantVariant.ROOT_STRAND.ordinal() || meta == PlantVariant.TORCHBERRY.ordinal()) { + // [VanillaCopy] super's side offsetting logic + Block block = world.getBlockState(pos).getBlock(); + + if (block == Blocks.SNOW_LAYER && block.isReplaceable(world, pos)) { + side = EnumFacing.UP; + } else if (!block.isReplaceable(world, pos)) { + pos = pos.offset(side); + } + + return BlockTFPlant.canPlaceRootAt(world, pos); + } else { + return super.canPlaceBlockOnSide(world, pos, side, player, stack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemBlockTFThorns.java b/src/main/java/twilightforest/item/ItemBlockTFThorns.java deleted file mode 100644 index fdaf5c602c..0000000000 --- a/src/main/java/twilightforest/item/ItemBlockTFThorns.java +++ /dev/null @@ -1,13 +0,0 @@ -package twilightforest.item; - -import net.minecraft.block.Block; -import net.minecraft.item.ItemMultiTexture; -import twilightforest.block.BlockTFThorns; - -public class ItemBlockTFThorns extends ItemMultiTexture { - - public ItemBlockTFThorns(Block p_i45346_1_, BlockTFThorns p_i45346_2_, String[] p_i45346_3_) { - super(p_i45346_1_, p_i45346_2_, p_i45346_3_); - } - -} diff --git a/src/main/java/twilightforest/item/ItemBlockWearable.java b/src/main/java/twilightforest/item/ItemBlockWearable.java new file mode 100644 index 0000000000..7237daf00a --- /dev/null +++ b/src/main/java/twilightforest/item/ItemBlockWearable.java @@ -0,0 +1,26 @@ +package twilightforest.item; + +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +import javax.annotation.Nullable; + +public class ItemBlockWearable extends ItemBlock { + public ItemBlockWearable(Block block) { + super(block); + } + + @Override + public boolean isValidArmor(ItemStack stack, EntityEquipmentSlot armorType, Entity entity) { + return armorType == EntityEquipmentSlot.HEAD; + } + + @Override + @Nullable + public EntityEquipmentSlot getEquipmentSlot(ItemStack stack) { + return EntityEquipmentSlot.HEAD; + } +} diff --git a/src/main/java/twilightforest/item/ItemCharmBaubleable.java b/src/main/java/twilightforest/item/ItemCharmBaubleable.java new file mode 100644 index 0000000000..8a9802eb3b --- /dev/null +++ b/src/main/java/twilightforest/item/ItemCharmBaubleable.java @@ -0,0 +1,22 @@ +package twilightforest.item; + +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import twilightforest.compat.Baubles; +import twilightforest.compat.TFCompat; + +import javax.annotation.Nullable; + +public class ItemCharmBaubleable extends ItemTF { + ItemCharmBaubleable(EnumRarity rarity) { + super(rarity); + } + + @Nullable + @Override + public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable NBTTagCompound nbt) { + return TFCompat.BAUBLES.isActivated() ? new Baubles.BasicBaubleProvider() : null; + } +} diff --git a/src/main/java/twilightforest/item/ItemKnightlyShield.java b/src/main/java/twilightforest/item/ItemKnightlyShield.java new file mode 100644 index 0000000000..800431ab74 --- /dev/null +++ b/src/main/java/twilightforest/item/ItemKnightlyShield.java @@ -0,0 +1,43 @@ +package twilightforest.item; + +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemShield; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.translation.I18n; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; + +import javax.annotation.Nullable; +import java.util.List; + +public class ItemKnightlyShield extends ItemShield implements ModelRegisterCallback { + + public ItemKnightlyShield() { + this.setMaxDamage(1024); + this.setCreativeTab(TFItems.creativeTab); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return I18n.translateToLocal(this.getTranslationKey(stack) + ".name").trim(); + } + + @SideOnly(Side.CLIENT) + @Override + public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) {} + + @Override + public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) { + return repair.getItem() == TFItems.knightmetal_ingot || repair.getItem() != Item.getItemFromBlock(Blocks.PLANKS) && super.getIsRepairable(toRepair, repair); + } + + @Override + public boolean isShield(ItemStack stack, @Nullable EntityLivingBase entity) { + return true; + } +} diff --git a/src/main/java/twilightforest/item/ItemTF.java b/src/main/java/twilightforest/item/ItemTF.java index cb1b2b00f4..1c8caea10c 100644 --- a/src/main/java/twilightforest/item/ItemTF.java +++ b/src/main/java/twilightforest/item/ItemTF.java @@ -1,49 +1,28 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTF extends Item { - - private boolean isRare = false; +import javax.annotation.Nonnull; + +public class ItemTF extends Item implements ModelRegisterCallback { + private final EnumRarity RARITY; protected ItemTF() { - super(); this.setCreativeTab(TFItems.creativeTab); + this.RARITY = EnumRarity.COMMON; } - - /** - * Return an item rarity from EnumRarity - * - * This is automatically uncommon - */ - @Override - @SideOnly(Side.CLIENT) - public EnumRarity getRarity(ItemStack par1ItemStack) { - return isRare ? EnumRarity.rare : EnumRarity.uncommon; + + protected ItemTF(EnumRarity rarity) { + this.setCreativeTab(TFItems.creativeTab); + this.RARITY = rarity; } - /** - * Set rarity during creation - */ - public ItemTF makeRare() - { - this.isRare = true; - return this; + @Nonnull + @Override + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE.compareTo(RARITY) > 0 ? EnumRarity.RARE : RARITY : RARITY; } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFArcticArmor.java b/src/main/java/twilightforest/item/ItemTFArcticArmor.java index 118534ff31..7041f4e8ca 100644 --- a/src/main/java/twilightforest/item/ItemTFArcticArmor.java +++ b/src/main/java/twilightforest/item/ItemTFArcticArmor.java @@ -1,104 +1,169 @@ package twilightforest.item; -import java.util.List; - +import net.minecraft.block.BlockCauldron; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.stats.StatList; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFArcticArmor extends ItemArmor { +import javax.annotation.Nullable; +import java.util.List; - public ItemTFArcticArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int renderIndex, int armorType) { - super(par2EnumArmorMaterial, renderIndex, armorType); +public class ItemTFArcticArmor extends ItemTFArmor implements ModelRegisterCallback { + public ItemTFArcticArmor(ItemArmor.ArmorMaterial armorMaterial, EntityEquipmentSlot armorType, EnumRarity rarity) { + super(armorMaterial, armorType, rarity); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return an item rarity from EnumRarity - */ @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.uncommon; + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + if (slot == EntityEquipmentSlot.LEGS) { + return TwilightForestMod.ARMOR_DIR + "arcticarmor_2" + (layer == null ? "_dyed" : "_overlay") + ".png"; + } else { + return TwilightForestMod.ARMOR_DIR + "arcticarmor_1" + (layer == null ? "_dyed" : "_overlay") + ".png"; + } + } + + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + //istack.addEnchantment(TFEnchantment.reactFire, 2); + list.add(istack); + } + } + + @SideOnly(Side.CLIENT) + @Override + public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, ModelBiped oldM) { + return TwilightForestMod.proxy.getArcticArmorModel(armorSlot); + } + + @Override + public boolean hasOverlay(ItemStack stack) { + return getColor(stack) != 0xFFFFFF; + } + + @Override + public boolean hasColor(ItemStack stack) { + NBTTagCompound nbttagcompound = stack.getTagCompound(); + return (nbttagcompound != null && nbttagcompound.hasKey("display", 10)) && nbttagcompound.getCompoundTag("display").hasKey("color", 3); + } + + @Override + public int getColor(ItemStack stack) { + return this.getColor(stack, 1); + } + + @Override + public void removeColor(ItemStack stack) { + this.removeColor(stack, 1); + } + + @Override + public void setColor(ItemStack stack, int color) { + this.setColor(stack, color, 1); + } + + public int getColor(ItemStack stack, int type) { + String string = "";//type == 0 ? "" : ("" + type); + NBTTagCompound stackTagCompound = stack.getTagCompound(); + + int color = 0xBDCFD9; + + if (stackTagCompound != null) { + NBTTagCompound displayCompound = stackTagCompound.getCompoundTag("display"); + + if (displayCompound.hasKey("color" + string, 3)) + color = displayCompound.getInteger("color" + string); + } + + switch (type) { + //case 0: + //return stack.getItem() != TFItems.arctic_helmet ? 0x793828 : 0xFFFFFF; + case 0: + return 0xFFFFFF; + default: + return color; + } } - - /** - * Called by RenderBiped and RenderPlayer to determine the armor texture that - * should be use for the currently equiped item. - * This will only be called on instances of ItemArmor. - * - * Returning null from this function will use the default value. - * - * @param stack ItemStack for the equpt armor - * @param entity The entity wearing the armor - * @param slot The slot the armor is in - * @param layer The render layer, either 1 or 2, 2 is only used for CLOTH armor by default - * @return Path of texture to bind, or null to use default - */ - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) { - switch (slot) { - case 0 : - case 1 : - case 3 : - default : - return TwilightForestMod.ARMOR_DIR + "arcticarmor_1.png"; - case 2 : - return TwilightForestMod.ARMOR_DIR + "arcticarmor_2.png"; + public void removeColor(ItemStack stack, int type) { + String string = "";//type == 0 ? "" : ("" + type); + NBTTagCompound stackTagCompound = stack.getTagCompound(); + + if (stackTagCompound != null) { + NBTTagCompound displayCompound = stackTagCompound.getCompoundTag("display"); + + if (displayCompound.hasKey("color" + string)) + displayCompound.removeTag("color" + string); + + if (displayCompound.hasKey("hasColor")) + displayCompound.setBoolean("hasColor", false); } } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + + public void setColor(ItemStack stack, int color, int type) { + String string = "";//type == 0 ? "" : ("" + type); + NBTTagCompound stackTagCompound = stack.getTagCompound(); + + if (stackTagCompound == null) { + stackTagCompound = new NBTTagCompound(); + stack.setTagCompound(stackTagCompound); + } + + NBTTagCompound displayCompound = stackTagCompound.getCompoundTag("display"); + + if (!stackTagCompound.hasKey("display", 10)) + stackTagCompound.setTag("display", displayCompound); + + displayCompound.setInteger("color" + string, color); + displayCompound.setBoolean("hasColor", true); + } + @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) { - ItemStack istack = new ItemStack(par1, 1, 0); - //istack.addEnchantment(TFEnchantment.reactFire, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ????? - return par2ItemStack.getItem() == TFItems.arcticFur ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * Override this method to have an item handle its own armor rendering. - * - * @param entityLiving The entity wearing the armor - * @param itemStack The itemStack to render the model of - * @param armorSlot 0=head, 1=torso, 2=legs, 3=feet - * - * @return A ModelBiped to render instead of the default - */ - @SideOnly(Side.CLIENT) - public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) - { - return TwilightForestMod.proxy.getArcticArmorModel(armorSlot); - } -} + public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + + if (this.hasColor(stack)) { + IBlockState blockAt = world.getBlockState(pos); + + if (blockAt.getBlock() instanceof BlockCauldron && blockAt.getValue(BlockCauldron.LEVEL) > 0) { + removeColor(stack); + player.addStat(StatList.ARMOR_CLEANED); + + ((BlockCauldron) blockAt.getBlock()).setWaterLevel(world, pos, blockAt, blockAt.getValue(BlockCauldron.LEVEL) - 1); + return EnumActionResult.SUCCESS; + } + } + + return EnumActionResult.PASS; + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) { + super.addInformation(stack, worldIn, tooltip, flagIn); + tooltip.add(I18n.format("item.twilightforest.arctic_armor.tooltip")); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/item/ItemTFArmor.java b/src/main/java/twilightforest/item/ItemTFArmor.java new file mode 100644 index 0000000000..0aec8cc91a --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFArmor.java @@ -0,0 +1,31 @@ +package twilightforest.item; + +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import twilightforest.client.ModelRegisterCallback; + +import javax.annotation.Nonnull; + +public abstract class ItemTFArmor extends ItemArmor implements ModelRegisterCallback { + private final EnumRarity RARITY; + + //protected ItemTFArmor(ArmorMaterial materialIn, EntityEquipmentSlot equipmentSlotIn) { + // super(materialIn, 0, equipmentSlotIn); + // this.setCreativeTab(TFItems.creativeTab); + // this.RARITY = EnumRarity.COMMON; + //} + + protected ItemTFArmor(ArmorMaterial materialIn, EntityEquipmentSlot equipmentSlotIn, EnumRarity rarity) { + super(materialIn, 0, equipmentSlotIn); + this.setCreativeTab(TFItems.creativeTab); + this.RARITY = rarity; + } + + @Nonnull + @Override + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE.compareTo(RARITY) > 0 ? EnumRarity.RARE : RARITY : RARITY; + } +} diff --git a/src/main/java/twilightforest/item/ItemTFBowBase.java b/src/main/java/twilightforest/item/ItemTFBowBase.java index ba922428ee..55141b8f21 100644 --- a/src/main/java/twilightforest/item/ItemTFBowBase.java +++ b/src/main/java/twilightforest/item/ItemTFBowBase.java @@ -1,154 +1,16 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.init.Items; +import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.ArrowLooseEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public abstract class ItemTFBowBase extends ItemBow { +public abstract class ItemTFBowBase extends ItemBow implements ModelRegisterCallback { - private IIcon[] iconArray; + private static final EnumRarity RARITY = EnumRarity.UNCOMMON; - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) { - this.itemIcon = par1IconRegister.registerIcon(this.getIconString() + "_standby"); - this.iconArray = new IIcon[bowPullIconNameArray.length]; - - for (int i = 0; i < this.iconArray.length; ++i) - { - this.iconArray[i] = par1IconRegister.registerIcon(this.getIconString() + "_" + bowPullIconNameArray[i]); - } - } - - /** - * used to cycle through icons based on their used duration, i.e. for the bow - */ - @SideOnly(Side.CLIENT) - public IIcon getItemIconForUseDuration(int par1) { - return this.iconArray[par1]; + @Override + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE.compareTo(RARITY) > 0 ? EnumRarity.RARE : RARITY : RARITY; } - - /** - * Player, Render pass, and item usage sensitive version of getIconIndex. - * - * @param stack The item stack to get the icon for. (Usually this, and usingItem will be the same if usingItem is not null) - * @param renderPass The pass to get the icon for, 0 is default. - * @param player The player holding the item - * @param usingItem The item the player is actively using. Can be null if not using anything. - * @param useRemaining The ticks remaining for the active item. - * @return The icon index - */ - public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { - if (usingItem != null) { - int j = usingItem.getMaxItemUseDuration() - useRemaining; - - if (j >= 18) - { - return this.getItemIconForUseDuration(2); - } - - if (j > 13) - { - return this.getItemIconForUseDuration(1); - } - - if (j > 0) - { - return this.getItemIconForUseDuration(0); - } - } - - return getIcon(stack, renderPass); - } - - /** - * called when the player releases the use item button. Args: itemstack, world, entityplayer, itemInUseCount - */ - public void onPlayerStoppedUsing(ItemStack itemstack, World world, EntityPlayer entityPlayer, int itemInUseCount) { - int charge = this.getMaxItemUseDuration(itemstack) - itemInUseCount; - - ArrowLooseEvent event = new ArrowLooseEvent(entityPlayer, itemstack, charge); - MinecraftForge.EVENT_BUS.post(event); - if (event.isCanceled()) - { - return; - } - charge = event.charge; - - boolean isNoPickup = entityPlayer.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, itemstack) > 0; - - if (isNoPickup || entityPlayer.inventory.hasItem(Items.arrow)) - { - float velocity = (float)charge / 20.0F; - velocity = (velocity * velocity + velocity * 2.0F) / 3.0F; - - if ((double)velocity < 0.1D) - { - return; - } - - if (velocity > 1.0F) - { - velocity = 1.0F; - } - - EntityArrow entityarrow = getArrow(world, entityPlayer, velocity * 2.0F); - - if (velocity == 1.0F) - { - entityarrow.setIsCritical(true); - } - - int powerLevel = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, itemstack); - - if (powerLevel > 0) - { - entityarrow.setDamage(entityarrow.getDamage() + (double)powerLevel * 0.5D + 0.5D); - } - - int punchLevel = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, itemstack); - - if (punchLevel > 0) - { - entityarrow.setKnockbackStrength(punchLevel); - } - - if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, itemstack) > 0) - { - entityarrow.setFire(100); - } - - itemstack.damageItem(1, entityPlayer); - world.playSoundAtEntity(entityPlayer, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + velocity * 0.5F); - - if (isNoPickup) - { - entityarrow.canBePickedUp = 2; - } - else - { - entityPlayer.inventory.consumeInventoryItem(Items.arrow); - } - - if (!world.isRemote) - { - world.spawnEntityInWorld(entityarrow); - } - } - } - - protected EntityArrow getArrow(World world, EntityPlayer entityPlayer, float velocity) { - return new EntityArrow(world, entityPlayer, velocity); - } - } diff --git a/src/main/java/twilightforest/item/ItemTFChainBlock.java b/src/main/java/twilightforest/item/ItemTFChainBlock.java index 7b7efbf78a..297565e412 100644 --- a/src/main/java/twilightforest/item/ItemTFChainBlock.java +++ b/src/main/java/twilightforest/item/ItemTFChainBlock.java @@ -1,201 +1,131 @@ package twilightforest.item; -import java.util.HashMap; - import com.google.common.collect.Sets; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import twilightforest.TwilightForestMod; -import twilightforest.entity.EntityTFChainBlock; -import twilightforest.entity.EntityTFCubeOfAnnihilation; -import twilightforest.entity.EntityTFTwilightWandBolt; -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.item.IItemPropertyGetter; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemTool; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.IIcon; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.entity.EntityTFChainBlock; + +import javax.annotation.Nullable; +import java.util.UUID; + +public class ItemTFChainBlock extends ItemTool implements ModelRegisterCallback { -public class ItemTFChainBlock extends ItemTool { - - // which items have launched which blocks? - private HashMap launchedBlocksMap = new HashMap(); + private static final String THROWN_UUID_KEY = "chainEntity"; protected ItemTFChainBlock() { - super(6, TFItems.TOOL_KNIGHTLY, Sets.newHashSet(new Block[] {Blocks.stone})); - this.maxStackSize = 1; - this.setMaxDamage(99); + super(6, -3.0F, TFItems.TOOL_KNIGHTLY, Sets.newHashSet(Blocks.STONE)); + this.maxStackSize = 1; + this.setMaxDamage(99); this.setCreativeTab(TFItems.creativeTab); + this.addPropertyOverride(TwilightForestMod.prefix("thrown"), new IItemPropertyGetter() { + @SideOnly(Side.CLIENT) + @Override + public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) { + return getThrownUuid(stack) != null ? 1 : 0; + } + }); } - - @Override - public ItemStack onItemRightClick(ItemStack stack, World worldObj, EntityPlayer player) { - player.setItemInUse(stack, this.getMaxItemUseDuration(stack)); - if (!worldObj.isRemote && !this.hasLaunchedBlock(stack)) { + @Override + public void onUpdate(ItemStack stack, World world, Entity holder, int slot, boolean isSelected) { + if (!world.isRemote && getThrownUuid(stack) != null && getThrownEntity(world, stack) == null) { + stack.getTagCompound().removeTag(THROWN_UUID_KEY + "Most"); + stack.getTagCompound().removeTag(THROWN_UUID_KEY + "Least"); + } + } - worldObj.playSoundAtEntity(player, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F)); + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + if (getThrownUuid(stack) != null) + return ActionResult.newResult(EnumActionResult.PASS, stack); - EntityTFChainBlock launchedBlock = new EntityTFChainBlock(worldObj, player); - worldObj.spawnEntityInWorld(launchedBlock); - this.setLaunchedBlock(stack, launchedBlock); + player.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F)); - setChainAsThrown(stack); + if (!world.isRemote) { + EntityTFChainBlock launchedBlock = new EntityTFChainBlock(world, player, hand); + world.spawnEntity(launchedBlock); + setThrownEntity(stack, launchedBlock); stack.damageItem(1, player); - } - return stack; + + player.setActiveHand(hand); + return ActionResult.newResult(EnumActionResult.SUCCESS, stack); } - /** - * Set this item as having been thrown - * @param stack - */ - public static void setChainAsThrown(ItemStack stack) { - // set NBT tag for stack - if (stack.getTagCompound() == null) { - stack.setTagCompound(new NBTTagCompound()); + @Nullable + private static UUID getThrownUuid(ItemStack stack) { + if (stack.hasTagCompound() && stack.getTagCompound().hasUniqueId(THROWN_UUID_KEY)) { + return stack.getTagCompound().getUniqueId(THROWN_UUID_KEY); } - stack.getTagCompound().setBoolean("thrown", true); + + return null; } - /** - * Set the spike block for this item as returned to the player - * @param stack - */ - public static void setChainAsReturned(ItemStack stack) { - // set NBT tag for stack - if (stack.getTagCompound() == null) { - stack.setTagCompound(new NBTTagCompound()); + @Nullable + private static EntityTFChainBlock getThrownEntity(World world, ItemStack stack) { + if (world instanceof WorldServer) { + UUID id = getThrownUuid(stack); + if (id != null) { + Entity e = ((WorldServer) world).getEntityFromUuid(id); + if (e instanceof EntityTFChainBlock) { + return (EntityTFChainBlock) e; + } + } } - stack.getTagCompound().setBoolean("thrown", false); + + return null; } - - - /** - * Method for the client to determine if the block has been thrown or not. Not as accurate as server method due to lag, etc. - * @param stack - */ - public static boolean doesChainHaveBlock(ItemStack stack) { - if (stack.getTagCompound() == null) { - return true; - } else { - return !stack.getTagCompound().getBoolean("thrown"); + + private static void setThrownEntity(ItemStack stack, EntityTFChainBlock cube) { + if (!stack.hasTagCompound()) { + stack.setTagCompound(new NBTTagCompound()); } + stack.getTagCompound().setUniqueId(THROWN_UUID_KEY, cube.getUniqueID()); } - - /** - * Set the spike block belonging to the player as returned - * @param player - */ - public static void setChainAsReturned(EntityPlayer player) { - if (player != null && player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() == TFItems.chainBlock) { - setChainAsReturned(player.getCurrentEquippedItem()); - } + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 72000; } - /** - * Method on the server that determines definitively if the item has been thrown or not - */ - public boolean hasLaunchedBlock(ItemStack stack) { - Entity cube = this.launchedBlocksMap.get(stack); - - return cube != null && !cube.isDead; + @Override + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BLOCK; } - - public void setLaunchedBlock(ItemStack stack, EntityTFChainBlock launchedCube) { - this.launchedBlocksMap.put(stack, launchedCube); + + @Override + public boolean canDisableShield(ItemStack stack, ItemStack shield, EntityLivingBase entity, EntityLivingBase attacker) { + return true; } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * Player, Render pass, and item usage sensitive version of getIconIndex. - * - * @param stack The item stack to get the icon for. (Usually this, and usingItem will be the same if usingItem is not null) - * @param renderPass The pass to get the icon for, 0 is default. - * @param player The player holding the item - * @param usingItem The item the player is actively using. Can be null if not using anything. - * @param useRemaining The ticks remaining for the active item. - * @return The icon index - */ - public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { - - if (this.doesChainHaveBlock(stack)) { - return this.itemIcon; + + @Override + public int getHarvestLevel(ItemStack stack, String toolClass, @Nullable EntityPlayer player, @Nullable IBlockState state) { + if ("pickaxe".equals(toolClass)) { + return 2; } else { - return TFItems.knightmetalRing.getIconIndex(stack); + return -1; } } - - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.block; - } - - - /** - * Called when a entity tries to play the 'swing' animation. - * - * @param entityLiving The entity swinging the item. - * @param stack The Item stack - * @return True to cancel any further processing by EntityLiving - */ - @Override - public boolean onEntitySwing(EntityLivingBase entityLiving, ItemStack stack) { - return false; - } - - - @Override - public int getHarvestLevel(ItemStack stack, String toolClass) - { - if (toolClass != null && toolClass.equals("pickaxe")) { - return 2; - } else { - return -1; - } - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with knightmetal ingots - return par2ItemStack.getItem() == TFItems.knightMetal ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } } diff --git a/src/main/java/twilightforest/item/ItemTFCharm.java b/src/main/java/twilightforest/item/ItemTFCharm.java deleted file mode 100644 index 30118c876d..0000000000 --- a/src/main/java/twilightforest/item/ItemTFCharm.java +++ /dev/null @@ -1,25 +0,0 @@ -package twilightforest.item; - -import net.minecraft.client.renderer.texture.IIconRegister; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class ItemTFCharm extends ItemTF -{ - - protected ItemTFCharm() { - super(); - this.setCreativeTab(TFItems.creativeTab); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } -} diff --git a/src/main/java/twilightforest/item/ItemTFCompressed.java b/src/main/java/twilightforest/item/ItemTFCompressed.java new file mode 100644 index 0000000000..b4c11d526c --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFCompressed.java @@ -0,0 +1,19 @@ +package twilightforest.item; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; + +public class ItemTFCompressed extends ItemBlockTFMeta { + public ItemTFCompressed(Block block) { + super(block); + } + + @Override + public int getItemBurnTime(ItemStack stack) { + /* vanilla has dumb logic that sets burn time to 300 for all metas + if default state material is wood + todo assign proper values here? + */ + return 0; + } +} diff --git a/src/main/java/twilightforest/item/ItemTFCrumbleHorn.java b/src/main/java/twilightforest/item/ItemTFCrumbleHorn.java index d0a39ba1d3..d60f969052 100644 --- a/src/main/java/twilightforest/item/ItemTFCrumbleHorn.java +++ b/src/main/java/twilightforest/item/ItemTFCrumbleHorn.java @@ -1,198 +1,212 @@ package twilightforest.item; import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.BlockSand; +import net.minecraft.block.BlockStoneBrick; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.event.ForgeEventFactory; +import org.apache.commons.lang3.tuple.Pair; +import twilightforest.advancements.TFAdvancements; +import twilightforest.block.BlockTFMazestone; +import twilightforest.block.BlockTFTowerWood; +import twilightforest.block.BlockTFUnderBrick; import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.enums.MazestoneVariant; +import twilightforest.enums.TowerWoodVariant; +import twilightforest.enums.UnderBrickVariant; +import twilightforest.util.WorldUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; + +public class ItemTFCrumbleHorn extends ItemTF { -public class ItemTFCrumbleHorn extends ItemTF -{ private static final int CHANCE_HARVEST = 20; private static final int CHANCE_CRUMBLE = 5; - protected ItemTFCrumbleHorn() { - super(); - this.setCreativeTab(TFItems.creativeTab); + private final List, UnaryOperator>> crumbleTransforms = new ArrayList<>(); + private final List> harvestedStates = new ArrayList<>(); + + ItemTFCrumbleHorn(EnumRarity rarity) { + super(rarity); this.maxStackSize = 1; - this.setMaxDamage(1024); + this.setMaxDamage(1024); + this.addCrumbleTransforms(); + } + + private void addCrumbleTransforms() { + addCrumble(() -> Blocks.STONE, () -> Blocks.COBBLESTONE.getDefaultState()); + addCrumble(state -> state.getBlock() == Blocks.STONEBRICK + && state.getValue(BlockStoneBrick.VARIANT) == BlockStoneBrick.EnumType.DEFAULT, + state -> state.withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CRACKED) + ); + addCrumble(state -> state.getBlock() == TFBlocks.maze_stone + && state.getValue(BlockTFMazestone.VARIANT) == MazestoneVariant.BRICK, + state -> state.withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.CRACKED) + ); + addCrumble(state -> state.getBlock() == TFBlocks.underbrick + && state.getValue(BlockTFUnderBrick.VARIANT) == UnderBrickVariant.NORMAL, + state -> state.withProperty(BlockTFUnderBrick.VARIANT, UnderBrickVariant.CRACKED) + ); + addCrumble(state -> state.getBlock() == TFBlocks.tower_wood + && state.getValue(BlockTFTowerWood.VARIANT) == TowerWoodVariant.PLAIN, + state -> state.withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.CRACKED) + ); + addCrumble(() -> Blocks.COBBLESTONE, () -> Blocks.GRAVEL.getDefaultState()); + addCrumble(() -> Blocks.SANDSTONE, () -> Blocks.SAND.getDefaultState()); + addCrumble(() -> Blocks.RED_SANDSTONE, + () -> Blocks.SAND.getDefaultState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND) + ); + addCrumble(() -> Blocks.GRASS, () -> Blocks.DIRT.getDefaultState()); + addCrumble(() -> Blocks.MYCELIUM, () -> Blocks.DIRT.getDefaultState()); + + addHarvest(() -> Blocks.GRAVEL); + addHarvest(() -> Blocks.DIRT); + addHarvest(() -> Blocks.SAND); + addHarvest(() -> Blocks.CLAY); + } + + private void addCrumble(Supplier block, Supplier result) { + addCrumble(state -> state.getBlock() == block.get(), state -> result.get()); } - + + private void addCrumble(Predicate test, UnaryOperator transform) { + crumbleTransforms.add(Pair.of(test, transform)); + } + + private void addHarvest(Supplier block) { + addHarvest(state -> state.getBlock() == block.get()); + } + + private void addHarvest(Predicate test) { + harvestedStates.add(test); + } + @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World world, EntityPlayer player) { - - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); - - world.playSoundAtEntity(player, "mob.sheep.say", 1.0F, 0.8F); - - return par1ItemStack; - } - - - /** - * Called each tick while using an item. - * @param stack The Item being used - * @param player The Player using the item - * @param count The amount of time in tick the item has been used for continuously - */ - @Override - public void onUsingTick(ItemStack stack, EntityPlayer player, int count) - { - if (count > 10 && count % 5 == 0 && !player.worldObj.isRemote) - { - int crumbled = doCrumble(player.worldObj, player); - - if (crumbled > 0) - { - stack.damageItem(crumbled, player); + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + player.setActiveHand(hand); + player.playSound(SoundEvents.ENTITY_SHEEP_AMBIENT, 1.0F, 0.8F); + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); + } + @Override + public void onUsingTick(ItemStack stack, EntityLivingBase living, int count) { + if (count > 10 && count % 5 == 0 && !living.world.isRemote) { + int crumbled = doCrumble(stack, living.world, living); + + if (crumbled > 0) { + stack.damageItem(crumbled, living); } - - player.worldObj.playSoundAtEntity(player, "mob.sheep.say", 1.0F, 0.8F); + living.world.playSound(null, living.posX, living.posY, living.posZ, SoundEvents.ENTITY_SHEEP_AMBIENT, living.getSoundCategory(), 1.0F, 0.8F); } - - } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.bow; - } - - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } - - /** - * Bleeeat! - */ - private int doCrumble(World world, EntityPlayer player) - { - double range = 3.0D; - double radius = 2.0D; - Vec3 srcVec = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 lookVec = player.getLookVec(); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - - AxisAlignedBB crumbleBox = AxisAlignedBB.getBoundingBox(destVec.xCoord - radius, destVec.yCoord - radius, destVec.zCoord - radius, destVec.xCoord + radius, destVec.yCoord + radius, destVec.zCoord + radius); - - return crumbleBlocksInAABB(world, player, crumbleBox); - } - - - /** - * Crumble block in the box - */ - private int crumbleBlocksInAABB(World world, EntityPlayer player, AxisAlignedBB par1AxisAlignedBB) - { - //System.out.println("Destroying blocks in " + par1AxisAlignedBB); - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - - int crumbled = 0; - - for (int dx = minX; dx <= maxX; ++dx) - { - for (int dy = minY; dy <= maxY; ++dy) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - crumbled += crumbleBlock(world, player, dx, dy, dz); - } - } - } - - - - return crumbled; - } - - /** - * Crumble a specific block. - */ - private int crumbleBlock(World world, EntityPlayer player, int dx, int dy, int dz) { - int cost = 0; - - Block currentID = world.getBlock(dx, dy, dz); - - if (currentID != Blocks.air) - { - int currentMeta = world.getBlockMetadata(dx, dy, dz); - - if (currentID == Blocks.stone && world.rand.nextInt(CHANCE_CRUMBLE) == 0) - { - world.setBlock(dx, dy, dz, Blocks.cobblestone, 0, 3); - world.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - cost++; - } - - if (currentID == Blocks.stonebrick && currentMeta == 0 && world.rand.nextInt(CHANCE_CRUMBLE) == 0) - { - world.setBlock(dx, dy, dz, Blocks.stonebrick, 2, 3); - world.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - cost++; - } - - if (currentID == TFBlocks.mazestone && currentMeta == 1 && world.rand.nextInt(CHANCE_CRUMBLE) == 0) - { - world.setBlock(dx, dy, dz, TFBlocks.mazestone, 4, 3); - world.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - cost++; - } - - if (currentID == Blocks.cobblestone && world.rand.nextInt(CHANCE_CRUMBLE) == 0) - { - world.setBlock(dx, dy, dz, Blocks.gravel, 0, 3); - world.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - cost++; - } - - if (currentID == Blocks.gravel || currentID == Blocks.dirt) - { - if (currentID.canHarvestBlock(player, currentMeta) && world.rand.nextInt(CHANCE_HARVEST) == 0) - { - world.setBlock(dx, dy, dz, Blocks.air, 0, 3); - currentID.harvestBlock(world, player, dx, dy, dz, currentMeta); - world.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); - cost++; - } + } + + @Override + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BOW; + } + + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 72000; + } + + @Override + public boolean canContinueUsing(ItemStack oldStack, ItemStack newStack) { + return oldStack.getItem() == newStack.getItem(); + } + + @Override + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) { + return slotChanged || newStack.getItem() != oldStack.getItem(); + } + + private int doCrumble(ItemStack stack, World world, EntityLivingBase living) { + + final double range = 3.0D; + final double radius = 2.0D; + + Vec3d srcVec = new Vec3d(living.posX, living.posY + living.getEyeHeight(), living.posZ); + Vec3d lookVec = living.getLookVec().scale(range); + Vec3d destVec = srcVec.add(lookVec); + + AxisAlignedBB crumbleBox = new AxisAlignedBB(destVec.x - radius, destVec.y - radius, destVec.z - radius, destVec.x + radius, destVec.y + radius, destVec.z + radius); + + return crumbleBlocksInAABB(stack, world, living, crumbleBox); + } + + private int crumbleBlocksInAABB(ItemStack stack, World world, EntityLivingBase living, AxisAlignedBB box) { + int crumbled = 0; + for (BlockPos pos : WorldUtil.getAllInBB(box)) { + if (crumbleBlock(stack, world, living, pos)) crumbled++; + } + return crumbled; + } + + private boolean crumbleBlock(ItemStack stack, World world, EntityLivingBase living, BlockPos pos) { + + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + + if (block.isAir(state, world, pos)) return false; + + for (Pair, UnaryOperator> transform : crumbleTransforms) { + if (transform.getLeft().test(state) && world.rand.nextInt(CHANCE_CRUMBLE) == 0) { + world.setBlockState(pos, transform.getRight().apply(state), 3); + world.playEvent(2001, pos, Block.getStateId(state)); + + postTrigger(living, stack, world, pos); + + return true; } + } + + for (Predicate predicate : harvestedStates) { + if (predicate.test(state) && world.rand.nextInt(CHANCE_HARVEST) == 0) { + if (living instanceof EntityPlayer) { + if (block.canHarvestBlock(world, pos, (EntityPlayer) living)) { + world.setBlockToAir(pos); + block.harvestBlock(world, (EntityPlayer) living, pos, state, world.getTileEntity(pos), ItemStack.EMPTY); + world.playEvent(2001, pos, Block.getStateId(state)); + + postTrigger(living, stack, world, pos); + + return true; + } + } else if (ForgeEventFactory.getMobGriefingEvent(world, living)) { + world.destroyBlock(pos, true); + postTrigger(living, stack, world, pos); + + return true; + } + } } - - return cost; - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + + return false; + } + + private void postTrigger(EntityLivingBase living, ItemStack stack, World world, BlockPos pos) { + if (living instanceof EntityPlayerMP) + TFAdvancements.ITEM_USE_TRIGGER.trigger((EntityPlayerMP) living, stack, world, pos); + } } diff --git a/src/main/java/twilightforest/item/ItemTFCubeOfAnnihilation.java b/src/main/java/twilightforest/item/ItemTFCubeOfAnnihilation.java index 6c100a217f..a089fc2b70 100644 --- a/src/main/java/twilightforest/item/ItemTFCubeOfAnnihilation.java +++ b/src/main/java/twilightforest/item/ItemTFCubeOfAnnihilation.java @@ -1,192 +1,110 @@ package twilightforest.item; -import java.util.HashMap; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -import twilightforest.TwilightForestMod; -import twilightforest.entity.EntityTFChainBlock; -import twilightforest.entity.EntityTFCubeOfAnnihilation; -import twilightforest.entity.EntityTFTwilightWandBolt; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.EnumAction; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.IItemPropertyGetter; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.IIcon; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFCubeOfAnnihilation; -public class ItemTFCubeOfAnnihilation extends ItemTF { - - private IIcon annihilateIcon; - +import javax.annotation.Nullable; +import java.util.UUID; - private HashMap launchedCubesMap = new HashMap(); - - protected ItemTFCubeOfAnnihilation() { - super(); - this.maxStackSize = 1; - this.setCreativeTab(TFItems.creativeTab); +public class ItemTFCubeOfAnnihilation extends ItemTF { + private static final String THROWN_UUID_KEY = "cubeEntity"; + + protected ItemTFCubeOfAnnihilation(EnumRarity rarity) { + super(rarity); + this.maxStackSize = 1; + this.addPropertyOverride(TwilightForestMod.prefix("thrown"), new IItemPropertyGetter() { + @SideOnly(Side.CLIENT) + @Override + public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) { + return getThrownUuid(stack) != null ? 1 : 0; + } + }); } - - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ + @Override - public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) - { - return false; + public void onUpdate(ItemStack stack, World world, Entity holder, int slot, boolean isSelected) { + if (!world.isRemote && getThrownUuid(stack) != null && getThrownEntity(world, stack) == null) { + stack.getTagCompound().removeTag(THROWN_UUID_KEY + "Most"); + stack.getTagCompound().removeTag(THROWN_UUID_KEY + "Least"); + } } @Override - public ItemStack onItemRightClick(ItemStack stack, World worldObj, EntityPlayer player) { - player.setItemInUse(stack, this.getMaxItemUseDuration(stack)); + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); - if (!worldObj.isRemote && !this.hasLaunchedCube(stack)) { - EntityTFCubeOfAnnihilation launchedCube = new EntityTFCubeOfAnnihilation(worldObj, player); + if (getThrownUuid(stack) != null) + return ActionResult.newResult(EnumActionResult.PASS, stack); - worldObj.spawnEntityInWorld(launchedCube); - - this.setLaunchedCube(stack, launchedCube); - setCubeAsThrown(stack); + if (!world.isRemote) { + EntityTFCubeOfAnnihilation launchedCube = new EntityTFCubeOfAnnihilation(world, player); + world.spawnEntity(launchedCube); + setThrownEntity(stack, launchedCube); } - - return stack; - } - - /** - * Set this item as having been thrown - * @param stack - */ - public static void setCubeAsThrown(ItemStack stack) { - // set NBT tag for stack - if (stack.getTagCompound() == null) { - stack.setTagCompound(new NBTTagCompound()); - } - stack.getTagCompound().setBoolean("thrown", true); + player.setActiveHand(hand); + return ActionResult.newResult(EnumActionResult.SUCCESS, stack); } - /** - * Set the cube for this item as returned to the player - * @param stack - */ - public static void setCubeAsReturned(ItemStack stack) { - // set NBT tag for stack - if (stack.getTagCompound() == null) { - stack.setTagCompound(new NBTTagCompound()); - } - stack.getTagCompound().setBoolean("thrown", false); - } - - - /** - * Method for the client to determine if the cube has been thrown or not. Not as accurate as server method due to lag, etc. - * @param stack - */ - public static boolean doesTalismanHaveCube(ItemStack stack) { - if (stack.getTagCompound() == null) { - return true; - } else { - return !stack.getTagCompound().getBoolean("thrown"); + @Nullable + private static UUID getThrownUuid(ItemStack stack) { + if (stack.hasTagCompound() && stack.getTagCompound().hasUniqueId(THROWN_UUID_KEY)) { + return stack.getTagCompound().getUniqueId(THROWN_UUID_KEY); } + + return null; } - - /** - * Set the cube belonging to the player as returned - * @param player - */ - public static void setCubeAsReturned(EntityPlayer player) { - if (player != null && player.getCurrentEquippedItem() != null && player.getCurrentEquippedItem().getItem() == TFItems.cubeOfAnnihilation) { - setCubeAsReturned(player.getCurrentEquippedItem()); + @Nullable + private static EntityTFCubeOfAnnihilation getThrownEntity(World world, ItemStack stack) { + if (world instanceof WorldServer) { + UUID id = getThrownUuid(stack); + if (id != null) { + Entity e = ((WorldServer) world).getEntityFromUuid(id); + if (e instanceof EntityTFCubeOfAnnihilation) { + return (EntityTFCubeOfAnnihilation) e; + } + } } + + return null; } - - /** - * Player, Render pass, and item usage sensitive version of getIconIndex. - * - * @param stack The item stack to get the icon for. (Usually this, and usingItem will be the same if usingItem is not null) - * @param renderPass The pass to get the icon for, 0 is default. - * @param player The player holding the item - * @param usingItem The item the player is actively using. Can be null if not using anything. - * @param useRemaining The ticks remaining for the active item. - * @return The icon index - */ - public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { - - if (this.doesTalismanHaveCube(stack)) { - return this.itemIcon; - } else { - return TFItems.cubeTalisman.getIconIndex(stack); + + private static void setThrownEntity(ItemStack stack, EntityTFCubeOfAnnihilation cube) { + if (!stack.hasTagCompound()) { + stack.setTagCompound(new NBTTagCompound()); } + stack.getTagCompound().setUniqueId(THROWN_UUID_KEY, cube.getUniqueID()); } - public boolean hasLaunchedCube(ItemStack stack) { - Entity cube = this.launchedCubesMap.get(stack); - - return cube != null && !cube.isDead; - } - - public void setLaunchedCube(ItemStack stack, EntityTFCubeOfAnnihilation launchedCube) { - this.launchedCubesMap.put(stack, launchedCube); + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 72000; } - /** - * Called each tick while using an item. - * @param stack The Item being used - * @param player The Player using the item - * @param count The amount of time in tick the item has been used for continuously - */ - @Override - public void onUsingTick(ItemStack stack, EntityPlayer player, int count) { -// if (stack.getItemDamage() >= this.getMaxDamage()) { -// // do not use -// player.stopUsingItem(); -// return; -// } - - - + @Override + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BLOCK; } - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.block; - } - - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - this.annihilateIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":annihilate_particle"); - } - - public IIcon getAnnihilateIcon() { - return this.annihilateIcon; - } - + @Override + public boolean canDisableShield(ItemStack stack, ItemStack shield, EntityLivingBase entity, EntityLivingBase attacker) { + return true; + } } diff --git a/src/main/java/twilightforest/item/ItemTFEmptyMagicMap.java b/src/main/java/twilightforest/item/ItemTFEmptyMagicMap.java index dfc17835f4..7fa8717adf 100644 --- a/src/main/java/twilightforest/item/ItemTFEmptyMagicMap.java +++ b/src/main/java/twilightforest/item/ItemTFEmptyMagicMap.java @@ -1,70 +1,37 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemMapBase; import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatList; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import net.minecraft.world.storage.MapData; -import twilightforest.TFAchievementPage; -import twilightforest.TFMagicMapData; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFEmptyMagicMap extends ItemMapBase -{ - protected ItemTFEmptyMagicMap() - { - super(); +public class ItemTFEmptyMagicMap extends ItemMapBase implements ModelRegisterCallback { + protected ItemTFEmptyMagicMap() { this.setCreativeTab(TFItems.creativeTab); - } + } - /** - * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer - */ - @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) - { - ItemStack mapItem = new ItemStack(TFItems.magicMap, 1, par2World.getUniqueDataId(ItemTFMagicMap.STR_ID)); - String mapName = ItemTFMagicMap.STR_ID + "_" + mapItem.getItemDamage(); - MapData mapData = new TFMagicMapData(mapName); - par2World.setItemData(mapName, mapData); - mapData.scale = 4; - int step = 128 * (1 << mapData.scale); - mapData.xCenter = (int)(Math.round(par3EntityPlayer.posX / step) * step); - mapData.zCenter = (int)(Math.round(par3EntityPlayer.posZ / step) * step); - mapData.dimension = (byte)par2World.provider.dimensionId; - mapData.markDirty(); - --par1ItemStack.stackSize; - - //cheevo - if (mapItem.getItem() == TFItems.magicMap) { - par3EntityPlayer.triggerAchievement(TFAchievementPage.twilightMagicMap); - } + // [VanillaCopy] ItemEmptyMap.onItemRightClick, edits noted + @Override + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { + // TF - scale at 4 + ItemStack itemstack = ItemTFMagicMap.setupNewMap(worldIn, playerIn.posX, playerIn.posZ, (byte) 4, true, false); + ItemStack itemstack1 = playerIn.getHeldItem(handIn); + itemstack1.shrink(1); - if (par1ItemStack.stackSize <= 0) - { - return mapItem; - } - else - { - if (!par3EntityPlayer.inventory.addItemStackToInventory(mapItem.copy())) - { - par3EntityPlayer.dropPlayerItemWithRandomChoice(mapItem, false); - } + if (itemstack1.isEmpty()) { + return new ActionResult<>(EnumActionResult.SUCCESS, itemstack); + } else { + if (!playerIn.inventory.addItemStackToInventory(itemstack.copy())) { + playerIn.dropItem(itemstack, false); + } - return par1ItemStack; - } - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + playerIn.addStat(StatList.getObjectUseStats(this)); + return new ActionResult<>(EnumActionResult.SUCCESS, itemstack1); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFEmptyMazeMap.java b/src/main/java/twilightforest/item/ItemTFEmptyMazeMap.java index 8274bb0f2e..2a71fca8b6 100644 --- a/src/main/java/twilightforest/item/ItemTFEmptyMazeMap.java +++ b/src/main/java/twilightforest/item/ItemTFEmptyMazeMap.java @@ -1,88 +1,39 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemMapBase; import net.minecraft.item.ItemStack; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; +import net.minecraft.stats.StatList; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.TFFeature; -import twilightforest.TFMazeMapData; -import twilightforest.TwilightForestMod; -import twilightforest.world.WorldProviderTwilightForest; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFEmptyMazeMap extends ItemMapBase -{ - boolean mapOres; - - protected ItemTFEmptyMazeMap(boolean mapOres) - { - super(); +public class ItemTFEmptyMazeMap extends ItemMapBase implements ModelRegisterCallback { + boolean mapOres; + + protected ItemTFEmptyMazeMap(boolean mapOres) { this.setCreativeTab(TFItems.creativeTab); - this.mapOres = mapOres; - } + this.mapOres = mapOres; + } - /** - * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer - */ - @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) - { - ItemStack mapItem = new ItemStack(mapOres ? TFItems.oreMap : TFItems.mazeMap, 1, par2World.getUniqueDataId(ItemTFMazeMap.STR_ID)); - String var5 = "mazemap_" + mapItem.getItemDamage(); - TFMazeMapData mapData = new TFMazeMapData(var5); - par2World.setItemData(var5, mapData); - mapData.scale = 0; - int step = 128 * (1 << mapData.scale); - // need to fix center for feature offset - if (par2World.provider instanceof WorldProviderTwilightForest && TFFeature.getFeatureForRegion(MathHelper.floor_double(par3EntityPlayer.posX) >> 4, MathHelper.floor_double(par3EntityPlayer.posZ) >> 4, par2World) == TFFeature.labyrinth) { - ChunkCoordinates mc = TFFeature.getNearestCenterXYZ(MathHelper.floor_double(par3EntityPlayer.posX) >> 4, MathHelper.floor_double(par3EntityPlayer.posZ) >> 4, par2World); - mapData.xCenter = mc.posX; - mapData.zCenter = mc.posZ; - mapData.yCenter = MathHelper.floor_double(par3EntityPlayer.posY); - } else { - mapData.xCenter = (int)(Math.round(par3EntityPlayer.posX / step) * step) + 10; // mazes are offset slightly - mapData.zCenter = (int)(Math.round(par3EntityPlayer.posZ / step) * step) + 10; // mazes are offset slightly - mapData.yCenter = MathHelper.floor_double(par3EntityPlayer.posY); - } - mapData.dimension = par2World.provider.dimensionId; - mapData.markDirty(); - --par1ItemStack.stackSize; - - //cheevos - if (mapItem.getItem() == TFItems.mazeMap) { - par3EntityPlayer.triggerAchievement(TFAchievementPage.twilightMazeMap); - } - if (mapItem.getItem() == TFItems.oreMap) { - par3EntityPlayer.triggerAchievement(TFAchievementPage.twilightOreMap); - } + // [VanillaCopy] ItemEmptyMap.onItemRightClick calling own setup method + @Override + public ActionResult onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { + ItemStack itemstack = ItemTFMazeMap.setupNewMap(worldIn, playerIn.posX, playerIn.posZ, (byte) 0, true, false, playerIn.posY, this.mapOres); + ItemStack itemstack1 = playerIn.getHeldItem(handIn); + itemstack1.shrink(1); - if (par1ItemStack.stackSize <= 0) - { - return mapItem; - } - else - { - if (!par3EntityPlayer.inventory.addItemStackToInventory(mapItem.copy())) - { - par3EntityPlayer.dropPlayerItemWithRandomChoice(mapItem, false); - } + if (itemstack1.isEmpty()) { + return new ActionResult<>(EnumActionResult.SUCCESS, itemstack); + } else { + if (!playerIn.inventory.addItemStackToInventory(itemstack.copy())) { + playerIn.dropItem(itemstack, false); + } - return par1ItemStack; - } - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + playerIn.addStat(StatList.getObjectUseStats(this)); + return new ActionResult<>(EnumActionResult.SUCCESS, itemstack1); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFEnderBow.java b/src/main/java/twilightforest/item/ItemTFEnderBow.java index 026d30420c..6f3d32f9ec 100644 --- a/src/main/java/twilightforest/item/ItemTFEnderBow.java +++ b/src/main/java/twilightforest/item/ItemTFEnderBow.java @@ -1,14 +1,9 @@ package twilightforest.item; -import twilightforest.TwilightForestMod; - public class ItemTFEnderBow extends ItemTFBowBase { - - - public ItemTFEnderBow() { - this.setTextureName(TwilightForestMod.ID + ":enderbow"); - this.setCreativeTab(TFItems.creativeTab); - } + public ItemTFEnderBow() { + this.setCreativeTab(TFItems.creativeTab); + } } diff --git a/src/main/java/twilightforest/item/ItemTFExperiment115.java b/src/main/java/twilightforest/item/ItemTFExperiment115.java new file mode 100644 index 0000000000..a529535dd2 --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFExperiment115.java @@ -0,0 +1,51 @@ +package twilightforest.item; + +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.TFBlocks; + +public class ItemTFExperiment115 extends ItemTFFood { + + public ItemTFExperiment115() { + super(4, 0.3F, false); + } + + @Override + public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); + + // Let eating take priority over block placement + if (player.canEat(false)) + return EnumActionResult.PASS; + + IBlockState e115 = TFBlocks.experiment_115.getDefaultState(); + + if (!block.isReplaceable(world, pos)) pos = pos.offset(facing); + ItemStack itemstack = player.getHeldItem(hand); + + if (!itemstack.isEmpty() && player.canPlayerEdit(pos, facing, itemstack) && world.mayPlace(e115.getBlock(), pos, false, facing, null)) { + if (world.setBlockState(pos, e115, 11)) { + TFBlocks.experiment_115.onBlockPlacedBy(world, pos, e115, player, itemstack); + SoundType soundtype = world.getBlockState(pos).getBlock().getSoundType(world.getBlockState(pos), world, pos, player); + world.playSound(player, pos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F); + itemstack.shrink(1); + } + + if (player instanceof EntityPlayerMP) CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, pos, itemstack); + + return EnumActionResult.SUCCESS; + } else return super.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/item/ItemTFFieryArmor.java b/src/main/java/twilightforest/item/ItemTFFieryArmor.java index dc8b6cee93..1e1d7a5f67 100644 --- a/src/main/java/twilightforest/item/ItemTFFieryArmor.java +++ b/src/main/java/twilightforest/item/ItemTFFieryArmor.java @@ -1,106 +1,60 @@ package twilightforest.item; -import java.util.List; - import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; -import net.minecraft.util.StatCollector; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; + +import javax.annotation.Nullable; +import java.util.List; -public class ItemTFFieryArmor extends ItemArmor { +public class ItemTFFieryArmor extends ItemTFArmor implements ModelRegisterCallback { - public ItemTFFieryArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int renderIndex, int armorType) { - super(par2EnumArmorMaterial, renderIndex, armorType); + public ItemTFFieryArmor(ItemArmor.ArmorMaterial armorMaterial, EntityEquipmentSlot armorType, EnumRarity rarity) { + super(armorMaterial, armorType, rarity); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return an item rarity from EnumRarity - */ @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.epic; + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + if (slot == EntityEquipmentSlot.LEGS) { + return TwilightForestMod.ARMOR_DIR + "fiery_2.png"; + } else { + return TwilightForestMod.ARMOR_DIR + "fiery_1.png"; + } } @Override - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) { - - - if(itemstack.getItem() == TFItems.fieryPlate || itemstack.getItem() == TFItems.fieryHelm || itemstack.getItem() == TFItems.fieryBoots) - { - return TwilightForestMod.ARMOR_DIR + "fiery_1.png"; - } - if(itemstack.getItem() == TFItems.fieryLegs) - { - return TwilightForestMod.ARMOR_DIR + "fiery_2.png"; + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack stack = new ItemStack(this); + //stack.addEnchantment(TFEnchantment.fieryAura, 2); + list.add(stack); } - return TwilightForestMod.ARMOR_DIR + "fiery_1.png"; } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - //istack.addEnchantment(TFEnchantment.fieryAura, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with fiery ingots - return par2ItemStack.getItem() == TFItems.fieryIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * allows items to add custom lines of information to the mouseover description - */ + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format(getTranslationKey() + ".tooltip")); + } + @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, ModelBiped oldModel) { + return TwilightForestMod.proxy.getFieryArmorModel(armorSlot); } - - /** - * Override this method to have an item handle its own armor rendering. - * - * @param entityLiving The entity wearing the armor - * @param itemStack The itemStack to render the model of - * @param armorSlot 0=head, 1=torso, 2=legs, 3=feet - * - * @return A ModelBiped to render instead of the default - */ - @SideOnly(Side.CLIENT) - public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) - { - return TwilightForestMod.proxy.getFieryArmorModel(armorSlot); - } } diff --git a/src/main/java/twilightforest/item/ItemTFFieryPick.java b/src/main/java/twilightforest/item/ItemTFFieryPick.java index 16e528cac2..bda1b205ed 100644 --- a/src/main/java/twilightforest/item/ItemTFFieryPick.java +++ b/src/main/java/twilightforest/item/ItemTFFieryPick.java @@ -1,150 +1,112 @@ package twilightforest.item; -import java.util.ArrayList; -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.FurnaceRecipes; -import net.minecraft.util.StatCollector; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.util.ParticleHelper; +import twilightforest.util.TFItemStackUtils; -public class ItemTFFieryPick extends ItemPickaxe { +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class ItemTFFieryPick extends ItemPickaxe implements ModelRegisterCallback { - protected ItemTFFieryPick(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFFieryPick(Item.ToolMaterial toolMaterial) { + super(toolMaterial); this.setCreativeTab(TFItems.creativeTab); } - @Override - public boolean onBlockDestroyed(ItemStack par1ItemStack, World par2World, Block blockID, int x, int y, int z, EntityLivingBase par7EntityLiving) { - if (super.onBlockDestroyed(par1ItemStack, par2World, blockID, x, y, z, par7EntityLiving) && this.func_150897_b(blockID)) - { - // we are just displaying the fire animation here, so check if we're on the client - if (par2World.isRemote) - { - int meta = par2World.getBlockMetadata(x, y, z); // I guess the block is still there at this point - - ArrayList items = blockID.getDrops(par2World, x, y, z, meta, 0); - - for (ItemStack input : items) - { - // does it smelt? - ItemStack result = FurnaceRecipes.smelting().getSmeltingResult(input); - if (result != null) - { - - // display fire animation - for (int var1 = 0; var1 < 5; ++var1) - { - double rx = itemRand.nextGaussian() * 0.02D; - double ry = itemRand.nextGaussian() * 0.02D; - double rz = itemRand.nextGaussian() * 0.02D; - double magnitude = 20.0; - par2World.spawnParticle("flame", x + 0.5 + (rx * magnitude), y + 0.5 + (ry * magnitude), z + 0.5 + (rz * magnitude), -rx, -ry, -rz); + @SubscribeEvent + public static void onDrops(BlockEvent.HarvestDropsEvent event) { + if (event.getHarvester() != null && event.getHarvester().getHeldItemMainhand().getItem() == TFItems.fiery_pickaxe + && event.getState().getBlock().canHarvestBlock(event.getWorld(), event.getPos(), event.getHarvester())) { + + List removeThese = new ArrayList<>(); + List addThese = new ArrayList<>(); + + for (ItemStack input : event.getDrops()) { + ItemStack result = FurnaceRecipes.instance().getSmeltingResult(input); + if (!result.isEmpty()) { + + int combinedCount = input.getCount() * result.getCount(); + + addThese.addAll(TFItemStackUtils.splitToSize(new ItemStack(result.getItem(), combinedCount, result.getItemDamage()))); + removeThese.add(input); + + // [VanillaCopy] SlotFurnaceOutput.onCrafting + int i = combinedCount; + float f = FurnaceRecipes.instance().getSmeltingExperience(result); + + if (f == 0.0F) { + i = 0; + } else if (f < 1.0F) { + int j = MathHelper.floor((float) i * f); + + if (j < MathHelper.ceil((float) i * f) && Math.random() < (double) ((float) i * f - (float) j)) { + ++j; } + i = j; } + while (i > 0) { + int k = EntityXPOrb.getXPSplit(i); + i -= k; + event.getHarvester().world.spawnEntity(new EntityXPOrb(event.getWorld(), event.getHarvester().posX, event.getHarvester().posY + 0.5D, event.getHarvester().posZ, k)); + } + + ParticleHelper.spawnParticles(event.getWorld(), event.getPos(), EnumParticleTypes.FLAME, 5, 0.02); } } - - return true; - } - else - { - return false; + event.getDrops().removeAll(removeThese); + event.getDrops().addAll(addThese); } } - - /** - * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise - * the damage on the stack. - */ - @Override - public boolean hitEntity(ItemStack par1ItemStack, EntityLivingBase par2EntityLiving, EntityLivingBase par3EntityLiving) { - boolean result = super.hitEntity(par1ItemStack, par2EntityLiving, par3EntityLiving); - - if (result && !par2EntityLiving.isImmuneToFire()) - { - if (par2EntityLiving.worldObj.isRemote) - { - // fire animation! - for (int var1 = 0; var1 < 20; ++var1) - { - double var2 = itemRand.nextGaussian() * 0.02D; - double var4 = itemRand.nextGaussian() * 0.02D; - double var6 = itemRand.nextGaussian() * 0.02D; - double var8 = 10.0D; - par2EntityLiving.worldObj.spawnParticle("flame", par2EntityLiving.posX + itemRand.nextFloat() * par2EntityLiving.width * 2.0F - par2EntityLiving.width - var2 * var8, par2EntityLiving.posY + itemRand.nextFloat() * par2EntityLiving.height - var4 * var8, par2EntityLiving.posZ + itemRand.nextFloat() * par2EntityLiving.width * 2.0F - par2EntityLiving.width - var6 * var8, var2, var4, var6); - } - } - else - { - par2EntityLiving.setFire(15); - } + + @Override + public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { + boolean result = super.hitEntity(stack, target, attacker); + + if (result && !target.world.isRemote && !target.isImmuneToFire()) { + ParticleHelper.spawnParticles(target, EnumParticleTypes.FLAME, 20, 0.02); + target.setFire(15); } - + return result; } - /** - * Return an item rarity from EnumRarity - * - * This is automatically rare - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; + private static final EnumRarity RARITY = EnumRarity.UNCOMMON; + + @Nonnull + @Override + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE.compareTo(RARITY) > 0 ? EnumRarity.RARE : RARITY : RARITY; } - - /** - * allows items to add custom lines of information to the mouseover description - */ + @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format(getTranslationKey() + ".tooltip")); } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with fiery ingots - return par2ItemStack.getItem() == TFItems.fieryIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - - /** - * Returns if the item (tool) can harvest results from the block type. (canHarvestBlock) - */ - public boolean func_150897_b(Block par1Block) - { - return par1Block == Blocks.obsidian ? true : super.func_150897_b(par1Block); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFFierySword.java b/src/main/java/twilightforest/item/ItemTFFierySword.java index 8ca74f136a..f5782a7f96 100644 --- a/src/main/java/twilightforest/item/ItemTFFierySword.java +++ b/src/main/java/twilightforest/item/ItemTFFierySword.java @@ -1,108 +1,65 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Enchantments; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import net.minecraft.util.StatCollector; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.util.ParticleHelper; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; -public class ItemTFFierySword extends ItemSword { +public class ItemTFFierySword extends ItemSword implements ModelRegisterCallback { - public ItemTFFierySword(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFFierySword(Item.ToolMaterial toolMaterial) { + super(toolMaterial); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + private static final EnumRarity RARITY = EnumRarity.UNCOMMON; + + @Nonnull @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - //istack.addEnchantment(Enchantment.fireAspect, 1); - par3List.add(istack); - } - - /** - * Return an item rarity from EnumRarity - * - * This is automatically rare - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE.compareTo(RARITY) > 0 ? EnumRarity.RARE : RARITY : RARITY; } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with fiery ingots - return par2ItemStack.getItem() == TFItems.fieryIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise - * the damage on the stack. - */ - @Override - public boolean hitEntity(ItemStack par1ItemStack, EntityLivingBase par2EntityLiving, EntityLivingBase par3EntityLiving) { - boolean result = super.hitEntity(par1ItemStack, par2EntityLiving, par3EntityLiving); - - if (result && !par2EntityLiving.isImmuneToFire()) - { - if (par2EntityLiving.worldObj.isRemote) - { - // fire animation! - for (int var1 = 0; var1 < 20; ++var1) - { - double var2 = itemRand.nextGaussian() * 0.02D; - double var4 = itemRand.nextGaussian() * 0.02D; - double var6 = itemRand.nextGaussian() * 0.02D; - double var8 = 10.0D; - par2EntityLiving.worldObj.spawnParticle("flame", par2EntityLiving.posX + itemRand.nextFloat() * par2EntityLiving.width * 2.0F - par2EntityLiving.width - var2 * var8, par2EntityLiving.posY + itemRand.nextFloat() * par2EntityLiving.height - var4 * var8, par2EntityLiving.posZ + itemRand.nextFloat() * par2EntityLiving.width * 2.0F - par2EntityLiving.width - var6 * var8, var2, var4, var6); - } - } - else - { - par2EntityLiving.setFire(15); - } + @Override + public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { + boolean result = super.hitEntity(stack, target, attacker); + + if (result && !target.world.isRemote && !target.isImmuneToFire()) { + ParticleHelper.spawnParticles(target, EnumParticleTypes.FLAME, 20, 0.02); } - + return result; } - - /** - * allows items to add custom lines of information to the mouseover description - */ + + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack stack = new ItemStack(this); + stack.addEnchantment(Enchantments.FIRE_ASPECT, 2); + list.add(stack); + } + } + @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format(getTranslationKey() + ".tooltip")); } } diff --git a/src/main/java/twilightforest/item/ItemTFFood.java b/src/main/java/twilightforest/item/ItemTFFood.java index 928b161563..d164e7581d 100644 --- a/src/main/java/twilightforest/item/ItemTFFood.java +++ b/src/main/java/twilightforest/item/ItemTFFood.java @@ -1,109 +1,10 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.Item; import net.minecraft.item.ItemFood; -import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFFood extends ItemFood { - - protected Item looksLike; - protected boolean isSoup; - - - /** - * Soup constructor - */ - public ItemTFFood(int par2) - { - super(par2, false); - this.setCreativeTab(TFItems.creativeTab); - this.setSoup(true); - } - - public ItemTFFood(int par2, float par3, boolean par4) - { - super(par2, par3, par4); - this.setCreativeTab(TFItems.creativeTab); +public class ItemTFFood extends ItemFood implements ModelRegisterCallback { + public ItemTFFood(int amount, float saturation, boolean isWolfFood) { + super(amount, saturation, isWolfFood); } - - - - public Item getLooksLike() { - return looksLike; - } - - /** - * Set this food to look like the specified item - */ - public ItemTFFood setLooksLike(Item itemLike) { - this.looksLike = itemLike; - return this; - } - - /** - * Gets an icon index based on an item's damage value and the given render pass - */ - public IIcon getIconFromDamage(int par1) - { - if (this.looksLike != null) - { - return looksLike.getIconFromDamage(0); - } - else - { - return super.getIconFromDamage(par1); - } - } - - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - // only try to load if we don't have a lookalike - if (this.looksLike == null) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - } - - - public boolean isSoup() { - return isSoup; - } - - public void setSoup(boolean isSoup) { - this.isSoup = isSoup; - this.setMaxStackSize(1); - } - - /** - * Give a bowl back if we are soup - */ - public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) - { - super.onEaten(par1ItemStack, par2World, par3EntityPlayer); - - if (isSoup) - { - return new ItemStack(Items.bowl); - } - else - { - return par1ItemStack; - } - } - - } diff --git a/src/main/java/twilightforest/item/ItemTFGiantBlock.java b/src/main/java/twilightforest/item/ItemTFGiantBlock.java new file mode 100644 index 0000000000..841dd87fc6 --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFGiantBlock.java @@ -0,0 +1,69 @@ +package twilightforest.item; + +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFGiantBlock; +import twilightforest.block.TFBlocks; + +public class ItemTFGiantBlock extends ItemBlock { + + public ItemTFGiantBlock(Block block) { + super(block); + } + + // [VanillaCopy] super, but check every block in the box for permissions + @Override + public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + + IBlockState iblockstate = worldIn.getBlockState(pos); + Block block = iblockstate.getBlock(); + + if (!block.isReplaceable(worldIn, pos)) { + pos = pos.offset(facing); + } + + ItemStack itemstack = player.getHeldItem(hand); + + if (itemstack.isEmpty()) { + return EnumActionResult.FAIL; + } + + for (BlockPos iterPos : BlockTFGiantBlock.getVolume(pos)) { + if (!player.canPlayerEdit(iterPos, facing, itemstack) || !worldIn.mayPlace(this.block, iterPos, false, facing, null)) { + return EnumActionResult.FAIL; + } + } + + pos = BlockTFGiantBlock.roundCoords(pos); + + int i = this.getMetadata(itemstack.getMetadata()); + IBlockState iblockstate1 = this.block.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, i, player, hand); + + if (placeBlockAt(itemstack, player, worldIn, pos, facing, hitX, hitY, hitZ, iblockstate1)) { + iblockstate1 = worldIn.getBlockState(pos); + SoundType soundtype = iblockstate1.getBlock().getSoundType(iblockstate1, worldIn, pos, player); + worldIn.playSound(player, pos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F); + itemstack.shrink(1); + } + + return EnumActionResult.SUCCESS; + } + + @Override + public int getItemBurnTime(ItemStack itemStack) { + if (this.block == TFBlocks.giant_log) { + return 300 * 64; + } + return super.getItemBurnTime(itemStack); + } +} diff --git a/src/main/java/twilightforest/item/ItemTFGiantPick.java b/src/main/java/twilightforest/item/ItemTFGiantPick.java index a58de5d9c8..6d2c443669 100644 --- a/src/main/java/twilightforest/item/ItemTFGiantPick.java +++ b/src/main/java/twilightforest/item/ItemTFGiantPick.java @@ -1,127 +1,58 @@ package twilightforest.item; -import java.util.List; - -import twilightforest.block.BlockTFGiantBlock; -import twilightforest.block.TFBlocks; -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.entity.SharedMonsterAttributes; +import com.google.common.collect.Multimap; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Items; -import net.minecraft.item.EnumRarity; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; -import net.minecraft.util.StatCollector; - -import com.google.common.collect.Multimap; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.block.BlockTFGiantBlock; +import twilightforest.block.TFBlocks; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFGiantPick extends ItemPickaxe { +import javax.annotation.Nullable; +import java.util.List; - private float damageVsEntity; - private GiantItemIcon giantIcon; +public class ItemTFGiantPick extends ItemPickaxe implements ModelRegisterCallback { - protected ItemTFGiantPick(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFGiantPick(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); - this.damageVsEntity = 4 + par2EnumToolMaterial.getDamageVsEntity(); - - } - - /** - * Return an item rarity from EnumRarity - * - * This is automatically rare - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; + this.attackDamage = 8 + material.getAttackDamage(); + this.attackSpeed = -3.5F; } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with knightmetal ingots - return par2ItemStack.getItem() == TFItems.knightMetal ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = Items.stone_pickaxe.getIconFromDamage(0); - this.giantIcon = new GiantItemIcon(this.itemIcon, 0.0625F * 7F, 0.0625F * 2F); - } - - /** - * Return the correct icon for rendering based on the supplied ItemStack and render pass. - * - * Defers to {@link #getIconFromDamageForRenderPass(int, int)} - * @param stack to render for - * @param pass the multi-render pass - * @return the icon - */ - public IIcon getIcon(ItemStack stack, int pass) - { - // render pass 1 gives the giant Icon - if (pass == -1) { - return this.giantIcon; - } else { - return super.getIcon(stack, pass); - } - } - - /** - * allows items to add custom lines of information to the mouseover description - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format(getTranslationKey() + ".tooltip")); } - - /** - * Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Multimap getItemAttributeModifiers() - { - Multimap multimap = super.getItemAttributeModifiers(); - // remove old damage value - multimap.removeAll(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()); - // add new one - multimap.put(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "Tool modifier", (double)this.damageVsEntity, 0)); - return multimap; - } - - + @Override - public float func_150893_a(ItemStack par1ItemStack, Block par2Block) { - float strVsBlock = super.func_150893_a(par1ItemStack, par2Block); + public float getDestroySpeed(ItemStack stack, IBlockState state) { + float destroySpeed = super.getDestroySpeed(stack, state); // extra 64X strength vs giant obsidian - strVsBlock *= (par2Block == TFBlocks.giantObsidian) ? 64 : 1; + destroySpeed *= (state.getBlock() == TFBlocks.giant_obsidian) ? 64 : 1; // 64x strength vs giant blocks - return isGiantBlock(par2Block) ? strVsBlock * 64 : strVsBlock; + return state.getBlock() instanceof BlockTFGiantBlock ? destroySpeed * 64 : destroySpeed; } - private boolean isGiantBlock(Block block) { - return block instanceof BlockTFGiantBlock; - } + @Override + public Multimap getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot) { + Multimap multimap = super.getItemAttributeModifiers(equipmentSlot); + if (equipmentSlot == EntityEquipmentSlot.MAINHAND) { + multimap.put(EntityPlayer.REACH_DISTANCE.getName(), new AttributeModifier(TFItems.GIANT_REACH_MODIFIER, "Tool modifier", 2.5, 0)); + } + return multimap; + } } diff --git a/src/main/java/twilightforest/item/ItemTFGiantSword.java b/src/main/java/twilightforest/item/ItemTFGiantSword.java index 400966faf5..e721e02729 100644 --- a/src/main/java/twilightforest/item/ItemTFGiantSword.java +++ b/src/main/java/twilightforest/item/ItemTFGiantSword.java @@ -1,60 +1,47 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.init.Items; +import com.google.common.collect.Multimap; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import net.minecraft.util.IIcon; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFGiantSword extends ItemSword { +import javax.annotation.Nonnull; - private GiantItemIcon giantIcon; +public class ItemTFGiantSword extends ItemSword implements ModelRegisterCallback { - public ItemTFGiantSword(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFGiantSword(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ironwood ingots - return par2ItemStack.getItem() == TFItems.ironwoodIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = Items.stone_sword.getIconFromDamage(0); - this.giantIcon = new GiantItemIcon(this.itemIcon, 0.0625F * 3F, 0.0625F * 5F); - - } - - /** - * Return the correct icon for rendering based on the supplied ItemStack and render pass. - * - * Defers to {@link #getIconFromDamageForRenderPass(int, int)} - * @param stack to render for - * @param pass the multi-render pass - * @return the icon - */ - public IIcon getIcon(ItemStack stack, int pass) - { - // render pass 1 gives the giant Icon - if (pass == -1) { - return this.giantIcon; - } else { - return super.getIcon(stack, pass); - } - } + @Override + public boolean getIsRepairable(ItemStack stack, ItemStack material) { + return material.getItem() == TFItems.ironwood_ingot || super.getIsRepairable(stack, material); + } + + @Override + @Nonnull + public Multimap getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot) { + Multimap multimap = super.getItemAttributeModifiers(equipmentSlot); + + if (equipmentSlot == EntityEquipmentSlot.MAINHAND) { + AttributeModifier damageModifier = new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", 10 + getAttackDamage(), 0); + AttributeModifier speedModifier = new AttributeModifier(ATTACK_SPEED_MODIFIER, "Weapon modifier", -3.5, 0); + + // remove the entries added by superclass (to allow 'overwriting') + multimap.remove(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), damageModifier); + multimap.remove(SharedMonsterAttributes.ATTACK_SPEED.getName(), speedModifier); + + multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), damageModifier); + multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), speedModifier); + multimap.put(EntityPlayer.REACH_DISTANCE.getName(), new AttributeModifier(TFItems.GIANT_REACH_MODIFIER, "Weapon modifier", 2.5, 0)); + } + + return multimap; + } } diff --git a/src/main/java/twilightforest/item/ItemTFGlassSword.java b/src/main/java/twilightforest/item/ItemTFGlassSword.java index 5dade14c95..c9e9917e4c 100644 --- a/src/main/java/twilightforest/item/ItemTFGlassSword.java +++ b/src/main/java/twilightforest/item/ItemTFGlassSword.java @@ -1,69 +1,52 @@ package twilightforest.item; -import twilightforest.TwilightForestMod; import net.minecraft.block.Block; -import net.minecraft.entity.Entity; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.util.ParticleHelper; -public class ItemTFGlassSword extends ItemSword { +import javax.annotation.Nonnull; - public ItemTFGlassSword(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); +public class ItemTFGlassSword extends ItemSword implements ModelRegisterCallback { + + public ItemTFGlassSword(Item.ToolMaterial toolMaterial) { + super(toolMaterial); this.setCreativeTab(TFItems.creativeTab); - this.setTextureName(TwilightForestMod.ID + ":glassSword"); } - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { - return false; - } - - /** - * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise - * the damage on the stack. - */ - @Override - public boolean hitEntity(ItemStack par1ItemStack, EntityLivingBase par2EntityLiving, EntityLivingBase par3EntityLiving) { - boolean result = super.hitEntity(par1ItemStack, par2EntityLiving, par3EntityLiving); - if (result) { - par1ItemStack.damageItem(1000, par3EntityLiving); - } - - return result; + @Override + public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { + attacker.world.playSound(null, attacker.posX, attacker.posY, attacker.posZ, Blocks.GLASS.getSoundType().getBreakSound(), attacker.getSoundCategory(), 1F, 0.5F); + ParticleHelper.spawnParticles(target, EnumParticleTypes.BLOCK_CRACK, 20, 0.0, Block.getStateId(Blocks.STAINED_GLASS.getDefaultState())); + stack.damageItem(stack.getMaxDamage() + 1, attacker); + return true; + } + + @Nonnull + @Override + public EnumRarity getRarity(ItemStack stack) { + return EnumRarity.RARE; } - - /** - * Called when the player Left Clicks (attacks) an entity. - * Processed before damage is done, if return value is true further processing is canceled - * and the entity is not attacked. - * - * @param stack The Item being used - * @param player The player that is attacking - * @param entity The entity being attacked - * @return True to cancel the rest of the interaction. - */ - public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) - { - if (player.worldObj.isRemote) { - // snow animation! - for (int var1 = 0; var1 < 20; ++var1) { - double px = entity.posX + itemRand.nextFloat() * entity.width * 2.0F - entity.width; - double py = entity.posY + itemRand.nextFloat() * entity.height; - double pz = entity.posZ + itemRand.nextFloat() * entity.width * 2.0F - entity.width; - entity.worldObj.spawnParticle("blockcrack_" + Block.getIdFromBlock(Blocks.stained_glass) + "_" + 0, px, py, pz, 0, 0, 0); - } - - player.playSound(Blocks.glass.stepSound.getBreakSound(), 1F, 0.5F); - } - return false; - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList items) { + super.getSubItems(tab, items); + + if (isInCreativeTab(tab)) { + ItemStack stack = new ItemStack(this); + NBTTagCompound tags = new NBTTagCompound(); + tags.setBoolean("Unbreakable", true); + stack.setTagCompound(tags); + items.add(stack); + } + } } \ No newline at end of file diff --git a/src/main/java/twilightforest/item/ItemTFHydraChops.java b/src/main/java/twilightforest/item/ItemTFHydraChops.java index cd0e94a633..9e8520f6a5 100644 --- a/src/main/java/twilightforest/item/ItemTFHydraChops.java +++ b/src/main/java/twilightforest/item/ItemTFHydraChops.java @@ -1,24 +1,35 @@ package twilightforest.item; -import twilightforest.TFAchievementPage; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; -import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; +import twilightforest.advancements.TFAdvancements; + +import javax.annotation.Nonnull; public class ItemTFHydraChops extends ItemTFFood { - public ItemTFHydraChops(int par2, float par3, boolean par4) { - super(par2, par3, par4); + public ItemTFHydraChops(int amount, float saturation) { + super(amount, saturation, true); + } + + @Override + public ItemStack onItemUseFinish(ItemStack itemStack, World world, EntityLivingBase living) { + // if the player is at zero food, achievements + if (living instanceof EntityPlayerMP && ((EntityPlayerMP) living).getFoodStats().getFoodLevel() <= 0) { + TFAdvancements.CONSUME_HYDRA_CHOP.trigger((EntityPlayerMP) living); + } + // then normal effects + return super.onItemUseFinish(itemStack, world, living); } - - public ItemStack onEaten(ItemStack itemStack, World world, EntityPlayer player) { - // if the player is at zero food, achievements - if (player.getFoodStats().getFoodLevel() <= 0) { - player.triggerAchievement(TFAchievementPage.twilightHydraChop); - } - // then normal effects - return super.onEaten(itemStack, world, player); - } + private static final EnumRarity RARITY = EnumRarity.UNCOMMON; + + @Nonnull + @Override + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE.compareTo(RARITY) > 0 ? EnumRarity.RARE : RARITY : RARITY; + } } diff --git a/src/main/java/twilightforest/item/ItemTFIceBomb.java b/src/main/java/twilightforest/item/ItemTFIceBomb.java index c5c9df6dbb..469f354bcf 100644 --- a/src/main/java/twilightforest/item/ItemTFIceBomb.java +++ b/src/main/java/twilightforest/item/ItemTFIceBomb.java @@ -1,57 +1,33 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; import twilightforest.entity.boss.EntityTFIceBomb; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; public class ItemTFIceBomb extends ItemTF { - - private IIcon[] snowIcon = new IIcon[4]; - - public ItemTFIceBomb() { - super(); this.setMaxStackSize(16); } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - for (int i = 0; i < 4; i++) { - this.snowIcon[i] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":snow_" + i); - } - } - - public IIcon getSnowIcon(int i) { - return snowIcon[i]; - } - - /** - * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer - */ - public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { - if (!par3EntityPlayer.capabilities.isCreativeMode) { - --par1ItemStack.stackSize; - } - par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + player.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); - if (!par2World.isRemote) { - par2World.spawnEntityInWorld(new EntityTFIceBomb(par2World, par3EntityPlayer)); - } + if (!world.isRemote) { + if (!player.capabilities.isCreativeMode) { + player.getHeldItem(hand).shrink(1); + } + EntityTFIceBomb ice = new EntityTFIceBomb(world, player); + ice.shoot(player, player.rotationPitch, player.rotationYaw, -20.0F, 0.75F, 1.0F); + world.spawnEntity(ice); + } - return par1ItemStack; - } + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); + } } diff --git a/src/main/java/twilightforest/item/ItemTFIceBow.java b/src/main/java/twilightforest/item/ItemTFIceBow.java index d5b3138ae2..93b22705fc 100644 --- a/src/main/java/twilightforest/item/ItemTFIceBow.java +++ b/src/main/java/twilightforest/item/ItemTFIceBow.java @@ -1,37 +1,28 @@ package twilightforest.item; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; import twilightforest.entity.EntityIceArrow; public class ItemTFIceBow extends ItemTFBowBase { - - - public ItemTFIceBow() { - this.setTextureName(TwilightForestMod.ID + ":icebow"); + + public ItemTFIceBow() { this.setCreativeTab(TFItems.creativeTab); - } + } - /** - * Get the arrow for this specific bow - */ - @Override - protected EntityArrow getArrow(World world, EntityPlayer entityPlayer, float velocity) { - return new EntityIceArrow(world, entityPlayer, velocity); + @Override + public EntityArrow customizeArrow(EntityArrow arrow) { + if (arrow.shootingEntity instanceof EntityLivingBase) { + return new EntityIceArrow(arrow.world, (EntityLivingBase) arrow.shootingEntity); + } + return arrow; } - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ice blocks - return par2ItemStack.getItem() == Item.getItemFromBlock(Blocks.ice) ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } + @Override + public boolean getIsRepairable(ItemStack toRepair, ItemStack repairWith) { + return repairWith.getItem() == Item.getItemFromBlock(Blocks.ICE) || super.getIsRepairable(toRepair, repairWith); + } } diff --git a/src/main/java/twilightforest/item/ItemTFIceSword.java b/src/main/java/twilightforest/item/ItemTFIceSword.java index 11e4f7aa0b..beb0b36605 100644 --- a/src/main/java/twilightforest/item/ItemTFIceSword.java +++ b/src/main/java/twilightforest/item/ItemTFIceSword.java @@ -1,72 +1,31 @@ package twilightforest.item; -import twilightforest.TwilightForestMod; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.client.particle.TFParticleType; +import twilightforest.potions.TFPotions; +import twilightforest.util.ParticleHelper; -public class ItemTFIceSword extends ItemSword { +public class ItemTFIceSword extends ItemSword implements ModelRegisterCallback { - public ItemTFIceSword(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFIceSword(Item.ToolMaterial toolMaterial) { + super(toolMaterial); this.setCreativeTab(TFItems.creativeTab); - this.setTextureName(TwilightForestMod.ID + ":iceSword"); } - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with packed ice - return par2ItemStack.getItem() == Item.getItemFromBlock(Blocks.packed_ice) ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } + @Override + public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { + boolean result = super.hitEntity(stack, target, attacker); - /** - * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise - * the damage on the stack. - */ - @Override - public boolean hitEntity(ItemStack par1ItemStack, EntityLivingBase par2EntityLiving, EntityLivingBase par3EntityLiving) { - boolean result = super.hitEntity(par1ItemStack, par2EntityLiving, par3EntityLiving); - - if (result) { - int chillLevel = 2; - par2EntityLiving.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 20 * 10, chillLevel, true)); + if (result && !target.world.isRemote) { + target.addPotionEffect(new PotionEffect(TFPotions.frosty, 20 * 10, 2)); + ParticleHelper.spawnParticles(target, TFParticleType.SNOW, 20); } - + return result; } - - - /** - * Called when the player Left Clicks (attacks) an entity. - * Processed before damage is done, if return value is true further processing is canceled - * and the entity is not attacked. - * - * @param stack The Item being used - * @param player The player that is attacking - * @param entity The entity being attacked - * @return True to cancel the rest of the interaction. - */ - public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) - { - if (player.worldObj.isRemote) { - // snow animation! - for (int var1 = 0; var1 < 20; ++var1) { - double px = entity.posX + itemRand.nextFloat() * entity.width * 2.0F - entity.width; - double py = entity.posY + itemRand.nextFloat() * entity.height; - double pz = entity.posZ + itemRand.nextFloat() * entity.width * 2.0F - entity.width; - TwilightForestMod.proxy.spawnParticle(entity.worldObj, "snowstuff", px, py, pz, 0, 0, 0); - } - } - return false; - } } diff --git a/src/main/java/twilightforest/item/ItemTFIronwoodArmor.java b/src/main/java/twilightforest/item/ItemTFIronwoodArmor.java index ede394840f..3e5b06f63f 100644 --- a/src/main/java/twilightforest/item/ItemTFIronwoodArmor.java +++ b/src/main/java/twilightforest/item/ItemTFIronwoodArmor.java @@ -1,91 +1,52 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.Entity; +import net.minecraft.init.Enchantments; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFIronwoodArmor extends ItemArmor { +public class ItemTFIronwoodArmor extends ItemTFArmor implements ModelRegisterCallback { - public ItemTFIronwoodArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int renderIndex, int armorType) { - super(par2EnumArmorMaterial, renderIndex, armorType); + public ItemTFIronwoodArmor(ArmorMaterial armorMaterial, EntityEquipmentSlot armorType, EnumRarity rarity) { + super(armorMaterial, armorType, rarity); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return an item rarity from EnumRarity - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.uncommon; - } - @Override - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) { - - - if(itemstack.getItem() == TFItems.ironwoodPlate || itemstack.getItem() == TFItems.ironwoodHelm || itemstack.getItem() == TFItems.ironwoodBoots) - { - return TwilightForestMod.ARMOR_DIR + "ironwood_1.png"; - } - if(itemstack.getItem() == TFItems.ironwoodLegs) - { + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + if (slot == EntityEquipmentSlot.LEGS) { return TwilightForestMod.ARMOR_DIR + "ironwood_2.png"; + } else { + return TwilightForestMod.ARMOR_DIR + "ironwood_1.png"; } - return TwilightForestMod.ARMOR_DIR + "ironwood_1.png"; } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - switch (this.armorType) - { - case 0: - istack.addEnchantment(Enchantment.aquaAffinity, 1); - break; - case 1: - istack.addEnchantment(Enchantment.protection, 1); - break; - case 2: - istack.addEnchantment(Enchantment.protection, 1); - break; - case 3: - istack.addEnchantment(Enchantment.featherFalling, 1); - break; - } - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ironwood ingots - return par2ItemStack.getItem() == TFItems.ironwoodIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + switch (this.armorType) { + case HEAD: + istack.addEnchantment(Enchantments.AQUA_AFFINITY, 1); + break; + case CHEST: + istack.addEnchantment(Enchantments.PROTECTION, 1); + break; + case LEGS: + istack.addEnchantment(Enchantments.PROTECTION, 1); + break; + case FEET: + istack.addEnchantment(Enchantments.FEATHER_FALLING, 1); + break; + default: + break; + } + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFIronwoodAxe.java b/src/main/java/twilightforest/item/ItemTFIronwoodAxe.java index 71da9efc40..0393ae9f41 100644 --- a/src/main/java/twilightforest/item/ItemTFIronwoodAxe.java +++ b/src/main/java/twilightforest/item/ItemTFIronwoodAxe.java @@ -1,52 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFIronwoodAxe extends ItemAxe { +public class ItemTFIronwoodAxe extends ItemAxe implements ModelRegisterCallback { - protected ItemTFIronwoodAxe(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFIronwoodAxe(Item.ToolMaterial material) { + super(material, 6F + material.getAttackDamage(), material.getEfficiency() * 0.05f - 3.4f); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.fortune, 1); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ironwood ingots - return par2ItemStack.getItem() == TFItems.ironwoodIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.FORTUNE, 1); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFIronwoodHoe.java b/src/main/java/twilightforest/item/ItemTFIronwoodHoe.java index 30bb13b9fa..a21f7c25d1 100644 --- a/src/main/java/twilightforest/item/ItemTFIronwoodHoe.java +++ b/src/main/java/twilightforest/item/ItemTFIronwoodHoe.java @@ -1,37 +1,13 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.item.Item; import net.minecraft.item.ItemHoe; -import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFIronwoodHoe extends ItemHoe { +public class ItemTFIronwoodHoe extends ItemHoe implements ModelRegisterCallback { - public ItemTFIronwoodHoe(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFIronwoodHoe(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ironwood ingots - return par2ItemStack.getItem() == TFItems.ironwoodIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFIronwoodPick.java b/src/main/java/twilightforest/item/ItemTFIronwoodPick.java index 7a8d6bef03..5b2be13095 100644 --- a/src/main/java/twilightforest/item/ItemTFIronwoodPick.java +++ b/src/main/java/twilightforest/item/ItemTFIronwoodPick.java @@ -1,52 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFIronwoodPick extends ItemPickaxe { +public class ItemTFIronwoodPick extends ItemPickaxe implements ModelRegisterCallback { - protected ItemTFIronwoodPick(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFIronwoodPick(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.efficiency, 1); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ironwood ingots - return par2ItemStack.getItem() == TFItems.ironwoodIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.EFFICIENCY, 1); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFIronwoodShovel.java b/src/main/java/twilightforest/item/ItemTFIronwoodShovel.java index 6255799ab6..f5a6e16f7f 100644 --- a/src/main/java/twilightforest/item/ItemTFIronwoodShovel.java +++ b/src/main/java/twilightforest/item/ItemTFIronwoodShovel.java @@ -1,53 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemSpade; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFIronwoodShovel extends ItemSpade { +public class ItemTFIronwoodShovel extends ItemSpade implements ModelRegisterCallback { - public ItemTFIronwoodShovel(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFIronwoodShovel(Item.ToolMaterial toolMaterial) { + super(toolMaterial); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.unbreaking, 1); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ironwood ingots - return par2ItemStack.getItem() == TFItems.ironwoodIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.UNBREAKING, 1); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFIronwoodSword.java b/src/main/java/twilightforest/item/ItemTFIronwoodSword.java index 66d3ff08fa..46ebd7c507 100644 --- a/src/main/java/twilightforest/item/ItemTFIronwoodSword.java +++ b/src/main/java/twilightforest/item/ItemTFIronwoodSword.java @@ -1,52 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFIronwoodSword extends ItemSword { +public class ItemTFIronwoodSword extends ItemSword implements ModelRegisterCallback { - public ItemTFIronwoodSword(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFIronwoodSword(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.knockback, 1); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ironwood ingots - return par2ItemStack.getItem() == TFItems.ironwoodIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.KNOCKBACK, 1); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFKnightlyArmor.java b/src/main/java/twilightforest/item/ItemTFKnightlyArmor.java index 3856f814a1..86561fc725 100644 --- a/src/main/java/twilightforest/item/ItemTFKnightlyArmor.java +++ b/src/main/java/twilightforest/item/ItemTFKnightlyArmor.java @@ -1,105 +1,47 @@ package twilightforest.item; -import java.util.List; - import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFKnightlyArmor extends ItemArmor { +public class ItemTFKnightlyArmor extends ItemTFArmor implements ModelRegisterCallback { - public ItemTFKnightlyArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int renderIndex, int armorType) { - super(par2EnumArmorMaterial, renderIndex, armorType); + public ItemTFKnightlyArmor(ItemArmor.ArmorMaterial material, EntityEquipmentSlot slot, EnumRarity rarity) { + super(material, slot, rarity); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return an item rarity from EnumRarity - */ @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; - } - - /** - * Called by RenderBiped and RenderPlayer to determine the armor texture that - * should be use for the currently equiped item. - * This will only be called on instances of ItemArmor. - * - * Returning null from this function will use the default value. - * - * @param stack ItemStack for the equpt armor - * @param entity The entity wearing the armor - * @param slot The slot the armor is in - * @param layer The render layer, either 1 or 2, 2 is only used for CLOTH armor by default - * @return Path of texture to bind, or null to use default - */ - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) - { - - if (slot == 2) - { + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + if (slot == EntityEquipmentSlot.LEGS) { return TwilightForestMod.ARMOR_DIR + "knightly_2.png"; - } - else - { + } else { return TwilightForestMod.ARMOR_DIR + "knightly_1.png"; } } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + //istack.addEnchantment(TFEnchantment.reactFire, 2); + list.add(istack); + } + } + @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - //istack.addEnchantment(TFEnchantment.reactFire, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with knightmetal ingots - return par2ItemStack.getItem() == TFItems.knightMetal ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * Override this method to have an item handle its own armor rendering. - * - * @param entityLiving The entity wearing the armor - * @param itemStack The itemStack to render the model of - * @param armorSlot 0=head, 1=torso, 2=legs, 3=feet - * - * @return A ModelBiped to render instead of the default - */ - @SideOnly(Side.CLIENT) - public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) - { - return TwilightForestMod.proxy.getKnightlyArmorModel(armorSlot); - } + @SideOnly(Side.CLIENT) + public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, ModelBiped original) { + return TwilightForestMod.proxy.getKnightlyArmorModel(armorSlot); + } } diff --git a/src/main/java/twilightforest/item/ItemTFKnightlyAxe.java b/src/main/java/twilightforest/item/ItemTFKnightlyAxe.java index 929897713f..9c96c77878 100644 --- a/src/main/java/twilightforest/item/ItemTFKnightlyAxe.java +++ b/src/main/java/twilightforest/item/ItemTFKnightlyAxe.java @@ -1,132 +1,29 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.attributes.AttributeModifier; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumRarity; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; -import net.minecraft.util.StatCollector; -import twilightforest.TwilightForestMod; - -import com.google.common.collect.Multimap; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFKnightlyAxe extends ItemAxe { +import javax.annotation.Nullable; +import java.util.List; - private static final int BONUS_DAMAGE = 2; - private EntityPlayer bonusDamagePlayer; - private Entity bonusDamageEntity; - private float damageVsEntity; +public class ItemTFKnightlyAxe extends ItemAxe implements ModelRegisterCallback { - protected ItemTFKnightlyAxe(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFKnightlyAxe(Item.ToolMaterial material) { + super(material, 6F + material.getAttackDamage(), material.getEfficiency() * 0.05f - 3.4f); this.setCreativeTab(TFItems.creativeTab); - this.damageVsEntity = 4 + par2EnumToolMaterial.getDamageVsEntity(); - } - /** - * Return an item rarity from EnumRarity - * - * This is automatically rare - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with knightmetal ingots - return par2ItemStack.getItem() == TFItems.knightMetal ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Called when the player Left Clicks (attacks) an entity. - * Processed before damage is done, if return value is true further processing is canceled - * and the entity is not attacked. - * - * @param stack The Item being used - * @param player The player that is attacking - * @param entity The entity being attacked - * @return True to cancel the rest of the interaction. - */ - @Override - public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) - { - // extra damage to unarmored target - if (entity instanceof EntityLivingBase && ((EntityLivingBase)entity).getTotalArmorValue() == 0) - { - this.bonusDamageEntity = entity; - this.bonusDamagePlayer = player; - } - - return false; - } - -// /** -// * Returns the damage against a given entity. -// */ -// @Override -// public float getDamageVsEntity(Entity par1Entity, ItemStack itemStack) -// { -// if (this.bonusDamagePlayer != null && this.bonusDamageEntity != null && par1Entity == this.bonusDamageEntity) -// { -// this.bonusDamagePlayer.onEnchantmentCritical(par1Entity); -// this.bonusDamagePlayer = null; -// this.bonusDamageEntity = null; -// return this.damageVsEntity + BONUS_DAMAGE; -// } -// else -// { -// return super.getDamageVsEntity(par1Entity, itemStack); -// } -// } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * allows items to add custom lines of information to the mouseover description - */ @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List tooltips, ITooltipFlag flags) { + super.addInformation(stack, world, tooltips, flags); + tooltips.add(I18n.format(getTranslationKey() + ".tooltip")); } - - - /** - * Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. - */ - public Multimap getItemAttributeModifiers() - { - Multimap multimap = super.getItemAttributeModifiers(); - // remove old damage value - multimap.removeAll(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()); - // add new one - multimap.put(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "Tool modifier", (double)this.damageVsEntity, 0)); - return multimap; - } } diff --git a/src/main/java/twilightforest/item/ItemTFKnightlyPick.java b/src/main/java/twilightforest/item/ItemTFKnightlyPick.java index 38bbe6dd46..1793c35559 100644 --- a/src/main/java/twilightforest/item/ItemTFKnightlyPick.java +++ b/src/main/java/twilightforest/item/ItemTFKnightlyPick.java @@ -1,132 +1,29 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.attributes.AttributeModifier; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumRarity; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.Item; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; -import net.minecraft.util.StatCollector; -import twilightforest.TwilightForestMod; - -import com.google.common.collect.Multimap; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFKnightlyPick extends ItemPickaxe { +import javax.annotation.Nullable; +import java.util.List; - private static final int BONUS_DAMAGE = 2; - private EntityPlayer bonusDamagePlayer; - private Entity bonusDamageEntity; - private float damageVsEntity; +public class ItemTFKnightlyPick extends ItemPickaxe implements ModelRegisterCallback { - protected ItemTFKnightlyPick(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFKnightlyPick(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); - this.damageVsEntity = 4 + par2EnumToolMaterial.getDamageVsEntity(); - - } - - /** - * Return an item rarity from EnumRarity - * - * This is automatically rare - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with knightmetal ingots - return par2ItemStack.getItem() == TFItems.knightMetal ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Called when the player Left Clicks (attacks) an entity. - * Processed before damage is done, if return value is true further processing is canceled - * and the entity is not attacked. - * - * @param stack The Item being used - * @param player The player that is attacking - * @param entity The entity being attacked - * @return True to cancel the rest of the interaction. - */ - @Override - public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) - { - // extra damage to armored targets - if (entity instanceof EntityLivingBase && ((EntityLivingBase)entity).getTotalArmorValue() > 0) - { - this.bonusDamageEntity = entity; - this.bonusDamagePlayer = player; - } - - return false; - } - -// /** -// * Returns the damage against a given entity. -// */ -// @Override -// public float getDamageVsEntity(Entity par1Entity, ItemStack itemStack) -// { -// if (this.bonusDamagePlayer != null && this.bonusDamageEntity != null && par1Entity == this.bonusDamageEntity) -// { -// this.bonusDamagePlayer.onEnchantmentCritical(par1Entity); -// this.bonusDamagePlayer = null; -// this.bonusDamageEntity = null; -// return this.damageVsEntity + BONUS_DAMAGE; -// } -// else -// { -// return super.getDamageVsEntity(par1Entity, itemStack); -// } -// } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * allows items to add custom lines of information to the mouseover description - */ @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List list, ITooltipFlag flags) { + super.addInformation(stack, world, list, flags); + list.add(I18n.format(getTranslationKey() + ".tooltip")); } - - /** - * Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. - */ - public Multimap getItemAttributeModifiers() - { - Multimap multimap = super.getItemAttributeModifiers(); - // remove old damage value - multimap.removeAll(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()); - // add new one - multimap.put(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "Tool modifier", (double)this.damageVsEntity, 0)); - return multimap; - } } diff --git a/src/main/java/twilightforest/item/ItemTFKnightlySword.java b/src/main/java/twilightforest/item/ItemTFKnightlySword.java index 2b13ef6b0c..3a529eddb5 100644 --- a/src/main/java/twilightforest/item/ItemTFKnightlySword.java +++ b/src/main/java/twilightforest/item/ItemTFKnightlySword.java @@ -1,113 +1,58 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.entity.Entity; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import net.minecraft.util.StatCollector; +import net.minecraft.network.play.server.SPacketAnimation; +import net.minecraft.util.DamageSource; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.event.entity.living.LivingAttackEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; + +import javax.annotation.Nullable; +import java.util.List; -public class ItemTFKnightlySword extends ItemSword { +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class ItemTFKnightlySword extends ItemSword implements ModelRegisterCallback { private static final int BONUS_DAMAGE = 2; - private Entity bonusDamageEntity; - private EntityPlayer bonusDamagePlayer; - public ItemTFKnightlySword(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFKnightlySword(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - - /** - * Return an item rarity from EnumRarity - * - * This is automatically rare - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with knightmetal ingots - return par2ItemStack.getItem() == TFItems.knightMetal ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Called when the player Left Clicks (attacks) an entity. - * Processed before damage is done, if return value is true further processing is canceled - * and the entity is not attacked. - * - * @param stack The Item being used - * @param player The player that is attacking - * @param entity The entity being attacked - * @return True to cancel the rest of the interaction. - */ - @Override - public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) - { - // extra damage to armored targets - if (entity instanceof EntityLivingBase && ((EntityLivingBase)entity).getTotalArmorValue() > 0) - { - this.bonusDamageEntity = entity; - this.bonusDamagePlayer = player; - } - - return false; - } - -// /** -// * Returns the damage against a given entity. -// */ -// @Override -// public float getDamageVsEntity(Entity par1Entity, ItemStack itemStack) -// { -// if (this.bonusDamagePlayer != null && this.bonusDamageEntity != null && par1Entity == this.bonusDamageEntity) -// { -// //System.out.println("Minotaur Axe extra damage!"); -// this.bonusDamagePlayer.onEnchantmentCritical(par1Entity); -// this.bonusDamagePlayer = null; -// this.bonusDamageEntity = null; -// return super.getDamageVsEntity(par1Entity, itemStack) + BONUS_DAMAGE; -// } -// else -// { -// return super.getDamageVsEntity(par1Entity, itemStack); -// } -// } + @SubscribeEvent + public static void onDamage(LivingAttackEvent evt) { + EntityLivingBase target = evt.getEntityLiving(); + + if (!target.world.isRemote && evt.getSource().getImmediateSource() instanceof EntityLivingBase) { + ItemStack weapon = ((EntityLivingBase) evt.getSource().getImmediateSource()).getHeldItemMainhand(); + + if (!weapon.isEmpty() && ((target.getTotalArmorValue() > 0 && (weapon.getItem() == TFItems.knightmetal_pickaxe || weapon.getItem() == TFItems.knightmetal_sword)) || (target.getTotalArmorValue() == 0 && weapon.getItem() == TFItems.knightmetal_axe))) { + // TODO scale bonus dmg with the amount of armor? + target.attackEntityFrom(DamageSource.MAGIC, BONUS_DAMAGE); + // don't prevent main damage from applying + target.hurtResistantTime = 0; + // enchantment attack sparkles + ((WorldServer) target.world).getEntityTracker().sendToTrackingAndSelf(target, new SPacketAnimation(target, 5)); + } + } + } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * allows items to add custom lines of information to the mouseover description - */ @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List list, ITooltipFlag flags) { + super.addInformation(stack, world, list, flags); + list.add(I18n.format(getTranslationKey() + ".tooltip")); } } diff --git a/src/main/java/twilightforest/item/ItemTFLampOfCinders.java b/src/main/java/twilightforest/item/ItemTFLampOfCinders.java index cf56478822..151ffbd7af 100644 --- a/src/main/java/twilightforest/item/ItemTFLampOfCinders.java +++ b/src/main/java/twilightforest/item/ItemTFLampOfCinders.java @@ -1,160 +1,130 @@ package twilightforest.item; -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import twilightforest.TFAchievementPage; -import twilightforest.TwilightForestMod; import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class ItemTFLampOfCinders extends ItemTF { +import javax.annotation.Nonnull; +public class ItemTFLampOfCinders extends ItemTF { private static final int FIRING_TIME = 12; - public ItemTFLampOfCinders() { - super(); + ItemTFLampOfCinders(EnumRarity rarity) { + super(rarity); this.setCreativeTab(TFItems.creativeTab); this.maxStackSize = 1; - this.setMaxDamage(1024); + this.setMaxDamage(1024); + } + + @Nonnull + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { + player.setActiveHand(hand); + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - + + @Nonnull @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World world, EntityPlayer player) { - if (par1ItemStack.getItemDamage() < this.getMaxDamage()) - { - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + if (burnBlock(world, pos)) { + if (player instanceof EntityPlayerMP) + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, pos, player.getHeldItem(hand)); + + player.playSound(SoundEvents.ENTITY_GHAST_SHOOT, 0.5F, 1.5F); + + // spawn flame particles + for (int i = 0; i < 10; i++) { + float dx = pos.getX() + 0.5F + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.75F; + float dy = pos.getY() + 0.5F + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.75F; + float dz = pos.getZ() + 0.5F + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.75F; + + world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, dx, dy, dz, 0.0D, 0.0D, 0.0D); + world.spawnParticle(EnumParticleTypes.FLAME, dx, dy, dz, 0.0D, 0.0D, 0.0D); + } + + return EnumActionResult.SUCCESS; + } else { + return EnumActionResult.PASS; } - else - { - player.stopUsingItem(); + } + + private boolean burnBlock(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + if (state.getBlock() == TFBlocks.thorns) { + world.setBlockState(pos, TFBlocks.burnt_thorns.getDefaultState().withProperty(BlockRotatedPillar.AXIS, state.getValue(BlockRotatedPillar.AXIS))); + return true; + } else { + return false; } - return par1ItemStack; } - - - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ + @Override - public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) - { - if (burnBlock(player, world, x, y, z)) { - world.playSoundAtEntity(player, this.getSound(), 0.5F, 1.5F); - - // spawn flame particles - for (int i = 0; i < 10; i++) { - float dx = x + 0.5F + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.75F; - float dy = y + 0.5F + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.75F; - float dz = z + 0.5F + (itemRand.nextFloat() - itemRand.nextFloat()) * 0.75F; - - world.spawnParticle("smoke", dx, dy, dz, 0.0D, 0.0D, 0.0D); - world.spawnParticle("flame", dx, dy, dz, 0.0D, 0.0D, 0.0D); - } - - return true; - } else { - return false; - } - - } + public void onPlayerStoppedUsing(ItemStack stack, World world, EntityLivingBase living, int useRemaining) { + int useTime = this.getMaxItemUseDuration(stack) - useRemaining; - private boolean burnBlock(EntityPlayer player, World world, int x, int y, int z) { - Block block = world.getBlock(x, y, z); - if (block == TFBlocks.thorns) { - world.setBlock(x, y, z, TFBlocks.burntThorns, world.getBlockMetadata(x, y, z) & 12, 2); - return true; - } else { - return false; - } + if (useTime > FIRING_TIME && (stack.getItemDamage() + 1) < this.getMaxDamage(stack)) { + doBurnEffect(world, living); + } } - - - /** - * called when the player releases the use item button. Args: itemstack, world, entityplayer, itemInUseCount - */ - @Override - public void onPlayerStoppedUsing(ItemStack par1ItemStack, World world, EntityPlayer player, int useRemaining) - { - int useTime = this.getMaxItemUseDuration(par1ItemStack) - useRemaining; - - - if (useTime > FIRING_TIME && (par1ItemStack.getItemDamage() + 1) < this.getMaxDamage()) - { - doBurnEffect(world, player); - - // trigger achievement - player.triggerAchievement(TFAchievementPage.twilightProgressTroll); - } - - } - - private void doBurnEffect(World world, EntityPlayer player) { - int px = MathHelper.floor_double(player.lastTickPosX); - int py = MathHelper.floor_double(player.lastTickPosY + player.getEyeHeight()); - int pz = MathHelper.floor_double(player.lastTickPosZ); + + private void doBurnEffect(World world, EntityLivingBase living) { + BlockPos pos = new BlockPos( + MathHelper.floor(living.lastTickPosX), + MathHelper.floor(living.lastTickPosY + living.getEyeHeight()), + MathHelper.floor(living.lastTickPosZ) + ); int range = 4; - + if (!world.isRemote) { - world.playSoundAtEntity(player, this.getSound(), 1.5F, 0.8F); + world.playSound(null, living.posX, living.posY, living.posZ, SoundEvents.ENTITY_GHAST_SHOOT, living.getSoundCategory(), 1.5F, 0.8F); // set nearby thorns to burnt - for (int dx = -range; dx <=range; dx++) { - for (int dy = -range; dy <=range; dy++) { - for (int dz = -range; dz <=range; dz++) { - this.burnBlock(player, world, px + dx, py + dy, pz + dz); + for (int dx = -range; dx <= range; dx++) { + for (int dy = -range; dy <= range; dy++) { + for (int dz = -range; dz <= range; dz++) { + this.burnBlock(world, pos.add(dx, dy, dz)); } } } } - for (int i = 0; i < 6; i++) { - int rx = px + itemRand.nextInt(range) - itemRand.nextInt(range); - int ry = py + itemRand.nextInt(2); - int rz = pz + itemRand.nextInt(range) - itemRand.nextInt(range); + if (living instanceof EntityPlayer) { + for (int i = 0; i < 6; i++) { + BlockPos rPos = pos.add( + itemRand.nextInt(range) - itemRand.nextInt(range), + itemRand.nextInt(2), + itemRand.nextInt(range) - itemRand.nextInt(range) + ); - world.playAuxSFXAtEntity(player, 2004, rx, ry, rz, 0); + world.playEvent((EntityPlayer) living, 2004, rPos, 0); + } } } - - public String getSound() - { - return "mob.ghast.fireball"; + @Override + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BOW; + } + + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 72000; } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.bow; - } - - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } } diff --git a/src/main/java/twilightforest/item/ItemTFMagicBeans.java b/src/main/java/twilightforest/item/ItemTFMagicBeans.java index 0514b2bbe9..db0a05c4e9 100644 --- a/src/main/java/twilightforest/item/ItemTFMagicBeans.java +++ b/src/main/java/twilightforest/item/ItemTFMagicBeans.java @@ -1,167 +1,162 @@ package twilightforest.item; -import twilightforest.block.TFBlocks; -import twilightforest.world.WorldProviderTwilightForest; import net.minecraft.block.Block; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; +import twilightforest.advancements.TFAdvancements; +import twilightforest.block.BlockTFLeaves3; +import twilightforest.block.TFBlocks; +import twilightforest.enums.Leaves3Variant; +import twilightforest.world.WorldProviderTwilightForest; + +import javax.annotation.Nonnull; public class ItemTFMagicBeans extends ItemTF { - - public ItemTFMagicBeans() { - this.makeRare(); - } - - - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ - public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) - { - Block blockAt = world.getBlock(x, y, z); - - int minY = y + 1; - int maxY = Math.max(y + 100, (int) (getCloudHeight(world) + 25)); - if (y < maxY && blockAt == TFBlocks.uberousSoil) { + @Nonnull + @Override + public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { + Block blockAt = world.getBlockState(pos).getBlock(); + int minY = pos.getY() + 1; + int maxY = Math.max(pos.getY() + 100, (int) (getCloudHeight(world) + 25)); + if (pos.getY() < maxY && blockAt == TFBlocks.uberous_soil) { if (!world.isRemote) { - makeHugeStalk(world, x, z, minY, maxY); + ItemStack is = player.getHeldItem(hand); + is.shrink(1); + makeHugeStalk(world, pos, minY, maxY); + + if (player instanceof EntityPlayerMP) + TFAdvancements.ITEM_USE_TRIGGER.trigger((EntityPlayerMP) player, is, world, pos); } - - return true; + + return EnumActionResult.SUCCESS; } else { - return false; + return EnumActionResult.PASS; } - } + } - /** - * Try to find the given world's cloud height - * @param world - * @return - */ + @SuppressWarnings("RedundantCast") private float getCloudHeight(World world) { - if (world.provider instanceof WorldProviderTwilightForest) { // WorldProviderTwilightForest has this method on both server and client - return ((WorldProviderTwilightForest)world.provider).getCloudHeight(); + return ((WorldProviderTwilightForest) world.provider).getCloudHeight(); // This cast is actually needed for some reason, else this will toss a Method Not Found on dedicated servers. } else { - // are we on a dedicated server - //TODO: don't use exceptions for program flow? - try { - return world.provider.getCloudHeight(); - } catch (NoSuchMethodError nsme) { - // this method exists even on a dedicated server - return world.provider.terrainType.getCloudHeight(); - } + // otherwise, world.provider.getCloudHeight() is client only. guess 128 + return 128; } } - private void makeHugeStalk(World world, int x, int z, int minY, int maxY) { + private void makeHugeStalk(World world, BlockPos pos, int minY, int maxY) { + float x = pos.getX(); + float z = pos.getZ(); + int yOffset = world.rand.nextInt(100); - + float cScale = world.rand.nextFloat() * 0.25F + 0.125F; // spiral tightness scaling - float rScale = world.rand.nextFloat() * 0.25F + 0.125F; // radius change scaling - + float rScale = world.rand.nextFloat() * 0.25F + 0.125F; // radius change scaling + // offset x and z to make stalk start at origin float radius = 4F + MathHelper.sin((minY + yOffset) * rScale) * 3F; // make radius a little wavy x -= MathHelper.sin((minY + yOffset) * cScale) * radius; z -= MathHelper.cos((minY + yOffset) * cScale) * radius; - + // leaves! int nextLeafY = minY + 10 + world.rand.nextInt(20); - + // make stalk boolean isClear = true; for (int dy = minY; dy < maxY && isClear; dy++) { // make radius a little wavy - radius = 5F + MathHelper.sin((dy + yOffset) * rScale) * 2.5F; - + radius = 5F + MathHelper.sin((dy + yOffset) * rScale) * 2.5F; + // find center of stalk float cx = x + MathHelper.sin((dy + yOffset) * cScale) * radius; float cz = z + MathHelper.cos((dy + yOffset) * cScale) * radius; - + float stalkThickness = 2.5F; - + // reduce thickness near top if (maxY - dy < 5) { stalkThickness *= (maxY - dy) / 5F; } - int minX = MathHelper.floor_float(x - radius - stalkThickness); - int maxX = MathHelper.ceiling_float_int(x + radius + stalkThickness); - int minZ = MathHelper.floor_float(z - radius - stalkThickness); - int maxZ = MathHelper.ceiling_float_int(z + radius + stalkThickness); - + int minX = MathHelper.floor(x - radius - stalkThickness); + int maxX = MathHelper.ceil(x + radius + stalkThickness); + int minZ = MathHelper.floor(z - radius - stalkThickness); + int maxZ = MathHelper.ceil(z + radius + stalkThickness); + // generate stalk for (int dx = minX; dx < maxX; dx++) { for (int dz = minZ; dz < maxZ; dz++) { if ((dx - cx) * (dx - cx) + (dz - cz) * (dz - cz) < stalkThickness * stalkThickness) { - isClear &= this.tryToPlaceStalk(world, dx, dy, dz); + isClear &= this.tryToPlaceStalk(world, new BlockPos(dx, dy, dz)); } } } - + // leaves? if (dy == nextLeafY) { // make leaf blob - + int lx = (int) (x + MathHelper.sin((dy + yOffset) * cScale) * (radius + stalkThickness)); int lz = (int) (z + MathHelper.cos((dy + yOffset) * cScale) * (radius + stalkThickness)); - - this.placeLeaves(world, lx, dy, lz); - + + this.placeLeaves(world, new BlockPos(lx, dy, lz)); + nextLeafY = dy + 5 + world.rand.nextInt(10); } } } - private void placeLeaves(World world, int x, int y, int z) { + private void placeLeaves(World world, BlockPos pos) { // stalk at center - world.setBlock(x, y, z, TFBlocks.hugeStalk); - + world.setBlockState(pos, TFBlocks.huge_stalk.getDefaultState()); + // small squares for (int dx = -1; dx <= 1; dx++) { for (int dz = -1; dz <= 1; dz++) { - this.tryToPlaceLeaves(world, x + dx, y - 1, z + dz); - this.tryToPlaceLeaves(world, x + dx, y + 1, z + dz); + this.tryToPlaceLeaves(world, pos.add(dx, -1, dz)); + this.tryToPlaceLeaves(world, pos.add(dx, 1, dz)); } } // larger square for (int dx = -2; dx <= 2; dx++) { for (int dz = -2; dz <= 2; dz++) { if (!((dx == 2 || dx == -2) && (dz == 2 || dz == -2))) { - this.tryToPlaceLeaves(world, x + dx, y + 0, z + dz); + this.tryToPlaceLeaves(world, pos.add(dx, 0, dz)); } } } } - /** * Place the stalk block only if the destination is clear. Return false if blocked. */ - private boolean tryToPlaceStalk(World world, int x, int y, int z) { - Block blockThere = world.getBlock(x, y, z); - if (blockThere == Blocks.air || blockThere.isReplaceable(world, x, y, z) || blockThere.canBeReplacedByLeaves(world, x, y, z) || blockThere.isLeaves(world, x, y, z) || blockThere.canSustainLeaves(world, x, y, z)) { - world.setBlock(x, y, z, TFBlocks.hugeStalk); + private boolean tryToPlaceStalk(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + if (state.getBlock().isAir(state, world, pos) || state.getBlock().isReplaceable(world, pos) || state.getBlock().canBeReplacedByLeaves(state, world, pos) || state.getBlock().isLeaves(state, world, pos) || state.getBlock().canSustainLeaves(state, world, pos)) { + world.setBlockState(pos, TFBlocks.huge_stalk.getDefaultState()); return true; } else { return false; } } - - private void tryToPlaceLeaves(World world, int x, int y, int z) { - Block blockThere = world.getBlock(x, y, z); - if (blockThere == Blocks.air || blockThere.canBeReplacedByLeaves(world, x, y, z)) { - world.setBlock(x, y, z, TFBlocks.leaves3, 1, 2); + private void tryToPlaceLeaves(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + if (state.getBlock().isAir(state, world, pos) || state.getBlock().canBeReplacedByLeaves(state, world, pos)) { + world.setBlockState(pos, TFBlocks.twilight_leaves_3.getDefaultState().withProperty(BlockTFLeaves3.VARIANT, Leaves3Variant.BEANSTALK).withProperty(BlockLeaves.CHECK_DECAY, false), 2); } } - } diff --git a/src/main/java/twilightforest/item/ItemTFMagicMap.java b/src/main/java/twilightforest/item/ItemTFMagicMap.java index 567ffb11b3..190ac6debc 100644 --- a/src/main/java/twilightforest/item/ItemTFMagicMap.java +++ b/src/main/java/twilightforest/item/ItemTFMagicMap.java @@ -1,290 +1,220 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.material.MapColor; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumRarity; +import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; import net.minecraft.network.Packet; -import net.minecraft.util.MathHelper; -import net.minecraft.util.StatCollector; +import net.minecraft.network.play.server.SPacketMaps; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.storage.MapData.MapInfo; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.storage.MapData; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TFFeature; import twilightforest.TFMagicMapData; -import twilightforest.TFMapPacketHandler; -import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; -import twilightforest.world.TFWorldChunkManager; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class ItemTFMagicMap extends ItemMap -{ - public static final String STR_ID = "magicmap"; - - protected ItemTFMagicMap() - { - super(); - } - - @SideOnly(Side.CLIENT) - public static TFMagicMapData getMPMapData(int par0, World par1World) - { - String mapName = STR_ID + "_" + par0; - TFMagicMapData mapData = (TFMagicMapData)par1World.loadItemData(TFMagicMapData.class, mapName); - - if (mapData == null) - { - mapData = new TFMagicMapData(mapName); - par1World.setItemData(mapName, mapData); - } - - return mapData; - } - - @Override - public TFMagicMapData getMapData(ItemStack par1ItemStack, World par2World) - { - String mapName = STR_ID + "_" + par1ItemStack.getItemDamage(); - TFMagicMapData mapData = (TFMagicMapData)par2World.loadItemData(TFMagicMapData.class, mapName); - - if (mapData == null && !par2World.isRemote) - { - par1ItemStack.setItemDamage(par2World.getUniqueDataId(STR_ID)); - mapName = STR_ID + "_" + par1ItemStack.getItemDamage(); - mapData = new TFMagicMapData(mapName); - mapData.xCenter = par2World.getWorldInfo().getSpawnX(); - mapData.zCenter = par2World.getWorldInfo().getSpawnZ(); - mapData.scale = 4; - mapData.dimension = par2World.provider.dimensionId; - mapData.markDirty(); - par2World.setItemData(mapName, mapData); - } - - return mapData; - } - - public void updateMapData(World par1World, Entity par2Entity, TFMagicMapData par3MapData) - { - if (par1World.provider.dimensionId == par3MapData.dimension && par2Entity instanceof EntityPlayer) - { - short xSize = 128; - short zSize = 128; - int scaleFactor = 1 << par3MapData.scale; - int xCenter = par3MapData.xCenter; - int zCenter = par3MapData.zCenter; - int xDraw = MathHelper.floor_double(par2Entity.posX - (double)xCenter) / scaleFactor + xSize / 2; - int zDraw = MathHelper.floor_double(par2Entity.posZ - (double)zCenter) / scaleFactor + zSize / 2; - int drawSize = 512 / scaleFactor; -// int drawSize = 1024 / scaleFactor; - - MapInfo mapInfo = par3MapData.func_82568_a((EntityPlayer)par2Entity); - ++mapInfo.field_82569_d; - - for (int xStep = xDraw - drawSize + 1; xStep < xDraw + drawSize; ++xStep) - { - if ((xStep & 15) == (mapInfo.field_82569_d & 15)) - { - int highNumber = 255; - int lowNumber = 0; - - for (int zStep = zDraw - drawSize - 1; zStep < zDraw + drawSize; ++zStep) - { - if (xStep >= 0 && zStep >= -1 && xStep < xSize && zStep < zSize) - { - int xOffset = xStep - xDraw; - int zOffset = zStep - zDraw; - boolean var20 = xOffset * xOffset + zOffset * zOffset > (drawSize - 2) * (drawSize - 2); - int xDraw2 = (xCenter / scaleFactor + xStep - xSize / 2) * scaleFactor; - int zDraw2 = (zCenter / scaleFactor + zStep - zSize / 2) * scaleFactor; - int[] biomeFrequencies = new int[256]; - int zStep2; - int xStep2; - - - int biomeID; - - - for (xStep2 = 0; xStep2 < scaleFactor; ++xStep2) - { - for (zStep2 = 0; zStep2 < scaleFactor; ++zStep2) - { - biomeID = par1World.getBiomeGenForCoords(xDraw2 + xStep2, zDraw2 + zStep2).biomeID; - - biomeFrequencies[biomeID]++; - - // make rivers and streams 3x more prominent - if (biomeID == BiomeGenBase.river.biomeID || biomeID == TFBiomeBase.stream.biomeID) { - biomeFrequencies[biomeID] += 2; - } - // add in TF features - if (par1World.getWorldChunkManager() instanceof TFWorldChunkManager) - { - TFWorldChunkManager tfManager = (TFWorldChunkManager) par1World.getWorldChunkManager(); - - if (tfManager.isInFeatureChunk(par1World, xDraw2 + xStep2, zDraw2 + zStep2) && zStep >= 0 && xOffset * xOffset + zOffset * zOffset < drawSize * drawSize) - { - par3MapData.addFeatureToMap(TFFeature.getNearestFeature((xDraw2 + xStep2) >> 4, (zDraw2 + zStep2) >> 4, par1World), xDraw2, zDraw2); - } - } - -// // mark features we find into the mapdata, provided they are within our draw area -// if (biomeID == TFBiomeBase.majorFeature.biomeID && zStep >= 0 && xOffset * xOffset + zOffset * zOffset < drawSize * drawSize) { -// par3MapData.addFeatureToMap(TFFeature.getNearestFeature((xDraw2 + xStep2) >> 4, (zDraw2 + zStep2) >> 4, par1World), xDraw2, zDraw2); -//// biomeFrequencies[biomeID] += 4096; // don't bother, now the icon will show -// } - -// // mark features we find into the mapdata, provided they are within our draw area -// if (biomeID == TFBiomeBase.minorFeature.biomeID) { -// biomeFrequencies[biomeID] += 4096; // don't bother, now the icon will show -// } - } - } - - // figure out which color is the most prominent and make that one appear on the map - byte biomeIDToShow = 0; - int highestFrequency = 0; - - for (int i = 0; i < 256; i++) { - if (biomeFrequencies[i] > highestFrequency) - { - biomeIDToShow = (byte)i; - highestFrequency = biomeFrequencies[i]; - } - } - - // increase biomeID by one so we can properly show oceans - biomeIDToShow++; - - if (zStep >= 0 && xOffset * xOffset + zOffset * zOffset < drawSize * drawSize && (!var20 || (xStep + zStep & 1) != 0)) - { - byte existingColor = par3MapData.colors[xStep + zStep * xSize]; - - if (existingColor != biomeIDToShow) - { - if (highNumber > zStep) - { - highNumber = zStep; - } +import twilightforest.network.TFPacketHandler; +import twilightforest.biomes.TFBiomes; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.network.PacketMagicMap; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + +public class ItemTFMagicMap extends ItemMap implements ModelRegisterCallback { + public static final String STR_ID = "magicmap"; + private static final Map BIOME_COLORS = new HashMap<>(); + + private static class MapColorBrightness { + public MapColor color; + public int brightness; + + public MapColorBrightness(MapColor color, int brightness) { + this.color = color; + this.brightness = brightness; + } + + public MapColorBrightness(MapColor color) { + this.color = color; + this.brightness = 1; + } + } - if (lowNumber < zStep) - { - lowNumber = zStep; - } + // [VanillaCopy] super with own id + public static ItemStack setupNewMap(World world, double worldX, double worldZ, byte scale, boolean trackingPosition, boolean unlimitedTracking) { + // TF - own item and string id + ItemStack itemstack = new ItemStack(TFItems.magic_map, 1, world.getUniqueDataId(ItemTFMagicMap.STR_ID)); + String s = ItemTFMagicMap.STR_ID + "_" + itemstack.getMetadata(); + MapData mapdata = new TFMagicMapData(s); + world.setData(s, mapdata); + mapdata.scale = scale; + mapdata.calculateMapCenter(worldX, worldZ, mapdata.scale); + mapdata.dimension = world.provider.getDimension(); + mapdata.trackingPosition = trackingPosition; + mapdata.unlimitedTracking = unlimitedTracking; + mapdata.markDirty(); + return itemstack; + } - par3MapData.colors[xStep + zStep * xSize] = biomeIDToShow; - } - } - } - } + // [VanillaCopy] super, with own string ID and class, narrowed types + @Nullable + @SideOnly(Side.CLIENT) + public static TFMagicMapData loadMapData(int mapId, World worldIn) { + String s = STR_ID + "_" + mapId; + return (TFMagicMapData) worldIn.loadData(TFMagicMapData.class, s); + } - if (highNumber <= lowNumber) - { - par3MapData.setColumnDirty(xStep, highNumber, lowNumber); - } - } - } - } - } - - /** - * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and - * update it's contents. - */ - public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) - { - if (!par2World.isRemote) - { - TFMagicMapData mapData = this.getMapData(par1ItemStack, par2World); + // [VanillaCopy] super, with own string ID and class + @Override + public TFMagicMapData getMapData(ItemStack stack, World worldIn) { + String s = STR_ID + "_" + stack.getMetadata(); + TFMagicMapData mapdata = (TFMagicMapData) worldIn.loadData(TFMagicMapData.class, s); + + if (mapdata == null && !worldIn.isRemote) { + stack.setItemDamage(worldIn.getUniqueDataId(STR_ID)); + s = STR_ID + "_" + stack.getMetadata(); + mapdata = new TFMagicMapData(s); + mapdata.scale = 3; + mapdata.calculateMapCenter((double) worldIn.getWorldInfo().getSpawnX(), (double) worldIn.getWorldInfo().getSpawnZ(), mapdata.scale); + mapdata.dimension = worldIn.provider.getDimension(); + mapdata.markDirty(); + worldIn.setData(s, mapdata); + } + + return mapdata; + } - if (par3Entity instanceof EntityPlayer) - { - EntityPlayer var7 = (EntityPlayer)par3Entity; - mapData.updateVisiblePlayers(var7, par1ItemStack); - } + @Override + public void updateMapData(World world, Entity viewer, MapData data) { + if (world.provider.getDimension() == data.dimension && viewer instanceof EntityPlayer) { + int biomesPerPixel = 4; + int blocksPerPixel = 16; // don't even bother with the scale, just hardcode it + int centerX = data.xCenter; + int centerZ = data.zCenter; + int viewerX = MathHelper.floor(viewer.posX - (double) centerX) / blocksPerPixel + 64; + int viewerZ = MathHelper.floor(viewer.posZ - (double) centerZ) / blocksPerPixel + 64; + int viewRadiusPixels = 512 / blocksPerPixel; + + // use the generation map, which is larger scale than the other biome map + int startX = (centerX / blocksPerPixel - 64) * biomesPerPixel; + int startZ = (centerZ / blocksPerPixel - 64) * biomesPerPixel; + Biome[] biomes = world.getBiomeProvider().getBiomesForGeneration((Biome[]) null, startX, startZ, 128 * biomesPerPixel, 128 * biomesPerPixel); + + for (int xPixel = viewerX - viewRadiusPixels + 1; xPixel < viewerX + viewRadiusPixels; ++xPixel) { + for (int zPixel = viewerZ - viewRadiusPixels - 1; zPixel < viewerZ + viewRadiusPixels; ++zPixel) { + if (xPixel >= 0 && zPixel >= 0 && xPixel < 128 && zPixel < 128) { + int xPixelDist = xPixel - viewerX; + int zPixelDist = zPixel - viewerZ; + boolean shouldFuzz = xPixelDist * xPixelDist + zPixelDist * zPixelDist > (viewRadiusPixels - 2) * (viewRadiusPixels - 2); + + Biome biome = biomes[xPixel * biomesPerPixel + zPixel * biomesPerPixel * 128 * biomesPerPixel]; + + // make streams more visible + Biome overBiome = biomes[xPixel * biomesPerPixel + zPixel * biomesPerPixel * 128 * biomesPerPixel + 1]; + Biome downBiome = biomes[xPixel * biomesPerPixel + (zPixel * biomesPerPixel + 1) * 128 * biomesPerPixel]; + if (overBiome == TFBiomes.stream || downBiome == TFBiomes.stream) { + biome = TFBiomes.stream; + } + + MapColorBrightness colorBrightness = this.getMapColorPerBiome(world, biome); + + MapColor mapcolor = colorBrightness.color; + int brightness = colorBrightness.brightness; + + if (zPixel >= 0 && xPixelDist * xPixelDist + zPixelDist * zPixelDist < viewRadiusPixels * viewRadiusPixels && (!shouldFuzz || (xPixel + zPixel & 1) != 0)) { + byte orgPixel = data.colors[xPixel + zPixel * 128]; + byte ourPixel = (byte) (mapcolor.colorIndex * 4 + brightness); + + if (orgPixel != ourPixel) { + data.colors[xPixel + zPixel * 128] = ourPixel; + data.updateMapData(xPixel, zPixel); + } + + // look for TF features + int worldX = (centerX / blocksPerPixel + xPixel - 64) * blocksPerPixel; + int worldZ = (centerZ / blocksPerPixel + zPixel - 64) * blocksPerPixel; + if (TFFeature.isInFeatureChunk(world, worldX, worldZ)) { + byte mapX = (byte) ((worldX - centerX) / (float) blocksPerPixel * 2F); + byte mapZ = (byte) ((worldZ - centerZ) / (float) blocksPerPixel * 2F); + TFFeature feature = TFFeature.getFeatureAt(worldX, worldZ, world); + TFMagicMapData tfData = (TFMagicMapData) data; + tfData.tfDecorations.add(new TFMagicMapData.TFMapDecoration(feature.ordinal(), mapX, mapZ, (byte) 8)); + //TwilightForestMod.LOGGER.info("Found feature at {}, {}. Placing it on the map at {}, {}", worldX, worldZ, mapX, mapZ); + } + } + } + } + } + } + } - if (par5) - { - this.updateMapData(par2World, par3Entity, mapData); - } - } - } + private MapColorBrightness getMapColorPerBiome(World world, Biome biome) { + if (BIOME_COLORS.isEmpty()) { + setupBiomeColors(); + } + MapColorBrightness color = BIOME_COLORS.get(biome.getRegistryName()); + if (color != null) { + return color; + } else { + return new MapColorBrightness(biome.topBlock.getMapColor(world, BlockPos.ORIGIN)); + } + } - /** - * Called when item is crafted/smelted. Used only by maps so far. - */ - @Override - public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) - { - // we don't need to do anything here, I think - } - - /** - * Return an item rarity from EnumRarity - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.uncommon; + private static void setupBiomeColors() { + putBiomeColor(TFBiomes.twilightForest, new MapColorBrightness(MapColor.FOLIAGE, 1)); + putBiomeColor(TFBiomes.denseTwilightForest, new MapColorBrightness(MapColor.FOLIAGE, 0)); + putBiomeColor(TFBiomes.tfLake, new MapColorBrightness(MapColor.WATER, 3)); + putBiomeColor(TFBiomes.stream, new MapColorBrightness(MapColor.WATER, 1)); + putBiomeColor(TFBiomes.tfSwamp, new MapColorBrightness(MapColor.DIAMOND, 3)); + putBiomeColor(TFBiomes.fireSwamp, new MapColorBrightness(MapColor.NETHERRACK, 1)); + putBiomeColor(TFBiomes.clearing, new MapColorBrightness(MapColor.GRASS, 2)); + putBiomeColor(TFBiomes.oakSavanna, new MapColorBrightness(MapColor.GRASS, 0)); + putBiomeColor(TFBiomes.highlands, new MapColorBrightness(MapColor.DIRT, 0)); + putBiomeColor(TFBiomes.thornlands, new MapColorBrightness(MapColor.WOOD, 3)); + putBiomeColor(TFBiomes.highlandsCenter, new MapColorBrightness(MapColor.SILVER, 2)); + putBiomeColor(TFBiomes.fireflyForest, new MapColorBrightness(MapColor.EMERALD, 1)); + putBiomeColor(TFBiomes.darkForest, new MapColorBrightness(MapColor.GREEN, 3)); + putBiomeColor(TFBiomes.darkForestCenter, new MapColorBrightness(MapColor.ADOBE, 3)); + putBiomeColor(TFBiomes.snowy_forest, new MapColorBrightness(MapColor.SNOW, 1)); + putBiomeColor(TFBiomes.glacier, new MapColorBrightness(MapColor.ICE, 1)); + putBiomeColor(TFBiomes.mushrooms, new MapColorBrightness(MapColor.ADOBE, 0)); + putBiomeColor(TFBiomes.deepMushrooms, new MapColorBrightness(MapColor.PINK, 0)); + putBiomeColor(TFBiomes.enchantedForest, new MapColorBrightness(MapColor.LIME, 2)); + putBiomeColor(TFBiomes.spookyForest, new MapColorBrightness(MapColor.PURPLE, 0)); } - /** - * Do the enchanted shimmer thing - */ - @Override - public boolean hasEffect(ItemStack par1ItemStack) - { - return false; - } + private static void putBiomeColor(Biome biome, MapColorBrightness color) { + BIOME_COLORS.put(biome.getRegistryName(), color); + } - /** - * returns null if no update is to be sent - * - * We have re-written this to provide a Packet250CustomPayload to be sent, since the map data packet is only for the actual map map. - * - * Also every 4 player update packets we send is actually a feature icon update packet. - */ @Override - public Packet func_150911_c(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) - { -// System.out.println("Getting magic map packet"); - - byte[] mapBytes = this.getMapData(par1ItemStack, par2World).getUpdatePacketData(par1ItemStack, par2World, par3EntityPlayer); - - if (mapBytes == null) { - return null; - } - else { - // hijack random player data packets for our feature data packets? - if (mapBytes[0] == 1 && par2World.rand.nextInt(4) == 0) { - this.getMapData(par1ItemStack, par2World).checkExistingFeatures(par2World); - mapBytes = this.getMapData(par1ItemStack, par2World).makeFeatureStorageArray(); - } - - //short mapItemID = (short) TFItems.magicMap; - short uniqueID = (short)par1ItemStack.getItemDamage(); - - return TFMapPacketHandler.makeMagicMapPacket(ItemTFMagicMap.STR_ID, uniqueID, mapBytes); - } - } + public void onCreated(ItemStack stack, World world, EntityPlayer player) { + // disable zooming + } - /** - * Add the map number to the tooltip - */ - public String getItemStackDisplayName(ItemStack par1ItemStack) - { - return ("" + StatCollector.translateToLocal(this.getUnlocalizedNameInefficiently(par1ItemStack) + ".name") + " #" + par1ItemStack.getItemDamage()).trim(); - } + @Override + @Nullable + public Packet createMapDataPacket(ItemStack stack, World world, EntityPlayer player) { + Packet p = super.createMapDataPacket(stack, world, player); + if (p instanceof SPacketMaps) { + TFMagicMapData mapdata = getMapData(stack, world); + return TFPacketHandler.CHANNEL.getPacketFrom(new PacketMagicMap(stack.getItemDamage(), mapdata, (SPacketMaps) p)); + } else { + return p; + } + } - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomMeshDefinition(this, stack -> new ModelResourceLocation(getRegistryName(), "inventory")); + } } diff --git a/src/main/java/twilightforest/item/ItemTFMazeMap.java b/src/main/java/twilightforest/item/ItemTFMazeMap.java index f22afdc804..27450fa3a7 100644 --- a/src/main/java/twilightforest/item/ItemTFMazeMap.java +++ b/src/main/java/twilightforest/item/ItemTFMazeMap.java @@ -1,8 +1,14 @@ package twilightforest.item; -import net.minecraft.block.Block; +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multiset; +import com.google.common.collect.Multisets; +import net.minecraft.block.BlockDirt; +import net.minecraft.block.BlockStone; import net.minecraft.block.material.MapColor; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; @@ -10,317 +16,282 @@ import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; import net.minecraft.network.Packet; -import net.minecraft.util.MathHelper; -import net.minecraft.util.StatCollector; +import net.minecraft.network.play.server.SPacketMaps; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.storage.MapData.MapCoord; -import net.minecraft.world.storage.MapData.MapInfo; -import twilightforest.TFMapPacketHandler; +import net.minecraft.world.storage.MapData; +import net.minecraft.world.storage.MapDecoration; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TFMazeMapData; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.network.TFPacketHandler; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.network.PacketMazeMap; -public class ItemTFMazeMap extends ItemMap -{ - public static final String STR_ID = "mazemap"; +import javax.annotation.Nullable; + +public class ItemTFMazeMap extends ItemMap implements ModelRegisterCallback { + + public static final String STR_ID = "mazemap"; private static final int YSEARCH = 3; - protected boolean mapOres; - - protected ItemTFMazeMap(boolean par2MapOres) - { - super(); - this.mapOres = par2MapOres; - //this.setCreativeTab(TFItems.creativeTab); - } - - @SideOnly(Side.CLIENT) - public static TFMazeMapData getMPMapData(int par0, World par1World) - { - String mapName = STR_ID + "_" + par0; - - TFMazeMapData mapData = (TFMazeMapData)par1World.loadItemData(TFMazeMapData.class, mapName); - - //System.out.println("Incoming maze data! = " + mapData); - - if (mapData == null) - { - mapData = new TFMazeMapData(mapName); - par1World.setItemData(mapName, mapData); - } - - return mapData; - } - - @Override - public TFMazeMapData getMapData(ItemStack par1ItemStack, World par2World) - { - TFMazeMapData mapData = (TFMazeMapData)par2World.loadItemData(TFMazeMapData.class, STR_ID + "_" + par1ItemStack.getItemDamage()); - - if (mapData == null && !par2World.isRemote) - { - par1ItemStack.setItemDamage(par2World.getUniqueDataId(STR_ID)); - String mapName = STR_ID + "_" + par1ItemStack.getItemDamage(); - mapData = new TFMazeMapData(mapName); - mapData.xCenter = par2World.getWorldInfo().getSpawnX(); - mapData.zCenter = par2World.getWorldInfo().getSpawnZ(); - mapData.scale = 0; - mapData.dimension = par2World.provider.dimensionId; - mapData.markDirty(); - par2World.setItemData(mapName, mapData); - } - - return mapData; - } - - /** - * Maze map update data. Look at scale 0 for walls, and maybe ores. - */ - public void updateMapData(World par1World, Entity par2Entity, TFMazeMapData par3MapData) - { - int yDraw = MathHelper.floor_double(par2Entity.posY - (double)par3MapData.yCenter); - - if (par1World.provider.dimensionId == par3MapData.dimension && yDraw > -YSEARCH && yDraw < YSEARCH) - { - short xSize = 128; - short zSize = 128; - int xCenter = par3MapData.xCenter; - int zCenter = par3MapData.zCenter; - int xDraw = MathHelper.floor_double(par2Entity.posX - (double)xCenter) + xSize / 2; - int zDraw = MathHelper.floor_double(par2Entity.posZ - (double)zCenter) + zSize / 2; - int drawSize = 16; - - MapInfo mapInfo = par3MapData.func_82568_a((EntityPlayer)par2Entity); - ++mapInfo.field_82569_d; - - for (int xStep = xDraw - drawSize + 1; xStep < xDraw + drawSize; ++xStep) - { - if ((xStep & 15) == (mapInfo.field_82569_d & 15)) - { - int highNumber = 255; - int lowNumber = 0; - - for (int zStep = zDraw - drawSize - 1; zStep < zDraw + drawSize; ++zStep) - { - if (xStep >= 0 && zStep >= -1 && xStep < xSize && zStep < zSize) - { - int xOffset = xStep - xDraw; - int zOffset = zStep - zDraw; - boolean var20 = xOffset * xOffset + zOffset * zOffset > (drawSize - 2) * (drawSize - 2); - int xDraw2 = (xCenter + xStep - xSize / 2); - int zDraw2 = (zCenter + zStep - zSize / 2); - Chunk chunk = par1World.getChunkFromBlockCoords(xDraw2, zDraw2); - int x15 = xDraw2 & 15; - int z15 = zDraw2 & 15; - int heightValue; - int colorIndex; - - heightValue = par3MapData.yCenter; - Block blockID = chunk.getBlock(x15, heightValue, z15); - - byte tint = 1; - - colorIndex = 0; - - // for stone, search up and down for ores - - if (blockID == Blocks.stone && mapOres) { - for (int i = -YSEARCH; i <= YSEARCH; i++) { - Block searchID = chunk.getBlock(x15, heightValue + i, z15); - if (searchID != Blocks.stone) { - blockID = searchID; - if (i > 0) { - tint = 2; - } - if (i < 0) { - tint = 0; - } - // stop searching - break; - } - } - - - } - - - if (blockID != Blocks.air) - { - MapColor mapColor = blockID.getMaterial().getMaterialMapColor(); - colorIndex = mapColor.colorIndex; - } - - if (mapOres) { - // need to reobfuscate - // recolor ores - if (blockID == Blocks.coal_ore) { - colorIndex = MapColor.obsidianColor.colorIndex; - } - else if (blockID == Blocks.gold_ore) { - colorIndex = MapColor.goldColor.colorIndex; - } - else if (blockID == Blocks.iron_ore) { - colorIndex = MapColor.ironColor.colorIndex; - } - else if (blockID == Blocks.lapis_ore) { - colorIndex = MapColor.lapisColor.colorIndex; - } - else if (blockID == Blocks.redstone_ore || blockID == Blocks.lit_redstone_ore) { - colorIndex = MapColor.redColor.colorIndex; - } - else if (blockID == Blocks.diamond_ore) { - colorIndex = MapColor.diamondColor.colorIndex; - } - else if (blockID == Blocks.emerald_ore) { - colorIndex = MapColor.emeraldColor.colorIndex; - } - else if (blockID != Blocks.air && blockID.getUnlocalizedName().toLowerCase().contains("ore")) - { - // any other ore, catchall - colorIndex = MapColor.pinkColor.colorIndex; - } - } - - if (zStep >= 0 && xOffset * xOffset + zOffset * zOffset < drawSize * drawSize && (!var20 || (xStep + zStep & 1) != 0)) - { - byte existingColor = par3MapData.colors[xStep + zStep * xSize]; - byte tintedColor = (byte)(colorIndex * 4 + tint); - - if (existingColor != tintedColor) + + protected final boolean mapOres; + + protected ItemTFMazeMap(boolean mapOres) { + this.mapOres = mapOres; + } + + // [VanillaCopy] super with own item and id, and y parameter, also whether we have an ore map or not + public static ItemStack setupNewMap(World world, double worldX, double worldZ, byte scale, boolean trackingPosition, boolean unlimitedTracking, double worldY, boolean mapOres) { + ItemStack itemstack = new ItemStack(mapOres ? TFItems.ore_map : TFItems.maze_map, 1, world.getUniqueDataId(STR_ID)); + String s = STR_ID + "_" + itemstack.getMetadata(); + TFMazeMapData mapdata = new TFMazeMapData(s); + world.setData(s, mapdata); + mapdata.scale = scale; + mapdata.calculateMapCenter(world, worldX, worldY, worldZ, scale); // TF custom method here + mapdata.dimension = world.provider.getDimension(); + mapdata.trackingPosition = trackingPosition; + mapdata.unlimitedTracking = unlimitedTracking; + mapdata.markDirty(); + return itemstack; + } + + // [VanillaCopy] super, with own string ID and class, narrowed types + @Nullable + @SideOnly(Side.CLIENT) + public static TFMazeMapData loadMapData(int mapId, World world) { + String s = STR_ID + "_" + mapId; + return (TFMazeMapData) world.loadData(TFMazeMapData.class, s); + } + + // [VanillaCopy] super, with own string ID and class + @Override + public TFMazeMapData getMapData(ItemStack stack, World worldIn) { + String s = STR_ID + "_" + stack.getMetadata(); + TFMazeMapData mapdata = (TFMazeMapData) worldIn.loadData(TFMazeMapData.class, s); + + if (mapdata == null && !worldIn.isRemote) { + stack.setItemDamage(worldIn.getUniqueDataId(STR_ID)); + s = STR_ID + "_" + stack.getMetadata(); + mapdata = new TFMazeMapData(s); + mapdata.scale = 0; // TF - fix scale at 0 + mapdata.calculateMapCenter((double) worldIn.getWorldInfo().getSpawnX(), (double) worldIn.getWorldInfo().getSpawnZ(), mapdata.scale); + mapdata.dimension = worldIn.provider.getDimension(); + mapdata.markDirty(); + worldIn.setData(s, mapdata); + } + + return mapdata; + } + + // [VanillaCopy] of superclass, with sane variable names and noted changes + @SuppressWarnings("unused") + @Override + public void updateMapData(World world, Entity viewer, MapData data) { + if (world.provider.getDimension() == data.dimension && viewer instanceof EntityPlayer) { + int blocksPerPixel = 1 << data.scale; + int centerX = data.xCenter; + int centerZ = data.zCenter; + int viewerX = MathHelper.floor(viewer.posX - (double) centerX) / blocksPerPixel + 64; + int viewerZ = MathHelper.floor(viewer.posZ - (double) centerZ) / blocksPerPixel + 64; + int viewRadiusPixels = 16; // TF this is smaller on the maze map + + if (world.provider.isNether()) { + viewRadiusPixels /= 2; + } + + MapData.MapInfo mapdata$mapinfo = data.getMapInfo((EntityPlayer) viewer); + ++mapdata$mapinfo.step; + boolean flag = false; + + for (int xPixel = viewerX - viewRadiusPixels + 1; xPixel < viewerX + viewRadiusPixels; ++xPixel) { + if ((xPixel & 15) == (mapdata$mapinfo.step & 15) || flag) { + flag = false; + double d0 = 0.0D; + + for (int zPixel = viewerZ - viewRadiusPixels - 1; zPixel < viewerZ + viewRadiusPixels; ++zPixel) { + if (xPixel >= 0 && zPixel >= -1 && xPixel < 128 && zPixel < 128) { + int xPixelDist = xPixel - viewerX; + int zPixelDist = zPixel - viewerZ; + boolean shouldFuzz = xPixelDist * xPixelDist + zPixelDist * zPixelDist > (viewRadiusPixels - 2) * (viewRadiusPixels - 2); + int worldX = (centerX / blocksPerPixel + xPixel - 64) * blocksPerPixel; + int worldZ = (centerZ / blocksPerPixel + zPixel - 64) * blocksPerPixel; + Multiset multiset = HashMultiset.create(); + Chunk chunk = world.getChunk(new BlockPos(worldX, 0, worldZ)); + + int brightness = 1; + if (!chunk.isEmpty()) { + int worldXRounded = worldX & 15; + int worldZRounded = worldZ & 15; + int numLiquid = 0; + double d1 = 0.0D; + + if (world.provider.isNether()) { + int l3 = worldX + worldZ * 231871; + l3 = l3 * l3 * 31287121 + l3 * 11; + + if ((l3 >> 20 & 1) == 0) { + multiset.add(Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.DIRT).getMapColor(world, BlockPos.ORIGIN), 10); + } else { + multiset.add(Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.STONE).getMapColor(world, BlockPos.ORIGIN), 100); + } + + d1 = 100.0D; + } else { + // TF - remove extra 2 levels of loops + // maze maps are always 0 scale, which is 1 pixel = 1 block, so the loops are unneeded + int yCenter = ((TFMazeMapData) data).yCenter; + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(worldXRounded, yCenter, worldZRounded); + IBlockState state = chunk.getBlockState(blockpos$mutableblockpos); + + multiset.add(state.getMapColor(world, blockpos$mutableblockpos)); + + if (state.getBlock() == Blocks.STONE || state.getBlock() == Blocks.AIR) { + for (int i = -YSEARCH; i <= YSEARCH; i++) { + blockpos$mutableblockpos.setY(yCenter + i); + IBlockState searchID = chunk.getBlockState(blockpos$mutableblockpos); + if (searchID.getBlock() != Blocks.STONE && searchID.getBlock() != Blocks.AIR) { + state = searchID; + if (i > 0) { + brightness = 2; + } + if (i < 0) { + brightness = 0; + } + + break; + } + } + } + + if (mapOres) { + // recolor ores + if (state.getBlock() == Blocks.COAL_ORE) { + multiset.add(MapColor.BLACK, 1000); + } else if (state.getBlock() == Blocks.GOLD_ORE) { + multiset.add(MapColor.GOLD, 1000); + } else if (state.getBlock() == Blocks.IRON_ORE) { + multiset.add(MapColor.IRON, 1000); + } else if (state.getBlock() == Blocks.LAPIS_ORE) { + multiset.add(MapColor.LAPIS, 1000); + } else if (state.getBlock() == Blocks.REDSTONE_ORE || state.getBlock() == Blocks.LIT_REDSTONE_ORE) { + multiset.add(MapColor.RED, 1000); + } else if (state.getBlock() == Blocks.DIAMOND_ORE) { + multiset.add(MapColor.DIAMOND, 1000); + } else if (state.getBlock() == Blocks.EMERALD_ORE) { + multiset.add(MapColor.EMERALD, 1000); + } else if (state.getBlock() != Blocks.AIR && state.getBlock().getRegistryName().getPath().contains("ore")) { // TODO: improve this 0.o + // any other ore, catchall + multiset.add(MapColor.PINK, 1000); + } + } + } + + /*numLiquid = numLiquid / (blocksPerPixel * blocksPerPixel); + double d2 = (d1 - d0) * 4.0D / (double)(blocksPerPixel + 4) + ((double)(xPixel + zPixel & 1) - 0.5D) * 0.4D; + int brightness = 1; + + if (d2 > 0.6D) + { + brightness = 2; + } + + if (d2 < -0.6D) + { + brightness = 0; + }*/ + + MapColor mapcolor = (MapColor) Iterables.getFirst(Multisets.copyHighestCountFirst(multiset), MapColor.AIR); + + /*if (mapcolor == MapColor.WATER) { - if (highNumber > zStep) + d2 = (double)numLiquid * 0.1D + (double)(xPixel + zPixel & 1) * 0.2D; + brightness = 1; + + if (d2 < 0.5D) { - highNumber = zStep; + brightness = 2; } - if (lowNumber < zStep) + if (d2 > 0.9D) { - lowNumber = zStep; + brightness = 0; } + }*/ - par3MapData.colors[xStep + zStep * xSize] = tintedColor; - } - } - } - } - - if (highNumber <= lowNumber) - { - par3MapData.setColumnDirty(xStep, highNumber, lowNumber); - } - } - } - } - } - - /** - * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and - * update it's contents. - */ - public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean isActiveItem) - { - if (!par2World.isRemote) - { - TFMazeMapData mapData = this.getMapData(par1ItemStack, par2World); - - if (par3Entity instanceof EntityPlayer) - { - EntityPlayer player = (EntityPlayer)par3Entity; - mapData.updateVisiblePlayers(player, par1ItemStack); - - int yProximity = MathHelper.floor_double(player.posY - mapData.yCenter); - if (yProximity < -YSEARCH || yProximity > YSEARCH) { - // fix player icon so that it's a dot - - MapCoord mapCoord = (MapCoord) mapData.playersVisibleOnMap.get(player.getCommandSenderName()); - if (mapCoord != null) - { - mapCoord.iconSize = 6; - } - } - } - - if (isActiveItem) - { - this.updateMapData(par2World, par3Entity, mapData); - } - } - } - - /** - * Called when item is crafted/smelted. Used only by maps so far. - */ - @Override - public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) - { - par1ItemStack.setItemDamage(par2World.getUniqueDataId(STR_ID)); - String mapName = STR_ID + "_" + par1ItemStack.getItemDamage(); - TFMazeMapData mapData = new TFMazeMapData(mapName); - par2World.setItemData(mapName, mapData); - mapData.xCenter = MathHelper.floor_double(par3EntityPlayer.posX); - mapData.yCenter = MathHelper.floor_double(par3EntityPlayer.posY); - mapData.zCenter = MathHelper.floor_double(par3EntityPlayer.posZ); - mapData.scale = 0; - mapData.dimension = par2World.provider.dimensionId; - mapData.markDirty(); - } - - /** - * Return an item rarity from EnumRarity - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return mapOres ? EnumRarity.epic : EnumRarity.uncommon; + d0 = d1; + + if (zPixel >= 0 && xPixelDist * xPixelDist + zPixelDist * zPixelDist < viewRadiusPixels * viewRadiusPixels && (!shouldFuzz || (xPixel + zPixel & 1) != 0)) { + byte b0 = data.colors[xPixel + zPixel * 128]; + byte b1 = (byte) (mapcolor.colorIndex * 4 + brightness); + + if (b0 != b1) { + data.colors[xPixel + zPixel * 128] = b1; + data.updateMapData(xPixel, zPixel); + flag = true; + } + } + } + } + } + } + } + } + } + + // [VanillaCopy] super but shows a dot if player is too far in the vertical direction as well + @Override + public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int slot, boolean isSelected) { + if (!worldIn.isRemote) { + TFMazeMapData mapdata = this.getMapData(stack, worldIn); + + if (entityIn instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entityIn; + mapdata.updateVisiblePlayers(entityplayer, stack); + + // TF - if player is far away vertically, show a dot + int yProximity = MathHelper.floor(entityplayer.posY - mapdata.yCenter); + if (yProximity < -YSEARCH || yProximity > YSEARCH) { + MapDecoration decoration = mapdata.mapDecorations.get(entityplayer.getName()); + if (decoration != null) { + mapdata.mapDecorations.put(entityplayer.getName(), new MapDecoration(MapDecoration.Type.PLAYER_OFF_MAP, decoration.getX(), decoration.getY(), decoration.getRotation())); + } + } + } + + if (isSelected || entityIn instanceof EntityPlayer && ((EntityPlayer) entityIn).getHeldItemOffhand() == stack) { + this.updateMapData(worldIn, entityIn, mapdata); + } + } + } + + @Override + public void onCreated(ItemStack stack, World world, EntityPlayer player) { + // disable zooming + } + + @Override + public EnumRarity getRarity(ItemStack stack) { + return mapOres ? EnumRarity.UNCOMMON : EnumRarity.COMMON; } - - /** - * Do the enchanted shimmer thing - */ - @Override - public boolean hasEffect(ItemStack par1ItemStack) - { - return false; - } - - /** - * returns null if no update is to be sent - * - * We have re-written this to provide a Packet250CustomPayload to be sent, since the map data packet is only for the actual map map. - */ + @Override - public Packet func_150911_c(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) - { - //System.out.println("Making maze map packet"); - //System.out.println("yCenter = " + this.getMapData(par1ItemStack, par2World).yCenter); - - byte[] mapBytes = this.getMapData(par1ItemStack, par2World).getUpdatePacketData(par1ItemStack, par2World, par3EntityPlayer); - - if (mapBytes == null) { - return null; - } - else { - short uniqueID = (short)par1ItemStack.getItemDamage(); - - return TFMapPacketHandler.makeMagicMapPacket(ItemTFMazeMap.STR_ID, uniqueID, mapBytes); - } - } - - /** - * Add the map number to the tooltip - */ - public String getItemStackDisplayName(ItemStack par1ItemStack) - { - return ("" + StatCollector.translateToLocal(this.getUnlocalizedNameInefficiently(par1ItemStack) + ".name") + " #" + par1ItemStack.getItemDamage()).trim(); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Nullable + public Packet createMapDataPacket(ItemStack stack, World worldIn, EntityPlayer player) { + Packet p = super.createMapDataPacket(stack, worldIn, player); + if (p instanceof SPacketMaps) { + return TFPacketHandler.CHANNEL.getPacketFrom(new PacketMazeMap((SPacketMaps) p)); + } else { + return p; + } + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + ModelLoader.setCustomMeshDefinition(this, stack -> new ModelResourceLocation(getRegistryName(), "inventory")); + } } diff --git a/src/main/java/twilightforest/item/ItemTFMazebreakerPick.java b/src/main/java/twilightforest/item/ItemTFMazebreakerPick.java index 8b57ecbd22..89a791bdea 100644 --- a/src/main/java/twilightforest/item/ItemTFMazebreakerPick.java +++ b/src/main/java/twilightforest/item/ItemTFMazebreakerPick.java @@ -1,54 +1,44 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; +import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; +import net.minecraft.util.NonNullList; import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFMazebreakerPick extends ItemPickaxe { +import javax.annotation.Nonnull; - protected ItemTFMazebreakerPick(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); +public class ItemTFMazebreakerPick extends ItemPickaxe implements ModelRegisterCallback { + protected ItemTFMazebreakerPick(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.efficiency, 4); - istack.addEnchantment(Enchantment.unbreaking, 3); - istack.addEnchantment(Enchantment.fortune, 2); - par3List.add(istack); - } + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.EFFICIENCY, 4); + istack.addEnchantment(Enchantments.UNBREAKING, 3); + istack.addEnchantment(Enchantments.FORTUNE, 2); + list.add(istack); + } + } + + @Override + public float getDestroySpeed(@Nonnull ItemStack stack, IBlockState state) { + float destroySpeed = super.getDestroySpeed(stack, state); + return state.getBlock() == TFBlocks.maze_stone ? destroySpeed * 16F : destroySpeed; + } + @Nonnull @Override - public float func_150893_a(ItemStack par1ItemStack, Block par2Block) { - float strVsBlock = super.func_150893_a(par1ItemStack, par2Block); - // 16x strength vs mazestone - return par2Block == TFBlocks.mazestone ? strVsBlock * 16F : strVsBlock; + public EnumRarity getRarity(ItemStack stack) { + return EnumRarity.RARE; } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFMiniatureStructure.java b/src/main/java/twilightforest/item/ItemTFMiniatureStructure.java new file mode 100644 index 0000000000..f6755c044b --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFMiniatureStructure.java @@ -0,0 +1,20 @@ +package twilightforest.item; + +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.translation.I18n; +import twilightforest.enums.StructureVariant; + +import java.util.Locale; + +public class ItemTFMiniatureStructure extends ItemBlockTFMeta { + public ItemTFMiniatureStructure(Block block) { + super(block); + this.setAppend(false); + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return I18n.translateToLocalFormatted(this.getTranslationKey(stack), I18n.translateToLocal("structure." + StructureVariant.values()[stack.getMetadata() % StructureVariant.values().length].getName().toLowerCase(Locale.ROOT) + ".name")); + } +} diff --git a/src/main/java/twilightforest/item/ItemTFMinotaurAxe.java b/src/main/java/twilightforest/item/ItemTFMinotaurAxe.java index 191f21380b..4bb4473082 100644 --- a/src/main/java/twilightforest/item/ItemTFMinotaurAxe.java +++ b/src/main/java/twilightforest/item/ItemTFMinotaurAxe.java @@ -1,130 +1,86 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.attributes.AttributeModifier; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; -import net.minecraft.util.StatCollector; +import net.minecraft.network.play.server.SPacketAnimation; +import net.minecraft.util.DamageSource; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.event.entity.living.LivingAttackEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; +import twilightforest.client.ModelRegisterCallback; -import com.google.common.collect.Multimap; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; -public class ItemTFMinotaurAxe extends ItemAxe { +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class ItemTFMinotaurAxe extends ItemAxe implements ModelRegisterCallback { - public static final int BONUS_CHARGING_DAMAGE = 7; - private Entity bonusDamageEntity; - private EntityPlayer bonusDamagePlayer; - private float damageVsEntity; + private static final int BONUS_CHARGING_DAMAGE = 7; + private final EnumRarity RARITY; - protected ItemTFMinotaurAxe(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); - this.damageVsEntity = 4 + par2EnumToolMaterial.getDamageVsEntity(); + protected ItemTFMinotaurAxe(Item.ToolMaterial material, EnumRarity rarity) { + super(material, 6F + material.getAttackDamage(), material.getEfficiency() * 0.05f - 3.4f); this.setCreativeTab(TFItems.creativeTab); + + this.RARITY = rarity; + } + + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + //istack.addEnchantment(Enchantments.EFFICIENCY, 2); + list.add(istack); + } + } + + @SubscribeEvent + public static void onAttack(LivingAttackEvent evt) { + EntityLivingBase target = evt.getEntityLiving(); + Entity source = evt.getSource().getImmediateSource(); + + if (!target.world.isRemote && source instanceof EntityLivingBase && source.isSprinting()) { + ItemStack weapon = ((EntityLivingBase) evt.getSource().getImmediateSource()).getHeldItemMainhand(); + + if (!weapon.isEmpty() && weapon.getItem() == TFItems.minotaur_axe) { + target.attackEntityFrom(DamageSource.MAGIC, BONUS_CHARGING_DAMAGE); + // don't prevent main damage from applying + target.hurtResistantTime = 0; + // enchantment attack sparkles + ((WorldServer) target.world).getEntityTracker().sendToTrackingAndSelf(target, new SPacketAnimation(target, 5)); + } + } + } + + @Override + public int getItemEnchantability() { + return Item.ToolMaterial.GOLD.getEnchantability(); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - //istack.addEnchantment(Enchantment.efficiency, 2); - par3List.add(istack); - } - - /** - * Called when the player Left Clicks (attacks) an entity. - * Processed before damage is done, if return value is true further processing is canceled - * and the entity is not attacked. - * - * @param stack The Item being used - * @param player The player that is attacking - * @param entity The entity being attacked - * @return True to cancel the rest of the interaction. - */ - @Override - public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) - { - // if the player is sprinting, keep the entity, we will do extra damage to it - if (player.isSprinting()) - { - this.bonusDamageEntity = entity; - this.bonusDamagePlayer = player; - } - - return false; - } - - /** - * Returns the damage against a given entity. - */ - public float getDamageVsEntity(Entity par1Entity, ItemStack itemStack) - { - if (this.bonusDamagePlayer != null && this.bonusDamageEntity != null && par1Entity == this.bonusDamageEntity) - { - //System.out.println("Minotaur Axe extra damage!"); - this.bonusDamagePlayer.onEnchantmentCritical(par1Entity); - this.bonusDamagePlayer = null; - this.bonusDamageEntity = null; - return damageVsEntity + BONUS_CHARGING_DAMAGE; - } - else - { - return damageVsEntity; - } - } - - /** - * Return the enchantability factor of the item, most of the time is based on material. - */ - @Override - public int getItemEnchantability() - { - return Item.ToolMaterial.GOLD.getEnchantability(); - } - - /** - * allows items to add custom lines of information to the mouseover description - */ @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format(getTranslationKey() + ".tooltip")); } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * Gets a map of item attribute modifiers, used by ItemSword to increase hit damage. - */ - public Multimap getItemAttributeModifiers() - { - Multimap multimap = super.getItemAttributeModifiers(); - // remove old damage value - multimap.removeAll(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()); - // add new one - multimap.put(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName(), new AttributeModifier(field_111210_e, "Tool modifier", (double)this.damageVsEntity, 0)); - return multimap; - } -} + @Nonnull + @Override + public EnumRarity getRarity(ItemStack stack) { + return stack.isItemEnchanted() ? EnumRarity.RARE.compareTo(RARITY) > 0 ? EnumRarity.RARE : RARITY : RARITY; + } +} diff --git a/src/main/java/twilightforest/item/ItemTFMoonDial.java b/src/main/java/twilightforest/item/ItemTFMoonDial.java new file mode 100644 index 0000000000..86c43c14d7 --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFMoonDial.java @@ -0,0 +1,51 @@ +package twilightforest.item; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.IItemPropertyGetter; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; + +public class ItemTFMoonDial extends ItemTF { + public ItemTFMoonDial() { + this.addPropertyOverride(new ResourceLocation("phase"), new IItemPropertyGetter() { + @Override + @SideOnly(Side.CLIENT) + public float apply(ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entityBase) { + boolean flag = entityBase != null; + Entity entity = flag ? entityBase : stack.getItemFrame(); + + if (world == null && entity != null) world = entity.world; + + return world == null ? 0.0F : (float) (world.provider.isSurfaceWorld() ? MathHelper.frac(world.getMoonPhase() / 8.0f) : this.wobble(world, Math.random())); + } + + @SideOnly(Side.CLIENT) + double rotation; + @SideOnly(Side.CLIENT) + double rota; + @SideOnly(Side.CLIENT) + long lastUpdateTick; + + @SideOnly(Side.CLIENT) + private double wobble(World world, double rotation) { + if (world.getTotalWorldTime() != this.lastUpdateTick) { + this.lastUpdateTick = world.getTotalWorldTime(); + double delta = rotation - this.rotation; + delta = MathHelper.positiveModulo(delta + 0.5D, 1.0D) - 0.5D; + this.rota += delta * 0.1D; + this.rota *= 0.9D; + this.rotation = MathHelper.positiveModulo(this.rotation + this.rota, 1.0D); + } + + return this.rotation; + } + }); + } +} diff --git a/src/main/java/twilightforest/item/ItemTFMoonwormQueen.java b/src/main/java/twilightforest/item/ItemTFMoonwormQueen.java index c392f7d030..c4f2ab97d6 100644 --- a/src/main/java/twilightforest/item/ItemTFMoonwormQueen.java +++ b/src/main/java/twilightforest/item/ItemTFMoonwormQueen.java @@ -1,217 +1,138 @@ package twilightforest.item; +import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.SoundType; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.IItemPropertyGetter; import net.minecraft.item.ItemStack; -import net.minecraft.util.IIcon; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; import twilightforest.block.TFBlocks; import twilightforest.entity.EntityTFMoonwormShot; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; -public class ItemTFMoonwormQueen extends ItemTF -{ +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class ItemTFMoonwormQueen extends ItemTF { private static final int FIRING_TIME = 12; - - private IIcon[] icons; - private String[] iconNames = new String[] {"moonwormQueen", "moonwormQueenAlt"}; - protected ItemTFMoonwormQueen() { - super(); - this.setCreativeTab(TFItems.creativeTab); + protected ItemTFMoonwormQueen(EnumRarity rarity) { + super(rarity); this.maxStackSize = 1; - this.setMaxDamage(256); + this.setMaxDamage(256); + addPropertyOverride(TwilightForestMod.prefix("alt"), new IItemPropertyGetter() { + @SideOnly(Side.CLIENT) + @Override + public float apply(@Nonnull ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) { + if (entityIn != null && entityIn.getActiveItemStack() == stack) { + int useTime = stack.getMaxItemUseDuration() - entityIn.getItemInUseCount(); + if (useTime >= FIRING_TIME && (useTime >>> 1) % 2 == 0) { + return 1; + } + } + + return 0; + } + }); } @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World world, EntityPlayer player) { - if (par1ItemStack.getItemDamage() < this.getMaxDamage()) - { - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + if (stack.getItemDamage() >= stack.getMaxDamage() - 1) { + return ActionResult.newResult(EnumActionResult.FAIL, stack); + } else { + player.setActiveHand(hand); + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - else - { - player.stopUsingItem(); - } - return par1ItemStack; } - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ + // [VanillaCopy] ItemBlock.onItemUse, harcoding the block @Override - public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) - { - // adjust x, y, z for which block we're placing onto - Block currentBlockID = world.getBlock(x, y, z); - - if (currentBlockID == TFBlocks.moonworm) - { - return false; - } - - // don't wear item out, leave it at 0 uses left so that it can be recharged - if (par1ItemStack != null && par1ItemStack.getItemDamage() == this.getMaxDamage()) - { - return false; + public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + IBlockState iblockstate = worldIn.getBlockState(pos); + Block block = iblockstate.getBlock(); + + if (!block.isReplaceable(worldIn, pos)) { + pos = pos.offset(facing); } - - if (currentBlockID == Blocks.snow) - { - side = 1; - } - else if (currentBlockID != Blocks.vine && currentBlockID != Blocks.tallgrass && currentBlockID != Blocks.deadbush - && (currentBlockID == Blocks.air || !currentBlockID.isReplaceable(world, x, y, z))) - { - if (side == 0) - { - --y; - } - - if (side == 1) - { - ++y; - } - - if (side == 2) - { - --z; - } - - if (side == 3) - { - ++z; - } - - if (side == 4) - { - --x; - } - - if (side == 5) - { - ++x; - } - } - - // try to place firefly - if (world.canPlaceEntityOnSide(TFBlocks.moonworm, x, y, z, false, side, player, par1ItemStack)) - { - int placementMeta = TFBlocks.moonworm.onBlockPlaced(world, x, y, z, side, hitX, hitY, hitZ, 0); - if (world.setBlock(x, y, z, TFBlocks.moonworm, placementMeta, 3)) - { - if (world.getBlock(x, y, z) == TFBlocks.moonworm) - { - //((BlockTFMoonworm) TFBlocks.moonworm).updateBlockMetadata(world, x, y, z, side, hitX, hitY, hitZ); - TFBlocks.moonworm.onBlockPlacedBy(world, x, y, z, player, par1ItemStack); - } - world.playSoundEffect((double)(x + 0.5F), (double)(y + 0.5F), (double)(z + 0.5F), this.getSound(), TFBlocks.moonworm.stepSound.getVolume() / 2.0F, TFBlocks.moonworm.stepSound.getPitch() * 0.8F); - - if (par1ItemStack != null) - { - par1ItemStack.damageItem(1, player); - player.stopUsingItem(); - } - } + ItemStack itemstack = player.getHeldItem(hand); + if (itemstack.getItemDamage() < itemstack.getMaxDamage() && player.canPlayerEdit(pos, facing, itemstack) && worldIn.mayPlace(TFBlocks.moonworm, pos, false, facing, (Entity) null)) { + int i = this.getMetadata(itemstack.getMetadata()); + IBlockState iblockstate1 = TFBlocks.moonworm.getStateForPlacement(worldIn, pos, facing, hitX, hitY, hitZ, i, player, hand); + + if (placeMoonwormAt(itemstack, player, worldIn, pos, facing, hitX, hitY, hitZ, iblockstate1)) { + SoundType soundtype = worldIn.getBlockState(pos).getBlock().getSoundType(worldIn.getBlockState(pos), worldIn, pos, player); + worldIn.playSound(player, pos, soundtype.getPlaceSound(), SoundCategory.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F); + // TF - damage stack instead of shrinking + itemstack.damageItem(1, player); + player.resetActiveHand(); + } - return true; + return EnumActionResult.SUCCESS; + } else { + return EnumActionResult.FAIL; } - else - { - return false; + } + + // [VanillaCopy] ItemBlock.placeBlockAt + private boolean placeMoonwormAt(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, IBlockState state) { + if (!world.setBlockState(pos, state, 11)) return false; + + IBlockState real = world.getBlockState(pos); + if (real.getBlock() == TFBlocks.moonworm) { + TFBlocks.moonworm.onBlockPlacedBy(world, pos, state, player, stack); + if (player instanceof EntityPlayerMP) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP) player, pos, stack); + } } + + return true; } - - public String getSound() - { - return "mob.slime.big"; + + @Override + public void onPlayerStoppedUsing(ItemStack stack, World world, EntityLivingBase living, int useRemaining) { + int useTime = this.getMaxItemUseDuration(stack) - useRemaining; + + if (!world.isRemote && useTime > FIRING_TIME && (stack.getItemDamage() + 1) < stack.getMaxDamage()) { + boolean fired = world.spawnEntity(new EntityTFMoonwormShot(world, living)); + + if (fired) { + stack.damageItem(2, living); + + world.playSound(null, living.posX, living.posY, living.posZ, SoundEvents.BLOCK_SLIME_HIT, living instanceof EntityPlayer ? SoundCategory.PLAYERS : SoundCategory.NEUTRAL, 1, 1); + } + } + } - /** - * called when the player releases the use item button. Args: itemstack, world, entityplayer, itemInUseCount - */ - @Override - public void onPlayerStoppedUsing(ItemStack par1ItemStack, World world, EntityPlayer player, int useRemaining) - { - int useTime = this.getMaxItemUseDuration(par1ItemStack) - useRemaining; - - - if (!world.isRemote && useTime > FIRING_TIME && (par1ItemStack.getItemDamage() + 1) < this.getMaxDamage()) - { - boolean fired = world.spawnEntityInWorld(new EntityTFMoonwormShot(world, player)); - - if (fired) - { - par1ItemStack.damageItem(2, player); - - world.playSoundAtEntity(player, this.getSound(), 1.0F, 1.0F); - } - } - - } - - /** - * Player, Render pass, and item usage sensitive version of getIconIndex. - * - * @param stack The item stack to get the icon for. (Usually this, and usingItem will be the same if usingItem is not null) - * @param renderPass The pass to get the icon for, 0 is default. - * @param player The player holding the item - * @param usingItem The item the player is actively using. Can be null if not using anything. - * @param useRemaining The ticks remaining for the active item. - * @return The icon index - */ - @Override - public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { - if (usingItem != null && usingItem.getItem() == this) - { - int useTime = usingItem.getMaxItemUseDuration() - useRemaining; - if (useTime >= FIRING_TIME) - { - return (useTime >> 1) % 2 == 0 ? this.icons[0] : this.icons[1]; - } - } - return this.icons[0]; - - } - - - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - super.registerIcons(par1IconRegister); - this.icons = new IIcon[iconNames.length]; - - for (int i = 0; i < this.iconNames.length; ++i) - { - this.icons[i] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + iconNames[i]); - } - } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.bow; - } - - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } + @Nonnull + @Override + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BOW; + } + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 72000; + } } diff --git a/src/main/java/twilightforest/item/ItemTFNagaArmor.java b/src/main/java/twilightforest/item/ItemTFNagaArmor.java index d8fa0624fe..d7018cd142 100644 --- a/src/main/java/twilightforest/item/ItemTFNagaArmor.java +++ b/src/main/java/twilightforest/item/ItemTFNagaArmor.java @@ -1,52 +1,44 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; -import net.minecraft.item.ItemArmor; +import net.minecraft.init.Enchantments; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFNagaArmor extends ItemArmor { - - public ItemTFNagaArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int par3, int par4) { - super(par2EnumArmorMaterial, par3, par4); - this.setCreativeTab(TFItems.creativeTab); +public class ItemTFNagaArmor extends ItemTFArmor implements ModelRegisterCallback { + protected ItemTFNagaArmor(ArmorMaterial materialIn, EntityEquipmentSlot equipmentSlotIn, EnumRarity rarity) { + super(materialIn, equipmentSlotIn, rarity); } @Override - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) { - - - if(itemstack.getItem() == TFItems.plateNaga) - { - return TwilightForestMod.ARMOR_DIR + "naga_scale_1.png"; - } - if(itemstack.getItem() == TFItems.legsNaga) - { - return TwilightForestMod.ARMOR_DIR + "naga_scale_2.png"; - } - return TwilightForestMod.ARMOR_DIR + "naga_scale_1.png"; + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + if (slot == EntityEquipmentSlot.LEGS) { + return TwilightForestMod.ARMOR_DIR + "naga_scale_2.png"; + } else { + return TwilightForestMod.ARMOR_DIR + "naga_scale_1.png"; + } } - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with naga scale - return par2ItemStack.getItem() == TFItems.nagaScale ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + switch (this.armorType) { + case CHEST: + istack.addEnchantment(Enchantments.FIRE_PROTECTION, 3); + break; + case LEGS: + istack.addEnchantment(Enchantments.PROTECTION, 3); + break; + default: + break; + } + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFOreMagnet.java b/src/main/java/twilightforest/item/ItemTFOreMagnet.java index 178a68bfc1..c6641c4a55 100644 --- a/src/main/java/twilightforest/item/ItemTFOreMagnet.java +++ b/src/main/java/twilightforest/item/ItemTFOreMagnet.java @@ -1,294 +1,196 @@ package twilightforest.item; -import java.util.ArrayList; - import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; +import net.minecraft.block.state.pattern.BlockMatcher; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.item.IItemPropertyGetter; import net.minecraft.item.ItemStack; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.block.BlockTFRoots; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenerator; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.enums.RootVariant; +import twilightforest.world.feature.TFGenerator; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.HashSet; +import java.util.Set; -public class ItemTFOreMagnet extends ItemTF -{ +public class ItemTFOreMagnet extends ItemTF { private static final float WIGGLE = 10F; - - private IIcon[] icons; - private String[] iconNames = new String[] {"oreMagnet", "oreMagnet1", "oreMagnet2"}; protected ItemTFOreMagnet() { - super(); - this.setCreativeTab(TFItems.creativeTab); this.maxStackSize = 1; - this.setMaxDamage(12); + this.setMaxDamage(12); + // [VanillaCopy] ItemBow with our item + this.addPropertyOverride(new ResourceLocation("pull"), new IItemPropertyGetter() { + @Override + @SideOnly(Side.CLIENT) + public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) { + if (entityIn == null) { + return 0.0F; + } else { + ItemStack itemstack = entityIn.getActiveItemStack(); + return !itemstack.isEmpty() && itemstack.getItem() == TFItems.ore_magnet ? (float) (stack.getMaxItemUseDuration() - entityIn.getItemInUseCount()) / 20.0F : 0.0F; + } + } + }); + this.addPropertyOverride(new ResourceLocation("pulling"), new IItemPropertyGetter() { + @Override + @SideOnly(Side.CLIENT) + public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) { + return entityIn != null && entityIn.isHandActive() && entityIn.getActiveItemStack() == stack ? 1.0F : 0.0F; + } + }); } + @Nonnull @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World world, EntityPlayer player) { - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); - return par1ItemStack; + public ActionResult onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { + player.setActiveHand(hand); + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - - /** - * called when the player releases the use item button. Args: itemstack, world, entityplayer, itemInUseCount - */ - @Override - public void onPlayerStoppedUsing(ItemStack par1ItemStack, World world, EntityPlayer player, int useRemaining) - { - int useTime = this.getMaxItemUseDuration(par1ItemStack) - useRemaining; - - if (!world.isRemote && useTime > 10) - { - //player.addChatMessage("Ore Magnet!"); - - int moved = doMagnet(world, player, 0, 0); - - if (moved == 0) - { - moved = doMagnet(world, player, WIGGLE, 0); - } - if (moved == 0) - { - moved = doMagnet(world, player, WIGGLE, WIGGLE); - } - if (moved == 0) - { - moved = doMagnet(world, player, 0, WIGGLE); - } - if (moved == 0) - { - moved = doMagnet(world, player, -WIGGLE, WIGGLE); - } - if (moved == 0) - { - moved = doMagnet(world, player, -WIGGLE, 0); - } - if (moved == 0) - { - moved = doMagnet(world, player, -WIGGLE, -WIGGLE); - } - if (moved == 0) - { - moved = doMagnet(world, player, 0, -WIGGLE); - } - if (moved == 0) - { - moved = doMagnet(world, player, WIGGLE, -WIGGLE); - } - - //player.addChatMessage("Cost: " + moved); - - if (moved > 0) - { - par1ItemStack.damageItem(moved, player); - - if (par1ItemStack.stackSize == 0) - { - player.destroyCurrentEquippedItem(); - } - - world.playSoundAtEntity(player, "mob.endermen.portal", 1.0F, 1.0F); - } - } - - } - - /** - * Player, Render pass, and item usage sensitive version of getIconIndex. - * - * @param stack The item stack to get the icon for. (Usually this, and usingItem will be the same if usingItem is not null) - * @param renderPass The pass to get the icon for, 0 is default. - * @param player The player holding the item - * @param usingItem The item the player is actively using. Can be null if not using anything. - * @param useRemaining The ticks remaining for the active item. - * @return The icon index - */ - @Override - public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { - if (usingItem != null && usingItem.getItem() == this) - { - int useTime = usingItem.getMaxItemUseDuration() - useRemaining; - if (useTime >= 20) - { - return (useTime >> 2) % 2 == 0 ? this.icons[2] : this.icons[1]; - - } - if (useTime > 10) - { - return this.icons[1]; - } - } - return this.icons[0]; - - } - - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - super.registerIcons(par1IconRegister); - this.icons = new IIcon[iconNames.length]; - - for (int i = 0; i < this.iconNames.length; ++i) - { - this.icons[i] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + iconNames[i]); - } - } + @Override + public void onPlayerStoppedUsing(ItemStack stack, World world, EntityLivingBase living, int useRemaining) { + int useTime = this.getMaxItemUseDuration(stack) - useRemaining; - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.bow; - } - - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } + if (!world.isRemote && useTime > 10) { + int moved = doMagnet(world, living, 0, 0); + + if (moved == 0) { + moved = doMagnet(world, living, WIGGLE, 0); + } + if (moved == 0) { + moved = doMagnet(world, living, WIGGLE, WIGGLE); + } + if (moved == 0) { + moved = doMagnet(world, living, 0, WIGGLE); + } + if (moved == 0) { + moved = doMagnet(world, living, -WIGGLE, WIGGLE); + } + if (moved == 0) { + moved = doMagnet(world, living, -WIGGLE, 0); + } + if (moved == 0) { + moved = doMagnet(world, living, -WIGGLE, -WIGGLE); + } + if (moved == 0) { + moved = doMagnet(world, living, 0, -WIGGLE); + } + if (moved == 0) { + moved = doMagnet(world, living, WIGGLE, -WIGGLE); + } + + if (moved > 0) { + stack.damageItem(moved, living); + world.playSound(null, living.posX, living.posY, living.posZ, SoundEvents.ENTITY_ENDERMEN_TELEPORT, living.getSoundCategory(), 1.0F, 1.0F); + } + } + } + + @Override + public float getXpRepairRatio(ItemStack stack) { + return 0.1f; + } + + @Nonnull + @Override + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BOW; + } + + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 72000; + } /** * Magnet from the player's position and facing to the specified offset */ - protected int doMagnet(World world, EntityPlayer player, float yawOffset, float pitchOffset) { - + private int doMagnet(World world, EntityLivingBase living, float yawOffset, float pitchOffset) { + // find vector 32 blocks from look double range = 32.0D; - Vec3 srcVec = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 lookVec = getOffsetLook(player, yawOffset, pitchOffset); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - - int useX = MathHelper.floor_double(srcVec.xCoord); - int useY = MathHelper.floor_double(srcVec.yCoord); - int useZ = MathHelper.floor_double(srcVec.zCoord); - - int destX = MathHelper.floor_double(destVec.xCoord); - int destY = MathHelper.floor_double(destVec.yCoord); - int destZ = MathHelper.floor_double(destVec.zCoord); - - int blocksMoved = doMagnet(world, useX, useY, useZ, destX, destY, destZ); - - return blocksMoved; + Vec3d srcVec = new Vec3d(living.posX, living.posY + living.getEyeHeight(), living.posZ); + Vec3d lookVec = getOffsetLook(living, yawOffset, pitchOffset); + Vec3d destVec = srcVec.add(lookVec.x * range, lookVec.y * range, lookVec.z * range); + + return doMagnet(world, new BlockPos(srcVec), new BlockPos(destVec)); } - /** - * This function makes the magnet work - */ - public static int doMagnet(World world, int useX, int useY, int useZ, int destX, int destY, int destZ) { + public static int doMagnet(World world, BlockPos usePos, BlockPos destPos) { int blocksMoved = 0; // get blocks in line from src to dest - ChunkCoordinates[] lineArray = TFGenerator.getBresehnamArrayCoords(useX, useY, useZ, destX, destY, destZ); - - //System.out.println("Searching from " + useX + ", " + useY + ", " + useZ + " to " + destX + ", " + destY + ", " + destZ); - + BlockPos[] lineArray = TFGenerator.getBresehnamArrays(usePos, destPos); + // find some ore? - Block foundID = Blocks.air; - int foundMeta = -1; - int foundX = -1; - int foundY = -1; - int foundZ = -1; - int baseX = -1; - int baseY = -1; - int baseZ = -1; - - boolean isNetherrack = false; - - for (ChunkCoordinates coord : lineArray) - { - Block searchID = world.getBlock(coord.posX, coord.posY, coord.posZ); - int searchMeta = world.getBlockMetadata(coord.posX, coord.posY, coord.posZ); - - // keep track of where the dirt/stone we first find is.s - if (baseY == -1) - { - if (isReplaceable(world, searchID, searchMeta, coord.posX, coord.posY, coord.posZ)) - { - baseX = coord.posX; - baseY = coord.posY; - baseZ = coord.posZ; + IBlockState foundState = Blocks.AIR.getDefaultState(); + BlockPos foundPos = null; + BlockPos basePos = null; - } - else if (isNetherReplaceable(world, searchID, searchMeta, coord.posX, coord.posY, coord.posZ)) - { + boolean isNetherrack = false; + + for (BlockPos coord : lineArray) { + IBlockState searchState = world.getBlockState(coord); + + // keep track of where the dirt/stone we first find is.s + if (basePos == null) { + if (isReplaceable(world, searchState, coord)) { + basePos = coord; + } else if (isNetherReplaceable(world, searchState, coord)) { isNetherrack = true; - baseX = coord.posX; - baseY = coord.posY; - baseZ = coord.posZ; + basePos = coord; } - } - - if (searchID != Blocks.air && isOre(searchID, searchMeta)) - { - //System.out.println("I found ore: " + searchID + " at " + coord.PosX + ", " + coord.PosY + ", " + coord.PosZ); - - foundID = searchID; - foundMeta = searchMeta; - foundX = coord.posX; - foundY = coord.posY; - foundZ = coord.posZ; - - break; - } + // This ordering is so that the base pos is found first before we pull ores - pushing ores away is a baaaaad idea! + } else if (foundPos == null && searchState.getBlock() != Blocks.AIR && isOre(searchState) && (world.getTileEntity(coord) == null)) { + foundState = searchState; + foundPos = coord; + } } - - //System.out.println("I found ground at " + baseX + ", " + baseY + ", " + baseZ); - - if (baseY != -1 && foundID != Blocks.air) - { + if (basePos != null && foundState.getBlock() != Blocks.AIR) { // find the whole vein - ArrayList veinBlocks = new ArrayList(); - findVein(world, foundX, foundY, foundZ, foundID, foundMeta, veinBlocks); + Set veinBlocks = new HashSet(); + findVein(world, foundPos, foundState, veinBlocks); // move it up into minable blocks or dirt - int offX = baseX - foundX; - int offY = baseY - foundY; - int offZ = baseZ - foundZ; - - for (ChunkCoordinates coord : veinBlocks) - { - int replaceX = coord.posX + offX; - int replaceY = coord.posY + offY; - int replaceZ = coord.posZ + offZ; - - Block replaceID = world.getBlock(replaceX, replaceY, replaceZ); - int replaceMeta = world.getBlockMetadata(replaceX, replaceY, replaceZ); - - if ((isNetherrack ? isNetherReplaceable(world, replaceID, replaceMeta, replaceX, replaceY, replaceZ) : isReplaceable(world, replaceID, replaceMeta, replaceX, replaceY, replaceZ)) || replaceID == Blocks.air) - { + int offX = basePos.getX() - foundPos.getX(); + int offY = basePos.getY() - foundPos.getY(); + int offZ = basePos.getZ() - foundPos.getZ(); + + for (BlockPos coord : veinBlocks) { + BlockPos replacePos = coord.add(offX, offY, offZ); + IBlockState replaceState = world.getBlockState(replacePos); + + if ((isNetherrack ? isNetherReplaceable(world, replaceState, replacePos) : isReplaceable(world, replaceState, replacePos)) || replaceState.getBlock() == Blocks.AIR) { // set vein to stone / netherrack - world.setBlock(coord.posX, coord.posY, coord.posZ, isNetherrack ? Blocks.netherrack : Blocks.stone, 0, 2); - + world.setBlockState(coord, isNetherrack ? Blocks.NETHERRACK.getDefaultState() : Blocks.STONE.getDefaultState(), 2); + // set close to ore material - world.setBlock(replaceX, replaceY, replaceZ, foundID, foundMeta, 2); + world.setBlockState(replacePos, foundState, 2); blocksMoved++; } - else - { - //System.out.println("Not moving a block because we did not find a replaceable block to move to"); - } } - -// player.addChatMessage("Moved blocks! " + blocksMoved); } + return blocksMoved; } @@ -296,137 +198,83 @@ else if (isNetherReplaceable(world, searchID, searchMeta, coord.posX, coord.posY * Get the player look vector, but offset by the specified parameters. We use to scan the area around where the player is looking * in the likely case there's no ore in the exact look direction. */ - private Vec3 getOffsetLook(EntityPlayer player, float yawOffset, float pitchOffset) { - float var2 = MathHelper.cos(-(player.rotationYaw + yawOffset) * 0.017453292F - (float)Math.PI); - float var3 = MathHelper.sin(-(player.rotationYaw + yawOffset) * 0.017453292F - (float)Math.PI); - float var4 = -MathHelper.cos(-(player.rotationPitch + pitchOffset) * 0.017453292F); - float var5 = MathHelper.sin(-(player.rotationPitch + pitchOffset) * 0.017453292F); - return Vec3.createVectorHelper(var3 * var4, var5, var2 * var4); + private Vec3d getOffsetLook(EntityLivingBase living, float yawOffset, float pitchOffset) { + float var2 = MathHelper.cos(-(living.rotationYaw + yawOffset) * 0.017453292F - (float) Math.PI); + float var3 = MathHelper.sin(-(living.rotationYaw + yawOffset) * 0.017453292F - (float) Math.PI); + float var4 = -MathHelper.cos(-(living.rotationPitch + pitchOffset) * 0.017453292F); + float var5 = MathHelper.sin(-(living.rotationPitch + pitchOffset) * 0.017453292F); + return new Vec3d(var3 * var4, var5, var2 * var4); } - private static boolean isReplaceable(World world, Block replaceID, int replaceMeta, int x, int y, int z) - { - if (replaceID == Blocks.dirt) - { - return true; - } - if (replaceID == Blocks.grass) - { - return true; - } - if (replaceID == Blocks.gravel) - { - return true; - } - if (replaceID != Blocks.air && replaceID.isReplaceableOreGen(world, x, y, z, Blocks.stone)) - { + private static boolean isReplaceable(World world, IBlockState state, BlockPos pos) { + Block block = state.getBlock(); + + if (block == Blocks.DIRT + || block == Blocks.GRASS + || block == Blocks.GRAVEL + || (block != Blocks.AIR && block.isReplaceableOreGen(state, world, pos, BlockMatcher.forBlock(Blocks.STONE)))) { return true; } - + return false; } - private static boolean isNetherReplaceable(World world, Block replaceID, int replaceMeta, int x, int y, int z) - { - if (replaceID == Blocks.netherrack) - { + private static boolean isNetherReplaceable(World world, IBlockState state, BlockPos pos) { + if (state.getBlock() == Blocks.NETHERRACK) { return true; } - if (replaceID != Blocks.air && replaceID.isReplaceableOreGen(world, x, y, z, Blocks.netherrack)) - { + if (state.getBlock() != Blocks.AIR && state.getBlock().isReplaceableOreGen(state, world, pos, BlockMatcher.forBlock(Blocks.NETHERRACK))) { return true; } - + return false; } - private static boolean findVein(World world, int x, int y, int z, Block oreID, int oreMeta, ArrayList veinBlocks) - { - ChunkCoordinates here = new ChunkCoordinates(x, y, z); - - // is this already on the list? - if (veinBlocks.contains(here)) - { + private static boolean findVein(World world, BlockPos here, IBlockState oreState, Set veinBlocks) { + // is this already on the list? + if (veinBlocks.contains(here)) { return false; } // let's limit it to 24 blocks at a time - if (veinBlocks.size() >= 24) - { + if (veinBlocks.size() >= 24) { return false; } // otherwise, check if we're still in the vein - if (world.getBlock(x, y, z) == oreID && world.getBlockMetadata(x, y, z) == oreMeta) - { + if (world.getBlockState(here) == oreState) { veinBlocks.add(here); // recurse in 6 directions - findVein(world, x + 1, y, z, oreID, oreMeta, veinBlocks); - findVein(world, x - 1, y, z, oreID, oreMeta, veinBlocks); - findVein(world, x, y + 1, z, oreID, oreMeta, veinBlocks); - findVein(world, x, y - 1, z, oreID, oreMeta, veinBlocks); - findVein(world, x, y, z + 1, oreID, oreMeta, veinBlocks); - findVein(world, x, y, z - 1, oreID, oreMeta, veinBlocks); - + for (EnumFacing e : EnumFacing.VALUES) { + findVein(world, here.offset(e), oreState, veinBlocks); + } + return true; - } - else - { + } else { return false; } } + private static boolean isOre(IBlockState state) { + Block block = state.getBlock(); + + if (block == Blocks.COAL_ORE) return false; + + if (block == Blocks.IRON_ORE + || block == Blocks.DIAMOND_ORE + || block == Blocks.EMERALD_ORE + || block == Blocks.GOLD_ORE + || block == Blocks.LAPIS_ORE + || block == Blocks.REDSTONE_ORE + || block == Blocks.LIT_REDSTONE_ORE + || block == Blocks.QUARTZ_ORE + || state == TFBlocks.root.getDefaultState().withProperty(BlockTFRoots.VARIANT, RootVariant.LIVEROOT) + // todo 1.9 oh god + // National treasure -Drullkus + || state.getBlock().getRegistryName().getPath().contains("ore")) + return true; - public static boolean isOre(Block blockID, int meta) { - - if (blockID == Blocks.coal_ore) - { - return false; - } - if (blockID == Blocks.iron_ore) - { - return true; - } - if (blockID == Blocks.diamond_ore) - { - return true; - } - if (blockID == Blocks.emerald_ore) - { - return true; - } - if (blockID == Blocks.gold_ore) - { - return true; - } - if (blockID == Blocks.lapis_ore) - { - return true; - } - if (blockID == Blocks.redstone_ore) - { - return true; - } - if (blockID == Blocks.lit_redstone_ore) - { - return true; - } - if (blockID == Blocks.quartz_ore) - { - return true; - } - if (blockID == TFBlocks.root && meta == BlockTFRoots.OREROOT_META) - { - return true; - } - if (blockID.getUnlocalizedName().toLowerCase().contains("ore")) - { - return true; - } - return false; } - - -} +} \ No newline at end of file diff --git a/src/main/java/twilightforest/item/ItemTFOreMeter.java b/src/main/java/twilightforest/item/ItemTFOreMeter.java index e3a75067a3..ede440456c 100644 --- a/src/main/java/twilightforest/item/ItemTFOreMeter.java +++ b/src/main/java/twilightforest/item/ItemTFOreMeter.java @@ -1,93 +1,53 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; -import net.minecraft.util.MathHelper; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; import twilightforest.TwilightForestMod; import twilightforest.block.BlockTFRoots; import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import twilightforest.enums.RootVariant; +import javax.annotation.Nonnull; +import java.util.IdentityHashMap; +import java.util.Map; public class ItemTFOreMeter extends ItemTF { protected ItemTFOreMeter() { - super(); this.setCreativeTab(TFItems.creativeTab); } - - + @Nonnull @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World world, EntityPlayer player) { - - int useX = MathHelper.floor_double(player.posX); - int useZ = MathHelper.floor_double(player.posZ); - + public ActionResult onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { + int useX = MathHelper.floor(player.posX); + int useZ = MathHelper.floor(player.posZ); + if (!world.isRemote) { countOreInArea(player, world, useX, useZ, 3); } - -// player.addChatMessage("func_72971_b = " + player.worldObj.func_72971_b(1.0f)); -// player.addChatMessage("calculateSkylightSubtracted = " + player.worldObj.calculateSkylightSubtracted(1.0f)); - -// player.addChatMessage("player health =" + player.getHealth()); - - return super.onItemRightClick(par1ItemStack, world, player); + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - private void countOreInChunk(EntityPlayer player, World world, int useX, int useZ) { - int chunkX = useX >> 4; - int chunkZ = useZ >> 4; - - int countStone = countBlockInChunk(world, Blocks.stone, chunkX, chunkZ); - int countDirt = countBlockInChunk(world, Blocks.dirt, chunkX, chunkZ); - int countGravel = countBlockInChunk(world, Blocks.gravel, chunkX, chunkZ); - - int countCoal = countBlockInChunk(world, Blocks.coal_ore, chunkX, chunkZ); - int countIron = countBlockInChunk(world, Blocks.iron_ore, chunkX, chunkZ); - int countGold = countBlockInChunk(world, Blocks.gold_ore, chunkX, chunkZ); - int countDiamond = countBlockInChunk(world, Blocks.diamond_ore, chunkX, chunkZ); - int countLapis = countBlockInChunk(world, Blocks.lapis_ore, chunkX, chunkZ); - int countRedstone = countBlockInChunk(world, Blocks.redstone_ore, chunkX, chunkZ); - - int countRoots = countBlockInChunk(world, TFBlocks.root, BlockTFRoots.ROOT_META, chunkX, chunkZ); - int countOreRoots = countBlockInChunk(world, TFBlocks.root, BlockTFRoots.OREROOT_META, chunkX, chunkZ); - - int total = countStone + countDirt + countGravel + countCoal + countIron + countGold + countDiamond + countLapis + countRedstone + countRoots + countOreRoots; - - -// player.addChatMessage("Ore Meter!"); -// player.addChatMessage("Metering chunk [" + chunkX + ", " + chunkZ + "]"); -// player.addChatMessage("Coal - " + countCoal + " " + percent(countCoal, total)); -// player.addChatMessage("Iron - " + countIron + " " + percent(countIron, total)); -// player.addChatMessage("Gold - " + countGold + " " + percent(countGold, total)); -// player.addChatMessage("Diamond - " + countDiamond + " " + percent(countDiamond, total)); -// player.addChatMessage("Lapis - " + countLapis + " " + percent(countLapis, total)); -// player.addChatMessage("Redstone - " + countRedstone + " " + percent(countRedstone, total)); -// player.addChatMessage("Roots - " + countRoots + " " + percent(countRoots, total)); -// player.addChatMessage("Ore Roots - " + countOreRoots + " " + percent(countOreRoots, total)); - } - private void countOreInArea(EntityPlayer player, World world, int useX, int useZ, int radius) { int chunkX = useX >> 4; int chunkZ = useZ >> 4; - int countStone = 0; int countDirt = 0; int countGravel = 0; - + int countCoal = 0; int countIron = 0; int countGold = 0; @@ -101,125 +61,71 @@ private void countOreInArea(EntityPlayer player, World world, int useX, int useZ int total = 0; - + ScanResult dummy = new ScanResult(); for (int cx = chunkX - radius; cx <= chunkX + radius; cx++) { for (int cz = chunkZ - radius; cz <= chunkZ + radius; cz++) { - - countStone += countBlockInChunk(world, Blocks.stone, cx, cz); - countDirt += countBlockInChunk(world, Blocks.dirt, cx, cz); - countGravel += countBlockInChunk(world, Blocks.gravel, cx, cz); - - countCoal += countBlockInChunk(world, Blocks.coal_ore, cx, cz); - countIron += countBlockInChunk(world, Blocks.iron_ore, cx, cz); - countGold += countBlockInChunk(world, Blocks.gold_ore, cx, cz); - countDiamond += countBlockInChunk(world, Blocks.diamond_ore, cx, cz); - countLapis += countBlockInChunk(world, Blocks.lapis_ore, cx, cz); - countRedstone += countBlockInChunk(world, Blocks.redstone_ore, cx, cz); - countExposedDiamond += countExposedBlockInChunk(world, Blocks.diamond_ore, cx, cz); - - - countRoots += countBlockInChunk(world, TFBlocks.root, BlockTFRoots.ROOT_META, cx, cz); - countOreRoots += countBlockInChunk(world, TFBlocks.root, BlockTFRoots.OREROOT_META, cx, cz); - - + Map results = countBlocksInChunk(world, chunkX, chunkZ); + + countStone += results.entrySet().stream().filter(e -> e.getKey().getBlock() == Blocks.STONE).mapToInt(e -> e.getValue().count).sum(); + countDirt += results.entrySet().stream().filter(e -> e.getKey().getBlock() == Blocks.DIRT).mapToInt(e -> e.getValue().count).sum(); + countGravel += results.getOrDefault(Blocks.GRAVEL.getDefaultState(), dummy).count; + + countCoal += results.getOrDefault(Blocks.COAL_ORE.getDefaultState(), dummy).count; + countIron += results.getOrDefault(Blocks.IRON_ORE.getDefaultState(), dummy).count; + countGold += results.getOrDefault(Blocks.GOLD_ORE.getDefaultState(), dummy).count; + countDiamond += results.getOrDefault(Blocks.DIAMOND_ORE.getDefaultState(), dummy).count; + countLapis += results.getOrDefault(Blocks.LAPIS_ORE.getDefaultState(), dummy).count; + countRedstone += results.getOrDefault(Blocks.REDSTONE_ORE.getDefaultState(), dummy).count + results.getOrDefault(Blocks.LIT_REDSTONE_ORE.getDefaultState(), dummy).count; + countExposedDiamond += results.getOrDefault(Blocks.DIAMOND_ORE.getDefaultState(), dummy).exposedCount; + + countRoots += results.getOrDefault(TFBlocks.root.getDefaultState().withProperty(BlockTFRoots.VARIANT, RootVariant.ROOT), dummy).count; + countOreRoots += results.getOrDefault(TFBlocks.root.getDefaultState().withProperty(BlockTFRoots.VARIANT, RootVariant.LIVEROOT), dummy).count; } } total = countStone + countDirt + countGravel + countCoal + countIron + countGold + countDiamond + countLapis + countRedstone + countRoots + countOreRoots; - -// player.addChatMessage("Ore Meter!"); -// player.addChatMessage("Metering chunks in radius " + radius + " around chunk [" + chunkX + ", " + chunkZ + "]"); -// player.addChatMessage("Coal - " + countCoal + " " + percent(countCoal, total)); -// player.addChatMessage("Iron - " + countIron + " " + percent(countIron, total)); -// player.addChatMessage("Gold - " + countGold + " " + percent(countGold, total)); -// player.addChatMessage("Diamond - " + countDiamond + " " + percent(countDiamond, total) + ", exposed - " + countExposedDiamond); -// player.addChatMessage("Lapis - " + countLapis + " " + percent(countLapis, total)); -// player.addChatMessage("Redstone - " + countRedstone + " " + percent(countRedstone, total)); -// player.addChatMessage("Roots - " + countRoots + " " + percent(countRoots, total)); -// player.addChatMessage("Ore Roots - " + countOreRoots + " " + percent(countOreRoots, total)); - } - - public float percent(int count, int total) { - return (float)count / (float)total * 100F; - } - - public int countBlockInChunk(World world, Block stone, int cx, int cz) { - - Chunk chunk = world.getChunkFromChunkCoords(cx, cz); - - int count = 0; - - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - for (int y = 0; y < 256; y++) { - if (chunk.getBlock(x, y, z) == stone) { - count++; - } - } - } - } - - return count; - } - - public int countBlockInChunk(World world, Block blockID, int meta, int cx, int cz) { - - Chunk chunk = world.getChunkFromChunkCoords(cx, cz); - - int count = 0; - - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - for (int y = 0; y < 256; y++) { - if (chunk.getBlock(x, y, z) == blockID && chunk.getBlockMetadata(x, y, z) == meta) { - count++; - } - } - } - } - - return count; + player.sendMessage(new TextComponentTranslation(getTranslationKey() + ".name").appendText("!")); + player.sendMessage(new TextComponentTranslation(TwilightForestMod.ID + ".ore_meter.range", radius, chunkX, chunkZ)); + player.sendMessage(new TextComponentTranslation(Blocks.COAL_ORE.getTranslationKey() + ".name").appendText(" - " + countCoal + " " + percent(countCoal, total))); + player.sendMessage(new TextComponentTranslation(Blocks.IRON_ORE.getTranslationKey() + ".name").appendText(" - " + countIron + " " + percent(countIron, total))); + player.sendMessage(new TextComponentTranslation(Blocks.GOLD_ORE.getTranslationKey() + ".name").appendText(" - " + countGold + " " + percent(countGold, total))); + player.sendMessage(new TextComponentTranslation(Blocks.DIAMOND_ORE.getTranslationKey() + ".name").appendText(" - " + countDiamond + " " + percent(countDiamond, total) + ", ").appendSibling(new TextComponentTranslation(TwilightForestMod.ID + ".ore_meter.exposed", countExposedDiamond))); + player.sendMessage(new TextComponentTranslation(Blocks.LAPIS_ORE.getTranslationKey() + ".name").appendText(" - " + countLapis + " " + percent(countLapis, total))); + player.sendMessage(new TextComponentTranslation(Blocks.REDSTONE_ORE.getTranslationKey() + ".name").appendText(" - " + countRedstone + " " + percent(countRedstone, total))); + player.sendMessage(new TextComponentTranslation(new ItemStack(TFBlocks.root).getTranslationKey() + ".name").appendText(" - " + countRoots + " " + percent(countRoots, total))); + player.sendMessage(new TextComponentTranslation(new ItemStack(TFBlocks.root, 1, 1).getTranslationKey() + ".name").appendText(" - " + countOreRoots + " " + percent(countOreRoots, total))); } - private int countExposedBlockInChunk(World world, Block blockID, int cx, int cz) { - - int count = 0; + private String percent(int count, int total) { + return Float.toString((float) count / (float) total * 100F) + "%"; + } + private Map countBlocksInChunk(World world, int cx, int cz) { + Map ret = new IdentityHashMap<>(); + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); for (int x = cx << 4; x < (cx << 4) + 16; x++) { for (int z = cz << 4; z < (cz << 4) + 16; z++) { for (int y = 0; y < 256; y++) { - if (world.getBlock(x, y, z) == blockID) { - // check if exposed - if (world.isAirBlock(x + 1, y, z) || world.isAirBlock(x - 1, y, z) - ||world.isAirBlock(x, y + 1, z) || world.isAirBlock(x, y - 1, z) - ||world.isAirBlock(x, y + 1, z) || world.isAirBlock(x, y - 1, z)) - { - count++; + IBlockState state = world.getBlockState(pos.setPos(x, y, z)); + ScanResult res = ret.computeIfAbsent(state, s -> new ScanResult()); + res.count++; + + for (EnumFacing e : EnumFacing.VALUES) { + if (world.isAirBlock(pos.setPos(x, y, z).move(e))) { + res.exposedCount++; + break; } } } } } - - return count; + return ret; } - - - @Override - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); + private static class ScanResult { + int count; + int exposedCount; } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFPeacockFan.java b/src/main/java/twilightforest/item/ItemTFPeacockFan.java index a48ef6f5da..f3f8044c26 100644 --- a/src/main/java/twilightforest/item/ItemTFPeacockFan.java +++ b/src/main/java/twilightforest/item/ItemTFPeacockFan.java @@ -1,235 +1,146 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.block.Block; import net.minecraft.block.BlockFlower; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.init.MobEffects; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class ItemTFPeacockFan extends ItemTF -{ - protected ItemTFPeacockFan() { - super(); - this.setCreativeTab(TFItems.creativeTab); +import twilightforest.util.WorldUtil; + +import javax.annotation.Nonnull; + +public class ItemTFPeacockFan extends ItemTF { + ItemTFPeacockFan(EnumRarity rarity) { + super(rarity); this.maxStackSize = 1; - this.setMaxDamage(1024); + this.setMaxDamage(1024); } - - @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World world, EntityPlayer player) { - if (!world.isRemote) - { - if (!player.onGround) - { - player.addPotionEffect(new PotionEffect(Potion.jump.id, 45, 0)); - } - else - { - int fanned = 0; - - fanned = doFan(world, player); + @Nonnull + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { - if (fanned > 0) - { - par1ItemStack.damageItem(fanned, player); + if (!world.isRemote) { + if (!player.onGround) { + player.addPotionEffect(new PotionEffect(MobEffects.JUMP_BOOST, 45, 0)); + } else { + int fanned = doFan(world, player); + if (fanned > 0) { + player.getHeldItem(hand).damageItem(fanned, player); } } - - } - else - { - - + } else { // jump if the player is in the air //TODO: only one extra jump per jump - if (!player.onGround && !player.isPotionActive(Potion.jump.id)) - { + if (!player.onGround && !player.isPotionActive(MobEffects.JUMP_BOOST)) { player.motionX *= 3F; player.motionY = 1.5F; player.motionZ *= 3F; player.fallDistance = 0.0F; - } - else - { - AxisAlignedBB fanBox = getEffectAABB(world, player); - Vec3 lookVec = player.getLookVec(); + } else { + AxisAlignedBB fanBox = getEffectAABB(player); + Vec3d lookVec = player.getLookVec(); // particle effect - for (int i = 0; i < 30; i++) - { - world.spawnParticle("cloud", fanBox.minX + world.rand.nextFloat() * (fanBox.maxX - fanBox.minX), - fanBox.minY + world.rand.nextFloat() * (fanBox.maxY - fanBox.minY), - fanBox.minZ + world.rand.nextFloat() * (fanBox.maxZ - fanBox.minZ), - lookVec.xCoord, lookVec.yCoord, lookVec.zCoord); + for (int i = 0; i < 30; i++) { + world.spawnParticle(EnumParticleTypes.CLOUD, fanBox.minX + world.rand.nextFloat() * (fanBox.maxX - fanBox.minX), + fanBox.minY + world.rand.nextFloat() * (fanBox.maxY - fanBox.minY), + fanBox.minZ + world.rand.nextFloat() * (fanBox.maxZ - fanBox.minZ), + lookVec.x, lookVec.y, lookVec.z); } - - } - world.playSound(player.posX + 0.5D, player.posY + 0.5D, player.posZ + 0.5D, "random.breath", 1.0F + itemRand.nextFloat(), itemRand.nextFloat() * 0.7F + 0.3F, false); + } + player.playSound(SoundEvents.ENTITY_PLAYER_BREATH, 1.0F + itemRand.nextFloat(), itemRand.nextFloat() * 0.7F + 0.3F); } - - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); - - return par1ItemStack; + + player.setActiveHand(hand); + + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); + } + + @Nonnull + @Override + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BLOCK; } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.block; - } - - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 20; - } - - /** - * Returns True is the item is renderer in full 3D when hold. - */ - @Override - public boolean isFull3D() - { - return true; - } - - /** - * Fannnn - */ - private int doFan(World world, EntityPlayer player) - { - AxisAlignedBB fanBox = getEffectAABB(world, player); - + + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 20; + } + + private int doFan(World world, EntityPlayer player) { + AxisAlignedBB fanBox = getEffectAABB(player); + fanBlocksInAABB(world, player, fanBox); - + fanEntitiesInAABB(world, player, fanBox); - + return 1; } - /** - * Move entities in the box - */ - private void fanEntitiesInAABB(World world, EntityPlayer player, AxisAlignedBB fanBox) - { - Vec3 moveVec = player.getLookVec(); - - List inBox = world.getEntitiesWithinAABB(Entity.class, fanBox); - - float force = 2.0F; - - for (Entity entity : inBox) - { - if (entity.canBePushed() || entity instanceof EntityItem) - { - entity.motionX = moveVec.xCoord * force; - entity.motionY = moveVec.yCoord * force; - entity.motionZ = moveVec.zCoord * force; + private void fanEntitiesInAABB(World world, EntityPlayer player, AxisAlignedBB fanBox) { + Vec3d moveVec = player.getLookVec().scale(2); + + for (Entity entity : world.getEntitiesWithinAABB(Entity.class, fanBox)) { + if (entity.canBePushed() || entity instanceof EntityItem) { + entity.motionX = moveVec.x; + entity.motionY = moveVec.y; + entity.motionZ = moveVec.z; } } - + } - private AxisAlignedBB getEffectAABB(World world, EntityPlayer player) { + private AxisAlignedBB getEffectAABB(EntityPlayer player) { double range = 3.0D; double radius = 2.0D; - Vec3 srcVec = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 lookVec = player.getLookVec(); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - - AxisAlignedBB crumbleBox = AxisAlignedBB.getBoundingBox(destVec.xCoord - radius, destVec.yCoord - radius, destVec.zCoord - radius, destVec.xCoord + radius, destVec.yCoord + radius, destVec.zCoord + radius); - return crumbleBox; + Vec3d srcVec = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); + Vec3d lookVec = player.getLookVec().scale(range); + Vec3d destVec = srcVec.add(lookVec.x, lookVec.y, lookVec.z); + + return new AxisAlignedBB(destVec.x - radius, destVec.y - radius, destVec.z - radius, destVec.x + radius, destVec.y + radius, destVec.z + radius); } + private int fanBlocksInAABB(World world, EntityPlayer player, AxisAlignedBB box) { + int fan = 0; + for (BlockPos pos : WorldUtil.getAllInBB(box)) { + fan += fanBlock(world, player, pos); + } + return fan; + } - /** - * Do fan effects on blocks in the bounding box - * @param player - */ - private int fanBlocksInAABB(World world, EntityPlayer player, AxisAlignedBB par1AxisAlignedBB) - { - - int minX = MathHelper.floor_double(par1AxisAlignedBB.minX); - int minY = MathHelper.floor_double(par1AxisAlignedBB.minY); - int minZ = MathHelper.floor_double(par1AxisAlignedBB.minZ); - int maxX = MathHelper.floor_double(par1AxisAlignedBB.maxX); - int maxY = MathHelper.floor_double(par1AxisAlignedBB.maxY); - int maxZ = MathHelper.floor_double(par1AxisAlignedBB.maxZ); - - int fan = 0; - - for (int dx = minX; dx <= maxX; ++dx) - { - for (int dy = minY; dy <= maxY; ++dy) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - fan += fanBlock(world, player, dx, dy, dz); - } - } - } - - - - return fan; - } - - private int fanBlock(World world, EntityPlayer player, int dx, int dy, int dz) { + private int fanBlock(World world, EntityPlayer player, BlockPos pos) { int cost = 0; - - Block currentID = world.getBlock(dx, dy, dz); - - if (currentID != Blocks.air) - { - int currentMeta = world.getBlockMetadata(dx, dy, dz); - - if (currentID instanceof BlockFlower) - { - if(currentID.canHarvestBlock(player, currentMeta) && itemRand.nextInt(3) == 0) - { - currentID.harvestBlock(world, player, dx, dy, dz, currentMeta); - world.setBlock(dx, dy, dz, Blocks.air, 0, 3); - world.playAuxSFX(2001, dx, dy, dz, Block.getIdFromBlock(currentID) + (currentMeta << 12)); + + IBlockState state = world.getBlockState(pos); + + if (state.getBlock() != Blocks.AIR) { + if (state.getBlock() instanceof BlockFlower) { + if (state.getBlock().canHarvestBlock(world, pos, player) && itemRand.nextInt(3) == 0) { + state.getBlock().harvestBlock(world, player, pos, state, world.getTileEntity(pos), ItemStack.EMPTY); + world.destroyBlock(pos, false); } } - } - + return cost; } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFPhantomArmor.java b/src/main/java/twilightforest/item/ItemTFPhantomArmor.java index 236c398464..aaf6f81838 100644 --- a/src/main/java/twilightforest/item/ItemTFPhantomArmor.java +++ b/src/main/java/twilightforest/item/ItemTFPhantomArmor.java @@ -1,98 +1,64 @@ package twilightforest.item; -import java.util.List; - import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentBindingCurse; +import net.minecraft.enchantment.EnchantmentVanishingCurse; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; + +import javax.annotation.Nullable; +import java.util.List; -public class ItemTFPhantomArmor extends ItemArmor { +public class ItemTFPhantomArmor extends ItemTFArmor implements ModelRegisterCallback { - public ItemTFPhantomArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int renderIndex, int armorType) { - super(par2EnumArmorMaterial, renderIndex, armorType); + public ItemTFPhantomArmor(ItemArmor.ArmorMaterial armorMaterial, EntityEquipmentSlot armorType, EnumRarity rarity) { + super(armorMaterial, armorType, rarity); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return an item rarity from EnumRarity - */ @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.epic; - } - - /** - * Called by RenderBiped and RenderPlayer to determine the armor texture that - * should be use for the currently equiped item. - * This will only be called on instances of ItemArmor. - * - * Returning null from this function will use the default value. - * - * @param stack ItemStack for the equpt armor - * @param entity The entity wearing the armor - * @param slot The slot the armor is in - * @param layer The render layer, either 1 or 2, 2 is only used for CLOTH armor by default - * @return Path of texture to bind, or null to use default - */ - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) - { - // there's no legs, so let's not worry about them + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + // there's no legs, so let's not worry about them return TwilightForestMod.ARMOR_DIR + "phantom_1.png"; } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + //istack.addEnchantment(TFEnchantment.reactFire, 2); + list.add(istack); + } + } + + @Override + @SideOnly(Side.CLIENT) + public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, ModelBiped original) { + return TwilightForestMod.proxy.getPhantomArmorModel(armorSlot); + } + @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - //istack.addEnchantment(TFEnchantment.reactFire, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with knightmetal ingots - return par2ItemStack.getItem() == TFItems.knightMetal ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * Override this method to have an item handle its own armor rendering. - * - * @param entityLiving The entity wearing the armor - * @param itemStack The itemStack to render the model of - * @param armorSlot 0=head, 1=torso, 2=legs, 3=feet - * - * @return A ModelBiped to render instead of the default - */ - @SideOnly(Side.CLIENT) - public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) - { - return TwilightForestMod.proxy.getPhantomArmorModel(armorSlot); - } + public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) { + return !(enchantment instanceof EnchantmentVanishingCurse) && !(enchantment instanceof EnchantmentBindingCurse) && enchantment.type.canEnchantItem(stack.getItem()); + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + tooltip.add(I18n.format(getTranslationKey() + ".tooltip")); + } } diff --git a/src/main/java/twilightforest/item/ItemTFScepterLifeDrain.java b/src/main/java/twilightforest/item/ItemTFScepterLifeDrain.java index 464116dd49..fda41694e7 100644 --- a/src/main/java/twilightforest/item/ItemTFScepterLifeDrain.java +++ b/src/main/java/twilightforest/item/ItemTFScepterLifeDrain.java @@ -1,277 +1,244 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; +import net.minecraft.init.MobEffects; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ActionResult; import net.minecraft.util.DamageSource; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import javax.annotation.Nullable; +import java.util.List; public class ItemTFScepterLifeDrain extends ItemTF { - protected ItemTFScepterLifeDrain() { - super(); - this.maxStackSize = 1; - this.setMaxDamage(99); + protected ItemTFScepterLifeDrain(EnumRarity rarity) { + super(rarity); + this.maxStackSize = 1; + this.setMaxDamage(99); this.setCreativeTab(TFItems.creativeTab); + } + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + player.setActiveHand(hand); + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - + @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World worldObj, EntityPlayer player) { - if (par1ItemStack.getItemDamage() < this.getMaxDamage()) { - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); - } - else { - player.stopUsingItem(); - } - - return par1ItemStack; + public float getXpRepairRatio(ItemStack stack) { + return 1f; } /** * Animates the target falling apart into a rain of shatter particles */ - public static void animateTargetShatter(World worldObj, EntityLivingBase target) { - for (int var1 = 0; var1 < 50; ++var1) - { - double gaussX = itemRand.nextGaussian() * 0.02D; - double gaussY = itemRand.nextGaussian() * 0.02D; - double gaussZ = itemRand.nextGaussian() * 0.02D; - double gaussFactor = 10.0D; - - Item popItem = getTargetDropItemId(target) != null ? getTargetDropItemId(target) : Items.rotten_flesh; - - worldObj.spawnParticle("iconcrack_" + Item.getIdFromItem(popItem), target.posX + itemRand.nextFloat() * target.width * 2.0F - target.width - gaussX * gaussFactor, target.posY + itemRand.nextFloat() * target.height - gaussY * gaussFactor, target.posZ + itemRand.nextFloat() * target.width * 2.0F - target.width - gaussZ * gaussFactor, gaussX, gaussY, gaussZ); + private static void animateTargetShatter(World world, EntityLivingBase target) { + int itemId = Item.getIdFromItem(getTargetDropItem(target)); + for (int i = 0; i < 50; ++i) { + double gaussX = itemRand.nextGaussian() * 0.02D; + double gaussY = itemRand.nextGaussian() * 0.02D; + double gaussZ = itemRand.nextGaussian() * 0.02D; + double gaussFactor = 10.0D; + world.spawnParticle(EnumParticleTypes.ITEM_CRACK, target.posX + itemRand.nextFloat() * target.width * 2.0F - target.width - gaussX * gaussFactor, target.posY + itemRand.nextFloat() * target.height - gaussY * gaussFactor, target.posZ + itemRand.nextFloat() * target.width * 2.0F - target.width - gaussZ * gaussFactor, gaussX, gaussY, gaussZ, itemId); } } - - public static Item getTargetDropItemId(EntityLivingBase target) { - //TODO: make this actually work - return Items.rotten_flesh; + + private static Item getTargetDropItem(EntityLivingBase target) { + // TODO: make this actually work + return Items.ROTTEN_FLESH; } /** * What, if anything, is the player currently looking at? */ - private Entity getPlayerLookTarget(World worldObj, EntityPlayer player) { + @Nullable + private Entity getPlayerLookTarget(World world, EntityLivingBase living) { Entity pointedEntity = null; double range = 20.0D; - Vec3 srcVec = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 lookVec = player.getLook(1.0F); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - float var9 = 1.0F; - List possibleList = worldObj.getEntitiesWithinAABBExcludingEntity(player, player.boundingBox.addCoord(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range).expand(var9, var9, var9)); - double hitDist = 0; - - for (Entity possibleEntity : possibleList) - { - - - if (possibleEntity.canBeCollidedWith()) - { - float borderSize = possibleEntity.getCollisionBorderSize(); - AxisAlignedBB collisionBB = possibleEntity.boundingBox.expand((double)borderSize, (double)borderSize, (double)borderSize); - MovingObjectPosition interceptPos = collisionBB.calculateIntercept(srcVec, destVec); - - if (collisionBB.isVecInside(srcVec)) - { - if (0.0D < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = 0.0D; - } - } - else if (interceptPos != null) - { - double possibleDist = srcVec.distanceTo(interceptPos.hitVec); - - if (possibleDist < hitDist || hitDist == 0.0D) - { - pointedEntity = possibleEntity; - hitDist = possibleDist; - } - } - } - } + Vec3d srcVec = new Vec3d(living.posX, living.posY + living.getEyeHeight(), living.posZ); + Vec3d lookVec = living.getLook(1.0F); + Vec3d destVec = srcVec.add(lookVec.x * range, lookVec.y * range, lookVec.z * range); + float var9 = 1.0F; + List possibleList = world.getEntitiesWithinAABBExcludingEntity(living, living.getEntityBoundingBox().expand(lookVec.x * range, lookVec.y * range, lookVec.z * range).grow(var9, var9, var9)); + double hitDist = 0; + + for (Entity possibleEntity : possibleList) { + + + if (possibleEntity.canBeCollidedWith()) { + float borderSize = possibleEntity.getCollisionBorderSize(); + AxisAlignedBB collisionBB = possibleEntity.getEntityBoundingBox().grow((double) borderSize, (double) borderSize, (double) borderSize); + RayTraceResult interceptPos = collisionBB.calculateIntercept(srcVec, destVec); + + if (collisionBB.contains(srcVec)) { + if (0.0D < hitDist || hitDist == 0.0D) { + pointedEntity = possibleEntity; + hitDist = 0.0D; + } + } else if (interceptPos != null) { + double possibleDist = srcVec.distanceTo(interceptPos.hitVec); + + if (possibleDist < hitDist || hitDist == 0.0D) { + pointedEntity = possibleEntity; + hitDist = possibleDist; + } + } + } + } return pointedEntity; } - - + + @Override - public void onUsingTick(ItemStack stack, EntityPlayer player, int count) { - World worldObj = player.worldObj; - - if (stack.getItemDamage() >= this.getMaxDamage()) { + public void onUsingTick(ItemStack stack, EntityLivingBase living, int count) { + World world = living.world; + + if (stack.getItemDamage() >= this.getMaxDamage(stack)) { // do not use - player.stopUsingItem(); + living.resetActiveHand(); return; } if (count % 5 == 0) { // is the player looking at an entity - Entity pointedEntity = getPlayerLookTarget(worldObj, player); + Entity pointedEntity = getPlayerLookTarget(world, living); if (pointedEntity != null && pointedEntity instanceof EntityLivingBase) { - EntityLivingBase target = (EntityLivingBase)pointedEntity; + EntityLivingBase target = (EntityLivingBase) pointedEntity; - if (target.getActivePotionEffect(Potion.moveSlowdown) != null || target.getHealth() < 1) { + if (target.getActivePotionEffect(MobEffects.SLOWNESS) != null || target.getHealth() < 1) { if (target.getHealth() <= 3) { // make it explode - makeRedMagicTrail(worldObj, player.posX, player.posY + player.getEyeHeight(), player.posZ, target.posX, target.posY + target.getEyeHeight(), target.posZ); - if (target instanceof EntityLiving) - { + makeRedMagicTrail(world, living.posX, living.posY + living.getEyeHeight(), living.posZ, target.posX, target.posY + target.getEyeHeight(), target.posZ); + if (target instanceof EntityLiving) { ((EntityLiving) target).spawnExplosionParticle(); } - worldObj.playSoundAtEntity(target, "game.player.hurt.fall.big", 1.0F, ((itemRand.nextFloat() - itemRand.nextFloat()) * 0.7F + 1.0F) * 2.0F); - animateTargetShatter(worldObj, (EntityLivingBase) target); - if (!worldObj.isRemote) { + target.playSound(SoundEvents.ENTITY_GENERIC_BIG_FALL, 1.0F, ((itemRand.nextFloat() - itemRand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + animateTargetShatter(world, (EntityLivingBase) target); + if (!world.isRemote) { target.setDead(); - target.onDeath(DamageSource.causeIndirectMagicDamage(player, player)); + target.onDeath(DamageSource.causeIndirectMagicDamage(living, living)); } - player.stopUsingItem(); - } - else { + living.resetActiveHand(); + } else { // we have hit this creature recently - if (!worldObj.isRemote) { - target.attackEntityFrom(DamageSource.causeIndirectMagicDamage(player, player), 3); + if (!world.isRemote) { + target.attackEntityFrom(DamageSource.causeIndirectMagicDamage(living, living), 3); // only do lifting effect on creatures weaker than the player - if (getMaxHealth(target) <= getMaxHealth(player)) { + if (getMaxHealth(target) <= getMaxHealth(living)) { target.motionX = 0; target.motionY = 0.2; target.motionZ = 0; } - target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 20, 2)); + target.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 20, 2)); if (count % 10 == 0) { // heal the player - player.heal(1); + living.heal(1); // and give foods - player.getFoodStats().addStats(1, 0.1F); + if (living instanceof EntityPlayer) + ((EntityPlayer) living).getFoodStats().addStats(1, 0.1F); } } } - } - else { + } else { // this is a new creature to start draining - makeRedMagicTrail(worldObj, player.posX, player.posY + player.getEyeHeight(), player.posZ, target.posX, target.posY + target.getEyeHeight(), target.posZ); + makeRedMagicTrail(world, living.posX, living.posY + living.getEyeHeight(), living.posZ, target.posX, target.posY + target.getEyeHeight(), target.posZ); - worldObj.playSoundAtEntity(player, "fire.ignite", 1.0F, (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.2F + 1.0F); + living.playSound(SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F, (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F + 1.0F); + + if (!world.isRemote) { + target.attackEntityFrom(DamageSource.causeIndirectMagicDamage(living, living), 1); - if (!worldObj.isRemote) { - target.attackEntityFrom(DamageSource.causeIndirectMagicDamage(player, player), 1); - // only do lifting effect on creatures weaker than the player - if (getMaxHealth(target) <= getMaxHealth(player)) { + if (getMaxHealth(target) <= getMaxHealth(living)) { target.motionX = 0; target.motionY = 0.2; target.motionZ = 0; } - target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 20, 2)); + target.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 20, 2)); } } - if (!worldObj.isRemote) { - stack.damageItem(1, player); + if (!world.isRemote) { + stack.damageItem(1, living); } } } } - - private float getMaxHealth(EntityLivingBase target) - { - return (float) target.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue(); + + private float getMaxHealth(EntityLivingBase target) { + return (float) target.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).getBaseValue(); } - /** - * Make a trail of particles from one point to another - */ - protected void makeRedMagicTrail(World worldObj, double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { + private void makeRedMagicTrail(World world, double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { // make particle trail - int particles = 32; - for (int i = 0; i < particles; i++) - { - double trailFactor = i / (particles - 1.0D); - float f = 1.0F; - float f1 = 0.5F; - float f2 = 0.5F; - double tx = srcX + (destX - srcX) * trailFactor + worldObj.rand.nextGaussian() * 0.005; - double ty = srcY + (destY - srcY) * trailFactor + worldObj.rand.nextGaussian() * 0.005; - double tz = srcZ + (destZ - srcZ) * trailFactor + worldObj.rand.nextGaussian() * 0.005; - worldObj.spawnParticle("mobSpell", tx, ty, tz, f, f1, f2); - } + int particles = 32; + for (int i = 0; i < particles; i++) { + double trailFactor = i / (particles - 1.0D); + float f = 1.0F; + float f1 = 0.5F; + float f2 = 0.5F; + double tx = srcX + (destX - srcX) * trailFactor + world.rand.nextGaussian() * 0.005; + double ty = srcY + (destY - srcY) * trailFactor + world.rand.nextGaussian() * 0.005; + double tz = srcZ + (destZ - srcZ) * trailFactor + world.rand.nextGaussian() * 0.005; + world.spawnParticle(EnumParticleTypes.SPELL_MOB, tx, ty, tz, f, f1, f2); + } } - - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.bow; - } - - - /** - * Return an item rarity from EnumRarity - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; + + @Override + public int getMaxItemUseDuration(ItemStack stack) { + return 72000; } - /** - * Display charges left in tooltip - */ @Override - @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add((par1ItemStack.getMaxDamage() - par1ItemStack.getItemDamage()) + " charges left"); + public EnumAction getItemUseAction(ItemStack stack) { + return EnumAction.BOW; } - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public boolean canContinueUsing(ItemStack oldStack, ItemStack newStack) { + return oldStack.getItem() == newStack.getItem(); + } + + @Override + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) { + return slotChanged || newStack.getItem() != oldStack.getItem(); + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format("twilightforest.scepter_charges", stack.getMaxDamage() - stack.getItemDamage())); + } } diff --git a/src/main/java/twilightforest/item/ItemTFSeekerBow.java b/src/main/java/twilightforest/item/ItemTFSeekerBow.java index 7bb86c6fc0..2c60cbda4d 100644 --- a/src/main/java/twilightforest/item/ItemTFSeekerBow.java +++ b/src/main/java/twilightforest/item/ItemTFSeekerBow.java @@ -1,25 +1,20 @@ package twilightforest.item; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; import twilightforest.entity.EntitySeekerArrow; public class ItemTFSeekerBow extends ItemTFBowBase { - - - public ItemTFSeekerBow() { - this.setTextureName(TwilightForestMod.ID + ":seekerbow"); - this.setCreativeTab(TFItems.creativeTab); - } - /** - * Get the arrow for this specific bow - */ - @Override - protected EntityArrow getArrow(World world, EntityPlayer entityPlayer, float velocity) { - return new EntitySeekerArrow(world, entityPlayer, velocity * 0.5F); + public ItemTFSeekerBow() { + this.setCreativeTab(TFItems.creativeTab); } + @Override + public EntityArrow customizeArrow(EntityArrow arrow) { + if (arrow.shootingEntity instanceof EntityLivingBase) { + return new EntitySeekerArrow(arrow.world, (EntityLivingBase) arrow.shootingEntity); + } + return arrow; + } } diff --git a/src/main/java/twilightforest/item/ItemTFShieldWand.java b/src/main/java/twilightforest/item/ItemTFShieldWand.java new file mode 100644 index 0000000000..fffe0a3e49 --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFShieldWand.java @@ -0,0 +1,63 @@ +package twilightforest.item; + +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.capabilities.CapabilityList; +import twilightforest.capabilities.shield.IShieldCapability; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class ItemTFShieldWand extends ItemTF { + + protected ItemTFShieldWand(EnumRarity rarity) { + super(rarity); + this.maxStackSize = 1; + this.setMaxDamage(9); + this.setCreativeTab(TFItems.creativeTab); + } + + @Nonnull + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + + if (stack.getItemDamage() == stack.getMaxDamage()) { + return ActionResult.newResult(EnumActionResult.FAIL, stack); + } + + if (!world.isRemote && player.hasCapability(CapabilityList.SHIELDS, null)) { + IShieldCapability cap = player.getCapability(CapabilityList.SHIELDS, null); + if(cap != null) + cap.replenishShields(); + stack.damageItem(1, player); + } + + if (!player.isCreative()) + player.getCooldownTracker().setCooldown(this, 1200); + + return ActionResult.newResult(EnumActionResult.SUCCESS, stack); + } + + @Override + public float getXpRepairRatio(ItemStack stack) { + return 0.1f; + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format("twilightforest.scepter_charges", stack.getMaxDamage() - stack.getItemDamage())); + } +} diff --git a/src/main/java/twilightforest/item/ItemTFSoup.java b/src/main/java/twilightforest/item/ItemTFSoup.java new file mode 100644 index 0000000000..bf91fe9c1b --- /dev/null +++ b/src/main/java/twilightforest/item/ItemTFSoup.java @@ -0,0 +1,10 @@ +package twilightforest.item; + +import net.minecraft.item.ItemSoup; +import twilightforest.client.ModelRegisterCallback; + +public class ItemTFSoup extends ItemSoup implements ModelRegisterCallback { + public ItemTFSoup(int healAmount) { + super(healAmount); + } +} diff --git a/src/main/java/twilightforest/item/ItemTFSpawnEgg.java b/src/main/java/twilightforest/item/ItemTFSpawnEgg.java deleted file mode 100644 index 4249fa115d..0000000000 --- a/src/main/java/twilightforest/item/ItemTFSpawnEgg.java +++ /dev/null @@ -1,167 +0,0 @@ -package twilightforest.item; - -import java.util.Iterator; -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IIconRegister; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.IEntityLivingData; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemMonsterPlacer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Facing; -import net.minecraft.util.IIcon; -import net.minecraft.util.StatCollector; -import net.minecraft.world.World; -import twilightforest.TwilightForestMod; -import twilightforest.entity.TFCreatures; -import twilightforest.entity.TFEntityEggInfo; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class ItemTFSpawnEgg extends ItemMonsterPlacer { - - protected ItemTFSpawnEgg() { - super(); - this.setHasSubtypes(true); - this.setCreativeTab(TFItems.creativeTab); - } - - @SideOnly(Side.CLIENT) - @Override - public int getColorFromItemStack(ItemStack par1ItemStack, int par2) - { - TFEntityEggInfo info = (TFEntityEggInfo)TFCreatures.entityEggs.get(Integer.valueOf(par1ItemStack.getItemDamage())); - return info != null ? (par2 == 0 ? info.primaryColor : info.secondaryColor) : 16777215; - } - - - @Override - @SideOnly(Side.CLIENT) - public String getItemStackDisplayName(ItemStack par1ItemStack) - { - String prefix = ("" + StatCollector.translateToLocal(this.getUnlocalizedName() + ".name")).trim(); - String entityname = TFCreatures.getStringFromID(par1ItemStack.getItemDamage()); - - if (entityname != null) - { - prefix = prefix + " " + StatCollector.translateToLocal(String.format("entity.%s.%s.name", TwilightForestMod.ID, entityname)); - } - - return prefix; - } - - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ - @Override - public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) - { - if (par3World.isRemote) - { - return true; - } - else - { - Block var11 = par3World.getBlock(par4, par5, par6); - par4 += Facing.offsetsXForSide[par7]; - par5 += Facing.offsetsYForSide[par7]; - par6 += Facing.offsetsZForSide[par7]; - double var12 = 0.0D; - - if (par7 == 1 && var11 == Blocks.fence || var11 == Blocks.nether_brick_fence) - { - var12 = 0.5D; - } - - Entity entity = spawnCreature(par3World, par1ItemStack.getItemDamage(), (double)par4 + 0.5D, (double)par5 + var12, (double)par6 + 0.5D); - - if (entity != null) - { - if (entity instanceof EntityLiving && par1ItemStack.hasDisplayName()) - { - ((EntityLiving)entity).setCustomNameTag(par1ItemStack.getDisplayName()); - } - - if (!par2EntityPlayer.capabilities.isCreativeMode) - { - --par1ItemStack.stackSize; - } - } - - return true; - } - } - - /** - * Spawns the creature specified by the egg's type in the location specified by the last three parameters. - * Parameters: world, entityID, x, y, z. - */ - public static Entity spawnCreature(World par0World, int par1, double par2, double par4, double par6) - { - //System.out.println("Trying to spawn twilight egg"); - - if (!TFCreatures.entityEggs.containsKey(Integer.valueOf(par1))) - { - return null; - } - else - { - Entity entityToSpawn = TFCreatures.createEntityByID(par1, par0World); - - if (entityToSpawn != null && entityToSpawn instanceof EntityLivingBase) - { - EntityLiving entityliving = (EntityLiving)entityToSpawn; - - entityToSpawn.setLocationAndAngles(par2, par4, par6, par0World.rand.nextFloat() * 360.0F, 0.0F); - entityliving.onSpawnWithEgg((IEntityLivingData)null); - par0World.spawnEntityInWorld(entityToSpawn); - ((EntityLiving)entityToSpawn).playLivingSound(); - } - - return entityToSpawn; - } - } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - Iterator var4 = TFCreatures.entityEggs.values().iterator(); - - while (var4.hasNext()) - { - TFEntityEggInfo var5 = (TFEntityEggInfo)var4.next(); - par3List.add(new ItemStack(par1, 1, var5.spawnedID)); - } - } - - /** - * Gets an icon index based on an item's damage value and the given render pass - */ - public IIcon getIconFromDamageForRenderPass(int par1, int par2) - { - return Items.spawn_egg.getIconFromDamageForRenderPass(par1, par2); - } - - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - ; // don't load anything - } -} diff --git a/src/main/java/twilightforest/item/ItemTFSteeleafArmor.java b/src/main/java/twilightforest/item/ItemTFSteeleafArmor.java index fa2afda64a..d6c570158c 100644 --- a/src/main/java/twilightforest/item/ItemTFSteeleafArmor.java +++ b/src/main/java/twilightforest/item/ItemTFSteeleafArmor.java @@ -1,89 +1,53 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.Entity; +import net.minecraft.init.Enchantments; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFSteeleafArmor extends ItemArmor { +public class ItemTFSteeleafArmor extends ItemTFArmor implements ModelRegisterCallback { - public ItemTFSteeleafArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int renderIndex, int armorType) { - super(par2EnumArmorMaterial, renderIndex, armorType); + public ItemTFSteeleafArmor(ItemArmor.ArmorMaterial material, EntityEquipmentSlot slot, EnumRarity rarity) { + super(material, slot, rarity); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return an item rarity from EnumRarity - */ @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.uncommon; + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + if (slot == EntityEquipmentSlot.LEGS) { + return TwilightForestMod.ARMOR_DIR + "steeleaf_2.png"; + } else { + return TwilightForestMod.ARMOR_DIR + "steeleaf_1.png"; + } } @Override - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) { - if(itemstack.getItem() == TFItems.steeleafPlate || itemstack.getItem() == TFItems.steeleafHelm || itemstack.getItem() == TFItems.steeleafBoots) - { - return TwilightForestMod.ARMOR_DIR + "steeleaf_1.png"; + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + switch (this.armorType) { + case HEAD: + istack.addEnchantment(Enchantments.PROJECTILE_PROTECTION, 2); + break; + case CHEST: + istack.addEnchantment(Enchantments.BLAST_PROTECTION, 2); + break; + case LEGS: + istack.addEnchantment(Enchantments.FIRE_PROTECTION, 2); + break; + case FEET: + istack.addEnchantment(Enchantments.FEATHER_FALLING, 2); + break; + default: + break; + } + list.add(istack); } - if(itemstack.getItem() == TFItems.steeleafLegs) - { - return TwilightForestMod.ARMOR_DIR + "steeleaf_2.png"; - } - return TwilightForestMod.ARMOR_DIR + "steeleaf_1.png"; } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) { - ItemStack istack = new ItemStack(par1, 1, 0); - switch (this.armorType) { - case 0: - istack.addEnchantment(Enchantment.projectileProtection, 2); - break; - case 1: - istack.addEnchantment(Enchantment.blastProtection, 2); - break; - case 2: - istack.addEnchantment(Enchantment.fireProtection, 2); - break; - case 3: - istack.addEnchantment(Enchantment.featherFalling, 2); - break; - } - par3List.add(istack); - } - - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with steeleaf ingots - return par2ItemStack.getItem() == TFItems.steeleafIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFSteeleafAxe.java b/src/main/java/twilightforest/item/ItemTFSteeleafAxe.java index 7e93828a2d..5f2ab6583a 100644 --- a/src/main/java/twilightforest/item/ItemTFSteeleafAxe.java +++ b/src/main/java/twilightforest/item/ItemTFSteeleafAxe.java @@ -1,52 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFSteeleafAxe extends ItemAxe { +public class ItemTFSteeleafAxe extends ItemAxe implements ModelRegisterCallback { - protected ItemTFSteeleafAxe(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFSteeleafAxe(Item.ToolMaterial material) { + super(material, 6F + material.getAttackDamage(), material.getEfficiency() * 0.05f - 3.4f); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.efficiency, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with steeleaf ingots - return par2ItemStack.getItem() == TFItems.steeleafIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.EFFICIENCY, 2); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFSteeleafHoe.java b/src/main/java/twilightforest/item/ItemTFSteeleafHoe.java index 7bf34a8e0f..4ba1dd81b1 100644 --- a/src/main/java/twilightforest/item/ItemTFSteeleafHoe.java +++ b/src/main/java/twilightforest/item/ItemTFSteeleafHoe.java @@ -1,37 +1,13 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.item.Item; import net.minecraft.item.ItemHoe; -import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFSteeleafHoe extends ItemHoe { +public class ItemTFSteeleafHoe extends ItemHoe implements ModelRegisterCallback { - public ItemTFSteeleafHoe(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFSteeleafHoe(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with steeleaf ingots - return par2ItemStack.getItem() == TFItems.steeleafIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFSteeleafPick.java b/src/main/java/twilightforest/item/ItemTFSteeleafPick.java index 6a75cb32c0..3ea4f5a41c 100644 --- a/src/main/java/twilightforest/item/ItemTFSteeleafPick.java +++ b/src/main/java/twilightforest/item/ItemTFSteeleafPick.java @@ -1,53 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFSteeleafPick extends ItemPickaxe { +public class ItemTFSteeleafPick extends ItemPickaxe implements ModelRegisterCallback { - protected ItemTFSteeleafPick(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + protected ItemTFSteeleafPick(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.fortune, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with steeleaf ingots - return par2ItemStack.getItem() == TFItems.steeleafIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.FORTUNE, 2); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFSteeleafShovel.java b/src/main/java/twilightforest/item/ItemTFSteeleafShovel.java index f5b8c6244d..24eafe7525 100644 --- a/src/main/java/twilightforest/item/ItemTFSteeleafShovel.java +++ b/src/main/java/twilightforest/item/ItemTFSteeleafShovel.java @@ -1,54 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemSpade; import net.minecraft.item.ItemStack; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFSteeleafShovel extends ItemSpade { +public class ItemTFSteeleafShovel extends ItemSpade implements ModelRegisterCallback { - public ItemTFSteeleafShovel(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFSteeleafShovel(Item.ToolMaterial toolMaterial) { + super(toolMaterial); this.setCreativeTab(TFItems.creativeTab); } - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.efficiency, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with steeleaf ingots - return par2ItemStack.getItem() == TFItems.steeleafIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.EFFICIENCY, 2); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFSteeleafSword.java b/src/main/java/twilightforest/item/ItemTFSteeleafSword.java index 5dd41cad6f..f366590ce1 100644 --- a/src/main/java/twilightforest/item/ItemTFSteeleafSword.java +++ b/src/main/java/twilightforest/item/ItemTFSteeleafSword.java @@ -1,53 +1,26 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; +import net.minecraft.init.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import twilightforest.TwilightForestMod; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.util.NonNullList; +import twilightforest.client.ModelRegisterCallback; -public class ItemTFSteeleafSword extends ItemSword { +public class ItemTFSteeleafSword extends ItemSword implements ModelRegisterCallback { - public ItemTFSteeleafSword(Item.ToolMaterial par2EnumToolMaterial) { - super(par2EnumToolMaterial); + public ItemTFSteeleafSword(Item.ToolMaterial material) { + super(material); this.setCreativeTab(TFItems.creativeTab); } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) - { - ItemStack istack = new ItemStack(par1, 1, 0); - istack.addEnchantment(Enchantment.looting, 2); - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with steeleaf ingots - return par2ItemStack.getItem() == TFItems.steeleafIngot ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + istack.addEnchantment(Enchantments.LOOTING, 2); + list.add(istack); + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFTowerKey.java b/src/main/java/twilightforest/item/ItemTFTowerKey.java index b14ccc354a..18e452a2b1 100644 --- a/src/main/java/twilightforest/item/ItemTFTowerKey.java +++ b/src/main/java/twilightforest/item/ItemTFTowerKey.java @@ -1,46 +1,37 @@ package twilightforest.item; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; +import net.minecraft.item.EnumRarity; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.enums.TowerDeviceVariant; -public class ItemTFTowerKey extends ItemTF -{ +import javax.annotation.Nonnull; - protected ItemTFTowerKey() { - super(); +public class ItemTFTowerKey extends ItemTF { + ItemTFTowerKey(EnumRarity rarity) { + super(rarity); } - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ - public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float fx, float fy, float fz) - { - if (!world.isRemote && world.getBlock(x, y, z) == TFBlocks.towerDevice && world.getBlockMetadata(x, y, z) == BlockTFTowerDevice.META_VANISH_LOCKED) - { - BlockTFTowerDevice.unlockBlock(world, x, y, z); - --itemStack.stackSize; + @Nonnull + @Override + public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float fx, float fy, float fz) { + IBlockState state = world.getBlockState(pos); + if (state.getBlock() == TFBlocks.tower_device && state.getValue(BlockTFTowerDevice.VARIANT) == TowerDeviceVariant.VANISH_LOCKED) { + if (!world.isRemote) { + BlockTFTowerDevice.unlockBlock(world, pos); + player.getHeldItem(hand).shrink(1); + } - return true; + return EnumActionResult.SUCCESS; } - return false; + return EnumActionResult.PASS; } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFTransformPowder.java b/src/main/java/twilightforest/item/ItemTFTransformPowder.java index 6283b44206..b7ac8236ad 100644 --- a/src/main/java/twilightforest/item/ItemTFTransformPowder.java +++ b/src/main/java/twilightforest/item/ItemTFTransformPowder.java @@ -1,190 +1,128 @@ package twilightforest.item; -import java.util.HashMap; - -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.monster.EntityBlaze; -import net.minecraft.entity.monster.EntityCaveSpider; -import net.minecraft.entity.monster.EntityPigZombie; -import net.minecraft.entity.monster.EntitySpider; -import net.minecraft.entity.monster.EntityWitch; -import net.minecraft.entity.passive.EntityBat; -import net.minecraft.entity.passive.EntityChicken; -import net.minecraft.entity.passive.EntityCow; -import net.minecraft.entity.passive.EntityPig; -import net.minecraft.entity.passive.EntitySheep; -import net.minecraft.entity.passive.EntityVillager; -import net.minecraft.entity.passive.EntityWolf; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.Vec3; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; + import twilightforest.TwilightForestMod; -import twilightforest.entity.EntityTFHedgeSpider; -import twilightforest.entity.EntityTFHostileWolf; -import twilightforest.entity.EntityTFMinotaur; -import twilightforest.entity.EntityTFRedcap; -import twilightforest.entity.EntityTFSkeletonDruid; -import twilightforest.entity.EntityTFSwarmSpider; -import twilightforest.entity.EntityTFWraith; -import twilightforest.entity.passive.EntityTFBighorn; -import twilightforest.entity.passive.EntityTFBoar; -import twilightforest.entity.passive.EntityTFDeer; -import twilightforest.entity.passive.EntityTFPenguin; -import twilightforest.entity.passive.EntityTFRaven; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class ItemTFTransformPowder extends ItemTF -{ - - HashMap, Class> transformMap; - - protected ItemTFTransformPowder() - { - super(); - this.maxStackSize = 64; +import twilightforest.util.TFEntityNames; +import twilightforest.util.VanillaEntityNames; + +import javax.annotation.Nonnull; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class ItemTFTransformPowder extends ItemTF { + + private final Map transformMap = new HashMap<>(); + + protected ItemTFTransformPowder() { + this.maxStackSize = 64; this.setCreativeTab(TFItems.creativeTab); - - transformMap = new HashMap, Class>(); - - - addTwoWayTransformation(EntityTFMinotaur.class, EntityPigZombie.class); - addTwoWayTransformation(EntityTFDeer.class, EntityCow.class); - addTwoWayTransformation(EntityTFBighorn.class, EntitySheep.class); - addTwoWayTransformation(EntityTFBoar.class, EntityPig.class); - addTwoWayTransformation(EntityTFRaven.class, EntityBat.class); - addTwoWayTransformation(EntityTFHostileWolf.class, EntityWolf.class); - addTwoWayTransformation(EntityTFPenguin.class, EntityChicken.class); - addTwoWayTransformation(EntityTFHedgeSpider.class, EntitySpider.class); - addTwoWayTransformation(EntityTFSwarmSpider.class, EntityCaveSpider.class); - addTwoWayTransformation(EntityTFWraith.class, EntityBlaze.class); - addTwoWayTransformation(EntityTFRedcap.class, EntityVillager.class); - addTwoWayTransformation(EntityTFSkeletonDruid.class, EntityWitch.class); - } - public void addTwoWayTransformation(Class class1, Class class2) { + addTwoWayTransformation(TFEntityNames.MINOTAUR, VanillaEntityNames.ZOMBIE_PIGMAN); + addTwoWayTransformation(TFEntityNames.DEER, VanillaEntityNames.COW); + addTwoWayTransformation(TFEntityNames.BIGHORN_SHEEP, VanillaEntityNames.SHEEP); + addTwoWayTransformation(TFEntityNames.WILD_BOAR, VanillaEntityNames.PIG); + addTwoWayTransformation(TFEntityNames.BUNNY, VanillaEntityNames.RABBIT); + addTwoWayTransformation(TFEntityNames.TINY_BIRD, VanillaEntityNames.PARROT); + addTwoWayTransformation(TFEntityNames.RAVEN, VanillaEntityNames.BAT); + addTwoWayTransformation(TFEntityNames.HOSTILE_WOLF, VanillaEntityNames.WOLF); + addTwoWayTransformation(TFEntityNames.PENGUIN, VanillaEntityNames.CHICKEN); + addTwoWayTransformation(TFEntityNames.HEDGE_SPIDER, VanillaEntityNames.SPIDER); + addTwoWayTransformation(TFEntityNames.SWARM_SPIDER, VanillaEntityNames.CAVE_SPIDER); + addTwoWayTransformation(TFEntityNames.WRAITH, VanillaEntityNames.BLAZE); + addTwoWayTransformation(TFEntityNames.REDCAP, VanillaEntityNames.VILLAGER); + addTwoWayTransformation(TFEntityNames.SKELETON_DRUID, VanillaEntityNames.WITCH); + } - transformMap.put(class1, class2); - transformMap.put(class2, class1); + private void addTwoWayTransformation(ResourceLocation from, ResourceLocation to) { + transformMap.put(from, to); + transformMap.put(to, from); } - /** - * dye sheep, place saddles, etc ... - */ @Override - public boolean itemInteractionForEntity(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, EntityLivingBase target) - { - // this is where we transform normal entities into twilight entities and vice versa - - Class transformClass = getMonsterTransform(target.getClass()); - - if (transformClass != null) - { - if (target.worldObj.isRemote) - { - // particles, sound - if (target instanceof EntityLiving) - { - ((EntityLiving) target).spawnExplosionParticle(); - ((EntityLiving) target).spawnExplosionParticle(); - } - - target.worldObj.playSound(target.posX + 0.5D, target.posY + 0.5D, target.posZ + 0.5D, "mob.zombie.remedy", 1.0F + itemRand.nextFloat(), itemRand.nextFloat() * 0.7F + 0.3F, false); - } - else - { - // add new monster with old monster's attributes - EntityLivingBase newMonster = null; - try - { - newMonster = (EntityLivingBase)transformClass.getConstructor(new Class[] {World.class}).newInstance(new Object[] {target.worldObj}); - } - catch (Exception e) - { - e.printStackTrace(); - } - - if (newMonster == null) - { - return false; - } - else - { - newMonster.setPositionAndRotation(target.posX, target.posY, target.posZ, target.rotationYaw, target.rotationPitch); - //newMonster.initCreature(); - - target.worldObj.spawnEntityInWorld(newMonster); - - // remove original monster - target.setDead(); - } - } - - --par1ItemStack.stackSize; - - return true; + public boolean itemInteractionForEntity(ItemStack stack, EntityPlayer player, EntityLivingBase target, EnumHand hand) { + + if (target.isDead) return false; + + ResourceLocation location = transformMap.get(EntityList.getKey(target)); + if (location == null) return false; + + if (target.world.isRemote) { + return EntityList.isRegistered(location); } - else - { - return false; + + Entity newEntity = EntityList.createEntityByIDFromName(location, target.world); + if (newEntity == null) return false; + + newEntity.setLocationAndAngles(target.posX, target.posY, target.posZ, target.rotationYaw, target.rotationPitch); + if (newEntity instanceof EntityLiving) { + ((EntityLiving) newEntity).onInitialSpawn(target.world.getDifficultyForLocation(new BlockPos(target)), null); } + + try { // try copying what can be copied + UUID uuid = newEntity.getUniqueID(); + newEntity.readFromNBT(target.writeToNBT(newEntity.writeToNBT(new NBTTagCompound()))); + newEntity.setUniqueId(uuid); + } catch (Exception e) { + TwilightForestMod.LOGGER.warn("Couldn't transform entity NBT data: {}", e); + } + + target.world.spawnEntity(newEntity); + target.setDead(); + stack.shrink(1); + + if (target instanceof EntityLiving) { + ((EntityLiving) target).spawnExplosionParticle(); + ((EntityLiving) target).spawnExplosionParticle(); + } + target.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 1.0F + itemRand.nextFloat(), itemRand.nextFloat() * 0.7F + 0.3F); + + return true; } - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ + @Nonnull @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World world, EntityPlayer player) - { - if (world.isRemote) - { - AxisAlignedBB fanBox = getEffectAABB(world, player); - + public ActionResult onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { + if (world.isRemote) { + AxisAlignedBB fanBox = getEffectAABB(player); + // particle effect - for (int i = 0; i < 30; i++) - { - world.spawnParticle("magicCrit", fanBox.minX + world.rand.nextFloat() * (fanBox.maxX - fanBox.minX), - fanBox.minY + world.rand.nextFloat() * (fanBox.maxY - fanBox.minY), - fanBox.minZ + world.rand.nextFloat() * (fanBox.maxZ - fanBox.minZ), + for (int i = 0; i < 30; i++) { + world.spawnParticle(EnumParticleTypes.CRIT_MAGIC, fanBox.minX + world.rand.nextFloat() * (fanBox.maxX - fanBox.minX), + fanBox.minY + world.rand.nextFloat() * (fanBox.maxY - fanBox.minY), + fanBox.minZ + world.rand.nextFloat() * (fanBox.maxZ - fanBox.minZ), 0, 0, 0); } } - - return par1ItemStack; + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); } - - private AxisAlignedBB getEffectAABB(World world, EntityPlayer player) { + + private AxisAlignedBB getEffectAABB(EntityPlayer player) { double range = 2.0D; double radius = 1.0D; - Vec3 srcVec = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 lookVec = player.getLookVec(); - Vec3 destVec = srcVec.addVector(lookVec.xCoord * range, lookVec.yCoord * range, lookVec.zCoord * range); - - return AxisAlignedBB.getBoundingBox(destVec.xCoord - radius, destVec.yCoord - radius, destVec.zCoord - radius, destVec.xCoord + radius, destVec.yCoord + radius, destVec.zCoord + radius); - } - - /** - * Which class should the specified monster class transform into? - */ - public Class getMonsterTransform(Class originalMonster) - { - return transformMap.get(originalMonster); + Vec3d srcVec = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); + Vec3d lookVec = player.getLookVec(); + Vec3d destVec = srcVec.add(lookVec.x * range, lookVec.y * range, lookVec.z * range); + + return new AxisAlignedBB(destVec.x - radius, destVec.y - radius, destVec.z - radius, destVec.x + radius, destVec.y + radius, destVec.z + radius); } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } -} \ No newline at end of file +} diff --git a/src/main/java/twilightforest/item/ItemTFTripleBow.java b/src/main/java/twilightforest/item/ItemTFTripleBow.java index a08ca72d37..40ac1ee560 100644 --- a/src/main/java/twilightforest/item/ItemTFTripleBow.java +++ b/src/main/java/twilightforest/item/ItemTFTripleBow.java @@ -1,119 +1,119 @@ package twilightforest.item; -import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.entity.projectile.EntityTippedArrow; +import net.minecraft.init.Enchantments; import net.minecraft.init.Items; +import net.minecraft.init.SoundEvents; +import net.minecraft.item.ItemArrow; import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatList; +import net.minecraft.util.SoundCategory; import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.ArrowLooseEvent; -import twilightforest.TwilightForestMod; public class ItemTFTripleBow extends ItemTFBowBase { - - - public ItemTFTripleBow() { - this.setTextureName(TwilightForestMod.ID + ":triplebow"); - this.setCreativeTab(TFItems.creativeTab); - } - - /** - * called when the player releases the use item button. Args: itemstack, world, entityplayer, itemInUseCount - */ - public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, int par4) - { - int j = this.getMaxItemUseDuration(par1ItemStack) - par4; - - ArrowLooseEvent event = new ArrowLooseEvent(par3EntityPlayer, par1ItemStack, j); - MinecraftForge.EVENT_BUS.post(event); - if (event.isCanceled()) - { - return; - } - j = event.charge; - - boolean flag = par3EntityPlayer.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, par1ItemStack) > 0; - - if (flag || par3EntityPlayer.inventory.hasItem(Items.arrow)) - { - float f = (float)j / 20.0F; - f = (f * f + f * 2.0F) / 3.0F; - - if ((double)f < 0.1D) - { - return; - } - - if (f > 1.0F) - { - f = 1.0F; - } - - EntityArrow entityarrow = new EntityArrow(par2World, par3EntityPlayer, f * 2.0F); - // other arrows with slight deviation - EntityArrow entityarrow1 = new EntityArrow(par2World, par3EntityPlayer, f * 2.0F); - entityarrow1.motionY += 0.007499999832361937D * 20F; - entityarrow1.posY += 0.025F; - EntityArrow entityarrow2 = new EntityArrow(par2World, par3EntityPlayer, f * 2.0F); - entityarrow2.motionY -= 0.007499999832361937D * 20F; - entityarrow2.posY -= 0.025F; - - if (f == 1.0F) - { - entityarrow.setIsCritical(true); - entityarrow1.setIsCritical(true); - entityarrow2.setIsCritical(true); - } - - int k = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, par1ItemStack); - - if (k > 0) - { - entityarrow.setDamage(entityarrow.getDamage() + (double)k * 0.5D + 0.5D); - entityarrow1.setDamage(entityarrow.getDamage() + (double)k * 0.5D + 0.5D); - entityarrow2.setDamage(entityarrow.getDamage() + (double)k * 0.5D + 0.5D); - } - - int l = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, par1ItemStack); - - if (l > 0) - { - entityarrow.setKnockbackStrength(l); - entityarrow1.setKnockbackStrength(l); - entityarrow2.setKnockbackStrength(l); - } - - if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, par1ItemStack) > 0) - { - entityarrow.setFire(100); - entityarrow1.setFire(100); - entityarrow2.setFire(100); - } - - par1ItemStack.damageItem(1, par3EntityPlayer); - par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F); - - if (flag) - { - entityarrow.canBePickedUp = 2; - } - else - { - par3EntityPlayer.inventory.consumeInventoryItem(Items.arrow); - } - entityarrow1.canBePickedUp = 2; - entityarrow2.canBePickedUp = 2; - - - if (!par2World.isRemote) - { - par2World.spawnEntityInWorld(entityarrow); - par2World.spawnEntityInWorld(entityarrow1); - par2World.spawnEntityInWorld(entityarrow2); - } - } - } + public ItemTFTripleBow() { + this.setCreativeTab(TFItems.creativeTab); + } + + // Half [VanillaCopy]: copy of modified super to fire three arrows + // TODO: make it less dirty + @SuppressWarnings("unused") + @Override + public void onPlayerStoppedUsing(ItemStack stack, World worldIn, EntityLivingBase entityLiving, int timeLeft) { + if (entityLiving instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entityLiving; + boolean flag = entityplayer.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantments.INFINITY, stack) > 0; + ItemStack itemstack = this.findAmmo(entityplayer); + + int i = this.getMaxItemUseDuration(stack) - timeLeft; + i = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, worldIn, entityplayer, i, !itemstack.isEmpty() || flag); + if (i < 0) return; + + if (!itemstack.isEmpty() || flag) { + if (itemstack.isEmpty()) { + itemstack = new ItemStack(Items.ARROW); + } + + float f = getArrowVelocity(i); + + if ((double) f >= 0.1D) { + boolean flag1 = entityplayer.capabilities.isCreativeMode || (itemstack.getItem() instanceof ItemArrow && ((ItemArrow) itemstack.getItem()).isInfinite(itemstack, stack, entityplayer)); + + if (!worldIn.isRemote) { + ItemArrow itemarrow = (ItemArrow) (itemstack.getItem() instanceof ItemArrow ? itemstack.getItem() : Items.ARROW); + EntityArrow entityarrow = itemarrow.createArrow(worldIn, itemstack, entityplayer); + entityarrow.shoot(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F, f * 3.0F, 1.0F); + + // other arrows with slight deviation + EntityArrow entityarrow1 = new EntityTippedArrow(worldIn, entityLiving); + entityarrow1.shoot(entityLiving, entityLiving.rotationPitch, entityLiving.rotationYaw, 0, f * 2, 1); + entityarrow1.motionY += 0.007499999832361937D * 20F; + entityarrow1.posY += 0.025F; + entityarrow1.pickupStatus = EntityArrow.PickupStatus.CREATIVE_ONLY; + + EntityArrow entityarrow2 = new EntityTippedArrow(worldIn, entityLiving); + entityarrow2.shoot(entityLiving, entityLiving.rotationPitch, entityLiving.rotationYaw, 0, f * 2, 1); + entityarrow2.motionY -= 0.007499999832361937D * 20F; + entityarrow2.posY -= 0.025F; + entityarrow2.pickupStatus = EntityArrow.PickupStatus.CREATIVE_ONLY; + + if (f == 1.0F) { + entityarrow.setIsCritical(true); + entityarrow1.setIsCritical(true); + entityarrow2.setIsCritical(true); + } + + int j = EnchantmentHelper.getEnchantmentLevel(Enchantments.POWER, stack); + + if (j > 0) { + entityarrow.setDamage(entityarrow.getDamage() + (double) j * 0.5D + 0.5D); + entityarrow1.setDamage(entityarrow.getDamage() + (double) j * 0.5D + 0.5D); + entityarrow2.setDamage(entityarrow.getDamage() + (double) j * 0.5D + 0.5D); + } + + int k = EnchantmentHelper.getEnchantmentLevel(Enchantments.PUNCH, stack); + + if (k > 0) { + entityarrow.setKnockbackStrength(k); + entityarrow1.setKnockbackStrength(k); + entityarrow2.setKnockbackStrength(k); + } + + if (EnchantmentHelper.getEnchantmentLevel(Enchantments.FLAME, stack) > 0) { + entityarrow.setFire(100); + entityarrow1.setFire(100); + entityarrow2.setFire(100); + } + + stack.damageItem(1, entityplayer); + + if (flag1 || entityplayer.capabilities.isCreativeMode && (itemstack.getItem() == Items.SPECTRAL_ARROW || itemstack.getItem() == Items.TIPPED_ARROW)) { + entityarrow.pickupStatus = EntityArrow.PickupStatus.CREATIVE_ONLY; + } + + worldIn.spawnEntity(entityarrow); + worldIn.spawnEntity(entityarrow1); + worldIn.spawnEntity(entityarrow2); + } + + worldIn.playSound((EntityPlayer) null, entityplayer.posX, entityplayer.posY, entityplayer.posZ, SoundEvents.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F); + + if (!flag1 && !entityplayer.capabilities.isCreativeMode) { + itemstack.shrink(1); + + if (itemstack.isEmpty()) { + entityplayer.inventory.deleteStack(itemstack); + } + } + + entityplayer.addStat(StatList.getObjectUseStats(this)); + } + } + } + } } diff --git a/src/main/java/twilightforest/item/ItemTFTrophy.java b/src/main/java/twilightforest/item/ItemTFTrophy.java index e32019b33a..7c5471fbb9 100644 --- a/src/main/java/twilightforest/item/ItemTFTrophy.java +++ b/src/main/java/twilightforest/item/ItemTFTrophy.java @@ -1,192 +1,168 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.ModelBakery; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntitySkull; -import net.minecraft.util.IIcon; -import net.minecraft.util.MathHelper; +import net.minecraft.util.*; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.translation.I18n; import net.minecraft.world.World; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.fml.client.registry.ClientRegistry; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFTrophy; import twilightforest.block.TFBlocks; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -public class ItemTFTrophy extends ItemTF -{ - private static final String[] trophyTypes = new String[] {"hydra", "naga", "lich", "ur-ghast", "snowQueen"}; - public static final String[] trophyTextures = new String[] {"hydraTrophy", "nagaTrophy", "lichTrophy", "urGhastTrophy", "snowQueenTrophy"}; - public IIcon[] trophyIcons; - - - public ItemTFTrophy() - { - super(); - this.setCreativeTab(TFItems.creativeTab); - this.setMaxDamage(0); - this.setHasSubtypes(true); +import twilightforest.enums.BossVariant; +import twilightforest.client.renderer.tileentity.TileEntityTFTrophyRenderer; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Locale; + +public class ItemTFTrophy extends ItemTF { + + public ItemTFTrophy() { + this.setCreativeTab(TFItems.creativeTab); + this.setMaxDamage(0); + this.setHasSubtypes(true); + } + + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + for (BossVariant v : BossVariant.values()) { + if (v != BossVariant.ALPHA_YETI && v != BossVariant.FINAL_BOSS) { + list.add(new ItemStack(this, 1, v.ordinal())); + } + } + } + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + return I18n.translateToLocalFormatted(this.getTranslationKey(stack), I18n.translateToLocal("entity.twilightforest." + BossVariant.values()[stack.getMetadata() % BossVariant.values().length].getName().toLowerCase(Locale.ROOT) + ".name")); + } + + @Nonnull + @Override + public EnumRarity getRarity(ItemStack stack) { + return TwilightForestMod.getRarity(); + } + + // [VanillaCopy] ItemSkull, with own block and no player heads + @Nonnull + @Override + public EnumActionResult onItemUse(EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + if (facing == EnumFacing.DOWN) { + return EnumActionResult.FAIL; + } else { + if (worldIn.getBlockState(pos).getBlock().isReplaceable(worldIn, pos)) { + facing = EnumFacing.UP; + pos = pos.down(); + } + IBlockState iblockstate = worldIn.getBlockState(pos); + Block block = iblockstate.getBlock(); + boolean flag = block.isReplaceable(worldIn, pos); + + if (!flag) { + if (!worldIn.getBlockState(pos).getMaterial().isSolid() && !worldIn.isSideSolid(pos, facing, true)) { + return EnumActionResult.FAIL; + } + + pos = pos.offset(facing); + } + + ItemStack itemstack = playerIn.getHeldItem(hand); + + if (playerIn.canPlayerEdit(pos, facing, itemstack) && TFBlocks.trophy.canPlaceBlockAt(worldIn, pos)) { + if (worldIn.isRemote) { + return EnumActionResult.SUCCESS; + } else { + worldIn.setBlockState(pos, TFBlocks.trophy.getDefaultState().withProperty(BlockTFTrophy.FACING, facing), 11); + int i = 0; + + if (facing == EnumFacing.UP) { + i = MathHelper.floor((double) (playerIn.rotationYaw * 16.0F / 360.0F) + 0.5D) & 15; + } + + TileEntity tileentity = worldIn.getTileEntity(pos); + + if (tileentity instanceof TileEntitySkull) { + TileEntitySkull tileentityskull = (TileEntitySkull) tileentity; + + tileentityskull.setType(itemstack.getMetadata()); + + tileentityskull.setSkullRotation(i); + } + + if (playerIn instanceof EntityPlayerMP) { + CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)playerIn, pos, itemstack); + } + + itemstack.shrink(1); + return EnumActionResult.SUCCESS; + } + } else { + return EnumActionResult.FAIL; + } + } } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) { - for (int j = 0; j < trophyTypes.length; ++j) { - par3List.add(new ItemStack(par1, 1, j)); - } - } - - - /** - * Return an item rarity from EnumRarity - * - * This is automatically uncommon - */ - @Override - @SideOnly(Side.CLIENT) - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; + + @Nonnull + @Override + public String getTranslationKey(ItemStack stack) { + //int meta = MathHelper.clamp(stack.getItemDamage(), 0, BossVariant.values().length); + return "item.twilightforest.tf_trophy.name"; //super.getUnlocalizedName() + "." + BossVariant.values()[meta].getName(); + } + + @Override + public boolean isValidArmor(ItemStack stack, EntityEquipmentSlot armorType, Entity entity) { + return armorType == EntityEquipmentSlot.HEAD; + } + + @Override + @Nullable + public EntityEquipmentSlot getEquipmentSlot(ItemStack stack) { + return EntityEquipmentSlot.HEAD; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerModel() { + + ModelResourceLocation itemModelLocation = new ModelResourceLocation(TwilightForestMod.ID + ":trophy_tesr", "inventory"); + + TileEntityTFTrophyRenderer tesr = new TileEntityTFTrophyRenderer(itemModelLocation); + //TileEntityTFTrophyRenderer tesrMinor = new TileEntityTFTrophyRenderer() { @Override protected String getModelRSL() { return TwilightForestMod.ID + ":trophy_minor"; } }; + + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTFTrophyRenderer.DummyTile.class, tesr); + + for (BossVariant variant : BossVariant.values()) { + if (variant != BossVariant.ALPHA_YETI) { + ModelLoader.setCustomModelResourceLocation(this, variant.ordinal(), itemModelLocation); + ForgeHooksClient.registerTESRItemStack(this, variant.ordinal(), TileEntityTFTrophyRenderer.DummyTile.class); + } + } + + ModelBakery.registerItemVariants(this, + new ModelResourceLocation(new ResourceLocation(TwilightForestMod.ID, "trophy"), "inventory"), + new ModelResourceLocation(new ResourceLocation(TwilightForestMod.ID, "trophy_minor"), "inventory"), + new ModelResourceLocation(new ResourceLocation(TwilightForestMod.ID, "trophy_quest"), "inventory") + ); } - - /** - * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return - * True if something happen and false if it don't. This is for ITEMS, not BLOCKS - */ - public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int direction, float par8, float par9, float par10) - { - if (direction == 0) - { - return false; - } - else if (!world.getBlock(x, y, z).getMaterial().isSolid()) - { - return false; - } - else - { - if (direction == 1) - { - ++y; - } - - if (direction == 2) - { - --z; - } - - if (direction == 3) - { - ++z; - } - - if (direction == 4) - { - --x; - } - - if (direction == 5) - { - ++x; - } - - if (!player.canPlayerEdit(x, y, z, direction, itemStack)) - { - return false; - } - else if (!TFBlocks.trophy.canPlaceBlockAt(world, x, y, z)) - { - return false; - } - else - { - world.setBlock(x, y, z, TFBlocks.trophy, direction, 3); - int skullRotate = 0; - - if (direction == 1) - { - skullRotate = MathHelper.floor_double((double)(player.rotationYaw * 16.0F / 360.0F) + 0.5D) & 15; - } - - TileEntity tileEntity = world.getTileEntity(x, y, z); - - if (tileEntity != null && tileEntity instanceof TileEntitySkull) - { - TileEntitySkull skull = ((TileEntitySkull)tileEntity); - - // use NBT method to set skulltype in order to have 1.7.10 compatibility - NBTTagCompound tags = new NBTTagCompound(); - skull.writeToNBT(tags); - tags.setByte("SkullType", (byte)(itemStack.getItemDamage() & 255)); - skull.readFromNBT(tags); - -// try { -// String skullName = ""; -// ((TileEntitySkull)tileEntity).func_145905_a(itemStack.getItemDamage(), skullName); -// } catch (NoSuchMethodError ex) { -// // stop checking admin -// FMLLog.warning("[TwilightForest] Could not determine op status for adminOnlyPortals option, ignoring option."); -// TwilightForestMod.adminOnlyPortals = false; -// } - skull.func_145903_a(skullRotate); - } - - --itemStack.stackSize; - return true; - } - } - } - - /** - * Returns the unlocalized name of this item. This version accepts an ItemStack so different stacks can have - * different names based on their damage or NBT. - */ - public String getUnlocalizedName(ItemStack par1ItemStack) - { - int i = par1ItemStack.getItemDamage(); - - if (i < 0 || i >= trophyTypes.length) - { - i = 0; - } - - return super.getUnlocalizedName() + "." + trophyTypes[i]; - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.trophyIcons = new IIcon[trophyTextures.length]; - - for (int i = 0; i < trophyTextures.length; ++i) - { - this.trophyIcons[i] = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + trophyTextures[i]); - } - } - - - /** - * Gets an icon index based on an item's damage value - */ - @SideOnly(Side.CLIENT) - public IIcon getIconFromDamage(int par1) - { - if (par1 < 0 || par1 >= trophyTypes.length) - { - par1 = 0; - } - - return this.trophyIcons[par1]; - } } diff --git a/src/main/java/twilightforest/item/ItemTFTwilightWand.java b/src/main/java/twilightforest/item/ItemTFTwilightWand.java index 3033fb3dfa..0ead9bc0c0 100644 --- a/src/main/java/twilightforest/item/ItemTFTwilightWand.java +++ b/src/main/java/twilightforest/item/ItemTFTwilightWand.java @@ -1,117 +1,58 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumAction; +import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.entity.EntityTFTwilightWandBolt; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import javax.annotation.Nullable; +import java.util.List; public class ItemTFTwilightWand extends ItemTF { - protected ItemTFTwilightWand() { - super(); - this.maxStackSize = 1; - this.setMaxDamage(99); + protected ItemTFTwilightWand(EnumRarity rarity) { + super(rarity); + this.maxStackSize = 1; + this.setMaxDamage(99); this.setCreativeTab(TFItems.creativeTab); - } @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World worldObj, EntityPlayer player) { - if (par1ItemStack.getItemDamage() < this.getMaxDamage()) - { - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); - } - else - { - player.stopUsingItem(); - } - - return par1ItemStack; - } - - /** - * Called each tick while using an item. - * @param stack The Item being used - * @param player The Player using the item - * @param count The amount of time in tick the item has been used for continuously - */ - @Override - public void onUsingTick(ItemStack stack, EntityPlayer player, int count) { - if (stack.getItemDamage() >= this.getMaxDamage()) { - // do not use - player.stopUsingItem(); - return; - } - - if (count % 6 == 0) { - World worldObj = player.worldObj; - - worldObj.playSoundAtEntity(player, "mob.ghast.fireball", 1.0F, (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.2F + 1.0F); - - if (!worldObj.isRemote) { - worldObj.spawnEntityInWorld(new EntityTFTwilightWandBolt(worldObj, player)); - + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + ItemStack stack = player.getHeldItem(hand); + + if (stack.getItemDamage() == stack.getMaxDamage()) { + return ActionResult.newResult(EnumActionResult.FAIL, player.getHeldItem(hand)); + } else { + player.playSound(SoundEvents.ENTITY_GHAST_SHOOT, 1.0F, (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F + 1.0F); + + if (!world.isRemote) { + world.spawnEntity(new EntityTFTwilightWandBolt(world, player)); stack.damageItem(1, player); } - } - + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); + } } - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 72000; - } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.bow; - } - - /** - * Return an item rarity from EnumRarity - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; + @Override + public float getXpRepairRatio(ItemStack stack) { + return 1f; } - /** - * Display charges left in tooltip - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add((par1ItemStack.getMaxDamage() - par1ItemStack.getItemDamage()) + " charges left"); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format("twilightforest.scepter_charges", stack.getMaxDamage() - stack.getItemDamage())); } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } } diff --git a/src/main/java/twilightforest/item/ItemTFYetiArmor.java b/src/main/java/twilightforest/item/ItemTFYetiArmor.java index 509d38a6e2..8fde2f7cb3 100644 --- a/src/main/java/twilightforest/item/ItemTFYetiArmor.java +++ b/src/main/java/twilightforest/item/ItemTFYetiArmor.java @@ -1,132 +1,72 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Enchantments; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; -import net.minecraft.util.StatCollector; +import net.minecraft.util.NonNullList; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.TwilightForestMod; -import twilightforest.enchantment.TFEnchantment; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import twilightforest.client.ModelRegisterCallback; + +import javax.annotation.Nullable; +import java.util.List; -public class ItemTFYetiArmor extends ItemArmor { +public class ItemTFYetiArmor extends ItemTFArmor implements ModelRegisterCallback { - public ItemTFYetiArmor(ItemArmor.ArmorMaterial par2EnumArmorMaterial, int renderIndex, int armorType) { - super(par2EnumArmorMaterial, renderIndex, armorType); + public ItemTFYetiArmor(ItemArmor.ArmorMaterial material, EntityEquipmentSlot slot, EnumRarity rarity) { + super(material, slot, rarity); this.setCreativeTab(TFItems.creativeTab); } - /** - * Return an item rarity from EnumRarity - */ @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.epic; - } - - /** - * Called by RenderBiped and RenderPlayer to determine the armor texture that - * should be use for the currently equiped item. - * This will only be called on instances of ItemArmor. - * - * Returning null from this function will use the default value. - * - * @param stack ItemStack for the equpt armor - * @param entity The entity wearing the armor - * @param slot The slot the armor is in - * @param layer The render layer, either 1 or 2, 2 is only used for CLOTH armor by default - * @return Path of texture to bind, or null to use default - */ - public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) { - switch (slot) { - case 0 : - case 3 : - default : - return TwilightForestMod.ARMOR_DIR + "yetiarmor_1.png"; - case 1 : - case 2 : + public String getArmorTexture(ItemStack itemstack, Entity entity, EntityEquipmentSlot slot, String layer) { + if (slot == EntityEquipmentSlot.LEGS || slot == EntityEquipmentSlot.CHEST) { return TwilightForestMod.ARMOR_DIR + "yetiarmor_2.png"; + } else { + return TwilightForestMod.ARMOR_DIR + "yetiarmor_1.png"; + } + } + @Override + public void getSubItems(CreativeTabs tab, NonNullList list) { + if (isInCreativeTab(tab)) { + ItemStack istack = new ItemStack(this); + switch (this.armorType) { + case HEAD: + case CHEST: + case LEGS: + istack.addEnchantment(Enchantments.PROTECTION, 2); + break; + case FEET: + istack.addEnchantment(Enchantments.PROTECTION, 2); + istack.addEnchantment(Enchantments.FEATHER_FALLING, 4); + break; + default: + break; + } + list.add(istack); } } - - /** - * returns a list of items with the same ID, but different meta (eg: dye returns 16 items) - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + + @SideOnly(Side.CLIENT) @Override - public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) { - ItemStack istack = new ItemStack(par1, 1, 0); - switch (this.armorType) { - case 0: - istack.addEnchantment(Enchantment.protection, 2); - break; - case 1: - istack.addEnchantment(Enchantment.protection, 2); - break; - case 2: - istack.addEnchantment(Enchantment.protection, 2); - break; - case 3: - istack.addEnchantment(Enchantment.protection, 2); - istack.addEnchantment(Enchantment.featherFalling, 4); - break; - } - par3List.add(istack); - } - - /** - * Return whether this item is repairable in an anvil. - */ - @Override - public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) - { - // repair with ????? - return par2ItemStack.getItem() == TFItems.alphaFur ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); - } - - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } - - /** - * Override this method to have an item handle its own armor rendering. - * - * @param entityLiving The entity wearing the armor - * @param itemStack The itemStack to render the model of - * @param armorSlot 0=head, 1=torso, 2=legs, 3=feet - * - * @return A ModelBiped to render instead of the default - */ - @SideOnly(Side.CLIENT) - public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) - { - return TwilightForestMod.proxy.getYetiArmorModel(armorSlot); - } - - /** - * allows items to add custom lines of information to the mouseover description - */ + public net.minecraft.client.model.ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, net.minecraft.client.model.ModelBiped _default) { + return TwilightForestMod.proxy.getYetiArmorModel(armorSlot); + } + @Override @SideOnly(Side.CLIENT) - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - super.addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); - par3List.add(StatCollector.translateToLocal(getUnlocalizedName() + ".tooltip")); + public void addInformation(ItemStack stack, @Nullable World world, List tooltips, ITooltipFlag flags) { + super.addInformation(stack, world, tooltips, flags); + tooltips.add(I18n.format(getTranslationKey() + ".tooltip")); } } diff --git a/src/main/java/twilightforest/item/ItemTFZombieWand.java b/src/main/java/twilightforest/item/ItemTFZombieWand.java index fa38748a37..cd8d17a9e3 100644 --- a/src/main/java/twilightforest/item/ItemTFZombieWand.java +++ b/src/main/java/twilightforest/item/ItemTFZombieWand.java @@ -1,127 +1,73 @@ package twilightforest.item; -import java.util.List; - -import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.util.ITooltipFlag; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.EnumAction; +import net.minecraft.init.MobEffects; import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.MovingObjectPosition; -import net.minecraft.util.Vec3; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; -import twilightforest.TwilightForestMod; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import twilightforest.entity.EntityTFLoyalZombie; -import cpw.mods.fml.common.FMLLog; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - +import twilightforest.util.EntityUtil; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; public class ItemTFZombieWand extends ItemTF { - protected ItemTFZombieWand() { - super(); - this.maxStackSize = 1; - this.setMaxDamage(9); + protected ItemTFZombieWand(EnumRarity rarity) { + super(rarity); + this.maxStackSize = 1; + this.setMaxDamage(9); this.setCreativeTab(TFItems.creativeTab); } + @Nonnull @Override - public ItemStack onItemRightClick(ItemStack par1ItemStack, World worldObj, EntityPlayer player) { - - if (par1ItemStack.getItemDamage() < this.getMaxDamage()) { - player.setItemInUse(par1ItemStack, this.getMaxItemUseDuration(par1ItemStack)); - - if (!worldObj.isRemote) { - // what block is the player pointing at? - MovingObjectPosition mop = getPlayerPointVec(worldObj, player, 20.0F); - - if (mop != null) { - // make a zombie there - EntityTFLoyalZombie zombie = new EntityTFLoyalZombie(worldObj); - zombie.setPositionAndRotation(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord, 1.0F, 1.0F); /// NPE here needs to be fixed - zombie.setTamed(true); - try { - zombie.func_152115_b(player.getUniqueID().toString()); - //zombie.setOwner(player.getCommandSenderName()); - } catch (NoSuchMethodError ex) { - // ignore? - FMLLog.warning("[TwilightForest] Could not determine player name for loyal zombie, ignoring error."); - } - zombie.addPotionEffect(new PotionEffect(Potion.damageBoost.id, 1200, 1)); - worldObj.spawnEntityInWorld(zombie); + public ActionResult onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { - par1ItemStack.damageItem(1, player); - } - } - } - else { - player.stopUsingItem(); + ItemStack stack = player.getHeldItem(hand); + + if (stack.getItemDamage() == stack.getMaxDamage()) { + return ActionResult.newResult(EnumActionResult.FAIL, stack); } - - return par1ItemStack; - } - - /** - * What block is the player pointing the wand at? - * - * This very similar to player.rayTrace, but that method is not available on the server. - * - * @return - */ - private MovingObjectPosition getPlayerPointVec(World worldObj, EntityPlayer player, float range) { - Vec3 position = Vec3.createVectorHelper(player.posX, player.posY + player.getEyeHeight(), player.posZ); - Vec3 look = player.getLook(1.0F); - Vec3 dest = position.addVector(look.xCoord * range, look.yCoord * range, look.zCoord * range); - return worldObj.rayTraceBlocks(position, dest); - } + if (!world.isRemote) { + // what block is the player pointing at? + RayTraceResult ray = EntityUtil.rayTrace(player, 20.0); + + if (ray != null && ray.hitVec != null) { + EntityTFLoyalZombie zombie = new EntityTFLoyalZombie(world); + zombie.setPositionAndRotation(ray.hitVec.x, ray.hitVec.y, ray.hitVec.z, 1.0F, 1.0F); + zombie.setTamed(true); + zombie.setOwnerId(player.getUniqueID()); + zombie.addPotionEffect(new PotionEffect(MobEffects.STRENGTH, 1200, 1)); + world.spawnEntity(zombie); + + stack.damageItem(1, player); + } + } - /** - * How long it takes to use or consume an item - */ - @Override - public int getMaxItemUseDuration(ItemStack par1ItemStack) - { - return 30; - } - - /** - * returns the action that specifies what animation to play when the items is being used - */ - @Override - public EnumAction getItemUseAction(ItemStack par1ItemStack) - { - return EnumAction.bow; - } - - /** - * Return an item rarity from EnumRarity - */ - @Override - public EnumRarity getRarity(ItemStack par1ItemStack) { - return EnumRarity.rare; + return ActionResult.newResult(EnumActionResult.SUCCESS, stack); } - - /** - * Display charges left in tooltip - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override - public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { - par3List.add((par1ItemStack.getMaxDamage() - par1ItemStack.getItemDamage()) + " charges left"); + public float getXpRepairRatio(ItemStack stack) { + return 0.1f; } - /** - * Properly register icon source - */ - @Override - @SideOnly(Side.CLIENT) - public void registerIcons(IIconRegister par1IconRegister) - { - this.itemIcon = par1IconRegister.registerIcon(TwilightForestMod.ID + ":" + this.getUnlocalizedName().substring(5)); - } + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flags) { + super.addInformation(stack, world, tooltip, flags); + tooltip.add(I18n.format("twilightforest.scepter_charges", stack.getMaxDamage() - stack.getItemDamage())); + } } diff --git a/src/main/java/twilightforest/item/RegisterItemEvent.java b/src/main/java/twilightforest/item/RegisterItemEvent.java new file mode 100644 index 0000000000..7031b60e5a --- /dev/null +++ b/src/main/java/twilightforest/item/RegisterItemEvent.java @@ -0,0 +1,337 @@ +package twilightforest.item; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.properties.IProperty; +import net.minecraft.item.*; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.registries.IForgeRegistry; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFLog; +import twilightforest.block.BlockTFMagicLog; +import twilightforest.block.TFBlocks; +import twilightforest.client.ModelRegisterCallback; +import twilightforest.compat.TFCompat; +import twilightforest.enums.DeadrockVariant; +import twilightforest.enums.MagicWoodVariant; +import twilightforest.enums.ThornVariant; +import twilightforest.enums.WoodVariant; +import twilightforest.util.IMapColorSupplier; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static java.util.Arrays.stream; +import static net.minecraft.init.MobEffects.REGENERATION; +import static net.minecraft.inventory.EntityEquipmentSlot.*; +import static net.minecraft.item.Item.ToolMaterial.DIAMOND; +import static net.minecraft.item.Item.ToolMaterial.GOLD; +import static twilightforest.item.TFItems.*; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class RegisterItemEvent { + @SubscribeEvent + public static void onRegisterItems(RegistryEvent.Register event) { + ItemRegistryHelper items = new ItemRegistryHelper(event.getRegistry()); + + items.register("naga_scale", "nagaScale", new ItemTF(EnumRarity.UNCOMMON)); + items.register("naga_chestplate", "plateNaga", new ItemTFNagaArmor(ARMOR_NAGA, CHEST, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("naga_leggings", "legsNaga", new ItemTFNagaArmor(ARMOR_NAGA, LEGS, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("twilight_scepter", "scepterTwilight", new ItemTFTwilightWand(EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("lifedrain_scepter", "scepterLifeDrain", new ItemTFScepterLifeDrain(EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("zombie_scepter", "scepterZombie", new ItemTFZombieWand(EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("shield_scepter", "scepterShield", new ItemTFShieldWand(EnumRarity.UNCOMMON).setMaxStackSize(1)); + //items.register("Wand of Pacification [NYI]", new ItemTF().setIconIndex(6).setTranslationKey("wandPacification").setMaxStackSize(1)); + items.register("ore_meter", "oreMeter", new ItemTFOreMeter().setMaxStackSize(1)); + items.register("magic_map", "magicMap", new ItemTFMagicMap().setMaxStackSize(1)); + items.register("maze_map", "mazeMap", new ItemTFMazeMap(false).setMaxStackSize(1)); + items.register("ore_map", "oreMap", new ItemTFMazeMap(true).setMaxStackSize(1)); + items.register("raven_feather", "tfFeather", new ItemTF()); + items.register("magic_map_focus", "magicMapFocus", new ItemTF()); + items.register("maze_map_focus", "mazeMapFocus", new ItemTF()); + items.register("liveroot", "liveRoot", new ItemTF()); + items.register("ironwood_raw", "ironwoodRaw", new ItemTF()); + items.register("ironwood_ingot", "ironwoodIngot", new ItemTF()); + items.register("ironwood_helmet", "ironwoodHelm", new ItemTFIronwoodArmor(ARMOR_IRONWOOD, HEAD, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("ironwood_chestplate", "ironwoodPlate", new ItemTFIronwoodArmor(ARMOR_IRONWOOD, CHEST, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("ironwood_leggings", "ironwoodLegs", new ItemTFIronwoodArmor(ARMOR_IRONWOOD, LEGS, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("ironwood_boots", "ironwoodBoots", new ItemTFIronwoodArmor(ARMOR_IRONWOOD, FEET, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("ironwood_sword", "ironwoodSword", new ItemTFIronwoodSword(TOOL_IRONWOOD).setMaxStackSize(1)); + items.register("ironwood_shovel", "ironwoodShovel", new ItemTFIronwoodShovel(TOOL_IRONWOOD).setMaxStackSize(1)); + items.register("ironwood_pickaxe", "ironwoodPick", new ItemTFIronwoodPick(TOOL_IRONWOOD).setMaxStackSize(1)); + items.register("ironwood_axe", "ironwoodAxe", new ItemTFIronwoodAxe(TOOL_IRONWOOD).setMaxStackSize(1)); + items.register("ironwood_hoe", "ironwoodHoe", new ItemTFIronwoodHoe(TOOL_IRONWOOD).setMaxStackSize(1)); + items.register("torchberries", "torchberries", new ItemTF()); + items.register("raw_venison", "venisonRaw", new ItemTFFood(3, 0.3F, true)); + items.register("cooked_venison", "venisonCooked", new ItemTFFood(8, 0.8F, true)); + items.register("hydra_chop", "hydraChop", new ItemTFHydraChops(18, 2.0F).setPotionEffect(new PotionEffect(REGENERATION, 100, 0), 1.0F)); + items.register("fiery_blood", "fieryBlood", new ItemTF(EnumRarity.UNCOMMON)); + items.register("fiery_tears", "fieryTears", new ItemTF(EnumRarity.UNCOMMON)); + items.register("trophy", "trophy", new ItemTFTrophy()); + items.register("fiery_ingot", "fieryIngot", new ItemTF(EnumRarity.UNCOMMON)); + items.register("fiery_helmet", "fieryHelm", new ItemTFFieryArmor(ARMOR_FIERY, HEAD, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("fiery_chestplate", "fieryPlate", new ItemTFFieryArmor(ARMOR_FIERY, CHEST, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("fiery_leggings", "fieryLegs", new ItemTFFieryArmor(ARMOR_FIERY, LEGS, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("fiery_boots", "fieryBoots", new ItemTFFieryArmor(ARMOR_FIERY, FEET, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("fiery_sword", "fierySword", new ItemTFFierySword(TOOL_FIERY).setMaxStackSize(1)); + items.register("fiery_pickaxe", "fieryPick", new ItemTFFieryPick(TOOL_FIERY).setMaxStackSize(1)); + items.register("steeleaf_ingot", "steeleafIngot", new ItemTF()); + items.register("steeleaf_helmet", "steeleafHelm", new ItemTFSteeleafArmor(ARMOR_STEELEAF, HEAD, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("steeleaf_chestplate", "steeleafPlate", new ItemTFSteeleafArmor(ARMOR_STEELEAF, CHEST, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("steeleaf_leggings", "steeleafLegs", new ItemTFSteeleafArmor(ARMOR_STEELEAF, LEGS, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("steeleaf_boots", "steeleafBoots", new ItemTFSteeleafArmor(ARMOR_STEELEAF, FEET, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("steeleaf_sword", "steeleafSword", new ItemTFSteeleafSword(TOOL_STEELEAF).setMaxStackSize(1)); + items.register("steeleaf_shovel", "steeleafShovel", new ItemTFSteeleafShovel(TOOL_STEELEAF).setMaxStackSize(1)); + items.register("steeleaf_pickaxe", "steeleafPick", new ItemTFSteeleafPick(TOOL_STEELEAF).setMaxStackSize(1)); + items.register("steeleaf_axe", "steeleafAxe", new ItemTFSteeleafAxe(TOOL_STEELEAF).setMaxStackSize(1)); + items.register("steeleaf_hoe", "steeleafHoe", new ItemTFSteeleafHoe(TOOL_STEELEAF).setMaxStackSize(1)); + items.register("minotaur_axe_gold", "minotaurAxeGold", new ItemTFMinotaurAxe(GOLD, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("minotaur_axe", "minotaurAxe", new ItemTFMinotaurAxe(DIAMOND, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("mazebreaker_pickaxe", "mazebreakerPick", new ItemTFMazebreakerPick(DIAMOND).setMaxStackSize(1)); + items.register("transformation_powder", "transformPowder", new ItemTFTransformPowder()); + items.register("raw_meef", "meefRaw", new ItemTFFood(2, 0.3F, true)); + items.register("cooked_meef", "meefSteak", new ItemTFFood(6, 0.6F, true)); + items.register("meef_stroganoff", "meefStroganoff", new ItemTFSoup(8)); + items.register("maze_wafer", "mazeWafer", new ItemTFFood(4, 0.6F, false)); + items.register("magic_map_empty", "emptyMagicMap", new ItemTFEmptyMagicMap()); + items.register("maze_map_empty", "emptyMazeMap", new ItemTFEmptyMazeMap(false)); + items.register("ore_map_empty", "emptyOreMap", new ItemTFEmptyMazeMap(true)); + items.register("ore_magnet", "oreMagnet", new ItemTFOreMagnet()); + items.register("crumble_horn", "crumbleHorn", new ItemTFCrumbleHorn(EnumRarity.RARE)); + items.register("peacock_fan", "peacockFan", new ItemTFPeacockFan(EnumRarity.RARE)); + items.register("moonworm_queen", "moonwormQueen", new ItemTFMoonwormQueen(EnumRarity.RARE)); + items.register("charm_of_life_1", "charmOfLife1", new ItemCharmBaubleable(EnumRarity.UNCOMMON)); + items.register("charm_of_life_2", "charmOfLife2", new ItemCharmBaubleable(EnumRarity.UNCOMMON)); + items.register("charm_of_keeping_1", "charmOfKeeping1", new ItemCharmBaubleable(EnumRarity.UNCOMMON)); + items.register("charm_of_keeping_2", "charmOfKeeping2", new ItemCharmBaubleable(EnumRarity.UNCOMMON)); + items.register("charm_of_keeping_3", "charmOfKeeping3", new ItemCharmBaubleable(EnumRarity.UNCOMMON)); + items.register("tower_key", "towerKey", new ItemTFTowerKey(EnumRarity.UNCOMMON)); + items.register("borer_essence", "borerEssence", new ItemTF()); + items.register("carminite", "carminite", new ItemTF()); + items.register("experiment_115", "experiment115", new ItemTFExperiment115()); + items.register("armor_shard", "armorShards", new ItemTF()); + items.register("knightmetal_ingot", "knightMetal", new ItemTF()); + items.register("armor_shard_cluster", "shardCluster", new ItemTF()); + items.register("knightmetal_helmet", "knightlyHelm", new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, HEAD, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("knightmetal_chestplate", "knightlyPlate", new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, CHEST, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("knightmetal_leggings", "knightlyLegs", new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, LEGS, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("knightmetal_boots", "knightlyBoots", new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, FEET, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("knightmetal_sword", "knightlySword", new ItemTFKnightlySword(TOOL_KNIGHTLY).setMaxStackSize(1)); + items.register("knightmetal_pickaxe", "knightlyPick", new ItemTFKnightlyPick(TOOL_KNIGHTLY).setMaxStackSize(1)); + items.register("knightmetal_axe", "knightlyAxe", new ItemTFKnightlyAxe(TOOL_KNIGHTLY).setMaxStackSize(1)); + items.register("knightmetal_shield", "knightlyShield", new ItemKnightlyShield().setMaxStackSize(1)); + items.register("phantom_helmet", "phantomHelm", new ItemTFPhantomArmor(ARMOR_PHANTOM, HEAD, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("phantom_chestplate", "phantomPlate", new ItemTFPhantomArmor(ARMOR_PHANTOM, CHEST, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("lamp_of_cinders", "lampOfCinders", new ItemTFLampOfCinders(EnumRarity.UNCOMMON)); + items.register("alpha_fur", "alphaFur", new ItemTF(EnumRarity.UNCOMMON)); + items.register("yeti_helmet", "yetiHelm", new ItemTFYetiArmor(ARMOR_YETI, HEAD, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("yeti_chestplate", "yetiPlate", new ItemTFYetiArmor(ARMOR_YETI, CHEST, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("yeti_leggings", "yetiLegs", new ItemTFYetiArmor(ARMOR_YETI, LEGS, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("yeti_boots", "yetiBoots", new ItemTFYetiArmor(ARMOR_YETI, FEET, EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("ice_bomb", "iceBomb", new ItemTFIceBomb().setMaxStackSize(16)); + items.register("arctic_fur", "arcticFur", new ItemTF()); + items.register("arctic_helmet", "arcticHelm", new ItemTFArcticArmor(ARMOR_ARCTIC, HEAD, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("arctic_chestplate", "arcticPlate", new ItemTFArcticArmor(ARMOR_ARCTIC, CHEST, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("arctic_leggings", "arcticLegs", new ItemTFArcticArmor(ARMOR_ARCTIC, LEGS, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("arctic_boots", "arcticBoots", new ItemTFArcticArmor(ARMOR_ARCTIC, FEET, EnumRarity.COMMON).setMaxStackSize(1)); + items.register("magic_beans", "magicBeans", new ItemTFMagicBeans()); + items.register("giant_pickaxe", "giantPick", new ItemTFGiantPick(TOOL_GIANT).setMaxStackSize(1)); + items.register("giant_sword", "giantSword", new ItemTFGiantSword(TOOL_GIANT).setMaxStackSize(1)); + items.register("triple_bow", "tripleBow", new ItemTFTripleBow().setMaxStackSize(1)); + items.register("seeker_bow", "seekerBow", new ItemTFSeekerBow().setMaxStackSize(1)); + items.register("ice_bow", "iceBow", new ItemTFIceBow().setMaxStackSize(1)); + items.register("ender_bow", "enderBow", new ItemTFEnderBow().setMaxStackSize(1)); + items.register("ice_sword", "iceSword", new ItemTFIceSword(TOOL_ICE).setMaxStackSize(1)); + items.register("glass_sword", "glassSword", new ItemTFGlassSword(TOOL_GLASS).setMaxStackSize(1)); + items.register("knightmetal_ring", "knightmetalRing", new ItemTF()); + items.register("block_and_chain", "chainBlock", new ItemTFChainBlock().setMaxStackSize(1)); + items.register("cube_talisman", "cubeTalisman", new ItemTF(EnumRarity.UNCOMMON)); + items.register("cube_of_annihilation", "cubeOfAnnihilation", new ItemTFCubeOfAnnihilation(EnumRarity.UNCOMMON).setMaxStackSize(1)); + items.register("moon_dial", "moonDial", new ItemTFMoonDial()); + + String[] thornNames = stream(ThornVariant.values()).map(IStringSerializable::getName).toArray(String[]::new); + String[] deadrockNames = stream(DeadrockVariant.values()).map(IStringSerializable::getName).toArray(String[]::new); + // register blocks with their pickup values + items.registerSubItemBlock(TFBlocks.twilight_log); + items.registerSubItemBlock(TFBlocks.root); + items.register(new ItemBlockTFLeaves(TFBlocks.twilight_leaves)); + items.register(new ItemBlockWearable(TFBlocks.firefly)); + items.register(new ItemBlockWearable(TFBlocks.cicada)); + items.registerSubItemBlock(TFBlocks.maze_stone); + items.registerSubItemBlock(TFBlocks.hedge); + items.registerSubItemBlock(TFBlocks.boss_spawner); + items.registerBlock(TFBlocks.firefly_jar); + items.register(new ItemBlockTFPlant(TFBlocks.twilight_plant)); + items.registerBlock(TFBlocks.uncrafting_table); + items.registerSubItemBlock(TFBlocks.fire_jet); + items.registerSubItemBlock(TFBlocks.naga_stone); + items.register(new ItemBlockTFMeta(TFBlocks.twilight_sapling) { + @Override + public int getItemBurnTime(ItemStack itemStack) { + return 100; + } + + @Override + public EnumRarity getRarity(ItemStack stack) { + switch (stack.getMetadata()) { + case 5: + case 6: + case 7: + case 8: + return EnumRarity.RARE; + default: + return EnumRarity.COMMON; + } + } + }.setAppend(true)); + items.register(new ItemBlockWearable(TFBlocks.moonworm)); + items.registerSubItemBlock(TFBlocks.magic_log); + items.register(new ItemBlockTFLeaves(TFBlocks.magic_leaves)); + items.registerSubItemBlock(TFBlocks.magic_log_core); + items.registerSubItemBlock(TFBlocks.tower_wood); + items.registerSubItemBlock(TFBlocks.tower_device); + items.registerSubItemBlock(TFBlocks.tower_translucent); + items.registerBlock(TFBlocks.stronghold_shield); + items.registerSubItemBlock(TFBlocks.trophy_pedestal); + items.registerBlock(TFBlocks.aurora_block); + items.registerSubItemBlock(TFBlocks.underbrick); + items.register(new ItemMultiTexture(TFBlocks.thorns, TFBlocks.thorns, thornNames)); + items.registerBlock(TFBlocks.burnt_thorns); + items.registerBlock(TFBlocks.thorn_rose); + items.register(new ItemBlockTFLeaves(TFBlocks.twilight_leaves_3)); + items.register(new ItemMultiTexture(TFBlocks.deadrock, TFBlocks.deadrock, deadrockNames)); + items.registerBlock(TFBlocks.dark_leaves); + items.registerBlock(TFBlocks.aurora_pillar); + items.register(new ItemSlab(TFBlocks.aurora_slab, TFBlocks.aurora_slab, TFBlocks.double_aurora_slab)); + items.registerBlock(TFBlocks.trollsteinn); + items.registerBlock(TFBlocks.wispy_cloud); + items.registerBlock(TFBlocks.fluffy_cloud); + items.register(new ItemTFGiantBlock(TFBlocks.giant_cobblestone)); + items.register(new ItemTFGiantBlock(TFBlocks.giant_log)); + items.register(new ItemTFGiantBlock(TFBlocks.giant_leaves)); + items.register(new ItemTFGiantBlock(TFBlocks.giant_obsidian)); + items.registerBlock(TFBlocks.uberous_soil); + items.registerBlock(TFBlocks.huge_stalk); + items.registerBlock(TFBlocks.huge_mushgloom); + items.registerBlock(TFBlocks.trollvidr); + items.registerBlock(TFBlocks.unripe_trollber); + items.registerBlock(TFBlocks.trollber); + items.registerBlock(TFBlocks.knightmetal_block); + items.register(new ItemBlockTFHugeLilyPad(TFBlocks.huge_lilypad)); + items.register(new ItemBlockTFHugeWaterLily(TFBlocks.huge_waterlily)); + items.registerSubItemBlock(TFBlocks.slider); + items.registerSubItemBlock(TFBlocks.castle_brick); + items.registerBlock(TFBlocks.castle_stairs_brick); + items.registerBlock(TFBlocks.castle_stairs_cracked); + items.registerBlock(TFBlocks.castle_stairs_worn); + items.registerBlock(TFBlocks.castle_stairs_mossy); + items.registerSubItemBlock(TFBlocks.castle_pillar); + items.registerSubItemBlock(TFBlocks.castle_stairs); + items.registerSubItemBlock(TFBlocks.castle_rune_brick); + items.registerSubItemBlock(TFBlocks.force_field); + items.registerBlock(TFBlocks.cinder_furnace); + items.registerBlock(TFBlocks.cinder_log); + items.registerSubItemBlock(TFBlocks.castle_door); + items.register(new ItemTFMiniatureStructure(TFBlocks.miniature_structure)); + items.register(new ItemTFCompressed(TFBlocks.block_storage)); + //items.registerBlock(TFBlocks.lapis_block); + items.registerBlock(TFBlocks.spiral_bricks); + items.registerBlock(TFBlocks.etched_nagastone); + items.registerBlock(TFBlocks.nagastone_pillar); + items.registerSubItemBlock(TFBlocks.nagastone_stairs); + items.registerBlock(TFBlocks.etched_nagastone_mossy); + items.registerBlock(TFBlocks.nagastone_pillar_mossy); + items.registerSubItemBlock(TFBlocks.nagastone_stairs_mossy); + items.registerBlock(TFBlocks.etched_nagastone_weathered); + items.registerBlock(TFBlocks.nagastone_pillar_weathered); + items.registerSubItemBlock(TFBlocks.nagastone_stairs_weathered); + items.registerBlock(TFBlocks.auroralized_glass); + items.registerBlock(TFBlocks.iron_ladder); + items.registerBlock(TFBlocks.terrorcotta_circle); + items.registerBlock(TFBlocks.terrorcotta_diagonal); + items.registerBlock(TFBlocks.stone_twist); + items.registerBlock(TFBlocks.stone_twist_thin); + + registerWoodVariants(items, BlockTFLog.VARIANT, WoodVariant.values()); + registerWoodVariants(items, BlockTFMagicLog.VARIANT, MagicWoodVariant.values()); + + TFCompat.initCompatItems(items); + } + + private static & IMapColorSupplier> void registerWoodVariants(ItemRegistryHelper items, IProperty key, T[] types) { + for (T woodType : types) { + String woodName = woodType.getName(); + + if ("oak".equals(woodName)) // Not really going to rename that enum entry just yet + woodName = "twilight_oak"; + + items.registerBlock(Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_planks"))); + items.registerBlock(Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_stairs"))); + BlockSlab slab = (BlockSlab) Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_slab")); + items.register(woodName + "_slab", new ItemSlab(slab, slab, (BlockSlab) Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_doubleslab")))); + items.registerBlock(Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_button"))); + + ResourceLocation doorRL = TwilightForestMod.prefix(woodName + "_door"); + Block doorBlock = Block.REGISTRY.getObject(doorRL); + items.register(doorRL.getPath(), new ItemDoor(doorBlock)).setTranslationKey(doorBlock.getTranslationKey()); + + items.registerBlock(Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_trapdoor"))); + items.registerBlock(Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_fence"))); + items.registerBlock(Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_gate"))); + items.registerBlock(Block.REGISTRY.getObject(TwilightForestMod.prefix(woodName + "_plate"))); + } + } + + public static List getItemModels() { + return Collections.unmodifiableList(ItemRegistryHelper.itemModels); + } + + public static class ItemRegistryHelper { + + static final List itemModels = new ArrayList<>(); + + private final IForgeRegistry registry; + + ItemRegistryHelper(IForgeRegistry registry) { + this.registry = registry; + } + + void register(String registryName, String translationKey, T item) { + item.setTranslationKey(TwilightForestMod.ID + "." + translationKey); + register(registryName, item); + } + + public Item register(String registryName, T item) { + item.setRegistryName(TwilightForestMod.ID, registryName); + if (item instanceof ModelRegisterCallback) { + itemModels.add((ModelRegisterCallback) item); + } + registry.register(item); + return item; + } + + void registerBlock(Block block) { + register(new ItemBlock(block)); + } + + void registerSubItemBlock(Block block) { + registerSubItemBlock(block, true); + } + + void registerSubItemBlock(Block block, boolean shouldAppendNumber) { + register(new ItemBlockTFMeta(block).setAppend(shouldAppendNumber)); + } + + void register(T item) { + item.setRegistryName(item.getBlock().getRegistryName()); + item.setTranslationKey(item.getBlock().getTranslationKey()); + registry.register(item); + } + } +} diff --git a/src/main/java/twilightforest/item/TFItems.java b/src/main/java/twilightforest/item/TFItems.java index e00d29f017..d88cf64232 100644 --- a/src/main/java/twilightforest/item/TFItems.java +++ b/src/main/java/twilightforest/item/TFItems.java @@ -1,24 +1,28 @@ package twilightforest.item; +import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; -import net.minecraft.potion.Potion; +import net.minecraft.item.ItemStack; import net.minecraftforge.common.util.EnumHelper; +import net.minecraftforge.fml.common.registry.GameRegistry; import twilightforest.TwilightForestMod; -import cpw.mods.fml.common.registry.GameRegistry; +import java.util.UUID; + +@GameRegistry.ObjectHolder(TwilightForestMod.ID) public class TFItems { + public static ItemArmor.ArmorMaterial ARMOR_NAGA = EnumHelper.addArmorMaterial("NAGA_SCALE", "naga_scale", 21, new int[]{3, 6, 7, 2}, 15, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 0.5F); + public static ItemArmor.ArmorMaterial ARMOR_IRONWOOD = EnumHelper.addArmorMaterial("IRONWOOD", "ironwood", 20, new int[]{2, 5, 7, 2}, 15, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 0F); + public static ItemArmor.ArmorMaterial ARMOR_FIERY = EnumHelper.addArmorMaterial("FIERY", "fiery", 25, new int[]{4, 7, 9, 4}, 10, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 1.5F); + public static ItemArmor.ArmorMaterial ARMOR_STEELEAF = EnumHelper.addArmorMaterial("STEELEAF", "steeleaf", 10, new int[]{3, 6, 8, 3}, 9, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 0F); + public static ItemArmor.ArmorMaterial ARMOR_KNIGHTLY = EnumHelper.addArmorMaterial("KNIGHTMETAL", "knightly", 20, new int[]{3, 6, 8, 3}, 8, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 1.0F); + public static ItemArmor.ArmorMaterial ARMOR_PHANTOM = EnumHelper.addArmorMaterial("KNIGHTPHANTOM", "phantom", 30, new int[]{3, 6, 8, 3}, 8, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 2.5F); + public static ItemArmor.ArmorMaterial ARMOR_YETI = EnumHelper.addArmorMaterial("YETI", "yetiarmor", 20, new int[]{3, 6, 7, 4}, 15, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 3F); + public static ItemArmor.ArmorMaterial ARMOR_ARCTIC = EnumHelper.addArmorMaterial("ARCTIC", "arcticarmor", 10, new int[]{2, 5, 7, 2}, 8, SoundEvents.ITEM_ARMOR_EQUIP_GENERIC, 2F); - public static ItemArmor.ArmorMaterial ARMOR_NAGA = EnumHelper.addArmorMaterial("NAGA_SCALE", 21, new int[] {2, 7, 6, 3}, 15); - public static ItemArmor.ArmorMaterial ARMOR_IRONWOOD = EnumHelper.addArmorMaterial("IRONWOOD", 20, new int[] {2, 7, 5, 2}, 15); - public static ItemArmor.ArmorMaterial ARMOR_FIERY = EnumHelper.addArmorMaterial("FIERY", 25, new int[] {4, 9, 7, 4}, 10); - public static ItemArmor.ArmorMaterial ARMOR_STEELEAF = EnumHelper.addArmorMaterial("STEELEAF", 10, new int[] {3, 8, 6, 3}, 9); - public static ItemArmor.ArmorMaterial ARMOR_KNIGHTLY = EnumHelper.addArmorMaterial("KNIGHTMETAL", 20, new int[] {3, 8, 6, 3}, 8); - public static ItemArmor.ArmorMaterial ARMOR_PHANTOM = EnumHelper.addArmorMaterial("KNIGHTPHANTOM", 30, new int[] {3, 8, 6, 3}, 8); - public static ItemArmor.ArmorMaterial ARMOR_YETI = EnumHelper.addArmorMaterial("YETI", 20, new int[] {4, 7, 6, 3}, 15); - public static ItemArmor.ArmorMaterial ARMOR_ARCTIC = EnumHelper.addArmorMaterial("ARCTIC", 10, new int[] {2, 7, 5, 2}, 8); - - + // harvestLevel, maxUses, efficiency, damage, enchantability public static Item.ToolMaterial TOOL_IRONWOOD = EnumHelper.addToolMaterial("IRONWOOD", 2, 512, 6.5F, 2, 25); public static Item.ToolMaterial TOOL_FIERY = EnumHelper.addToolMaterial("FIERY", 4, 1024, 9F, 4, 10); public static Item.ToolMaterial TOOL_STEELEAF = EnumHelper.addToolMaterial("STEELEAF", 3, 131, 8.0F, 3, 9); @@ -26,365 +30,376 @@ public class TFItems { public static Item.ToolMaterial TOOL_GIANT = EnumHelper.addToolMaterial("GIANTSTONE", 1, 1024, 4.0F, 1.0F, 5); public static Item.ToolMaterial TOOL_ICE = EnumHelper.addToolMaterial("TFICE", 0, 32, 1.0F, 3.5F, 5); public static Item.ToolMaterial TOOL_GLASS = EnumHelper.addToolMaterial("TFGLASS", 0, 1, 1.0F, 36.0F, 30); - - public static Item nagaScale; - public static Item plateNaga; - public static Item legsNaga; - public static Item scepterTwilight; - public static Item scepterLifeDrain; - public static Item scepterZombie; - public static Item wandPacification; - public static Item oreMeter; - public static Item magicMap; - public static Item mazeMap; - public static Item oreMap; - public static Item feather; - public static Item magicMapFocus; - public static Item mazeMapFocus; - public static Item liveRoot; - public static Item ironwoodRaw; - public static Item ironwoodIngot; - public static Item ironwoodHelm; - public static Item ironwoodPlate; - public static Item ironwoodLegs; - public static Item ironwoodBoots; - public static Item ironwoodSword; - public static Item ironwoodShovel; - public static Item ironwoodPick; - public static Item ironwoodAxe; - public static Item ironwoodHoe; - public static Item torchberries; - public static Item spawnEgg; - public static Item venisonRaw; - public static Item venisonCooked; - public static Item hydraChop; - public static Item fieryBlood; - public static Item trophy; - public static Item fieryIngot; - public static Item fieryHelm; - public static Item fieryPlate; - public static Item fieryLegs; - public static Item fieryBoots; - public static Item fierySword; - public static Item fieryPick; - public static Item steeleafIngot; - public static Item steeleafHelm; - public static Item steeleafPlate; - public static Item steeleafLegs; - public static Item steeleafBoots; - public static Item steeleafSword; - public static Item steeleafShovel; - public static Item steeleafPick; - public static Item steeleafAxe; - public static Item steeleafHoe; - public static Item minotaurAxe; - public static Item mazebreakerPick; - public static Item transformPowder; - public static Item meefRaw; - public static Item meefSteak; - public static Item meefStroganoff; - public static Item mazeWafer; - public static Item emptyMagicMap; - public static Item emptyMazeMap; - public static Item emptyOreMap; - public static Item oreMagnet; - public static Item crumbleHorn; - public static Item peacockFan; - public static Item moonwormQueen; - public static Item charmOfLife1; - public static Item charmOfLife2; - public static Item charmOfKeeping1; - public static Item charmOfKeeping2; - public static Item charmOfKeeping3; - public static Item towerKey; - public static Item borerEssence; - public static Item carminite; - public static Item experiment115; - public static Item armorShard; - public static Item knightMetal; - public static Item shardCluster; - public static Item knightlyHelm; - public static Item knightlyPlate; - public static Item knightlyLegs; - public static Item knightlyBoots; - public static Item knightlySword; - public static Item knightlyPick; - public static Item knightlyAxe; - public static Item phantomHelm; - public static Item phantomPlate; - public static Item lampOfCinders; - public static Item fieryTears; - public static Item alphaFur; - public static Item yetiHelm; - public static Item yetiPlate; - public static Item yetiLegs; - public static Item yetiBoots; - public static Item iceBomb; - public static Item arcticFur; - public static Item arcticHelm; - public static Item arcticPlate; - public static Item arcticLegs; - public static Item arcticBoots; - public static Item magicBeans; - public static Item giantPick; - public static Item giantSword; - public static Item tripleBow; - public static Item seekerBow; - public static Item iceBow; - public static Item enderBow; - public static Item iceSword; - public static Item glassSword; - public static Item knightmetalRing; - public static Item chainBlock; - public static Item cubeTalisman; - public static Item cubeOfAnnihilation; - public static CreativeTabTwilightForest creativeTab = new CreativeTabTwilightForest("twilightForest"); + static final UUID GIANT_REACH_MODIFIER = UUID.fromString("7f10172d-de69-49d7-81bd-9594286a6827"); - public static void registerItems() - { - int nagaScaleRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/nagascale_"); // the prefix doesn't seem to matter - int ironwoodRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/ironwood_"); // the prefix doesn't seem to matter - int fieryRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/fiery_"); // the prefix doesn't seem to matter - int steeleafRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/steeleaf_"); // the prefix doesn't seem to matter - int knightlyRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/knightly_"); // the prefix doesn't seem to matter - int phantomRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/phantom_"); // the prefix doesn't seem to matter - int yetiRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/yeti_"); // the prefix doesn't seem to matter - int arcticRenderID = TwilightForestMod.proxy.registerArmorRenderID("twilightforest/arctic_"); // the prefix doesn't seem to matter - - nagaScale = new ItemTF().setUnlocalizedName("nagaScale"); - plateNaga = new ItemTFNagaArmor(ARMOR_NAGA, nagaScaleRenderID, 1).setUnlocalizedName("plateNaga").setMaxStackSize(1); - legsNaga = new ItemTFNagaArmor(ARMOR_NAGA, nagaScaleRenderID, 2).setUnlocalizedName("legsNaga").setMaxStackSize(1); - scepterTwilight = new ItemTFTwilightWand().setUnlocalizedName("scepterTwilight").setMaxStackSize(1).setFull3D(); - scepterLifeDrain = new ItemTFScepterLifeDrain().setUnlocalizedName("scepterLifeDrain").setMaxStackSize(1).setFull3D(); - scepterZombie = new ItemTFZombieWand().setUnlocalizedName("scepterZombie").setMaxStackSize(1).setFull3D(); - //wandPacification = new ItemTF().setIconIndex(6).setUnlocalizedName("wandPacification").setMaxStackSize(1).setFull3D(); - oreMeter = new ItemTFOreMeter().setUnlocalizedName("oreMeter").setMaxStackSize(1); - magicMap = new ItemTFMagicMap().setUnlocalizedName("magicMap").setMaxStackSize(1); - mazeMap = new ItemTFMazeMap(false).setUnlocalizedName("mazeMap").setMaxStackSize(1); - oreMap = new ItemTFMazeMap(true).setUnlocalizedName("oreMap").setMaxStackSize(1); - feather = new ItemTF().setUnlocalizedName("tfFeather"); - magicMapFocus = new ItemTF().setUnlocalizedName("magicMapFocus"); - mazeMapFocus = new ItemTF().setUnlocalizedName("mazeMapFocus"); - liveRoot = new ItemTF().setUnlocalizedName("liveRoot"); - ironwoodRaw = new ItemTF().setUnlocalizedName("ironwoodRaw"); - ironwoodIngot = new ItemTF().setUnlocalizedName("ironwoodIngot"); - ironwoodHelm = new ItemTFIronwoodArmor(ARMOR_IRONWOOD, ironwoodRenderID, 0).setUnlocalizedName("ironwoodHelm").setMaxStackSize(1); - ironwoodPlate = new ItemTFIronwoodArmor(ARMOR_IRONWOOD, ironwoodRenderID, 1).setUnlocalizedName("ironwoodPlate").setMaxStackSize(1); - ironwoodLegs = new ItemTFIronwoodArmor(ARMOR_IRONWOOD, ironwoodRenderID, 2).setUnlocalizedName("ironwoodLegs").setMaxStackSize(1); - ironwoodBoots = new ItemTFIronwoodArmor(ARMOR_IRONWOOD, ironwoodRenderID, 3).setUnlocalizedName("ironwoodBoots").setMaxStackSize(1); - ironwoodSword = new ItemTFIronwoodSword(TOOL_IRONWOOD).setUnlocalizedName("ironwoodSword").setMaxStackSize(1); - ironwoodShovel = new ItemTFIronwoodShovel(TOOL_IRONWOOD).setUnlocalizedName("ironwoodShovel").setMaxStackSize(1); - ironwoodPick = new ItemTFIronwoodPick(TOOL_IRONWOOD).setUnlocalizedName("ironwoodPick").setMaxStackSize(1); - ironwoodAxe = new ItemTFIronwoodAxe(TOOL_IRONWOOD).setUnlocalizedName("ironwoodAxe").setMaxStackSize(1); - ironwoodHoe = new ItemTFIronwoodHoe(TOOL_IRONWOOD).setUnlocalizedName("ironwoodHoe").setMaxStackSize(1); - torchberries = new ItemTF().setUnlocalizedName("torchberries"); - spawnEgg = new ItemTFSpawnEgg().setUnlocalizedName("tfspawnegg"); - venisonRaw = (new ItemTFFood(3, 0.3F, true)).setUnlocalizedName("venisonRaw"); - venisonCooked = (new ItemTFFood(8, 0.8F, true)).setUnlocalizedName("venisonCooked"); - hydraChop = (new ItemTFHydraChops(18, 2.0F, true)).setPotionEffect(Potion.regeneration.id, 5, 0, 1.0F).setUnlocalizedName("hydraChop"); - fieryBlood = new ItemTF().makeRare().setUnlocalizedName("fieryBlood"); - trophy = new ItemTFTrophy().setUnlocalizedName("trophy"); - fieryIngot = new ItemTF().makeRare().setUnlocalizedName("fieryIngot"); - fieryHelm = new ItemTFFieryArmor(ARMOR_FIERY, fieryRenderID, 0).setUnlocalizedName("fieryHelm").setMaxStackSize(1); - fieryPlate = new ItemTFFieryArmor(ARMOR_FIERY, fieryRenderID, 1).setUnlocalizedName("fieryPlate").setMaxStackSize(1); - fieryLegs = new ItemTFFieryArmor(ARMOR_FIERY, fieryRenderID, 2).setUnlocalizedName("fieryLegs").setMaxStackSize(1); - fieryBoots = new ItemTFFieryArmor(ARMOR_FIERY, fieryRenderID, 3).setUnlocalizedName("fieryBoots").setMaxStackSize(1); - fierySword = new ItemTFFierySword(TOOL_FIERY).setUnlocalizedName("fierySword").setMaxStackSize(1); - fieryPick = new ItemTFFieryPick(TOOL_FIERY).setUnlocalizedName("fieryPick").setMaxStackSize(1); - steeleafIngot = new ItemTF().setUnlocalizedName("steeleafIngot"); - steeleafHelm = new ItemTFSteeleafArmor(ARMOR_IRONWOOD, steeleafRenderID, 0).setUnlocalizedName("steeleafHelm").setMaxStackSize(1); - steeleafPlate = new ItemTFSteeleafArmor(ARMOR_IRONWOOD, steeleafRenderID, 1).setUnlocalizedName("steeleafPlate").setMaxStackSize(1); - steeleafLegs = new ItemTFSteeleafArmor(ARMOR_IRONWOOD, steeleafRenderID, 2).setUnlocalizedName("steeleafLegs").setMaxStackSize(1); - steeleafBoots = new ItemTFSteeleafArmor(ARMOR_IRONWOOD, steeleafRenderID, 3).setUnlocalizedName("steeleafBoots").setMaxStackSize(1); - steeleafSword = new ItemTFSteeleafSword(TOOL_STEELEAF).setUnlocalizedName("steeleafSword").setMaxStackSize(1); - steeleafShovel = new ItemTFSteeleafShovel(TOOL_STEELEAF).setUnlocalizedName("steeleafShovel").setMaxStackSize(1); - steeleafPick = new ItemTFSteeleafPick(TOOL_STEELEAF).setUnlocalizedName("steeleafPick").setMaxStackSize(1); - steeleafAxe = new ItemTFSteeleafAxe(TOOL_STEELEAF).setUnlocalizedName("steeleafAxe").setMaxStackSize(1); - steeleafHoe = new ItemTFSteeleafHoe(TOOL_STEELEAF).setUnlocalizedName("steeleafHoe").setMaxStackSize(1); - minotaurAxe = new ItemTFMinotaurAxe(Item.ToolMaterial.EMERALD).setUnlocalizedName("minotaurAxe").setMaxStackSize(1); - mazebreakerPick = new ItemTFMazebreakerPick(Item.ToolMaterial.EMERALD).setUnlocalizedName("mazebreakerPick").setMaxStackSize(1); - transformPowder = new ItemTFTransformPowder().makeRare().setUnlocalizedName("transformPowder"); - meefRaw = (new ItemTFFood(2, 0.3F, true)).setUnlocalizedName("meefRaw"); - meefSteak = (new ItemTFFood(6, 0.6F, true)).setUnlocalizedName("meefSteak"); - meefStroganoff = (new ItemTFFood(8)).setUnlocalizedName("meefStroganoff"); - mazeWafer = (new ItemTFFood(4, 0.6F, false)).setUnlocalizedName("mazeWafer"); - emptyMagicMap = (new ItemTFEmptyMagicMap()).setUnlocalizedName("emptyMagicMap"); - emptyMazeMap = (new ItemTFEmptyMazeMap(false)).setUnlocalizedName("emptyMazeMap"); - emptyOreMap = (new ItemTFEmptyMazeMap(true)).setUnlocalizedName("emptyOreMap"); - oreMagnet = (new ItemTFOreMagnet()).setUnlocalizedName("oreMagnet"); - crumbleHorn = (new ItemTFCrumbleHorn()).setUnlocalizedName("crumbleHorn"); - peacockFan = (new ItemTFPeacockFan()).setUnlocalizedName("peacockFan"); - moonwormQueen = (new ItemTFMoonwormQueen()).setUnlocalizedName("moonwormQueen"); - charmOfLife1 = new ItemTFCharm().setUnlocalizedName("charmOfLife1"); - charmOfLife2 = new ItemTFCharm().setUnlocalizedName("charmOfLife2"); - charmOfKeeping1 = new ItemTFCharm().setUnlocalizedName("charmOfKeeping1"); - charmOfKeeping2 = new ItemTFCharm().setUnlocalizedName("charmOfKeeping2"); - charmOfKeeping3 = new ItemTFCharm().setUnlocalizedName("charmOfKeeping3"); - towerKey = new ItemTFTowerKey().setUnlocalizedName("towerKey"); - borerEssence = new ItemTF().setUnlocalizedName("borerEssence"); - carminite = new ItemTF().makeRare().setUnlocalizedName("carminite"); - experiment115 = (new ItemTFFood(4, 0.3F, false)).setUnlocalizedName("experiment115"); - armorShard = new ItemTF().setUnlocalizedName("armorShards"); - knightMetal = new ItemTF().setUnlocalizedName("knightMetal"); - shardCluster = new ItemTF().setUnlocalizedName("shardCluster"); - knightlyHelm = new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, knightlyRenderID, 0).setUnlocalizedName("knightlyHelm").setMaxStackSize(1); - knightlyPlate = new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, knightlyRenderID, 1).setUnlocalizedName("knightlyPlate").setMaxStackSize(1); - knightlyLegs = new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, knightlyRenderID, 2).setUnlocalizedName("knightlyLegs").setMaxStackSize(1); - knightlyBoots = new ItemTFKnightlyArmor(ARMOR_KNIGHTLY, knightlyRenderID, 3).setUnlocalizedName("knightlyBoots").setMaxStackSize(1); - knightlySword = new ItemTFKnightlySword(TOOL_KNIGHTLY).setUnlocalizedName("knightlySword").setMaxStackSize(1); - knightlyPick = new ItemTFKnightlyPick(TOOL_KNIGHTLY).setUnlocalizedName("knightlyPick").setMaxStackSize(1); - knightlyAxe = new ItemTFKnightlyAxe(TOOL_KNIGHTLY).setUnlocalizedName("knightlyAxe").setMaxStackSize(1); - phantomHelm = new ItemTFPhantomArmor(ARMOR_PHANTOM, phantomRenderID, 0).setUnlocalizedName("phantomHelm").setMaxStackSize(1); - phantomPlate = new ItemTFPhantomArmor(ARMOR_PHANTOM, phantomRenderID, 1).setUnlocalizedName("phantomPlate").setMaxStackSize(1); - lampOfCinders = new ItemTFLampOfCinders().setUnlocalizedName("lampOfCinders"); - fieryTears = new ItemTF().makeRare().setUnlocalizedName("fieryTears"); - alphaFur = new ItemTF().makeRare().setUnlocalizedName("alphaFur"); - yetiHelm = new ItemTFYetiArmor(ARMOR_YETI, yetiRenderID, 0).setUnlocalizedName("yetiHelm").setMaxStackSize(1); - yetiPlate = new ItemTFYetiArmor(ARMOR_YETI, yetiRenderID, 1).setUnlocalizedName("yetiPlate").setMaxStackSize(1); - yetiLegs = new ItemTFYetiArmor(ARMOR_YETI, yetiRenderID, 2).setUnlocalizedName("yetiLegs").setMaxStackSize(1); - yetiBoots = new ItemTFYetiArmor(ARMOR_YETI, yetiRenderID, 3).setUnlocalizedName("yetiBoots").setMaxStackSize(1); - iceBomb = new ItemTFIceBomb().makeRare().setUnlocalizedName("iceBomb").setMaxStackSize(16); - arcticFur = new ItemTF().setUnlocalizedName("arcticFur"); - arcticHelm = new ItemTFArcticArmor(ARMOR_ARCTIC, arcticRenderID, 0).setUnlocalizedName("arcticHelm").setMaxStackSize(1); - arcticPlate = new ItemTFArcticArmor(ARMOR_ARCTIC, arcticRenderID, 1).setUnlocalizedName("arcticPlate").setMaxStackSize(1); - arcticLegs = new ItemTFArcticArmor(ARMOR_ARCTIC, arcticRenderID, 2).setUnlocalizedName("arcticLegs").setMaxStackSize(1); - arcticBoots = new ItemTFArcticArmor(ARMOR_ARCTIC, arcticRenderID, 3).setUnlocalizedName("arcticBoots").setMaxStackSize(1); - magicBeans = new ItemTFMagicBeans().setUnlocalizedName("magicBeans"); - giantPick = new ItemTFGiantPick(TOOL_GIANT).setUnlocalizedName("giantPick").setMaxStackSize(1); - giantSword = new ItemTFGiantSword(TOOL_GIANT).setUnlocalizedName("giantSword").setMaxStackSize(1); - tripleBow = new ItemTFTripleBow().setUnlocalizedName("tripleBow").setMaxStackSize(1); - seekerBow = new ItemTFSeekerBow().setUnlocalizedName("seekerBow").setMaxStackSize(1); - iceBow = new ItemTFIceBow().setUnlocalizedName("iceBow").setMaxStackSize(1); - enderBow = new ItemTFEnderBow().setUnlocalizedName("enderBow").setMaxStackSize(1); - iceSword = new ItemTFIceSword(TOOL_ICE).setUnlocalizedName("iceSword").setMaxStackSize(1); - glassSword = new ItemTFGlassSword(TOOL_GLASS).setUnlocalizedName("glassSword").setMaxStackSize(1); - knightmetalRing = new ItemTF().setUnlocalizedName("knightmetalRing"); - chainBlock = new ItemTFChainBlock().setUnlocalizedName("chainBlock").setMaxStackSize(1); - cubeTalisman = new ItemTF().setUnlocalizedName("cubeTalisman"); - cubeOfAnnihilation = new ItemTFCubeOfAnnihilation().setUnlocalizedName("cubeOfAnnihilation").setMaxStackSize(1); + @GameRegistry.ObjectHolder("naga_scale") + public static final Item naga_scale; + @GameRegistry.ObjectHolder("naga_chestplate") + public static final Item naga_chestplate; + @GameRegistry.ObjectHolder("naga_leggings") + public static final Item naga_leggings; + @GameRegistry.ObjectHolder("twilight_scepter") + public static final Item twilight_scepter; + @GameRegistry.ObjectHolder("lifedrain_scepter") + public static final Item lifedrain_scepter; + @GameRegistry.ObjectHolder("zombie_scepter") + public static final Item zombie_scepter; + @GameRegistry.ObjectHolder("shield_scepter") + public static final Item shield_scepter; + @GameRegistry.ObjectHolder("ore_meter") + public static final Item ore_meter; + @GameRegistry.ObjectHolder("magic_map") + public static final Item magic_map; + @GameRegistry.ObjectHolder("maze_map") + public static final Item maze_map; + @GameRegistry.ObjectHolder("ore_map") + public static final Item ore_map; + @GameRegistry.ObjectHolder("raven_feather") + public static final Item raven_feather; + @GameRegistry.ObjectHolder("magic_map_focus") + public static final Item magic_map_focus; + @GameRegistry.ObjectHolder("maze_map_focus") + public static final Item maze_map_focus; + @GameRegistry.ObjectHolder("liveroot") + public static final Item liveroot; + @GameRegistry.ObjectHolder("ironwood_raw") + public static final Item ironwood_raw; + @GameRegistry.ObjectHolder("ironwood_ingot") + public static final Item ironwood_ingot; + @GameRegistry.ObjectHolder("ironwood_helmet") + public static final Item ironwood_helmet; + @GameRegistry.ObjectHolder("ironwood_chestplate") + public static final Item ironwood_chestplate; + @GameRegistry.ObjectHolder("ironwood_leggings") + public static final Item ironwood_leggings; + @GameRegistry.ObjectHolder("ironwood_boots") + public static final Item ironwood_boots; + @GameRegistry.ObjectHolder("ironwood_sword") + public static final Item ironwood_sword; + @GameRegistry.ObjectHolder("ironwood_shovel") + public static final Item ironwood_shovel; + @GameRegistry.ObjectHolder("ironwood_pickaxe") + public static final Item ironwood_pickaxe; + @GameRegistry.ObjectHolder("ironwood_axe") + public static final Item ironwood_axe; + @GameRegistry.ObjectHolder("ironwood_hoe") + public static final Item ironwood_hoe; + @GameRegistry.ObjectHolder("torchberries") + public static final Item torchberries; + @GameRegistry.ObjectHolder("raw_venison") + public static final Item raw_venison; + @GameRegistry.ObjectHolder("cooked_venison") + public static final Item cooked_venison; + @GameRegistry.ObjectHolder("hydra_chop") + public static final Item hydra_chop; + @GameRegistry.ObjectHolder("fiery_blood") + public static final Item fiery_blood; + @GameRegistry.ObjectHolder("trophy") + public static final Item trophy; + @GameRegistry.ObjectHolder("fiery_ingot") + public static final Item fiery_ingot; + @GameRegistry.ObjectHolder("fiery_helmet") + public static final Item fiery_helmet; + @GameRegistry.ObjectHolder("fiery_chestplate") + public static final Item fiery_chestplate; + @GameRegistry.ObjectHolder("fiery_leggings") + public static final Item fiery_leggings; + @GameRegistry.ObjectHolder("fiery_boots") + public static final Item fiery_boots; + @GameRegistry.ObjectHolder("fiery_sword") + public static final Item fiery_sword; + @GameRegistry.ObjectHolder("fiery_pickaxe") + public static final Item fiery_pickaxe; + @GameRegistry.ObjectHolder("steeleaf_ingot") + public static final Item steeleaf_ingot; + @GameRegistry.ObjectHolder("steeleaf_helmet") + public static final Item steeleaf_helmet; + @GameRegistry.ObjectHolder("steeleaf_chestplate") + public static final Item steeleaf_chestplate; + @GameRegistry.ObjectHolder("steeleaf_leggings") + public static final Item steeleaf_leggings; + @GameRegistry.ObjectHolder("steeleaf_boots") + public static final Item steeleaf_boots; + @GameRegistry.ObjectHolder("steeleaf_sword") + public static final Item steeleaf_sword; + @GameRegistry.ObjectHolder("steeleaf_shovel") + public static final Item steeleaf_shovel; + @GameRegistry.ObjectHolder("steeleaf_pickaxe") + public static final Item steeleaf_pickaxe; + @GameRegistry.ObjectHolder("steeleaf_axe") + public static final Item steeleaf_axe; + @GameRegistry.ObjectHolder("steeleaf_hoe") + public static final Item steeleaf_hoe; + @GameRegistry.ObjectHolder("minotaur_axe") + public static final Item minotaur_axe; + @GameRegistry.ObjectHolder("minotaur_axe_gold") + public static final Item minotaur_axe_gold; + @GameRegistry.ObjectHolder("mazebreaker_pickaxe") + public static final Item mazebreaker_pickaxe; + @GameRegistry.ObjectHolder("transformation_powder") + public static final Item transformation_powder; + @GameRegistry.ObjectHolder("raw_meef") + public static final Item raw_meef; + @GameRegistry.ObjectHolder("cooked_meef") + public static final Item cooked_meef; + @GameRegistry.ObjectHolder("meef_stroganoff") + public static final Item meef_stroganoff; + @GameRegistry.ObjectHolder("maze_wafer") + public static final Item maze_wafer; + @GameRegistry.ObjectHolder("magic_map_empty") + public static final Item magic_map_empty; + @GameRegistry.ObjectHolder("maze_map_empty") + public static final Item maze_map_empty; + @GameRegistry.ObjectHolder("ore_map_empty") + public static final Item ore_map_empty; + @GameRegistry.ObjectHolder("ore_magnet") + public static final Item ore_magnet; + @GameRegistry.ObjectHolder("crumble_horn") + public static final Item crumble_horn; + @GameRegistry.ObjectHolder("peacock_fan") + public static final Item peacock_fan; + @GameRegistry.ObjectHolder("moonworm_queen") + public static final Item moonworm_queen; + @GameRegistry.ObjectHolder("charm_of_life_1") + public static final Item charm_of_life_1; + @GameRegistry.ObjectHolder("charm_of_life_2") + public static final Item charm_of_life_2; + @GameRegistry.ObjectHolder("charm_of_keeping_1") + public static final Item charm_of_keeping_1; + @GameRegistry.ObjectHolder("charm_of_keeping_2") + public static final Item charm_of_keeping_2; + @GameRegistry.ObjectHolder("charm_of_keeping_3") + public static final Item charm_of_keeping_3; + @GameRegistry.ObjectHolder("tower_key") + public static final Item tower_key; + @GameRegistry.ObjectHolder("borer_essence") + public static final Item borer_essence; + @GameRegistry.ObjectHolder("carminite") + public static final Item carminite; + @GameRegistry.ObjectHolder("experiment_115") + public static final Item experiment_115; + @GameRegistry.ObjectHolder("armor_shard") + public static final Item armor_shard; + @GameRegistry.ObjectHolder("knightmetal_ingot") + public static final Item knightmetal_ingot; + @GameRegistry.ObjectHolder("armor_shard_cluster") + public static final Item armor_shard_cluster; + @GameRegistry.ObjectHolder("knightmetal_helmet") + public static final Item knightmetal_helmet; + @GameRegistry.ObjectHolder("knightmetal_chestplate") + public static final Item knightmetal_chestplate; + @GameRegistry.ObjectHolder("knightmetal_leggings") + public static final Item knightmetal_leggings; + @GameRegistry.ObjectHolder("knightmetal_boots") + public static final Item knightmetal_boots; + @GameRegistry.ObjectHolder("knightmetal_shield") + public static final Item knightmetal_shield; + @GameRegistry.ObjectHolder("knightmetal_sword") + public static final Item knightmetal_sword; + @GameRegistry.ObjectHolder("knightmetal_pickaxe") + public static final Item knightmetal_pickaxe; + @GameRegistry.ObjectHolder("knightmetal_axe") + public static final Item knightmetal_axe; + @GameRegistry.ObjectHolder("phantom_helmet") + public static final Item phantom_helmet; + @GameRegistry.ObjectHolder("phantom_chestplate") + public static final Item phantom_chestplate; + @GameRegistry.ObjectHolder("lamp_of_cinders") + public static final Item lamp_of_cinders; + @GameRegistry.ObjectHolder("fiery_tears") + public static final Item fiery_tears; + @GameRegistry.ObjectHolder("alpha_fur") + public static final Item alpha_fur; + @GameRegistry.ObjectHolder("yeti_helmet") + public static final Item yeti_helmet; + @GameRegistry.ObjectHolder("yeti_chestplate") + public static final Item yeti_chestplate; + @GameRegistry.ObjectHolder("yeti_leggings") + public static final Item yeti_leggings; + @GameRegistry.ObjectHolder("yeti_boots") + public static final Item yeti_boots; + @GameRegistry.ObjectHolder("ice_bomb") + public static final Item ice_bomb; + @GameRegistry.ObjectHolder("arctic_fur") + public static final Item arctic_fur; + @GameRegistry.ObjectHolder("arctic_helmet") + public static final Item arctic_helmet; + @GameRegistry.ObjectHolder("arctic_chestplate") + public static final Item arctic_chestplate; + @GameRegistry.ObjectHolder("arctic_leggings") + public static final Item arctic_leggings; + @GameRegistry.ObjectHolder("arctic_boots") + public static final Item arctic_boots; + @GameRegistry.ObjectHolder("magic_beans") + public static final Item magic_beans; + @GameRegistry.ObjectHolder("giant_pickaxe") + public static final Item giant_pickaxe; + @GameRegistry.ObjectHolder("giant_sword") + public static final Item giant_sword; + @GameRegistry.ObjectHolder("triple_bow") + public static final Item triple_bow; + @GameRegistry.ObjectHolder("seeker_bow") + public static final Item seeker_bow; + @GameRegistry.ObjectHolder("ice_bow") + public static final Item ice_bow; + @GameRegistry.ObjectHolder("ender_bow") + public static final Item ender_bow; + @GameRegistry.ObjectHolder("ice_sword") + public static final Item ice_sword; + @GameRegistry.ObjectHolder("glass_sword") + public static final Item glass_sword; + @GameRegistry.ObjectHolder("knightmetal_ring") + public static final Item knightmetal_ring; + @GameRegistry.ObjectHolder("block_and_chain") + public static final Item block_and_chain; + @GameRegistry.ObjectHolder("cube_talisman") + public static final Item cube_talisman; + @GameRegistry.ObjectHolder("cube_of_annihilation") + public static final Item cube_of_annihilation; + @GameRegistry.ObjectHolder("miniature_structure") + public static final Item miniature_structure; + @GameRegistry.ObjectHolder("castle_door") + public static final Item castle_door; + @GameRegistry.ObjectHolder("block_storage") + public static final Item block_storage; - registerTFItem(nagaScale, "Naga Scale"); - registerTFItem(plateNaga, "Naga Scale Tunic"); - registerTFItem(legsNaga, "Naga Scale Leggings"); - registerTFItem(scepterTwilight, "Scepter of Twilight"); - registerTFItem(scepterLifeDrain, "Scepter of Life Draining"); - registerTFItem(scepterZombie, "Zombie Scepter"); - //registerTFItem(wandPacification, "Wand of Pacification [NYI]"); - registerTFItem(oreMeter, "Ore Meter [WIP]"); - registerTFItem(magicMap, "Magic Map"); - registerTFItem(mazeMap, "Maze Map"); - registerTFItem(oreMap, "Maze/Ore Map"); - registerTFItem(feather, "Raven's Feather"); - registerTFItem(magicMapFocus, "Magic Map Focus"); - registerTFItem(mazeMapFocus, "Maze Map Focus"); - registerTFItem(liveRoot, "Liveroot"); - registerTFItem(ironwoodRaw, "Raw Ironwood Materials"); - registerTFItem(ironwoodIngot, "Ironwood Ingot"); - registerTFItem(ironwoodHelm, "Ironwood Helm"); - registerTFItem(ironwoodPlate, "Ironwood Plate"); - registerTFItem(ironwoodLegs, "Ironwood Legs"); - registerTFItem(ironwoodBoots, "Ironwood Boots"); - registerTFItem(ironwoodSword, "Ironwood Sword"); - registerTFItem(ironwoodShovel, "Ironwood Shovel"); - registerTFItem(ironwoodPick, "Ironwood Pick"); - registerTFItem(ironwoodAxe, "Ironwood Axe"); - registerTFItem(ironwoodHoe, "Ironwood Hoe"); - registerTFItem(torchberries, "Torchberries"); - registerTFItem(venisonRaw, "Raw Venison"); - registerTFItem(venisonCooked, "Venison Steak"); - registerTFItem(hydraChop, "Hydra Chop"); - registerTFItem(fieryBlood, "Fiery Blood"); - registerTFItem(trophy, "Hydra Trophy"); - registerTFItem(fieryIngot, "Fiery Ingot"); - registerTFItem(fieryHelm, "Fiery Helm"); - registerTFItem(fieryPlate, "Fiery Plate"); - registerTFItem(fieryLegs, "Fiery Legs"); - registerTFItem(fieryBoots, "Fiery Boots"); - registerTFItem(fierySword, "Fiery Sword"); - registerTFItem(fieryPick, "Fiery Pick"); - registerTFItem(steeleafIngot, "Steeleaf"); - registerTFItem(steeleafHelm, "Steeleaf Helm"); - registerTFItem(steeleafPlate, "Steeleaf Plate"); - registerTFItem(steeleafLegs, "Steeleaf Legs"); - registerTFItem(steeleafBoots, "Steeleaf Boots"); - registerTFItem(steeleafSword, "Steeleaf Sword"); - registerTFItem(steeleafShovel, "Steeleaf Shovel"); - registerTFItem(steeleafPick, "Steeleaf Pick"); - registerTFItem(steeleafAxe, "Steeleaf Axe"); - registerTFItem(steeleafHoe, "Steeleaf Hoe"); - registerTFItem(minotaurAxe, "Minotaur Axe"); - registerTFItem(mazebreakerPick, "Mazebreaker"); - registerTFItem(transformPowder, "Transformation Powder"); - registerTFItem(meefRaw, "Raw Meef"); - registerTFItem(meefSteak, "Meef Steak"); - registerTFItem(meefStroganoff, "Meef Stroganoff"); - registerTFItem(mazeWafer, "Maze Wafer"); - registerTFItem(emptyMagicMap, "Blank Magic Map"); - registerTFItem(emptyMazeMap, "Blank Maze Map"); - registerTFItem(emptyOreMap, "Blank Maze/Ore Map"); - registerTFItem(oreMagnet, "Ore Magnet"); - registerTFItem(crumbleHorn, "Crumble Horn"); - registerTFItem(peacockFan, "Peacock Feather Fan"); - registerTFItem(moonwormQueen, "Moonworm Queen"); - registerTFItem(charmOfLife1, "Charm of Life I"); - registerTFItem(charmOfLife2, "Charm of Life II"); - registerTFItem(charmOfKeeping1, "Charm of Keeping I"); - registerTFItem(charmOfKeeping2, "Charm of Keeping II"); - registerTFItem(charmOfKeeping3, "Charm of Keeping III"); - registerTFItem(towerKey, "Tower Key"); - registerTFItem(borerEssence, "Borer Essence"); - registerTFItem(carminite, "Carminite"); - registerTFItem(experiment115, "Experiment 115"); - registerTFItem(armorShard, "Armor Shards"); - registerTFItem(knightMetal, "Knightmetal Ingot"); - registerTFItem(shardCluster, "Shard Cluster"); - registerTFItem(knightlyHelm, "Knightly Helm"); - registerTFItem(knightlyPlate, "Knightly Plate"); - registerTFItem(knightlyLegs, "Knightly Legs"); - registerTFItem(knightlyBoots, "Knightly Boots"); - registerTFItem(knightlySword, "Knightly Sword"); - registerTFItem(knightlyPick, "Knightly Pick"); - registerTFItem(knightlyAxe, "Knightly Axe"); - registerTFItem(phantomHelm, "Phantom Helm"); - registerTFItem(phantomPlate, "Phantom Plate"); - registerTFItem(lampOfCinders); - registerTFItem(fieryTears); - registerTFItem(alphaFur); - registerTFItem(yetiHelm); - registerTFItem(yetiPlate); - registerTFItem(yetiLegs); - registerTFItem(yetiBoots); - registerTFItem(iceBomb); - registerTFItem(arcticFur); - registerTFItem(arcticHelm); - registerTFItem(arcticPlate); - registerTFItem(arcticLegs); - registerTFItem(arcticBoots); - registerTFItem(magicBeans); - registerTFItem(giantPick); - registerTFItem(giantSword); - registerTFItem(tripleBow); - registerTFItem(seekerBow); - registerTFItem(iceBow); - registerTFItem(enderBow); - registerTFItem(iceSword); - registerTFItem(glassSword); - registerTFItem(knightmetalRing); - registerTFItem(chainBlock); - registerTFItem(cubeTalisman); - registerTFItem(cubeOfAnnihilation); + public static CreativeTabTwilightForest creativeTab = new CreativeTabTwilightForest("twilightForest"); - registerTFItem(spawnEgg, "Spawn"); - } + public static void initRepairMaterials() { + ARMOR_NAGA.setRepairItem(new ItemStack(naga_scale)); + ARMOR_IRONWOOD.setRepairItem(new ItemStack(ironwood_ingot)); + ARMOR_FIERY.setRepairItem(new ItemStack(fiery_ingot)); + ARMOR_STEELEAF.setRepairItem(new ItemStack(steeleaf_ingot)); + ARMOR_KNIGHTLY.setRepairItem(new ItemStack(knightmetal_ingot)); + ARMOR_PHANTOM.setRepairItem(new ItemStack(knightmetal_ingot)); + ARMOR_YETI.setRepairItem(new ItemStack(alpha_fur)); + ARMOR_ARCTIC.setRepairItem(new ItemStack(arctic_fur)); - private static void registerTFItem(Item item, String englishName) { - //LanguageRegistry.instance().addNameForObject(item, "en_US", englishName); - GameRegistry.registerItem(item, item.getUnlocalizedName(), TwilightForestMod.ID); + TOOL_IRONWOOD.setRepairItem(new ItemStack(ironwood_ingot)); + TOOL_FIERY.setRepairItem(new ItemStack(fiery_ingot)); + TOOL_STEELEAF.setRepairItem(new ItemStack(steeleaf_ingot)); + TOOL_KNIGHTLY.setRepairItem(new ItemStack(knightmetal_ingot)); + TOOL_GIANT.setRepairItem(new ItemStack(knightmetal_ingot)); + TOOL_ICE.setRepairItem(new ItemStack(Blocks.PACKED_ICE)); } - private static void registerTFItem(Item item) { - GameRegistry.registerItem(item, item.getUnlocalizedName(), TwilightForestMod.ID); + static { + naga_scale = null; + naga_chestplate = null; + naga_leggings = null; + twilight_scepter = null; + lifedrain_scepter = null; + zombie_scepter = null; + shield_scepter = null; + //items.register(wandPacification, "Wand of Pacification [NYI]"); + ore_meter = null; + magic_map = null; + maze_map = null; + ore_map = null; + raven_feather = null; + magic_map_focus = null; + maze_map_focus = null; + liveroot = null; + ironwood_raw = null; + ironwood_ingot = null; + ironwood_helmet = null; + ironwood_chestplate = null; + ironwood_leggings = null; + ironwood_boots = null; + ironwood_sword = null; + ironwood_shovel = null; + ironwood_pickaxe = null; + ironwood_axe = null; + ironwood_hoe = null; + torchberries = null; + raw_venison = null; + cooked_venison = null; + hydra_chop = null; + fiery_blood = null; + trophy = null; + fiery_ingot = null; + fiery_helmet = null; + fiery_chestplate = null; + fiery_leggings = null; + fiery_boots = null; + fiery_sword = null; + fiery_pickaxe = null; + steeleaf_ingot = null; + steeleaf_helmet = null; + steeleaf_chestplate = null; + steeleaf_leggings = null; + steeleaf_boots = null; + steeleaf_sword = null; + steeleaf_shovel = null; + steeleaf_pickaxe = null; + steeleaf_axe = null; + steeleaf_hoe = null; + minotaur_axe = null; + minotaur_axe_gold = null; + mazebreaker_pickaxe = null; + transformation_powder = null; + raw_meef = null; + cooked_meef = null; + meef_stroganoff = null; + maze_wafer = null; + magic_map_empty = null; + maze_map_empty = null; + ore_map_empty = null; + ore_magnet = null; + crumble_horn = null; + peacock_fan = null; + moonworm_queen = null; + charm_of_life_1 = null; + charm_of_life_2 = null; + charm_of_keeping_1 = null; + charm_of_keeping_2 = null; + charm_of_keeping_3 = null; + tower_key = null; + borer_essence = null; + carminite = null; + experiment_115 = null; + armor_shard = null; + knightmetal_ingot = null; + armor_shard_cluster = null; + knightmetal_helmet = null; + knightmetal_chestplate = null; + knightmetal_leggings = null; + knightmetal_boots = null; + knightmetal_shield = null; + knightmetal_sword = null; + knightmetal_pickaxe = null; + knightmetal_axe = null; + phantom_helmet = null; + phantom_chestplate = null; + lamp_of_cinders = null; + fiery_tears = null; + alpha_fur = null; + yeti_helmet = null; + yeti_chestplate = null; + yeti_leggings = null; + yeti_boots = null; + ice_bomb = null; + arctic_fur = null; + arctic_helmet = null; + arctic_chestplate = null; + arctic_leggings = null; + arctic_boots = null; + magic_beans = null; + giant_pickaxe = null; + giant_sword = null; + triple_bow = null; + seeker_bow = null; + ice_bow = null; + ender_bow = null; + ice_sword = null; + glass_sword = null; + knightmetal_ring = null; + block_and_chain = null; + cube_talisman = null; + cube_of_annihilation = null; + miniature_structure = null; + castle_door = null; + block_storage = null; } - -} +} \ No newline at end of file diff --git a/src/main/java/twilightforest/item/TFMapCloningRecipe.java b/src/main/java/twilightforest/item/TFMapCloningRecipe.java deleted file mode 100644 index a79af9ef89..0000000000 --- a/src/main/java/twilightforest/item/TFMapCloningRecipe.java +++ /dev/null @@ -1,126 +0,0 @@ -package twilightforest.item; - -import net.minecraft.inventory.InventoryCrafting; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.world.World; - -public class TFMapCloningRecipe implements IRecipe -{ - public Item fullMapID; - public Item blankMapID; - - public TFMapCloningRecipe(Item magicMap, Item emptyMagicMap) - { - this.fullMapID = magicMap; - this.blankMapID = emptyMagicMap; - } - - /** - * Used to check if a recipe matches current crafting inventory - */ - @Override - public boolean matches(InventoryCrafting par1InventoryCrafting, World par2World) - { - int var3 = 0; - ItemStack var4 = null; - - for (int var5 = 0; var5 < par1InventoryCrafting.getSizeInventory(); ++var5) - { - ItemStack var6 = par1InventoryCrafting.getStackInSlot(var5); - - if (var6 != null) - { - if (var6.getItem() == this.fullMapID) - { - if (var4 != null) - { - return false; - } - - var4 = var6; - } - else - { - if (var6.getItem() != this.blankMapID) - { - return false; - } - - ++var3; - } - } - } - - return var4 != null && var3 > 0; - } - - /** - * Returns an Item that is the result of this recipe - */ - @Override - public ItemStack getCraftingResult(InventoryCrafting par1InventoryCrafting) - { - int var2 = 0; - ItemStack var3 = null; - - for (int var4 = 0; var4 < par1InventoryCrafting.getSizeInventory(); ++var4) - { - ItemStack var5 = par1InventoryCrafting.getStackInSlot(var4); - - if (var5 != null) - { - if (var5.getItem() == this.fullMapID) - { - if (var3 != null) - { - return null; - } - - var3 = var5; - } - else - { - if (var5.getItem() != this.blankMapID) - { - return null; - } - - ++var2; - } - } - } - - if (var3 != null && var2 >= 1) - { - ItemStack var6 = new ItemStack(this.fullMapID, var2 + 1, var3.getItemDamage()); - - if (var3.hasDisplayName()) - { - var6.setStackDisplayName(var3.getDisplayName()); - } - - return var6; - } - else - { - return null; - } - } - - /** - * Returns the size of the recipe area - */ - @Override - public int getRecipeSize() - { - return 9; - } - - @Override - public ItemStack getRecipeOutput() - { - return null; - } -} diff --git a/src/main/java/twilightforest/item/TFRecipes.java b/src/main/java/twilightforest/item/TFRecipes.java deleted file mode 100644 index 09e60dc46b..0000000000 --- a/src/main/java/twilightforest/item/TFRecipes.java +++ /dev/null @@ -1,222 +0,0 @@ -package twilightforest.item; - - -import static net.minecraftforge.oredict.RecipeSorter.Category.SHAPELESS; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.oredict.OreDictionary; -import net.minecraftforge.oredict.RecipeSorter; -import twilightforest.TwilightForestMod; -import twilightforest.block.BlockTFFireJet; -import twilightforest.block.BlockTFPlant; -import twilightforest.block.BlockTFTowerDevice; -import twilightforest.block.TFBlocks; -import twilightforest.enchantment.TFEnchantment; -import cpw.mods.fml.common.registry.GameRegistry; - - -public class TFRecipes { - - public static void registerRecipes() { - - // ore dictionary - OreDictionary.registerOre("logWood", new ItemStack(TFBlocks.log, 1, OreDictionary.WILDCARD_VALUE)); - OreDictionary.registerOre("logWood", new ItemStack(TFBlocks.magicLog, 1, OreDictionary.WILDCARD_VALUE)); - OreDictionary.registerOre("treeSapling", new ItemStack(TFBlocks.sapling, 1, OreDictionary.WILDCARD_VALUE)); - OreDictionary.registerOre("treeLeaves", new ItemStack(TFBlocks.leaves, 1, OreDictionary.WILDCARD_VALUE)); - OreDictionary.registerOre("treeLeaves", new ItemStack(TFBlocks.magicLeaves, 1, OreDictionary.WILDCARD_VALUE)); - OreDictionary.registerOre("plankWood", new ItemStack(TFBlocks.towerWood, 1, OreDictionary.WILDCARD_VALUE)); - - // register my ores, just for fun - OreDictionary.registerOre("ingotFiery", new ItemStack(TFItems.fieryIngot)); - OreDictionary.registerOre("oreIronwood", new ItemStack(TFItems.ironwoodRaw)); - OreDictionary.registerOre("ingotIronwood", new ItemStack(TFItems.ironwoodIngot)); - OreDictionary.registerOre("ingotSteeleaf", new ItemStack(TFItems.steeleafIngot)); - OreDictionary.registerOre("oreKnightmetal", new ItemStack(TFItems.shardCluster)); - OreDictionary.registerOre("ingotKnightmetal", new ItemStack(TFItems.knightMetal)); - - // recipe sorter - RecipeSorter.register(TwilightForestMod.ID + ":mapcloning", TFMapCloningRecipe.class, SHAPELESS, "after:minecraft:shapeless"); - - // smelting for logs - GameRegistry.addSmelting(TFBlocks.log, new ItemStack(Items.coal, 1, 1), 0.1F); - GameRegistry.addSmelting(TFBlocks.magicLog, new ItemStack(Items.coal, 1, 1), 0.1F); - - // recipes - GameRegistry.addRecipe(new ItemStack(Blocks.planks, 4, 0), new Object[] {"w", 'w', new ItemStack(TFBlocks.log, 1, 0)}); - GameRegistry.addRecipe(new ItemStack(Blocks.planks, 4, 1), new Object[] {"w", 'w', new ItemStack(TFBlocks.log, 1, 1)}); - GameRegistry.addRecipe(new ItemStack(Blocks.planks, 4, 2), new Object[] {"w", 'w', new ItemStack(TFBlocks.log, 1, 2)}); - GameRegistry.addRecipe(new ItemStack(Blocks.planks, 4, 1), new Object[] {"w", 'w', new ItemStack(TFBlocks.log, 1, 3)}); - - addEnchantedRecipe(TFItems.plateNaga, Enchantment.fireProtection, 3, new Object[] {"# #", "###", "###", '#', TFItems.nagaScale}); - addEnchantedRecipe(TFItems.legsNaga, Enchantment.protection, 3, new Object[] {"###", "# #", "# #", '#', TFItems.nagaScale}); - - GameRegistry.addShapelessRecipe(new ItemStack(TFBlocks.fireflyJar, 1, 0), new Object[] {TFBlocks.firefly, Items.glass_bottle}); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterTwilight), new Object[] {new ItemStack(TFItems.scepterTwilight, 1, TFItems.scepterTwilight.getMaxDamage()), Items.ender_pearl}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterLifeDrain), new Object[] {new ItemStack(TFItems.scepterLifeDrain, 1, TFItems.scepterLifeDrain.getMaxDamage()), Items.fermented_spider_eye}); - // aah, why are there so many potions of strength - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterZombie), new Object[] {new ItemStack(TFItems.scepterZombie, 1, TFItems.scepterZombie.getMaxDamage()), new ItemStack(Items.rotten_flesh), new ItemStack(Items.potionitem, 1, 16281)}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterZombie), new Object[] {new ItemStack(TFItems.scepterZombie, 1, TFItems.scepterZombie.getMaxDamage()), new ItemStack(Items.rotten_flesh), new ItemStack(Items.potionitem, 1, 16313)}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterZombie), new Object[] {new ItemStack(TFItems.scepterZombie, 1, TFItems.scepterZombie.getMaxDamage()), new ItemStack(Items.rotten_flesh), new ItemStack(Items.potionitem, 1, 16345)}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterZombie), new Object[] {new ItemStack(TFItems.scepterZombie, 1, TFItems.scepterZombie.getMaxDamage()), new ItemStack(Items.rotten_flesh), new ItemStack(Items.potionitem, 1, 16377)}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterZombie), new Object[] {new ItemStack(TFItems.scepterZombie, 1, TFItems.scepterZombie.getMaxDamage()), new ItemStack(Items.rotten_flesh), new ItemStack(Items.potionitem, 1, 8201)}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterZombie), new Object[] {new ItemStack(TFItems.scepterZombie, 1, TFItems.scepterZombie.getMaxDamage()), new ItemStack(Items.rotten_flesh), new ItemStack(Items.potionitem, 1, 8265)}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.scepterZombie), new Object[] {new ItemStack(TFItems.scepterZombie, 1, TFItems.scepterZombie.getMaxDamage()), new ItemStack(Items.rotten_flesh), new ItemStack(Items.potionitem, 1, 8233)}); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.magicMapFocus), new Object[] {TFItems.feather, TFItems.torchberries, Items.glowstone_dust}); - GameRegistry.addRecipe(new ItemStack(TFItems.emptyMagicMap), new Object[] {"###", "#X#", "###", '#', Items.paper, 'X', TFItems.magicMapFocus}); - GameRegistry.addRecipe(new ItemStack(TFItems.emptyMazeMap), new Object[] {"###", "#X#", "###", '#', Items.paper, 'X', TFItems.mazeMapFocus}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.emptyOreMap), new Object[] {new ItemStack(TFItems.mazeMap, 1, Short.MAX_VALUE), Blocks.gold_block, Blocks.diamond_block, Blocks.iron_block}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.emptyOreMap), new Object[] {new ItemStack(TFItems.emptyMazeMap, 1, Short.MAX_VALUE), Blocks.gold_block, Blocks.diamond_block, Blocks.iron_block}); - - GameRegistry.addRecipe(new ItemStack(Items.arrow, 4), new Object[] {"X", "#", "Y", 'Y', TFItems.feather, 'X', Items.flint, '#', Items.stick}); - - GameRegistry.addShapelessRecipe(new ItemStack(Items.stick), new Object[] {new ItemStack(TFBlocks.plant, 1, BlockTFPlant.META_ROOT_STRAND)}); - GameRegistry.addRecipe(new ItemStack(Blocks.torch, 5), new Object[] {"B", "S", 'B', TFItems.torchberries, 'S', Items.stick}); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.ironwoodRaw), new Object[] {TFItems.liveRoot, Items.iron_ingot, Items.gold_nugget}); - GameRegistry.addSmelting(TFItems.ironwoodRaw, new ItemStack(TFItems.ironwoodIngot, 2), 1.0F); - - addEnchantedRecipe(TFItems.ironwoodHelm, Enchantment.aquaAffinity, 1, new Object[] {"###", "# #", '#', TFItems.ironwoodIngot}); - addEnchantedRecipe(TFItems.ironwoodPlate, Enchantment.protection, 1, new Object[] {"# #", "###", "###", '#', TFItems.ironwoodIngot}); - addEnchantedRecipe(TFItems.ironwoodLegs, Enchantment.protection, 1, new Object[] {"###", "# #", "# #", '#', TFItems.ironwoodIngot}); - addEnchantedRecipe(TFItems.ironwoodBoots, Enchantment.featherFalling, 1, new Object[] {"# #", "# #", '#', TFItems.ironwoodIngot}); - addEnchantedRecipe(TFItems.ironwoodSword, Enchantment.knockback, 1, new Object[] {"#", "#", "X", '#', TFItems.ironwoodIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.ironwoodShovel, Enchantment.unbreaking, 1, new Object[] {"#", "X", "X", '#', TFItems.ironwoodIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.ironwoodPick, Enchantment.efficiency, 1, new Object[] {"###", " X ", " X ", '#', TFItems.ironwoodIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.ironwoodAxe, Enchantment.fortune, 1, new Object[] {"##", "#X", " X", '#', TFItems.ironwoodIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.ironwoodHoe, null, 0, new Object[] {"##", " X", " X", '#', TFItems.ironwoodIngot, 'X', Items.stick}); - - GameRegistry.addRecipe(new ItemStack(TFBlocks.uncraftingTable), new Object[] {"###", "#X#", "###", '#', Blocks.crafting_table, 'X', TFItems.mazeMapFocus}); - - GameRegistry.addSmelting(TFItems.venisonRaw, new ItemStack(TFItems.venisonCooked), 0.3F); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.fieryIngot), new Object[] {TFItems.fieryBlood, Items.iron_ingot}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.fieryIngot), new Object[] {TFItems.fieryTears, Items.iron_ingot}); - GameRegistry.addRecipe(new ItemStack(TFItems.fieryHelm), new Object[] {"###", "# #", '#', TFItems.fieryIngot}); - GameRegistry.addRecipe(new ItemStack(TFItems.fieryPlate), new Object[] {"# #", "###", "###", '#', TFItems.fieryIngot}); - GameRegistry.addRecipe(new ItemStack(TFItems.fieryLegs), new Object[] {"###", "# #", "# #", '#', TFItems.fieryIngot}); - GameRegistry.addRecipe(new ItemStack(TFItems.fieryBoots), new Object[] {"# #", "# #", '#', TFItems.fieryIngot}); - addEnchantedRecipe(TFItems.fierySword, Enchantment.fireAspect, 2, new Object[] {"#", "#", "X", '#', TFItems.fieryIngot, 'X', Items.blaze_rod}); - GameRegistry.addRecipe(new ItemStack(TFItems.fieryPick), new Object[] {"###", " X ", " X ", '#', TFItems.fieryIngot, 'X', Items.blaze_rod}); - - addEnchantedRecipe(TFItems.steeleafHelm, Enchantment.projectileProtection, 2, new Object[] {"###", "# #", '#', TFItems.steeleafIngot}); - addEnchantedRecipe(TFItems.steeleafPlate, Enchantment.blastProtection, 2, new Object[] {"# #", "###", "###", '#', TFItems.steeleafIngot}); - addEnchantedRecipe(TFItems.steeleafLegs, Enchantment.fireProtection, 2, new Object[] {"###", "# #", "# #", '#', TFItems.steeleafIngot}); - addEnchantedRecipe(TFItems.steeleafBoots, Enchantment.featherFalling, 2, new Object[] {"# #", "# #", '#', TFItems.steeleafIngot}); - addEnchantedRecipe(TFItems.steeleafSword, Enchantment.looting, 2, new Object[] {"#", "#", "X", '#', TFItems.steeleafIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.steeleafShovel, Enchantment.efficiency, 2, new Object[] {"#", "X", "X", '#', TFItems.steeleafIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.steeleafPick, Enchantment.fortune, 2, new Object[] {"###", " X ", " X ", '#', TFItems.steeleafIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.steeleafAxe, Enchantment.efficiency, 2, new Object[] {"##", "#X", " X", '#', TFItems.steeleafIngot, 'X', Items.stick}); - addEnchantedRecipe(TFItems.steeleafHoe, null, 0, new Object[] {"##", " X", " X", '#', TFItems.steeleafIngot, 'X', Items.stick}); - - GameRegistry.addSmelting(TFItems.meefRaw, new ItemStack(TFItems.meefSteak), 0.3F); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.moonwormQueen), new Object[] {new ItemStack(TFItems.moonwormQueen, 1, Short.MAX_VALUE), TFItems.torchberries, TFItems.torchberries, TFItems.torchberries}); - - GameRegistry.addRecipe(new ItemStack(TFItems.emptyMagicMap), new Object[] {"###", "#X#", "###", '#', Items.paper, 'X', TFItems.magicMapFocus}); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.charmOfKeeping2), new Object[] {TFItems.charmOfKeeping1, TFItems.charmOfKeeping1, TFItems.charmOfKeeping1, TFItems.charmOfKeeping1}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.charmOfKeeping3), new Object[] {TFItems.charmOfKeeping2, TFItems.charmOfKeeping2, TFItems.charmOfKeeping2, TFItems.charmOfKeeping2}); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.charmOfLife2), new Object[] {TFItems.charmOfLife1, TFItems.charmOfLife1, TFItems.charmOfLife1, TFItems.charmOfLife1}); - - GameRegistry.addRecipe(new TFMapCloningRecipe(TFItems.magicMap, TFItems.emptyMagicMap)); - GameRegistry.addRecipe(new TFMapCloningRecipe(TFItems.mazeMap, TFItems.emptyMazeMap)); - GameRegistry.addRecipe(new TFMapCloningRecipe(TFItems.oreMap, TFItems.emptyOreMap)); - - // dark tower recipes - GameRegistry.addRecipe(new ItemStack(TFBlocks.towerWood, 4, 0), new Object[] {"##", "##", '#', new ItemStack(TFBlocks.log, 1, 3)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.towerWood, 3, 1), new Object[] {"#", "#", "#", '#', new ItemStack(TFBlocks.towerWood, 1, 0)}); - GameRegistry.addRecipe(new ItemStack(TFItems.carminite), new Object[] {"brb", "rgr", "brb", 'b', new ItemStack(TFItems.borerEssence), 'r', new ItemStack(Items.redstone), 'g', new ItemStack(Items.ghast_tear)}); - GameRegistry.addRecipe(new ItemStack(TFItems.carminite), new Object[] {"rbr", "bgb", "rbr", 'b', new ItemStack(TFItems.borerEssence), 'r', new ItemStack(Items.redstone), 'g', new ItemStack(Items.ghast_tear)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.towerDevice, 8, BlockTFTowerDevice.META_VANISH_INACTIVE), new Object[] {"ewe", "wcw", "ewe", 'e', new ItemStack(TFBlocks.towerWood, 1, 1), 'w', new ItemStack(TFBlocks.towerWood, 1, 0), 'c', new ItemStack(TFItems.carminite)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.towerDevice, 2, BlockTFTowerDevice.META_REAPPEARING_INACTIVE), new Object[] {"ere", "rcr", "ere", 'e', new ItemStack(TFBlocks.towerWood, 1, 1), 'r', new ItemStack(Items.redstone), 'c', new ItemStack(TFItems.carminite)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.towerDevice, 1, BlockTFTowerDevice.META_BUILDER_INACTIVE), new Object[] {"ece", "cdc", "ece", 'e', new ItemStack(TFBlocks.towerWood, 1, 1), 'd', new ItemStack(Blocks.dispenser), 'c', new ItemStack(TFItems.carminite)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.towerDevice, 1, BlockTFTowerDevice.META_REACTOR_INACTIVE), new Object[] {"ece", "coc", "ece", 'e', new ItemStack(TFBlocks.towerWood, 1, 1), 'o', new ItemStack(Blocks.redstone_ore), 'c', new ItemStack(TFItems.carminite)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.fireJet, 1, BlockTFFireJet.META_ENCASED_SMOKER_OFF), new Object[] {"ere", "rsr", "ere", 'e', new ItemStack(TFBlocks.towerWood, 1, 1), 'r', new ItemStack(Items.redstone), 's', new ItemStack(TFBlocks.fireJet, 1, BlockTFFireJet.META_SMOKER)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.fireJet, 1, BlockTFFireJet.META_ENCASED_JET_IDLE), new Object[] {"ere", "rjr", "lll", 'e', new ItemStack(TFBlocks.towerWood, 1, 1), 'r', new ItemStack(Items.redstone), 'l', new ItemStack(Items.lava_bucket), 'j', new ItemStack(TFBlocks.fireJet, 1, BlockTFFireJet.META_JET_IDLE)}); - - - GameRegistry.addRecipe(new ItemStack(TFItems.shardCluster), new Object[] {"###", "###", "###", '#', TFItems.armorShard}); - - GameRegistry.addSmelting(TFItems.shardCluster, new ItemStack(TFItems.knightMetal), 1.0F); - - GameRegistry.addRecipe(new ItemStack(TFItems.knightlyHelm), new Object[] {"###", "# #", '#', TFItems.knightMetal}); - GameRegistry.addRecipe(new ItemStack(TFItems.knightlyPlate), new Object[] {"# #", "###", "###", '#', TFItems.knightMetal}); - GameRegistry.addRecipe(new ItemStack(TFItems.knightlyLegs), new Object[] {"###", "# #", "# #", '#', TFItems.knightMetal}); - GameRegistry.addRecipe(new ItemStack(TFItems.knightlyBoots), new Object[] {"# #", "# #", '#', TFItems.knightMetal}); - - GameRegistry.addRecipe(new ItemStack(TFItems.knightlySword), new Object[] {"#", "#", "X", '#', TFItems.knightMetal, 'X', Items.stick}); - GameRegistry.addRecipe(new ItemStack(TFItems.knightlyPick), new Object[] {"###", " X ", " X ", '#', TFItems.knightMetal, 'X', Items.stick}); - GameRegistry.addRecipe(new ItemStack(TFItems.knightlyAxe), new Object[] {"##", "#X", " X", '#', TFItems.knightMetal, 'X', Items.stick}); - GameRegistry.addRecipe(new ItemStack(TFItems.knightlyAxe), new Object[] {"##", "X#", "X ", '#', TFItems.knightMetal, 'X', Items.stick}); - - addEnchantedRecipe(TFItems.yetiHelm, Enchantment.protection, 2, new Object[] {"###", "# #", '#', TFItems.alphaFur}); - addEnchantedRecipe(TFItems.yetiPlate, Enchantment.protection, 2, new Object[] {"# #", "###", "###", '#', TFItems.alphaFur}); - addEnchantedRecipe(TFItems.yetiLegs, Enchantment.protection, 2, new Object[] {"###", "# #", "# #", '#', TFItems.alphaFur}); - addEnchantedRecipe(TFItems.yetiBoots, Enchantment.protection, 2, Enchantment.featherFalling, 4, new Object[] {"# #", "# #", '#', TFItems.alphaFur}); - - GameRegistry.addRecipe(new ItemStack(TFItems.arcticHelm), new Object[] {"###", "# #", '#', TFItems.arcticFur}); - GameRegistry.addRecipe(new ItemStack(TFItems.arcticPlate), new Object[] {"# #", "###", "###", '#', TFItems.arcticFur}); - GameRegistry.addRecipe(new ItemStack(TFItems.arcticLegs), new Object[] {"###", "# #", "# #", '#', TFItems.arcticFur}); - GameRegistry.addRecipe(new ItemStack(TFItems.arcticBoots), new Object[] {"# #", "# #", '#', TFItems.arcticFur}); - - GameRegistry.addRecipe(new ItemStack(TFBlocks.auroraSlab, 6, 0), new Object[] {"###", '#', TFBlocks.auroraBlock}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.auroraPillar, 2, 0), new Object[] {"#", "#", '#', TFBlocks.auroraBlock}); - - GameRegistry.addRecipe(new ItemStack(TFItems.giantPick), new Object[] {"###", " X ", " X ", '#', TFBlocks.giantCobble, 'X', TFBlocks.giantLog}); - GameRegistry.addRecipe(new ItemStack(TFItems.giantSword), new Object[] {"#", "#", "X", '#', TFBlocks.giantCobble, 'X', TFBlocks.giantLog}); - - GameRegistry.addShapelessRecipe(new ItemStack(Blocks.cobblestone, 64), new Object[] {new ItemStack(TFBlocks.giantCobble)}); - GameRegistry.addShapelessRecipe(new ItemStack(Blocks.planks, 64), new Object[] {new ItemStack(TFBlocks.giantLog)}); - GameRegistry.addShapelessRecipe(new ItemStack(Blocks.leaves, 64), new Object[] {new ItemStack(TFBlocks.giantLeaves)}); - - GameRegistry.addRecipe(new ItemStack(TFItems.knightmetalRing), new Object[] {" # ", "# #", " # ", '#', TFItems.knightMetal}); - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.chainBlock), new Object[] {TFItems.knightmetalRing, TFItems.knightMetal, TFItems.knightMetal, TFItems.knightMetal, TFBlocks.knightmetalStorage}); - - GameRegistry.addShapelessRecipe(new ItemStack(TFItems.knightMetal, 9), new Object[] {new ItemStack(TFBlocks.knightmetalStorage)}); - GameRegistry.addRecipe(new ItemStack(TFBlocks.knightmetalStorage), new Object[] {"###", "###", "###", '#', TFItems.knightMetal}); - - } - - /** - * Add a recipe for an enchanted item. Always shaped. - * - * @param item - * @param enchantment - * @param enchantmentLevel - * @param ingredientArray - */ - public static void addEnchantedRecipe(Item item, Enchantment enchantment, int enchantmentLevel, Object ... ingredientArray) { - ItemStack result = new ItemStack(item); - if (enchantment != null) { - result.addEnchantment(enchantment, enchantmentLevel); - } - - GameRegistry.addRecipe(result, ingredientArray); - } - /** - * Add a recipe for an enchanted item. Always shaped. - * - * @param item - * @param enchantment - * @param enchantmentLevel - * @param ingredientArray - */ - public static void addEnchantedRecipe(Item item, Enchantment enchantment, int enchantmentLevel, Enchantment enchantment2, int enchantmentLevel2, Object ... ingredientArray) { - ItemStack result = new ItemStack(item); - if (enchantment != null) { - result.addEnchantment(enchantment, enchantmentLevel); - } - if (enchantment2 != null) { - result.addEnchantment(enchantment2, enchantmentLevel2); - } - - GameRegistry.addRecipe(result, ingredientArray); - } -} diff --git a/src/main/java/twilightforest/item/package-info.java b/src/main/java/twilightforest/item/package-info.java new file mode 100644 index 0000000000..1d1f1b45f9 --- /dev/null +++ b/src/main/java/twilightforest/item/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.item; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/item/recipe/ConditionFactories.java b/src/main/java/twilightforest/item/recipe/ConditionFactories.java new file mode 100644 index 0000000000..a551ec2e38 --- /dev/null +++ b/src/main/java/twilightforest/item/recipe/ConditionFactories.java @@ -0,0 +1,18 @@ +package twilightforest.item.recipe; + +import com.google.gson.JsonObject; +import net.minecraftforge.common.crafting.IConditionFactory; +import net.minecraftforge.common.crafting.JsonContext; +import twilightforest.TFConfig; + +import java.util.function.BooleanSupplier; + +public class ConditionFactories { + + public static class UncraftingEnabled implements IConditionFactory { + @Override + public BooleanSupplier parse(JsonContext context, JsonObject json) { + return () -> !TFConfig.disableUncrafting; + } + } +} diff --git a/src/main/java/twilightforest/item/recipe/TFArmorDyeingRecipe.java b/src/main/java/twilightforest/item/recipe/TFArmorDyeingRecipe.java new file mode 100644 index 0000000000..451345d468 --- /dev/null +++ b/src/main/java/twilightforest/item/recipe/TFArmorDyeingRecipe.java @@ -0,0 +1,102 @@ +package twilightforest.item.recipe; + +import com.google.common.collect.Lists; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.RecipesArmorDyes; +import net.minecraft.world.World; +import twilightforest.item.ItemTFArcticArmor; + +import java.util.List; + +/* Copied from net.minecraft.item.crafting.RecipesArmorDyes with a bit of modification */ +public class TFArmorDyeingRecipe extends RecipesArmorDyes { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + ItemStack itemstack = ItemStack.EMPTY; + List list = Lists.newArrayList(); + + for (int i = 0; i < inv.getSizeInventory(); ++i) { + ItemStack itemstack1 = inv.getStackInSlot(i); + + if (!itemstack1.isEmpty()) { + if (itemstack1.getItem() instanceof ItemTFArcticArmor) { + itemstack = itemstack1; + } else { + if (!net.minecraftforge.oredict.DyeUtils.isDye(itemstack1)) { + return false; + } + + list.add(itemstack1); + } + } + } + + return !itemstack.isEmpty() && !list.isEmpty(); + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + ItemStack stackAccumulator = ItemStack.EMPTY; + int[] aint = new int[3]; + int i = 0; + int j = 0; + ItemTFArcticArmor arcticArmor = null; + + for (int k = 0; k < inv.getSizeInventory(); ++k) { + ItemStack stackInSlot = inv.getStackInSlot(k); + + if (!stackInSlot.isEmpty()) { + if (stackInSlot.getItem() instanceof ItemTFArcticArmor) { + arcticArmor = (ItemTFArcticArmor)stackInSlot.getItem(); + + stackAccumulator = stackInSlot.copy(); + stackAccumulator.setCount(1); + + if (arcticArmor.hasColor(stackInSlot)) { + int l = arcticArmor.getColor(stackAccumulator); + float f = (float)(l >> 16 & 255) / 255.0F; + float f1 = (float)(l >> 8 & 255) / 255.0F; + float f2 = (float)(l & 255) / 255.0F; + i = (int)((float)i + Math.max(f, Math.max(f1, f2)) * 255.0F); + aint[0] = (int)((float)aint[0] + f * 255.0F); + aint[1] = (int)((float)aint[1] + f1 * 255.0F); + aint[2] = (int)((float)aint[2] + f2 * 255.0F); + ++j; + } + } else { + if (!net.minecraftforge.oredict.DyeUtils.isDye(stackInSlot)) { + return ItemStack.EMPTY; + } + + float[] afloat = net.minecraftforge.oredict.DyeUtils.colorFromStack(stackInSlot).get().getColorComponentValues(); + int l1 = (int)(afloat[0] * 255.0F); + int i2 = (int)(afloat[1] * 255.0F); + int j2 = (int)(afloat[2] * 255.0F); + i += Math.max(l1, Math.max(i2, j2)); + aint[0] += l1; + aint[1] += i2; + aint[2] += j2; + ++j; + } + } + } + + if (arcticArmor == null) { + return ItemStack.EMPTY; + } else { + int i1 = aint[0] / j; + int j1 = aint[1] / j; + int k1 = aint[2] / j; + float f3 = (float)i / (float)j; + float f4 = (float)Math.max(i1, Math.max(j1, k1)); + i1 = (int)((float)i1 * f3 / f4); + j1 = (int)((float)j1 * f3 / f4); + k1 = (int)((float)k1 * f3 / f4); + int k2 = (i1 << 8) + j1; + k2 = (k2 << 8) + k1; + arcticArmor.setColor(stackAccumulator, k2); + return stackAccumulator; + } + } +} diff --git a/src/main/java/twilightforest/item/recipe/TFMapCloningRecipe.java b/src/main/java/twilightforest/item/recipe/TFMapCloningRecipe.java new file mode 100644 index 0000000000..67e0b8560f --- /dev/null +++ b/src/main/java/twilightforest/item/recipe/TFMapCloningRecipe.java @@ -0,0 +1,89 @@ +package twilightforest.item.recipe; + +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.RecipesMapCloning; +import net.minecraft.world.World; + +public class TFMapCloningRecipe extends RecipesMapCloning { + private final Item fullMapID; + private final Item blankMapID; + + public TFMapCloningRecipe(Item magicMap, Item emptyMagicMap) { + this.fullMapID = magicMap; + this.blankMapID = emptyMagicMap; + } + + // [VanillaCopy] super with own items + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + int i = 0; + ItemStack itemstack = ItemStack.EMPTY; + + for (int j = 0; j < inv.getSizeInventory(); ++j) { + ItemStack itemstack1 = inv.getStackInSlot(j); + + if (!itemstack1.isEmpty()) { + if (itemstack1.getItem() == fullMapID) { + if (!itemstack.isEmpty()) { + return false; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != blankMapID) { + return false; + } + + ++i; + } + } + } + + return !itemstack.isEmpty() && i > 0; + } + + // [VanillaCopy] super with own items + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + int i = 0; + ItemStack itemstack = ItemStack.EMPTY; + + for (int j = 0; j < inv.getSizeInventory(); ++j) { + ItemStack itemstack1 = inv.getStackInSlot(j); + + if (!itemstack1.isEmpty()) { + if (itemstack1.getItem() == fullMapID) { + if (!itemstack.isEmpty()) { + return ItemStack.EMPTY; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != blankMapID) { + return ItemStack.EMPTY; + } + + ++i; + } + } + } + + if (!itemstack.isEmpty() && i >= 1) { + ItemStack itemstack2 = new ItemStack(fullMapID, i + 1, itemstack.getMetadata()); + + if (itemstack.hasDisplayName()) { + itemstack2.setStackDisplayName(itemstack.getDisplayName()); + } + + if (itemstack.hasTagCompound()) { + itemstack2.setTagCompound(itemstack.getTagCompound()); + } + + return itemstack2; + } else { + return ItemStack.EMPTY; + } + } +} diff --git a/src/main/java/twilightforest/item/recipe/TFRecipes.java b/src/main/java/twilightforest/item/recipe/TFRecipes.java new file mode 100644 index 0000000000..2f57c93482 --- /dev/null +++ b/src/main/java/twilightforest/item/recipe/TFRecipes.java @@ -0,0 +1,128 @@ +package twilightforest.item.recipe; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.oredict.OreDictionary; +import twilightforest.TwilightForestMod; +import twilightforest.block.TFBlocks; +import twilightforest.enums.CompressedVariant; +import twilightforest.item.TFItems; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class TFRecipes { + + @SubscribeEvent + public static void registerRecipes(RegistryEvent.Register event) { + OreDictionary.registerOre("logWood", new ItemStack(TFBlocks.twilight_log, 1, OreDictionary.WILDCARD_VALUE)); + OreDictionary.registerOre("logWood", new ItemStack(TFBlocks.magic_log, 1, OreDictionary.WILDCARD_VALUE)); + OreDictionary.registerOre("treeSapling", new ItemStack(TFBlocks.twilight_sapling, 1, OreDictionary.WILDCARD_VALUE)); + OreDictionary.registerOre("treeLeaves", new ItemStack(TFBlocks.twilight_leaves, 1, OreDictionary.WILDCARD_VALUE)); + OreDictionary.registerOre("treeLeaves", new ItemStack(TFBlocks.magic_leaves, 1, OreDictionary.WILDCARD_VALUE)); + OreDictionary.registerOre("treeLeaves", new ItemStack(TFBlocks.twilight_leaves_3, 1, OreDictionary.WILDCARD_VALUE)); + OreDictionary.registerOre("treeLeaves", new ItemStack(TFBlocks.dark_leaves, 1, OreDictionary.WILDCARD_VALUE)); + OreDictionary.registerOre("plankWood", new ItemStack(TFBlocks.tower_wood, 1, OreDictionary.WILDCARD_VALUE)); + + OreDictionary.registerOre("feather", new ItemStack(TFItems.raven_feather)); + + OreDictionary.registerOre("ingotFiery", new ItemStack(TFItems.fiery_ingot)); + OreDictionary.registerOre("blockFiery", new ItemStack(TFBlocks.block_storage, 1, CompressedVariant.FIERY.ordinal())); + + OreDictionary.registerOre("oreIronwood", new ItemStack(TFItems.ironwood_raw)); + OreDictionary.registerOre("ingotIronwood", new ItemStack(TFItems.ironwood_ingot)); + + OreDictionary.registerOre("ingotSteeleaf", new ItemStack(TFItems.steeleaf_ingot)); + OreDictionary.registerOre("blockSteeleaf", new ItemStack(TFBlocks.block_storage, 1, CompressedVariant.STEELLEAF.ordinal())); + + OreDictionary.registerOre("oreKnightmetal", new ItemStack(TFItems.armor_shard_cluster)); + OreDictionary.registerOre("ingotKnightmetal", new ItemStack(TFItems.knightmetal_ingot)); + OreDictionary.registerOre("blockKnightmetal", new ItemStack(TFBlocks.knightmetal_block)); + + OreDictionary.registerOre("carminite", new ItemStack(TFItems.carminite)); + OreDictionary.registerOre("furArctic", new ItemStack(TFItems.arctic_fur)); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.twilight_oak_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.twilight_oak_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.twilight_oak_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.twilight_oak_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.twilight_oak_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.twilight_oak_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.twilight_oak_plate )); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.canopy_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.canopy_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.canopy_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.canopy_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.canopy_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.canopy_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.canopy_plate )); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.mangrove_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.mangrove_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.mangrove_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.mangrove_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.mangrove_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.mangrove_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.mangrove_plate )); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.dark_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.dark_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.dark_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.dark_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.dark_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.dark_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.dark_plate )); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.time_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.time_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.time_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.time_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.time_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.time_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.time_plate )); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.trans_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.trans_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.trans_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.trans_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.trans_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.trans_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.trans_plate )); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.mine_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.mine_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.mine_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.mine_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.mine_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.mine_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.mine_plate )); + + OreDictionary.registerOre("plankWood" , new ItemStack(TFBlocks.sort_planks )); + OreDictionary.registerOre("stairWood" , new ItemStack(TFBlocks.sort_stairs )); + OreDictionary.registerOre("slabWood" , new ItemStack(TFBlocks.sort_slab )); + //OreDictionary.registerOre("buttonWood" , new ItemStack(TFBlocks.sort_button )); + OreDictionary.registerOre("fenceWood" , new ItemStack(TFBlocks.sort_fence )); + OreDictionary.registerOre("fenceGateWood", new ItemStack(TFBlocks.sort_gate )); + //OreDictionary.registerOre("plateWood" , new ItemStack(TFBlocks.sort_plate )); + + // recipe sorter + // RecipeSorter.register(TwilightForestMod.ID + ":mapcloning", TFMapCloningRecipe.class, SHAPELESS, "after:minecraft:shapeless"); + + GameRegistry.addSmelting(TFBlocks.twilight_log, new ItemStack(Items.COAL, 1, 1), 0.1F); + GameRegistry.addSmelting(TFBlocks.magic_log, new ItemStack(Items.COAL, 1, 1), 0.1F); + GameRegistry.addSmelting(TFItems.ironwood_raw, new ItemStack(TFItems.ironwood_ingot, 2), 1.0F); + GameRegistry.addSmelting(TFItems.raw_venison, new ItemStack(TFItems.cooked_venison), 0.3F); + GameRegistry.addSmelting(TFItems.raw_meef, new ItemStack(TFItems.cooked_meef), 0.3F); + GameRegistry.addSmelting(TFItems.armor_shard_cluster, new ItemStack(TFItems.knightmetal_ingot), 1.0F); + + event.getRegistry().register(new TFArmorDyeingRecipe().setRegistryName(TwilightForestMod.ID, "arctic_armor_dyeing")); + + event.getRegistry().register(new TFMapCloningRecipe(TFItems.magic_map, TFItems.magic_map_empty).setRegistryName(TwilightForestMod.ID, "magic_map_cloning")); + event.getRegistry().register(new TFMapCloningRecipe(TFItems.maze_map, TFItems.maze_map_empty).setRegistryName(TwilightForestMod.ID, "maze_map_cloning")); + event.getRegistry().register(new TFMapCloningRecipe(TFItems.ore_map, TFItems.ore_map_empty).setRegistryName(TwilightForestMod.ID, "ore_map_cloning")); + } +} diff --git a/src/main/java/twilightforest/loot/LootConditionIsMinion.java b/src/main/java/twilightforest/loot/LootConditionIsMinion.java new file mode 100644 index 0000000000..9f255e00bb --- /dev/null +++ b/src/main/java/twilightforest/loot/LootConditionIsMinion.java @@ -0,0 +1,45 @@ +package twilightforest.loot; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import net.minecraft.util.JsonUtils; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.conditions.LootCondition; +import twilightforest.TwilightForestMod; +import twilightforest.entity.EntityTFMiniGhast; + +import javax.annotation.Nonnull; +import java.util.Random; + +public class LootConditionIsMinion implements LootCondition { + + private final boolean inverse; + + public LootConditionIsMinion(boolean inverse) { + this.inverse = inverse; + } + + @Override + public boolean testCondition(@Nonnull Random rand, @Nonnull LootContext context) { + return context.getLootedEntity() instanceof EntityTFMiniGhast && ((EntityTFMiniGhast) context.getLootedEntity()).isMinion() == !inverse; + } + + public static class Serializer extends LootCondition.Serializer { + + protected Serializer() { + super(TwilightForestMod.prefix("is_minion"), LootConditionIsMinion.class); + } + + @Override + public void serialize(@Nonnull JsonObject json, @Nonnull LootConditionIsMinion value, @Nonnull JsonSerializationContext context) { + json.addProperty("inverse", value.inverse); + } + + @Nonnull + @Override + public LootConditionIsMinion deserialize(@Nonnull JsonObject json, @Nonnull JsonDeserializationContext context) { + return new LootConditionIsMinion(JsonUtils.getBoolean(json, "inverse", false)); + } + } +} diff --git a/src/main/java/twilightforest/loot/LootConditionModExists.java b/src/main/java/twilightforest/loot/LootConditionModExists.java new file mode 100644 index 0000000000..bf419dcb28 --- /dev/null +++ b/src/main/java/twilightforest/loot/LootConditionModExists.java @@ -0,0 +1,48 @@ +package twilightforest.loot; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import net.minecraft.util.JsonUtils; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.conditions.LootCondition; +import net.minecraftforge.fml.common.Loader; +import twilightforest.TwilightForestMod; + +import javax.annotation.Nonnull; +import java.util.Random; + +// Loot condition for checking if a mod exists. +public class LootConditionModExists implements LootCondition { + + private final boolean exists; + private final String modID; + + public LootConditionModExists(String modID) { + this.exists = Loader.isModLoaded(modID); + this.modID = modID; + } + + @Override + public boolean testCondition(Random rand, LootContext context) { + return exists; + } + + public static class Serializer extends LootCondition.Serializer { + + protected Serializer() { + super(TwilightForestMod.prefix("mod_exists"), LootConditionModExists.class); + } + + @Override + public void serialize(@Nonnull JsonObject json, @Nonnull LootConditionModExists value, @Nonnull JsonSerializationContext context) { + json.addProperty("mod_id", value.modID); + } + + @Nonnull + @Override + public LootConditionModExists deserialize(@Nonnull JsonObject json, @Nonnull JsonDeserializationContext context) { + return new LootConditionModExists(JsonUtils.getString(json, "mod_id")); + } + } +} diff --git a/src/main/java/twilightforest/loot/LootFunctionEnchant.java b/src/main/java/twilightforest/loot/LootFunctionEnchant.java new file mode 100644 index 0000000000..4f8ff8d840 --- /dev/null +++ b/src/main/java/twilightforest/loot/LootFunctionEnchant.java @@ -0,0 +1,126 @@ +package twilightforest.loot; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSyntaxException; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentData; +import net.minecraft.init.Items; +import net.minecraft.item.ItemEnchantedBook; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.JsonUtils; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.conditions.LootCondition; +import net.minecraft.world.storage.loot.functions.LootFunction; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.registries.IRegistryDelegate; +import twilightforest.TwilightForestMod; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +// Similar to EnchantRandomly but applies everything and with exact levels +public class LootFunctionEnchant extends LootFunction { + + private final Map, Short> enchantments; + + protected LootFunctionEnchant(LootCondition[] conditions, Map, Short> enchantments) { + super(conditions); + this.enchantments = enchantments; + } + + @Override + public ItemStack apply(ItemStack stack, Random rand, LootContext context) { + for (Map.Entry, Short> e : enchantments.entrySet()) { + if (stack.getItem() == Items.ENCHANTED_BOOK) { + ItemEnchantedBook.addEnchantment(stack, new EnchantmentData(e.getKey().get(), e.getValue())); + } else { + addEnchantment(stack, e.getKey().get(), e.getValue()); + } + } + return stack; + } + + // Not using stack.addEnchantment because it doesn't handle duplicates like enchanted book does + private void addEnchantment(ItemStack stack, Enchantment e, short level) { + if (stack.getTagCompound() == null) { + stack.setTagCompound(new NBTTagCompound()); + } + + final String enchantedCompoundKey = stack.getItem() == Items.ENCHANTED_BOOK ? "StoredEnchantments" : "ench"; + + if (!stack.getTagCompound().hasKey(enchantedCompoundKey, Constants.NBT.TAG_LIST)) { + stack.getTagCompound().setTag(enchantedCompoundKey, new NBTTagList()); + } + + NBTTagList list = stack.getTagCompound().getTagList(enchantedCompoundKey, Constants.NBT.TAG_COMPOUND); + + for (int i = 0; i < list.tagCount(); i++) { + NBTTagCompound existing = list.getCompoundTagAt(i); + if (existing.getShort("id") == Enchantment.getEnchantmentID(e)) { + existing.setShort("lvl", level); + return; + } + } + + NBTTagCompound newCmp = new NBTTagCompound(); + newCmp.setShort("id", (short) Enchantment.getEnchantmentID(e)); + newCmp.setShort("lvl", level); + list.appendTag(newCmp); + } + + public static class Serializer extends LootFunction.Serializer { + + protected Serializer() { + super(TwilightForestMod.prefix("enchant"), LootFunctionEnchant.class); + } + + @Override + public void serialize(JsonObject object, LootFunctionEnchant function, JsonSerializationContext ctx) { + if (!function.enchantments.isEmpty()) { + JsonObject obj = new JsonObject(); + + for (Map.Entry, Short> e : function.enchantments.entrySet()) { + obj.addProperty(e.getKey().get().getRegistryName().toString(), e.getValue()); + } + + object.add("enchantments", obj); + } + } + + @Override + public LootFunctionEnchant deserialize(JsonObject object, JsonDeserializationContext ctx, LootCondition[] conditions) { + Map, Short> enchantments = new HashMap<>(); + + if (object.has("enchantments")) { + JsonObject enchantObj = JsonUtils.getJsonObject(object, "enchantments"); + + for (Map.Entry e : enchantObj.entrySet()) { + Enchantment ench = Enchantment.REGISTRY.getObject(new ResourceLocation(e.getKey())); + if (ench == null) { + throw new JsonSyntaxException("Can't find enchantment " + e.getKey()); + } + + short lvl = e.getValue().getAsShort(); + + for (IRegistryDelegate other : enchantments.keySet()) { + if (!ench.isCompatibleWith(other.get())) { + throw new JsonParseException(String.format("Enchantments %s and %s conflict", ench.getRegistryName(), other.get().getRegistryName())); + } + } + + enchantments.put(ench.delegate, lvl); + } + } + + return new LootFunctionEnchant(conditions, enchantments); + } + } +} diff --git a/src/main/java/twilightforest/loot/LootFunctionModItemSwap.java b/src/main/java/twilightforest/loot/LootFunctionModItemSwap.java new file mode 100644 index 0000000000..f69df6ad89 --- /dev/null +++ b/src/main/java/twilightforest/loot/LootFunctionModItemSwap.java @@ -0,0 +1,69 @@ +package twilightforest.loot; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSyntaxException; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.JsonUtils; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.conditions.LootCondition; +import net.minecraft.world.storage.loot.functions.LootFunction; +import twilightforest.TwilightForestMod; + +import java.util.Random; + +// Loot condition for checking that if a mod exists, then swap original item with its deserialized item. +public class LootFunctionModItemSwap extends LootFunction { + + private final Item item; + private final boolean success; + + protected LootFunctionModItemSwap(LootCondition[] conditionsIn, Item itemIn, boolean success) { + super(conditionsIn); + this.item = itemIn; + this.success = success; + } + + @Override + public ItemStack apply(ItemStack stack, Random rand, LootContext context) { + ItemStack newStack = new ItemStack(item, stack.getCount(), stack.getItemDamage()); + + newStack.setTagCompound(stack.getTagCompound()); + + return newStack; + } + + public static class Serializer extends LootFunction.Serializer { + + protected Serializer() { + super(TwilightForestMod.prefix("item_or_default"), LootFunctionModItemSwap.class); + } + + @Override + public void serialize(JsonObject object, LootFunctionModItemSwap function, JsonSerializationContext serializationContext) { + if (function.success) + object.addProperty("item", function.item.getRegistryName().toString()); + else + + object.addProperty("default", function.item.getRegistryName().toString()); + } + + @Override + public LootFunctionModItemSwap deserialize(JsonObject object, JsonDeserializationContext deserializationContext, LootCondition[] conditionsIn) { + Item item; + boolean success; + + try { + item = JsonUtils.getItem(object, "item"); + success = true; + } catch (JsonSyntaxException e) { + item = JsonUtils.getItem(object, "default"); + success = false; + } + + return new LootFunctionModItemSwap(conditionsIn, item, success); + } + } +} diff --git a/src/main/java/twilightforest/loot/TFTreasure.java b/src/main/java/twilightforest/loot/TFTreasure.java new file mode 100644 index 0000000000..e940f72f26 --- /dev/null +++ b/src/main/java/twilightforest/loot/TFTreasure.java @@ -0,0 +1,126 @@ +package twilightforest.loot; + +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityChest; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.storage.loot.LootTableList; +import net.minecraft.world.storage.loot.conditions.LootConditionManager; +import net.minecraft.world.storage.loot.functions.LootFunctionManager; +import twilightforest.TwilightForestMod; +import twilightforest.entity.*; +import twilightforest.entity.boss.EntityTFHydra; +import twilightforest.entity.boss.EntityTFIceCrystal; +import twilightforest.entity.boss.EntityTFLich; +import twilightforest.entity.boss.EntityTFMinoshroom; +import twilightforest.entity.boss.EntityTFNaga; +import twilightforest.entity.boss.EntityTFSnowQueen; +import twilightforest.entity.boss.EntityTFYetiAlpha; +import twilightforest.entity.passive.*; + +public class TFTreasure { + // For easy testing: + // /give @p chest 1 0 {"display":{"Name":"Master Loot Crate"},"BlockEntityTag":{"LootTable":"twilightforest:entities/all_bosses"}} + + public static final TFTreasure hill1 = new TFTreasure("hill_1"); + public static final TFTreasure hill2 = new TFTreasure("hill_2"); + public static final TFTreasure hill3 = new TFTreasure("hill_3"); + public static final TFTreasure hedgemaze = new TFTreasure("hedge_maze"); + public static final TFTreasure labyrinth_room = new TFTreasure("labyrinth_room"); + public static final TFTreasure labyrinth_deadend = new TFTreasure("labyrinth_dead_end"); + public static final TFTreasure tower_room = new TFTreasure("tower_room"); + public static final TFTreasure tower_library = new TFTreasure("tower_library"); + public static final TFTreasure basement = new TFTreasure("basement"); + public static final TFTreasure labyrinth_vault = new TFTreasure("labyrinth_vault"); + public static final TFTreasure darktower_cache = new TFTreasure("darktower_cache"); + public static final TFTreasure darktower_key = new TFTreasure("darktower_key"); + public static final TFTreasure darktower_boss = new TFTreasure("darktower_boss"); + public static final TFTreasure tree_cache = new TFTreasure("tree_cache"); + public static final TFTreasure stronghold_cache = new TFTreasure("stronghold_cache"); + public static final TFTreasure stronghold_room = new TFTreasure("stronghold_room"); + public static final TFTreasure stronghold_boss = new TFTreasure("stronghold_boss"); + public static final TFTreasure aurora_cache = new TFTreasure("aurora_cache"); + public static final TFTreasure aurora_room = new TFTreasure("aurora_room"); + public static final TFTreasure aurora_boss = new TFTreasure("aurora_boss"); + public static final TFTreasure troll_garden = new TFTreasure("troll_garden"); + public static final TFTreasure troll_vault = new TFTreasure("troll_vault"); + public static final TFTreasure graveyard = new TFTreasure("graveyard"); + + public static void init() { + // Preload all entity tables + LootTableList.register(EntityTFArmoredGiant.LOOT_TABLE); + LootTableList.register(EntityTFBird.LOOT_TABLE); + LootTableList.register(EntityTFBighorn.SHEARED_LOOT_TABLE); + EntityTFBighorn.COLORED_LOOT_TABLES.values().forEach(LootTableList::register); + LootTableList.register(EntityTFBlockGoblin.LOOT_TABLE); + LootTableList.register(EntityTFBoar.LOOT_TABLE); + LootTableList.register(EntityTFBunny.LOOT_TABLE); + LootTableList.register(EntityTFDeathTome.LOOT_TABLE); + LootTableList.register(EntityTFDeathTome.HURT_LOOT_TABLE); + LootTableList.register(EntityTFDeer.LOOT_TABLE); + LootTableList.register(EntityTFFireBeetle.LOOT_TABLE); + LootTableList.register(EntityTFGiantMiner.LOOT_TABLE); + LootTableList.register(EntityTFGoblinKnightUpper.LOOT_TABLE); + LootTableList.register(EntityTFHelmetCrab.LOOT_TABLE); + LootTableList.register(EntityTFHydra.LOOT_TABLE); + LootTableList.register(EntityTFIceCrystal.LOOT_TABLE); + LootTableList.register(EntityTFIceExploder.LOOT_TABLE); + LootTableList.register(EntityTFIceShooter.LOOT_TABLE); + LootTableList.register(EntityTFKobold.LOOT_TABLE); + LootTableList.register(EntityTFLich.LOOT_TABLE); + LootTableList.register(EntityTFMazeSlime.LOOT_TABLE); + LootTableList.register(EntityTFMiniGhast.LOOT_TABLE); + LootTableList.register(EntityTFMinoshroom.LOOT_TABLE); + LootTableList.register(EntityTFMinotaur.LOOT_TABLE); + LootTableList.register(EntityTFNaga.LOOT_TABLE); + LootTableList.register(EntityTFPenguin.LOOT_TABLE); + LootTableList.register(EntityTFQuestRam.LOOT_TABLE); + LootTableList.register(EntityTFQuestRam.REWARD_LOOT_TABLE); + LootTableList.register(EntityTFRaven.LOOT_TABLE); + LootTableList.register(EntityTFRedcap.LOOT_TABLE); + LootTableList.register(EntityTFSkeletonDruid.LOOT_TABLE); + LootTableList.register(EntityTFSlimeBeetle.LOOT_TABLE); + LootTableList.register(EntityTFSnowGuardian.LOOT_TABLE); + LootTableList.register(EntityTFSnowQueen.LOOT_TABLE); + LootTableList.register(EntityTFSquirrel.LOOT_TABLE); + LootTableList.register(EntityTFTinyBird.LOOT_TABLE); + LootTableList.register(EntityTFTowerGolem.LOOT_TABLE); + LootTableList.register(EntityTFTowerTermite.LOOT_TABLE); + LootTableList.register(EntityTFTroll.LOOT_TABLE); + LootTableList.register(EntityTFWinterWolf.LOOT_TABLE); + LootTableList.register(EntityTFWraith.LOOT_TABLE); + LootTableList.register(EntityTFYeti.LOOT_TABLE); + LootTableList.register(EntityTFYetiAlpha.LOOT_TABLE); + + LootFunctionManager.registerFunction(new LootFunctionEnchant.Serializer()); + LootFunctionManager.registerFunction(new LootFunctionModItemSwap.Serializer()); + + LootConditionManager.registerCondition(new LootConditionIsMinion.Serializer()); + LootConditionManager.registerCondition(new LootConditionModExists.Serializer()); + } + + private final ResourceLocation lootTable; + + private TFTreasure(String path) { + lootTable = TwilightForestMod.prefix(String.format("structures/%s/%s", path, path)); + + // only preload the primary table, the subtables will be loaded on-demand the first time the primary table is used + LootTableList.register(lootTable); + } + + public void generateChest(World world, BlockPos pos, boolean trapped) { + world.setBlockState(pos, trapped ? Blocks.TRAPPED_CHEST.getDefaultState() : Blocks.CHEST.getDefaultState(), 2); + TileEntity te = world.getTileEntity(pos); + if (te instanceof TileEntityChest) { + ((TileEntityChest) te).setLootTable(lootTable, world.getSeed() * pos.getX() + pos.getY() ^ pos.getZ()); + } + } + + public void generateChestContents(World world, BlockPos pos) { + TileEntity te = world.getTileEntity(pos); + if (te instanceof TileEntityChest) + ((TileEntityChest) te).setLootTable(lootTable, world.getSeed() * pos.getX() + pos.getY() ^ pos.getZ()); + } +} diff --git a/src/main/java/twilightforest/network/PacketAnnihilateBlock.java b/src/main/java/twilightforest/network/PacketAnnihilateBlock.java new file mode 100644 index 0000000000..c5180f7454 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketAnnihilateBlock.java @@ -0,0 +1,61 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; + +public class PacketAnnihilateBlock implements IMessage { + + private BlockPos pos; + + public PacketAnnihilateBlock() {} + + public PacketAnnihilateBlock(BlockPos pos) { + this.pos = pos; + } + + @Override + public void fromBytes(ByteBuf buf) { + pos = BlockPos.fromLong(buf.readLong()); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeLong(pos.toLong()); + } + + public static class Handler implements IMessageHandler { + @Override + public IMessage onMessage(PacketAnnihilateBlock message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + World world = Minecraft.getMinecraft().world; + for (int dx = 0; dx < 4; ++dx) { + for (int dy = 0; dy < 4; ++dy) { + for (int dz = 0; dz < 4; ++dz) { + + double x = message.pos.getX() + (dx + 0.5D) / 4; + double y = message.pos.getY() + (dy + 0.5D) / 4; + double z = message.pos.getZ() + (dz + 0.5D) / 4; + + double vx = world.rand.nextGaussian() * 0.2D; + double vy = world.rand.nextGaussian() * 0.2D; + double vz = world.rand.nextGaussian() * 0.2D; + + TwilightForestMod.proxy.spawnParticle(TFParticleType.ANNIHILATE, x, y, z, vx, vy, vz); + } + } + } + } + }); + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketAreaProtection.java b/src/main/java/twilightforest/network/PacketAreaProtection.java new file mode 100644 index 0000000000..8a1f86efad --- /dev/null +++ b/src/main/java/twilightforest/network/PacketAreaProtection.java @@ -0,0 +1,91 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; +import twilightforest.entity.EntityTFProtectionBox; + +public class PacketAreaProtection implements IMessage { + + private StructureBoundingBox sbb; + private BlockPos pos; + + public PacketAreaProtection() {} + + public PacketAreaProtection(StructureBoundingBox sbb, BlockPos pos) { + this.sbb = sbb; + this.pos = pos; + } + + @Override + public void fromBytes(ByteBuf buf) { + sbb = new StructureBoundingBox( + buf.readInt(), buf.readInt(), buf.readInt(), + buf.readInt(), buf.readInt(), buf.readInt() + ); + pos = BlockPos.fromLong(buf.readLong()); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(sbb.minX); + buf.writeInt(sbb.minY); + buf.writeInt(sbb.minZ); + buf.writeInt(sbb.maxX); + buf.writeInt(sbb.maxY); + buf.writeInt(sbb.maxZ); + buf.writeLong(pos.toLong()); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketAreaProtection message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + + World world = Minecraft.getMinecraft().world; + addProtectionBox(world, message.sbb); + + for (int i = 0; i < 20; i++) { + + double vx = world.rand.nextGaussian() * 0.02D; + double vy = world.rand.nextGaussian() * 0.02D; + double vz = world.rand.nextGaussian() * 0.02D; + + double x = message.pos.getX() + 0.5D + world.rand.nextFloat() - world.rand.nextFloat(); + double y = message.pos.getY() + 0.5D + world.rand.nextFloat() - world.rand.nextFloat(); + double z = message.pos.getZ() + 0.5D + world.rand.nextFloat() - world.rand.nextFloat(); + + TwilightForestMod.proxy.spawnParticle(TFParticleType.PROTECTION, x, y, z, vx, vy, vz); + } + } + }); + return null; + } + + static void addProtectionBox(World world, StructureBoundingBox sbb) { + + for (Entity entity : world.weatherEffects) { + if (entity instanceof EntityTFProtectionBox) { + EntityTFProtectionBox protectionBox = (EntityTFProtectionBox) entity; + if (protectionBox.matches(sbb)) { + protectionBox.resetLifetime(); + return; + } + } + } + + world.addWeatherEffect(new EntityTFProtectionBox(world, sbb)); + } + } +} diff --git a/src/main/java/twilightforest/network/PacketChangeBiome.java b/src/main/java/twilightforest/network/PacketChangeBiome.java new file mode 100644 index 0000000000..dd4a612774 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketChangeBiome.java @@ -0,0 +1,58 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; + +public class PacketChangeBiome implements IMessage { + + private BlockPos pos; + private byte biomeId; + + public PacketChangeBiome() { + } + + public PacketChangeBiome(BlockPos pos, Biome biome) { + this.pos = pos; + this.biomeId = (byte) Biome.getIdForBiome(biome); + } + + @Override + public void fromBytes(ByteBuf buf) { + pos = new BlockPos(buf.readInt(), 0, buf.readInt()); + biomeId = buf.readByte(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(pos.getX()); + buf.writeInt(pos.getZ()); + buf.writeByte(biomeId); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketChangeBiome message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + World world = Minecraft.getMinecraft().world; + Chunk chunkAt = world.getChunk(message.pos); + + chunkAt.getBiomeArray()[(message.pos.getZ() & 15) << 4 | (message.pos.getX() & 15)] = message.biomeId; + + world.markBlockRangeForRenderUpdate(message.pos, message.pos.up(255)); + } + }); + + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketEnforceProgressionStatus.java b/src/main/java/twilightforest/network/PacketEnforceProgressionStatus.java new file mode 100644 index 0000000000..be76c88d73 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketEnforceProgressionStatus.java @@ -0,0 +1,43 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.TwilightForestMod; + +public class PacketEnforceProgressionStatus implements IMessage { + + private boolean enforce; + + public PacketEnforceProgressionStatus() {} + + public PacketEnforceProgressionStatus(boolean enforce) { + this.enforce = enforce; + } + + @Override + public void fromBytes(ByteBuf buf) { + enforce = buf.readBoolean(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeBoolean(enforce); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketEnforceProgressionStatus message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + Minecraft.getMinecraft().world.getGameRules().setOrCreateGameRule(TwilightForestMod.ENFORCED_PROGRESSION_RULE, String.valueOf(message.enforce)); + } + }); + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketMagicMap.java b/src/main/java/twilightforest/network/PacketMagicMap.java new file mode 100644 index 0000000000..ea37f2ac11 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketMagicMap.java @@ -0,0 +1,116 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.MapItemRenderer; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SPacketMaps; +import net.minecraft.world.storage.MapData; +import net.minecraft.world.storage.MapDecoration; +import net.minecraftforge.fml.common.network.ByteBufUtils; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.TFMagicMapData; +import twilightforest.item.ItemTFMagicMap; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +// Rewraps vanilla SPacketMaps to properly expose our custom decorations +public class PacketMagicMap implements IMessage { + private int mapID; + private byte[] featureData; + private SPacketMaps inner; + + public PacketMagicMap() { + } + + public PacketMagicMap(int mapID, TFMagicMapData mapData, SPacketMaps inner) { + this.mapID = mapID; + this.featureData = mapData.serializeFeatures(); + this.inner = inner; + } + + @Override + public void fromBytes(ByteBuf buf) { + PacketBuffer tmp = new PacketBuffer(buf); + mapID = ByteBufUtils.readVarInt(buf, 5); + featureData = tmp.readByteArray(); + + inner = new SPacketMaps(); + try { + inner.readPacketData(tmp); + } catch (IOException e) { + throw new RuntimeException("Couldn't read inner SPacketMaps", e); + } + } + + @Override + public void toBytes(ByteBuf buf) { + PacketBuffer tmp = new PacketBuffer(buf); + ByteBufUtils.writeVarInt(buf, mapID, 5); + tmp.writeByteArray(featureData); + + try { + inner.writePacketData(tmp); + } catch (IOException e) { + throw new RuntimeException("Couldn't write inner SPacketMaps", e); + } + } + + public static class Handler implements IMessageHandler { + @Override + public IMessage onMessage(PacketMagicMap message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + + MapItemRenderer mapItemRenderer = Minecraft.getMinecraft().entityRenderer.getMapItemRenderer(); + TFMagicMapData mapData = ItemTFMagicMap.loadMapData(message.mapID, Minecraft.getMinecraft().world); + + // Adapted from NetHandlerPlayClient#handleMaps + if (mapData == null) + { + String s = ItemTFMagicMap.STR_ID + "_" + message.mapID; + mapData = new TFMagicMapData(s); + + if (mapItemRenderer.getMapInstanceIfExists(s) != null) + { + MapData mapdata1 = mapItemRenderer.getData(mapItemRenderer.getMapInstanceIfExists(s)); + + if (mapdata1 instanceof TFMagicMapData) + { + mapData = (TFMagicMapData) mapdata1; + } + } + + Minecraft.getMinecraft().world.setData(s, mapData); + } + + message.inner.setMapdataTo(mapData); + + // Deserialize to tfDecorations + mapData.deserializeFeatures(message.featureData); + + // Cheat and put tfDecorations into main collection so they are called by renderer + // However, clear the decorations vanilla put there so player markers go above feature markers. + Map saveVanilla = mapData.mapDecorations; + mapData.mapDecorations = new LinkedHashMap<>(); + + for (TFMagicMapData.TFMapDecoration tfDecor : mapData.tfDecorations) { + mapData.mapDecorations.put(tfDecor.toString(), tfDecor); + } + + mapData.mapDecorations.putAll(saveVanilla); + + mapItemRenderer.updateMapTexture(mapData); + } + }); + + return null; + } + } + +} diff --git a/src/main/java/twilightforest/network/PacketMazeMap.java b/src/main/java/twilightforest/network/PacketMazeMap.java new file mode 100644 index 0000000000..4a4152d099 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketMazeMap.java @@ -0,0 +1,83 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.MapItemRenderer; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SPacketMaps; +import net.minecraft.world.storage.MapData; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.TFMazeMapData; +import twilightforest.item.ItemTFMazeMap; + +import java.io.IOException; + +/** + * Vanilla's SPacketMaps handler looks for and loads the vanilla MapData instances. + * We rewrap the packet here in order to load our own MapData instances properly. + */ +public class PacketMazeMap implements IMessage { + + private SPacketMaps inner; + + public PacketMazeMap() {} + + public PacketMazeMap(SPacketMaps inner) { + this.inner = inner; + } + + @Override + public void fromBytes(ByteBuf buf) { + inner = new SPacketMaps(); + try { + inner.readPacketData(new PacketBuffer(buf)); + } catch (IOException e) { + throw new RuntimeException("Couldn't read inner SPacketMaps", e); + } + } + + @Override + public void toBytes(ByteBuf buf) { + try { + inner.writePacketData(new PacketBuffer(buf)); + } catch (IOException e) { + throw new RuntimeException("Couldn't write inner SPacketMaps", e); + } + } + + public static class Handler implements IMessageHandler { + @Override + public IMessage onMessage(PacketMazeMap message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + + MapItemRenderer mapItemRenderer = Minecraft.getMinecraft().entityRenderer.getMapItemRenderer(); + MapData mapData = ItemTFMazeMap.loadMapData(message.inner.getMapId(), Minecraft.getMinecraft().world); + + // Adapted from NetHandlerPlayClient#handleMaps + if (mapData == null) { + + String s = ItemTFMazeMap.STR_ID + "_" + message.inner.getMapId(); + mapData = new TFMazeMapData(s); + + if (mapItemRenderer.getMapInstanceIfExists(s) != null) { + MapData mapData1 = mapItemRenderer.getData(mapItemRenderer.getMapInstanceIfExists(s)); + if (mapData1 != null) { + mapData = mapData1; + } + } + + Minecraft.getMinecraft().world.setData(s, mapData); + } + + message.inner.setMapdataTo(mapData); + mapItemRenderer.updateMapTexture(mapData); + } + }); + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketSetSkylightEnabled.java b/src/main/java/twilightforest/network/PacketSetSkylightEnabled.java new file mode 100644 index 0000000000..a5896aad3c --- /dev/null +++ b/src/main/java/twilightforest/network/PacketSetSkylightEnabled.java @@ -0,0 +1,37 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.world.WorldProviderTwilightForest; + +public class PacketSetSkylightEnabled implements IMessage { + + private boolean enabled; + + public PacketSetSkylightEnabled() {} + + public PacketSetSkylightEnabled(boolean enabled) { + this.enabled = enabled; + } + + @Override + public void fromBytes(ByteBuf buf) { + enabled = buf.readBoolean(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeBoolean(enabled); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketSetSkylightEnabled message, MessageContext ctx) { + WorldProviderTwilightForest.setSkylightEnabled(message.enabled); + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketSpawnEntityParticles.java b/src/main/java/twilightforest/network/PacketSpawnEntityParticles.java new file mode 100644 index 0000000000..ecc5a7b51d --- /dev/null +++ b/src/main/java/twilightforest/network/PacketSpawnEntityParticles.java @@ -0,0 +1,72 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; + +import java.util.Random; + +public class PacketSpawnEntityParticles implements IMessage { + + private TFParticleType type; + private double x, y, z; + private float width, height; + private int count; + + public PacketSpawnEntityParticles() {} + + public PacketSpawnEntityParticles(TFParticleType type, Entity entity, int count) { + this.type = type; + this.x = entity.posX; + this.y = entity.posY; + this.z = entity.posZ; + this.width = entity.width; + this.height = entity.height; + this.count = count; + } + + @Override + public void fromBytes(ByteBuf buf) { + type = TFParticleType.values()[buf.readInt()]; + x = buf.readDouble(); + y = buf.readDouble(); + z = buf.readDouble(); + width = buf.readFloat(); + height = buf.readFloat(); + count = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(type.ordinal()); + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeFloat(width); + buf.writeFloat(height); + buf.writeInt(count); + } + + public static class Handler implements IMessageHandler { + + private final Random random = new Random(); + + @Override + public IMessage onMessage(PacketSpawnEntityParticles message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(() -> { + for (int i = 0; i < message.count; i++) { + double x = message.x + random.nextFloat() * message.width * 2.0 - message.width; + double y = message.y + random.nextFloat() * message.height; + double z = message.z + random.nextFloat() * message.width * 2.0 - message.width; + TwilightForestMod.proxy.spawnParticle(message.type, x, y, z, 0.0, 0.0, 0.0); + } + }); + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketStructureProtection.java b/src/main/java/twilightforest/network/PacketStructureProtection.java new file mode 100644 index 0000000000..d87ad478f7 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketStructureProtection.java @@ -0,0 +1,63 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraftforge.client.IRenderHandler; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.client.renderer.TFWeatherRenderer; +import twilightforest.world.WorldProviderTwilightForest; + +public class PacketStructureProtection implements IMessage { + + private StructureBoundingBox sbb; + + @SuppressWarnings("unused") + public PacketStructureProtection() {} + + public PacketStructureProtection(StructureBoundingBox sbb) { + this.sbb = sbb; + } + + @Override + public void fromBytes(ByteBuf buf) { + sbb = new StructureBoundingBox( + buf.readInt(), buf.readInt(), buf.readInt(), + buf.readInt(), buf.readInt(), buf.readInt() + ); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(sbb.minX); + buf.writeInt(sbb.minY); + buf.writeInt(sbb.minZ); + buf.writeInt(sbb.maxX); + buf.writeInt(sbb.maxY); + buf.writeInt(sbb.maxZ); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketStructureProtection message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(() -> { + WorldProvider provider = Minecraft.getMinecraft().world.provider; + + // add weather box if needed + if (provider instanceof WorldProviderTwilightForest) { + IRenderHandler weatherRenderer = provider.getWeatherRenderer(); + + if (weatherRenderer instanceof TFWeatherRenderer) { + ((TFWeatherRenderer) weatherRenderer).setProtectedBox(message.sbb); + } + } + }); + + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketStructureProtectionClear.java b/src/main/java/twilightforest/network/PacketStructureProtectionClear.java new file mode 100644 index 0000000000..9cc05e044a --- /dev/null +++ b/src/main/java/twilightforest/network/PacketStructureProtectionClear.java @@ -0,0 +1,40 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.world.WorldProvider; +import net.minecraftforge.client.IRenderHandler; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.client.renderer.TFWeatherRenderer; +import twilightforest.world.WorldProviderTwilightForest; + +public class PacketStructureProtectionClear implements IMessage { + + @Override + public void fromBytes(ByteBuf buf) {} + + @Override + public void toBytes(ByteBuf buf) {} + + public static class Handler implements IMessageHandler { + @Override + public IMessage onMessage(PacketStructureProtectionClear message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(() -> { + WorldProvider provider = Minecraft.getMinecraft().world.provider; + + // add weather box if needed + if (provider instanceof WorldProviderTwilightForest) { + IRenderHandler weatherRenderer = provider.getWeatherRenderer(); + + if (weatherRenderer instanceof TFWeatherRenderer) { + ((TFWeatherRenderer) weatherRenderer).setProtectedBox(null); + } + } + }); + + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketThrowPlayer.java b/src/main/java/twilightforest/network/PacketThrowPlayer.java new file mode 100644 index 0000000000..3c31498cc1 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketThrowPlayer.java @@ -0,0 +1,51 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; + +public class PacketThrowPlayer implements IMessage { + private float motionX; + private float motionY; + private float motionZ; + + public PacketThrowPlayer() { + } + + public PacketThrowPlayer(float motionX, float motionY, float motionZ) { + this.motionX = motionX; + this.motionY = motionY; + this.motionZ = motionZ; + } + + @Override + public void fromBytes(ByteBuf buf) { + motionX = buf.readFloat(); + motionY = buf.readFloat(); + motionZ = buf.readFloat(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeFloat(motionX); + buf.writeFloat(motionY); + buf.writeFloat(motionZ); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketThrowPlayer message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + Minecraft.getMinecraft().player.addVelocity(message.motionX, message.motionY, message.motionZ); + } + }); + + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketUncraftingGui.java b/src/main/java/twilightforest/network/PacketUncraftingGui.java new file mode 100644 index 0000000000..2f545117ff --- /dev/null +++ b/src/main/java/twilightforest/network/PacketUncraftingGui.java @@ -0,0 +1,82 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.Container; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.inventory.ContainerTFUncrafting; + +public class PacketUncraftingGui implements IMessage { + private int type; + + public PacketUncraftingGui(int type) { + this.type = type; + } + + public PacketUncraftingGui() { + } + + @Override + public void fromBytes(ByteBuf buf) { + type = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(type); + } + + public static class Handler implements IMessageHandler { + public Handler () { + + } + + @SuppressWarnings("Convert2Lambda") + @Override + public IMessage onMessage(PacketUncraftingGui message, MessageContext ctx) { + EntityPlayerMP player = ctx.getServerHandler().player; + + player.getServerWorld().addScheduledTask(new Runnable() { + @Override + public void run() { + Container container = player.openContainer; + + if (container instanceof ContainerTFUncrafting) { + ContainerTFUncrafting uncrafting = (ContainerTFUncrafting) container; + + switch (message.type) { + case 0: + uncrafting.unrecipeInCycle++; + break; + case 1: + uncrafting.unrecipeInCycle--; + break; + case 2: + uncrafting.ingredientsInCycle++; + break; + case 3: + uncrafting.ingredientsInCycle--; + break; + case 4: + uncrafting.recipeInCycle++; + break; + case 5: + uncrafting.recipeInCycle--; + break; + } + + if (message.type < 4) + uncrafting.onCraftMatrixChanged(uncrafting.tinkerInput); + + if (message.type >= 4) + uncrafting.onCraftMatrixChanged(uncrafting.assemblyMatrix); + } + } + }); + + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/PacketUpdateShield.java b/src/main/java/twilightforest/network/PacketUpdateShield.java new file mode 100644 index 0000000000..4f3efe6a80 --- /dev/null +++ b/src/main/java/twilightforest/network/PacketUpdateShield.java @@ -0,0 +1,66 @@ +package twilightforest.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import twilightforest.capabilities.CapabilityList; +import twilightforest.capabilities.shield.IShieldCapability; + +public class PacketUpdateShield implements IMessage { + + private int entityID; + private int temporaryShields; + private int permanentShields; + + public PacketUpdateShield() {} + + public PacketUpdateShield(int id, IShieldCapability cap) { + entityID = id; + temporaryShields = cap.temporaryShieldsLeft(); + permanentShields = cap.permanentShieldsLeft(); + } + + public PacketUpdateShield(Entity entity, IShieldCapability cap) { + this(entity.getEntityId(), cap); + } + + @Override + public void fromBytes(ByteBuf buf) { + entityID = buf.readInt(); + temporaryShields = buf.readInt(); + permanentShields = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(entityID); + buf.writeInt(temporaryShields); + buf.writeInt(permanentShields); + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(PacketUpdateShield message, MessageContext ctx) { + Minecraft.getMinecraft().addScheduledTask(new Runnable() { + @Override + public void run() { + Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.entityID); + if (entity instanceof EntityLivingBase) { + IShieldCapability cap = entity.getCapability(CapabilityList.SHIELDS, null); + if (cap != null) { + cap.setShields(message.temporaryShields, true); + cap.setShields(message.permanentShields, false); + } + } + } + }); + + return null; + } + } +} diff --git a/src/main/java/twilightforest/network/TFPacketHandler.java b/src/main/java/twilightforest/network/TFPacketHandler.java new file mode 100644 index 0000000000..c636dd6f55 --- /dev/null +++ b/src/main/java/twilightforest/network/TFPacketHandler.java @@ -0,0 +1,30 @@ +package twilightforest.network; + +import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; +import net.minecraftforge.fml.relauncher.Side; +import twilightforest.TwilightForestMod; + +public class TFPacketHandler { + + public static final SimpleNetworkWrapper CHANNEL = NetworkRegistry.INSTANCE.newSimpleChannel(TwilightForestMod.ID); + + @SuppressWarnings("UnusedAssignment") + public static void init() { + int id = 0; + CHANNEL.registerMessage(PacketAnnihilateBlock.Handler.class, PacketAnnihilateBlock.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketAreaProtection.Handler.class, PacketAreaProtection.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketChangeBiome.Handler.class, PacketChangeBiome.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketEnforceProgressionStatus.Handler.class, PacketEnforceProgressionStatus.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketStructureProtection.Handler.class, PacketStructureProtection.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketStructureProtectionClear.Handler.class, PacketStructureProtectionClear.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketThrowPlayer.Handler.class, PacketThrowPlayer.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketMagicMap.Handler.class, PacketMagicMap.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketMazeMap.Handler.class, PacketMazeMap.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketUpdateShield.Handler.class, PacketUpdateShield.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketSetSkylightEnabled.Handler.class, PacketSetSkylightEnabled.class, id++, Side.CLIENT); + CHANNEL.registerMessage(PacketSpawnEntityParticles.Handler.class, PacketSpawnEntityParticles.class, id++, Side.CLIENT); + + CHANNEL.registerMessage(PacketUncraftingGui.Handler.class, PacketUncraftingGui.class, id++, Side.SERVER); + } +} diff --git a/src/main/java/twilightforest/package-info.java b/src/main/java/twilightforest/package-info.java new file mode 100644 index 0000000000..29059b48b1 --- /dev/null +++ b/src/main/java/twilightforest/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/potions/PotionFrosted.java b/src/main/java/twilightforest/potions/PotionFrosted.java new file mode 100644 index 0000000000..4991083723 --- /dev/null +++ b/src/main/java/twilightforest/potions/PotionFrosted.java @@ -0,0 +1,38 @@ +package twilightforest.potions; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TwilightForestMod; +import twilightforest.client.GuiUtils; + +import java.util.UUID; + +public class PotionFrosted extends Potion { + + public static final UUID MODIFIER_UUID = UUID.fromString("CE9DBC2A-EE3F-43F5-9DF7-F7F1EE4915A9"); + + private static final ResourceLocation sprite = TwilightForestMod.prefix("textures/gui/frosty.png"); + + public PotionFrosted(boolean isBadEffectIn, int liquidColorIn) { + super(isBadEffectIn, liquidColorIn); + } + + @Override + @SideOnly(Side.CLIENT) + public void renderHUDEffect(PotionEffect effect, Gui gui, int x, int y, float z, float alpha) { + Minecraft.getMinecraft().renderEngine.bindTexture(sprite); + GuiUtils.drawModalRectWithCustomSizedTexture(x + 3, y + 3, z, 0, 0, 18, 18, 18, 18); + } + + @Override + @SideOnly(Side.CLIENT) + public void renderInventoryEffect(PotionEffect effect, Gui gui, int x, int y, float z) { + Minecraft.getMinecraft().renderEngine.bindTexture(sprite); + GuiUtils.drawModalRectWithCustomSizedTexture(x + 6, y + 7, z, 0, 0, 18, 18, 18, 18); + } +} diff --git a/src/main/java/twilightforest/potions/TFPotions.java b/src/main/java/twilightforest/potions/TFPotions.java new file mode 100644 index 0000000000..7958fc69da --- /dev/null +++ b/src/main/java/twilightforest/potions/TFPotions.java @@ -0,0 +1,17 @@ +package twilightforest.potions; + +import net.minecraft.potion.Potion; +import net.minecraftforge.fml.common.registry.GameRegistry; +import twilightforest.TwilightForestMod; + +@GameRegistry.ObjectHolder(TwilightForestMod.ID) +public class TFPotions { + + @GameRegistry.ObjectHolder("frosted") + public static final Potion frosty; + + static { + frosty = null; + } + +} diff --git a/src/main/java/twilightforest/potions/TFRegisterPotionEvent.java b/src/main/java/twilightforest/potions/TFRegisterPotionEvent.java new file mode 100644 index 0000000000..5dcc391202 --- /dev/null +++ b/src/main/java/twilightforest/potions/TFRegisterPotionEvent.java @@ -0,0 +1,21 @@ +package twilightforest.potions; + +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.potion.Potion; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import twilightforest.TwilightForestMod; + +@Mod.EventBusSubscriber(modid = TwilightForestMod.ID) +public class TFRegisterPotionEvent { + + @SubscribeEvent + public static void onRegisterPotions(RegistryEvent.Register event) { + registerPotion("frosted", new PotionFrosted(true, 0x56CBFD).setPotionName(TwilightForestMod.ID + ".effect.frosted").registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED, PotionFrosted.MODIFIER_UUID.toString(), -0.15000000596046448D, 2), event); + } + + public static void registerPotion(String name, Potion potion, RegistryEvent.Register event){ + event.getRegistry().register(potion.setRegistryName(TwilightForestMod.ID, name)); + } +} diff --git a/src/main/java/twilightforest/structures/ComponentTFHedgeMaze.java b/src/main/java/twilightforest/structures/ComponentTFHedgeMaze.java index c8154da04a..d1f29787e7 100644 --- a/src/main/java/twilightforest/structures/ComponentTFHedgeMaze.java +++ b/src/main/java/twilightforest/structures/ComponentTFHedgeMaze.java @@ -1,52 +1,56 @@ package twilightforest.structures; -import java.util.Random; - +import net.minecraft.block.BlockPumpkin; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityList; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.TFTreasure; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; +import twilightforest.entity.EntityTFHedgeSpider; +import twilightforest.entity.EntityTFHostileWolf; +import twilightforest.entity.EntityTFSwarmSpider; + +import java.util.Random; +public class ComponentTFHedgeMaze extends StructureTFComponentOld { -public class ComponentTFHedgeMaze extends StructureTFComponent { - - static int MSIZE = 16; - static int RADIUS = (MSIZE / 2 * 3) + 1; - static int DIAMETER = 2 * RADIUS; - - static int FLOOR_LEVEL = 3; + private static final int MSIZE = 16; + private static final int RADIUS = (MSIZE / 2 * 3) + 1; + private static final int DIAMETER = 2 * RADIUS; + private static final int FLOOR_LEVEL = 3; - public ComponentTFHedgeMaze() - { - ; + public ComponentTFHedgeMaze() { + super(); } - public ComponentTFHedgeMaze(World world, Random rand, int i, int x, int y, int z) { - super(i); - - this.setCoordBaseMode(0); - + public ComponentTFHedgeMaze(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, i); + + this.setCoordBaseMode(EnumFacing.SOUTH); + // the maze is 50 x 50 for now - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -RADIUS, -3, -RADIUS, RADIUS * 2, 10, RADIUS * 2, 0); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -RADIUS, -3, -RADIUS, RADIUS * 2, 10, RADIUS * 2, EnumFacing.SOUTH); } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - + TFMaze maze = new TFMaze(MSIZE, MSIZE); - + maze.oddBias = 2; - maze.torchBlockID = TFBlocks.firefly; - maze.wallBlockID = TFBlocks.hedge; - maze.wallBlockMeta = 0; + maze.torchBlockState = TFBlocks.firefly.getDefaultState(); + maze.wallBlockState = TFBlocks.hedge.getDefaultState(); maze.type = 4; maze.tall = 3; maze.roots = 3; - + // set the seed to a fixed value based on this maze's x and z maze.setSeed(world.getSeed() + this.boundingBox.minX * this.boundingBox.minZ); @@ -54,70 +58,72 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox // grass underneath for (int fx = 0; fx <= DIAMETER; fx++) { for (int fz = 0; fz <= DIAMETER; fz++) { - placeBlockAtCurrentPosition(world, Blocks.grass, 0, fx, FLOOR_LEVEL - 1, fz, sbb); + setBlockState(world, Blocks.GRASS.getDefaultState(), fx, FLOOR_LEVEL - 1, fz, sbb); } } + IBlockState northJacko = Blocks.LIT_PUMPKIN.getDefaultState().withProperty(BlockPumpkin.FACING, EnumFacing.NORTH); + IBlockState southJacko = Blocks.LIT_PUMPKIN.getDefaultState().withProperty(BlockPumpkin.FACING, EnumFacing.SOUTH); + IBlockState westJacko = Blocks.LIT_PUMPKIN.getDefaultState().withProperty(BlockPumpkin.FACING, EnumFacing.WEST); + IBlockState eastJacko = Blocks.LIT_PUMPKIN.getDefaultState().withProperty(BlockPumpkin.FACING, EnumFacing.EAST); + // plunk down some jack-o-lanterns outside for decoration - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 1, 0, FLOOR_LEVEL, 24, sbb); - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 1, 0, FLOOR_LEVEL, 29, sbb); - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 3, 50, FLOOR_LEVEL, 24, sbb); - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 3, 50, FLOOR_LEVEL, 29, sbb); - - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 2, 24, FLOOR_LEVEL, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 2, 29, FLOOR_LEVEL, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 0, 24, FLOOR_LEVEL, 50, sbb); - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, 0, 29, FLOOR_LEVEL, 50, sbb); - - + setBlockState(world, westJacko, 0, FLOOR_LEVEL, 24, sbb); + setBlockState(world, westJacko, 0, FLOOR_LEVEL, 29, sbb); + setBlockState(world, eastJacko, 50, FLOOR_LEVEL, 24, sbb); + setBlockState(world, eastJacko, 50, FLOOR_LEVEL, 29, sbb); + + setBlockState(world, northJacko, 24, FLOOR_LEVEL, 0, sbb); + setBlockState(world, northJacko, 29, FLOOR_LEVEL, 0, sbb); + setBlockState(world, southJacko, 24, FLOOR_LEVEL, 50, sbb); + setBlockState(world, southJacko, 29, FLOOR_LEVEL, 50, sbb); + + int nrooms = MSIZE / 3; int rcoords[] = new int[nrooms * 2]; - for (int i = 0; i < nrooms; i++) - { + for (int i = 0; i < nrooms; i++) { int rx, rz; do { rx = maze.rand.nextInt(MSIZE - 2) + 1; rz = maze.rand.nextInt(MSIZE - 2) + 1; - } while(isNearRoom(rx, rz, rcoords)); + } while (isNearRoom(rx, rz, rcoords)); maze.carveRoom1(rx, rz); rcoords[i * 2] = rx; rcoords[i * 2 + 1] = rz; } - + maze.generateRecursiveBacktracker(0, 0); - + maze.add4Exits(); - + maze.copyToStructure(world, 1, FLOOR_LEVEL, 1, this, sbb); - + decorate3x3Rooms(world, rcoords, sbb); - - - + + return true; } - + /** * @return true if the specified dx and dz are within 3 of a room specified in rcoords */ - protected boolean isNearRoom(int dx, int dz, int[] rcoords) { + private boolean isNearRoom(int dx, int dz, int[] rcoords) { // if proposed coordinates are covering the origin, return true to stop the room from causing the maze to fail if (dx == 1 && dz == 1) { return true; } - - for (int i = 0; i < rcoords.length / 2; i++) - { + + for (int i = 0; i < rcoords.length / 2; i++) { int rx = rcoords[i * 2]; int rz = rcoords[i * 2 + 1]; - + if (rx == 0 && rz == 0) { continue; } - + if (Math.abs(dx - rx) < 3 && Math.abs(dz - rz) < 3) { return true; } @@ -125,21 +131,11 @@ protected boolean isNearRoom(int dx, int dz, int[] rcoords) { return false; } - - /** - * - * @param rand - * @param world - * @param rcoords - * @param sbb - */ - void decorate3x3Rooms(World world, int[] rcoords, StructureBoundingBox sbb) - { - for (int i = 0; i < rcoords.length / 2; i++) - { + private void decorate3x3Rooms(World world, int[] rcoords, StructureBoundingBox sbb) { + for (int i = 0; i < rcoords.length / 2; i++) { int dx = rcoords[i * 2]; int dz = rcoords[i * 2 + 1]; - + // MAGIC NUMBERS!!! convert the maze coordinates into coordinates for our structure dx = dx * 3 + 3; dz = dz * 3 + 3; @@ -150,21 +146,14 @@ void decorate3x3Rooms(World world, int[] rcoords, StructureBoundingBox sbb) /** * Decorates a room in the maze. Makes assumptions that the room is 3x3 cells and thus 11x11 blocks large. - * @param rand - * @param world - * @param sbb - * - * @param dx - * @param dy */ - void decorate3x3Room(World world, int x, int z, StructureBoundingBox sbb) - { + private void decorate3x3Room(World world, int x, int z, StructureBoundingBox sbb) { // make a new RNG for this room! Random roomRNG = new Random(world.getSeed() ^ x + z); - + // a few jack-o-lanterns roomJackO(world, roomRNG, x, z, 8, sbb); - if(roomRNG.nextInt(4) == 0) { + if (roomRNG.nextInt(4) == 0) { roomJackO(world, roomRNG, x, z, 8, sbb); } @@ -185,21 +174,21 @@ private void roomSpawner(World world, Random rand, int x, int z, int diameter, S int rx = x + rand.nextInt(diameter) - (diameter / 2); int rz = z + rand.nextInt(diameter) - (diameter / 2); - String mobID; + ResourceLocation mobID; switch (rand.nextInt(3)) { - case 1 : - mobID = TFCreatures.getSpawnerNameFor("Swarm Spider"); - break; - case 2 : - mobID = TFCreatures.getSpawnerNameFor("Hostile Wolf"); - break; - case 0 : - default: - mobID = TFCreatures.getSpawnerNameFor("Hedge Spider"); + case 1: + mobID = EntityList.getKey(EntityTFSwarmSpider.class); + break; + case 2: + mobID = EntityList.getKey(EntityTFHostileWolf.class); + break; + case 0: + default: + mobID = EntityList.getKey(EntityTFHedgeSpider.class); } - placeSpawnerAtCurrentPosition(world, rand, rx, FLOOR_LEVEL, rz, mobID, sbb); + setSpawner(world, rx, FLOOR_LEVEL, rz, sbb, mobID); } /** @@ -220,7 +209,8 @@ private void roomJackO(World world, Random rand, int x, int z, int diameter, Str int rx = x + rand.nextInt(diameter) - (diameter / 2); int rz = z + rand.nextInt(diameter) - (diameter / 2); - placeBlockAtCurrentPosition(world, Blocks.lit_pumpkin, rand.nextInt(4), rx, FLOOR_LEVEL, rz, sbb); + setBlockState(world, Blocks.LIT_PUMPKIN.getDefaultState().withProperty(BlockPumpkin.FACING, EnumFacing.byHorizontalIndex(rand.nextInt(4))), + rx, FLOOR_LEVEL, rz, sbb); } diff --git a/src/main/java/twilightforest/structures/ComponentTFHillMaze.java b/src/main/java/twilightforest/structures/ComponentTFHillMaze.java deleted file mode 100644 index fe4a1f0c0b..0000000000 --- a/src/main/java/twilightforest/structures/ComponentTFHillMaze.java +++ /dev/null @@ -1,195 +0,0 @@ -package twilightforest.structures; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.TFTreasure; -import twilightforest.block.TFBlocks; - - - -public class ComponentTFHillMaze extends StructureTFComponent { - - public ComponentTFHillMaze() { - super(); - // TODO Auto-generated constructor stub - } - - private static final int FLOOR_LEVEL = 1; - private int hillSize; - - public ComponentTFHillMaze(int i, int x, int y, int z, int hsize) { - super(i); - this.hillSize = hsize; - - this.setCoordBaseMode(0); - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -getRadius(), 0, -getRadius(), getRadius() * 2, 5, getRadius() * 2, 0); - - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // clear the area - fillWithBlocks(world, sbb, 0, 1, 0, getDiameter(), 3, getDiameter(), Blocks.air, Blocks.air, false); - fillWithBlocks(world, sbb, 0, 0, 0, getDiameter(), 0, getDiameter(), TFBlocks.mazestone, TFBlocks.mazestone, false); - fillWithBlocks(world, sbb, 0, 4, 0, getDiameter(), 4, getDiameter(), TFBlocks.mazestone, TFBlocks.mazestone, true); - - - // make maze object - TFMaze maze = new TFMaze(getMazeSize(), getMazeSize()); - - maze.wallBlockID = TFBlocks.mazestone; - maze.wallBlockMeta = 3; - maze.torchRarity = 0.05F; - - // set the seed to a fixed value based on this maze's x and z - maze.setSeed(world.getSeed() + this.boundingBox.minX * this.boundingBox.minZ); - - - int nrooms = getMazeSize() / 3; - int rcoords[] = new int[nrooms * 2]; - - // add rooms, trying to keep them separate from existing rooms - for (int i = 0; i < nrooms; i++) - { - int rx, rz; - do { - rx = maze.rand.nextInt(getMazeSize() - 2) + 1; - rz = maze.rand.nextInt(getMazeSize() - 2) + 1; - } while(isNearRoom(rx, rz, rcoords)); - - maze.carveRoom1(rx, rz); - - rcoords[i * 2] = rx; - rcoords[i * 2 + 1] = rz; - } - - // make actual maze - maze.generateRecursiveBacktracker(0, 0); - - maze.add4Exits(); - - maze.copyToStructure(world, 0, 1, 0, this, sbb); - - - decorate3x3Rooms(world, rcoords, sbb); - - - return true; - - } - - public int getMazeSize() { - return hillSize == 1 ? 11 : hillSize == 2 ? 19 : 27; - } - - public int getRadius() { - return getMazeSize() * 2; - } - - public int getDiameter() { - return getMazeSize() * 4; - } - - /** - * @return true if the specified dx and dz are within 3 of a room specified in rcoords - */ - protected boolean isNearRoom(int dx, int dz, int[] rcoords) { - // if proposed coordinates are covering the origin, return true to stop the room from causing the maze to fail - if (dx == 1 && dz == 1) { - return true; - } - - for (int i = 0; i < rcoords.length / 2; i++) - { - int rx = rcoords[i * 2]; - int rz = rcoords[i * 2 + 1]; - - if (rx == 0 && rz == 0) { - continue; - } - - if (Math.abs(dx - rx) < 3 && Math.abs(dz - rz) < 3) { - return true; - } - } - return false; - } - - - void decorate3x3Rooms(World world, int[] rcoords, StructureBoundingBox sbb) - { - for (int i = 0; i < rcoords.length / 2; i++) - { - int dx = rcoords[i * 2]; - int dz = rcoords[i * 2 + 1]; - - // MAGIC NUMBERS!!! convert the maze coordinates into coordinates for our structure - dx = dx * 4 + 2; - dz = dz * 4 + 2; - - decorate3x3Room(world, dx, dz, sbb); - } - } - - /** - * Decorates a room in the maze. Makes assumptions that the room is 3x3 cells and thus 11x11 blocks large. - * @param rand - * @param world - * @param sbb - * - * @param dx - * @param dy - */ - void decorate3x3Room(World world, int x, int z, StructureBoundingBox sbb) - { - // make a new RNG for this room! - Random roomRNG = new Random(world.getSeed() ^ x + z); - - // all rooms should have 1 spawner - roomSpawner(world, roomRNG, x, z, 8, sbb); - - // and 1-2 chests - roomTreasure(world, roomRNG, x, z, 8, sbb); - if (roomRNG.nextInt(4) == 0) { - roomTreasure(world, roomRNG, x, z, 8, sbb); - } - } - - /** - * Place a spawner within diameter / 2 squares of the specified x and z coordinates - */ - private void roomSpawner(World world, Random rand, int x, int z, int diameter, StructureBoundingBox sbb) { - int rx = x + rand.nextInt(diameter) - (diameter / 2); - int rz = z + rand.nextInt(diameter) - (diameter / 2); - - String mobID; - - switch (rand.nextInt(3)) { - case 1 : - mobID = "Skeleton"; - break; - case 2 : - mobID = "Zombie"; - break; - case 0 : - default: - mobID = "Spider"; - } - - placeSpawnerAtCurrentPosition(world, rand, rx, FLOOR_LEVEL, rz, mobID, sbb); - } - - /** - * Place a treasure chest within diameter / 2 squares of the specified x and z coordinates - */ - private void roomTreasure(World world, Random rand, int x, int z, int diameter, StructureBoundingBox sbb) { - int rx = x + rand.nextInt(diameter) - (diameter / 2); - int rz = z + rand.nextInt(diameter) - (diameter / 2); - - placeTreasureAtCurrentPosition(world, rand, rx, FLOOR_LEVEL, rz, TFTreasure.labyrinth_room, sbb); - } -} diff --git a/src/main/java/twilightforest/structures/ComponentTFHollowHill.java b/src/main/java/twilightforest/structures/ComponentTFHollowHill.java index 7faed360c6..da046a42c5 100644 --- a/src/main/java/twilightforest/structures/ComponentTFHollowHill.java +++ b/src/main/java/twilightforest/structures/ComponentTFHollowHill.java @@ -1,80 +1,68 @@ package twilightforest.structures; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.monster.EntityCaveSpider; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.monster.EntitySilverfish; +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.entity.monster.EntitySpider; +import net.minecraft.entity.monster.EntityZombie; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; -import twilightforest.entity.TFCreatures; -import twilightforest.world.TFGenCaveStalactite; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.entity.EntityTFFireBeetle; +import twilightforest.entity.EntityTFPinchBeetle; +import twilightforest.entity.EntityTFRedcap; +import twilightforest.entity.EntityTFSlimeBeetle; +import twilightforest.entity.EntityTFSwarmSpider; +import twilightforest.entity.EntityTFWraith; +import twilightforest.world.feature.TFGenCaveStalactite; +import java.util.Random; -public class ComponentTFHollowHill extends StructureTFComponent { - +public class ComponentTFHollowHill extends StructureTFComponentOld { + int hillSize; int radius; public ComponentTFHollowHill() { super(); - // TODO Auto-generated constructor stub } + public ComponentTFHollowHill(TFFeature feature, World world, Random rand, int i, int size, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.SOUTH); - public ComponentTFHollowHill(World world, Random rand, int i, int size, int x, int y, int z) { - super(i); - - this.setCoordBaseMode(0); - // get the size of this hill? this.hillSize = size; radius = ((hillSize * 2 + 1) * 8) - 6; // can we determine the size here? - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -radius, -3, -radius, radius * 2, 10, radius * 2, 0); - } - - - /** - * Save to NBT - */ - @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("hillSize", this.hillSize); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -radius, -(3 + hillSize), -radius, radius * 2, radius / 2, radius * 2, EnumFacing.SOUTH); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.hillSize = par1NBTTagCompound.getInteger("hillSize"); - this.radius = ((hillSize * 2 + 1) * 8) - 6; - + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + tagCompound.setInteger("hillSize", this.hillSize); } - /** - * Add on any other components we need. In this case we add the maze below the hill - */ - @SuppressWarnings("rawtypes") @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { - -// // add a maze -// ComponentTFHillMaze maze = new ComponentTFHillMaze(1, boundingBox.minX + ((boundingBox.maxX - boundingBox.minX) / 2), boundingBox.minY - 20, boundingBox.minZ + ((boundingBox.maxZ - boundingBox.minZ) / 2), hillSize); -// list.add(maze); -// maze.buildComponent(this, list, random); - - + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.hillSize = tagCompound.getInteger("hillSize"); + this.radius = ((hillSize * 2 + 1) * 8) - 6; + } /** @@ -92,69 +80,62 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox int tc = tca[hillSize]; // number of treasure chests tca = {0, 2, 6, 12}; // fill in features - + // monster generators! - for (int i = 0; i < mg; i++) - { + for (int i = 0; i < mg; i++) { int[] dest = getCoordsInHill2D(rand); - String mobID = getMobID(rand); - - placeSpawnerAtCurrentPosition(world, rand, dest[0],rand.nextInt(4), dest[1], mobID, sbb); + ResourceLocation mobID = getMobID(rand); + + setSpawner(world, dest[0], rand.nextInt(4), dest[1], sbb, mobID); // placeMobSpawner(dest[0], hy + rand.nextInt(4), dest[1]); } // treasure chests!! - for (int i = 0; i < tc; i++) - { + for (int i = 0; i < tc; i++) { int[] dest = getCoordsInHill2D(rand); generateTreasureChest(world, dest[0], 0, dest[1], sbb); } // ore or glowing stalactites! (smaller, less plentiful) - for (int i = 0; i < sn; i++) - { + for (int i = 0; i < sn; i++) { int[] dest = getCoordsInHill2D(rand); generateOreStalactite(world, dest[0], 1, dest[1], sbb); } // stone stalactites! - for (int i = 0; i < sn; i++) - { + for (int i = 0; i < sn; i++) { int[] dest = getCoordsInHill2D(rand); - generateBlockStalactite(world, Blocks.stone, 1.0F, true, dest[0], 1, dest[1], sbb); + generateBlockStalactite(world, Blocks.STONE, 1.0F, true, dest[0], 1, dest[1], sbb); } // stone stalagmites! - for (int i = 0; i < sn; i++) - { + for (int i = 0; i < sn; i++) { int[] dest = getCoordsInHill2D(rand); - generateBlockStalactite(world, Blocks.stone, 0.9F, false, dest[0], 1, dest[1], sbb); + generateBlockStalactite(world, Blocks.STONE, 0.9F, false, dest[0], 1, dest[1], sbb); } - + // level 3 hills get 2 mid-air wraith spawners - if (hillSize == 3) - { -// int[] dest = getEmptyCoordsInHill(hy + 10, 20); + if (hillSize == 3) { +// int[] dest = getEmptysInHill(hy + 10, 20); // placeWraithSpawner(dest[0], hy + 10, dest[1]); -// dest = getEmptyCoordsInHill(hy + 10, 20); +// dest = getEmptysInHill(hy + 10, 20); // placeWraithSpawner(dest[0], hy + 10, dest[1]); } - return true; } - + /** * Make an RNG and attempt to use it to place a treasure chest */ protected void generateTreasureChest(World world, int x, int y, int z, StructureBoundingBox sbb) { // generate an RNG for this chest - //TODO: MOAR RANDOM! - Random chestRNG = new Random(world.getSeed() + x * z); - - // try placing it - placeTreasureAtCurrentPosition(world, chestRNG, x, y, z, this.hillSize == 3 ? TFTreasure.hill3 : (this.hillSize == 2 ? TFTreasure.hill2 : TFTreasure.hill1), sbb); - - // make something for it to stand on, if necessary - func_151554_b(world, Blocks.cobblestone, 0, x, y - 1, z, sbb); + //TODO: MOAR RANDOM! + Random chestRNG = new Random(world.getSeed() + x * z); + + // try placing it + placeTreasureAtCurrentPosition(world, chestRNG, x, y, z, this.hillSize == 3 ? TFTreasure.hill3 : (this.hillSize == 2 ? TFTreasure.hill2 : TFTreasure.hill1), sbb); + + // make something for it to stand on, if necessary + setBlockState(world, Blocks.COBBLESTONE.getDefaultState(), x, y - 1, z, sbb); } @@ -163,19 +144,19 @@ protected void generateTreasureChest(World world, int x, int y, int z, Structure */ protected void generateOreStalactite(World world, int x, int y, int z, StructureBoundingBox sbb) { // are the coordinates in our bounding box? - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) != Blocks.mob_spawner) - { - // generate an RNG for this stalactite - //TODO: MOAR RANDOM! - Random stalRNG = new Random(world.getSeed() + dx * dz); - - // make the actual stalactite + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() != Blocks.MOB_SPAWNER) { + // generate an RNG for this stalactite + //TODO: MOAR RANDOM! + Random stalRNG = new Random(world.getSeed() + dx * dz); + + // make the actual stalactite TFGenCaveStalactite stalag = TFGenCaveStalactite.makeRandomOreStalactite(stalRNG, hillSize); - stalag.generate(world, stalRNG, dx, dy, dz); - } + stalag.generate(world, stalRNG, pos); + } } /** @@ -183,187 +164,169 @@ protected void generateOreStalactite(World world, int x, int y, int z, Structure */ protected void generateBlockStalactite(World world, Block blockToGenerate, float length, boolean up, int x, int y, int z, StructureBoundingBox sbb) { // are the coordinates in our bounding box? - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) != Blocks.mob_spawner) - { - // generate an RNG for this stalactite - //TODO: MOAR RANDOM! - Random stalRNG = new Random(world.getSeed() + dx * dz); - - if (hillSize == 1) { - length *= 1.9F; - } - - // make the actual stalactite - (new TFGenCaveStalactite(blockToGenerate, length, up)).generate(world, stalRNG, dx, dy, dz); - } + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() != Blocks.MOB_SPAWNER) { + // generate an RNG for this stalactite + //TODO: MOAR RANDOM! + Random stalRNG = new Random(world.getSeed() + dx * dz); + + if (hillSize == 1) { + length *= 1.9F; + } + + // make the actual stalactite + (new TFGenCaveStalactite(blockToGenerate, length, up)).generate(world, stalRNG, pos); + } } /** - * * @param cx * @param cz * @return true if the coordinates would be inside the hill on the "floor" of the hill */ - boolean isInHill(int cx, int cz) - { + boolean isInHill(int cx, int cz) { int dx = radius - cx; int dz = radius - cz; int dist = (int) Math.sqrt(dx * dx + dz * dz); - + return dist < radius; } - + /** * @return true if the coordinates are inside the hill in 3D */ - boolean isInHill(int mapX, int mapY, int mapZ) - { + boolean isInHill(int mapX, int mapY, int mapZ) { int dx = boundingBox.minX + radius - mapX; int dy = (boundingBox.minY - mapY) * 2; // hill is half as high as it is wide, thus we just double y distance from center. I *think* that math works! int dz = boundingBox.minZ + radius - mapZ; int dist = dx * dx + dy * dy + dz * dz; return dist < radius * radius; } - - int[] getCoordsInHill2D(Random rand) - { + + int[] getCoordsInHill2D(Random rand) { return getCoordsInHill2D(rand, radius); } - + /** - * * @return a two element array containing some coordinates in the hill */ - int[] getCoordsInHill2D(Random rand, int rad) - { + int[] getCoordsInHill2D(Random rand, int rad) { int rx, rz; do { rx = rand.nextInt(2 * rad); rz = rand.nextInt(2 * rad); } while (!isInHill(rx, rz)); - + int[] coords = {rx, rz}; return coords; } - + /** * Gets the id of a mob appropriate to the current hill size. */ - protected String getMobID(Random rand) - { + protected ResourceLocation getMobID(Random rand) { return getMobID(rand, this.hillSize); } - + /** * Gets the id of a mob appropriate to the specified hill size. - * + * * @param level * @return */ - protected String getMobID(Random rand, int level) - { - if (level == 1) - { + protected ResourceLocation getMobID(Random rand, int level) { + if (level == 1) { return getLevel1Mob(rand); } - if (level == 2) - { + if (level == 2) { return getLevel2Mob(rand); } - if (level == 3) - { + if (level == 3) { return getLevel3Mob(rand); } - - /// aaah, default: spider! - return "Spider"; + + return EntityList.getKey(EntitySpider.class); } - + /** * Returns a mob string appropriate for a level 1 hill */ - public String getLevel1Mob(Random rand) - { - switch (rand.nextInt(10)) - { - case 0: - case 1: - case 2: - return TFCreatures.getSpawnerNameFor("Swarm Spider"); - case 3: - case 4: - case 5: - return "Spider"; - case 6: - case 7: - return "Zombie"; - case 8: - return "Silverfish"; - case 9: - return TFCreatures.getSpawnerNameFor("Redcap"); - default: - return TFCreatures.getSpawnerNameFor("Swarm Spider"); + public ResourceLocation getLevel1Mob(Random rand) { + switch (rand.nextInt(10)) { + case 0: + case 1: + case 2: + return EntityList.getKey(EntityTFSwarmSpider.class); + case 3: + case 4: + case 5: + return EntityList.getKey(EntitySpider.class); + case 6: + case 7: + return EntityList.getKey(EntityZombie.class); + case 8: + return EntityList.getKey(EntitySilverfish.class); + case 9: + return EntityList.getKey(EntityTFRedcap.class); + default: + return EntityList.getKey(EntityTFSwarmSpider.class); } } - + /** * Returns a mob string appropriate for a level 2 hill */ - public String getLevel2Mob(Random rand) - { - switch (rand.nextInt(10)) - { - case 0: - case 1: - case 2: - return TFCreatures.getSpawnerNameFor("Redcap"); - case 3: - case 4: - case 5: - return "Zombie"; - case 6: - case 7: - return "Skeleton"; - case 8: - return TFCreatures.getSpawnerNameFor("Swarm Spider"); - case 9: - return "CaveSpider"; - default: - return TFCreatures.getSpawnerNameFor("Redcap"); + public ResourceLocation getLevel2Mob(Random rand) { + switch (rand.nextInt(10)) { + case 0: + case 1: + case 2: + return EntityList.getKey(EntityTFRedcap.class); + case 3: + case 4: + case 5: + return EntityList.getKey(EntityZombie.class); + case 6: + case 7: + return EntityList.getKey(EntitySkeleton.class); + case 8: + return EntityList.getKey(EntityTFSwarmSpider.class); + case 9: + return EntityList.getKey(EntityCaveSpider.class); + default: + return EntityList.getKey(EntityTFRedcap.class); } } - + /** * Returns a mob string appropriate for a level 3 hill. The level 3 also has 2 mid-air wraith spawners. */ - public String getLevel3Mob(Random rand) - { - switch (rand.nextInt(11)) - { - case 0: - return TFCreatures.getSpawnerNameFor("Slime Beetle"); - case 1: - return TFCreatures.getSpawnerNameFor("Fire Beetle"); - case 2: - return TFCreatures.getSpawnerNameFor("Pinch Beetle"); - case 3: - case 4: - case 5: - return "Skeleton"; - case 6: - case 7: - case 8: - return "CaveSpider"; - case 9: - return "Creeper"; - case 10: - default: - return TFCreatures.getSpawnerNameFor("Twilight Wraith"); + public ResourceLocation getLevel3Mob(Random rand) { + switch (rand.nextInt(11)) { + case 0: + return EntityList.getKey(EntityTFSlimeBeetle.class); + case 1: + return EntityList.getKey(EntityTFFireBeetle.class); + case 2: + return EntityList.getKey(EntityTFPinchBeetle.class); + case 3: + case 4: + case 5: + return EntityList.getKey(EntitySkeleton.class); + case 6: + case 7: + case 8: + return EntityList.getKey(EntityCaveSpider.class); + case 9: + return EntityList.getKey(EntityCreeper.class); + case 10: + default: + return EntityList.getKey(EntityTFWraith.class); } } diff --git a/src/main/java/twilightforest/structures/ComponentTFHydraLair.java b/src/main/java/twilightforest/structures/ComponentTFHydraLair.java index 0ae1d7e91c..7b79881d83 100644 --- a/src/main/java/twilightforest/structures/ComponentTFHydraLair.java +++ b/src/main/java/twilightforest/structures/ComponentTFHydraLair.java @@ -1,37 +1,32 @@ package twilightforest.structures; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFBossSpawner; import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; + +import java.util.List; +import java.util.Random; public class ComponentTFHydraLair extends ComponentTFHollowHill { public ComponentTFHydraLair() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFHydraLair(World world, Random rand, int i, int x, int y, int z) { - super(world, rand, i, 2, x, y + 2, z); + public ComponentTFHydraLair(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, world, rand, i, 2, x, y + 2, z); } - /** - * Add on any other components we need. Override with noop since we don't need a maze - */ - @SuppressWarnings("rawtypes") @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { + public void buildComponent(StructureComponent structurecomponent, List list, Random random) { ; } - - /** - * Add in all the blocks we're adding. - */ + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { int stalacts = 64; @@ -39,26 +34,23 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox // fill in features // ore or glowing stalactites! (smaller, less plentiful) - for (int i = 0; i < stalacts; i++) - { + for (int i = 0; i < stalacts; i++) { int[] dest = getCoordsInHill2D(rand); generateOreStalactite(world, dest[0], 1, dest[1], sbb); } // stone stalactites! - for (int i = 0; i < stalacts; i++) - { + for (int i = 0; i < stalacts; i++) { int[] dest = getCoordsInHill2D(rand); - generateBlockStalactite(world, Blocks.stone, 1.0F, true, dest[0], 1, dest[1], sbb); + generateBlockStalactite(world, Blocks.STONE, 1.0F, true, dest[0], 1, dest[1], sbb); } // stone stalagmites! - for (int i = 0; i < stalags; i++) - { + for (int i = 0; i < stalags; i++) { int[] dest = getCoordsInHill2D(rand); - generateBlockStalactite(world, Blocks.stone, 0.9F, false, dest[0], 1, dest[1], sbb); + generateBlockStalactite(world, Blocks.STONE, 0.9F, false, dest[0], 1, dest[1], sbb); } // boss spawner seems important - placeBlockAtCurrentPosition(world, TFBlocks.bossSpawner, 2, 27, 3, 27, sbb); + setBlockState(world, TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.HYDRA), 27, 3, 27, sbb); return true; } diff --git a/src/main/java/twilightforest/structures/ComponentTFNagaCourtyard.java b/src/main/java/twilightforest/structures/ComponentTFNagaCourtyard.java deleted file mode 100644 index 648cc3568d..0000000000 --- a/src/main/java/twilightforest/structures/ComponentTFNagaCourtyard.java +++ /dev/null @@ -1,374 +0,0 @@ -package twilightforest.structures; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.block.TFBlocks; - - -public class ComponentTFNagaCourtyard extends StructureTFComponent { - - static int RADIUS = 46; - static int DIAMETER = 2 * RADIUS + 1; - - - public ComponentTFNagaCourtyard() { - super(); - // TODO Auto-generated constructor stub - } - - public ComponentTFNagaCourtyard(World world, Random rand, int i, int x, int y, int z) { - super(i); - - this.setCoordBaseMode(0); - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -RADIUS, -1, -RADIUS, RADIUS * 2, 10, RADIUS * 2, 0); - - } - - /** - * At the moment, this just draws the whole courtyard as a giant 93x93 block every time. We may break this up properly later. - * - * TODO: what I just said - */ - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // add a broken up courtyard - for (int fx = 0; fx <= DIAMETER; fx++) { - for (int fz = 0; fz <= DIAMETER; fz++) { - if (rand.nextInt(3) == 0) { - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, fx, 0, fz, sbb); - - // put some half slabs around - if (rand.nextInt(20) == 0) { - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, fx, 1, fz, sbb); - } - else { - placeBlockAtCurrentPosition(world, Blocks.air, 0, fx, 1, fz, sbb); // clear out grass or flowers - } - } - else { - placeBlockAtCurrentPosition(world, Blocks.grass, 0, fx, 0, fz, sbb); - } - } - } - - // fence! except not a fence, more of a wall - for (int fx = 0; fx <= DIAMETER; fx++) { - randomBrick(world, rand, fx, 0, DIAMETER, sbb); - randomBrick(world, rand, fx, 0, 0, sbb); - randomBrick(world, rand, fx, 1, DIAMETER, sbb); - randomBrick(world, rand, fx, 1, 0, sbb); - randomBrick(world, rand, fx, 2, DIAMETER, sbb); - randomBrick(world, rand, fx, 2, 0, sbb); - randomBrick(world, rand, fx, 3, DIAMETER, sbb); - randomBrick(world, rand, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, fx, 4, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, fx, 4, 0, sbb); - - - // make nagastone pattern! - switch (fx % 23) - { - case 2 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 7, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 7, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 11, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 11, fx, 1, 0, sbb); - break; - case 3 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 3, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 3, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 1, 0, sbb); - break; - case 4 : - case 8 : - case 16 : - case 20 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 1, 0, sbb); - break; - case 5 : - case 9 : - case 17 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 7, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 7, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 10, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 10, fx, 1, 0, sbb); - break; - case 6 : - case 10 : - case 14 : - case 18 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 3, 0, sbb); - break; - case 7 : - case 15 : - case 19 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 6, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 6, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 11, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 11, fx, 1, 0, sbb); - break; - case 11 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 6, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 6, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 1, 0, sbb); - break; - case 13 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 7, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 7, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 1, 0, sbb); - break; - case 21 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 2, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 2, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 12, fx, 1, 0, sbb); - break; - case 22 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 6, fx, 3, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 6, fx, 3, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, fx, 2, 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 10, fx, 1, DIAMETER, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 10, fx, 1, 0, sbb); - break; - } - -// if (fx % 2 == 0) { -// placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, fx, 4, DIAMETER, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, fx, 4, 0, sbb); -// } -// else -// { -// placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, fx, 4, 0, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, fx, 4, DIAMETER, sbb); -// } - } - - for (int fz = 0; fz <= DIAMETER; fz++) { - randomBrick(world, rand, DIAMETER, 0, fz, sbb); - randomBrick(world, rand, 0, 0, fz, sbb); - randomBrick(world, rand, DIAMETER, 1, fz, sbb); - randomBrick(world, rand, 0, 1, fz, sbb); - randomBrick(world, rand, DIAMETER, 2, fz, sbb); - randomBrick(world, rand, 0, 2, fz, sbb); - randomBrick(world, rand, DIAMETER, 3, fz, sbb); - randomBrick(world, rand, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, DIAMETER, 4, fz, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, 0, 4, fz, sbb); - - // make nagastone pattern! - switch (fz % 23) - { - case 2 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 5, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 5, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 9, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 9, 0, 1, fz, sbb); - break; - case 3 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 1, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 1, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, 0, 1, fz, sbb); - break; - case 4 : - case 8 : - case 16 : - case 20 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, 0, 1, fz, sbb); - break; - case 5 : - case 9 : - case 17 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 5, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 5, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 8, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 8, 0, 1, fz, sbb); - break; - case 6 : - case 10 : - case 14 : - case 18 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, 0, 3, fz, sbb); - break; - case 7 : - case 15 : - case 19 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 4, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 4, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 9, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 9, 0, 1, fz, sbb); - break; - case 11 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 4, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 4, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 1, fz, sbb); - break; - case 13 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 5, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 5, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 1, fz, sbb); - break; - case 21 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 0, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 0, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 13, 0, 1, fz, sbb); - break; - case 22 : - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 4, DIAMETER, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 4, 0, 3, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, DIAMETER, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 14, 0, 2, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 8, DIAMETER, 1, fz, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.nagastone, 8, 0, 1, fz, sbb); - break; - } - -// if (fz % 2 == 0) { -// placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, DIAMETER, 4, fz, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, 0, 4, fz, sbb); -// } -// else -// { -// placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, 0, 4, fz, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, DIAMETER, 4, fz, sbb); -// } - } - - // make a new rand here because we keep getting different results and this actually matters... or should the pillars be different StructureComponents? - Random pillarRand = new Random(world.getSeed() + this.boundingBox.minX * this.boundingBox.minZ); - - // pick a few spots and make pillars - for (int i = 0; i < 20; i++) { - int rx = 2 + pillarRand.nextInt(DIAMETER - 4); - int rz = 2 + pillarRand.nextInt(DIAMETER - 4); - - makePillar(world, pillarRand, rx, 1, rz, sbb); - } - - - - // naga spawner seems important - placeBlockAtCurrentPosition(world, TFBlocks.bossSpawner, 0, RADIUS + 1, 2, RADIUS + 1, sbb); - - return true; - } - - /** - * Make a pillar out of stone brick - */ - public boolean makePillar(World world, Random rand, int x, int y, int z, StructureBoundingBox sbb) { - int height = 8; - - // make the base - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x - 1, y + 0, z - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 0, y + 0, z - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 1, y + 0, z - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x - 1, y + 0, z + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 1, y + 0, z + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x - 1, y + 0, z + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 0, y + 0, z + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 1, y + 0, z + 1, sbb); - - // make the pillar - for (int i = 0; i < height; i++) { - randomBrick(world, rand, x, y + i, z, sbb); - if (i > 0 && rand.nextInt(2) == 0) { - // vines? - switch (rand.nextInt(4)) - { - case 0: - placeBlockAtCurrentPosition(world, Blocks.vine, 8, x - 1, y + i, z + 0, sbb); - break; - case 1: - placeBlockAtCurrentPosition(world, Blocks.vine, 2, x + 1, y + i, z + 0, sbb); - break; - case 2: - placeBlockAtCurrentPosition(world, Blocks.vine, 4, x + 0, y + i, z + 1, sbb); - break; - case 3: - placeBlockAtCurrentPosition(world, Blocks.vine, 1, x + 0, y + i, z - 1, sbb); - break; - } - } - else if (i > 0 && rand.nextInt(4) == 0) { - // fireflies! - switch (rand.nextInt(4)) - { - case 0: - placeBlockAtCurrentPosition(world, TFBlocks.firefly, 0, x - 1, y + i, z + 0, sbb); - break; - case 1: - placeBlockAtCurrentPosition(world, TFBlocks.firefly, 0, x + 1, y + i, z + 0, sbb); - break; - case 2: - placeBlockAtCurrentPosition(world, TFBlocks.firefly, 0, x + 0, y + i, z + 1, sbb); - break; - case 3: - placeBlockAtCurrentPosition(world, TFBlocks.firefly, 0, x + 0, y + i, z - 1, sbb); - break; - } - } - } - - // top? - if (height == 8) { - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x - 1, y + 8, z - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 0, y + 8, z - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 1, y + 8, z - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x - 1, y + 8, z + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, x + 0, y + 8, z + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 1, y + 8, z + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x - 1, y + 8, z + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 0, y + 8, z + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, x + 1, y + 8, z + 1, sbb); - - - } - - return true; - } - - /** - * Places a random stone brick at the specified location - */ - public void randomBrick(World world, Random rand, int x, int y, int z, StructureBoundingBox sbb) { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, rand.nextInt(3), x, y, z, sbb); - } - - -} diff --git a/src/main/java/twilightforest/structures/ComponentTFQuestGrove.java b/src/main/java/twilightforest/structures/ComponentTFQuestGrove.java index 29c944440e..b2b544fdeb 100644 --- a/src/main/java/twilightforest/structures/ComponentTFQuestGrove.java +++ b/src/main/java/twilightforest/structures/ComponentTFQuestGrove.java @@ -1,166 +1,175 @@ package twilightforest.structures; -import java.util.Random; - +import net.minecraft.block.BlockButton; +import net.minecraft.block.BlockDispenser; +import net.minecraft.block.BlockStoneBrick; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.entity.passive.EntityTFQuestRam; +import java.util.Random; + -public class ComponentTFQuestGrove extends StructureTFComponent { - - public static final int RADIUS = 13; - - protected boolean beastPlaced = false; - protected boolean dispenserPlaced = false; +public class ComponentTFQuestGrove extends StructureTFComponentOld { + private static final int RADIUS = 13; + private static final IBlockState MOSSY_STONEBRICK = Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.MOSSY); + private static final IBlockState CHISELED_STONEBRICK = Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CHISELED); + + protected boolean beastPlaced = false; + protected boolean dispenserPlaced = false; public ComponentTFQuestGrove() { super(); } - public ComponentTFQuestGrove(World world, Random rand, int i, int x, int y, int z) { - super(i); - - this.setCoordBaseMode(0); - + public ComponentTFQuestGrove(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, i); + + this.setCoordBaseMode(EnumFacing.SOUTH); + // the maze is 25 x 25 for now - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -RADIUS, 0, -RADIUS, RADIUS * 2, 10, RADIUS * 2, 0); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -RADIUS, 0, -RADIUS, RADIUS * 2, 10, RADIUS * 2, EnumFacing.SOUTH); } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - for (int i = 0; i < 4; i++) { + for (EnumFacing e : EnumFacing.HORIZONTALS) { // make the rings - makeWallSide(world, rand, i, sbb); + makeWallSide(world, rand, e, sbb); } - + // a small platform for (int x = 10; x < 17; x++) { for (int z = 10; z < 17; z++) { if (x == 10 || x == 16 || z == 10 || z == 16) { if (rand.nextInt(2) > 0) { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, x, -1, z, sbb); + setBlockState(world, MOSSY_STONEBRICK, x, -1, z, sbb); } - } - else if (x == 11 || x == 15 || z == 11 || z == 15) { + } else if (x == 11 || x == 15 || z == 11 || z == 15) { if (rand.nextInt(3) > 0) { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, x, -1, z, sbb); - } - } - else { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, x, -1, z, sbb); + setBlockState(world, MOSSY_STONEBRICK, x, -1, z, sbb); + } + } else { + setBlockState(world, MOSSY_STONEBRICK, x, -1, z, sbb); } } } - + // dispenser frame and button - placeBlockAtCurrentPosition(world, Blocks.stone_button, 4, 13, 5, 19, sbb); - - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, 12, 7, 20, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, 13, 7, 20, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, 14, 7, 20, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, 12, 7, 21, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, 13, 7, 21, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, 14, 7, 21, sbb); - - + setBlockState(world, Blocks.STONE_BUTTON.getDefaultState().withProperty(BlockButton.FACING, EnumFacing.SOUTH), 13, 5, 19, sbb); + + setBlockState(world, MOSSY_STONEBRICK, 12, 7, 20, sbb); + setBlockState(world, MOSSY_STONEBRICK, 13, 7, 20, sbb); + setBlockState(world, MOSSY_STONEBRICK, 14, 7, 20, sbb); + setBlockState(world, MOSSY_STONEBRICK, 12, 7, 21, sbb); + setBlockState(world, MOSSY_STONEBRICK, 13, 7, 21, sbb); + setBlockState(world, MOSSY_STONEBRICK, 14, 7, 21, sbb); + + // the dispenser if (!dispenserPlaced) { int bx = this.getXWithOffset(13, 20); int by = this.getYWithOffset(6); int bz = this.getZWithOffset(13, 20); - - if (sbb.isVecInside(bx, by, bz)) { + BlockPos pos = new BlockPos(bx, by, bz); + + if (sbb.isVecInside(pos)) { dispenserPlaced = true; - - world.setBlock(bx, by, bz, Blocks.dispenser, 2, 4); - TileEntityDispenser ted = (TileEntityDispenser)world.getTileEntity(bx, by, bz); - + + world.setBlockState(pos, Blocks.DISPENSER.getDefaultState().withProperty(BlockDispenser.FACING, EnumFacing.NORTH), 4); + TileEntityDispenser ted = (TileEntityDispenser) world.getTileEntity(pos); + // add 4 random wool blocks for (int i = 0; i < 4; i++) { - ted.setInventorySlotContents(i, new ItemStack(Blocks.wool, 1, rand.nextInt(16))); + ted.setInventorySlotContents(i, new ItemStack(Blocks.WOOL, 1, rand.nextInt(16))); } - + } } - + // the quest beast! if (!beastPlaced) { int bx = this.getXWithOffset(13, 13); int by = this.getYWithOffset(0); int bz = this.getZWithOffset(13, 13); - - if (sbb.isVecInside(bx, by, bz)) { + BlockPos pos = new BlockPos(bx, by, bz); + + if (sbb.isVecInside(pos)) { beastPlaced = true; - + EntityTFQuestRam ram = new EntityTFQuestRam(world); ram.setPosition(bx, by, bz); - ram.setHomeArea(bx, by, bz, 13); - - world.spawnEntityInWorld(ram); + ram.setHomePosAndDistance(pos, 13); + ram.onInitialSpawn(world.getDifficultyForLocation(pos), null); + + world.spawnEntity(ram); } } - + return true; } - private void makeWallSide(World world, Random rand, int direction, StructureBoundingBox sbb) { - int temp = this.getCoordBaseMode(); + private void makeWallSide(World world, Random rand, EnumFacing direction, StructureBoundingBox sbb) { + EnumFacing temp = this.getCoordBaseMode(); this.setCoordBaseMode(direction); - + // arches placeOuterArch(world, 3, -1, sbb); placeOuterArch(world, 11, -1, sbb); placeOuterArch(world, 19, -1, sbb); - + // connecting thingers - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 0, 0, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 0, 1, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 0, 2, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 0, 0, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 0, 1, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 0, 2, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 0, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 1, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 2, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 0, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 1, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 2, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 8, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 9, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 10, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 8, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 9, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 10, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 16, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 17, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 18, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 16, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 17, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 18, 3, 0, sbb); + + setBlockState(world, CHISELED_STONEBRICK, 24, 3, 0, sbb); + setBlockState(world, CHISELED_STONEBRICK, 25, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 24, 3, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 25, 3, 0, sbb); - // inner arch for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { for (int z = 0; z < 2; z++) { if (x == 0 || x == 1 || x == 7 || x == 8 || y == 0 || y == 1 || y == 7 || y == 8) { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, x + 9, y - 2, z + 5, sbb); + setBlockState(world, MOSSY_STONEBRICK, x + 9, y - 2, z + 5, sbb); } } } } - + // connecting thingers - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 6, 0, 6, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 6, 1, 6, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 6, 2, 6, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 6, 3, 6, sbb); - - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 6, 4, 6, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 7, 4, 6, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 8, 4, 6, sbb); - - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 18, 4, 6, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 3, 19, 4, 6, sbb); - + setBlockState(world, CHISELED_STONEBRICK, 6, 0, 6, sbb); + setBlockState(world, CHISELED_STONEBRICK, 6, 1, 6, sbb); + setBlockState(world, CHISELED_STONEBRICK, 6, 2, 6, sbb); + setBlockState(world, CHISELED_STONEBRICK, 6, 3, 6, sbb); + + setBlockState(world, CHISELED_STONEBRICK, 6, 4, 6, sbb); + setBlockState(world, CHISELED_STONEBRICK, 7, 4, 6, sbb); + setBlockState(world, CHISELED_STONEBRICK, 8, 4, 6, sbb); + + setBlockState(world, CHISELED_STONEBRICK, 18, 4, 6, sbb); + setBlockState(world, CHISELED_STONEBRICK, 19, 4, 6, sbb); + this.setCoordBaseMode(temp); } @@ -168,7 +177,7 @@ private void placeOuterArch(World world, int ox, int oy, StructureBoundingBox sb for (int x = 0; x < 5; x++) { for (int y = 0; y < 6; y++) { if (x == 0 || x == 4 || y == 0 || y == 5) { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 1, x + ox, y + oy, 0, sbb); + setBlockState(world, MOSSY_STONEBRICK, x + ox, y + oy, 0, sbb); } } } diff --git a/src/main/java/twilightforest/structures/ComponentTFYetiCave.java b/src/main/java/twilightforest/structures/ComponentTFYetiCave.java index 2d9a8ad8b6..60dc423ee3 100644 --- a/src/main/java/twilightforest/structures/ComponentTFYetiCave.java +++ b/src/main/java/twilightforest/structures/ComponentTFYetiCave.java @@ -1,46 +1,48 @@ package twilightforest.structures; -import java.util.Random; - +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.entity.boss.EntityTFYetiAlpha; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; import twilightforest.world.TFWorld; -public class ComponentTFYetiCave extends ComponentTFHollowHill { +import java.util.Random; - private boolean yetiPlaced; +public class ComponentTFYetiCave extends ComponentTFHollowHill { public ComponentTFYetiCave() { super(); } - public ComponentTFYetiCave(World world, Random rand, int i, int x, int y, int z) { - super(world, rand, i, 2, x, y + 2, z); + public ComponentTFYetiCave(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, world, rand, i, 2, x, y + 2, z); } - + /** - * * @param cx * @param cz * @return true if the coordinates would be inside the hill on the "floor" of the hill */ - boolean isInHill(int cx, int cz) - { + @Override + boolean isInHill(int cx, int cz) { // yeti cave is square return cx < this.radius * 2 && cx > 0 && cz < this.radius * 2 && cz > 0; } - + /** * @return true if the coordinates are inside the hill in 3D */ - boolean isInHill(int mapX, int mapY, int mapZ) - { + @Override + boolean isInHill(int mapX, int mapY, int mapZ) { // yeti cave is square and 16 blocks tall return mapX < this.radius * 2 && mapX > 0 && mapZ < this.radius * 2 && mapZ > 0 && mapY > TFWorld.SEALEVEL && mapY < TFWorld.SEALEVEL + 20; } - + /** * Add in all the blocks we're adding. */ @@ -50,7 +52,7 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox int sn = 128; // fill in features - + // // ore or glowing stalactites! (smaller, less plentiful) // for (int i = 0; i < sn; i++) // { @@ -58,42 +60,25 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox // generateOreStalactite(world, dest[0], 1, dest[1], sbb); // } // stone stalactites! - for (int i = 0; i < sn; i++) - { + for (int i = 0; i < sn; i++) { int[] dest = getCoordsInHill2D(rand); - generateBlockStalactite(world, Blocks.stone, 1.0F, true, dest[0], 1, dest[1], sbb); - } + generateBlockStalactite(world, Blocks.STONE, 1.0F, true, dest[0], 1, dest[1], sbb); + } // ice stalactites! - for (int i = 0; i < sn; i++) - { + for (int i = 0; i < sn; i++) { int[] dest = getCoordsInHill2D(rand); - generateBlockStalactite(world, Blocks.ice, 1.0F, true, dest[0], 1, dest[1], sbb); + generateBlockStalactite(world, Blocks.ICE, 1.0F, true, dest[0], 1, dest[1], sbb); } // packed ice stalactites! - for (int i = 0; i < sn; i++) - { + for (int i = 0; i < sn; i++) { int[] dest = getCoordsInHill2D(rand); - generateBlockStalactite(world, Blocks.packed_ice, 0.9F, true, dest[0], 1, dest[1], sbb); + generateBlockStalactite(world, Blocks.PACKED_ICE, 0.9F, true, dest[0], 1, dest[1], sbb); } - + // spawn alpha yeti - if (!yetiPlaced) { - int bx = this.getXWithOffset(this.radius, this.radius); - int by = this.getYWithOffset(0); - int bz = this.getZWithOffset(this.radius, this.radius); - - if (sbb.isVecInside(bx, by, bz)) { - yetiPlaced = true; - - EntityTFYetiAlpha yeti = new EntityTFYetiAlpha(world); - yeti.setPosition(bx, by, bz); - yeti.setHomeArea(bx, by, bz, 30); - - world.spawnEntityInWorld(yeti); - } - } + final IBlockState yetiSpawner = TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.ALPHA_YETI); + setBlockStateRotated(world, yetiSpawner, radius, 1, radius, Rotation.NONE, sbb); - return true; } diff --git a/src/main/java/twilightforest/structures/MossyCobbleTemplateProcessor.java b/src/main/java/twilightforest/structures/MossyCobbleTemplateProcessor.java new file mode 100644 index 0000000000..526184ac53 --- /dev/null +++ b/src/main/java/twilightforest/structures/MossyCobbleTemplateProcessor.java @@ -0,0 +1,38 @@ +package twilightforest.structures; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockWall; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.template.PlacementSettings; +import net.minecraft.world.gen.structure.template.Template; + +import javax.annotation.Nullable; + +public class MossyCobbleTemplateProcessor extends RandomizedTemplateProcessor { + + public MossyCobbleTemplateProcessor(BlockPos pos, PlacementSettings settings) { + super(pos, settings); + } + + @Nullable + @Override + public Template.BlockInfo processBlock(World worldIn, BlockPos pos, Template.BlockInfo blockInfo) { + if (shouldPlaceBlock()) { + IBlockState state = blockInfo.blockState; + Block block = state.getBlock(); + + if (block == Blocks.COBBLESTONE) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, Blocks.MOSSY_COBBLESTONE.getDefaultState(), null); + + if (block == Blocks.COBBLESTONE_WALL) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, state.withProperty(BlockWall.VARIANT, BlockWall.EnumType.MOSSY), null); + + return blockInfo; + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/Porting Notes.txt b/src/main/java/twilightforest/structures/Porting Notes.txt new file mode 100644 index 0000000000..3e313a91b4 --- /dev/null +++ b/src/main/java/twilightforest/structures/Porting Notes.txt @@ -0,0 +1,10 @@ +Structure Directions +0 SOUTH +1 WEST +2 NORTH +3 EAST + +Slab Metadata + +Stair Metadata + diff --git a/src/main/java/twilightforest/structures/RandomizedTemplateProcessor.java b/src/main/java/twilightforest/structures/RandomizedTemplateProcessor.java new file mode 100644 index 0000000000..bb8d49c9d1 --- /dev/null +++ b/src/main/java/twilightforest/structures/RandomizedTemplateProcessor.java @@ -0,0 +1,43 @@ +package twilightforest.structures; + +import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.structure.template.ITemplateProcessor; +import net.minecraft.world.gen.structure.template.PlacementSettings; + +import java.util.Random; + +public abstract class RandomizedTemplateProcessor implements ITemplateProcessor { + + protected final Random random; + private final float integrity; + + public RandomizedTemplateProcessor(BlockPos pos, PlacementSettings settings) { + this.integrity = settings.getIntegrity(); + this.random = settings.getRandom(pos); + } + + protected boolean shouldPlaceBlock() { + return integrity >= 1.0F || random.nextFloat() > integrity; + } + + protected Block randomBlock(Block... blocks) { + return blocks[random.nextInt(blocks.length)]; + } + + protected static > IBlockState translateState(IBlockState stateIn, Block blockOut, IProperty property) { + return blockOut.getDefaultState().withProperty(property, stateIn.getValue(property)); + } + + protected static IBlockState translateState(IBlockState stateIn, Block blockOut, IProperty... properties) { + IBlockState stateOut = blockOut.getDefaultState(); + for (IProperty property : properties) stateOut = copyValue(stateIn, stateOut, property); + return stateOut; + } + + private static > IBlockState copyValue(IBlockState from, IBlockState to, IProperty property) { + return to.withProperty(property, from.getValue(property)); + } +} diff --git a/src/main/java/twilightforest/structures/StructureTFCastleBlocks.java b/src/main/java/twilightforest/structures/StructureTFCastleBlocks.java deleted file mode 100644 index 64670d0a9e..0000000000 --- a/src/main/java/twilightforest/structures/StructureTFCastleBlocks.java +++ /dev/null @@ -1,38 +0,0 @@ -package twilightforest.structures; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.block.TFBlocks; - -public class StructureTFCastleBlocks extends StructureComponent.BlockSelector { - - @Override - public void selectBlocks(Random par1Random, int x, int y, int z, boolean isWall) { - if (!isWall) - { - this.field_151562_a = Blocks.air; - this.selectedBlockMetaData = 0; - } - else - { - this.field_151562_a = TFBlocks.castleBlock; - float randFloat = par1Random.nextFloat(); - - if (randFloat < 0.1F) - { - this.selectedBlockMetaData = 1; - } - else if (randFloat < 0.2F) - { - this.selectedBlockMetaData = 2; - } - else - { - this.selectedBlockMetaData = 0; - } - } - } - -} diff --git a/src/main/java/twilightforest/structures/StructureTFComponent.java b/src/main/java/twilightforest/structures/StructureTFComponent.java index 5e2b198f00..6b30e1d0f4 100644 --- a/src/main/java/twilightforest/structures/StructureTFComponent.java +++ b/src/main/java/twilightforest/structures/StructureTFComponent.java @@ -1,650 +1,114 @@ package twilightforest.structures; -import java.util.Iterator; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; +import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.entity.passive.EntitySheep; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntityMobSpawner; -import net.minecraft.tileentity.TileEntitySign; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.EnumSkyBlock; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; public abstract class StructureTFComponent extends StructureComponent { - private static final StructureTFStrongholdStones strongholdStones = new StructureTFStrongholdStones(); - - public StructureTFDecorator deco = null; - public int spawnListIndex = 0; + public StructureTFDecorator deco = null; + public int spawnListIndex = 0; + protected TFFeature feature = TFFeature.NOTHING; - public StructureTFComponent() {} - - public StructureTFComponent(int i) { - super(i); + public StructureTFComponent() { + this.rotation = Rotation.NONE; } - /** - * Save to NBT - */ - @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) - { - par1NBTTagCompound.setInteger("si", this.spawnListIndex); - par1NBTTagCompound.setString("deco", StructureTFDecorator.getDecoString(this.deco)); - } - - /** - * Load from NBT - */ - @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) - { - this.spawnListIndex = par1NBTTagCompound.getInteger("si"); - this.deco = StructureTFDecorator.getDecoFor(par1NBTTagCompound.getString("deco")); - } - - public static StructureBoundingBox getComponentToAddBoundingBox(int x, int y, int z, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, int dir) - { - switch(dir) - { - default: - return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); - - case 0: // '\0' - return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); - - case 1: // '\001' - return new StructureBoundingBox(x - maxZ + minZ, y + minY, z + minX, x + minZ, y + maxY + minY, z + maxX + minX); - - case 2: // '\002' - return new StructureBoundingBox(x - maxX - minX, y + minY, z - maxZ - minZ, x - minX, y + maxY + minY, z - minZ); - - case 3: // '\003' - return new StructureBoundingBox(x + minZ, y + minY, z - maxX, x + maxZ + minZ, y + maxY + minY, z + minX); - } - } - - /** - * Fixed a bug with direction 1 and -z values, but I'm not sure if it'll break other things - */ - public static StructureBoundingBox getComponentToAddBoundingBox2(int x, int y, int z, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, int dir) - { - switch(dir) - { - default: - return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); - - case 0: // '\0' - return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); - - case 1: // '\001' - return new StructureBoundingBox(x - maxZ - minZ, y + minY, z + minX, x - minZ, y + maxY + minY, z + maxX + minX); - - case 2: // '\002' - return new StructureBoundingBox(x - maxX - minX, y + minY, z - maxZ - minZ, x - minX, y + maxY + minY, z - minZ); - - case 3: // '\003' - return new StructureBoundingBox(x + minZ, y + minY, z - maxX, x + maxZ + minZ, y + maxY + minY, z - minX); - } - } - - /** - * Place a monster spawner at the specified coordinates - * - * @param monsterID - */ - protected TileEntityMobSpawner placeSpawnerAtCurrentPosition(World world, Random rand, int x, int y, int z, String monsterID, StructureBoundingBox sbb) - { - TileEntityMobSpawner tileEntitySpawner = null; - - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) != Blocks.mob_spawner) - { - world.setBlock(dx, dy, dz, Blocks.mob_spawner, 0, 2); - tileEntitySpawner = (TileEntityMobSpawner)world.getTileEntity(dx, dy, dz); - if(tileEntitySpawner != null) - { - tileEntitySpawner.func_145881_a().setEntityName(monsterID); - } - } - - return tileEntitySpawner; - } - - /** - * Place a monster spawner at the specified coordinates, as if rotated - * - * @param monsterID - */ - protected TileEntityMobSpawner placeSpawnerRotated(World world, int x, int y, int z, int rotation, String monsterID, StructureBoundingBox sbb) - { - TileEntityMobSpawner tileEntitySpawner = null; - - int dx = getXWithOffsetAsIfRotated(x, z, rotation); - int dy = getYWithOffset(y); - int dz = getZWithOffsetAsIfRotated(x, z, rotation); - if(sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) != Blocks.mob_spawner) - { - world.setBlock(dx, dy, dz, Blocks.mob_spawner, 0, 2); - tileEntitySpawner = (TileEntityMobSpawner)world.getTileEntity(dx, dy, dz); - if(tileEntitySpawner != null) - { - tileEntitySpawner.func_145881_a().setEntityName(monsterID); - } - } - - return tileEntitySpawner; - } - - - /** - * Place a treasure chest at the specified coordinates - * - * @param treasureType - */ - protected void placeTreasureAtCurrentPosition(World world, Random rand, int x, int y, int z, TFTreasure treasureType, StructureBoundingBox sbb) - { - this.placeTreasureAtCurrentPosition(world, rand, x, y, z, treasureType, false, sbb); - } - - /** - * Place a treasure chest at the specified coordinates - * - * @param treasureType - */ - protected void placeTreasureAtCurrentPosition(World world, Random rand, int x, int y, int z, TFTreasure treasureType, boolean trapped, StructureBoundingBox sbb) - { - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) != Blocks.chest) - { - treasureType.generate(world, rand, dx, dy, dz, trapped ? Blocks.trapped_chest : Blocks.chest); - } - } - - /** - * Place a treasure chest at the specified coordinates - * - * @param treasureType - */ - protected void placeTreasureRotated(World world, int x, int y, int z, int rotation, TFTreasure treasureType, StructureBoundingBox sbb) - { - this.placeTreasureRotated(world, x, y, z, rotation, treasureType, false, sbb); - } - - /** - * Place a treasure chest at the specified coordinates - * - * @param treasureType - */ - protected void placeTreasureRotated(World world, int x, int y, int z, int rotation, TFTreasure treasureType, boolean trapped, StructureBoundingBox sbb) - { - int dx = getXWithOffsetAsIfRotated(x, z, rotation); - int dy = getYWithOffset(y); - int dz = getZWithOffsetAsIfRotated(x, z, rotation); - if(sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) != Blocks.chest) - { - treasureType.generate(world, null, dx, dy, dz, trapped ? Blocks.trapped_chest : Blocks.chest); - } - } - - protected void placeSignAtCurrentPosition(World world, int x, int y, int z, String string0, String string1, StructureBoundingBox sbb) { - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if (sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) != Blocks.standing_sign) - { - world.setBlock(dx, dy, dz, Blocks.standing_sign, (this.coordBaseMode * 2), 2); - - TileEntitySign teSign = (TileEntitySign)world.getTileEntity(dx, dy, dz); - if (teSign != null) - { - teSign.signText[1] = string0; - teSign.signText[2] = string1; - } - } + public StructureTFComponent(int i) { + super(i); + this.rotation = Rotation.NONE; } - -// -// public boolean makeTowerWing2(List list, Random rand, int index, int x, int y, int z, int size, int height, int direction) { -// -// ComponentTFTowerWing wing = new ComponentTFTowerWing(index, x, y, z, size, height, direction); -// // check to see if it intersects something already there -// StructureComponent intersect = StructureComponent.getIntersectingStructureComponent(list, wing.boundingBox); -// if (intersect == null || intersect == this) { -// list.add(wing); -// wing.buildComponent(this, list, rand); -// return true; -// } else { -// System.out.println("Planned wing intersects with " + intersect); -// return false; -// } -// } - - /** - * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. - */ - protected int[] offsetTowerCoords(int x, int y, int z, int towerSize, int direction) { - - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - - if (direction == 0) { - return new int[] {dx + 1, dy - 1, dz - towerSize / 2}; - } - else if (direction == 1) { - return new int[] {dx + towerSize / 2, dy - 1, dz + 1}; - } - else if (direction == 2) { - return new int[] {dx - 1, dy - 1, dz + towerSize / 2}; - } - else if (direction == 3) { - return new int[] {dx - towerSize / 2, dy - 1, dz - 1}; - } - - - // ugh? - return new int[] {x, y, z}; + public StructureTFComponent(TFFeature feature, int i) { + super(i); + this.feature = feature; + this.rotation = Rotation.NONE; } - /** - * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. - */ - protected ChunkCoordinates offsetTowerCCoords(int x, int y, int z, int towerSize, int direction) { - - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - - if (direction == 0) { - return new ChunkCoordinates(dx + 1, dy - 1, dz - towerSize / 2); - } else if (direction == 1) { - return new ChunkCoordinates(dx + towerSize / 2, dy - 1, dz + 1); - } else if (direction == 2) { - return new ChunkCoordinates(dx - 1, dy - 1, dz + towerSize / 2); - } else if (direction == 3) { - return new ChunkCoordinates(dx - towerSize / 2, dy - 1, dz - 1); - } - - - // ugh? - return new ChunkCoordinates(x, y, z); + public TFFeature getFeatureType() { + return feature; } - - public int[] getOffsetAsIfRotated(int src[], int rotation) { - int temp = this.getCoordBaseMode(); - int[] dest = new int[3]; - this.setCoordBaseMode(rotation); - - dest[0] = getXWithOffset(src[0], src[2]); - dest[1] = getYWithOffset(src[1]); - dest[2] = getZWithOffset(src[0], src[2]); - - this.setCoordBaseMode(temp); - return dest; + protected static boolean shouldDebug() { + return false; } + @SuppressWarnings({"SameParameterValue", "unused"}) + protected void setDebugCorners(World world) { + if (rotation == null) rotation = Rotation.NONE; - protected int getXWithOffset(int x, int z) - { - switch(getCoordBaseMode()) - { - case 0: // '\0' - return boundingBox.minX + x; - case 1: // '\001' - return boundingBox.maxX - z; - case 2: // '\002' - return boundingBox.maxX - x; - case 3: // '\003' - return boundingBox.minX + z; - } - return x; - } - - protected int getYWithOffset(int par1) - { - return super.getYWithOffset(par1); - } - - protected int getZWithOffset(int x, int z) - { - switch(getCoordBaseMode()) - { - case 0: // '\0' - return boundingBox.minZ + z; - case 1: // '\001' - return boundingBox.minZ + x; - case 2: // '\002' - return boundingBox.maxZ - z; - case 3: // '\003' - return boundingBox.maxZ - x; - } - return z; - } - - /** - * Pretend as though the structure is rotated beyond what it already is - */ - protected int getXWithOffsetAsIfRotated(int x, int z, int rotation) - { - if (coordBaseMode < 0) - { - return x; + if (shouldDebug() ) { // && rotation!= Rotation.NONE) { + int i = rotation.ordinal() * 4; + world.setBlockState(new BlockPos(this.getBoundingBox().minX, this.getBoundingBox().maxY + i , this.getBoundingBox().minZ), Blocks.WOOL.getStateFromMeta(i)); + world.setBlockState(new BlockPos(this.getBoundingBox().maxX, this.getBoundingBox().maxY + i + 1, this.getBoundingBox().minZ), Blocks.WOOL.getStateFromMeta(1 + i)); + world.setBlockState(new BlockPos(this.getBoundingBox().minX, this.getBoundingBox().maxY + i + 2, this.getBoundingBox().maxZ), Blocks.WOOL.getStateFromMeta(2 + i)); + world.setBlockState(new BlockPos(this.getBoundingBox().maxX, this.getBoundingBox().maxY + i + 3, this.getBoundingBox().maxZ), Blocks.WOOL.getStateFromMeta(3 + i)); } - - switch((coordBaseMode + rotation) % 4) - { - case 0: - return boundingBox.minX + x; - case 1: - return boundingBox.maxX - z; - case 2: - return boundingBox.maxX - x; - case 3: - return boundingBox.minX + z; - } - return x; } - protected int getZWithOffsetAsIfRotated(int x, int z, int rotation) - { - if (coordBaseMode < 0) - { - return x; - } - else - { - switch((coordBaseMode + rotation) % 4) - { - case 0: - return boundingBox.minZ + z; - case 1: - return boundingBox.minZ + x; - case 2: - return boundingBox.maxZ - z; - case 3: - return boundingBox.maxZ - x; + @SuppressWarnings({"SameParameterValue", "unused"}) + protected void setDebugEntity(World world, int x, int y, int z, StructureBoundingBox sbb, String s) { + setInvisibleTextEntity(world, x, y, z, sbb, s, shouldDebug(), 0f); + } + + @SuppressWarnings({"SameParameterValue", "unused"}) + protected void setInvisibleTextEntity(World world, int x, int y, int z, StructureBoundingBox sbb, String s, boolean forcePlace, float additionalYOffset) { + if (forcePlace) { + final BlockPos pos = new BlockPos(this.getXWithOffset(x, z), this.getYWithOffset(y), this.getZWithOffset(x, z)); + + if (sbb.isVecInside(pos)) { + final EntityArmorStand armorStand = new EntityArmorStand(world); + armorStand.setCustomNameTag(s); + armorStand.setLocationAndAngles(pos.getX() + 0.5, pos.getY() + additionalYOffset, pos.getZ() + 0.5, 0, 0); + armorStand.setEntityInvulnerable(true); + armorStand.setInvisible(true); + armorStand.setAlwaysRenderNameTag(true); + armorStand.setSilent(true); + armorStand.setNoGravity(true); + // set marker flag + armorStand.getDataManager().set(EntityArmorStand.STATUS, (byte) (armorStand.getDataManager().get(EntityArmorStand.STATUS) | 16)); + world.spawnEntity(armorStand); } - return z; } - } - - public int getCoordBaseMode() { - return coordBaseMode; - } - - public void setCoordBaseMode(int coordBaseMode) { - this.coordBaseMode = coordBaseMode; } - - protected Block getBlockAtCurrentPosition(World par1World, int par2, int par3, int par4, StructureBoundingBox par5StructureBoundingBox) { - return super.getBlockAtCurrentPosition(par1World, par2, par3, par4, par5StructureBoundingBox); - } - - /** - * current Position depends on currently set Coordinates mode, is computed here - */ - protected void placeBlockAtCurrentPosition(World par1World, Block par2, int par3, int par4, int par5, int par6, StructureBoundingBox par7StructureBoundingBox) { - super.placeBlockAtCurrentPosition(par1World, par2, par3, par4, par5, par6, par7StructureBoundingBox); - } - - /** - * Place a block as though the entire structure were rotated the specified amount beyond what it already is - */ - protected void placeBlockRotated(World world, Block blockID, int meta, int x, int y, int z, int rotation, StructureBoundingBox sbb) - { - int dx = this.getXWithOffsetAsIfRotated(x, z, rotation); - int dy = this.getYWithOffset(y); - int dz = this.getZWithOffsetAsIfRotated(x, z, rotation); - if (sbb.isVecInside(dx, dy, dz)) - { - world.setBlock(dx, dy, dz, blockID, meta, 2); - } - } - - /** - * Get a block ID as though the entire structure were rotated the specified amount beyond what it already is - */ - protected Block getBlockIDRotated(World world, int x, int y, int z, int rotation, StructureBoundingBox sbb) - { - int dx = this.getXWithOffsetAsIfRotated(x, z, rotation); - int dy = this.getYWithOffset(y); - int dz = this.getZWithOffsetAsIfRotated(x, z, rotation); - - if (sbb.isVecInside(dx, dy, dz)) - { - return world.getBlock(dx, dy, dz); - } - else - { - return Blocks.air; - } - } - - /** - * Fill with blocks as though rotated - */ - protected void fillBlocksRotated(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block blockID, int meta, int rotation) - { - for (int dx = minY; dx <= maxY; ++dx) - { - for (int dy = minX; dy <= maxX; ++dy) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - this.placeBlockRotated(world, blockID, meta, dy, dx, dz, rotation, sbb); - } - } - } - } - - /** - * Fill with blocks as though rotated - */ - protected void randomlyFillBlocksRotated(World world, StructureBoundingBox sbb, Random rand, float chance, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Block blockID, int meta, Block blockID2, int meta2, int rotation) - { - for (int dx = minY; dx <= maxY; ++dx) - { - for (int dy = minX; dy <= maxX; ++dy) - { - for (int dz = minZ; dz <= maxZ; ++dz) - { - if (rand.nextFloat() < chance) { - this.placeBlockRotated(world, blockID, meta, dy, dx, dz, rotation, sbb); - } else { - this.placeBlockRotated(world, blockID2, meta2, dy, dx, dz, rotation, sbb); - } - } - } - } - } - - - public void fillToGroundRotated(World world, Block stonebrick, int meta, int x, int y, int z, int rotation, StructureBoundingBox sbb) { - int dx = this.getXWithOffsetAsIfRotated(x, z, rotation); - int dy = this.getYWithOffset(y); - int dz = this.getZWithOffsetAsIfRotated(x, z, rotation); - - if (sbb.isVecInside(dx, dy, dz)) { - while ((world.isAirBlock(dx, dy, dz) || world.getBlock(dx, dy, dz).getMaterial().isLiquid()) && dy > 1) { - world.setBlock(dx, dy, dz, stonebrick, meta, 2); - --dy; - } - } - } - - - /** - * Fill with blocks as though rotated - */ - protected void fillAirRotated(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, int rotation) - { - this.fillBlocksRotated(world, sbb, minX, minY, minZ, maxX, maxY, maxZ, Blocks.air, 0, rotation); - } - - public static StructureComponent.BlockSelector getStrongholdStones() { - return strongholdStones; - } - - - - /** - * Gets the metadata necessary to make stairs facing the proper direction. - * - * @param dir - * @return - */ - protected int getStairMeta(int dir) { - switch ((this.getCoordBaseMode() + dir) % 4) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 1; - case 3: - return 3; - default: - return -1; // this is impossible + @SuppressWarnings({"SameParameterValue", "unused"}) + protected void setDebugEntity(World world, BlockPos blockpos, String s) { + if (shouldDebug()) { + final EntitySheep sheep = new EntitySheep(world); + sheep.setCustomNameTag(s); + sheep.setNoAI(true); + sheep.setLocationAndAngles(blockpos.getX() + 0.5, blockpos.getY() + 10, blockpos.getZ() + 0.5, 0, 0); + sheep.setEntityInvulnerable(true); + sheep.setInvisible(true); + sheep.setAlwaysRenderNameTag(true); + sheep.setSilent(true); + sheep.setNoGravity(true); + world.spawnEntity(sheep); } } - - /** - * Gets the metadata necessary to stick the ladder on the specified wall. - * - * @param ladderDir - * @return - */ - protected int getLadderMeta(int ladderDir) { - // ladder data values are... dumb. - switch ((this.getCoordBaseMode() + ladderDir) % 4) { - case 0: - return 4; - case 1: - return 2; - case 2: - return 5; - case 3: - return 3; - default: - return -1; // this is impossible - } - } - - /** - * Gets the metadata necessary to stick the ladder on the specified wall. - */ - protected int getLadderMeta(int ladderDir, int rotation) { - return getLadderMeta(ladderDir + rotation); - } - - /** - * Nullify all the sky light in this component bounding box - */ - public void nullifySkyLightForBoundingBox(World world) { - this.nullifySkyLight(world, boundingBox.minX - 1, boundingBox.minY - 1, boundingBox.minZ - 1, boundingBox.maxX + 1, boundingBox.maxY + 1, boundingBox.maxZ + 1); - } - /** - * Nullify all the sky light at the specified positions, using local coordinates - */ - public void nullifySkyLightAtCurrentPosition(World world, int sx, int sy, int sz, int dx, int dy, int dz) - { - // resolve all variables to their actual in-world positions - nullifySkyLight(world, getXWithOffset(sx, sz), getYWithOffset(sy), getZWithOffset(sx, sz), getXWithOffset(dx, dz), getYWithOffset(dy), getZWithOffset(dx, dz)); - } - - /** - * Nullify all the sky light at the specified positions, using world coordinates - */ - public void nullifySkyLight(World world, int sx, int sy, int sz, int dx, int dy, int dz) - { - for (int x = sx; x <= dx; x++) - { - for (int z = sz; z <= dz; z++) - { - for (int y = sy; y <= dy; y++) - { - world.setLightValue(EnumSkyBlock.Sky, x, y, z, 0); - } - } - } - } - - /** - * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the - * levels in the BB's horizontal rectangle). - * - * This is basically copied from ComponentVillage - */ - protected int getAverageGroundLevel(World world, StructureBoundingBox sbb) { - int totalHeight = 0; - int heightCount = 0; - - for (int bz = this.boundingBox.minZ; bz <= this.boundingBox.maxZ; ++bz) - { - for (int by = this.boundingBox.minX; by <= this.boundingBox.maxX; ++by) - { - if (sbb.isVecInside(by, 64, bz)) - { - totalHeight += Math.max(world.getTopSolidOrLiquidBlock(by, bz), world.provider.getAverageGroundLevel()); - ++heightCount; - } - } - } - - if (heightCount == 0) - { - return -1; - } - else - { - return totalHeight / heightCount; - } - } - - /** - * Find what y level the dirt/grass/stone is. Just check the center of the chunk we're given - */ - protected int getSampledDirtLevel(World world, StructureBoundingBox sbb) { - int dirtLevel = 256; - - for (int y = 90; y > 0; y--) // is 90 like a good place to start? :) - { - int cx = sbb.getCenterX(); - int cz = sbb.getCenterZ(); - - Material material = world.getBlock(cx, y, cz).getMaterial(); - if (material == Material.ground || material == Material.rock || material == Material.grass) - { - dirtLevel = y; - break; - } - } - - return dirtLevel; + @Override + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + tagCompound.setInteger("si", this.spawnListIndex); + tagCompound.setString("deco", StructureTFDecorator.getDecoString(this.deco)); + tagCompound.setInteger("rot", this.rotation.ordinal()); } - /** - * Temporary replacement - */ - protected void randomlyPlaceBlock(World world, StructureBoundingBox sbb, Random rand, float chance, int x, int y, int z, Block blockPlaced, int meta) { - this.func_151552_a(world, sbb, rand, chance, x, y, z, blockPlaced, meta); + @Override + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + this.spawnListIndex = tagCompound.getInteger("si"); + this.deco = StructureTFDecorator.getDecoFor(tagCompound.getString("deco")); + this.rotation = Rotation.values()[tagCompound.getInteger("rot") % Rotation.values().length]; } /** @@ -653,30 +117,4 @@ protected void randomlyPlaceBlock(World world, StructureBoundingBox sbb, Random public boolean isComponentProtected() { return true; } - - - /** - * Discover if bounding box can fit within the current bounding box object. - */ - public static StructureComponent findIntersectingExcluding(List list, StructureBoundingBox toCheck, StructureComponent exclude) - { - Iterator iterator = list.iterator(); - StructureComponent structurecomponent; - - do - { - if (!iterator.hasNext()) - { - return null; - } - - structurecomponent = (StructureComponent)iterator.next(); - } - while (structurecomponent == exclude || structurecomponent.getBoundingBox() == null || !structurecomponent.getBoundingBox().intersectsWith(toCheck)); - - return structurecomponent; - } - - - } \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/StructureTFComponentOld.java b/src/main/java/twilightforest/structures/StructureTFComponentOld.java new file mode 100644 index 0000000000..774d31767f --- /dev/null +++ b/src/main/java/twilightforest/structures/StructureTFComponentOld.java @@ -0,0 +1,652 @@ +package twilightforest.structures; + +import net.minecraft.block.*; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityMobSpawner; +import net.minecraft.tileentity.TileEntitySign; +import net.minecraft.util.*; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.EnumSkyBlock; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraftforge.common.util.BlockSnapshot; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.util.StructureBoundingBoxUtils; + +import javax.annotation.Nullable; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; + +@Deprecated +public abstract class StructureTFComponentOld extends StructureTFComponent { + + protected static final IBlockState AIR = Blocks.AIR.getDefaultState(); + private static final StructureTFStrongholdStones strongholdStones = new StructureTFStrongholdStones(); + + public StructureTFComponentOld() { + } + + public StructureTFComponentOld(TFFeature feature, int i) { + super(i); + this.feature = feature; + } + + @Override + public TFFeature getFeatureType() { + return feature; + } + + //Let's not use vanilla's weird rotation+mirror thing... + @Override + public void setCoordBaseMode(@Nullable EnumFacing facing) { + this.coordBaseMode = facing; + this.mirror = Mirror.NONE; + + if (facing == null) { + this.rotation = Rotation.NONE; + } else { + switch (facing) { + case SOUTH: + this.rotation = Rotation.CLOCKWISE_180; + break; + case WEST: + this.rotation = Rotation.COUNTERCLOCKWISE_90; + break; + case EAST: + this.rotation = Rotation.CLOCKWISE_90; + break; + default: + this.rotation = Rotation.NONE; + } + } + } + + public static StructureBoundingBox getComponentToAddBoundingBox(int x, int y, int z, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, @Nullable EnumFacing dir) { + switch (dir) { + default: + return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); + + case SOUTH: // '\0' + return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); + + case WEST: // '\001' + return new StructureBoundingBox(x - maxZ + minZ, y + minY, z + minX, x + minZ, y + maxY + minY, z + maxX + minX); + + case NORTH: // '\002' + return new StructureBoundingBox(x - maxX - minX, y + minY, z - maxZ - minZ, x - minX, y + maxY + minY, z - minZ); + + case EAST: // '\003' + return new StructureBoundingBox(x + minZ, y + minY, z - maxX, x + maxZ + minZ, y + maxY + minY, z + minX); + } + } + + /** + * Fixed a bug with direction 1 and -z values, but I'm not sure if it'll break other things + */ + public static StructureBoundingBox getComponentToAddBoundingBox2(int x, int y, int z, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, EnumFacing dir) { + switch (dir) { + default: + return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); + + case SOUTH: // '\0' + return new StructureBoundingBox(x + minX, y + minY, z + minZ, x + maxX + minX, y + maxY + minY, z + maxZ + minZ); + + case WEST: // '\001' + return new StructureBoundingBox(x - maxZ - minZ, y + minY, z + minX, x - minZ, y + maxY + minY, z + maxX + minX); + + case NORTH: // '\002' + return new StructureBoundingBox(x - maxX - minX, y + minY, z - maxZ - minZ, x - minX, y + maxY + minY, z - minZ); + + case EAST: // '\003' + return new StructureBoundingBox(x + minZ, y + minY, z - maxX, x + maxZ + minZ, y + maxY + minY, z - minX); + } + } + + // [VanillaCopy] Keep pinned to signature of setBlockState (no state arg) + protected TileEntityMobSpawner setSpawner(World world, int x, int y, int z, StructureBoundingBox sbb, ResourceLocation monsterID) { + TileEntityMobSpawner tileEntitySpawner = null; + + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() != Blocks.MOB_SPAWNER) { + world.setBlockState(pos, Blocks.MOB_SPAWNER.getDefaultState(), 2); + tileEntitySpawner = (TileEntityMobSpawner) world.getTileEntity(pos); + if (tileEntitySpawner != null) { + tileEntitySpawner.getSpawnerBaseLogic().setEntityId(monsterID); + } + } + + return tileEntitySpawner; + } + + protected void surroundBlockCardinal(World world, IBlockState block, int x, int y, int z, StructureBoundingBox sbb) { + setBlockState(world, block, x + 0, y, z - 1, sbb); + setBlockState(world, block, x + 0, y, z + 1, sbb); + setBlockState(world, block, x - 1, y, z + 0, sbb); + setBlockState(world, block, x + 1, y, z + 0, sbb); + } + + protected void surroundBlockCardinalRotated(World world, IBlockState block, int x, int y, int z, StructureBoundingBox sbb) { + setBlockState(world, block.withProperty(BlockStairs.FACING, EnumFacing.NORTH), x + 0, y, z - 1, sbb); + setBlockState(world, block.withProperty(BlockStairs.FACING, EnumFacing.SOUTH), x + 0, y, z + 1, sbb); + setBlockState(world, block.withProperty(BlockStairs.FACING, EnumFacing.WEST), x - 1, y, z + 0, sbb); + setBlockState(world, block.withProperty(BlockStairs.FACING, EnumFacing.EAST), x + 1, y, z + 0, sbb); + } + + protected void surroundBlockCorners(World world, IBlockState block, int x, int y, int z, StructureBoundingBox sbb) { + setBlockState(world, block, x - 1, y, z - 1, sbb); + setBlockState(world, block, x - 1, y, z + 1, sbb); + setBlockState(world, block, x + 1, y, z - 1, sbb); + setBlockState(world, block, x + 1, y, z + 1, sbb); + } + + protected TileEntityMobSpawner setSpawnerRotated(World world, int x, int y, int z, Rotation rotation, ResourceLocation monsterID, StructureBoundingBox sbb) { + EnumFacing oldBase = fakeBaseMode(rotation); + TileEntityMobSpawner ret = setSpawner(world, x, y, z, sbb, monsterID); + setCoordBaseMode(oldBase); + return ret; + } + + /** + * Place a treasure chest at the specified coordinates + * + * @param treasureType + */ + protected void placeTreasureAtCurrentPosition(World world, Random rand, int x, int y, int z, TFTreasure treasureType, StructureBoundingBox sbb) { + this.placeTreasureAtCurrentPosition(world, rand, x, y, z, treasureType, false, sbb); + } + + /** + * Place a treasure chest at the specified coordinates + * + * @param treasureType + */ + protected void placeTreasureAtCurrentPosition(World world, Random rand, int x, int y, int z, TFTreasure treasureType, boolean trapped, StructureBoundingBox sbb) { + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() != (trapped ? Blocks.TRAPPED_CHEST : Blocks.CHEST)) { + treasureType.generateChest(world, pos, trapped); + } + } + + /** + * Place a treasure chest at the specified coordinates + * + * @param treasureType + */ + protected void placeTreasureRotated(World world, int x, int y, int z, Rotation rotation, TFTreasure treasureType, StructureBoundingBox sbb) { + this.placeTreasureRotated(world, x, y, z, rotation, treasureType, false, sbb); + } + + /** + * Place a treasure chest at the specified coordinates + * + * @param treasureType + */ + protected void placeTreasureRotated(World world, int x, int y, int z, Rotation rotation, TFTreasure treasureType, boolean trapped, StructureBoundingBox sbb) { + int dx = getXWithOffsetRotated(x, z, rotation); + int dy = getYWithOffset(y); + int dz = getZWithOffsetRotated(x, z, rotation); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() != (trapped ? Blocks.TRAPPED_CHEST : Blocks.CHEST)) { + treasureType.generateChest(world, pos, trapped); + } + } + + /** + * Places a tripwire. + * + * Tries to delay notifying tripwire blocks of placement so they won't + * scan unloaded chunks looking for connections. + * + * See {@link net.minecraftforge.common.ForgeHooks#onPlaceItemIntoWorld(ItemStack, EntityPlayer, World, BlockPos, EnumFacing, float, float, float, EnumHand)} + * for block snapshot handling code. + */ + protected void placeTripwire(World world, int x, int y, int z, int size, EnumFacing facing, StructureBoundingBox sbb) { + + int dx = facing.getXOffset(); + int dz = facing.getZOffset(); + + world.captureBlockSnapshots = true; + + // add tripwire hooks + IBlockState tripwireHook = Blocks.TRIPWIRE_HOOK.getDefaultState(); + setBlockState(world, tripwireHook.withProperty(BlockTripWireHook.FACING, facing.getOpposite()), x, y, z, sbb); + setBlockState(world, tripwireHook.withProperty(BlockTripWireHook.FACING, facing), x + dx * size, y, z + dz * size, sbb); + + // add string + IBlockState tripwire = Blocks.TRIPWIRE.getDefaultState(); + for (int i = 1; i < size; i++) { + setBlockState(world, tripwire, x + dx * i, y, z + dz * i, sbb); + } + + world.captureBlockSnapshots = false; + + @SuppressWarnings("unchecked") + List blockSnapshots = (List) world.capturedBlockSnapshots.clone(); + world.capturedBlockSnapshots.clear(); + + for (BlockSnapshot snap : blockSnapshots) + { + int updateFlag = snap.getFlag(); + IBlockState oldBlock = snap.getReplacedBlock(); + IBlockState newBlock = world.getBlockState(snap.getPos()); + + newBlock.getBlock().onBlockAdded(world, snap.getPos(), newBlock); + world.markAndNotifyBlock(snap.getPos(), null, oldBlock, newBlock, updateFlag); + } + } + + protected void placeSignAtCurrentPosition(World world, int x, int y, int z, String string0, String string1, StructureBoundingBox sbb) { + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() != Blocks.STANDING_SIGN) { + world.setBlockState(pos, Blocks.STANDING_SIGN.getDefaultState().withProperty(BlockStandingSign.ROTATION, this.getCoordBaseMode().getHorizontalIndex() * 4), 2); + + TileEntitySign teSign = (TileEntitySign) world.getTileEntity(pos); + if (teSign != null) { + teSign.signText[1] = new TextComponentString(string0); + teSign.signText[2] = new TextComponentString(string1); + } + } + } + + protected void placeSignAtCurrentPosition(World world, int x, int y, int z, StructureBoundingBox sbb, String... text) { + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() != Blocks.STANDING_SIGN) { + world.setBlockState(pos, Blocks.STANDING_SIGN.getDefaultState().withProperty(BlockStandingSign.ROTATION, this.getCoordBaseMode().getHorizontalIndex() * 4), 2); + + TileEntitySign teSign = (TileEntitySign) world.getTileEntity(pos); + if (teSign != null) { + int min = Math.min(text.length, teSign.signText.length); + + for (int i = 0; i < min; i++) { + teSign.signText[i] = new TextComponentString(text[i]); + } + } + } + } + + +// +// public boolean makeTowerWing2(List list, Random rand, int index, int x, int y, int z, int size, int height, int direction) { +// +// ComponentTFTowerWing wing = new ComponentTFTowerWing(index, x, y, z, size, height, direction); +// // check to see if it intersects something already there +// StructureComponent intersect = StructureComponent.getIntersectingStructureComponent(list, wing.boundingBox); +// if (intersect == null || intersect == this) { +// list.add(wing); +// wing.buildComponent(this, list, rand); +// return true; +// } else { +// return false; +// } +// } + + /** + * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. + */ + protected int[] offsetTowerCoords(int x, int y, int z, int towerSize, EnumFacing direction) { + + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + + if (direction == EnumFacing.SOUTH) { + return new int[]{dx + 1, dy - 1, dz - towerSize / 2}; + } else if (direction == EnumFacing.WEST) { + return new int[]{dx + towerSize / 2, dy - 1, dz + 1}; + } else if (direction == EnumFacing.NORTH) { + return new int[]{dx - 1, dy - 1, dz + towerSize / 2}; + } else if (direction == EnumFacing.EAST) { + return new int[]{dx - towerSize / 2, dy - 1, dz - 1}; + } + + + // ugh? + return new int[]{x, y, z}; + } + + /** + * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. + */ + protected BlockPos offsetTowerCCoords(int x, int y, int z, int towerSize, EnumFacing direction) { + + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + + switch (direction) { + case SOUTH: + return new BlockPos(dx + 1, dy - 1, dz - towerSize / 2); + case WEST: + return new BlockPos(dx + towerSize / 2, dy - 1, dz + 1); + case NORTH: + return new BlockPos(dx - 1, dy - 1, dz + towerSize / 2); + case EAST: + return new BlockPos(dx - towerSize / 2, dy - 1, dz - 1); + default: + break; + } + + // ugh? + return new BlockPos(x, y, z); + } + + @Override + protected int getXWithOffset(int x, int z) { + //return super.getXWithOffset(x, z); + // [VanillaCopy] of super, edits noted. + EnumFacing enumfacing = this.getCoordBaseMode(); + + if (enumfacing == null) { + return x; + } else { + switch (enumfacing) { + case SOUTH: + return this.boundingBox.minX + x; + case WEST: + return this.boundingBox.maxX - z; + case NORTH: + return this.boundingBox.maxX - x; // TF - Add case for NORTH todo 1.9 is this correct? + case EAST: + return this.boundingBox.minX + z; + default: + return x; + } + } + } + + @Override + protected int getZWithOffset(int x, int z) { + //return super.getZWithOffset(x, z); + // [VanillaCopy] of super, edits noted. + EnumFacing enumfacing = this.getCoordBaseMode(); + + if (enumfacing == null) { + return z; + } else { + switch (enumfacing) { + case SOUTH: + return this.boundingBox.minZ + z; + case WEST: + return this.boundingBox.minZ + x; + case NORTH: + return this.boundingBox.maxZ - z; + case EAST: + return this.boundingBox.maxZ - x; + default: + return z; + } + } + } + + private EnumFacing fakeBaseMode(Rotation rotationsCW) { + final EnumFacing oldBaseMode = getCoordBaseMode(); + + if (oldBaseMode != null) { + EnumFacing pretendBaseMode = oldBaseMode; + pretendBaseMode = rotationsCW.rotate(pretendBaseMode); + + setCoordBaseMode(pretendBaseMode); + } + + return oldBaseMode; + } + + // [VanillaCopy] Keep pinned to the signature of getXWithOffset + protected int getXWithOffsetRotated(int x, int z, Rotation rotationsCW) { + EnumFacing oldMode = fakeBaseMode(rotationsCW); + int ret = getXWithOffset(x, z); + setCoordBaseMode(oldMode); + return ret; + } + + // [VanillaCopy] Keep pinned to the signature of getZWithOffset + protected int getZWithOffsetRotated(int x, int z, Rotation rotationsCW) { + EnumFacing oldMode = fakeBaseMode(rotationsCW); + int ret = getZWithOffset(x, z); + setCoordBaseMode(oldMode); + return ret; + } + + protected void setBlockStateRotated(World world, IBlockState state, int x, int y, int z, Rotation rotationsCW, StructureBoundingBox sbb) { + EnumFacing oldMode = fakeBaseMode(rotationsCW); + setBlockState(world, state, x, y, z, sbb); + setCoordBaseMode(oldMode); + } + + @Override + public IBlockState getBlockStateFromPos(World world, int x, int y, int z, StructureBoundingBox sbb) { + // Making public + return super.getBlockStateFromPos(world, x, y, z, sbb); + } + + @Override + protected void setBlockState(World worldIn, IBlockState blockstateIn, int x, int y, int z, StructureBoundingBox sbb) { + // Making public + super.setBlockState(worldIn, blockstateIn, x, y, z, sbb); + } + + // [VanillaCopy] Keep pinned to the signature of getBlockStateFromPos + public IBlockState getBlockStateFromPosRotated(World world, int x, int y, int z, StructureBoundingBox sbb, Rotation rotationsCW) { + EnumFacing oldMode = fakeBaseMode(rotationsCW); + IBlockState ret = getBlockStateFromPos(world, x, y, z, sbb); + setCoordBaseMode(oldMode); + return ret; + } + + protected void fillBlocksRotated(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, IBlockState state, Rotation rotation) { + EnumFacing oldBase = fakeBaseMode(rotation); + fillWithBlocks(world, sbb, minX, minY, minZ, maxX, maxY, maxZ, state, state, false); + setCoordBaseMode(oldBase); + } + + // [VanillaCopy] Keep pinned on signature of fillWithBlocksRandomly (though passing false for excludeAir) + protected void randomlyFillBlocksRotated(World worldIn, StructureBoundingBox boundingboxIn, Random rand, float chance, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, IBlockState blockstate1, IBlockState blockstate2, Rotation rotation) { + EnumFacing oldBase = fakeBaseMode(rotation); + final int minimumLightLevel = 15; + generateMaybeBox(worldIn, boundingboxIn, rand, chance, minX, minY, minZ, maxX, maxY, maxZ, blockstate1, blockstate2, false, minimumLightLevel); + setCoordBaseMode(oldBase); + } + + // [VanillaCopy] Keep pinned to signature of replaceAirAndLiquidDownwards + public void replaceAirAndLiquidDownwardsRotated(World world, IBlockState state, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) { + EnumFacing oldBaseMode = fakeBaseMode(rotation); + replaceAirAndLiquidDownwards(world, state, x, y, z, sbb); + setCoordBaseMode(oldBaseMode); + } + + protected void fillAirRotated(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Rotation rotation) { + EnumFacing oldBaseMode = fakeBaseMode(rotation); + fillWithAir(world, sbb, minX, minY, minZ, maxX, maxY, maxZ); + setCoordBaseMode(oldBaseMode); + } + + protected void fillWithAir(World world, StructureBoundingBox boundingBox, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Predicate predicate) { + fillWithBlocks(world, boundingBox, xMin, yMin, zMin, xMax, yMax, zMax, Blocks.AIR.getDefaultState(), predicate); + } + + protected void fillWithBlocks(World world, StructureBoundingBox boundingBox, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, IBlockState state, Predicate predicate) { + fillWithBlocks(world, boundingBox, xMin, yMin, zMin, xMax, yMax, zMax, state, state, predicate); + } + + protected void fillWithBlocks(World world, StructureBoundingBox boundingBox, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, IBlockState borderState, IBlockState interiorState, Predicate predicate) { + for (int y = yMin; y <= yMax; ++y) { + for (int x = xMin; x <= xMax; ++x) { + for (int z = zMin; z <= zMax; ++z) { + + if (predicate.test(this.getBlockStateFromPos(world, x, y, z, boundingBox))) { + + boolean isBorder = yMin != yMax && (y == yMin || y == yMax) + || xMin != xMax && (x == xMin || x == xMax) + || zMin != zMax && (z == zMin || z == zMax); + + this.setBlockState(world, isBorder ? borderState : interiorState, x, y, z, boundingBox); + } + } + } + } + } + + protected static StructureComponent.BlockSelector getStrongholdStones() { + return strongholdStones; + } + + protected EnumFacing getStructureRelativeRotation(Rotation rotationsCW) { + return rotationsCW.rotate(getCoordBaseMode()); + } + + /** + * Nullify all the sky light in this component bounding box + */ + public void nullifySkyLightForBoundingBox(World world) { + this.nullifySkyLight(world, boundingBox.minX - 1, boundingBox.minY - 1, boundingBox.minZ - 1, boundingBox.maxX + 1, boundingBox.maxY + 1, boundingBox.maxZ + 1); + } + + /** + * Nullify all the sky light at the specified positions, using local coordinates + */ + protected void nullifySkyLightAtCurrentPosition(World world, int sx, int sy, int sz, int dx, int dy, int dz) { + // resolve all variables to their actual in-world positions + nullifySkyLight(world, getXWithOffset(sx, sz), getYWithOffset(sy), getZWithOffset(sx, sz), getXWithOffset(dx, dz), getYWithOffset(dy), getZWithOffset(dx, dz)); + } + + /** + * Nullify all the sky light at the specified positions, using world coordinates + */ + protected void nullifySkyLight(World world, int sx, int sy, int sz, int dx, int dy, int dz) { + for (int x = sx; x <= dx; x++) { + for (int z = sz; z <= dz; z++) { + for (int y = sy; y <= dy; y++) { + world.setLightFor(EnumSkyBlock.SKY, new BlockPos(x, y, z), 0); + } + } + } + } + + /** + * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the + * levels in the BB's horizontal rectangle). + *

+ * This is basically copied from ComponentVillage + */ + protected int getAverageGroundLevel(World world, StructureBoundingBox sbb) { + int totalHeight = 0; + int heightCount = 0; + + for (int bz = this.boundingBox.minZ; bz <= this.boundingBox.maxZ; ++bz) { + for (int by = this.boundingBox.minX; by <= this.boundingBox.maxX; ++by) { + BlockPos pos = new BlockPos(by, 64, bz); + if (sbb.isVecInside(pos)) { + totalHeight += Math.max(world.getTopSolidOrLiquidBlock(pos).getY(), world.provider.getAverageGroundLevel()); + ++heightCount; + } + } + } + + if (heightCount == 0) { + return -1; + } else { + return totalHeight / heightCount; + } + } + + /** + * Find what y-level the ground is. Just check the center of the chunk we're given. + */ + protected int findGroundLevel(World world, StructureBoundingBox sbb, int start, Predicate predicate) { + + Vec3i center = StructureBoundingBoxUtils.getCenter(sbb); + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(center.getX(), 0, center.getZ()); + + for (int y = start; y > 0; y--) { + pos.setY(y); + if (predicate.test(world.getBlockState(pos))) { + return y; + } + } + + return 0; + } + + protected boolean isBoundingBoxOutsideBiomes(World world, StructureBoundingBox sbb, Predicate predicate) { + + int minX = this.boundingBox.minX - 1; + int minZ = this.boundingBox.minZ - 1; + int maxX = this.boundingBox.maxX + 1; + int maxZ = this.boundingBox.maxZ + 1; + + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + if (!predicate.test(world.getBiome(pos.setPos(x, 0, z)))) { + return true; + } + } + } + + return false; + } + + /** + * Discover if bounding box can fit within the current bounding box object. + */ + @Nullable + public static StructureComponent findIntersectingExcluding(List list, StructureBoundingBox toCheck, StructureComponent exclude) { + Iterator iterator = list.iterator(); + StructureComponent structurecomponent; + + do { + if (!iterator.hasNext()) { + return null; + } + + structurecomponent = (StructureComponent) iterator.next(); + } + while (structurecomponent == exclude || structurecomponent.getBoundingBox() == null || !structurecomponent.getBoundingBox().intersectsWith(toCheck)); + + return structurecomponent; + } + + public BlockPos getBlockPosWithOffset(int x, int y, int z) { + return new BlockPos( + getXWithOffset(x, z), + getYWithOffset(y), + getZWithOffset(x, z) + ); + } + + /* BlockState Helpers */ + protected static IBlockState getStairState(IBlockState stairState, EnumFacing direction, Rotation rotation, boolean isTopHalf) { + return stairState + .withProperty(BlockStairs.FACING, direction) + .withProperty(BlockStairs.HALF, isTopHalf ? BlockStairs.EnumHalf.TOP : BlockStairs.EnumHalf.BOTTOM); + } + + protected static IBlockState getSlabState(IBlockState inputBlockState, BlockPlanks.EnumType type, BlockSlab.EnumBlockHalf half) { + return inputBlockState + .withProperty(BlockPlanks.VARIANT, type) + .withProperty(BlockSlab.HALF, half); + } +} diff --git a/src/main/java/twilightforest/structures/StructureTFComponentTemplate.java b/src/main/java/twilightforest/structures/StructureTFComponentTemplate.java new file mode 100644 index 0000000000..a6297dbd2a --- /dev/null +++ b/src/main/java/twilightforest/structures/StructureTFComponentTemplate.java @@ -0,0 +1,249 @@ +package twilightforest.structures; + +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.PlacementSettings; +import net.minecraft.world.gen.structure.template.Template; +import net.minecraft.world.gen.structure.template.TemplateManager; +import net.minecraftforge.fml.common.FMLCommonHandler; +import twilightforest.TFFeature; + +/** + * Copied a few things from {@link net.minecraft.world.gen.structure.StructureComponentTemplate} + */ +public abstract class StructureTFComponentTemplate extends StructureTFComponent { + + protected PlacementSettings placeSettings = new PlacementSettings().setReplacedBlock(Blocks.STRUCTURE_VOID); + protected BlockPos templatePosition = BlockPos.ORIGIN; + protected BlockPos rotatedPosition; + protected Template TEMPLATE; + + public StructureTFComponentTemplate() { + super(); + this.rotation = Rotation.NONE; + this.mirror = Mirror.NONE; + } + + public StructureTFComponentTemplate(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(i); + this.feature = feature; + this.rotation = rotation; + this.mirror = Mirror.NONE; + this.placeSettings.setRotation(rotation); + this.templatePosition = new BlockPos(x, y, z); + this.boundingBox = new StructureBoundingBox(x, y, z, x, y, z); + } + + public StructureTFComponentTemplate(TFFeature feature, int i, int x, int y, int z, Rotation rotation, Mirror mirror) { + super(i); + this.feature = feature; + this.rotation = rotation; + this.mirror = mirror; + this.placeSettings.setRotation(rotation); + this.templatePosition = new BlockPos(x, y, z); + this.boundingBox = new StructureBoundingBox(x, y, z, x, y, z); + } + + public final void setup(TemplateManager templateManager, MinecraftServer server) { + loadTemplates(templateManager, server); + setModifiedTemplatePositionFromRotation(); + setBoundingBoxFromTemplate(rotatedPosition); + } + + protected abstract void loadTemplates(TemplateManager templateManager, MinecraftServer server); + + @Override + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + tagCompound.setInteger("TPX", this.templatePosition.getX()); + tagCompound.setInteger("TPY", this.templatePosition.getY()); + tagCompound.setInteger("TPZ", this.templatePosition.getZ()); + } + + @Override + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager manager) { + super.readStructureFromNBT(tagCompound, manager); + this.templatePosition = new BlockPos(tagCompound.getInteger("TPX"), tagCompound.getInteger("TPY"), tagCompound.getInteger("TPZ")); + this.placeSettings.setRotation(this.rotation); + setup(manager, FMLCommonHandler.instance().getMinecraftServerInstance()); + } + + protected final void setModifiedTemplatePositionFromRotation() { + + Rotation rotation = this.placeSettings.getRotation(); + BlockPos size = this.TEMPLATE.transformedSize(rotation); + + rotatedPosition = new BlockPos(this.templatePosition); + + if (rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.CLOCKWISE_180) { + rotatedPosition = rotatedPosition.east(size.getZ() - 1); + } + + if (rotation == Rotation.CLOCKWISE_180 || rotation == Rotation.COUNTERCLOCKWISE_90) { + rotatedPosition = rotatedPosition.south(size.getX() - 1); + } + } + + protected final void setBoundingBoxFromTemplate(BlockPos pos) { + Rotation rotation = this.placeSettings.getRotation(); + BlockPos size = this.TEMPLATE.transformedSize(rotation); + Mirror mirror = this.placeSettings.getMirror(); + this.boundingBox = new StructureBoundingBox(0, 0, 0, size.getX(), size.getY() - 1, size.getZ()); + + switch (rotation) + { + case NONE: + default: + break; + case CLOCKWISE_90: + this.boundingBox.offset(-size.getX(), 0, 0); + break; + case COUNTERCLOCKWISE_90: + this.boundingBox.offset(0, 0, -size.getZ()); + break; + case CLOCKWISE_180: + this.boundingBox.offset(-size.getX(), 0, -size.getZ()); + } + + switch (mirror) + { + case NONE: + default: + break; + case FRONT_BACK: + BlockPos blockpos2 = BlockPos.ORIGIN; + + if (rotation != Rotation.CLOCKWISE_90 && rotation != Rotation.COUNTERCLOCKWISE_90) + { + if (rotation == Rotation.CLOCKWISE_180) + { + blockpos2 = blockpos2.offset(EnumFacing.EAST, size.getX()); + } + else + { + blockpos2 = blockpos2.offset(EnumFacing.WEST, size.getX()); + } + } + else + { + blockpos2 = blockpos2.offset(rotation.rotate(EnumFacing.WEST), size.getZ()); + } + + this.boundingBox.offset(blockpos2.getX(), 0, blockpos2.getZ()); + break; + case LEFT_RIGHT: + BlockPos blockpos1 = BlockPos.ORIGIN; + + if (rotation != Rotation.CLOCKWISE_90 && rotation != Rotation.COUNTERCLOCKWISE_90) + { + if (rotation == Rotation.CLOCKWISE_180) + { + blockpos1 = blockpos1.offset(EnumFacing.SOUTH, size.getZ()); + } + else + { + blockpos1 = blockpos1.offset(EnumFacing.NORTH, size.getZ()); + } + } + else + { + blockpos1 = blockpos1.offset(rotation.rotate(EnumFacing.NORTH), size.getX()); + } + + this.boundingBox.offset(blockpos1.getX(), 0, blockpos1.getZ()); + } + + this.boundingBox.offset(pos.getX(), pos.getY(), pos.getZ()); + } + + @Deprecated + protected final void setTemplatePositionFromRotation() { + Rotation rotation = this.placeSettings.getRotation(); + BlockPos size = this.TEMPLATE.transformedSize(rotation); + + if (rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.CLOCKWISE_180) + this.templatePosition = this.templatePosition.east(size.getZ()-1); + + if (rotation == Rotation.CLOCKWISE_180 || rotation == Rotation.COUNTERCLOCKWISE_90) + this.templatePosition = this.templatePosition.south(size.getX()-1); + } + + @Deprecated + protected final void setBoundingBoxFromTemplate() { + Rotation rotation = this.placeSettings.getRotation(); + BlockPos size = this.TEMPLATE.transformedSize(rotation); + Mirror mirror = this.placeSettings.getMirror(); + this.boundingBox = new StructureBoundingBox(0, 0, 0, size.getX(), size.getY() - 1, size.getZ()); + + switch (rotation) + { + case NONE: + default: + break; + case CLOCKWISE_90: + this.boundingBox.offset(-size.getX(), 0, 0); + break; + case COUNTERCLOCKWISE_90: + this.boundingBox.offset(0, 0, -size.getZ()); + break; + case CLOCKWISE_180: + this.boundingBox.offset(-size.getX(), 0, -size.getZ()); + } + + switch (mirror) + { + case NONE: + default: + break; + case FRONT_BACK: + BlockPos blockpos2 = BlockPos.ORIGIN; + + if (rotation != Rotation.CLOCKWISE_90 && rotation != Rotation.COUNTERCLOCKWISE_90) + { + if (rotation == Rotation.CLOCKWISE_180) + { + blockpos2 = blockpos2.offset(EnumFacing.EAST, size.getX()); + } + else + { + blockpos2 = blockpos2.offset(EnumFacing.WEST, size.getX()); + } + } + else + { + blockpos2 = blockpos2.offset(rotation.rotate(EnumFacing.WEST), size.getZ()); + } + + this.boundingBox.offset(blockpos2.getX(), 0, blockpos2.getZ()); + break; + case LEFT_RIGHT: + BlockPos blockpos1 = BlockPos.ORIGIN; + + if (rotation != Rotation.CLOCKWISE_90 && rotation != Rotation.COUNTERCLOCKWISE_90) + { + if (rotation == Rotation.CLOCKWISE_180) + { + blockpos1 = blockpos1.offset(EnumFacing.SOUTH, size.getZ()); + } + else + { + blockpos1 = blockpos1.offset(EnumFacing.NORTH, size.getZ()); + } + } + else + { + blockpos1 = blockpos1.offset(rotation.rotate(EnumFacing.NORTH), size.getX()); + } + + this.boundingBox.offset(blockpos1.getX(), 0, blockpos1.getZ()); + } + + this.boundingBox.offset(this.templatePosition.getX(), this.templatePosition.getY(), this.templatePosition.getZ()); + } +} diff --git a/src/main/java/twilightforest/structures/StructureTFDecorator.java b/src/main/java/twilightforest/structures/StructureTFDecorator.java index 1b577f64e8..4290b86ce9 100644 --- a/src/main/java/twilightforest/structures/StructureTFDecorator.java +++ b/src/main/java/twilightforest/structures/StructureTFDecorator.java @@ -1,96 +1,70 @@ package twilightforest.structures; -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.world.gen.structure.StructureComponent; import twilightforest.structures.darktower.StructureDecoratorDarkTower; +import twilightforest.structures.finalcastle.StructureTFDecoratorCastle; import twilightforest.structures.icetower.StructureDecoratorIceTower; import twilightforest.structures.mushroomtower.StructureDecoratorMushroomTower; import twilightforest.structures.stronghold.StructureTFDecoratorStronghold; /** - * Stores information about what blocks to use in constructing this structure - * - * @author Ben + * Stores information about what blocks to use in constructing this structure * + * @author Ben */ -public class StructureTFDecorator -{ - public Block blockID = Blocks.stone; - public int blockMeta; - - public Block accentID = Blocks.cobblestone; - public int accentMeta; - - public Block stairID; - public int stairMeta; // probably not useful - - public Block fenceID; - public int fenceMeta; - - public Block pillarID; - public int pillarMeta; - - public Block platformID; - public int platformMeta; - - public Block floorID; - public int floorMeta; - - public Block roofID; - public int roofMeta; - +public class StructureTFDecorator { + public IBlockState blockState = Blocks.STONE.getDefaultState(); + public IBlockState accentState = Blocks.COBBLESTONE.getDefaultState(); + public IBlockState stairState = Blocks.STONE_STAIRS.getDefaultState(); + public IBlockState fenceState = Blocks.OAK_FENCE.getDefaultState(); + public IBlockState pillarState = Blocks.STONEBRICK.getDefaultState(); + public IBlockState platformState = Blocks.STONE_SLAB.getDefaultState(); + public IBlockState floorState = Blocks.STONEBRICK.getDefaultState(); + public IBlockState roofState = Blocks.STONEBRICK.getDefaultState(); + public StructureComponent.BlockSelector randomBlocks = new StructureTFStrongholdStones(); - - public static String getDecoString(StructureTFDecorator deco) - { - if (deco instanceof StructureDecoratorDarkTower) - { + + public static String getDecoString(StructureTFDecorator deco) { +//TODO: Structure Disabled + if (deco instanceof StructureDecoratorDarkTower) { return "DecoDarkTower"; } - if (deco instanceof StructureDecoratorIceTower) - { + if (deco instanceof StructureDecoratorIceTower) { return "DecoIceTower"; } - if (deco instanceof StructureDecoratorMushroomTower) - { + if (deco instanceof StructureDecoratorMushroomTower) { return "DecoMushroomTower"; } - if (deco instanceof StructureTFDecoratorStronghold) - { + if (deco instanceof StructureTFDecoratorStronghold) { return "DecoStronghold"; } - if (deco instanceof StructureTFDecoratorCastle) - { + if (deco instanceof StructureTFDecoratorCastle) { return "DecoCastle"; } - + return ""; } - - public static StructureTFDecorator getDecoFor(String decoString) - { - if (decoString.equals("DecoDarkTower")) - { + + public static StructureTFDecorator getDecoFor(String decoString) { +//TODO: Structure Disabled + if (decoString.equals("DecoDarkTower")) { return new StructureDecoratorDarkTower(); } - if (decoString.equals("DecoIceTower")) - { + if (decoString.equals("DecoIceTower")) { return new StructureDecoratorIceTower(); } - if (decoString.equals("DecoMushroomTower")) - { + if (decoString.equals("DecoMushroomTower")) { return new StructureDecoratorMushroomTower(); } - if (decoString.equals("DecoStronghold")) - { + if (decoString.equals("DecoStronghold")) { return new StructureTFDecoratorStronghold(); } - if (decoString.equals("DecoCastle")) - { + if (decoString.equals("DecoCastle")) { return new StructureTFDecoratorCastle(); } - + return new StructureTFDecorator(); } } diff --git a/src/main/java/twilightforest/structures/StructureTFDecoratorCastle.java b/src/main/java/twilightforest/structures/StructureTFDecoratorCastle.java deleted file mode 100644 index b8baba3c65..0000000000 --- a/src/main/java/twilightforest/structures/StructureTFDecoratorCastle.java +++ /dev/null @@ -1,32 +0,0 @@ -package twilightforest.structures; - -import net.minecraft.init.Blocks; -import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFDecorator; - -public class StructureTFDecoratorCastle extends StructureTFDecorator -{ - - public StructureTFDecoratorCastle() - { - this.blockID = TFBlocks.castleBlock; - this.blockMeta = 0; - - this.accentID = Blocks.quartz_block; - this.accentMeta = 1; - - this.roofID = TFBlocks.castleBlock; - this.roofMeta = 3; - - this.pillarID = Blocks.quartz_block; - this.pillarMeta = 2; - - this.fenceID = Blocks.fence; - this.fenceMeta = 0; - - this.stairID = Blocks.quartz_stairs; - - this.randomBlocks = new StructureTFCastleBlocks(); - } - -} diff --git a/src/main/java/twilightforest/structures/StructureTFHelper.java b/src/main/java/twilightforest/structures/StructureTFHelper.java new file mode 100644 index 0000000000..fab043b996 --- /dev/null +++ b/src/main/java/twilightforest/structures/StructureTFHelper.java @@ -0,0 +1,52 @@ +package twilightforest.structures; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockSapling; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; + +/** + * Created by Joseph on 7/16/2017. + */ +public class StructureTFHelper { + + public static final IBlockState stoneSlab = getSlab(Blocks.STONE_SLAB); + public static final IBlockState stoneSlabTop = getSlabTop(Blocks.STONE_SLAB); + public static final IBlockState stoneSlabDouble = Blocks.DOUBLE_STONE_SLAB.getDefaultState(); + + public static final IBlockState birchSlab = getSlab(Blocks.WOODEN_SLAB).withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + public static final IBlockState birchSlabTop = getSlabTop(Blocks.WOODEN_SLAB).withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + public static final IBlockState birchPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + + + private static IBlockState getSlabType(Block type, BlockSlab.EnumBlockHalf side) { + return type.getDefaultState().withProperty(BlockSlab.HALF, side); + } + + + public static IBlockState getSlab(Block type) { + return getSlabType(type, BlockSlab.EnumBlockHalf.BOTTOM); + } + + public static IBlockState getSlabTop(Block type) { + return getSlabType(type, BlockSlab.EnumBlockHalf.TOP); + } + + public static IBlockState randomPlant(int i) { + if(i < 4) return randomSapling(i); + else return randomMushroom(i-4); + } + + public static IBlockState randomSapling(int i) { + return Blocks.SAPLING.getDefaultState().withProperty(BlockSapling.TYPE, BlockPlanks.EnumType.values()[i]); + } + + public static IBlockState randomMushroom(int i) { + if(i == 0) return Blocks.RED_MUSHROOM.getDefaultState(); + else return Blocks.BROWN_MUSHROOM.getDefaultState(); + } + + +} diff --git a/src/main/java/twilightforest/structures/StructureTFMajorFeatureStart.java b/src/main/java/twilightforest/structures/StructureTFMajorFeatureStart.java deleted file mode 100644 index 3cf6113a1e..0000000000 --- a/src/main/java/twilightforest/structures/StructureTFMajorFeatureStart.java +++ /dev/null @@ -1,404 +0,0 @@ -package twilightforest.structures; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.gen.structure.MapGenStructureIO; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraft.world.gen.structure.StructureComponent; -import net.minecraft.world.gen.structure.StructureStart; -import net.minecraft.world.gen.structure.StructureStrongholdPieces; -import twilightforest.TFFeature; -import twilightforest.biomes.TFBiomeBase; -import twilightforest.block.TFBlocks; -import twilightforest.structures.darktower.ComponentTFDarkTowerMain; -import twilightforest.structures.darktower.TFDarkTowerPieces; -import twilightforest.structures.hollowtree.StructureTFHollowTreeStart; -import twilightforest.structures.hollowtree.TFHollowTreePieces; -import twilightforest.structures.icetower.ComponentTFIceTowerMain; -import twilightforest.structures.icetower.TFIceTowerPieces; -import twilightforest.structures.lichtower.ComponentTFTowerMain; -import twilightforest.structures.lichtower.TFLichTowerPieces; -import twilightforest.structures.minotaurmaze.ComponentTFMazeRuins; -import twilightforest.structures.minotaurmaze.TFMinotaurMazePieces; -import twilightforest.structures.mushroomtower.ComponentTFMushroomTowerMain; -import twilightforest.structures.mushroomtower.TFMushroomTowerPieces; -import twilightforest.structures.stronghold.ComponentTFStrongholdEntrance; -import twilightforest.structures.stronghold.TFStrongholdPieces; -import twilightforest.structures.trollcave.ComponentTFTrollCaveMain; -import twilightforest.structures.trollcave.TFTrollCavePieces; -import twilightforest.world.TFWorld; -import twilightforest.world.TFWorldChunkManager; - - -public class StructureTFMajorFeatureStart extends StructureStart { - - public static int NUM_LOCKS = 4; - - public TFFeature feature; - public boolean isConquered; - public byte[] lockBytes = new byte[NUM_LOCKS]; - - static - { - MapGenStructureIO.registerStructure(StructureTFMajorFeatureStart.class, "TFFeature"); - MapGenStructureIO.registerStructure(StructureTFHollowTreeStart.class, "TFHollowTree"); - - TFStrongholdPieces.registerPieces(); - TFMinotaurMazePieces.registerPieces(); - TFDarkTowerPieces.registerPieces(); - TFLichTowerPieces.registerPieces(); - TFIceTowerPieces.registerPieces(); - TFMushroomTowerPieces.registerPieces(); - TFHollowTreePieces.registerPieces(); - TFTrollCavePieces.registerPieces(); - TFFinalCastlePieces.registerFinalCastlePieces(); - - // register one-off pieces here - MapGenStructureIO.func_143031_a(ComponentTFHedgeMaze.class, "TFHedge"); - MapGenStructureIO.func_143031_a(ComponentTFHillMaze.class, "TFHillMaze"); - MapGenStructureIO.func_143031_a(ComponentTFHollowHill.class, "TFHill"); - MapGenStructureIO.func_143031_a(ComponentTFHydraLair.class, "TFHydra"); - MapGenStructureIO.func_143031_a(ComponentTFNagaCourtyard.class, "TFNaga"); - MapGenStructureIO.func_143031_a(ComponentTFQuestGrove.class, "TFQuest1"); - MapGenStructureIO.func_143031_a(ComponentTFYetiCave.class, "TFYeti"); -} - - public StructureTFMajorFeatureStart() {} - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public StructureTFMajorFeatureStart(World world, Random rand, int chunkX, int chunkZ) - { - StructureStrongholdPieces.prepareStructurePieces(); - //TFStrongholdPieces.prepareStructurePieces(); - - int x = (chunkX << 4) + 8; - int z = (chunkZ << 4) + 8; - int y = TFWorld.SEALEVEL + 1; //TODO: maybe a biome-specific altitude for some of them? - - this.feature = TFFeature.getFeatureDirectlyAt(chunkX, chunkZ, world); - this.isConquered = false; - - StructureComponent firstComponent = makeFirstComponent(world, rand, feature, x, y, z); - if (firstComponent != null) { - components.add(firstComponent); - firstComponent.buildComponent(firstComponent, components, rand); - } - - updateBoundingBox(); - - if (firstComponent instanceof StructureStrongholdPieces.Stairs2) - { - List var6 = ((StructureStrongholdPieces.Stairs2) firstComponent).field_75026_c; - - while (!var6.isEmpty()) - { - int var7 = rand.nextInt(var6.size()); - StructureComponent var8 = (StructureComponent)var6.remove(var7); - var8.buildComponent(firstComponent, this.components, rand); - } - - updateBoundingBox(); - - int offY = -33; - - boundingBox.offset(0, offY, 0); - - for (StructureComponent com : (LinkedList) getComponents()) - { - com.getBoundingBox().offset(0, offY, 0); - } - - - //System.out.println("Making stronghold!"); - - } - - if (firstComponent instanceof ComponentTFTowerMain || firstComponent instanceof ComponentTFDarkTowerMain) - { - moveToAvgGroundLevel(world, x, z); - } - } - - /** - * - * @return The first component we should add to our structure - */ - public StructureComponent makeFirstComponent(World world, Random rand, TFFeature feature, int x, int y, int z) { - - if (feature == TFFeature.nagaCourtyard) { - return new ComponentTFNagaCourtyard(world, rand, 0, x, y, z); - } - if (feature == TFFeature.hedgeMaze) { - return new ComponentTFHedgeMaze(world, rand, 0, x, y, z); - } - if (feature == TFFeature.hill1) { - return new ComponentTFHollowHill(world, rand, 0, 1, x, y, z); - } - if (feature == TFFeature.hill2) { - return new ComponentTFHollowHill(world, rand, 0, 2, x, y, z); - } - if (feature == TFFeature.hill3) { - return new ComponentTFHollowHill(world, rand, 0, 3, x, y, z); - } - if (feature == TFFeature.lichTower) { - return new ComponentTFTowerMain(world, rand, 0, x, y, z); - } - if (feature == TFFeature.questGrove) { - return new ComponentTFQuestGrove(world, rand, 0, x, y, z); - } - if (feature == TFFeature.hydraLair) { - return new ComponentTFHydraLair(world, rand, 0, x, y, z); - } - if (feature == TFFeature.labyrinth) { - return new ComponentTFMazeRuins(world, rand, 0, x, y, z); - } - if (feature == TFFeature.darkTower) { - return new ComponentTFDarkTowerMain(world, rand, 0, x, y - 1, z); - } - if (feature == TFFeature.tfStronghold) { - return new ComponentTFStrongholdEntrance(world, rand, 0, x, y, z); - } - if (feature == TFFeature.iceTower) { - return new ComponentTFIceTowerMain(world, rand, 0, x, y, z); - } - if (feature == TFFeature.mushroomTower) { - return new ComponentTFMushroomTowerMain(world, rand, 0, x, y, z); - } - if (feature == TFFeature.yetiCave) { - return new ComponentTFYetiCave(world, rand, 0, x, y, z); - } - if (feature == TFFeature.trollCave) { - return new ComponentTFTrollCaveMain(world, rand, 0, x, y, z); - } - if (feature == TFFeature.finalCastle) { - return new TFFinalCastlePieces.Main(world, rand, 0, x, y, z); - } - - return null; - } - - - /** - * currently only defined for Villages, returns true if Village has more than 2 non-road components - */ - public boolean isSizeableStructure() - { - return feature.isStructureEnabled; - } - - - /** - * Move the whole structure up or down - */ - @SuppressWarnings("unchecked") - protected void moveToAvgGroundLevel(World world, int x, int z) - { - if (world.getWorldChunkManager() instanceof TFWorldChunkManager) - { - // determine the biome at the origin - BiomeGenBase biomeAt = world.getBiomeGenForCoords(x, z); - - int offY = (int) ((biomeAt.rootHeight + biomeAt.heightVariation) * 8); - - // dark forest doesn't seem to get the right value. Why is my calculation so bad? - if (biomeAt == TFBiomeBase.darkForest) - { - offY += 4; - } - - if (offY > 0) - { - //System.out.println("Moving tower, offset is " + offY + " for biome " + biomeAt.biomeName); - - boundingBox.offset(0, offY, 0); - - for (StructureComponent com : (LinkedList) getComponents()) - { - com.getBoundingBox().offset(0, offY, 0); - } - } - } - } - -// /** -// * Keeps iterating Structure Pieces and spawning them until the checks tell it to stop -// */ -// public void generateStructure(World par1World, Random par2Random, StructureBoundingBox par3StructureBoundingBox) -// { -// if (this.getComponents().getFirst() instanceof ComponentTFStrongholdEntrance) -// { -// //System.out.println("We're generating a stronghold!"); -// -// for (StructureComponent component : (LinkedList) getComponents()) -// { -// -// // TODO: we need to test the shield bounding box here, otherwise we lose shield facings across chunk boundires -// -// if (isShieldable(component) ? isIntersectingLarger(par3StructureBoundingBox, component) : isIntersectingLarger(par3StructureBoundingBox, component)) -// { -// if (isShieldable(component)) -// { -// addShieldFor(par1World, component, (LinkedList) getComponents(), par3StructureBoundingBox); -// } -// component.addComponentParts(par1World, par2Random, par3StructureBoundingBox); -// } -// } -// } -// else -// { -// super.generateStructure(par1World, par2Random, par3StructureBoundingBox); -// } -// } - - /** - * Check if the component is within the chunk bounding box, but check as if it was one larger - */ - @SuppressWarnings("unused") - private boolean isIntersectingLarger(StructureBoundingBox chunkBB, StructureComponent component) { - StructureBoundingBox compBB = component.getBoundingBox(); - - // don't bother checking Y - return (compBB.maxX + 1) >= chunkBB.minX && (compBB.minX - 1) <= chunkBB.maxX && (compBB.maxZ + 1) >= chunkBB.minZ && (compBB.minZ - 1) <= chunkBB.maxZ; - - } - - @SuppressWarnings("unused") - private boolean isShieldable(StructureComponent component) { - return component.getBoundingBox().maxY <= 32; - } - - /** - * Make the stronghold shield around a component's bounding box - */ - @SuppressWarnings("unused") - private void addShieldFor(World world, StructureComponent component, List otherComponents, StructureBoundingBox chunkBox) { - StructureBoundingBox shieldBox = new StructureBoundingBox(component.getBoundingBox()); - - shieldBox.minX--; - shieldBox.minY--; - shieldBox.minZ--; - - shieldBox.maxX++; - shieldBox.maxY++; - shieldBox.maxZ++; - - ArrayList intersecting = new ArrayList(); - - for (StructureComponent other : otherComponents) - { - if (other != component && shieldBox.intersectsWith(other.getBoundingBox())) - { - intersecting.add(other); - } - } - - // trace outline - for (int x = shieldBox.minX; x <= shieldBox.maxX; x++) - { - for (int y = shieldBox.minY; y <= shieldBox.maxY; y++) - { - for (int z = shieldBox.minZ; z <= shieldBox.maxZ; z++) - { - if (x == shieldBox.minX || x == shieldBox.maxX || y == shieldBox.minY || y == shieldBox.maxY || z == shieldBox.minZ || z == shieldBox.maxZ) - { - if (chunkBox.isVecInside(x, y, z)) - { - // test other boxes - boolean notIntersecting = true; - - for (StructureComponent other : intersecting) - { - if (other.getBoundingBox().isVecInside(x, y, z)) - { - notIntersecting = false; - } - } - - - if (notIntersecting) - { - world.setBlock(x, y, z, TFBlocks.shield, calculateShieldMeta(shieldBox, x, y, z), 2); - } - - } - } - } - } - } - } - - private int calculateShieldMeta(StructureBoundingBox shieldBox, int x, int y, int z) { - int shieldMeta = 0; - if (x == shieldBox.minX) - { - shieldMeta = 5; - } - if (x == shieldBox.maxX) - { - shieldMeta = 4; - } - if (z == shieldBox.minZ) - { - shieldMeta = 3; - } - if (z == shieldBox.maxZ) - { - shieldMeta = 2; - } - if (y == shieldBox.minY) - { - shieldMeta = 1; - } - if (y == shieldBox.maxY) - { - shieldMeta = 0; - } - return shieldMeta; - } - - public void func_143022_a(NBTTagCompound par1NBTTagCompound) - { - super.func_143022_a(par1NBTTagCompound); - par1NBTTagCompound.setBoolean("Conquered", this.isConquered); - par1NBTTagCompound.setInteger("FeatureID", this.feature.featureID); - par1NBTTagCompound.setByteArray("Locks", this.lockBytes); - - //System.out.println("Saved structure for feature " + feature.name); - } - - public void func_143017_b(NBTTagCompound nbttagcompound) - { - super.func_143017_b(nbttagcompound); - this.isConquered = nbttagcompound.getBoolean("Conquered"); - this.feature = TFFeature.featureList[nbttagcompound.getInteger("FeatureID")]; - this.lockBytes = nbttagcompound.getByteArray("Locks"); - - //System.out.println("Loaded structure"); - } - - public boolean isLocked(int lockIndex) { - if (lockIndex < this.lockBytes.length) { - - System.out.println("Checking locks for lockIndex " + lockIndex); - - for (int i = 0; i < this.lockBytes.length; i++) { - System.out.println("Lock " + i + " = " + this.lockBytes[i]); - } - - return this.lockBytes[lockIndex] != 0; - } else { - - System.out.println("Current lock index, " + lockIndex + " is beyond array bounds " + this.lockBytes.length); - - - return false; - } - } - -} diff --git a/src/main/java/twilightforest/structures/StructureTFStrongholdStones.java b/src/main/java/twilightforest/structures/StructureTFStrongholdStones.java index c1656aadb8..b2149d34f2 100644 --- a/src/main/java/twilightforest/structures/StructureTFStrongholdStones.java +++ b/src/main/java/twilightforest/structures/StructureTFStrongholdStones.java @@ -1,42 +1,31 @@ package twilightforest.structures; -import java.util.Random; - +import net.minecraft.block.BlockSilverfish; +import net.minecraft.block.BlockStoneBrick; import net.minecraft.init.Blocks; import net.minecraft.world.gen.structure.StructureComponent; +import java.util.Random; + public class StructureTFStrongholdStones extends StructureComponent.BlockSelector { @Override - public void selectBlocks(Random par1Random, int par2, int par3, int par4, boolean par5) { - if (!par5) - { - this.field_151562_a = Blocks.air; - this.selectedBlockMetaData = 0; - } - else - { - this.field_151562_a = Blocks.stonebrick; - float var6 = par1Random.nextFloat(); + public void selectBlocks(Random random, int x, int y, int z, boolean wall) { + if (!wall) { + blockstate = Blocks.AIR.getDefaultState(); + } else { + float f = random.nextFloat(); - if (var6 < 0.2F) - { - this.selectedBlockMetaData = 2; - } - else if (var6 < 0.5F) - { - this.selectedBlockMetaData = 1; - } - else if (var6 < 0.55F) - { - this.field_151562_a = Blocks.monster_egg; - this.selectedBlockMetaData = 2; - } - else - { - this.selectedBlockMetaData = 0; - } - } + if (f < 0.2F) { + blockstate = Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CRACKED); + } else if (f < 0.5F) { + blockstate = Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.MOSSY); + } else if (f < 0.55F) { + blockstate = Blocks.MONSTER_EGG.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONEBRICK); + } else { + blockstate = Blocks.STONEBRICK.getDefaultState(); + } + } } } diff --git a/src/main/java/twilightforest/structures/TFFinalCastlePieces.java b/src/main/java/twilightforest/structures/TFFinalCastlePieces.java deleted file mode 100644 index b03c0a7cca..0000000000 --- a/src/main/java/twilightforest/structures/TFFinalCastlePieces.java +++ /dev/null @@ -1,3140 +0,0 @@ -package twilightforest.structures; - -import java.awt.Rectangle; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; - -import twilightforest.TFFeature; -import twilightforest.biomes.TFBiomeBase; -import twilightforest.block.BlockTFTowerDevice; -import twilightforest.block.TFBlocks; -import twilightforest.structures.TFFinalCastlePieces.EntranceTower; -import twilightforest.structures.TFFinalCastlePieces.MazeTower13; -import twilightforest.structures.icetower.ComponentTFIceTowerStairs; -import twilightforest.structures.icetower.StructureDecoratorIceTower; -import twilightforest.structures.lichtower.ComponentTFTowerBridge; -import twilightforest.structures.lichtower.ComponentTFTowerWing; -import twilightforest.structures.minotaurmaze.ComponentTFMazeUpperEntrance; -import twilightforest.structures.stronghold.StructureTFDecoratorStronghold; -import net.minecraft.block.Block; -import net.minecraft.block.BlockStainedGlassPane; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; -import net.minecraft.world.gen.structure.MapGenStructureIO; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraft.world.gen.structure.StructureComponent; -import net.minecraft.world.gen.structure.StructureNetherBridgePieces; - -public class TFFinalCastlePieces { - - - - - public static void registerFinalCastlePieces() - { - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Main.class, "TFFCMain"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.StairTower.class, "TFFCStTo"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.LargeTower.class, "TFFCLaTo"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Mural.class, "TFFCMur"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Foundation48.class, "TFFCToF48"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Roof48Crenellated.class, "TFFCRo48Cr"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.BossGazebo.class, "TFFCBoGaz"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.MazeTower13.class, "TFFCSiTo"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.DungeonSteps.class, "TFFCDunSt"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.DungeonEntrance.class, "TFFCDunEn"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.DungeonRoom31.class, "TFFCDunR31"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.DungeonExit.class, "TFFCDunEx"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.DungeonForgeRoom.class, "TFFCDunBoR"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Roof9Crenellated.class, "TFFCRo9Cr"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Roof13Crenellated.class, "TFFCRo13Cr"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Roof13Conical.class, "TFFCRo13Con"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Roof13Peaked.class, "TFFCRo13Pk"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.EntranceTower.class, "TFFCEnTo"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.EntranceSideTower.class, "TFFCEnSiTo"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.EntranceBottomTower.class, "TFFCEnBoTo"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.EntranceStairs.class, "TFFCEnSt"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.BellTower21.class, "TFFCBelTo"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Bridge.class, "TFFCBri"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Foundation13.class, "TFFCToF13"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.BellFoundation21.class, "TFFCBeF21"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.Foundation13Thorns.class, "TFFCFTh21"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.DamagedTower.class, "TFFCDamT"); - MapGenStructureIO.func_143031_a(TFFinalCastlePieces.WreckedTower.class, "TFFCWrT"); - } - - public static class Main extends StructureTFComponent { - - public Main() { - } - - public Main(World world, Random rand, int i, int x, int y, int z) { - this.setCoordBaseMode(0); - this.spawnListIndex = 1; // main monsters - - x = ((x + 127) >> 8) << 8; - z = ((z + 127) >> 8) << 8; - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -24, 120, -24, 48, 40, 48, 0); - - ChunkCoordinates cc = TFFeature.getNearestCenterXYZ(x >> 4, z >> 4, world); - - int cx = (x >> 8) << 8; - int cz = (z >> 8) << 8; - - System.out.println("Making castle at " + x + ", " + z + ". center is " + cc.posX + ", " + cc.posZ); - System.out.println("Natural center at " + cx + ", " + cz); - - // decorator - if (this.deco == null) - { - this.deco = new StructureTFDecoratorCastle(); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - // add foundation - Foundation48 foundation = new Foundation48(rand, 4, this); - list.add(foundation); - foundation.buildComponent(this, list, rand); - - // add roof - StructureTFComponent roof = new Roof48Crenellated(rand, 4, this); - list.add(roof); - roof.buildComponent(this, list, rand); - - // boss gazebo on roof - StructureTFComponent gazebo = new BossGazebo(rand, 5, this); - list.add(gazebo); - gazebo.buildComponent(this, list, rand); - - - // build 4 towers on sides - StairTower tower0 = new StairTower(rand, 3, boundingBox.minX, boundingBox.minY + 3, boundingBox.minZ, 2); - list.add(tower0); - tower0.buildComponent(this, list, rand); - - LargeTower tower1 = new LargeTower(rand, 3, boundingBox.maxX, boundingBox.minY + 3, boundingBox.minZ, 3); - list.add(tower1); - tower1.buildComponent(this, list, rand); - - StairTower tower2 = new StairTower(rand, 3, boundingBox.minX, boundingBox.minY + 3, boundingBox.maxZ, 1); - list.add(tower2); - tower2.buildComponent(this, list, rand); - - StairTower tower3 = new StairTower(rand, 3, boundingBox.maxX, boundingBox.minY + 3, boundingBox.maxZ, 0); - list.add(tower3); - tower3.buildComponent(this, list, rand); - - // tower maze towards entrance - ChunkCoordinates dest = new ChunkCoordinates(boundingBox.minX - 4, boundingBox.maxY, boundingBox.minZ - 24); - buildTowerMaze(list, rand, 48, 0, 24, 60, 0, 0, dest); - - - // another tower/bridge maze towards the clock tower - dest = new ChunkCoordinates(boundingBox.maxX + 4, boundingBox.minY, boundingBox.maxZ + 24); - buildTowerMaze(list, rand, 0, 30, 24, 60, 2, 1, dest); - - - // initial stairs down towards dungeon - DungeonSteps steps0 = new DungeonSteps(rand, 5, boundingBox.minX + 18, boundingBox.minY + 1, boundingBox.minZ + 18, 0); - list.add(steps0); - steps0.buildComponent(this, list, rand); - - // continued steps - DungeonSteps steps1 = steps0.buildMoreStepsTowards(parent, list, rand, 3); - DungeonSteps steps2 = steps1.buildMoreStepsTowards(parent, list, rand, 3); - DungeonSteps steps3 = steps2.buildMoreStepsTowards(parent, list, rand, 3); - - // start dungeon - DungeonEntrance dRoom = steps3.buildLevelUnder(parent, list, rand, 1); - - // mural on front - ChunkCoordinates mc = this.offsetTowerCCoords(48, 23, 25, 1, 0); - Mural mural0 = new Mural(rand, 7, mc.posX, mc.posY, mc.posZ, 35, 30, 0); - list.add(mural0); - mural0.buildComponent(this, list, rand); - - // mural inside - ChunkCoordinates mc1 = this.offsetTowerCCoords(48, 33, 24, -1, 0); - Mural mural1 = new Mural(rand, 7, mc1.posX, mc1.posY, mc.posZ, 19, 12, 2); - list.add(mural1); - mural1.buildComponent(this, list, rand); - - } - - /** - * Build a side tower, then tell it to start building towards the destination - */ - private void buildTowerMaze(List list, Random rand, int x, int y, int z, int howFar, int direction, int type, ChunkCoordinates dest) { - // duplicate list - LinkedList before = new LinkedList(list); - - // build - ChunkCoordinates tc = this.offsetTowerCCoords(x, y, z, howFar, direction); - MazeTower13 sTower = new MazeTower13(rand, 3, tc.posX, tc.posY, tc.posZ, type, direction); - // add bridge - ChunkCoordinates bc = this.offsetTowerCCoords(x, y, z, 1, direction); - Bridge bridge = new Bridge(this.getComponentType() + 1, bc.posX, bc.posY, bc.posZ, howFar - 7, direction); - list.add(bridge); - bridge.buildComponent(this, list, rand); - - // don't check if the bounding box is clear, there's either nothing there or we've made a terrible mistake - list.add(sTower); - sTower.buildTowards(this, list, rand, dest); - - // check if we've successfully built the end tower - if (this.isMazeComplete(list, type)) { - System.out.println("Tower maze type " + type + " complete!"); - } else { - // TODO: add limit on retrying, in case of infinite loop? - System.out.println("Tower maze type " + type + " INCOMPLETE, retrying!"); - list.clear(); - list.addAll(before); - this.buildTowerMaze(list, rand, x, y, z, howFar, direction, type, dest); - } - - } - - private boolean isMazeComplete(List list, int type) { - Iterator iterator = list.iterator(); - StructureComponent structurecomponent; - - do - { - if (!iterator.hasNext()) - { - return false; - } - - structurecomponent = (StructureComponent)iterator.next(); - } - while (!((structurecomponent instanceof EntranceTower && type == 0) || (structurecomponent instanceof BellTower21 && type == 1))); - - return true; - } - - /** - * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. - */ - protected ChunkCoordinates offsetTowerCCoords(int x, int y, int z, int howFar, int direction) { - - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - - switch (direction) { - case 0: - dx += howFar; - break; - case 1: - dz += howFar; - break; - case 2: - dx -= howFar; - break; - case 3: - dz -= howFar; - break; - } - - // ugh? - return new ChunkCoordinates(dx, dy, dz); - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // walls - fillWithRandomizedBlocks(world, sbb, 0, 0, 0, 48, 40, 48, false, rand, deco.randomBlocks); - - // 2M - fillWithRandomizedBlocks(world, sbb, 13, 30, 1, 47, 30, 12, false, rand, deco.randomBlocks); - this.fillWithBlocks(world, sbb, 13, 31, 12, 36, 31, 12, deco.fenceID, deco.fenceID, false); - fillWithRandomizedBlocks(world, sbb, 13, 30, 36, 47, 30, 47, false, rand, deco.randomBlocks); - this.fillWithBlocks(world, sbb, 13, 31, 36, 36, 31, 36, deco.fenceID, deco.fenceID, false); - fillWithRandomizedBlocks(world, sbb, 1, 30, 1, 12, 30, 47, false, rand, deco.randomBlocks); - this.fillWithBlocks(world, sbb, 12, 31, 12, 12, 31, 36, deco.fenceID, deco.fenceID, false); - - // second floor stairs to mezzanine - fillWithRandomizedBlocks(world, sbb, 38, 25, 13, 47, 25, 35, false, rand, deco.randomBlocks); - - for (int i = 0; i < 5; i++) { - int y = 30 - i; - - makeMezzTopStairs(world, sbb, y, 10 + i, 3); - makeMezzTopStairs(world, sbb, y, 38 - i, 1); - - y = 25 - i; - int x = 37 - i; - this.fillWithMetadataBlocks(world, sbb, x, y, 14, x, y, 22, deco.stairID, getStairMeta(0), deco.stairID, getStairMeta(0), false); - this.fillWithMetadataBlocks(world, sbb, x, y - 1, 14, x, y - 1, 22, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, x, y, 26, x, y, 34, deco.stairID, getStairMeta(0), deco.stairID, getStairMeta(0), false); - this.fillWithMetadataBlocks(world, sbb, x, y - 1, 26, x, y - 1, 34, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - } - - - // pillars - for (int x = 11; x < 47; x += 12) { - for (int z = 11; z < 47; z += 12) { - this.fillWithMetadataBlocks(world, sbb, x, 1, z, x + 2, 40, z + 2, deco.pillarID, deco.pillarMeta, deco.blockID, deco.blockMeta, false); - - makePillarBase(world, sbb, x, z, 1, 0); - makePillarBase(world, sbb, x, z, 19, 4); - makePillarBase(world, sbb, x, z, 21, 0); - makePillarBase(world, sbb, x, z, 39, 4); - - - } - } - - // side pillars - for (int rotation = 0; rotation < 4; rotation++) { - for (int z = 11; z < 47; z += 12) { - - // no middle pillars on walls with entrances - if (z == 23 && (rotation == 0 || rotation == 2)) { - continue; - } - - this.fillBlocksRotated(world, sbb, 1, 1, z, 1, 40, z + 2, deco.pillarID, deco.pillarMeta, rotation); - makeHalfPillarBase(world, sbb, rotation, 1, z, 0); - makeHalfPillarBase(world, sbb, rotation, 19, z, 4); - makeHalfPillarBase(world, sbb, rotation, 21, z, 0); - makeHalfPillarBase(world, sbb, rotation, 39, z, 4); - } - } - - // second floor - fillWithRandomizedBlocks(world, sbb, 1, 20, 1, 47, 20, 47, false, rand, deco.randomBlocks); - - // force field around dungeon stairs - Block fieldBlock = TFBlocks.forceField; - int fieldMeta = 6; - this.fillWithMetadataBlocks(world, sbb, 12, 1, 12, 24, 10, 12, fieldBlock, fieldMeta, fieldBlock, fieldMeta, false); - this.fillWithMetadataBlocks(world, sbb, 12, 1, 12, 12, 10, 24, fieldBlock, fieldMeta, fieldBlock, fieldMeta, false); - this.fillWithMetadataBlocks(world, sbb, 24, 1, 12, 24, 10, 24, fieldBlock, fieldMeta, fieldBlock, fieldMeta, false); - this.fillWithMetadataBlocks(world, sbb, 12, 1, 24, 24, 10, 24, fieldBlock, fieldMeta, fieldBlock, fieldMeta, false); - - this.fillWithMetadataBlocks(world, sbb, 12, 10, 12, 24, 10, 24, fieldBlock, fieldMeta, fieldBlock, fieldMeta, false); - - // doors in dungeon force field - this.fillWithMetadataBlocks(world, sbb, 17, 1, 12, 19, 4, 12, TFBlocks.castleDoor, 2, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 17, 1, 24, 19, 4, 24, TFBlocks.castleDoor, 2, Blocks.air, 0, false); - - // stairs to stair towers - makeSmallTowerStairs(world, sbb, 0); - makeSmallTowerStairs(world, sbb, 1); - makeSmallTowerStairs(world, sbb, 3); - makeLargeTowerStairs(world, sbb, 2); - - // door, first floor - this.fillWithMetadataBlocks(world, sbb, 48, 1, 23, 48, 4, 25, TFBlocks.castleDoor, 0, Blocks.air, 0, false); - - // door, second floor - this.fillWithMetadataBlocks(world, sbb, 0, 31, 23, 0, 34, 25, TFBlocks.castleDoor, 1, Blocks.air, 0, false); - - return true; - } - - private void makeSmallTowerStairs(World world, StructureBoundingBox sbb, int rotation) { - for (int y = 1; y < 4; y++) { - int z = 40 + y; - this.fillBlocksRotated(world, sbb, 1, 1, z, 4, y, z, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 2, y, z, 3, y, z, deco.stairID, getStairMeta(1 + rotation), rotation); - } - } - - private void makeLargeTowerStairs(World world, StructureBoundingBox sbb, int rotation) { - for (int y = 1; y < 4; y++) { - int z = 38 + y; - this.fillBlocksRotated(world, sbb, 2, 1, z, 6, y, z, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 3, y, z, 5, y, z, deco.stairID, getStairMeta(1 + rotation), rotation); - } - } - - private void makeMezzTopStairs(World world, StructureBoundingBox sbb, int y, int z, int stairMeta) { - this.fillWithMetadataBlocks(world, sbb, 38, y, z, 46, y, z, deco.stairID, getStairMeta(stairMeta), deco.stairID, getStairMeta(stairMeta), false); - this.fillWithMetadataBlocks(world, sbb, 38, y - 1, z, 46, y - 1, z, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithAir(world, sbb, 38, y + 1, z, 46, y + 3, z); - } - - private void makeHalfPillarBase(World world, StructureBoundingBox sbb, int rotation, int y, int z, int metaBit) { - this.fillBlocksRotated(world, sbb, 2, y, z - 1, 2, y, z + 3, deco.stairID, getStairMeta(2 + rotation) | metaBit, rotation); - this.placeBlockRotated(world, deco.stairID, getStairMeta(1 + rotation) | metaBit, 1, y, z - 1, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(3 + rotation) | metaBit, 1, y, z + 3, rotation, sbb); - } - - private void makePillarBase(World world, StructureBoundingBox sbb, int x, int z, int y, int metaBit) { - this.fillWithMetadataBlocks(world, sbb, x + 0, y, z + 3, x + 3, y, z + 3, deco.stairID, getStairMeta(3) | metaBit, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, x - 1, y, z - 1, x + 2, y, z - 1, deco.stairID, getStairMeta(1) | metaBit, Blocks.air, 0, false); - - this.fillWithMetadataBlocks(world, sbb, x + 3, y, z - 1, x + 3, y, z + 2, deco.stairID, getStairMeta(2) | metaBit, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, x - 1, y, z + 0, x - 1, y, z + 3, deco.stairID, getStairMeta(0) | metaBit, Blocks.air, 0, false); - } - - } - - public static class Roof48Crenellated extends StructureTFComponent { - public Roof48Crenellated() {} - - public Roof48Crenellated(Random rand, int i, StructureTFComponent keep) { - super(i); - - int height = 5; - - this.setCoordBaseMode(keep.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(keep.getBoundingBox().minX - 2, keep.getBoundingBox().maxY - 1, keep.getBoundingBox().minZ - 2, keep.getBoundingBox().maxX + 2, keep.getBoundingBox().maxY + height - 1, keep.getBoundingBox().maxZ + 2); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // add second layer of floor - this.fillWithMetadataBlocks(world, sbb, 2, 2, 2, 50, 2, 50, TFBlocks.castleMagic, 3, TFBlocks.castleMagic, 3, false); - - // crenellations - for (int rotation = 0; rotation < 4; rotation++) { - this.fillBlocksRotated(world, sbb, 3, 1, 1, 45, 3, 1, deco.blockID, deco.blockMeta, rotation); - - for (int i = 10; i < 41; i += 5) { - this.fillBlocksRotated(world, sbb, i, 1, 0, i + 2, 5, 2, deco.blockID, deco.blockMeta, rotation); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, i + 1, 0, 1, rotation, sbb); - } - } - - return true; - } - - } - - public static class BossGazebo extends StructureTFComponent { - - public BossGazebo() { - } - - public BossGazebo(Random rand, int i, StructureTFComponent keep) { - super(i); - this.spawnListIndex = -1; // no monsters - - this.setCoordBaseMode(keep.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(keep.getBoundingBox().minX + 14, keep.getBoundingBox().maxY + 2, keep.getBoundingBox().minZ + 14, keep.getBoundingBox().maxX - 14, keep.getBoundingBox().maxY + 13, keep.getBoundingBox().maxZ - 14); - - } - - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - this.deco = new StructureTFDecoratorCastle(); - this.deco.blockID = TFBlocks.castleMagic; - this.deco.blockMeta = 1; - - this.deco.fenceID = TFBlocks.forceField; - this.deco.fenceMeta = 10; - } - - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // walls - for (int rotation = 0; rotation < 4; rotation++) { - this.fillBlocksRotated(world, sbb, 0, 0, 0, 0, 10, 20, deco.fenceID, deco.fenceMeta, rotation); - } - - // roof - this.fillWithMetadataBlocks(world, sbb, 0, 11, 0, 20, 11, 20, deco.fenceID, deco.fenceMeta, deco.fenceID, deco.fenceMeta, false); - - this.placeSignAtCurrentPosition(world, 10, 0, 10, "Final Boss Here", "You win!", sbb); - - - return true; - } - - - } - - public static class Foundation48 extends StructureTFComponent { - private int groundLevel = -1; - - public Foundation48() { - } - - public Foundation48(Random rand, int i, StructureTFComponent sideTower) { - super(i); - - this.setCoordBaseMode(sideTower.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX, sideTower.getBoundingBox().minY, sideTower.getBoundingBox().minZ, sideTower.getBoundingBox().maxX, sideTower.getBoundingBox().minY - 1, sideTower.getBoundingBox().maxZ); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // foundation - for (int x = 4; x < 45; x++) - { - for (int z = 4; z < 45; z++) - { - this.func_151554_b(world, deco.blockID, deco.blockMeta, x, -1, z, sbb); - } - - } - - int mid = 16; - for (int rotation = 0; rotation < 4; rotation++) { - // do corner - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 3, -2, 3, rotation, sbb); - - // directly under castle - this.fillBlocksRotated(world, sbb, 2, -2, 1, 46, -1, 1, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 2, -4, 2, 45, -1, 2, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 4, -6, 3, 44, -1, 3, deco.blockID, deco.blockMeta, rotation); - - // pilings - for (int i = 9; i < 45; i += 6) { - makePiling(world, sbb, mid, rotation, i); - } - - makePiling(world, sbb, mid, rotation, 4); - makePiling(world, sbb, mid, rotation, 44); - - } - - // add supports for entrance bridge - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 21, -2, 0, 1, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 21, -4, 1, 1, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 21, -6, 2, 1, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 27, -2, 0, 1, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 27, -4, 1, 1, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 27, -6, 2, 1, sbb); - - return true; - } - - private void makePiling(World world, StructureBoundingBox sbb, int mid, int rotation, int i) { - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, i, -7, 3, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, i, -mid, 2, rotation, sbb); - - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, i, -1, 0, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, i, -3, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, i, -5, 2, rotation, sbb); - } - - } - - public static class DungeonSteps extends StructureTFComponent { - public DungeonSteps() { } - - public DungeonSteps(Random rand, int i, int x, int y, int z, int rotation) { - this.spawnListIndex = 2; // dungeon monsters - - this.setCoordBaseMode(rotation); - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox2(x, y, z, -2, -15, -3, 5, 15, 20, rotation); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - /** - * build more steps towards the specified direction - */ - public DungeonSteps buildMoreStepsTowards(StructureComponent parent, List list, Random rand, int rotation) { - - int direction = (rotation + this.coordBaseMode) % 4; - - int sx = 2; - int sy = 0; - int sz = 17; - - switch (rotation) { - case 0: - sz -= 5; - break; - case 1: - sx -= 5; - break; - case 2: - sz += 5; - break; - case 3: - sx += 6; - break; - } - - // find center of landing - int dx = this.getXWithOffset(sx, sz); - int dy = this.getYWithOffset(sy); - int dz = this.getZWithOffset(sx, sz); - - - // build a new stairway there - DungeonSteps steps = new DungeonSteps(rand, this.componentType + 1, dx, dy, dz, direction); - list.add(steps); - steps.buildComponent(this, list, rand); - - return steps; - } - - /** - * build a new level under the exit - */ - public DungeonEntrance buildLevelUnder(StructureComponent parent, List list, Random rand, int level) { - // find center of landing - int dx = this.getXWithOffset(2, 19); - int dy = this.getYWithOffset(-7); - int dz = this.getZWithOffset(2, 19); - - // build a new dungeon level under there - DungeonEntrance room = new DungeonEntrance(rand, 8, dx, dy, dz, this.coordBaseMode, level); - list.add(room); - room.buildComponent(this, list, rand); - - return room; - } - - /** - * build the boss room - */ - public DungeonForgeRoom buildBossRoomUnder(StructureComponent parent, List list, Random rand) { - // find center of landing - int dx = this.getXWithOffset(2, 19); - int dy = this.getYWithOffset(-31); - int dz = this.getZWithOffset(2, 19); - - // build a new dungeon level under there - DungeonForgeRoom room = new DungeonForgeRoom(rand, 8, dx, dy, dz, this.coordBaseMode); - list.add(room); - room.buildComponent(this, list, rand); - - //System.out.println("Made dungeon boss room at " + dx + ", " + dy + ", " + dz + "."); - - return room; - } - - - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - for (int z = 0; z < 15; z++) { - int y = 14 - z; - this.fillWithMetadataBlocks(world, sbb, 0, y, z, 4, y, z, deco.stairID, getStairMeta(3), deco.stairID, getStairMeta(3), false); - this.fillWithAir(world, sbb, 0, y + 1, z, 4, y + 6, z); - } - this.fillWithAir(world, sbb, 0, 0, 15, 4, 5, 19); - - return true; - } - - } - - public static class DungeonEntrance extends DungeonRoom31 { - public boolean hasExit = false; - - public DungeonEntrance() { - } - - public DungeonEntrance(Random rand, int i, int x, int y, int z, int direction, int level) { - super(rand, i, x, y, z, direction, level); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - this.deco = new StructureTFDecoratorCastle(); - this.deco.blockID = TFBlocks.castleMagic; - this.deco.blockMeta = 2; - - this.deco.fenceID = TFBlocks.forceField; - this.deco.fenceMeta = 1; - - // this is going to be the parent for all rooms on this level - super.buildComponent(this, list, rand); - } - - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - super.addComponentParts(world, rand, sbb); - - // stairs - for (int y = 0; y <= this.height; y++) { - int x = (this.size / 2) - 2; - int z = (this.size / 2) - y + 2; - this.fillWithMetadataBlocks(world, sbb, x, y, z, x + 4, y, z, deco.stairID, getStairMeta(3), deco.stairID, getStairMeta(3), false); - this.fillWithMetadataBlocks(world, sbb, x, 0, z, x + 4, y - 1, z, TFBlocks.deadrock, 0, TFBlocks.deadrock, 0, false); - } - - // door - this.fillWithMetadataBlocks(world, sbb, 23, 0, 12, 23, 3, 14, TFBlocks.castleDoor, 2, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 23, 4, 12, 23, 4, 14, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - - - return true; - } - - protected int getForceFieldMeta(Random decoRNG) { - return 1; - } - - protected int getRuneMeta(int fieldMeta) { - return 0; - } - } - - public static class DungeonExit extends DungeonRoom31 { - public DungeonExit() { - } - - public DungeonExit(Random rand, int i, int x, int y, int z, int direction, int level) { - super(rand, i, x, y, z, direction, level); - } - - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - // no need for additional rooms, we're along the outside anyways - - // add stairway down - int bestDir = this.findStairDirectionTowards(parent.getBoundingBox().minX, parent.getBoundingBox().minZ); - - DungeonSteps steps0 = new DungeonSteps(rand, 5, boundingBox.minX + 15, boundingBox.minY + 0, boundingBox.minZ + 15, bestDir); - list.add(steps0); - steps0.buildComponent(this, list, rand); - - // another level!? - if (this.level == 1) { - steps0.buildLevelUnder(parent, list, rand, this.level + 1); - } else { - steps0.buildBossRoomUnder(parent, list, rand); - } - } - - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - super.addComponentParts(world, rand, sbb); - - // door - this.fillWithMetadataBlocks(world, sbb, 7, 0, 16, 7, 3, 18, TFBlocks.castleDoor, 2, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 7, 4, 16, 7, 4, 18, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - - - return true; - } - - - public int findStairDirectionTowards(int x, int z) { - // center of component - int cx = this.boundingBox.getCenterX(); - int cz = this.boundingBox.getCenterZ(); - - // difference - int dx = cx - x; - int dz = cz - z; - - int absoluteDir; - if (Math.abs(dz) >= Math.abs(dx)) { - absoluteDir = (dz >= 0) ? 2 : 0; - } else { - absoluteDir = (dx >= 0) ? 3 : 1; - } - - return absoluteDir; - } - - protected int getForceFieldMeta(Random decoRNG) { - return 1; - } - - protected int getRuneMeta(int fieldMeta) { - return 0; - } - } - - public static class DungeonRoom31 extends ComponentTFTowerWing { - public int level; // this is not serialized, since it's only used during build, which should be all one step - - public DungeonRoom31() { - } - - public DungeonRoom31(Random rand, int i, int x, int y, int z, int direction, int level) { - super(i); - this.setCoordBaseMode(direction); - this.spawnListIndex = 2; // dungeon monsters - this.size = 31; - this.height = 7; - this.level = level; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -15, 0, -15, this.size - 1, this.height - 1, this.size - 1, 0); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - int mySpread = this.getComponentType() - parent.getComponentType(); - int maxSpread = (this.level == 1) ? 2 : 3; - - // add exit if we're far enough away and don't have one - if (mySpread == maxSpread && !isExitBuildForLevel(parent)) { - int direction = rand.nextInt(4); - for (int i = 0; i < 8 && !isExitBuildForLevel(parent); i++) { - direction = (direction + i) % 4; - if (this.addDungeonExit(parent, list, rand, direction)) { - this.setExitBuiltForLevel(parent, true); - } - } - } - - // add other rooms - if (mySpread < maxSpread) { - int direction = rand.nextInt(4); - for (int i = 0; i < 12; i++) { - direction = (direction + i) % 4; - this.addDungeonRoom(parent, list, rand, direction, this.level); - } - } - } - - private boolean isExitBuildForLevel(StructureComponent parent) { - if (parent instanceof DungeonEntrance) { - return ((DungeonEntrance)parent).hasExit; - } else { - return false; - } - } - - private void setExitBuiltForLevel(StructureComponent parent, boolean exit) { - if (parent instanceof DungeonEntrance) { - ((DungeonEntrance)parent).hasExit = exit; - } else {} - } - - protected boolean addDungeonRoom(StructureComponent parent, List list, Random rand, int rotation, int level) { - rotation = (this.coordBaseMode + rotation) % 4; - - ChunkCoordinates rc = this.getNewRoomCoords(rand, rotation); - - DungeonRoom31 dRoom = new DungeonRoom31(rand, this.componentType + 1, rc.posX, rc.posY, rc.posZ, rotation, level); - - StructureBoundingBox largerBB = new StructureBoundingBox(dRoom.getBoundingBox()); - - int expand = 0; - largerBB.minX -= expand; - largerBB.minZ -= expand; - largerBB.maxX += expand; - largerBB.maxZ += expand; - - StructureComponent intersect = StructureTFComponent.findIntersectingExcluding(list, largerBB, this); - if (intersect == null) { - list.add(dRoom); - dRoom.buildComponent(parent, list, rand); - return true; - } else { - return false; - } - } - - protected boolean addDungeonExit(StructureComponent parent, List list, Random rand, int rotation) { - - //TODO: check if we are sufficiently near the castle center - - rotation = (this.coordBaseMode + rotation) % 4; - ChunkCoordinates rc = this.getNewRoomCoords(rand, rotation); - DungeonExit dRoom = new DungeonExit(rand, this.componentType + 1, rc.posX, rc.posY, rc.posZ, rotation, this.level); - StructureComponent intersect = StructureTFComponent.findIntersectingExcluding(list, dRoom.getBoundingBox(), this); - if (intersect == null) { - list.add(dRoom); - dRoom.buildComponent(this, list, rand); - return true; - } else { - return false; - } - } - - private ChunkCoordinates getNewRoomCoords(Random rand, int rotation) { - // make the rooms connect around the corners, not the centers - int offset = rand.nextInt(15) - 9; - if (rand.nextBoolean()) { - offset += this.size; - } - - switch (rotation) { - default: - case 0: - return new ChunkCoordinates(this.boundingBox.maxX + 9, this.boundingBox.minY, this.boundingBox.minZ + offset); - case 1: - return new ChunkCoordinates(this.boundingBox.minX + offset, this.boundingBox.minY, this.boundingBox.maxZ + 9); - case 2: - return new ChunkCoordinates(this.boundingBox.minX - 9, this.boundingBox.minY, this.boundingBox.minZ + offset); - case 3: - return new ChunkCoordinates(this.boundingBox.minX + offset, this.boundingBox.minY, this.boundingBox.minZ - 9); - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isBoundingBoxOutOfPlateau(world, sbb)) { - return false; - } - - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - this.fillWithAir(world, sbb, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1); - int forceFieldMeta = this.getForceFieldMeta(decoRNG); - int runeMeta = getRuneMeta(forceFieldMeta); - - for (int rotation = 0; rotation < 4; rotation++) { - int cs = 7; - this.fillBlocksRotated(world, sbb, cs, 0, cs + 1, cs, this.height - 1, this.size - 2 - cs, TFBlocks.forceField, forceFieldMeta, rotation); - // verticals - for (int z = cs; z < ((this.size - 1) - cs); z += 4) { - this.fillBlocksRotated(world, sbb, cs, 0, z, cs, this.height - 1, z, TFBlocks.castleMagic, runeMeta, rotation); - // horizontals - int y = ((z - cs) % 8 == 0) ? decoRNG.nextInt(3) + 0 : decoRNG.nextInt(3) + 4; - this.fillBlocksRotated(world, sbb, cs, y, z + 1, cs, y, z + 3, TFBlocks.castleMagic, runeMeta, rotation); - } - } - - return true; - } - - private boolean isBoundingBoxOutOfPlateau(World world, StructureBoundingBox sbb) { - int minX = this.boundingBox.minX - 1; - int minZ = this.boundingBox.minZ - 1; - int maxX = this.boundingBox.maxX + 1; - int maxZ = this.boundingBox.maxZ + 1; - - for (int x = minX; x <= maxX; x++) { - for (int z = minZ; z <= maxZ; z++) { - if (world.getBiomeGenForCoords(x, z) != TFBiomeBase.highlandsCenter && world.getBiomeGenForCoords(x, z) != TFBiomeBase.thornlands) { - return true; - } - } - } - - return false; - } - - protected int getRuneMeta(int forceFieldMeta) { - return (forceFieldMeta == 4) ? 1 : 2; - } - - protected int getForceFieldMeta(Random decoRNG) { - return decoRNG.nextInt(2) + 3; - } - - } - - public static class DungeonForgeRoom extends StructureTFComponent { - public DungeonForgeRoom() { - } - - public DungeonForgeRoom(Random rand, int i, int x, int y, int z, int direction) { - super(i); - this.spawnListIndex = 3; // forge monsters - this.setCoordBaseMode(direction); - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox2(x, y, z, -15, 0, -15, 50, 30, 50, direction); - } - - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - this.fillWithAir(world, sbb, 0, 0, 0, 50, 30, 50); - - // sign - this.placeSignAtCurrentPosition(world, 25, 0, 25, "Mini-boss 2", "Gives talisman", sbb); - - return true; - } - - } - - - public static class StairTower extends ComponentTFTowerWing { - - public StairTower() { } - - public StairTower(Random rand, int i, int x, int y, int z, int rotation) { - this.setCoordBaseMode(rotation); - this.size = 9; - this.height = 51; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -4, 0, -4, 8, 50, 8, 0); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - // add crown - Roof9Crenellated roof = new Roof9Crenellated(rand, 4, this); - list.add(roof); - roof.buildComponent(this, list, rand); - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - fillWithRandomizedBlocks(world, sbb, 0, 0, 0, 8, 49, 8, false, rand, deco.randomBlocks); - - // add branching runes - int numBranches = 6 + decoRNG.nextInt(4); - for (int i = 0; i < numBranches; i++) { - makeGlyphBranches(world, decoRNG, this.getGlyphMeta(), sbb); - } - - // beard - for (int i = 1; i < 4; i++) { - fillWithRandomizedBlocks(world, sbb, i, 0 - (i * 2), i, 8 - i, 1 - (i * 2), 8 - i, false, rand, deco.randomBlocks); - } - this.placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, 4, -7, 4, sbb); - - - // door, first floor - this.fillWithMetadataBlocks(world, sbb, 0, 1, 1, 0, 3, 2, TFBlocks.castleDoor, this.getGlyphMeta(), Blocks.air, 0, false); - - // stairs - for (int f = 0; f < 5; f++) { - int rotation = (f + 2) % 4; - int y = f * 3 + 1; - for (int i = 0; i < 3; i++) { - int sx = 3 + i; - int sy = y + i; - int sz = 1; - - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), sx, sy, sz, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx, sy - 1, sz, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), sx, sy, sz + 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx, sy - 1, sz + 1, rotation, sbb); - } - // landing - this.fillBlocksRotated(world, sbb, 6, y + 2, 1, 7, y + 2, 2, deco.blockID, deco.blockMeta, rotation); - } - - // door, second floor - this.fillWithMetadataBlocks(world, sbb, 1, 18, 0, 2, 20, 0, TFBlocks.castleDoor, this.getGlyphMeta(), Blocks.air, 0, false); - - // second floor landing - this.fillWithMetadataBlocks(world, sbb, 1, 17, 1, 3, 17, 3, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 17, 4, 2, 17, 4, deco.stairID, getStairMeta(3), deco.stairID, getStairMeta(3), false); - this.fillWithMetadataBlocks(world, sbb, 1, 16, 4, 2, 16, 4, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 16, 5, 2, 16, 5, deco.stairID, getStairMeta(3), deco.stairID, getStairMeta(3), false); - this.fillWithMetadataBlocks(world, sbb, 1, 15, 5, 2, 15, 5, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - - // door, roof - this.fillWithMetadataBlocks(world, sbb, 1, 39, 0, 2, 41, 0, TFBlocks.castleDoor, this.getGlyphMeta(), Blocks.air, 0, false); - - // stairs - for (int f = 0; f < 7; f++) { - int rotation = (f + 0) % 4; - int y = f * 3 + 18; - for (int i = 0; i < 3; i++) { - int sx = 3 + i; - int sy = y + i; - int sz = 1; - - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), sx, sy, sz, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx, sy - 1, sz, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), sx, sy, sz + 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx, sy - 1, sz + 1, rotation, sbb); - } - // landing - this.fillBlocksRotated(world, sbb, 6, y + 2, 1, 7, y + 2, 2, deco.blockID, deco.blockMeta, rotation); - } - - // roof access landing - this.fillWithMetadataBlocks(world, sbb, 1, 38, 1, 3, 38, 5, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, 3, 39, 1, 3, 39, 5, deco.fenceID, deco.fenceMeta, deco.fenceID, deco.fenceMeta, false); - - - return true; - } - - - public int getGlyphMeta() { - return 1; - } - - - } - - public static class LargeTower extends ComponentTFTowerWing { - - public LargeTower() { - } - - public LargeTower(Random rand, int i, int x, int y, int z, int rotation) { - this.setCoordBaseMode(rotation); - this.size = 13; - this.height = 61; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -6, 0, -6, 12, 60, 12, 0); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - // add crown - Roof9Crenellated roof = new Roof9Crenellated(rand, 4, this); - list.add(roof); - roof.buildComponent(this, list, rand); - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - fillWithRandomizedBlocks(world, sbb, 0, 0, 0, 12, 59, 12, false, rand, deco.randomBlocks); - - // add branching runes - int numBranches = 6 + decoRNG.nextInt(4); - for (int i = 0; i < numBranches; i++) { - makeGlyphBranches(world, decoRNG, this.getGlyphMeta(), sbb); - } - - // beard - for (int i = 1; i < 4; i++) { - fillWithRandomizedBlocks(world, sbb, i, 0 - (i * 2), i, 8 - i, 1 - (i * 2), 8 - i, false, rand, deco.randomBlocks); - } - this.placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, 4, -7, 4, sbb); - - // door, first floor - this.fillWithMetadataBlocks(world, sbb, 0, 1, 1, 0, 4, 3, TFBlocks.castleDoor, 0, Blocks.air, this.getGlyphMeta(), false); - - this.placeSignAtCurrentPosition(world, 6, 1, 6, "Parkour area 1", "Unique monster?", sbb); - - return true; - } - - - public int getGlyphMeta() { - return 0; - } - - - } - - public static class Mural extends StructureTFComponent { - - private int height; - private int width; - - // we will model the mural in this byte array - private byte[][] mural; - - public Mural() {} - - public Mural(Random rand, int i, int x, int y, int z, int width, int height, int direction) { - super(i); - this.setCoordBaseMode(direction); - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox2(x, y, z, 0, -height / 2, -width / 2, 1, height - 1, width - 1, direction); - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - this.height = this.boundingBox.getYSize(); - this.width = (this.coordBaseMode == 0 || this.coordBaseMode == 2) ? this.boundingBox.getZSize() : this.boundingBox.getXSize(); - - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - if (mural == null) { - // only make it once - mural = new byte[width][height]; - - int startX = width / 2 - 1; - int startY = 2; - - // make mural, fill in dot by start - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - mural[startX + x][startY + y] = 1; - } - } - - // side branches - makeHorizontalTree(decoRNG, mural, startX + 1, startY, decoRNG.nextInt(width / 6) + width / 6, true); - makeHorizontalTree(decoRNG, mural, startX - 1, startY, decoRNG.nextInt(width / 6) + width / 6, false); - - // main tree - makeVerticalTree(decoRNG, mural, startX, startY + 1, decoRNG.nextInt(height / 6) + height / 6, true); - - // stripes - makeStripes(decoRNG, mural); - } - - // copy mural to world - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - if (mural[x][y] > 0) { - this.placeBlockAtCurrentPosition(world, TFBlocks.castleMagic, 1, 0, y, x, sbb); - } else { - //this.placeBlockAtCurrentPosition(world, TFBlocks.forceField, 0, 0, y, x, sbb); - } - } - } - - return true; - } - - private void makeHorizontalTree(Random decoRNG, byte[][] mural, int centerX, int centerY, int branchLength, boolean positive) { - this.fillHorizontalLine(mural, centerX, centerY, branchLength, positive); - - this.makeHorizontalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, true); - this.makeHorizontalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, false); - } - - private void makeVerticalTree(Random decoRNG, byte[][] mural, int centerX, int centerY, int branchLength, boolean positive) { - this.fillVerticalLine(mural, centerX, centerY, branchLength, positive); - - this.makeVerticalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, true); - this.makeVerticalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, false); - } - - private boolean makeHorizontalBranch(byte[][] mural, Random rand, int sx, int sy, int length, boolean plusX, boolean plusY) { - int downLine = (length / 2) + 1 + rand.nextInt(Math.max(length / 2, 2)); - int branchLength = rand.nextInt(width / 8) + width / 8; - - // check if the area is clear - boolean clear = true; - for (int i = 0; i <= branchLength; i++) { - int cx = sx + (plusX ? downLine - 1 + i : -(downLine - 1 + i)); - int cy = sy + (plusY ? 2 : -2); - if (cx < 0 || cx >= width || cy < 0 || cy >= height || mural[cx][cy] > 0) { - clear = false; - break; - } - } - if (clear) { - int bx = sx + (plusX ? downLine : -downLine); - int by = sy; - - // jag - this.fillVerticalLine(mural, bx, by, 1, plusY); - - by += (plusY ? 2 : -2); - - this.fillHorizontalLine(mural, bx, by, branchLength, plusX); - - // recurse? - if (bx > 0 && bx < width && by > 0 && by < height) { - if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true)) { - if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true)) { - if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true)) { - this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true); - } - } - } - if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false)) { - if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false)) { - if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false)) { - this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false); - } - } - } - } - return true; - } else { - return false; - } - } - - private boolean makeVerticalBranch(byte[][] mural, Random rand, int sx, int sy, int length, boolean plusY, boolean plusX) { - int downLine = (length / 2) + 1 + rand.nextInt(Math.max(length / 2, 2)); - int branchLength = rand.nextInt(height / 8) + height / 8; - - // check if the area is clear - boolean clear = true; - for (int i = 0; i <= branchLength; i++) { - int cx = sx + (plusX ? 2 : -2); - int cy = sy + (plusY ? downLine - 1 + i : -(downLine - 1 + i)); - if (cx < 0 || cx >= width || cy < 0 || cy >= height || mural[cx][cy] > 0) { - clear = false; - break; - } - } - if (clear) { - int bx = sx; - int by = sy + (plusY ? downLine : -downLine);; - - // jag - this.fillHorizontalLine(mural, bx, by, 1, plusX); - - bx += (plusX ? 2 : -2); - - this.fillVerticalLine(mural, bx, by, branchLength, plusY); - - // recurse? - if (bx > 0 && bx < width && by > 0 && by < height) { - if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true)) { - if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true)) { - if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true)) { - this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true); - } - } - } - if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false)) { - if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false)) { - if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false)) { - this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false); - } - } - } - } - return true; - } else { - return false; - } - } - - private void fillHorizontalLine(byte[][] mural, int sx, int sy, int length, boolean positive) { - int x = sx; - int y = sy; - - for (int i = 0; i <= length; i++) { - if (x >= 0 && x < width && y >= 0 && y < height) { - mural[x][y] = (byte) (positive ? 1 : 4); - - x += positive ? 1 : -1; - } - } - } - - private void fillVerticalLine(byte[][] mural, int sx, int sy, int length, boolean positive) { - int x = sx; - int y = sy; - - for (int i = 0; i <= length; i++) { - if (x >= 0 && x < width && y >= 0 && y < height) { - mural[x][y] = (byte) (positive ? 2 : 3); - - y += positive ? 1 : -1; - } - } - } - - private void makeStripes(Random decoRNG, byte[][] mural2) { - // stagger slightly on our way down - for (int y = this.height - 2; y > this.height / 3; y -= (2 + decoRNG.nextInt(2))) { - makeSingleStripe(mural2, y); - } - } - - private void makeSingleStripe(byte[][] mural2, int y) { - for (int x = 0; x < this.width - 2; x++) { - if (mural[x + 1][y] == 0 && mural[x + 1][y + 1] == 0) { - mural[x][y] = 1; - } else { - break; - } - } - for (int x = this.width - 1; x > 2; x--) { - if (mural[x - 1][y] == 0 && mural[x - 1][y + 1] == 0) { - mural[x][y] = 1; - } else { - break; - } - } - } - - } - - public static class MazeTower13 extends ComponentTFTowerWing { - - public static final int LOWEST_DOOR = 144; - public static final int HIGHEST_DOOR = 222; - - public int type; - - public MazeTower13() { - } - - public MazeTower13(Random rand, int i, int x, int y, int z, int type, int direction) { - super(i); - this.setCoordBaseMode(direction); - this.type = type; - this.size = 13; - - // decide a number of floors, 2-5 - int floors = rand.nextInt(3) + 2; - - this.height = floors * 8 + 1; - - // entrance should be on a random floor - int entranceFloor = rand.nextInt(floors); - - // rationalize entrance floor if the tower is going to be too low, put the entrance floor at bottom. Too high, put it at top - if ((y - (entranceFloor * 8)) < LOWEST_DOOR) { - //System.out.println("Tower at " + x + ", " + z + " is getting too low, setting entrance to bottom floor."); - entranceFloor = 0; - } - if ((y + ((floors - entranceFloor) * 8)) > HIGHEST_DOOR) { - //System.out.println("Tower at " + x + ", " + z + " is getting too high, setting entrance to floor " + (floors - 1) + "."); - entranceFloor = floors - 1; - } - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -6, 0 - (entranceFloor * 8), -6, this.size - 1, this.height, this.size - 1, 0); - - // we should have a door where we started - addOpening(0, entranceFloor * 8 + 1, size / 2, 2); - - } - - public MazeTower13(Random rand, int i, int x, int y, int z, int floors, int entranceFloor, int type, int direction) { - super(i); - this.setCoordBaseMode(direction); - this.type = type; - this.size = 13; - this.height = floors * 8 + 1; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -6, 0 - (entranceFloor * 8), -6, this.size - 1, this.height, this.size - 1, 0); - addOpening(0, entranceFloor * 8 + 1, size / 2, 2); - } - - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - // add foundation - Foundation13 foundation = new Foundation13(rand, 4, this); - list.add(foundation); - foundation.buildComponent(this, list, rand); - - // add roof - StructureTFComponent roof = rand.nextBoolean() ? new Roof13Conical(rand, 4, this) : new Roof13Crenellated(rand, 4, this); - list.add(roof); - roof.buildComponent(this, list, rand); - } - - /** - * Build more components towards the destination - */ - public void buildTowards(StructureComponent parent, List list, Random rand, ChunkCoordinates dest) { - // regular building first, adds roof/foundation - this.buildComponent(parent, list, rand); - - if (this.getComponentType() < 15) { - - // are we there? - if (this.isWithinRange(dest.posX, dest.posZ, this.boundingBox.minX + 6, this.boundingBox.minZ + 6, 30)) { - //System.out.println("We are within range of our destination, building final tower"); - int howFar = 20; - if (!buildEndTowerTowards(list, rand, dest, this.findBestDirectionTowards(dest), howFar)) { - if (!buildEndTowerTowards(list, rand, dest, this.findSecondDirectionTowards(dest), howFar)) { - if (!buildEndTowerTowards(list, rand, dest, this.findThirdDirectionTowards(dest), howFar)) { - //System.out.println("Cound not build final tower"); - } - } - } - } else { - - int howFar = 14 + rand.nextInt(24); - int direction = this.findBestDirectionTowards(dest); - - // build left or right, not straight if we can help it - if (direction == 0 || !buildContinueTowerTowards(list, rand, dest, direction, howFar)) { - direction = this.findSecondDirectionTowards(dest); - if (direction == 0 || !buildContinueTowerTowards(list, rand, dest, direction, howFar)) { - direction = this.findThirdDirectionTowards(dest); - if (direction == 0 || !buildContinueTowerTowards(list, rand, dest, direction, howFar)) { - // fine, just go straight - if (!buildContinueTowerTowards(list, rand, dest, 0, howFar)) { - //System.out.println("Could not build tower randomly"); - } - } - } - } - } - } - - // finally, now that the critical path is built, let's add some other towers for atmosphere and complication - this.buildNonCriticalTowers(parent, list, rand); - - } - - protected void buildNonCriticalTowers(StructureComponent parent, List list, Random rand) { - // pick a random direction - int dir = rand.nextInt(4); - - // if there isn't something in that direction, check if we can add a wrecked tower - if (this.openingTowards[dir] == false) { - if (!buildDamagedTower(list, rand, dir)) { - dir = (dir + rand.nextInt(4)) % 4; - if (!buildDamagedTower(list, rand, dir)) { - // maybe just a balcony? - //buildBalconyTowards(list, rand, dir); - } - } - } - - - } - - private int findBestDirectionTowards(ChunkCoordinates dest) { - - // center of tower - int cx = this.boundingBox.minX + 6; - int cz = this.boundingBox.minZ + 6; - - // difference - int dx = cx - dest.posX; - int dz = cz - dest.posZ; - - int absoluteDir = 0; - if (Math.abs(dx) > Math.abs(dz)) { - absoluteDir = (dx >= 0) ? 2 : 0; - } else { - absoluteDir = (dz >= 0) ? 3 : 1; - } - - int relativeDir = (absoluteDir + 4 - this.coordBaseMode) % 4; - - //System.out.println("Determining best direction! center is at " + cx + ", " + cz + " and dest is at " + dest + " offset is " + dx + ", " + dz + " so the best absolute direction is " + absoluteDir + " and relative dir is " + relativeDir); - - // return relative dir - return relativeDir; - } - - private int findSecondDirectionTowards(ChunkCoordinates dest) { - - // center of tower - int cx = this.boundingBox.minX + 6; - int cz = this.boundingBox.minZ + 6; - - // difference - int dx = cx - dest.posX; - int dz = cz - dest.posZ; - - int absoluteDir = 0; - if (Math.abs(dx) < Math.abs(dz)) { // reversed from findBestDirectionTowards - absoluteDir = (dx >= 0) ? 2 : 0; - } else { - absoluteDir = (dz >= 0) ? 3 : 1; - } - int relativeDir = (absoluteDir + 4 - this.coordBaseMode) % 4; - - - //System.out.println("Determining second direction! center is at " + cx + ", " + cz + " and dest is at " + dest + " offset is " + dx + ", " + dz + " so the best absolute direction is " + absoluteDir + " and relative dir is " + relativeDir); - - // return offset dir - return relativeDir; - } - - private int findThirdDirectionTowards(ChunkCoordinates dest) { - int first = this.findBestDirectionTowards(dest); - int second = this.findSecondDirectionTowards(dest); - - if (first == 0 && second == 1) { - return 3; - } else if (first == 1 && second == 3) { - return 0; - } else { - return 1; - } - } - - private boolean buildContinueTowerTowards(List list, Random rand, ChunkCoordinates dest, int direction, int howFar) { - ChunkCoordinates opening = this.getValidOpeningCC(rand, direction); - - // adjust opening towards dest.posY if we are getting close to dest - int adjustmentRange = 60; - if (this.isWithinRange(dest.posX, dest.posZ, this.boundingBox.minX + 6, this.boundingBox.minZ + 6, adjustmentRange)) { - opening.posY = this.adjustOpening(opening.posY, dest); - } - - //System.out.println("original direction is " + direction); - - - direction += this.coordBaseMode; - direction %= 4; - - // build towards - ChunkCoordinates tc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, howFar, direction); - - //System.out.println("Our coord mode is " + this.getCoordBaseMode() + ", and direction is " + direction + ", so our door is going to be at " + opening + " and the new tower will appear at " + tc); - - // find start - StructureComponent start = (StructureComponent)list.get(0); - - //System.out.println("Testing range, uncorrected center is at " + centerX + ", " + centerZ); - - int centerX = ((start.getBoundingBox().minX + 128) >> 8) << 8; - int centerZ = ((start.getBoundingBox().minZ + 128) >> 8) << 8; - - if (isWithinRange(centerX, centerZ, tc.posX, tc.posZ, 128)) { - - MazeTower13 sTower = new MazeTower13(rand, this.getComponentType() + 1, tc.posX, tc.posY, tc.posZ, this.type, direction); - - StructureBoundingBox largerBB = new StructureBoundingBox(sTower.getBoundingBox()); - - largerBB.minX -= 6; - largerBB.minZ -= 6; - largerBB.maxX += 6; - largerBB.maxZ += 6; - largerBB.minY = 0; - largerBB.maxY = 255; - - StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); - - if (intersect == null) { - //System.out.println("tower success!"); - list.add(sTower); - sTower.buildTowards(this, list, rand, dest); - - // add bridge - ChunkCoordinates bc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, 1, direction); - Bridge bridge = new Bridge(this.getComponentType() + 1, bc.posX, bc.posY, bc.posZ, howFar - 7, direction); - list.add(bridge); - bridge.buildComponent(this, list, rand); - - // opening - addOpening(opening.posX, opening.posY + 1, opening.posZ, direction); - - return true; - } else { - //System.out.println("tower blocked"); - return false; - } - } else { - //System.out.println("tower out of range"); - return false; - } - } - - - protected boolean buildDamagedTower(List list, Random rand, int direction) { - ChunkCoordinates opening = this.getValidOpeningCC(rand, direction); - - direction += this.coordBaseMode; - direction %= 4; - - int howFar = 14 + rand.nextInt(24); - // build towards - ChunkCoordinates tc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, howFar, direction); - - // what type of tower? - MazeTower13 eTower = makeNewDamagedTower(rand, direction, tc); - - StructureBoundingBox largerBB = new StructureBoundingBox(eTower.getBoundingBox()); - - largerBB.minX -= 6; - largerBB.minZ -= 6; - largerBB.maxX += 6; - largerBB.maxZ += 6; - - StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); - - if (intersect == null) { - //System.out.println("wreck tower success! tower is at " + tc.posX + ", " + tc.posY + ", " + tc.posZ); - list.add(eTower); - eTower.buildComponent(this, list, rand); - // add bridge - ChunkCoordinates bc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, 1, direction); - Bridge bridge = new Bridge(this.getComponentType() + 1, bc.posX, bc.posY, bc.posZ, howFar - 7, direction); - list.add(bridge); - bridge.buildComponent(this, list, rand); - - // opening - addOpening(opening.posX, opening.posY + 1, opening.posZ, direction); - - return true; - } else { - //System.out.println("damaged tower blocked"); - return false; - } - } - - protected MazeTower13 makeNewDamagedTower(Random rand, int direction, ChunkCoordinates tc) { - return new DamagedTower(rand, this.getComponentType() + 1, tc.posX, tc.posY, tc.posZ, direction); - } - - private int adjustOpening(int posY, ChunkCoordinates dest) { - int openY = posY; - - int realOpeningY = this.getYWithOffset(openY); - if (realOpeningY - dest.posY < 12) { - // if it is too low, move it to the top floor - openY = this.height - 9; - } else if (dest.posY - realOpeningY < 12) { - // if the opening is too high, move it to the bottom floor - openY = 0; - } - - return openY; - } - - private boolean buildEndTowerTowards(List list, Random rand, ChunkCoordinates dest, int direction, int howFar) { - ChunkCoordinates opening = this.getValidOpeningCC(rand, direction); - - // adjust opening towards dest.posY - opening.posY = this.adjustOpening(opening.posY, dest); - - direction += this.coordBaseMode; - direction %= 4; - - // build towards - ChunkCoordinates tc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, howFar, direction); - - //System.out.println("Our coord mode is " + this.getCoordBaseMode() + ", and direction is " + direction + ", so our door is going to be at " + opening + " and the new tower will appear at " + tc); - - // what type of tower? - MazeTower13 eTower; - if (this.type == 0) { - eTower = new EntranceTower(rand, this.getComponentType() + 1, tc.posX, tc.posY, tc.posZ, direction); - } else { - eTower = new BellTower21(rand, this.getComponentType() + 1, tc.posX, tc.posY, tc.posZ, direction); - } - - StructureBoundingBox largerBB = new StructureBoundingBox(eTower.getBoundingBox()); - - largerBB.minX -= 6; - largerBB.minZ -= 6; - largerBB.maxX += 6; - largerBB.maxZ += 6; - - StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); - - if (intersect == null) { - //System.out.println("entrance tower success! tower is at " + tc.posX + ", " + tc.posY + ", " + tc.posZ + " and dest is " + dest.posX + ", " + dest.posY + ", " + dest.posZ); - list.add(eTower); - eTower.buildComponent(this, list, rand); - // add bridge - ChunkCoordinates bc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, 1, direction); - Bridge bridge = new Bridge(this.getComponentType() + 1, bc.posX, bc.posY, bc.posZ, howFar - 7, direction); - list.add(bridge); - bridge.buildComponent(this, list, rand); - - // opening - addOpening(opening.posX, opening.posY + 1, opening.posZ, direction); - - return true; - } else { - //System.out.println("end tower blocked"); - return false; - } - - } - - private boolean isWithinRange(int centerX, int centerZ, int posX, int posZ, int range) { - boolean inRange = Math.abs(centerX - posX) < range && Math.abs(centerZ - posZ) < range; - - if (!inRange) { -// System.out.println("Tested range, center is at " + centerX + ", " + centerZ + " and tower is " + posX + ", " + posZ + " so distance is " + Math.max(Math.abs(centerX - posX), Math.abs(centerZ - posZ))); - } - - return inRange; - } - - /** - * Gets a random position in the specified direction that connects to a floor currently in the tower. - */ - public ChunkCoordinates getValidOpeningCC(Random rand, int direction) { - int floors = (this.height / 8); - - // for directions 0 or 2, the wall lies along the z axis - if (direction == 0 || direction == 2) { - int rx = direction == 0 ? 12 : 0; - int rz = 6; - int ry = rand.nextInt(floors) * 8; - - return new ChunkCoordinates(rx, ry, rz); - } - - // for directions 1 or 3, the wall lies along the x axis - if (direction == 1 || direction == 3) { - int rx = 6; - int rz = direction == 1 ? 12 : 0; - int ry = rand.nextInt(floors) * 8; - - return new ChunkCoordinates(rx, ry, rz); - } - - - return new ChunkCoordinates(0, 0, 0); - } - - /** - * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. - */ - protected ChunkCoordinates offsetTowerCCoords(int x, int y, int z, int howFar, int direction) { - - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - - switch (direction) { - case 0: - dx += howFar; - break; - case 1: - dz += howFar; - break; - case 2: - dx -= howFar; - break; - case 3: - dz -= howFar; - break; - } - - // ugh? - return new ChunkCoordinates(dx, dy, dz); - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - // walls - fillWithRandomizedBlocks(world, sbb, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1, false, rand, deco.randomBlocks); - - // stone to ground - for (int x = 0; x < this.size; x++) - { - for (int z = 0; z < this.size; z++) - { - this.func_151554_b(world, deco.blockID, deco.blockMeta, x, -1, z, sbb); - } - - } - - // add branching runes - int numBranches = 2 + decoRNG.nextInt(4) + + decoRNG.nextInt(3); - for (int i = 0; i < numBranches; i++) { - makeGlyphBranches(world, decoRNG, this.getGlyphMeta(), sbb); - } - - // floors - addFloors(world, decoRNG, sbb); - - // openings - makeOpenings(world, sbb); - - - return true; - } - - public int getGlyphMeta() { - return type; - } - - private void addFloors(World world, Random rand, StructureBoundingBox sbb) { - // only add floors up to highest opening - int floors = (this.highestOpening / 8) + 1; - - for (int i = 1; i < floors; i++) { - this.fillWithMetadataBlocks(world, sbb, 1, i * 8, 1, 11, i * 8, 11, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - - // stairs - addStairsDown(world, sbb, (i + 2) % 4, i * 8); - } - - if (hasAccessibleRoof()) { - // add stairs to roof - addStairsDown(world, sbb, (floors + 2) % 4, this.height - 1); - } - - } - - protected boolean hasAccessibleRoof() { - return this.height - this.highestOpening < 9; - } - - private void addStairsDown(World world, StructureBoundingBox sbb, int rotation, int y) { - // top flight - for (int i = 0; i < 4; i++) { - int sx = 8 - i; - int sy = y - i; - int sz = 9; - - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), sx, sy, sz, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx, sy - 1, sz, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), sx, sy, sz - 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx, sy - 1, sz - 1, rotation, sbb); - this.fillAirRotated(world, sbb, sx, sy + 1, sz - 1, sx, sy + 3, sz, rotation); - } - // landing - this.fillBlocksRotated(world, sbb, 3, y - 4, 8, 4, y - 4, 9, deco.blockID, deco.blockMeta, rotation); - - - // bottom flight - for (int i = 0; i < 4; i++) { - int sx = 4; - int sy = y - i - 4; - int sz = 7 - i; - - this.placeBlockRotated(world, deco.stairID, getStairMeta(1 + rotation), sx, sy, sz, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx, sy - 1, sz, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(1 + rotation), sx - 1, sy, sz, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, sx - 1, sy - 1, sz, rotation, sbb); - this.fillAirRotated(world, sbb, sx, sy + 1, sz, sx - 1, sy + 3, sz, rotation); - } - - } - - /** - * Make an opening in this tower for a door. - */ - @Override - protected void makeDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { - // nullify sky light - //nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); - - // clear the door - if (dx == 0 || dx == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 4, dz + 2, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - //this.fillWithAir(world, sbb, dx, dy, dz - 1, dx, dy + 3, dz + 1); - this.fillWithMetadataBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 3, dz + 1, TFBlocks.castleDoor, this.getGlyphMeta(), Blocks.air, 0, false); - } - if (dz == 0 || dz == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 4, dz, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - //this.fillWithAir(world, sbb, dx - 1, dy, dz, dx + 1, dy + 3, dz); - this.fillWithMetadataBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 3, dz, TFBlocks.castleDoor, this.getGlyphMeta(), Blocks.air, 0, false); - } - } - } - - - public static class EntranceTower extends MazeTower13 { - - public EntranceTower() { } - - public EntranceTower(Random rand, int i, int x, int y, int z, int direction) { - super(rand, i, x, y, z, 3, 2, 0, direction); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - // add foundation - Foundation13 foundation = new Foundation13(rand, 4, this); - list.add(foundation); - foundation.buildComponent(this, list, rand); - - // add roof - StructureTFComponent roof = new Roof13Peaked(rand, 4, this); - list.add(roof); - roof.buildComponent(this, list, rand); - - // how many floors until the bottom? - int missingFloors = (this.boundingBox.minY - 127) / 8; - - // place half on the bottom - int bottomFloors = missingFloors / 2; - // how many are left for the middle? - int middleFloors = missingFloors - bottomFloors; - - // what direction can we put the side tower in, if any? - int direction = 1; - int howFar = 20; - if (!this.buildSideTower(list, rand, middleFloors + 1, direction, howFar)) { - direction = 3; - if (!this.buildSideTower(list, rand, middleFloors + 1, direction, howFar)) { - direction = 0; - if (!this.buildSideTower(list, rand, middleFloors + 1, direction, howFar)) { - // side tower no worky - } - } - } - - // add bottom tower - int brDirection = (direction + this.coordBaseMode) % 4; - EntranceBottomTower eTower = new EntranceBottomTower(rand, this.getComponentType() + 1, this.boundingBox.minX + 6, this.boundingBox.minY - (middleFloors) * 8, this.boundingBox.minZ + 6, bottomFloors + 1, bottomFloors, (brDirection + 2) % 4); - list.add(eTower); - eTower.buildComponent(this, list, rand); - - // add bridge to bottom - ChunkCoordinates opening = this.getValidOpeningCC(rand, direction); - opening.posY -= middleFloors * 8; - - ChunkCoordinates bc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, 1, brDirection); - Bridge bridge = new Bridge(this.getComponentType() + 1, bc.posX, bc.posY, bc.posZ, howFar - 7, brDirection); - list.add(bridge); - bridge.buildComponent(this, list, rand); - } - - private boolean buildSideTower(List list, Random rand, int middleFloors, int direction, int howFar) { - ChunkCoordinates opening = this.getValidOpeningCC(rand, direction); - - direction += this.coordBaseMode; - direction %= 4; - - // build towards - ChunkCoordinates tc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, howFar, direction); - - //System.out.println("Our coord mode is " + this.getCoordBaseMode() + ", and direction is " + direction + ", so our door is going to be at " + opening + " and the new tower will appear at " + tc); - - EntranceSideTower eTower = new EntranceSideTower(rand, this.getComponentType() + 1, tc.posX, tc.posY, tc.posZ, middleFloors, middleFloors - 1, direction); - - StructureBoundingBox largerBB = new StructureBoundingBox(eTower.getBoundingBox()); - - largerBB.minX -= 6; - largerBB.minZ -= 6; - largerBB.maxX += 6; - largerBB.maxZ += 6; - - StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); - - if (intersect == null) { - list.add(eTower); - eTower.buildComponent(this, list, rand); - // add bridge - ChunkCoordinates bc = this.offsetTowerCCoords(opening.posX, opening.posY, opening.posZ, 1, direction); - Bridge bridge = new Bridge(this.getComponentType() + 1, bc.posX, bc.posY, bc.posZ, howFar - 7, direction); - list.add(bridge); - bridge.buildComponent(this, list, rand); - - // opening - addOpening(opening.posX, opening.posY + 1, opening.posZ, direction); - - return true; - } else { - System.out.println("side entrance tower blocked"); - return false; - } - - } - - /** - * Gets a random position in the specified direction that connects to a floor currently in the tower. - */ - public ChunkCoordinates getValidOpeningCC(Random rand, int direction) { - // for directions 0 or 2, the wall lies along the z axis - if (direction == 0 || direction == 2) { - int rx = direction == 0 ? 12 : 0; - int rz = 6; - int ry = 0; - - return new ChunkCoordinates(rx, ry, rz); - } - - // for directions 1 or 3, the wall lies along the x axis - if (direction == 1 || direction == 3) { - int rx = 6; - int rz = direction == 1 ? 12 : 0; - int ry = 0; - - return new ChunkCoordinates(rx, ry, rz); - } - - - return new ChunkCoordinates(0, 0, 0); - } - - - } - - public static class EntranceSideTower extends MazeTower13 { - public EntranceSideTower() {} - - public EntranceSideTower(Random rand, int i, int x, int y, int z, int floors, int entranceFloor, int direction) { - super(rand, i, x, y, z, floors, entranceFloor, 0, direction); - - addOpening(0, 1, size / 2, 2); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - // add foundation - Foundation13 foundation = new Foundation13(rand, 4, this); - list.add(foundation); - foundation.buildComponent(this, list, rand); - - // add roof - StructureTFComponent roof = new Roof13Peaked(rand, 4, this); - list.add(roof); - roof.buildComponent(this, list, rand); - } - - } - - public static class EntranceBottomTower extends MazeTower13 { - public EntranceBottomTower() {} - - public EntranceBottomTower(Random rand, int i, int x, int y, int z, int floors, int entranceFloor, int direction) { - super(rand, i, x, y, z, floors, entranceFloor, 0, direction); - -// addOpening(12, 1, size / 2, 0); -// addOpening(size / 2, 1, 0, 1); -// addOpening(0, 1, size / 2, 2); -// addOpening(size / 2, 1, 12, 3); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - // stairs - addStairs(list, rand, this.getComponentType() + 1, this.size - 1, 1, size / 2, 0); - addStairs(list, rand, this.getComponentType() + 1, 0, 1, size / 2, 2); - addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, 0, 3); - addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, this.size - 1, 1); - - } - - - /** - * Add some stairs leading to this tower - */ - private boolean addStairs(List list, Random rand, int index, int x, int y, int z, int rotation) { - // add door - this.addOpening(x, y, z, rotation); - - int direction = (getCoordBaseMode() + rotation) % 4; - ChunkCoordinates dx = offsetTowerCCoords(x, y, z, 0, direction); - - EntranceStairs stairs = new EntranceStairs(index, dx.posX, dx.posY, dx.posZ, direction); - - list.add(stairs); - stairs.buildComponent(list.get(0), list, rand); - return true; - } - - protected boolean hasAccessibleRoof() { - return false; - } - - } - - /** - * Stair blocks heading to the entrance tower doors - */ - public static class EntranceStairs extends StructureTFComponent { - - public EntranceStairs() {} - - public EntranceStairs(int index, int x, int y, int z, int direction) { - this.setCoordBaseMode(direction); - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox2(x, y, z, 0, -1, -5, 12, 0, 12, direction); - } - - @SuppressWarnings({ "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - - int size = 13; - - for (int x = 1; x < size; x++) { - - this.placeStairs(world, sbb, x, 1 - x, 5, 2); - - for (int z = 0; z <= x; z++) { - - if (z > 0 && z <= size / 2) { - this.placeStairs(world, sbb, x, 1 - x, 5 - z, 2); - this.placeStairs(world, sbb, x, 1 - x, 5 + z, 2); - } - - if (x <= size / 2) { - this.placeStairs(world, sbb, z, 1 - x, 5 - x, 1); - this.placeStairs(world, sbb, z, 1 - x, 5 + x, 3); - } - } - } - - this.func_151554_b(world, deco.blockID, deco.blockMeta, 0, 0, 5, sbb); - - - return true; - } - - private void placeStairs(World world, StructureBoundingBox sbb, int x, int y, int z, int stairMeta) { - if (this.getBlockAtCurrentPosition(world, x, y, z, sbb).isReplaceable(world, x, y, z)) { - //this.placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, x, y, z, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(stairMeta), x, y, z, sbb); - this.func_151554_b(world, deco.blockID, deco.blockMeta, x, y - 1, z, sbb); - } - } - - - } - - public static class BellTower21 extends MazeTower13 { - - private static final int FLOORS = 8; - - public BellTower21() { } - - public BellTower21(Random rand, int i, int x, int y, int z, int direction) { - super(rand, i, x, y, z, FLOORS, 1, 1, direction); - this.size = 21; - int floors = FLOORS; - this.height = floors * 8 + 1; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox2(x, y, z, -6, -8, -this.size / 2, this.size - 1, this.height, this.size - 1, direction); - this.openings.clear(); - addOpening(0, 9, size / 2, 2); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - // add foundation - BellFoundation21 foundation = new BellFoundation21(rand, 4, this); - list.add(foundation); - foundation.buildComponent(this, list, rand); - - // add roof - StructureTFComponent roof = new Roof13Crenellated(rand, 4, this); - list.add(roof); - roof.buildComponent(this, list, rand); - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - super.addComponentParts(world, rand, sbb); - - // openings! - Block fieldBlock = TFBlocks.forceField; - int fieldMeta = 4; - for (int rotation = 0; rotation < 4; rotation++) { - int y = 48; - for (int x = 5; x < this.size - 4; x += 2) { -// for (int wy = 0; wy < 15; wy++) { -// fieldMeta = rand.nextInt(4) + 1; -// this.placeBlockRotated(world, fieldBlock, fieldMeta, x, y + wy, 0, rotation, sbb); -// } -// fieldMeta = rand.nextInt(5); - this.fillBlocksRotated(world, sbb, x, y, 0, x, y + 14, 0, fieldBlock, fieldMeta, rotation); - } - y = 24; - for (int x = 1; x < this.size - 1; x += 8) { -// for (int wy = 0; wy < 15; wy++) { -// fieldMeta = rand.nextInt(4) + 1; -// this.placeBlockRotated(world, fieldBlock, fieldMeta, x, y + wy, 0, rotation, sbb); -// fieldMeta = rand.nextInt(4) + 1; -// this.placeBlockRotated(world, fieldBlock, fieldMeta, x + 2, y + wy, 0, rotation, sbb); -// } -// fieldMeta = rand.nextInt(5); - this.fillBlocksRotated(world, sbb, x, y, 0, x, y + 14, 0, fieldBlock, fieldMeta, rotation); -// fieldMeta = rand.nextInt(5); - this.fillBlocksRotated(world, sbb, x + 2, y, 0, x + 2, y + 14, 0, fieldBlock, fieldMeta, rotation); - } - } - - // sign - this.placeSignAtCurrentPosition(world, 7, 9, 8, "Parkour area 2", "mini-boss 1", sbb); - - return true; - } - } - - public static class DamagedTower extends MazeTower13 { - - public DamagedTower() { } - - public DamagedTower(Random rand, int i, int x, int y, int z, int direction) { - super(rand, i, x, y, z, 2, direction); //TODO: change rune type - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - - // add foundation - Foundation13 foundation = new Foundation13(rand, 0, this); - list.add(foundation); - foundation.buildComponent(this, list, rand); - - // add thorns - Foundation13 thorns = new Foundation13Thorns(rand, 0, this); - list.add(thorns); - thorns.buildComponent(this, list, rand); - -// // add roof -// StructureTFComponent roof = rand.nextBoolean() ? new Roof13Conical(rand, 4, this) : new Roof13Crenellated(rand, 4, this); -// list.add(roof); -// roof.buildComponent(this, list, rand); - - - // keep on building? - this.buildNonCriticalTowers(parent, list, rand); - } - - - protected MazeTower13 makeNewDamagedTower(Random rand, int direction, ChunkCoordinates tc) { - return new WreckedTower(rand, this.getComponentType() + 1, tc.posX, tc.posY, tc.posZ, direction); - } - - - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - super.addComponentParts(world, rand, sbb); - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - this.destroyTower(world, decoRNG, sbb); - - return true; - } - - public void destroyTower(World world, Random rand, StructureBoundingBox sbb) { - - // make list of destroyed areas - ArrayList areas = makeInitialDestroyList(rand); - - boolean hitDeadRock = false; - - // go down from the top of the tower to the ground, taking out rectangular chunks - //for (int y = this.boundingBox.maxY; y > this.boundingBox.minY; y--) { - for (int y = this.boundingBox.maxY; !hitDeadRock && y > 64; y--) { - for (int x = this.boundingBox.minX - 2; x <= this.boundingBox.maxX + 2; x++) { - for (int z = this.boundingBox.minZ - 2; z <= this.boundingBox.maxZ + 2; z++) { - if (sbb.isVecInside(x, y, z)) { - if (world.getBlock(x, y, z) == TFBlocks.deadrock) { - hitDeadRock = true; - } - determineBlockDestroyed(world, areas, y, x, z); - } - } - } - - // check to see if any of our DestroyAreas are entirely above the current y value - DestroyArea removeArea = null; - - for (DestroyArea dArea : areas) { - if (dArea == null || dArea.isEntirelyAbove(y)) { - removeArea = dArea; - } - } - // if so, replace them with new ones - if (removeArea != null) { - areas.remove(removeArea); - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, y, areas)); - - } - } - } - - protected ArrayList makeInitialDestroyList(Random rand) { - ArrayList areas = new ArrayList(2); - - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); - return areas; - } - - protected void determineBlockDestroyed(World world, ArrayList areas, int y, int x, int z) { - for (DestroyArea dArea : areas) { - if (dArea != null && dArea.isVecInside(x, y, z)) { - world.setBlockToAir(x, y, z); - } - } - } - - } - - /** - * An area that we're going to destroy. Default is just a StructureBoundingBox - */ - public static class DestroyArea { - - StructureBoundingBox destroyBox; - - public DestroyArea(StructureBoundingBox tower, Random rand, int y) { - // make a 4x4 area that's entirely within the tower bounding box - - int bx = tower.minX - 2 + rand.nextInt(tower.getXSize()); - int bz = tower.minZ - 2 + rand.nextInt(tower.getZSize()); - - this.destroyBox = new StructureBoundingBox(bx, y - 10, bz, bx + 4, y, bz + 4); - } - - public boolean isEntirelyAbove(int y) { - return this.destroyBox.minY > y; - } - - public boolean isVecInside(int x, int y, int z) { - return destroyBox.isVecInside(x, y, z); - } - - /** - * construct a new area that does not intersect any other areas in the list - */ - public static DestroyArea createNonIntersecting(StructureBoundingBox tower, Random rand, int y, ArrayList otherAreas) { - int attempts = 100; - - DestroyArea area = null; - for (int i = 0; i < attempts && area == null; i++) { - DestroyArea testArea = new DestroyArea(tower, rand, y); - - if (otherAreas.size() == 0) { - area = testArea; - } else { - for (DestroyArea otherArea : otherAreas) { - if (otherArea == null || !testArea.intersectsWith(otherArea)) { - area = testArea; - } - } - } - } - return area; - } - - /** - * We check if the box would intersect even if it was one block larger in the x and z directions - */ - private boolean intersectsWith(DestroyArea otherArea) { - return this.destroyBox.intersectsWith(otherArea.destroyBox.minX - 1, otherArea.destroyBox.minZ - 1, otherArea.destroyBox.maxX + 1, otherArea.destroyBox.maxX + 1); - } - } - - public static class WreckedTower extends DamagedTower { - - public WreckedTower() { } - - public WreckedTower(Random rand, int i, int x, int y, int z, int direction) { - super(rand, i, x, y, z, direction); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - -// // add foundation -// Foundation13 foundation = new Foundation13(rand, 4, this); -// list.add(foundation); -// foundation.buildComponent(this, list, rand); - - - // add thorns - Foundation13 thorns = new Foundation13Thorns(rand, 0, this); - list.add(thorns); - thorns.buildComponent(this, list, rand); - - -// // add roof -// StructureTFComponent roof = rand.nextBoolean() ? new Roof13Conical(rand, 4, this) : new Roof13Crenellated(rand, 4, this); -// list.add(roof); -// roof.buildComponent(this, list, rand); - - - // keep on building? -// this.buildNonCriticalTowers(parent, list, rand); - } - - public int getGlyphMeta() { - return 1; - } - - - protected void determineBlockDestroyed(World world, ArrayList areas, int y, int x, int z) { - boolean isInside = false; - for (DestroyArea dArea : areas) { - if (dArea != null && dArea.isVecInside(x, y, z)) { - isInside = true; - } - } - - if (!isInside) { - world.setBlockToAir(x, y, z); - } - - } - - - protected ArrayList makeInitialDestroyList(Random rand) { - ArrayList areas = new ArrayList(2); - - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); - areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); - return areas; - } - - - } - - - public static class Bridge extends StructureTFComponent { - public Bridge() {} - - public Bridge(int i, int x, int y, int z, int length, int direction) { - this.setCoordBaseMode(direction); - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox2(x, y, z, 0, -1, -3, length - 1, 5, 6, direction); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - int length = (this.coordBaseMode == 0 || this.coordBaseMode == 2) ? this.boundingBox.maxX - this.boundingBox.minX : this.boundingBox.maxZ - this.boundingBox.minZ; - - // span - fillWithRandomizedBlocks(world, sbb, 0, 0, 0, length, 1, 6, false, rand, deco.randomBlocks); - // rails - fillWithRandomizedBlocks(world, sbb, 0, 1, 0, length, 2, 0, false, rand, deco.randomBlocks); - fillWithRandomizedBlocks(world, sbb, 0, 1, 6, length, 2, 6, false, rand, deco.randomBlocks); - - // supports - int l3 = length / 3; - for (int i = 0; i < l3; i++) { - int sl = l3 - (int) (MathHelper.cos((float)(l3 - i) / (float)l3 * 1.6F) * (float)l3); // this could be better, maybe? - fillWithRandomizedBlocks(world, sbb, i, -sl, 0, i, 0, 0, false, rand, deco.randomBlocks); - fillWithRandomizedBlocks(world, sbb, i, -sl, 6, i, 0, 6, false, rand, deco.randomBlocks); - fillWithRandomizedBlocks(world, sbb, length - i, -sl, 0, length - i, 0, 0, false, rand, deco.randomBlocks); - fillWithRandomizedBlocks(world, sbb, length - i, -sl, 6, length - i, 0, 6, false, rand, deco.randomBlocks); - } - - // doorframes - this.fillWithMetadataBlocks(world, sbb, 0, 2, 1, 0, 7, 1, deco.pillarID, deco.pillarMeta, deco.pillarID, deco.pillarMeta, false); - this.fillWithMetadataBlocks(world, sbb, 0, 2, 5, 0, 7, 5, deco.pillarID, deco.pillarMeta, deco.pillarID, deco.pillarMeta, false); - this.fillWithMetadataBlocks(world, sbb, 0, 6, 2, 0, 6, 4, deco.accentID, deco.accentMeta, deco.accentID, deco.accentMeta, false); - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, 0, 7, 3, sbb); - - this.fillWithMetadataBlocks(world, sbb, length, 2, 1, length, 7, 1, deco.pillarID, deco.pillarMeta, deco.pillarID, deco.pillarMeta, false); - this.fillWithMetadataBlocks(world, sbb, length, 2, 5, length, 7, 5, deco.pillarID, deco.pillarMeta, deco.pillarID, deco.pillarMeta, false); - this.fillWithMetadataBlocks(world, sbb, length, 6, 2, length, 6, 4, deco.accentID, deco.accentMeta, deco.accentID, deco.accentMeta, false); - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, length, 7, 3, sbb); - - return true; - } - - } - - public static class Roof9Crenellated extends StructureTFComponent { - - public Roof9Crenellated() {} - - public Roof9Crenellated(Random rand, int i, StructureTFComponent sideTower) { - super(i); - - int height = 5; - - this.setCoordBaseMode(sideTower.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - for (int rotation = 0; rotation < 4; rotation++) { - this.fillBlocksRotated(world, sbb, 0, -1, 0, 2, 3, 2, deco.blockID, deco.blockMeta, rotation); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 2, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 2, -2, 1, rotation, sbb); - - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 3, 0, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 3, 1, 1, rotation, sbb); - - this.fillBlocksRotated(world, sbb, 4, 0, 0, 5, 3, 2, deco.blockID, deco.blockMeta, rotation); - - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 6, 0, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 6, 1, 1, rotation, sbb); - - this.fillBlocksRotated(world, sbb, 7, 0, 0, 8, 3, 2, deco.blockID, deco.blockMeta, rotation); - - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 9, 0, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 9, 1, 1, rotation, sbb); - } - - - return true; - } - - - } - - /** - * Pointy cone roof with variable height - */ - public static class Roof13Conical extends StructureTFComponent { - - public int slope; - - public Roof13Conical() {} - - public Roof13Conical(Random rand, int i, StructureTFComponent sideTower) { - super(i); - - this.slope = 2 + rand.nextInt(3) + rand.nextInt(3); - - int height = slope * 4; - - this.setCoordBaseMode(sideTower.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); - - } - - /** - * Save to NBT - */ - @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("slope", this.slope); - } - - /** - * Load from NBT - */ - @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.slope = par1NBTTagCompound.getInteger("slope"); - } - - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - for (int rotation = 0; rotation < 4; rotation++) { - this.fillBlocksRotated(world, sbb, 0, -1, 0, 3, 2, 3, deco.blockID, deco.blockMeta, rotation); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 2, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 2, -2, 1, rotation, sbb); - - this.fillBlocksRotated(world, sbb, 4, 0, 1, 12, 1, 1, deco.blockID, deco.blockMeta, rotation); - - // more teeny crenellations - for (int i = 3; i < 13; i += 2) { - this.fillBlocksRotated(world, sbb, i, -1, 1, i, 2, 1, deco.blockID, deco.blockMeta, rotation); - } - - // cone roof - for (int i = 2; i < 9; i++) { - int base = 2 - slope; - if (i < 7) { - this.fillBlocksRotated(world, sbb, i - 1, ((i - 1) * slope) + base, i - 1, i, (i * slope) + base - 1, i, deco.blockID, deco.blockMeta, rotation); - } else { - this.fillBlocksRotated(world, sbb, 16 - i, ((i - 1) * slope) + base, i, 16 - i, (i * slope) + base - 1, i, deco.roofID, deco.roofMeta, rotation); - } - this.fillBlocksRotated(world, sbb, i + 1, ((i - 1) * slope) + base, i, 15 - i, (i * slope) + base - 1, i, deco.roofID, deco.roofMeta, rotation); - } - - // point! - this.fillBlocksRotated(world, sbb, 8, (slope * 6) + 2, 8, 8, (slope * 7) + 2, 8, deco.roofID, deco.roofMeta, rotation); - - } - - - return true; - } - } - - public static class Roof13Crenellated extends StructureTFComponent { - - public Roof13Crenellated() {} - - public Roof13Crenellated(Random rand, int i, StructureTFComponent sideTower) { - super(i); - - int height = 5; - - this.setCoordBaseMode(sideTower.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // assume square - int size = this.boundingBox.maxX - this.boundingBox.minX; - - for (int rotation = 0; rotation < 4; rotation++) { - // corner - this.fillBlocksRotated(world, sbb, 0, -1, 0, 3, 3, 3, deco.blockID, deco.blockMeta, rotation); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 2, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 2, -2, 1, rotation, sbb); - - // walls - this.fillBlocksRotated(world, sbb, 4, 0, 1, size - 4, 1, 1, deco.blockID, deco.blockMeta, rotation); - - // smaller crenellations - for (int x = 5; x < size - 5; x += 4) { - this.fillBlocksRotated(world, sbb, x, 0, 0, x + 2, 3, 2, deco.blockID, deco.blockMeta, rotation); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 1, -1, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 1, -2, 1, rotation, sbb); - } - } - - return true; - } - } - - public static class Roof13Peaked extends StructureTFComponent { - - public Roof13Peaked() {} - - public Roof13Peaked(Random rand, int i, StructureTFComponent sideTower) { - super(i); - - int height = 18; - - this.setCoordBaseMode(sideTower.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); - - } - - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - - // peaky roof, loop unrolled as it was getting dumb - for (int i = 0; i < 3; i++) { - this.fillWithMetadataBlocks(world, sbb, 1, i, i, 15, i, i, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, i, 16 - i, 15, i, 16 - i, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - } - - for (int i = 0; i < 3; i++) { - int dz = 3 + i; - this.fillWithMetadataBlocks(world, sbb, 2, 5 + ((i - 1) * 2), dz, 14, 4 + (i * 2), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 1, dz, 1, 5 + ((i - 1) * 2), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 5 + ((i - 1) * 2), dz - 1, 1, 4 + (i * 2), dz, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 1, dz, 15, 5 + ((i - 1) * 2), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 5 + ((i - 1) * 2), dz - 1, 15, 4 + (i * 2), dz, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - - dz = 13 - i; - this.fillWithMetadataBlocks(world, sbb, 2, 5 + ((i - 1) * 2), dz, 14, 4 + (i * 2), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 1, dz, 1, 5 + ((i - 1) * 2), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 5 + ((i - 1) * 2), dz, 1, 4 + (i * 2), dz + 1, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 1, dz, 15, 5 + ((i - 1) * 2), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 5 + ((i - 1) * 2), dz, 15, 4 + (i * 2), dz + 1, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - } - - for (int i = 0; i < 3; i++) { - int dz = 6 + i; - this.fillWithMetadataBlocks(world, sbb, 2, 12 + ((i - 1) * 3), dz, 14, 11 + (i * 3), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 1, dz, 1, 12 + ((i - 1) * 3), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 12 + ((i - 1) * 3), dz - 1, 1, 11 + (i * 3), dz, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 1, dz, 15, 12 + ((i - 1) * 3), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 12 + ((i - 1) * 3), dz - 1, 15, 11 + (i * 3), dz, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - - dz = 10 - i; - this.fillWithMetadataBlocks(world, sbb, 2, 12 + ((i - 1) * 3), dz, 14, 11 + (i * 3), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 1, dz, 1, 12 + ((i - 1) * 3), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 1, 12 + ((i - 1) * 3), dz, 1, 11 + (i * 3), dz + 1, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 1, dz, 15, 12 + ((i - 1) * 3), dz, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 12 + ((i - 1) * 3), dz, 15, 11 + (i * 3), dz + 1, deco.blockID, deco.blockMeta, deco.blockID, deco.blockMeta, false); - } - - // top roof bobbles - this.fillWithMetadataBlocks(world, sbb, 1, 18, 8, 5, 18, 8, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 11, 18, 8, 14, 18, 8, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 0, 17, 8, 1, 19, 8, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - this.fillWithMetadataBlocks(world, sbb, 15, 17, 8, 16, 19, 8, deco.roofID, deco.roofMeta, deco.roofID, deco.roofMeta, false); - - - - for (int rotation = 1; rotation < 4; rotation += 2) { - // this might be one of my more confusing instances of code recycling - this.fillBlocksRotated(world, sbb, 4, 0, 1, 12, 1, 1, deco.blockID, deco.blockMeta, rotation); - // more teeny crenellations - for (int i = 3; i < 13; i += 2) { - this.fillBlocksRotated(world, sbb, i, -1, 1, i, 2, 1, deco.blockID, deco.blockMeta, rotation); - } - } - - // corners - for (int rotation = 0; rotation < 4; rotation++) { - this.fillBlocksRotated(world, sbb, 0, -1, 0, 3, 2, 3, deco.blockID, deco.blockMeta, rotation); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 2, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, -2, 1, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, 2, -2, 1, rotation, sbb); - } - - - - return true; - } - - } - - public static class Foundation13 extends StructureTFComponent { - protected int groundLevel = -1; - - public Foundation13() { - } - - public Foundation13(Random rand, int i, StructureTFComponent sideTower) { - super(i); - - this.setCoordBaseMode(sideTower.getCoordBaseMode()); - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().minY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().minY, sideTower.getBoundingBox().maxZ + 2); - - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; - } - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // offset bounding box to average ground level - if (this.groundLevel < 0) - { - this.groundLevel = this.getDeadrockLevel(world, sbb); - - if (this.groundLevel < 0) - { - return true; - } - - //System.out.println("Adjusting root bounding box to " + this.boundingBox.minY); - } - - // how tall are we - int height = this.boundingBox.maxY - this.groundLevel; - int mid = height / 2; - - // assume square - int size = this.boundingBox.maxX - this.boundingBox.minX; - - for (int rotation = 0; rotation < 4; rotation++) { - // do corner - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 1, -1, 1, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 2, -1, 1, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 2, -mid, 0, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 1, -1, 2, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 0, -mid, 2, rotation, sbb); - - for (int x = 6; x < (size - 3); x += 4) { - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, x, -1, 1, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, x, -mid, 0, rotation, sbb); - } - - } - - return true; - } - - /** - * Find what y level the local deadrock is. Just check the center of the chunk we're given - */ - protected int getDeadrockLevel(World world, StructureBoundingBox sbb) { - int groundLevel = 256; - - for (int y = 150; y > 0; y--) // is 150 a good place to start? :) - { - int cx = sbb.getCenterX(); - int cz = sbb.getCenterZ(); - - Block block = world.getBlock(cx, y, cz); - if (block == TFBlocks.deadrock) - { - groundLevel = y; - break; - } - } - - return groundLevel; - } - } - - /** - * Foundation that makes thorns go all through the tower - * - * @author benma_000 - * - */ - public static class Foundation13Thorns extends Foundation13 { - - public Foundation13Thorns() {} - - public Foundation13Thorns(Random rand, int i, StructureTFComponent sideTower) { - super(rand, i, sideTower); - - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 5, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 5, sideTower.getBoundingBox().maxX + 5, sideTower.getBoundingBox().maxY, sideTower.getBoundingBox().maxZ + 5); - - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // thorns - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - for (int i = 0; i < 4; i++) { - this.makeThornVine(world, decoRNG, i, sbb); - } - - return true; - } - - private void makeThornVine(World world, Random decoRNG, int rotation, StructureBoundingBox sbb) { - - int x = 3 + decoRNG.nextInt(13); - int z = 3 + decoRNG.nextInt(13); - - int y = this.boundingBox.getYSize() + 5; - - int twist = decoRNG.nextInt(4); - int twistMod = 3 + decoRNG.nextInt(3); - - while (this.getBlockIDRotated(world, x, y, z, rotation, sbb) != TFBlocks.deadrock && this.getYWithOffset(y) > 60) { - this.placeBlockRotated(world, TFBlocks.thorns, 0, x, y, z, rotation, sbb); - // twist vines around the center block - switch (twist) { - case 0: - this.placeBlockRotated(world, TFBlocks.thorns, 0, x + 1, y, z, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x, y, z + 1, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x + 1, y, z + 1, rotation, sbb); - break; - case 1: - this.placeBlockRotated(world, TFBlocks.thorns, 0, x + 1, y, z, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x, y, z - 1, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x + 1, y, z - 1, rotation, sbb); - break; - case 2: - this.placeBlockRotated(world, TFBlocks.thorns, 0, x - 1, y, z, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x, y, z - 1, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x - 1, y, z - 1, rotation, sbb); - break; - case 3: - this.placeBlockRotated(world, TFBlocks.thorns, 0, x - 1, y, z, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x, y, z + 1, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.thorns, 0, x - 1, y, z + 1, rotation, sbb); - break; - } - - if (Math.abs(y % twistMod) == 1) { - // make branch - this.makeThornBranch(world, x, y, z, rotation, sbb); - } - - // twist randomly - if (y % twistMod == 0) { - twist++; - twist = twist % 4; - } - - y--; - } - } - - private void makeThornBranch(World world, int x, int y, int z, int rotation, StructureBoundingBox sbb) { - Random rand = new Random(world.getSeed() + (x * 321534781) ^ (y * 756839) + z); - - // pick a direction - int dir = rand.nextInt(4); - - // initialize direction variables - int dx = 0; - int dz = 0; - - switch (dir) { - case 0: - dx = +1; - break; - case 1: - dz = +1; - break; - case 2: - dx = -1; - break; - case 3: - dz = -1; - break; - } - - // how far do we branch? - int dist = 2 + rand.nextInt(3); - - // check to make sure there's room - int destX = x + (dist * dx); - int destZ = z + (dist * dz); - - if (destX > 0 && destX < this.boundingBox.getXSize() && destZ > 0 && destZ < this.boundingBox.getZSize()) { - for (int i = 0; i < dist; i++) { - // go out that far - int branchMeta = ((dir + rotation + this.coordBaseMode) % 2 == 0) ? 5 : 9; - if (i > 0) { - this.placeBlockRotated(world, TFBlocks.thorns, branchMeta, x + (dx * i), y, z + (dz * i), rotation, sbb); - } - // go up that far - this.placeBlockRotated(world, TFBlocks.thorns, 1, destX, y + i, destZ, rotation, sbb); - // go back half that far - if (i > (dist/ 2)) { - this.placeBlockRotated(world, TFBlocks.thorns, branchMeta, x + (dx * i), y + dist - 1, z + (dz * i), rotation, sbb); - } - - - } - - - } - - } - - - } - - /** - * A larger foundation that comes all the way from the top of a tower - * - * @author benma_000 - * - */ - public static class BellFoundation21 extends Foundation13 { - - public BellFoundation21() {} - - public BellFoundation21(Random rand, int i, StructureTFComponent sideTower) { - super(rand, i, sideTower); - - this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY, sideTower.getBoundingBox().maxZ + 2); - - } - - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // find ground level - if (this.groundLevel < 0) { - this.groundLevel = this.getDeadrockLevel(world, sbb); - } - - // how tall are we? - int height = this.boundingBox.maxY - this.groundLevel; - - int mid = 16; - int low = 32; - - // assume square - int size = this.boundingBox.maxX - this.boundingBox.minX; - - for (int rotation = 0; rotation < 4; rotation++) { - // do corner - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 2, -1, 1, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 2, -mid, 0, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 1, -1, 2, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 0, -mid, 2, rotation, sbb); - - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 1, -low, 1, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 0, -low, 1, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 1, -low, 0, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, 0, -low, 0, rotation, sbb); - - for (int x = 6; x < (size - 3); x += 4) { - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, x, -1, 1, rotation, sbb); - this.fillToGroundRotated(world, deco.blockID, deco.blockMeta, x, -mid, 0, rotation, sbb); - } - - } - - return true; - } - - - } - -} diff --git a/src/main/java/twilightforest/structures/TFMaze.java b/src/main/java/twilightforest/structures/TFMaze.java index bc76b5c25e..1ebf6445e5 100644 --- a/src/main/java/twilightforest/structures/TFMaze.java +++ b/src/main/java/twilightforest/structures/TFMaze.java @@ -1,293 +1,247 @@ package twilightforest.structures; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenCanopyTree; +import twilightforest.enums.MazestoneVariant; +import twilightforest.world.feature.TFGenCanopyTree; +import java.util.Random; /** * This is a maze of cells and walls. - * + *

* The cells are at odd numbered x and y values, and the walls are at even numbered ones. This does make the storage slightly inefficient, but oh wells. - * - * @author Ben * + * @author Ben */ public class TFMaze { - + public int width; // cells wide (x) public int depth; // cells deep (z) - + public int oddBias; // corridor thickness, default 3 public int evenBias; // wall thickness here. NYI - + public int tall; // wall blocks tall public int head;// blocks placed above the maze public int roots;// blocks placed under the maze (used for hedge mazes) - + public int worldX; // set when we first copy the maze into the world public int worldY; public int worldZ; - + public int type; // 1-3 = various sizes hollow hills - - public Block wallBlockID; - public int wallBlockMeta; - - public Block wallVar0ID; - public int wallVar0Meta; - public float wallVarRarity; - - public Block headBlockID; - public int headBlockMeta; - - public Block rootBlockID; - public int rootBlockMeta; - - public Block pillarBlockID; - public int pillarBlockMeta; - - public Block doorBlockID; - public int doorBlockMeta; + + public StructureComponent.BlockSelector wallBlocks; + + public IBlockState wallBlockState; + + public IBlockState headBlockState; + + public IBlockState rootBlockState; + + public IBlockState pillarBlockState; + + public IBlockState doorBlockState; public float doorRarity; - - public Block torchBlockID; - public int torchBlockMeta; + + public IBlockState torchBlockState; public float torchRarity; - + protected int rawWidth; protected int rawDepth; protected int[] storage; - + public static final int OUT_OF_BOUNDS = Integer.MIN_VALUE; public static final int OOB = OUT_OF_BOUNDS; public static final int ROOM = 5; public static final int DOOR = 6; - + public Random rand; - - public TFMaze(int cellsWidth, int cellsDepth) - { + + public TFMaze(int cellsWidth, int cellsDepth) { // default values oddBias = 3; evenBias = 1; tall = 3; head = 0; roots = 0; - wallBlockID = TFBlocks.mazestone; - wallBlockMeta = 2; - rootBlockID = TFBlocks.mazestone; - rootBlockMeta = 0; - torchBlockID = Blocks.torch; - pillarBlockID = null; - - torchBlockMeta = 0; + wallBlockState = TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.CHISELED); + rootBlockState = TFBlocks.maze_stone.getDefaultState(); + torchBlockState = Blocks.TORCH.getDefaultState(); + pillarBlockState = null; + torchRarity = 0.75F; - doorRarity = 0F; - + this.width = cellsWidth; this.depth = cellsDepth; - + this.rawWidth = width * 2 + 1; this.rawDepth = depth * 2 + 1; - storage = new int [rawWidth * rawDepth]; - + storage = new int[rawWidth * rawDepth]; + rand = new Random(); } - + /** * Gets the value from a cell in the maze */ - public int getCell(int x, int z) { - return getRaw(x * 2 + 1, z * 2 + 1); + private int getCell(int x, int z) { + return getRaw(x * 2 + 1, z * 2 + 1); } /** * Puts a value into a cell in the maze */ - public void putCell(int x, int z, int value) { + private void putCell(int x, int z, int value) { putRaw(x * 2 + 1, z * 2 + 1, value); } - + /** * Returns true if the specified cell equals the specified value */ - public boolean cellEquals(int x, int z, int value) - { + private boolean cellEquals(int x, int z, int value) { return getCell(x, z) == value; } - + /** * Gets the wall value, or OUT_OF_BOUNDS if the area is out of bounds or the coordinates are not orthogonally adjacent. */ - public int getWall(int sx, int sz, int dx, int dz) - { - if (dx == sx + 1 && dz == sz) - { + private int getWall(int sx, int sz, int dx, int dz) { + if (dx == sx + 1 && dz == sz) { return getRaw(sx * 2 + 2, sz * 2 + 1); } - if (dx == sx - 1 && dz == sz) - { + if (dx == sx - 1 && dz == sz) { return getRaw(sx * 2 + 0, sz * 2 + 1); } - if (dx == sx && dz == sz + 1) - { + if (dx == sx && dz == sz + 1) { return getRaw(sx * 2 + 1, sz * 2 + 2); } - if (dx == sx && dz == sz - 1) - { + if (dx == sx && dz == sz - 1) { return getRaw(sx * 2 + 1, sz * 2 + 0); } - - System.out.println("Wall check out of bounds; s = " + sx + ", " + sz + "; d = " + dx + ", " + dz); - + + TwilightForestMod.LOGGER.info("Wall check out of bounds; s = {}, {}; d = {}, {}", sx, sz, dx, dz); + return OUT_OF_BOUNDS; } - - public void putWall(int sx, int sz, int dx, int dz, int value) - { - if (dx == sx + 1 && dz == sz) - { + + public void putWall(int sx, int sz, int dx, int dz, int value) { + if (dx == sx + 1 && dz == sz) { putRaw(sx * 2 + 2, sz * 2 + 1, value); } - if (dx == sx - 1 && dz == sz) - { - putRaw(sx * 2 + 0, sz * 2 + 1, value); + if (dx == sx - 1 && dz == sz) { + putRaw(sx * 2 + 0, sz * 2 + 1, value); } - if (dx == sx && dz == sz + 1) - { + if (dx == sx && dz == sz + 1) { putRaw(sx * 2 + 1, sz * 2 + 2, value); } - if (dx == sx && dz == sz - 1) - { + if (dx == sx && dz == sz - 1) { putRaw(sx * 2 + 1, sz * 2 + 0, value); } } - + /** * Returns true if there is a wall there */ - public boolean isWall(int sx, int sz, int dx, int dz) - { + public boolean isWall(int sx, int sz, int dx, int dz) { return getWall(sx, sz, dx, dz) == 0; } /** * Puts a value into the raw storage. */ - public void putRaw(int rawx, int rawz, int value) - { - if (rawx >= 0 && rawx < rawWidth && rawz >= 0 && rawz < rawDepth) - { + public void putRaw(int rawx, int rawz, int value) { + if (rawx >= 0 && rawx < rawWidth && rawz >= 0 && rawz < rawDepth) { storage[rawz * rawWidth + rawx] = value; } } - + /** * Gets a value from raw storage */ - protected int getRaw(int rawx, int rawz) - { - if (rawx < 0 || rawx >= rawWidth || rawz < 0 || rawz >= rawDepth) - { + private int getRaw(int rawx, int rawz) { + if (rawx < 0 || rawx >= rawWidth || rawz < 0 || rawz >= rawDepth) { return OUT_OF_BOUNDS; } else { return storage[rawz * rawWidth + rawx]; } } - + /** * Sets the random seed to a specific value */ public void setSeed(long newSeed) { rand.setSeed(newSeed); } - + /** * Copies the maze into the world by placing walls. */ - public void copyToWorld(World world, int dx, int dy, int dz) - { + public void copyToWorld(World world, int dx, int dy, int dz) { worldX = dx; worldY = dy; worldZ = dz; - - for(int x = 0; x < rawWidth; x++) - { - for(int z = 0; z < rawDepth; z++) - { - if (getRaw(x, z) == 0) - { + + for (int x = 0; x < rawWidth; x++) { + for (int z = 0; z < rawDepth; z++) { + if (getRaw(x, z) == 0) { int mdx = dx + (x / 2 * (evenBias + oddBias)); int mdz = dz + (z / 2 * (evenBias + oddBias)); - - if(isEven(x) && isEven(z)) - { + + if (isEven(x) && isEven(z)) { if (type == 4 && shouldTree(x, z)) { // occasionally make a tree - (new TFGenCanopyTree()).generate(world, rand, mdx, dy, mdz); + (new TFGenCanopyTree()).generate(world, rand, new BlockPos(mdx, dy, mdz)); } else { // make a block! - for(int y = 0; y < head; y++) - { + for (int y = 0; y < head; y++) { putHeadBlock(world, mdx, dy + tall + y, mdz); } - for(int y = 0; y < tall; y++) - { + for (int y = 0; y < tall; y++) { putWallBlock(world, mdx, dy + y, mdz); } - for(int y = 1; y <= roots; y++) - { + for (int y = 1; y <= roots; y++) { putRootBlock(world, mdx, dy - y, mdz); } } } - if(isEven(x) && !isEven(z)) - { + if (isEven(x) && !isEven(z)) { // make a | vertical | wall! - for(int even = 0; even < evenBias; even++) - { - for(int odd = 1; odd <= oddBias; odd++) - { - for(int y = 0; y < head; y++) - { + for (int even = 0; even < evenBias; even++) { + for (int odd = 1; odd <= oddBias; odd++) { + for (int y = 0; y < head; y++) { putHeadBlock(world, mdx + even, dy + tall + y, mdz + odd); } - for(int y = 0; y < tall; y++) - { + for (int y = 0; y < tall; y++) { putWallBlock(world, mdx + even, dy + y, mdz + odd); } - for(int y = 1; y <= roots; y++) - { + for (int y = 1; y <= roots; y++) { putRootBlock(world, mdx + even, dy - y, mdz + odd); } } } } - if(!isEven(x) && isEven(z)) - { + if (!isEven(x) && isEven(z)) { // make a - horizontal - wall! - for(int even = 0; even < evenBias; even++) - { - for(int odd = 1; odd <= oddBias; odd++) - { - for(int y = 0; y < head; y++) - { + for (int even = 0; even < evenBias; even++) { + for (int odd = 1; odd <= oddBias; odd++) { + for (int y = 0; y < head; y++) { putHeadBlock(world, mdx + odd, dy + tall + y, mdz + even); } - for(int y = 0; y < tall; y++) - { + for (int y = 0; y < tall; y++) { putWallBlock(world, mdx + odd, dy + y, mdz + even); } - for(int y = 1; y <= roots; y++) - { + for (int y = 1; y <= roots; y++) { putRootBlock(world, mdx + odd, dy - y, mdz + even); } } @@ -296,67 +250,49 @@ public void copyToWorld(World world, int dx, int dy, int dz) } } } - + placeTorches(world); } - + /** * Copies the maze into the world by carving out empty spaces. */ - public void carveToWorld(World world, int dx, int dy, int dz) - { + public void carveToWorld(World world, int dx, int dy, int dz) { worldX = dx; worldY = dy; worldZ = dz; - - for(int x = 0; x < rawWidth; x++) - { - for(int z = 0; z < rawDepth; z++) - { - if (getRaw(x, z) != 0) - { + + for (int x = 0; x < rawWidth; x++) { + for (int z = 0; z < rawDepth; z++) { + if (getRaw(x, z) != 0) { int mdx = dx + (x / 2 * (evenBias + oddBias)); int mdz = dz + (z / 2 * (evenBias + oddBias)); - if (isEven(x) && isEven(z)) - { + if (isEven(x) && isEven(z)) { // carve a one-block wide pillar - for(int y = 0; y < tall; y++) - { + for (int y = 0; y < tall; y++) { carveBlock(world, mdx, dy + y, mdz); - } - } - else if (isEven(x) && !isEven(z)) - { + } + } else if (isEven(x) && !isEven(z)) { // carve a | vertical | wall - for(int i = 1; i <= oddBias; i++) - { - for(int y = 0; y < tall; y++) - { + for (int i = 1; i <= oddBias; i++) { + for (int y = 0; y < tall; y++) { carveBlock(world, mdx, dy + y, mdz + i); } } - } - else if (!isEven(x) && isEven(z)) - { + } else if (!isEven(x) && isEven(z)) { // carve a - horizontal - wall! - for(int i = 1; i <= oddBias; i++) - { - for(int y = 0; y < tall; y++) - { + for (int i = 1; i <= oddBias; i++) { + for (int y = 0; y < tall; y++) { carveBlock(world, mdx + i, dy + y, mdz); } } - } - else if (!isEven(x) && !isEven(z)) // this should always be true at this point + } else if (!isEven(x) && !isEven(z)) // this should always be true at this point { // carve an open space - for(int mx = 1; mx <= oddBias; mx++) - { - for(int mz = 1; mz <= oddBias; mz++) - { - for(int y = 0; y < tall; y++) - { + for (int mx = 1; mx <= oddBias; mx++) { + for (int mz = 1; mz <= oddBias; mz++) { + for (int y = 0; y < tall; y++) { carveBlock(world, mdx + mx, dy + y, mdz + mz); } } @@ -368,136 +304,102 @@ else if (!isEven(x) && !isEven(z)) // this should always be true at this point placeTorches(world); } - - + + /** - * Copy the maze into a StructureTFComponent + * Copy the maze into a StructureTFComponentOld */ - public void copyToStructure(World world, int dx, int dy, int dz, StructureTFComponent component, StructureBoundingBox sbb) { - for(int x = 0; x < rawWidth; x++) - { - for(int z = 0; z < rawDepth; z++) - { + public void copyToStructure(World world, int dx, int dy, int dz, StructureTFComponentOld component, StructureBoundingBox sbb) { + for (int x = 0; x < rawWidth; x++) { + for (int z = 0; z < rawDepth; z++) { // only draw walls. if the data is 0 the there's a wall - if (getRaw(x, z) == 0) - { + if (getRaw(x, z) == 0) { int mdx = dx + (x / 2 * (evenBias + oddBias)); int mdz = dz + (z / 2 * (evenBias + oddBias)); - - if (evenBias > 1) - { + + if (evenBias > 1) { mdx--; mdz--; } - - if(isEven(x) && isEven(z)) - { + + if (isEven(x) && isEven(z)) { if (type == 4 && shouldTree(x, z)) { // occasionally make a tree // (new TFGenCanopyTree()).generate(world, rand, mdx, dy, mdz); putCanopyTree(world, mdx, dy, mdz, component, sbb); } else { // make a block! - for(int even = 0; even < evenBias; even++) - { - for(int even2 = 0; even2 < evenBias; even2++) - { - for(int y = 0; y < head; y++) - { + for (int even = 0; even < evenBias; even++) { + for (int even2 = 0; even2 < evenBias; even2++) { + for (int y = 0; y < head; y++) { putHeadBlock(world, mdx + even, dy + tall + y, mdz + even2, component, sbb); } - for(int y = 0; y < tall; y++) - { - if (shouldPillar(x, z)) - { + for (int y = 0; y < tall; y++) { + if (shouldPillar(x, z)) { putPillarBlock(world, mdx + even, dy + y, mdz + even2, component, sbb); - } - else - { + } else { putWallBlock(world, mdx + even, dy + y, mdz + even2, component, sbb); } } - for(int y = 1; y <= roots; y++) - { + for (int y = 1; y <= roots; y++) { putRootBlock(world, mdx + even, dy - y, mdz + even2, component, sbb); } } } } } - if(isEven(x) && !isEven(z)) - { + if (isEven(x) && !isEven(z)) { // make a | vertical | wall! - for(int even = 0; even < evenBias; even++) - { - for(int odd = 1; odd <= oddBias; odd++) - { + for (int even = 0; even < evenBias; even++) { + for (int odd = 1; odd <= oddBias; odd++) { makeWallThing(world, dy, component, sbb, mdx, mdz, even, odd); } } } - if(!isEven(x) && isEven(z)) - { + if (!isEven(x) && isEven(z)) { // make a - horizontal - wall! - for(int even = 0; even < evenBias; even++) - { - for(int odd = 1; odd <= oddBias; odd++) - { + for (int even = 0; even < evenBias; even++) { + for (int odd = 1; odd <= oddBias; odd++) { makeWallThing(world, dy, component, sbb, mdx, mdz, odd, even); } } } - } - else if (getRaw(x, z) == DOOR) - { + } else if (getRaw(x, z) == DOOR) { int mdx = dx + (x / 2 * (evenBias + oddBias)); int mdz = dz + (z / 2 * (evenBias + oddBias)); - - if (evenBias > 1) - { + + if (evenBias > 1) { mdx--; mdz--; } - if(isEven(x) && !isEven(z)) - { + if (isEven(x) && !isEven(z)) { // make a | vertical | door! - for(int even = 0; even < evenBias; even++) - { - for(int odd = 1; odd <= oddBias; odd++) - { - for(int y = 0; y < head; y++) - { + for (int even = 0; even < evenBias; even++) { + for (int odd = 1; odd <= oddBias; odd++) { + for (int y = 0; y < head; y++) { putHeadBlock(world, mdx + even, dy + tall + y, mdz + odd, component, sbb); } - for(int y = 0; y < tall; y++) - { + for (int y = 0; y < tall; y++) { putDoorBlock(world, mdx + even, dy + y, mdz + odd, component, sbb); } - for(int y = 1; y <= roots; y++) - { + for (int y = 1; y <= roots; y++) { putRootBlock(world, mdx + even, dy - y, mdz + odd, component, sbb); } } } } - if(!isEven(x) && isEven(z)) - { + if (!isEven(x) && isEven(z)) { // make a - horizontal - door! - for(int even = 0; even < evenBias; even++) - { - for(int odd = 1; odd <= oddBias; odd++) - { - for(int y = 0; y < head; y++) - { + for (int even = 0; even < evenBias; even++) { + for (int odd = 1; odd <= oddBias; odd++) { + for (int y = 0; y < head; y++) { putHeadBlock(world, mdx + odd, dy + tall + y, mdz + even, component, sbb); } - for(int y = 0; y < tall; y++) - { + for (int y = 0; y < tall; y++) { putDoorBlock(world, mdx + odd, dy + y, mdz + even, component, sbb); } - for(int y = 1; y <= roots; y++) - { + for (int y = 1; y <= roots; y++) { putRootBlock(world, mdx + odd, dy - y, mdz + even, component, sbb); } } @@ -506,172 +408,137 @@ else if (getRaw(x, z) == DOOR) } } } - + // instead of putting placetorches in a seperate function, I just put it here. - for(int x = 0; x < rawWidth; x++) - { - for(int z = 0; z < rawDepth; z++) - { - if (getRaw(x, z) == 0) - { + for (int x = 0; x < rawWidth; x++) { + for (int z = 0; z < rawDepth; z++) { + if (getRaw(x, z) == 0) { int mdx = dx + (x / 2 * (evenBias + oddBias)); int mdy = dy + 1; int mdz = dz + (z / 2 * (evenBias + oddBias)); - - if(isEven(x) && isEven(z)) - { - if (shouldTorch(x, z) && component.getBlockAtCurrentPosition(world, mdx, mdy, mdz, sbb) == wallBlockID) - { - component.placeBlockAtCurrentPosition(world, torchBlockID, torchBlockMeta, mdx, mdy, mdz, sbb); + + if (isEven(x) && isEven(z)) { + if (shouldTorch(x, z) && component.getBlockStateFromPos(world, mdx, mdy, mdz, sbb).getBlock() == wallBlockState.getBlock()) { + component.setBlockState(world, torchBlockState, mdx, mdy, mdz, sbb); } } } } } - + } - protected void makeWallThing(World world, int dy, StructureTFComponent component, StructureBoundingBox sbb, int mdx, int mdz, int even, int odd) { - for(int y = 0; y < head; y++) - { + private void makeWallThing(World world, int dy, StructureTFComponentOld component, StructureBoundingBox sbb, int mdx, int mdz, int even, int odd) { + for (int y = 0; y < head; y++) { putHeadBlock(world, mdx + even, dy + tall + y, mdz + odd, component, sbb); } - for(int y = 0; y < tall; y++) - { + for (int y = 0; y < tall; y++) { putWallBlock(world, mdx + even, dy + y, mdz + odd, component, sbb); } - for(int y = 1; y <= roots; y++) - { + for (int y = 1; y <= roots; y++) { putRootBlock(world, mdx + even, dy - y, mdz + odd, component, sbb); } } - + /** * Puts a wall block in the structure, if pillar blocks are properly specified */ - protected void putPillarBlock(World world, int x, int y, int z, StructureTFComponent component, StructureBoundingBox sbb) - { - component.placeBlockAtCurrentPosition(world, pillarBlockID, pillarBlockMeta, x, y, z, sbb); + private void putPillarBlock(World world, int x, int y, int z, StructureTFComponentOld component, StructureBoundingBox sbb) { + component.setBlockState(world, pillarBlockState, x, y, z, sbb); } /** * Puts a wall block in the world, at the specified world coordinates. */ - protected void putWallBlock(World world, int x, int y, int z) - { - world.setBlock(x, y, z, wallBlockID, wallBlockMeta, 2); + private void putWallBlock(World world, int x, int y, int z) { + world.setBlockState(new BlockPos(x, y, z), wallBlockState, 2); } - + /** * Puts a wall block in the structure, at the specified structure coordinates. */ - protected void putWallBlock(World world, int x, int y, int z, StructureTFComponent component, StructureBoundingBox sbb) - { - if (wallVarRarity > 0 && rand.nextFloat() < this.wallVarRarity) - { - component.placeBlockAtCurrentPosition(world, wallVar0ID, wallVar0Meta, x, y, z, sbb); - } - else - { - component.placeBlockAtCurrentPosition(world, wallBlockID, wallBlockMeta, x, y, z, sbb); + private void putWallBlock(World world, int x, int y, int z, StructureTFComponentOld component, StructureBoundingBox sbb) { + if (wallBlocks != null) { + wallBlocks.selectBlocks(rand, x, y, z, true); + component.setBlockState(world, wallBlocks.getBlockState(), x, y, z, sbb); + } else { + component.setBlockState(world, wallBlockState, x, y, z, sbb); } } - + /** * Puts a wall block in the structure, at the specified structure coordinates. */ - protected void putDoorBlock(World world, int x, int y, int z, StructureTFComponent component, StructureBoundingBox sbb) - { - component.placeBlockAtCurrentPosition(world, doorBlockID, doorBlockMeta, x, y, z, sbb); + private void putDoorBlock(World world, int x, int y, int z, StructureTFComponentOld component, StructureBoundingBox sbb) { + component.setBlockState(world, doorBlockState, x, y, z, sbb); } - + /** * Carves a block into the world. * TODO: check what's there? maybe only certain blocks? */ - protected void carveBlock(World world, int x, int y, int z) - { - world.setBlock(x, y, z, Blocks.air, 0, 2); + private void carveBlock(World world, int x, int y, int z) { + world.setBlockState(new BlockPos(x, y, z), Blocks.AIR.getDefaultState(), 2); } - - protected void putHeadBlock(World world, int x, int y, int z) - { - world.setBlock(x, y, z, headBlockID, headBlockMeta, 2); + + private void putHeadBlock(World world, int x, int y, int z) { + world.setBlockState(new BlockPos(x, y, z), headBlockState, 2); } - - protected void putHeadBlock(World world, int x, int y, int z, StructureTFComponent component, StructureBoundingBox sbb) - { - component.placeBlockAtCurrentPosition(world, headBlockID, headBlockMeta, x, y, z, sbb); + + private void putHeadBlock(World world, int x, int y, int z, StructureTFComponentOld component, StructureBoundingBox sbb) { + component.setBlockState(world, headBlockState, x, y, z, sbb); } /** * Puts a root block in the world, at the specified world coordinates. */ - protected void putRootBlock(World world, int x, int y, int z) - { - world.setBlock(x, y, z, rootBlockID, rootBlockMeta, 2); + private void putRootBlock(World world, int x, int y, int z) { + world.setBlockState(new BlockPos(x, y, z), rootBlockState, 2); } - + /** * Puts a root block in the structure, at the specified structure coordinates. */ - protected void putRootBlock(World world, int x, int y, int z, StructureTFComponent component, StructureBoundingBox sbb) - { - component.placeBlockAtCurrentPosition(world, rootBlockID, rootBlockMeta, x, y, z, sbb); + private void putRootBlock(World world, int x, int y, int z, StructureTFComponentOld component, StructureBoundingBox sbb) { + component.setBlockState(world, rootBlockState, x, y, z, sbb); } - + /** * Puts a canopy tree in the world at the specified structure coordinates. */ - protected void putCanopyTree(World world, int x, int y, int z, StructureTFComponent component, StructureBoundingBox sbb) - { - - int wx = component.getXWithOffset(x, z); - int wy = component.getYWithOffset(y); - int wz = component.getZWithOffset(x, z); - - // only place it if we're actually generating the chunk the tree is in (or at least the middle of the tree) - if(sbb.isVecInside(wx, wy, wz)) - { - (new TFGenCanopyTree()).generate(world, rand, wx, wy, wz); - } - } - - /** - * I'm not sure why I made a function of this simple thing. Maybe I need like... a macro? - */ - public final boolean isEven(int n) { - return n % 2 == 0; + private void putCanopyTree(World world, int x, int y, int z, StructureTFComponentOld component, StructureBoundingBox sbb) { + BlockPos pos = component.getBlockPosWithOffset(x, y, z); + + // only place it if we're actually generating the chunk the tree is in (or at least the middle of the tree) + if (sbb.isVecInside(pos)) { + (new TFGenCanopyTree()).generate(world, rand, pos); + } + } + + private final boolean isEven(int n) { + return n % 2 == 0; } - + /** * Called after copyToWorld. Places torches in the maze as appropriate - * - * @param world - * @param dx - * @param dy - * @param dz */ - public void placeTorches(World world) { - + private void placeTorches(World world) { + int torchHeight = 1; - - for(int x = 0; x < rawWidth; x++) - { - for(int z = 0; z < rawDepth; z++) - { - if (getRaw(x, z) == 0) - { + + for (int x = 0; x < rawWidth; x++) { + for (int z = 0; z < rawDepth; z++) { + if (getRaw(x, z) == 0) { int mdx = worldX + (x / 2 * (evenBias + oddBias)); int mdy = worldY + torchHeight; int mdz = worldZ + (z / 2 * (evenBias + oddBias)); - - if(isEven(x) && isEven(z)) - { - if (shouldTorch(x, z) && world.getBlock(mdx, mdy, mdz) == wallBlockID) - { - world.setBlock(mdx, mdy, mdz, torchBlockID, torchBlockMeta, 2); + + BlockPos pos = new BlockPos(mdx, mdy, mdz); + + if (isEven(x) && isEven(z)) { + if (shouldTorch(x, z) && world.getBlockState(pos).getBlock() == wallBlockState.getBlock()) { + world.setBlockState(pos, torchBlockState, 2); } } } @@ -684,58 +551,47 @@ public void placeTorches(World world) { */ public boolean shouldTorch(int rx, int rz) { // if there is out of bounds in any direction, no - if (getRaw(rx + 1, rz) == OOB || getRaw(rx - 1, rz) == OOB || getRaw(rx, rz + 1) == OOB || getRaw(rx, rz - 1) == OOB) - { + if (getRaw(rx + 1, rz) == OOB || getRaw(rx - 1, rz) == OOB || getRaw(rx, rz + 1) == OOB || getRaw(rx, rz - 1) == OOB) { return false; } - + // if there are walls in two opposite directions, no - if ((getRaw(rx + 1, rz) == 0 && getRaw(rx - 1, rz) == 0) || (getRaw(rx, rz + 1) == 0 && getRaw(rx, rz - 1) == 0)) - { + if ((getRaw(rx + 1, rz) == 0 && getRaw(rx - 1, rz) == 0) || (getRaw(rx, rz + 1) == 0 && getRaw(rx, rz - 1) == 0)) { return false; } - + // otherwise, I suppose yes - + // check rarity - return rand.nextFloat() <= this.torchRarity; + return rand.nextFloat() <= this.torchRarity; } - + /** * Should we put a torch here? Intended to be called on the in-between spots where x and y are even. */ - public boolean shouldPillar(int rx, int rz) - { + public boolean shouldPillar(int rx, int rz) { // if the pillar block is not defined, no - if (pillarBlockID == null) - { + if (pillarBlockState == null) { return false; } - + // if there is out of bounds in any direction, no - if (getRaw(rx + 1, rz) == OOB || getRaw(rx - 1, rz) == OOB || getRaw(rx, rz + 1) == OOB || getRaw(rx, rz - 1) == OOB) - { + if (getRaw(rx + 1, rz) == OOB || getRaw(rx - 1, rz) == OOB || getRaw(rx, rz + 1) == OOB || getRaw(rx, rz - 1) == OOB) { return false; } - + // if there are walls in two opposite directions, no - if ((getRaw(rx + 1, rz) == 0 && getRaw(rx - 1, rz) == 0) || (getRaw(rx, rz + 1) == 0 && getRaw(rx, rz - 1) == 0)) - { + if ((getRaw(rx + 1, rz) == 0 && getRaw(rx - 1, rz) == 0) || (getRaw(rx, rz + 1) == 0 && getRaw(rx, rz - 1) == 0)) { return false; } - + // otherwise, I suppose yes - return true; + return true; } - + /** * Should we put a tree instead of a post? - * * Essentially the answer is yes for the corners and the exits. - * - * @param rx - * @param ry - * @return */ public boolean shouldTree(int rx, int rz) { if ((rx == 0 || rx == rawWidth - 1) && (getRaw(rx, rz + 1) != 0 || getRaw(rx, rz - 1) != 0)) { @@ -744,42 +600,39 @@ public boolean shouldTree(int rx, int rz) { if ((rz == 0 || rz == rawDepth - 1) && (getRaw(rx + 1, rz) != 0 || getRaw(rx - 1, rz) != 0)) { return true; } - - + + return rand.nextInt(50) == 0; } - + /** * If the worldX is set properly, this returns where in that world the maze coordinate x lies - * + * * @param x * @return */ - int getWorldX(int x) - { + int getWorldX(int x) { return worldX + (x * (evenBias + oddBias)) + 1; } - + /** * If the worldZ is set properly, this returns where in that world the maze coordinate z lies - * + * * @param z * @return */ - int getWorldZ(int z) - { + int getWorldZ(int z) { return worldZ + (z * (evenBias + oddBias)) + 1; } - - + + /** * Carves a room into the maze. The coordinates given are cell coordinates. */ - public void carveRoom0(int cx, int cz) - { + public void carveRoom0(int cx, int cz) { putCell(cx, cz, 5); - + putCell(cx + 1, cz, 5); putWall(cx, cz, cx + 1, cz, 5); putCell(cx - 1, cz, 5); @@ -789,30 +642,27 @@ public void carveRoom0(int cx, int cz) putCell(cx, cz - 1, 5); putWall(cx, cz, cx, cz - 1, 5); } - + /** * This room is a 3x3 cell room with exits in every direction. */ - public void carveRoom1(int cx, int cz) - { - int rx = cx * 2 + 1; - int rz = cz * 2 + 1; - + public void carveRoom1(int cx, int cz) { + int rx = cx * 2 + 1; + int rz = cz * 2 + 1; + // remove walls and cells - for(int i = -2; i <= 2; i++) - { - for(int j = -2; j <= 2; j++) - { + for (int i = -2; i <= 2; i++) { + for (int j = -2; j <= 2; j++) { putRaw(rx + i, rz + j, ROOM); } } - + // mark the exit areas as unmazed putCell(rx, rz + 1, 0); putCell(rx, rz - 1, 0); putCell(rx + 1, rz, 0); putCell(rx - 1, rz, 0); - + // make 4 exits (if not at the edge of the maze) if (getRaw(rx, rz + 4) != OUT_OF_BOUNDS) { putRaw(rx, rz + 3, ROOM); @@ -823,47 +673,45 @@ public void carveRoom1(int cx, int cz) if (getRaw(rx + 4, rz) != OUT_OF_BOUNDS) { putRaw(rx + 3, rz, ROOM); } - if (getRaw(rx- 4, rz) != OUT_OF_BOUNDS) { + if (getRaw(rx - 4, rz) != OUT_OF_BOUNDS) { putRaw(rx - 3, rz, ROOM); } - } - - + } + + /** * Adds four exits into the maze. */ - public void add4Exits() - { + public void add4Exits() { int hx = rawWidth / 2 + 1; int hz = rawDepth / 2 + 1; - + putRaw(hx, 0, ROOM); putRaw(hx, rawDepth - 1, ROOM); putRaw(0, hz, ROOM); putRaw(rawWidth - 1, hz, ROOM); } - + /** - * Generates a maze using the recursive backtracking algorithm. - * + * Generates a maze using the recursive backtracking algorithm. + * * @param sx The starting x coordinate * @param sz The starting y coordinate */ - public void generateRecursiveBacktracker(int sx, int sz) - { + public void generateRecursiveBacktracker(int sx, int sz) { rbGen(sx, sz); } - + /** * Mark the cell as visited. If we have any unvisited neighbors, pick one randomly, carve the wall between them, then call this function on that neighbor. - * + * * @param sx * @param sz */ public void rbGen(int sx, int sz) { // mark cell as visited putCell(sx, sz, 1); - + // count the unvisted neighbors int unvisited = 0; if (cellEquals(sx + 1, sz, 0)) { @@ -878,18 +726,17 @@ public void rbGen(int sx, int sz) { if (cellEquals(sx, sz - 1, 0)) { unvisited++; } - + // if there are no unvisited neighbors, return - if (unvisited == 0) - { + if (unvisited == 0) { return; } - + // otherwise, pick a random neighbor to visit int rn = rand.nextInt(unvisited); int dx, dz; dx = dz = 0; - + if (cellEquals(sx + 1, sz, 0)) { if (rn == 0) { dx = sx + 1; @@ -917,20 +764,17 @@ public void rbGen(int sx, int sz) { dz = sz - 1; } } - + // carve wall or door - if (rand.nextFloat() <= this.doorRarity) - { + if (rand.nextFloat() <= this.doorRarity) { putWall(sx, sz, dx, dz, DOOR); - } - else - { + } else { putWall(sx, sz, dx, dz, 2); } - + // call function recursively at the destination rbGen(dx, dz); - + // the destination has run out of free spaces, let's try this square again, up to 2 more times rbGen(sx, sz); rbGen(sx, sz); diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeAbstract.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeAbstract.java new file mode 100644 index 0000000000..82d67cdc78 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeAbstract.java @@ -0,0 +1,49 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.Template; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentTemplate; + +import java.util.Random; + +public abstract class ComponentNagaCourtyardHedgeAbstract extends StructureTFComponentTemplate { + + private final ResourceLocation HEDGE; + private final ResourceLocation HEDGE_BIG; + + private Template templateBig; + + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgeAbstract(ResourceLocation hedge, ResourceLocation hedgeBig) { + super(); + this.HEDGE = hedge; + this.HEDGE_BIG = hedgeBig; + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgeAbstract(TFFeature feature, int i, int x, int y, int z, Rotation rotation, ResourceLocation hedge, ResourceLocation hedgeBig) { + super(feature, i, x, y, z, rotation); + this.HEDGE = hedge; + this.HEDGE_BIG = hedgeBig; + } + + @Override + protected void loadTemplates(TemplateManager templateManager, MinecraftServer server) { + TEMPLATE = templateManager.getTemplate(server, HEDGE); + templateBig = templateManager.getTemplate(server, HEDGE_BIG); + } + + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox structureBoundingBox) { + placeSettings.setBoundingBox(structureBoundingBox); + TEMPLATE.addBlocksToWorld(world, rotatedPosition, new CourtyardStairsTemplateProcessor(rotatedPosition, placeSettings), placeSettings, 18); + templateBig.addBlocksToWorld(world, rotatedPosition, placeSettings.copy().setIntegrity(ComponentNagaCourtyardMain.HEDGE_FLOOF), 18); + return true; + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCap.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCap.java new file mode 100644 index 0000000000..2d017f11ad --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCap.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardHedgeCap extends ComponentNagaCourtyardHedgeAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgeCap() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end_big")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgeCap(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end_big")); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCapPillar.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCapPillar.java new file mode 100644 index 0000000000..4500b634d1 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCapPillar.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardHedgeCapPillar extends ComponentNagaCourtyardHedgeAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgeCapPillar() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end_pillar"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end_pillar_big")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgeCapPillar(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end_pillar"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_end_big_pillar")); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCorner.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCorner.java new file mode 100644 index 0000000000..3e332739f3 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeCorner.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardHedgeCorner extends ComponentNagaCourtyardHedgeAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgeCorner() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_corner"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_corner_big")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgeCorner(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_corner"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_corner_big")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeIntersection.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeIntersection.java new file mode 100644 index 0000000000..aa6ec4a8b7 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeIntersection.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardHedgeIntersection extends ComponentNagaCourtyardHedgeAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgeIntersection() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_intersection"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_intersection_big")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgeIntersection(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_intersection"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_intersection_big")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeLine.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeLine.java new file mode 100644 index 0000000000..3ceae327d4 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeLine.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardHedgeLine extends ComponentNagaCourtyardHedgeAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgeLine() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_line"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_line_big")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgeLine(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_line"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_line_big")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgePadder.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgePadder.java new file mode 100644 index 0000000000..b740fac97b --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgePadder.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardHedgePadder extends ComponentNagaCourtyardHedgeAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgePadder() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_between"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_between_big")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgePadder(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_between"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_between_big")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeTJunction.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeTJunction.java new file mode 100644 index 0000000000..aa4d6f2c31 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardHedgeTJunction.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardHedgeTJunction extends ComponentNagaCourtyardHedgeAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardHedgeTJunction() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_t"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_t_big")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardHedgeTJunction(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_t"), new ResourceLocation(TwilightForestMod.ID, "courtyard/hedge_t_big")); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardMain.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardMain.java new file mode 100644 index 0000000000..4d9ac4c763 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardMain.java @@ -0,0 +1,42 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.Random; + +public class ComponentNagaCourtyardMain extends StructureMazeGenerator { + static int ROW_OF_CELLS = 8; + static int RADIUS = (int) ((((ROW_OF_CELLS - 2) / 2.0F) * 12.0F) + 8); + static int DIAMETER = 2 * RADIUS + 1; + + static final float HEDGE_FLOOF = 0.5f; + + static final float WALL_DECAY = 0.1f; + static final float WALL_INTEGRITY = 0.9f; + + @SuppressWarnings("unused") + public ComponentNagaCourtyardMain() { + super(); + } + + public ComponentNagaCourtyardMain(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, rand, i, ROW_OF_CELLS, ROW_OF_CELLS); + + this.setCoordBaseMode(EnumFacing.NORTH); + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -RADIUS, -1, -RADIUS, RADIUS * 2, 10, RADIUS * 2, this.getCoordBaseMode()); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // naga spawner seems important + setBlockState(world, TFBlocks.boss_spawner.getDefaultState(), RADIUS, 2, RADIUS, sbb); + + return true; + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardPath.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardPath.java new file mode 100644 index 0000000000..4fdf165f67 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardPath.java @@ -0,0 +1,40 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.structures.StructureTFComponentTemplate; + +import java.util.Random; + +public class ComponentNagaCourtyardPath extends StructureTFComponentTemplate { + + private static final ResourceLocation PATH = new ResourceLocation(TwilightForestMod.ID, "courtyard/pathway"); + + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardPath() { + super(); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardPath(TFFeature feature, int i, int x, int y, int z) { + super(feature, i, x, y, z, Rotation.NONE); + } + + @Override + protected void loadTemplates(TemplateManager templateManager, MinecraftServer server) { + TEMPLATE = templateManager.getTemplate(server, PATH); + } + + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox structureBoundingBox) { + placeSettings.setBoundingBox(structureBoundingBox); + TEMPLATE.addBlocksToWorld(world, templatePosition, new CourtyardWallTemplateProcessor(templatePosition, placeSettings), placeSettings, 18); + return true; + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceAbstract.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceAbstract.java new file mode 100644 index 0000000000..ec46110e77 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceAbstract.java @@ -0,0 +1,41 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentTemplate; + +import java.util.Random; + +public abstract class ComponentNagaCourtyardTerraceAbstract extends StructureTFComponentTemplate { + + private final ResourceLocation TERRACE; + + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardTerraceAbstract(ResourceLocation terrace) { + super(); + TERRACE = terrace; + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardTerraceAbstract(TFFeature feature, int i, int x, int y, int z, Rotation rotation, ResourceLocation terrace) { + super(feature, i, x, y, z, rotation); + TERRACE = terrace; + } + + @Override + protected void loadTemplates(TemplateManager templateManager, MinecraftServer server) { + TEMPLATE = templateManager.getTemplate(server, TERRACE); + } + + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox structureBoundingBox) { + placeSettings.setBoundingBox(structureBoundingBox); + TEMPLATE.addBlocksToWorld(world, rotatedPosition, new CourtyardTerraceTemplateProcessor(rotatedPosition, placeSettings), placeSettings, 18); + return true; + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceBrazier.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceBrazier.java new file mode 100644 index 0000000000..506d8ba89a --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceBrazier.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardTerraceBrazier extends ComponentNagaCourtyardTerraceAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardTerraceBrazier() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/terrace_fire")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardTerraceBrazier(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/terrace_fire")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceDuct.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceDuct.java new file mode 100644 index 0000000000..73968cb2eb --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceDuct.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardTerraceDuct extends ComponentNagaCourtyardTerraceAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardTerraceDuct() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/terrace_duct")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardTerraceDuct(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/terrace_duct")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceStatue.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceStatue.java new file mode 100644 index 0000000000..6fb146bbde --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardTerraceStatue.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardTerraceStatue extends ComponentNagaCourtyardTerraceAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardTerraceStatue() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/terrace_statue")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardTerraceStatue(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/terrace_statue")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWall.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWall.java new file mode 100644 index 0000000000..2cacb0d751 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWall.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardWall extends ComponentNagaCourtyardWallAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardWall() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_decayed")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardWall(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_decayed")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallAbstract.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallAbstract.java new file mode 100644 index 0000000000..54f85411df --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallAbstract.java @@ -0,0 +1,50 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.Template; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.MossyCobbleTemplateProcessor; +import twilightforest.structures.StructureTFComponentTemplate; + +import java.util.Random; + +public class ComponentNagaCourtyardWallAbstract extends StructureTFComponentTemplate { + + private final ResourceLocation WALL; + private final ResourceLocation WALL_DECAYED; + + private Template decayTemplate; + + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardWallAbstract(ResourceLocation wall, ResourceLocation wall_decayed) { + super(); + this.WALL = wall; + this.WALL_DECAYED = wall_decayed; + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardWallAbstract(TFFeature feature, int i, int x, int y, int z, Rotation rotation, ResourceLocation wall, ResourceLocation wall_decayed) { + super(feature, i, x, y, z, rotation); + this.WALL = wall; + this.WALL_DECAYED = wall_decayed; + } + + @Override + protected void loadTemplates(TemplateManager templateManager, MinecraftServer server) { + TEMPLATE = templateManager.getTemplate(server, WALL); + decayTemplate = templateManager.getTemplate(server, WALL_DECAYED); + } + + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox structureBoundingBox) { + placeSettings.setBoundingBox(structureBoundingBox); + TEMPLATE.addBlocksToWorld(world, rotatedPosition, new CourtyardWallTemplateProcessor(rotatedPosition, placeSettings), placeSettings.setIntegrity(ComponentNagaCourtyardMain.WALL_INTEGRITY), 18); + decayTemplate.addBlocksToWorld(world, rotatedPosition, new MossyCobbleTemplateProcessor(rotatedPosition, placeSettings), placeSettings.setIntegrity(ComponentNagaCourtyardMain.WALL_DECAY), 18); + return true; + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallCorner.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallCorner.java new file mode 100644 index 0000000000..1851607bc8 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallCorner.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardWallCorner extends ComponentNagaCourtyardWallAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardWallCorner() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner_decayed")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardWallCorner(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner_decayed")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallCornerAlt.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallCornerAlt.java new file mode 100644 index 0000000000..567056d3c1 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallCornerAlt.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardWallCornerAlt extends ComponentNagaCourtyardWallAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardWallCornerAlt() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner_inner"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner_inner_decayed")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardWallCornerAlt(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner_inner"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_corner_inner_decayed")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallPadder.java b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallPadder.java new file mode 100644 index 0000000000..1fa095eae9 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/ComponentNagaCourtyardWallPadder.java @@ -0,0 +1,18 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +public class ComponentNagaCourtyardWallPadder extends ComponentNagaCourtyardWallAbstract { + @SuppressWarnings({"WeakerAccess", "unused"}) + public ComponentNagaCourtyardWallPadder() { + super(new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_padding"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_padding_decayed")); + } + + @SuppressWarnings("WeakerAccess") + public ComponentNagaCourtyardWallPadder(TFFeature feature, int i, int x, int y, int z, Rotation rotation) { + super(feature, i, x, y, z, rotation, new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_padding"), new ResourceLocation(TwilightForestMod.ID, "courtyard/courtyard_wall_padding_decayed")); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/CourtyardStairsTemplateProcessor.java b/src/main/java/twilightforest/structures/courtyard/CourtyardStairsTemplateProcessor.java new file mode 100644 index 0000000000..9b2c6ffc26 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/CourtyardStairsTemplateProcessor.java @@ -0,0 +1,35 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.template.PlacementSettings; +import net.minecraft.world.gen.structure.template.Template; +import twilightforest.block.BlockTFNagastoneStairs; +import twilightforest.block.TFBlocks; +import twilightforest.structures.RandomizedTemplateProcessor; + +import javax.annotation.Nullable; + +public class CourtyardStairsTemplateProcessor extends RandomizedTemplateProcessor { + public CourtyardStairsTemplateProcessor(BlockPos pos, PlacementSettings settings) { + super(pos, settings); + } + + @Nullable + @Override + public Template.BlockInfo processBlock(World worldIn, BlockPos pos, Template.BlockInfo blockInfo) { + if (shouldPlaceBlock()) { + IBlockState state = blockInfo.blockState; + Block block = state.getBlock(); + + if (block == TFBlocks.nagastone_stairs) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, translateState(state, randomBlock(TFBlocks.nagastone_stairs_mossy, TFBlocks.nagastone_stairs_weathered), BlockTFNagastoneStairs.DIRECTION, BlockTFNagastoneStairs.FACING, BlockTFNagastoneStairs.HALF, BlockTFNagastoneStairs.SHAPE), null); + + return blockInfo; + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/courtyard/CourtyardTerraceTemplateProcessor.java b/src/main/java/twilightforest/structures/courtyard/CourtyardTerraceTemplateProcessor.java new file mode 100644 index 0000000000..722540bb43 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/CourtyardTerraceTemplateProcessor.java @@ -0,0 +1,78 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.block.*; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.template.PlacementSettings; +import net.minecraft.world.gen.structure.template.Template; +import twilightforest.block.BlockTFNagastoneStairs; +import twilightforest.block.TFBlocks; +import twilightforest.structures.RandomizedTemplateProcessor; + +import javax.annotation.Nullable; + +public class CourtyardTerraceTemplateProcessor extends RandomizedTemplateProcessor { + + public CourtyardTerraceTemplateProcessor(BlockPos pos, PlacementSettings settings) { + super(pos, settings); + } + + @Nullable + @Override + public Template.BlockInfo processBlock(World world, BlockPos pos, Template.BlockInfo blockInfo) { + + if (!shouldPlaceBlock()) return null; + + boolean shouldMakeNewBlockInfo = false; + IBlockState state = blockInfo.blockState; + + final IBlockState SMOOTHBRICK_SLAB_STATE = Blocks.STONE_SLAB.getDefaultState().withProperty(BlockStoneSlab.VARIANT, BlockStoneSlab.EnumType.SMOOTHBRICK); + final IBlockState SMOOTHBRICK_STATE = Blocks.STONEBRICK.getDefaultState(); //Blocks.DOUBLE_STONE_SLAB.getDefaultState().withProperty(BlockDoubleStoneSlab.VARIANT, BlockStoneSlab.EnumType.SMOOTHBRICK).withProperty(BlockDoubleStoneSlab.SEAMLESS, false); + + //final IBlockState SANDSTONE_SLAB_STATE = Blocks.STONE_SLAB.getDefaultState().withProperty(BlockStoneSlab.VARIANT, BlockStoneSlab.EnumType.SAND); + //final IBlockState SANDSTONE_STATE = Blocks.DOUBLE_STONE_SLAB.getDefaultState().withProperty(BlockDoubleStoneSlab.VARIANT, BlockStoneSlab.EnumType.SAND).withProperty(BlockDoubleStoneSlab.SEAMLESS, false); + + if (state.getBlock() == Blocks.DOUBLE_STONE_SLAB && state.getValue(BlockDoubleStoneSlab.VARIANT) == BlockStoneSlab.EnumType.SAND) { + IBlockState stateCheck = world.getBlockState(pos); + if (stateCheck == SMOOTHBRICK_SLAB_STATE) + return new Template.BlockInfo(pos, SMOOTHBRICK_SLAB_STATE, null); + else if (stateCheck.getMaterial() == Material.AIR) + return null; + else + state = SMOOTHBRICK_STATE; + + shouldMakeNewBlockInfo = true; + } + + if (state.getBlock() == Blocks.STONE_SLAB && state.getValue(BlockStoneSlab.VARIANT) == BlockStoneSlab.EnumType.SAND) { + IBlockState stateCheck = world.getBlockState(pos); + + if (stateCheck.getMaterial() == Material.AIR) + return null; + else + return new Template.BlockInfo(pos, SMOOTHBRICK_SLAB_STATE, null); + } + + Block block = state.getBlock(); + + if (block == Blocks.STONEBRICK && state != Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CHISELED)) + return random.nextBoolean() ? (shouldMakeNewBlockInfo ? new Template.BlockInfo(blockInfo.pos, state, blockInfo.tileentityData) : blockInfo) : new Template.BlockInfo(pos, state.withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.values()[random.nextInt(3)]), null); + + if (state == Blocks.STONE_SLAB.getDefaultState().withProperty(BlockStoneSlab.VARIANT, BlockStoneSlab.EnumType.STONE)) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, state.withProperty(BlockStoneSlab.VARIANT, BlockStoneSlab.EnumType.COBBLESTONE), null); + + if (block == TFBlocks.etched_nagastone) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, translateState(state, randomBlock(TFBlocks.etched_nagastone_mossy, TFBlocks.etched_nagastone_weathered), BlockDirectional.FACING), null); + + if (block == TFBlocks.nagastone_pillar) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, translateState(state, randomBlock(TFBlocks.nagastone_pillar_mossy, TFBlocks.nagastone_pillar_weathered), BlockRotatedPillar.AXIS), null); + + if (block == TFBlocks.nagastone_stairs) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, translateState(state, randomBlock(TFBlocks.nagastone_stairs, TFBlocks.nagastone_stairs), BlockTFNagastoneStairs.DIRECTION, BlockTFNagastoneStairs.FACING, BlockTFNagastoneStairs.HALF, BlockTFNagastoneStairs.SHAPE), null); + + return blockInfo; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/courtyard/CourtyardWallTemplateProcessor.java b/src/main/java/twilightforest/structures/courtyard/CourtyardWallTemplateProcessor.java new file mode 100644 index 0000000000..f9436f7d2d --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/CourtyardWallTemplateProcessor.java @@ -0,0 +1,49 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.block.*; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.template.PlacementSettings; +import net.minecraft.world.gen.structure.template.Template; +import twilightforest.block.BlockTFNagastoneStairs; +import twilightforest.block.TFBlocks; +import twilightforest.structures.RandomizedTemplateProcessor; + +import javax.annotation.Nullable; + +public class CourtyardWallTemplateProcessor extends RandomizedTemplateProcessor { + + public CourtyardWallTemplateProcessor(BlockPos pos, PlacementSettings settings) { + super(pos, settings); + } + + @Nullable + @Override + public Template.BlockInfo processBlock(World worldIn, BlockPos pos, Template.BlockInfo blockInfo) { + if (shouldPlaceBlock()) { + IBlockState state = blockInfo.blockState; + Block block = state.getBlock(); + + if (block == Blocks.STONEBRICK && state != Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CHISELED)) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, state.withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.values()[random.nextInt(3)]), null); + + if (state == Blocks.STONE_SLAB.getDefaultState().withProperty(BlockStoneSlab.VARIANT, BlockStoneSlab.EnumType.STONE)) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, state.withProperty(BlockStoneSlab.VARIANT, BlockStoneSlab.EnumType.COBBLESTONE), null); + + if (block == TFBlocks.etched_nagastone) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, translateState(state, randomBlock(TFBlocks.etched_nagastone_mossy, TFBlocks.etched_nagastone_weathered), BlockDirectional.FACING), null); + + if (block == TFBlocks.nagastone_pillar) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, translateState(state, randomBlock(TFBlocks.nagastone_pillar_mossy, TFBlocks.nagastone_pillar_weathered), BlockRotatedPillar.AXIS), null); + + if (block == TFBlocks.nagastone_stairs) + return random.nextBoolean() ? blockInfo : new Template.BlockInfo(pos, translateState(state, randomBlock(TFBlocks.nagastone_stairs, TFBlocks.nagastone_stairs), BlockTFNagastoneStairs.DIRECTION, BlockTFNagastoneStairs.FACING, BlockTFNagastoneStairs.HALF, BlockTFNagastoneStairs.SHAPE), null); + + return blockInfo; + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/courtyard/NagaCourtyardPieces.java b/src/main/java/twilightforest/structures/courtyard/NagaCourtyardPieces.java new file mode 100644 index 0000000000..cda5336065 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/NagaCourtyardPieces.java @@ -0,0 +1,27 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartCourtyard; + +public class NagaCourtyardPieces { + public static void registerPieces() { + MapGenStructureIO.registerStructure(StructureStartCourtyard.class, "TFNC"); + + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardMain.class, "TFNCMn"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardHedgeCap.class, "TFNCCp"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardHedgeCapPillar.class, "TFNCCpP"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardHedgeCorner.class, "TFNCCr"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardHedgeLine.class, "TFNCLn"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardHedgeTJunction.class, "TFNCT"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardHedgeIntersection.class, "TFNCIs"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardHedgePadder.class, "TFNCPd"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardTerraceBrazier.class, "TFNCTr"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardTerraceDuct.class, "TFNCDu"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardTerraceStatue.class, "TFNCSt"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardPath.class, "TFNCPa"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardWall.class, "TFNCWl"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardWallPadder.class, "TFNCWP"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardWallCorner.class, "TFNCWC"); + MapGenStructureIO.registerStructureComponent(ComponentNagaCourtyardWallCornerAlt.class, "TFNCWA"); + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/StructureMazeGenerator.java b/src/main/java/twilightforest/structures/courtyard/StructureMazeGenerator.java new file mode 100644 index 0000000000..afacdf4862 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/StructureMazeGenerator.java @@ -0,0 +1,647 @@ +package twilightforest.structures.courtyard; + +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.enums.Diagonals; +import twilightforest.structures.StructureTFComponent; + +import java.util.List; +import java.util.Random; + +public abstract class StructureMazeGenerator extends StructureTFComponent { + protected int[][] maze; + private int[][] cornerClipping = new int[4][2]; + private int widthInCellCount; + private int heightInCellCount; + + StructureMazeGenerator() { + super(); + } + + StructureMazeGenerator(TFFeature feature, Random rand, int i, int widthInCellCount, int heightInCellCount) { + super(feature, i); + this.widthInCellCount = widthInCellCount; + this.heightInCellCount = heightInCellCount; + this.maze = new int[widthInCellCount-1][heightInCellCount-1]; + generateMaze(this.maze, this.cornerClipping, rand, this.widthInCellCount, this.heightInCellCount, 2); + } + + // Actually assemble maze + @Override + public void buildComponent(StructureComponent structureComponent, List list, Random random) { + super.buildComponent(structureComponent, list, random); + final int offset = 6; + + final Rotation[] rotations = Rotation.values(); + + this.processInnerWallsAndFloor(structureComponent, list, random, offset, rotations); + + this.processOuterWalls(structureComponent, list, random, offset, rotations); + } + + @SuppressWarnings("SameParameterValue") + private static void generateMaze(int[][] maze, int[][] cornerClippings, Random random, int widthInCellCount, int heightInCellCount, int maximumClipping) { + // Trying to keep this optimized for speed I guess + + // Generates a connection map for the walls. It modifies the two-dimensional int array, inserting packed binary strings as ints. + // A One in its binary interpretation means the wall connects in this direction. + // As a result of this being a "connectome" of maze walls. It is "Size In Cell count" - 1. + + final WallFacing rotations[][] = new WallFacing[maze.length][maze[0].length]; + + for (int x = 0; x < widthInCellCount-1; x++) { + for (int y = 0; y < heightInCellCount-1; y++) { + rotations[x][y] = WallFacing.values()[random.nextInt(WallFacing.values().length)]; + // set the initial base byte + maze[x][y] |= rotations[x][y].BYTE; + } + } + + final int[][] mazeLocal = maze.clone(); + + int halfWayPointX = (widthInCellCount / 2) - 1; + int halfWayPointY = (heightInCellCount / 2) - 1; + + for (int y = 0; y < heightInCellCount-1; y++) { + for (int x = 0; x < widthInCellCount-1; x++) { + if (x == halfWayPointX && y == halfWayPointY) continue; + + // Did we pick west and will we not get an AIOOBException accessing array + if (rotations[x][y] == WallFacing.WEST && x > 0) { + // If neighbor does not connect to west, connect it to east + if (!rotations[x][y].unpackAndTest(maze[x-1][y])) + maze[x-1][y] |= rotations[x][y].OPPOSITE; + else { // else we cut the connection + // remove connection for the maze part we're looking at + maze[x][y] &= rotations[x][y].INVERTED; + // remove connection for the adjacent maze part + maze[x-1][y] &= rotations[x-1][y].INVERTED_OPPOSITE; + } + } + if (rotations[x][y] == WallFacing.NORTH && y > 0 ) { + if (!rotations[x][y].unpackAndTest(maze[x][y-1])) + maze[x][y-1] |= rotations[x][y].OPPOSITE; + else { + maze[x][y] &= rotations[x][y].INVERTED; + maze[x][y-1] &= rotations[x][y-1].INVERTED_OPPOSITE; + } + } + if (rotations[x][y] == WallFacing.EAST && x < widthInCellCount-2 ) { + if (!rotations[x][y].unpackAndTest(maze[x+1][y])) + maze[x+1][y] |= rotations[x][y].OPPOSITE; + else { + maze[x][y] &= rotations[x][y].INVERTED; + maze[x+1][y] &= rotations[x+1][y].INVERTED_OPPOSITE; + } + } + if (rotations[x][y] == WallFacing.SOUTH && y < heightInCellCount-2 ) { + if (!rotations[x][y].unpackAndTest(maze[x][y+1])) + maze[x][y+1] |= rotations[x][y].OPPOSITE; + else { + maze[x][y] &= rotations[x][y].INVERTED; + maze[x][y+1] &= rotations[x][y+1].INVERTED_OPPOSITE; + } + } + } + }//*/ + + for (WallFacing facing : WallFacing.values()) + maze[halfWayPointX + facing.xOffset][halfWayPointY + facing.zOffset] &= facing.INVERTED_OPPOSITE; + + maze[halfWayPointX][halfWayPointY] = 0b10000; + + for (int x = 1; x < maze.length; x++) { + for (int y = 1; y < maze[x].length; y++) { + if (mazeLocal[x][y] == 0) { + if (mazeLocal[x-1][y] == 0) { + maze[x][y] |= WallFacing.WEST.BYTE; + maze[x-1][y] |= WallFacing.WEST.OPPOSITE; + } + + if (mazeLocal[x][y-1] == 0) { + maze[x][y] |= WallFacing.NORTH.BYTE; + maze[x][y-1] |= WallFacing.NORTH.OPPOSITE; + } + } + } + } + + for (Diagonals diagonals : Diagonals.values()) { + cornerClippings[diagonals.ordinal()][0] = random.nextInt(maximumClipping) + 1; + cornerClippings[diagonals.ordinal()][1] = random.nextInt(maximumClipping) + 1; + + for (int y = 0; y < cornerClippings[diagonals.ordinal()][0]; y++) + for (int x = 0; x < cornerClippings[diagonals.ordinal()][1]; x++) + maze[diagonals.operationX.convert(x, widthInCellCount - 2)][diagonals.operationY.convert(y, heightInCellCount - 2)] |= 0b10000; + } + } + + @SuppressWarnings("ConstantConditions") + private void processInnerWallsAndFloor(StructureComponent structureComponent, List list, Random random, final int offset, final Rotation[] rotations) { + for (int x = 0; x < widthInCellCount - 1; x++) { + for (int y = 0; y < heightInCellCount - 1; y++) { + final boolean xCenter = x == (widthInCellCount / 2) - 1; + final boolean yCenter = y == (heightInCellCount / 2) - 1; + // -------- HEDGE + if ((!(xCenter || yCenter)) && (maze[x][y] & 0b10000) == 0b10000) continue; + + int rotation = 0; + + int xBB = boundingBox.minX + (x * 12) + offset; + int yBB = boundingBox.minY + 1; + int zBB = boundingBox.minZ + (y * 12) + offset; + + if (!(xCenter && yCenter)) { + StructureTFComponent structure; + + switch (maze[x][y] & 0b1111) { // These are inconsistent because I was stupid with the structures I saved to .nbt + case 0b0010: // FACE SOUTH + rotation++; // rotate 270 + case 0b0001: // FACE EAST + rotation++; // rotate 180 + case 0b1000: // FACE NORTH + rotation++; // rotate 90 + case 0b0100: // FACE WEST + final Rotation rotationCap = rotations[rotation]; + + if (random.nextBoolean()) + structure = new ComponentNagaCourtyardHedgeCap(getFeatureType(), (x * widthInCellCount) + y, xBB, yBB, zBB, rotationCap); + else + structure = new ComponentNagaCourtyardHedgeCapPillar(getFeatureType(), (x * widthInCellCount) + y, xBB, yBB, zBB, rotationCap); + + break; + case 0b1001: // NORTH EAST + rotation++; + case 0b1100: // NORTH WEST + rotation++; + case 0b0110: // SOUTH WEST + rotation++; + case 0b0011: // SOUTH EAST + final Rotation rotationCorner = rotations[rotation]; + + structure = new ComponentNagaCourtyardHedgeCorner(getFeatureType(), maze[x][y], xBB, yBB, zBB, rotationCorner); + break; + case 0b1101: // NOT SOUTH + rotation++; + case 0b1110: // NOT EAST + rotation++; + case 0b0111: // NOT NORTH + rotation++; + case 0b1011: // NOT WEST + final Rotation rotationT = rotations[rotation]; + + structure = new ComponentNagaCourtyardHedgeTJunction(getFeatureType(), maze[x][y], xBB, yBB, zBB, rotationT); + break; + case 0b1010: // NORTH AND SOUTH + rotation++; + case 0b0101: // EAST AND WEST + final Rotation rotationLine = rotations[rotation]; + + structure = new ComponentNagaCourtyardHedgeLine(getFeatureType(), maze[x][y], xBB, yBB, zBB, rotationLine); + break; + case 0b1111: + structure = new ComponentNagaCourtyardHedgeIntersection(getFeatureType(), maze[x][y], xBB, yBB, zBB, Rotation.NONE); + break; + default: + if (random.nextInt(150) == 0) { + structure = new ComponentNagaCourtyardTerraceStatue(getFeatureType(), maze[x][y], xBB - 6, yBB - 3, zBB - 6, rotations[random.nextInt(rotations.length)]); + } else if (random.nextBoolean()) + structure = new ComponentNagaCourtyardTerraceBrazier(getFeatureType(), maze[x][y], xBB - 6, yBB - 3, zBB - 6, Rotation.NONE); + else { + structure = new ComponentNagaCourtyardTerraceDuct(getFeatureType(), maze[x][y], xBB - 6, yBB - 3, zBB - 6, rotations[random.nextInt(rotations.length)]); + } + + break; + } + + list.add(structure); + structure.buildComponent(structureComponent, list, random); + } + + // -------- Hedge Connectors + + xBB = boundingBox.minX + (x * 12) + offset; + zBB = boundingBox.minZ + (y * 12) + offset; + + final boolean connectWest = WallFacing.WEST .unpackAndTest(maze[x][y]); + final boolean connectNorth = WallFacing.NORTH.unpackAndTest(maze[x][y]); + final boolean connectEast = WallFacing.EAST .unpackAndTest(maze[x][y]); + final boolean connectSouth = WallFacing.SOUTH.unpackAndTest(maze[x][y]); + + if (connectWest) { + ComponentNagaCourtyardHedgePadder padding = new ComponentNagaCourtyardHedgePadder(getFeatureType(), maze[x][y], xBB - 1, yBB, zBB, Rotation.NONE); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + + if (x > 0 && (maze[x-1][y] & 0b10000) != 0b10000) { + ComponentNagaCourtyardHedgePadder padding2 = new ComponentNagaCourtyardHedgePadder(getFeatureType(), maze[x][y], xBB - 7, yBB, zBB, Rotation.NONE); + list.add(padding2); + padding2.buildComponent(structureComponent, list, random); + } + + ComponentNagaCourtyardHedgeLine structureLine = new ComponentNagaCourtyardHedgeLine(getFeatureType(), maze[x][y], xBB - 6, yBB, zBB, Rotation.NONE); + list.add(structureLine); + structureLine.buildComponent(structureComponent, list, random); + } + + if (connectNorth) { + ComponentNagaCourtyardHedgePadder padding = new ComponentNagaCourtyardHedgePadder(getFeatureType(), maze[x][y], xBB + 4, yBB, zBB - 1, Rotation.CLOCKWISE_90); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + + if (y > 0 && (maze[x][y-1] & 0b10000) != 0b10000) { + ComponentNagaCourtyardHedgePadder padding2 = new ComponentNagaCourtyardHedgePadder(getFeatureType(), maze[x][y], xBB + 4, yBB, zBB - 7, Rotation.CLOCKWISE_90); + list.add(padding2); + padding2.buildComponent(structureComponent, list, random); + } + + ComponentNagaCourtyardHedgeLine structureLine = new ComponentNagaCourtyardHedgeLine(getFeatureType(), maze[x][y], xBB, yBB, zBB - 6, Rotation.CLOCKWISE_90); + list.add(structureLine); + structureLine.buildComponent(structureComponent, list, random); + } + + if ((x >= widthInCellCount - 2 || (maze[x+1][y] & 0b10000) == 0b10000) && connectEast) { + ComponentNagaCourtyardHedgePadder padding = new ComponentNagaCourtyardHedgePadder(getFeatureType(), maze[x][y], xBB + 5, yBB, zBB, Rotation.NONE); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardHedgeLine structureLine = new ComponentNagaCourtyardHedgeLine(getFeatureType(), maze[x][y], xBB + 6, yBB, zBB, Rotation.NONE); + list.add(structureLine); + structureLine.buildComponent(structureComponent, list, random); + } + + if ((y >= heightInCellCount - 2 || (maze[x][y+1] & 0b10000) == 0b10000) && connectSouth) { + ComponentNagaCourtyardHedgePadder padding = new ComponentNagaCourtyardHedgePadder(getFeatureType(), maze[x][y], xBB + 4, yBB, zBB + 5, Rotation.CLOCKWISE_90); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardHedgeLine structureLine = new ComponentNagaCourtyardHedgeLine(getFeatureType(), maze[x][y], xBB, yBB, zBB + 6, Rotation.CLOCKWISE_90); + list.add(structureLine); + structureLine.buildComponent(structureComponent, list, random); + }//*/ + + final boolean hasNoTerrace = (maze[x][y] & 0b1111) != 0; + + //final boolean westOfCenter = x == (widthInCellCount / 2) - 2; + //final boolean northOfCenter = y == (heightInCellCount / 2) - 2; + //final boolean eastOfCenter = x == widthInCellCount / 2; + //final boolean southOfCenter = y == heightInCellCount / 2; + + final boolean westHasNoTerraceOrIsSafe = /*(!(eastOfCenter && yCenter )) &&*/ (x == 0 || (maze[x-1][y] & 0b10000) == 0b10000 || (maze[x-1][y] & 0b1111) != 0); + final boolean northHasNoTerraceOrIsSafe = /*(!(xCenter && southOfCenter)) &&*/ (y == 0 || (maze[x][y-1] & 0b10000) == 0b10000 || (maze[x][y-1] & 0b1111) != 0); + final boolean eastHasNoTerraceOrIsSafe = /*(!(westOfCenter && yCenter )) &&*/ (x == widthInCellCount -2 || (maze[x+1][y] & 0b10000) == 0b10000); + final boolean southHasNoTerraceOrIsSafe = /*(!(xCenter && northOfCenter)) &&*/ (y == heightInCellCount-2 || (maze[x][y+1] & 0b10000) == 0b10000); + + final boolean westNorthHasNoTerraceOrIsSafe = /*(!(eastOfCenter && southOfCenter)) &&*/ ((x == 0 || y == 0 || maze[x - 1][y - 1] != 0)); + final boolean westSouthHasNoTerraceOrIsSafe = /*(!(eastOfCenter && northOfCenter)) &&*/ ((x == 0 || y >= heightInCellCount-2 || maze[x - 1][y + 1] != 0)); + final boolean eastNorthHasNoTerraceOrIsSafe = /*(!(westOfCenter && southOfCenter)) &&*/ ((x >= widthInCellCount -2 || y == 0 || maze[x + 1][y - 1] != 0)); + final boolean eastSouthHasNoTerraceOrIsSafe = /*(!(westOfCenter && northOfCenter)) &&*/ ((x >= widthInCellCount -2 || y >= heightInCellCount-2 || maze[x + 1][y + 1] != 0)); + + // -------- PATHS - cardinal + + if (xCenter && yCenter) { + ComponentNagaCourtyardPath path = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB - 1, yBB - 1, zBB - 1); + list.add(path); + path.buildComponent(structureComponent, list, random); + } + + if (hasNoTerrace && westHasNoTerraceOrIsSafe && !connectWest) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB - 7, yBB - 1, zBB - 1); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + } + + if (hasNoTerrace && northHasNoTerraceOrIsSafe && !connectNorth) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB - 1, yBB - 1, zBB - 7); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + } + + if (hasNoTerrace && eastHasNoTerraceOrIsSafe) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB + 5, yBB - 1, zBB - 1); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + } + + if (hasNoTerrace && southHasNoTerraceOrIsSafe) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB - 1, yBB - 1, zBB + 5); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + } + + // -------- PATHS - Diagonal + + if (hasNoTerrace && westHasNoTerraceOrIsSafe && northHasNoTerraceOrIsSafe && westNorthHasNoTerraceOrIsSafe) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB - 7, yBB - 1, zBB - 7); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + } + + if (hasNoTerrace && westHasNoTerraceOrIsSafe && southHasNoTerraceOrIsSafe && westSouthHasNoTerraceOrIsSafe) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB - 7, yBB - 1, zBB + 5); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + } + + if (hasNoTerrace && eastHasNoTerraceOrIsSafe && northHasNoTerraceOrIsSafe && eastNorthHasNoTerraceOrIsSafe) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB + 5, yBB - 1, zBB - 7); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + } + + if (hasNoTerrace && eastHasNoTerraceOrIsSafe && southHasNoTerraceOrIsSafe && eastSouthHasNoTerraceOrIsSafe) { + ComponentNagaCourtyardPath path2 = new ComponentNagaCourtyardPath(getFeatureType(), maze[x][y], xBB + 5, yBB - 1, zBB + 5); + list.add(path2); + path2.buildComponent(structureComponent, list, random); + }//*/ + } + } + } + + private void processOuterWalls(StructureComponent structureComponent, List list, Random random, final int offset, final Rotation[] rotations) { + // -------- WALLS + for (Diagonals diagonal : Diagonals.values()) { + // Walls at corner notches going with X Axis, crossing Z Axis. Sideways. + + int zBoundX = (diagonal.isTop() + ? boundingBox.minZ + (cornerClipping[diagonal.ordinal()][0] * 12) - 3 + : boundingBox.maxZ - (cornerClipping[diagonal.ordinal()][0] * 12) + 1 ); + + ComponentNagaCourtyardWallPadder paddingStartX = + new ComponentNagaCourtyardWallPadder( + getFeatureType(), + ( cornerClipping[diagonal.ordinal()][1] * 2 ) + 1, + ( diagonal.isLeft() ? boundingBox.minX + 2 : boundingBox.maxX - 2 ), + boundingBox.minY, + zBoundX, + Rotation.NONE ); + + list.add(paddingStartX); + paddingStartX.buildComponent(structureComponent, list, random); + + int xPadOffset = diagonal.isLeft() ? 11 : -1; + + for (int i = 0; i < cornerClipping[diagonal.ordinal()][1] - 1; i++) { + int xBound = (diagonal.isLeft() ? boundingBox.minX + (i*12) + 3 : boundingBox.maxX - (i*12) - 13 ); + + ComponentNagaCourtyardWall wall = new ComponentNagaCourtyardWall(getFeatureType(), i*2, xBound, boundingBox.minY, zBoundX, Rotation.NONE); + list.add(wall); + wall.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardWallPadder padding = new ComponentNagaCourtyardWallPadder(getFeatureType(), (i*2)+1, xBound + xPadOffset, boundingBox.minY, zBoundX, Rotation.NONE); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + } + + // Walls at corner notches going with Z Axis, crossing X Axis. Up/Down. + + int xBoundZ = (diagonal.isLeft() + ? boundingBox.minX + (cornerClipping[diagonal.ordinal()][1] * 12) - 1 + : boundingBox.maxX - (cornerClipping[diagonal.ordinal()][1] * 12) + 3 ); + + ComponentNagaCourtyardWallPadder paddingStartZ = + new ComponentNagaCourtyardWallPadder( + getFeatureType(), + ( cornerClipping[diagonal.ordinal()][1] * 2 ) + 1, + xBoundZ, + boundingBox.minY, + ( diagonal.isTop() ? boundingBox.minZ + 2 : boundingBox.maxZ - 2 ), + Rotation.CLOCKWISE_90 ); + + list.add(paddingStartZ); + paddingStartZ.buildComponent(structureComponent, list, random); + + int zPadOffset = diagonal.isTop() ? 11 : -1; + + for (int i = 0; i < cornerClipping[diagonal.ordinal()][0] - 1; i++) { + int zBound = (diagonal.isTop() ? boundingBox.minZ + (i*12) + 3 : boundingBox.maxZ - (i*12) - 13 ); + + ComponentNagaCourtyardWall wall = new ComponentNagaCourtyardWall(getFeatureType(), i*2, xBoundZ - 10, boundingBox.minY, zBound, Rotation.CLOCKWISE_90); + list.add(wall); + wall.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardWallPadder padding = new ComponentNagaCourtyardWallPadder(getFeatureType(), (i*2)+1, xBoundZ, boundingBox.minY, zBound + zPadOffset, Rotation.CLOCKWISE_90); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + } + + // WALL CORNERS + + int wallCornerInnerX = boundingBox.minX + (diagonal.operationX.convert(cornerClipping[diagonal.ordinal()][1], widthInCellCount - 1) * 12) + (diagonal.isLeft() ? -3 : 3); + int wallCornerInnerZ = boundingBox.minZ + (diagonal.operationY.convert(cornerClipping[diagonal.ordinal()][0], heightInCellCount - 1) * 12) + (diagonal.isTop() ? -3 : 3); + + // These touch upper/lower borders + + ComponentNagaCourtyardWallCorner corner1 = new ComponentNagaCourtyardWallCorner(getFeatureType(), diagonal.ordinal() * 3, + wallCornerInnerX, + boundingBox.minY, + diagonal.isTop() ? boundingBox.minZ - 3 : boundingBox.maxZ - 1, + rotations[diagonal.ordinal() % rotations.length]); + list.add(corner1); + corner1.buildComponent(structureComponent, list, random); + + // These touch side borders + + ComponentNagaCourtyardWallCorner corner2 = new ComponentNagaCourtyardWallCorner(getFeatureType(), (diagonal.ordinal() * 3) + 1, + diagonal.isLeft() ? boundingBox.minX - 3 : boundingBox.maxX - 1, + boundingBox.minY, + wallCornerInnerZ, + rotations[diagonal.ordinal() % rotations.length]); + list.add(corner2); + corner2.buildComponent(structureComponent, list, random); + + // These are inner anti-corners + + ComponentNagaCourtyardWallCornerAlt innerCorner = new ComponentNagaCourtyardWallCornerAlt(getFeatureType(), (diagonal.ordinal() * 3) + 3, + wallCornerInnerX + (diagonal.isLeft() ? -6 : 2), + boundingBox.minY, + wallCornerInnerZ + (diagonal.isTop() ? -6 : 2), + rotations[diagonal.ordinal() % rotations.length]); + list.add(innerCorner); + innerCorner.buildComponent(structureComponent, list, random); + } + + // Top / North + + for (int i = cornerClipping[3][1]; i < (widthInCellCount-1) - cornerClipping[0][1]; i++) { + ComponentNagaCourtyardWall wall = new ComponentNagaCourtyardWall(getFeatureType(), i, boundingBox.minX + (i * 12) + offset - 3, boundingBox.minY, boundingBox.minZ - 3, Rotation.NONE); + list.add(wall); + wall.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardWallPadder padding = new ComponentNagaCourtyardWallPadder(getFeatureType(), i, boundingBox.minX + (i * 12) + offset - 4, boundingBox.minY, boundingBox.minZ - 3, Rotation.NONE); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + } + + ComponentNagaCourtyardWallPadder padding2 = new ComponentNagaCourtyardWallPadder(getFeatureType(), (widthInCellCount-1) - cornerClipping[0][1], boundingBox.minX + (((widthInCellCount-1) - cornerClipping[0][1]) * 12) + offset - 4, boundingBox.minY, boundingBox.minZ - 3, Rotation.NONE); + list.add(padding2); + padding2.buildComponent(structureComponent, list, random); + + // Bottom / South + + for (int i = cornerClipping[2][1]; i < (widthInCellCount-1) - cornerClipping[1][1]; i++) { + ComponentNagaCourtyardWall wall = new ComponentNagaCourtyardWall(getFeatureType(), i, boundingBox.minX + (i * 12) + offset - 3, boundingBox.minY, boundingBox.maxZ + 1, Rotation.NONE); + list.add(wall); + wall.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardWallPadder padding = new ComponentNagaCourtyardWallPadder(getFeatureType(), i, boundingBox.minX + (i * 12) + offset - 4, boundingBox.minY, boundingBox.maxZ + 1, Rotation.NONE); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + } + + ComponentNagaCourtyardWallPadder padding5 = new ComponentNagaCourtyardWallPadder(getFeatureType(), (widthInCellCount-1) - cornerClipping[1][1], boundingBox.minX + (((widthInCellCount-1) - cornerClipping[1][1]) * 12) + offset - 4, boundingBox.minY, boundingBox.maxZ + 1, Rotation.NONE); + list.add(padding5); + padding5.buildComponent(structureComponent, list, random); + + // Left / West + + for (int i = cornerClipping[3][0]; i < (heightInCellCount-1) - cornerClipping[2][0]; i++) { + ComponentNagaCourtyardWall wall = new ComponentNagaCourtyardWall(getFeatureType(), i, boundingBox.minX - 11, boundingBox.minY, boundingBox.minZ + (i * 12) + offset - 3, Rotation.CLOCKWISE_90); + list.add(wall); + wall.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardWallPadder padding = new ComponentNagaCourtyardWallPadder(getFeatureType(), i, boundingBox.minX - 1, boundingBox.minY, boundingBox.minZ + (i * 12) + offset - 4, Rotation.CLOCKWISE_90); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + } + + ComponentNagaCourtyardWallPadder padding8 = new ComponentNagaCourtyardWallPadder(getFeatureType(), (heightInCellCount-1) - cornerClipping[2][0], boundingBox.minX - 1, boundingBox.minY, boundingBox.minZ + (((heightInCellCount-1) - cornerClipping[2][0]) * 12) + offset - 4, Rotation.CLOCKWISE_90); + list.add(padding8); + padding8.buildComponent(structureComponent, list, random); + + // Right / East + + for (int i = cornerClipping[0][0]; i < (heightInCellCount-1) - cornerClipping[1][0]; i++) { + ComponentNagaCourtyardWall wall = new ComponentNagaCourtyardWall(getFeatureType(), i, boundingBox.maxX - 7, boundingBox.minY, boundingBox.minZ + (i * 12) + offset - 3, Rotation.CLOCKWISE_90); + list.add(wall); + wall.buildComponent(structureComponent, list, random); + + ComponentNagaCourtyardWallPadder padding = new ComponentNagaCourtyardWallPadder(getFeatureType(), i, boundingBox.maxX + 3, boundingBox.minY, boundingBox.minZ + (i * 12) + offset - 4, Rotation.CLOCKWISE_90); + list.add(padding); + padding.buildComponent(structureComponent, list, random); + } + + ComponentNagaCourtyardWallPadder padding11 = new ComponentNagaCourtyardWallPadder(getFeatureType(), ((heightInCellCount-1) - cornerClipping[1][0]), boundingBox.maxX + 3, boundingBox.minY, boundingBox.minZ + (((heightInCellCount-1) - cornerClipping[1][0]) * 12) + offset - 4, Rotation.CLOCKWISE_90); + list.add(padding11); + padding11.buildComponent(structureComponent, list, random); + } + + private static String getStringFromFacings(int directions) { + switch (directions & 0b1111) { + case 0b0010: + return " ╷ "; + case 0b0001: + return " ╶─"; + case 0b1000: + return " ╵ "; + case 0b0100: + return "─╴ "; + case 0b1001: + return " └─"; + case 0b1100: + return "─┘ "; + case 0b0110: + return "─┐ "; + case 0b0011: + return " ┌─"; + case 0b1101: + return "─┴─"; + case 0b1110: + return "─┤ "; + case 0b0111: + return "─┬─"; + case 0b1011: + return " ├─"; + case 0b1010: + return " │ "; + case 0b0101: + return "───"; + case 0b1111: + return "─┼─"; + default: + return " • "; + } + } + + protected enum WallFacing { + EAST (0b0001, 0b0100, 0b1110, 0b1011, EnumFacing.EAST , 1, 0), + SOUTH(0b0010, 0b1000, 0b1101, 0b0111, EnumFacing.SOUTH, 0, 1), + WEST (0b0100, 0b0001, 0b1011, 0b1110, EnumFacing.WEST , -1, 0), + NORTH(0b1000, 0b0010, 0b0111, 0b1101, EnumFacing.NORTH, 0, -1); + + private final int BYTE; + private final int OPPOSITE; + private final int INVERTED; + private final int INVERTED_OPPOSITE; + private final EnumFacing enumFacing; + private final int xOffset; + private final int zOffset; + + WallFacing(int bite, int oppositeBite, int inverted, int invertedOpposite, EnumFacing enumFacing, int xOffset, int zOffset) { + this.BYTE = bite; + this.OPPOSITE = oppositeBite; + this.INVERTED = inverted; + this.INVERTED_OPPOSITE = invertedOpposite; + this.enumFacing = enumFacing; + this.xOffset = xOffset; + this.zOffset = zOffset; + } + + protected boolean unpackAndTest(int directions) { + return (this.BYTE & directions) == this.BYTE; + } + + protected boolean unpackAndTestOpposite(int directions) { + return (this.OPPOSITE & directions) == this.OPPOSITE; + } + + public EnumFacing getEnumFacing() { + return enumFacing; + } + } + + @Override + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + NBTTagList mazeX = new NBTTagList(); + + for (int x = 0; x < widthInCellCount-1; x++) { + NBTTagList mazeY = new NBTTagList(); + + for (int y = 0; y < heightInCellCount-1; y++) mazeY.appendTag(new NBTTagInt(maze[x][y])); + + mazeX.appendTag(mazeY); + } + + tagCompound.setInteger("mazeWidth", widthInCellCount); + tagCompound.setInteger("mazeHeight", heightInCellCount); + tagCompound.setTag("maze", mazeX); + } + + @Override + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + + this.widthInCellCount = tagCompound.getInteger("mazeWidth"); + this.heightInCellCount = tagCompound.getInteger("mazeHeight"); + + maze = new int[this.widthInCellCount-1][this.heightInCellCount-1]; + + NBTTagList mazeX = tagCompound.getTagList("maze", 9); + + for (int x = 0; x < widthInCellCount-1; x++) { + NBTBase mazeY = mazeX.get(x); + + if (mazeY instanceof NBTTagList) + for (int y = 0; y < heightInCellCount - 1; y++) maze[x][y] = ((NBTTagList) mazeY).getIntAt(y); + } + } +} diff --git a/src/main/java/twilightforest/structures/courtyard/package-info.java b/src/main/java/twilightforest/structures/courtyard/package-info.java new file mode 100644 index 0000000000..78dd782e69 --- /dev/null +++ b/src/main/java/twilightforest/structures/courtyard/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.structures.courtyard; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBalcony.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBalcony.java index 1a719f7003..c8512605a4 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBalcony.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBalcony.java @@ -1,52 +1,48 @@ package twilightforest.structures.darktower; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerWing; -public class ComponentTFDarkTowerBalcony extends ComponentTFTowerWing -{ - +import java.util.List; +import java.util.Random; + +public class ComponentTFDarkTowerBalcony extends ComponentTFTowerWing { + public ComponentTFDarkTowerBalcony() { - super(); - // TODO Auto-generated constructor stub } - protected ComponentTFDarkTowerBalcony(int i, int x, int y, int z, int direction) { - super(i, x, y, z, 5, 5, direction); + protected ComponentTFDarkTowerBalcony(TFFeature feature, int i, int x, int y, int z, EnumFacing direction) { + super(feature, i, x, y, z, 5, 5, direction); } - @SuppressWarnings("rawtypes") @Override - public void buildComponent(StructureComponent parent, List list, Random rand) - { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make floor - fillWithMetadataBlocks(world, sbb, 0, 0, 0, 2, 0, 4, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 0, 0, 1, 1, 0, 3, deco.blockID, deco.blockMeta, Blocks.air, 0, false); - - fillWithMetadataBlocks(world, sbb, 0, 1, 0, 2, 1, 4, deco.fenceID, deco.fenceMeta, Blocks.air, 0, false); + fillWithBlocks(world, sbb, 0, 0, 0, 2, 0, 4, deco.accentState, Blocks.AIR.getDefaultState(), false); + fillWithBlocks(world, sbb, 0, 0, 1, 1, 0, 3, deco.blockState, Blocks.AIR.getDefaultState(), false); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, 2, 1, 0, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, 2, 1, 4, sbb); + fillWithBlocks(world, sbb, 0, 1, 0, 2, 1, 4, deco.fenceState, Blocks.AIR.getDefaultState(), false); + + this.setBlockState(world, deco.accentState, 2, 1, 0, sbb); + this.setBlockState(world, deco.accentState, 2, 1, 4, sbb); // clear inside fillWithAir(world, sbb, 0, 1, 1, 1, 1, 3); - + return true; } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBeard.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBeard.java index c5441ab71b..de47754c8c 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBeard.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBeard.java @@ -1,17 +1,21 @@ package twilightforest.structures.darktower; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFTowerWood; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; +import twilightforest.enums.TowerWoodVariant; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.Random; -public class ComponentTFDarkTowerBeard extends StructureTFComponent { + +public class ComponentTFDarkTowerBeard extends StructureTFComponentOld { protected int size; protected int height; @@ -20,37 +24,31 @@ public ComponentTFDarkTowerBeard() { super(); } - public ComponentTFDarkTowerBeard(int i, ComponentTFTowerWing wing) { - super(i); - + public ComponentTFDarkTowerBeard(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i); + this.setCoordBaseMode(wing.getCoordBaseMode()); this.size = wing.size; this.height = size / 2; - + // just hang out at the very bottom of the tower this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX, wing.getBoundingBox().minY - this.height, wing.getBoundingBox().minZ, wing.getBoundingBox().maxX, wing.getBoundingBox().minY, wing.getBoundingBox().maxZ); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("beardSize", this.size); - par1NBTTagCompound.setInteger("beardHeight", this.height); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("beardSize", this.size); + tagCompound.setInteger("beardHeight", this.height); } - - /** - * Load from NBT - */ + @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.size = par1NBTTagCompound.getInteger("beardSize"); - this.height = par1NBTTagCompound.getInteger("beardHeight"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.size = tagCompound.getInteger("beardSize"); + this.height = tagCompound.getInteger("beardHeight"); } @@ -58,41 +56,32 @@ protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { * Makes a dark tower type beard */ @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) - { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { makeDarkBeard(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1); - - return true; + + return true; } - - protected void makeDarkBeard(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) - { - Block frameID = TFBlocks.towerWood; - int frameMeta = 1; - - for (int x = minX; x <= maxX; x++) - { - for (int z = minZ; z <= maxZ; z++) - { - if (x == minX || x == maxX || z == minZ || z == maxZ) - { - int length = Math.min(Math.abs(x - height) - 1, Math.abs(z - height) - 1) ; - - if (length == height - 1) - { - length ++; + + protected void makeDarkBeard(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + IBlockState frameState = TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.ENCASED); + + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + if (x == minX || x == maxX || z == minZ || z == maxZ) { + int length = Math.min(Math.abs(x - height) - 1, Math.abs(z - height) - 1); + + if (length == height - 1) { + length++; } - - if (length == -1) - { + + if (length == -1) { length = 1; } - - for (int y = maxY; y >= height - length; y--) - { + + for (int y = maxY; y >= height - length; y--) { // wall - this.placeBlockAtCurrentPosition(world, frameID, frameMeta, x, y, z, sbb); + this.setBlockState(world, frameState, x, y, z, sbb); } } } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossBridge.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossBridge.java index 86327e2ff5..85dc20de28 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossBridge.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossBridge.java @@ -1,29 +1,31 @@ package twilightforest.structures.darktower; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + import java.util.List; import java.util.Random; -import net.minecraft.world.gen.structure.StructureComponent; - public class ComponentTFDarkTowerBossBridge extends ComponentTFDarkTowerBridge { public ComponentTFDarkTowerBossBridge() { - super(); - // TODO Auto-generated constructor stub } - - protected ComponentTFDarkTowerBossBridge(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); + protected ComponentTFDarkTowerBossBridge(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + + @Override + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // make another size 15 main tower - int direction = (getCoordBaseMode() + rotation) % 4; + + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - ComponentTFDarkTowerBossTrap wing = new ComponentTFDarkTowerBossTrap(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFDarkTowerBossTrap wing = new ComponentTFDarkTowerBossTrap(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); list.add(wing); wing.buildComponent(this, list, rand); addOpening(x, y, z, rotation); diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossTrap.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossTrap.java index b2c23e28a8..dee802ae3e 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossTrap.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBossTrap.java @@ -1,50 +1,48 @@ package twilightforest.structures.darktower; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; -public class ComponentTFDarkTowerBossTrap extends ComponentTFDarkTowerWing -{ +import static twilightforest.enums.TowerDeviceVariant.GHASTTRAP_INACTIVE; + +public class ComponentTFDarkTowerBossTrap extends ComponentTFDarkTowerWing { public ComponentTFDarkTowerBossTrap() { - super(); - // TODO Auto-generated constructor stub } - protected ComponentTFDarkTowerBossTrap(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); - + protected ComponentTFDarkTowerBossTrap(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); + // no spawns this.spawnListIndex = -1; } - - @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) - { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - + // we should have a door where we started - addOpening(0, 1, size / 2, 2); + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); // add a beard makeABeard(parent, list, rand); - - for (int i = 0; i < 4; i++) - { - if (i == 2 || rand.nextBoolean()) - { + + for (Rotation i : RotationUtil.ROTATIONS) { + if (i == Rotation.CLOCKWISE_180 || rand.nextBoolean()) { continue; } // occasional balcony @@ -58,64 +56,65 @@ public void buildComponent(StructureComponent parent, List list, Random rand) /** * Attach a roof to this tower. */ + @Override public void makeARoof(StructureComponent parent, List list, Random rand) { //nope; } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); // make walls makeEncasedWalls(world, rand, sbb, 0, 0, 0, size - 1, height - 1, size - 1); - + // clear inside fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); - - // openings - makeOpenings(world, sbb); - + + // openings + makeOpenings(world, sbb); + // half floors, always starting at y = 4 addBossTrapFloors(world, decoRNG, sbb, 4, height - 1); - - // demolish some + + // demolish some destroyTower(world, decoRNG, 5, height + 2, 5, 4, sbb); destroyTower(world, decoRNG, 0, height, 0, 3, sbb); destroyTower(world, decoRNG, 0, height, 8, 4, sbb); - + // hole for boss trap beam destroyTower(world, decoRNG, 5, 6, 5, 2, sbb); - + // redraw some of the floor in case we destroyed it - this.fillWithMetadataBlocks(world, sbb, 1, 0, 1, size / 2, 0, size - 2, deco.blockID, deco.blockMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 1, 1, 1, size / 2, 1, size - 2, Blocks.air, 0, Blocks.air, 0, false); - + this.fillWithBlocks(world, sbb, 1, 0, 1, size / 2, 0, size - 2, deco.blockState, Blocks.AIR.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 1, 1, 1, size / 2, 1, size - 2, Blocks.AIR.getDefaultState(), Blocks.AIR.getDefaultState(), false); + // add boss trap - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_GHASTTRAP_INACTIVE, 5, 1, 5, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.redstone_wire, 0, 5, 1, 6, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.redstone_wire, 0, 5, 1, 7, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.redstone_wire, 0, 5, 1, 8, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.redstone_wire, 0, 4, 1, 8, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.redstone_wire, 0, 3, 1, 8, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.wooden_pressure_plate, 0, 2, 1, 8, sbb); - + this.setBlockState(world, TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, GHASTTRAP_INACTIVE), 5, 1, 5, sbb); + this.setBlockState(world, Blocks.REDSTONE_WIRE.getDefaultState(), 5, 1, 6, sbb); + this.setBlockState(world, Blocks.REDSTONE_WIRE.getDefaultState(), 5, 1, 7, sbb); + this.setBlockState(world, Blocks.REDSTONE_WIRE.getDefaultState(), 5, 1, 8, sbb); + this.setBlockState(world, Blocks.REDSTONE_WIRE.getDefaultState(), 4, 1, 8, sbb); + this.setBlockState(world, Blocks.REDSTONE_WIRE.getDefaultState(), 3, 1, 8, sbb); + this.setBlockState(world, Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(), 2, 1, 8, sbb); + return true; } - + /** * Add specific boss trap floors */ protected void addBossTrapFloors(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) { - makeFullFloor(world, sbb, 3, 4, 4); + makeFullFloor(world, sbb, Rotation.COUNTERCLOCKWISE_90, 4, 4); - addStairsDown(world, sbb, 3, 4, size - 2, 4); - addStairsDown(world, sbb, 3, 4, size - 3, 4); + addStairsDown(world, sbb, Rotation.COUNTERCLOCKWISE_90, 4, size - 2, 4); + addStairsDown(world, sbb, Rotation.COUNTERCLOCKWISE_90, 4, size - 3, 4); // stairs to roof - addStairsDown(world, sbb, 1, this.height - 1, size - 2, 4); - addStairsDown(world, sbb, 1, this.height - 1, size - 3, 4); + addStairsDown(world, sbb, Rotation.CLOCKWISE_90, this.height - 1, size - 2, 4); + addStairsDown(world, sbb, Rotation.CLOCKWISE_90, this.height - 1, size - 3, 4); } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBridge.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBridge.java index 8dd3fd0b28..d70f9c61c1 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBridge.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerBridge.java @@ -1,107 +1,101 @@ package twilightforest.structures.darktower; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerWing; -public class ComponentTFDarkTowerBridge extends ComponentTFTowerWing -{ - +import java.util.List; +import java.util.Random; + +public class ComponentTFDarkTowerBridge extends ComponentTFTowerWing { + public ComponentTFDarkTowerBridge() { - super(); } - int dSize; - int dHeight; - - protected ComponentTFDarkTowerBridge(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, 5, 5, direction); - + private int dSize; + private int dHeight; + + protected ComponentTFDarkTowerBridge(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, 5, 5, direction); + this.dSize = pSize; this.dHeight = pHeight; } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) - { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - makeTowerWing(list, rand, this.getComponentType(), 4, 1, 2, dSize, dHeight, 0); + makeTowerWing(list, rand, this.getComponentType(), 4, 1, 2, dSize, dHeight, Rotation.NONE); } - - - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + + + @Override + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // kill too-small towers if (wingHeight < 6) { return false; } - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - - if (dx[1] + wingHeight > 255) - { + + if (dx[1] + wingHeight > 255) { // end of the world! return false; } - ComponentTFTowerWing wing = new ComponentTFDarkTowerWing(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFTowerWing wing = new ComponentTFDarkTowerWing(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, wing.getBoundingBox()); - if (intersect == null || intersect == this) - { + if (intersect == null || intersect == this) { list.add(wing); wing.buildComponent(this, list, rand); addOpening(x, y, z, rotation); return true; - } - else - { - //System.out.println("Planned wing intersects with " + intersect); + } else { return false; } } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make walls - fillWithBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, deco.blockID, deco.blockID, false); + fillWithBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, deco.blockState, deco.blockState, false); // accents - for (int x = 0; x < size; x++) - { - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, 0, 0, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, height - 1, 0, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, 0, size - 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, height - 1, size - 1, sbb); + for (int x = 0; x < size; x++) { + this.setBlockState(world, deco.accentState, x, 0, 0, sbb); + this.setBlockState(world, deco.accentState, x, height - 1, 0, sbb); + this.setBlockState(world, deco.accentState, x, 0, size - 1, sbb); + this.setBlockState(world, deco.accentState, x, height - 1, size - 1, sbb); } - // nullify sky light + // nullify sky light nullifySkyLightForBoundingBox(world); - + // clear inside fillWithAir(world, sbb, 0, 1, 1, size - 1, height - 2, size - 2); - + return true; } /** * Gets the bounding box of the tower wing we would like to make. + * * @return */ public StructureBoundingBox getWingBB() { int[] dest = offsetTowerCoords(4, 1, 2, dSize, this.getCoordBaseMode()); - return StructureTFComponent.getComponentToAddBoundingBox(dest[0], dest[1], dest[2], 0, 0, 0, dSize - 1, dHeight - 1, dSize - 1, this.getCoordBaseMode()); + return StructureTFComponentOld.getComponentToAddBoundingBox(dest[0], dest[1], dest[2], 0, 0, 0, dSize - 1, dHeight - 1, dSize - 1, this.getCoordBaseMode()); } } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntrance.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntrance.java index a16e483b27..b9c02a1fe1 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntrance.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntrance.java @@ -1,75 +1,62 @@ package twilightforest.structures.darktower; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; -public class ComponentTFDarkTowerEntrance extends ComponentTFDarkTowerWing -{ +public class ComponentTFDarkTowerEntrance extends ComponentTFDarkTowerWing { public ComponentTFDarkTowerEntrance() { - super(); - // TODO Auto-generated constructor stub } - protected ComponentTFDarkTowerEntrance(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); + protected ComponentTFDarkTowerEntrance(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - - @SuppressWarnings("rawtypes") + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) - { + public void buildComponent(StructureComponent parent, List list, Random rand) { super.buildComponent(parent, list, rand); - + // a few more openings - addOpening(size / 2, 1, 0, 1, EnumDarkTowerDoor.REAPPEARING); - addOpening(size / 2, 1, size - 1, 3, EnumDarkTowerDoor.REAPPEARING); + addOpening(size / 2, 1, 0, Rotation.CLOCKWISE_90, EnumDarkTowerDoor.REAPPEARING); + addOpening(size / 2, 1, size - 1, Rotation.COUNTERCLOCKWISE_90, EnumDarkTowerDoor.REAPPEARING); } - - /** - * Add a beard to this structure. There is only one type of beard. - */ + @Override public void makeABeard(StructureComponent parent, List list, Random rand) { - //nope; } - - /** - * Attach a roof to this tower. - */ + @Override - public void makeARoof(StructureComponent parent, List list, Random rand) - { - // nope + public void makeARoof(StructureComponent parent, List list, Random rand) { } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make walls makeEncasedWalls(world, rand, sbb, 0, 0, 0, size - 1, height - 1, size - 1); - + // deco to ground - for (int x = 0; x < this.size; x++) - { - for (int z = 0; z < this.size; z++) - { - this.func_151554_b(world, deco.accentID, deco.accentMeta, x, -1, z, sbb); + for (int x = 0; x < this.size; x++) { + for (int z = 0; z < this.size; z++) { + this.setBlockState(world, deco.accentState, x, -1, z, sbb); } } - + // clear inside fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); // sky light nullifySkyLightForBoundingBox(world); - - // openings - makeOpenings(world, sbb); - + + // openings + makeOpenings(world, sbb); + return true; } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntranceBridge.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntranceBridge.java index 83cdd183e9..32cb82561d 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntranceBridge.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerEntranceBridge.java @@ -1,28 +1,29 @@ package twilightforest.structures.darktower; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + import java.util.List; import java.util.Random; -import net.minecraft.world.gen.structure.StructureComponent; - -public class ComponentTFDarkTowerEntranceBridge extends ComponentTFDarkTowerBridge -{ +public class ComponentTFDarkTowerEntranceBridge extends ComponentTFDarkTowerBridge { public ComponentTFDarkTowerEntranceBridge() { - super(); - // TODO Auto-generated constructor stub } - protected ComponentTFDarkTowerEntranceBridge(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); + protected ComponentTFDarkTowerEntranceBridge(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + @Override + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // make an entrance tower - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - ComponentTFDarkTowerWing wing = new ComponentTFDarkTowerEntrance(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFDarkTowerWing wing = new ComponentTFDarkTowerEntrance(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); list.add(wing); wing.buildComponent(this, list, rand); diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMain.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMain.java index 4a92d7821c..d935056c9e 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMain.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMain.java @@ -1,10 +1,7 @@ package twilightforest.structures.darktower; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.*; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.item.EntityItemFrame; import net.minecraft.init.Blocks; import net.minecraft.init.Items; @@ -12,50 +9,68 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntityMobSpawner; -import net.minecraft.util.Facing; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenForest; +import net.minecraft.world.gen.feature.WorldGenBirchTree; import net.minecraft.world.gen.feature.WorldGenTrees; import net.minecraft.world.gen.feature.WorldGenerator; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.BlockTFLog; import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; +import twilightforest.enums.BossVariant; +import twilightforest.enums.TowerDeviceVariant; +import twilightforest.enums.WoodVariant; import twilightforest.item.TFItems; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.StructureTFDecorator; import twilightforest.structures.TFMaze; -import twilightforest.world.TFGenSmallRainboak; -import twilightforest.world.TFGenSmallTwilightOak; -import cpw.mods.fml.common.FMLLog; +import twilightforest.util.RotationUtil; +import twilightforest.util.TFEntityNames; +import twilightforest.util.VanillaEntityNames; +import twilightforest.world.feature.TFGenSmallRainboak; +import twilightforest.world.feature.TFGenSmallTwilightOak; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; -public class ComponentTFDarkTowerMain extends ComponentTFDarkTowerWing +import static net.minecraft.util.EnumFacing.EAST; +import static net.minecraft.util.EnumFacing.WEST; + +public class ComponentTFDarkTowerMain extends ComponentTFDarkTowerWing { private boolean placedKeys = false; - public ComponentTFDarkTowerMain() { - super(); - // TODO Auto-generated constructor stub + public ComponentTFDarkTowerMain() + { } - public ComponentTFDarkTowerMain(World world, Random rand, int index, int x, int y, int z) { - this(world, rand, index, x + 10, y, z + 10, 2); + public ComponentTFDarkTowerMain(TFFeature feature, World world, Random rand, int index, int x, int y, int z) + { + this(feature, world, rand, index, x + 10, y, z + 10, EnumFacing.NORTH); } - public ComponentTFDarkTowerMain(World world, Random rand, int index, int x, int y, int z, int rotation) { - super(index, x, y, z, 19, 56 + ((rand.nextInt(32) / 5) * 5), rotation); - + public ComponentTFDarkTowerMain(TFFeature feature, World world, Random rand, int index, int x, int y, int z, EnumFacing rotation) + { + super(feature, index, x, y, z, 19, 56 + ((rand.nextInt(32) / 5) * 5), rotation); + // check to make sure we can build the whole tower if (this.boundingBox.maxY > 245) { int amtToLower = (((this.boundingBox.maxY - 245) / 5) * 5) + 5; - FMLLog.info("[TwilightForest] Lowering Dark Tower max height by %d to be within world bounds", amtToLower); - + TwilightForestMod.LOGGER.info("Lowering Dark Tower max height by {} to be within world bounds", amtToLower); + this.height -= amtToLower; this.boundingBox.maxY -= amtToLower; } @@ -67,47 +82,47 @@ public ComponentTFDarkTowerMain(World world, Random rand, int index, int x, int } } - - @SuppressWarnings({ "rawtypes", "unchecked", "unused" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) + public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) + if (parent != null && parent instanceof StructureTFComponentOld) { - this.deco = ((StructureTFComponent)parent).deco; + this.deco = ((StructureTFComponentOld)parent).deco; } - + // if this is not the first main part, add one if (this.getComponentType() > 0) { - addOpening(0, 1, size / 2, 2); + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); } - + // one direction gets a new main tower, unless we're at tower #3 - int mainDir = -1; - + Rotation mainDir = null; + if (this.getComponentType() < 2) { - mainDir = rand.nextInt(4); + mainDir = RotationUtil.ROTATIONS[rand.nextInt(RotationUtil.ROTATIONS.length)]; // make sub towers - for (int i = 0; i < 4; i++) { - if (i == mainDir) + for (Rotation rotation : RotationUtil.ROTATIONS) + { + if (rotation == mainDir) { continue; } - int[] dest = getValidOpening(rand, i); + int[] dest = getValidOpening(rand, rotation); int childHeight = validateChildHeight(21 + rand.nextInt(10), 11); - makeTowerWing(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], 11, childHeight, i); + makeTowerWing(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], 11, childHeight, rotation); } } else { // make boss trap towers - for (int i = 0; i < 4; i++) { + for (Rotation i : RotationUtil.ROTATIONS) + { int[] dest = getValidOpening(rand, i); makeBossTrapWing(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], i); } @@ -116,19 +131,20 @@ public void buildComponent(StructureComponent parent, List list, Random rand) if (this.getComponentType() > 0) { // sub towers at base of tower - for (int i = 0; i < 4; i++) { - if (i == 2) + for (Rotation i : RotationUtil.ROTATIONS) + { + if (i == Rotation.CLOCKWISE_180) { continue; } int[] dest = getValidOpening(rand, i); - + // move opening to tower base dest[1] = 1; int childHeight = validateChildHeight(21 + rand.nextInt(10), 11); - + makeTowerWing(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], 11, childHeight, i); } @@ -138,61 +154,53 @@ public void buildComponent(StructureComponent parent, List list, Random rand) else { // 2 entrance towers towers at base of tower - for (int i = 0; i < 4; i += 2) { + for (Rotation rotation : new Rotation[] {Rotation.NONE, Rotation.CLOCKWISE_180}) + { + + int[] dest = getValidOpening(rand, rotation); - int[] dest = getValidOpening(rand, i); - // move opening to tower base dest[1] = 1; int childHeight = validateChildHeight(10 + rand.nextInt(5), 9); - - makeEntranceTower(list, rand, 5, dest[0], dest[1], dest[2], 9, childHeight, i); + + makeEntranceTower(list, rand, 5, dest[0], dest[1], dest[2], 9, childHeight, rotation); } } - + // actually make main tower - if (mainDir > -1) + if (mainDir != null) { int[] dest = getValidOpening(rand, mainDir); makeNewLargeTower(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], mainDir); } - + // add a roof? makeARoof(parent, list, rand); - + // flag certain towers for keys if (!this.placedKeys && this.getComponentType() < 2) { // count how many size 9 towers we have hanging off us ArrayList possibleKeyTowers = new ArrayList(); - int smallTowers = 0; for (Object piece : list) { if (piece instanceof ComponentTFDarkTowerWing) { - ComponentTFDarkTowerWing wing = (ComponentTFDarkTowerWing) piece; + ComponentTFDarkTowerWing wing = (ComponentTFDarkTowerWing)piece; if (wing.size == 9 && wing.getComponentType() == this.getComponentType()) - { - //System.out.println("I found one of my small towers! Its type is " + wing.getComponentType() + " and mine is " + this.getComponentType()); - - smallTowers++; - possibleKeyTowers.add(wing); - } } } - //System.out.println("I found " + smallTowers + " of my small towers total, with index " + this.getComponentType() + " ."); - for (int i = 0; i < 4; i++) { if (possibleKeyTowers.size() < 1) { - FMLLog.warning("[TwilightForest] Dark forest tower could not find four small towers to place keys in."); + TwilightForestMod.LOGGER.warn("Dark forest tower could not find four small towers to place keys in."); break; } @@ -210,12 +218,12 @@ public void buildComponent(StructureComponent parent, List list, Random rand) /** * Make a bridge that leads to an entrance tower */ - private boolean makeEntranceTower(List list, Random rand, int index, int x, int y, int z, int childSize, int childHeight, int rotation) + private boolean makeEntranceTower(List list, Random rand, int index, int x, int y, int z, int childSize, int childHeight, Rotation rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 5, direction); - ComponentTFDarkTowerBridge bridge = new ComponentTFDarkTowerEntranceBridge(index, dx[0], dx[1], dx[2], childSize, childHeight, direction); + ComponentTFDarkTowerBridge bridge = new ComponentTFDarkTowerEntranceBridge(getFeatureType(), index, dx[0], dx[1], dx[2], childSize, childHeight, direction); // if I'm doing this right, the main towers can't intersect list.add(bridge); bridge.buildComponent(this, list, rand); @@ -226,15 +234,16 @@ private boolean makeEntranceTower(List list, Random rand, in /** * Make a bridge that leads to a new large-size tower */ - private boolean makeNewLargeTower(List list, Random rand, int index, int x, int y, int z, int rotation) { + private boolean makeNewLargeTower(List list, Random rand, int index, int x, int y, int z, Rotation rotation) + { int wingSize = 15; int wingHeight = 56; - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 5, direction); - ComponentTFDarkTowerMainBridge bridge = new ComponentTFDarkTowerMainBridge(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFDarkTowerMainBridge bridge = new ComponentTFDarkTowerMainBridge(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // if I'm doing this right, the main towers can't intersect list.add(bridge); bridge.buildComponent(this, list, rand); @@ -242,19 +251,20 @@ private boolean makeNewLargeTower(List list, Random rand, in addOpening(x, y, z, rotation, EnumDarkTowerDoor.LOCKED); return true; } - + /** * Make a bridge that leads to a boss trap tower */ - private boolean makeBossTrapWing(List list, Random rand, int index, int x, int y, int z, int rotation) { + private boolean makeBossTrapWing(List list, Random rand, int index, int x, int y, int z, Rotation rotation) + { int wingSize = 11; int wingHeight = 9; - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 5, direction); - ComponentTFDarkTowerBossBridge bridge = new ComponentTFDarkTowerBossBridge(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFDarkTowerBossBridge bridge = new ComponentTFDarkTowerBossBridge(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // if I'm doing this right, the main towers can't intersect list.add(bridge); bridge.buildComponent(this, list, rand); @@ -262,12 +272,12 @@ private boolean makeBossTrapWing(List list, Random rand, int addOpening(x, y, z, rotation); return true; } - + /** * Attach a roof to this tower. */ @Override - public void makeARoof(StructureComponent parent, List list, Random rand) + public void makeARoof(StructureComponent parent, List list, Random rand) { if (this.getComponentType() < 2) { @@ -276,12 +286,13 @@ public void makeARoof(StructureComponent parent, List list, } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) + { Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); // make walls makeEncasedWalls(world, rand, sbb, 0, 0, 0, size - 1, height - 1, size - 1); - + // clear inside fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); @@ -292,33 +303,33 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox { for (int z = 0; z < this.size; z++) { - this.func_151554_b(world, deco.accentID, deco.accentMeta, x, -1, z, sbb); + this.setBlockState(world, deco.accentState, x, -1, z, sbb); } } } - - // nullify sky light + + // nullify sky light this.nullifySkyLightForBoundingBox(world); - + // how many total floors do we have? int totalFloors = this.height / 5; - + // is the tower a beam maze? false = builder platforms boolean beamMaze = decoRNG.nextBoolean(); - + // how many floors should the center occupy? int centerFloors = beamMaze ? 4 : totalFloors / 2; - + // how many floors do we get on the top/bottom portion? int bottomFloors = (totalFloors - centerFloors) / 2; - + // readjust center floors if we have leftover floors centerFloors = totalFloors - (bottomFloors * 2); - + // where do the top floors start? int topFloorsStartY = height - (bottomFloors * 5 + 1); - - // add bottom and top floors + + // add bottom and top floors addThreeQuarterFloors(world, decoRNG, sbb, 0, bottomFloors * 5); if (this.getComponentType() < 2) { @@ -328,18 +339,18 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox { addThreeQuarterFloorsDecorateBoss(world, decoRNG, sbb, topFloorsStartY, height - 1); // boss destruction - + destroyTower(world, decoRNG, 12, height + 4, 3, 4, sbb); destroyTower(world, decoRNG, 3, height + 4, 12, 4, sbb); destroyTower(world, decoRNG, 3, height + 4, 3, 4, sbb); destroyTower(world, decoRNG, 12, height + 4, 12, 4, sbb); destroyTower(world, decoRNG, 8, height + 4, 8, 5, sbb); - + // make spawner where it will hopefully last - decorateBossSpawner(world, decoRNG, sbb, 0, height - 6); + decorateBossSpawner(world, decoRNG, sbb, Rotation.NONE, height - 6); } - + if (beamMaze) { addTimberMaze(world, decoRNG, sbb, (bottomFloors * 5), topFloorsStartY); @@ -348,27 +359,27 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox { addBuilderPlatforms(world, decoRNG, sbb, (bottomFloors * 5), topFloorsStartY); } - - // openings - makeOpenings(world, sbb); + // openings + makeOpenings(world, sbb); - return true; + + return true; } - - + + /** * Add a bunch of 3/4 floors */ - protected void addThreeQuarterFloors(World world, Random decoRNG, StructureBoundingBox sbb, int bottom, int top) { - + protected void addThreeQuarterFloors(World world, Random decoRNG, StructureBoundingBox sbb, int bottom, int top) + { + int spacing = 5; - int rotation = (this.boundingBox.minY + bottom) % 4; + Rotation rotation = RotationUtil.ROTATIONS[(this.boundingBox.minY + bottom) % 4]; if (bottom == 0) { makeLargeStairsUp(world, sbb, rotation, 0); - rotation += 3; - rotation %= 4; + rotation = rotation.add(Rotation.COUNTERCLOCKWISE_90); makeBottomEntrance(world, decoRNG, sbb, rotation, bottom); bottom += spacing; } @@ -379,81 +390,78 @@ protected void addThreeQuarterFloors(World world, Random decoRNG, StructureBound boolean isBottomFloor = (y == bottom && bottom != spacing); boolean isTopFloor = (y >= top - spacing); boolean isTowerTopFloor = (y >= height - spacing - 2); - + makeThreeQuarterFloor(world, sbb, rotation, y, isBottomFloor, isTowerTopFloor); if (!isTopFloor) { makeLargeStairsUp(world, sbb, rotation, y); } - + if (!isTopFloor || isTowerTopFloor) { decorateFloor(world, decoRNG, sbb, rotation, y, isBottomFloor, isTopFloor); } - - rotation += 3; - rotation %= 4; + rotation = rotation.add(Rotation.COUNTERCLOCKWISE_90); } } /** * Add a bunch of 3/4 floors */ - protected void addThreeQuarterFloorsDecorateBoss(World world, Random decoRNG, StructureBoundingBox sbb, int bottom, int top) { - + protected void addThreeQuarterFloorsDecorateBoss(World world, Random decoRNG, StructureBoundingBox sbb, int bottom, int top) + { + int spacing = 5; - int rotation = (this.boundingBox.minY + bottom) % 4; + Rotation rotation = RotationUtil.ROTATIONS[(this.boundingBox.minY + bottom) % 4]; if (bottom == 0) { makeLargeStairsUp(world, sbb, rotation, 0); - rotation += 3; - rotation %= 4; + rotation = rotation.add(Rotation.COUNTERCLOCKWISE_90); bottom += spacing; } - + // fill with 3/4 floors for (int y = bottom; y < top; y += spacing) { boolean isBottomFloor = (y == bottom && bottom != spacing); boolean isTopFloor = (y >= top - spacing); boolean isTowerTopFloor = (y >= height - spacing - 2); - + makeThreeQuarterFloor(world, sbb, rotation, y, isBottomFloor, isTowerTopFloor); - + if (!isTopFloor) { makeLargeStairsUp(world, sbb, rotation, y); decorateExperiment(world, decoRNG, sbb, rotation, y); - + } - - rotation += 3; - rotation %= 4; - + + rotation = rotation.add(Rotation.COUNTERCLOCKWISE_90); } } - private void decorateFloor(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y, boolean isBottom, boolean isTop) { + private void decorateFloor(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y, boolean isBottom, boolean isTop) + { // pick an appropriate decoration and use it - + if (isTop) { // there are a limited amount that can go at the top switch (decoRNG.nextInt(3)) { - default: - case 0: - decorateAquarium(world, decoRNG, sbb, rotation, y); - break; - case 1: - decorateBotanical(world, decoRNG, sbb, rotation, y); - break; - case 2: - decorateNetherwart(world, decoRNG, sbb, rotation, y, isTop); - break; + default: + case 0: + decorateAquarium(world, decoRNG, sbb, rotation, y); + break; + case 1: + decorateBotanical(world, decoRNG, sbb, rotation, y); + break; + case 2: + decorateNetherwart(world, decoRNG, sbb, rotation, y, isTop); + break; } } else if (isBottom) @@ -461,22 +469,22 @@ else if (isBottom) // similarly some don't work on the bottom switch (decoRNG.nextInt(4)) { - default: - case 0: - decorateAquarium(world, decoRNG, sbb, rotation, y); - break; - case 1: - decorateBotanical(world, decoRNG, sbb, rotation, y); - break; - case 2: - if (y + this.boundingBox.minY > 64) - { - decorateNetherwart(world, decoRNG, sbb, rotation, y, isTop); + default: + case 0: + decorateAquarium(world, decoRNG, sbb, rotation, y); + break; + case 1: + decorateBotanical(world, decoRNG, sbb, rotation, y); + break; + case 2: + if (y + this.boundingBox.minY > 64) + { + decorateNetherwart(world, decoRNG, sbb, rotation, y, isTop); + break; + } + case 3: + decorateForge(world, decoRNG, sbb, rotation, y); break; - } - case 3: - decorateForge(world, decoRNG, sbb, rotation, y); - break; } } else @@ -484,32 +492,32 @@ else if (isBottom) // but in the middle, anything goes switch (decoRNG.nextInt(8)) { - default: - case 0: - case 1: - decorateReappearingMaze(world, decoRNG, sbb, rotation, y); - break; - case 2: - decorateUnbuilderMaze(world, decoRNG, sbb, rotation, y); - break; - case 3: - decorateAquarium(world, decoRNG, sbb, rotation, y); - break; - case 4: - decorateBotanical(world, decoRNG, sbb, rotation, y); - break; - case 5: - if (y + this.boundingBox.minY > 64) - { - decorateNetherwart(world, decoRNG, sbb, rotation, y, isTop); + default: + case 0: + case 1: + decorateReappearingMaze(world, decoRNG, sbb, rotation, y); + break; + case 2: + decorateUnbuilderMaze(world, decoRNG, sbb, rotation, y); + break; + case 3: + decorateAquarium(world, decoRNG, sbb, rotation, y); + break; + case 4: + decorateBotanical(world, decoRNG, sbb, rotation, y); + break; + case 5: + if (y + this.boundingBox.minY > 64) + { + decorateNetherwart(world, decoRNG, sbb, rotation, y, isTop); + break; + } + case 6: + decorateLounge(world, decoRNG, sbb, rotation, y); + break; + case 7: + decorateForge(world, decoRNG, sbb, rotation, y); break; - } - case 6: - decorateLounge(world, decoRNG, sbb, rotation, y); - break; - case 7: - decorateForge(world, decoRNG, sbb, rotation, y); - break; } } } @@ -517,29 +525,31 @@ else if (isBottom) /** * Make a single three quarter floor - * @param isTowerTopFloor + * + * @param isTowerTopFloor */ - protected void makeThreeQuarterFloor(World world, StructureBoundingBox sbb, int rotation, int y, boolean isBottom, boolean isTowerTopFloor) { + protected void makeThreeQuarterFloor(World world, StructureBoundingBox sbb, Rotation rotation, int y, boolean isBottom, boolean isTowerTopFloor) + { int half = size / 2; // fill the floor - this.fillBlocksRotated(world, sbb, half + 1, y, 1, size - 2, y, half + 1, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 1, y, half + 1, size - 2, y, size - 2, deco.blockID, deco.blockMeta, rotation); + this.fillBlocksRotated(world, sbb, half + 1, y, 1, size - 2, y, half + 1, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 1, y, half + 1, size - 2, y, size - 2, deco.blockState, rotation); // don't make part of the fence if we have stairs coming up int startZ = isBottom ? 1 : 3; - - this.fillBlocksRotated(world, sbb, 1, y, half, half, y, half, deco.accentID, deco.accentMeta, rotation); - this.fillBlocksRotated(world, sbb, half, y, startZ, half, y, half, deco.accentID, deco.accentMeta, rotation); - this.fillBlocksRotated(world, sbb, 1, y + 1, half, half, y + 1, half, deco.fenceID, deco.fenceMeta, rotation); - this.fillBlocksRotated(world, sbb, half, y + 1, startZ, half, y + 1, half, deco.fenceID, deco.fenceMeta, rotation); - + + this.fillBlocksRotated(world, sbb, 1, y, half, half, y, half, deco.accentState, rotation); + this.fillBlocksRotated(world, sbb, half, y, startZ, half, y, half, deco.accentState, rotation); + this.fillBlocksRotated(world, sbb, 1, y + 1, half, half, y + 1, half, deco.fenceState, rotation); + this.fillBlocksRotated(world, sbb, half, y + 1, startZ, half, y + 1, half, deco.fenceState, rotation); + // little notch if we're at the tower top if (isTowerTopFloor) { - this.fillBlocksRotated(world, sbb, 1, y + 0, half - 2, 3, y + 0, half, deco.accentID, deco.accentMeta, rotation); - this.fillBlocksRotated(world, sbb, 1, y + 1, half - 2, 3, y + 1, half, deco.fenceID, deco.fenceMeta, rotation); - this.fillBlocksRotated(world, sbb, 1, y + 0, half - 1, 2, y + 0, half, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 1, y + 1, half - 1, 2, y + 1, half, Blocks.air, 0, rotation); + this.fillBlocksRotated(world, sbb, 1, y + 0, half - 2, 3, y + 0, half, deco.accentState, rotation); + this.fillBlocksRotated(world, sbb, 1, y + 1, half - 2, 3, y + 1, half, deco.fenceState, rotation); + this.fillBlocksRotated(world, sbb, 1, y + 0, half - 1, 2, y + 0, half, deco.fenceState, rotation); + this.fillBlocksRotated(world, sbb, 1, y + 1, half - 1, 2, y + 1, half, AIR, rotation); } } @@ -550,62 +560,63 @@ protected void makeThreeQuarterFloor(World world, StructureBoundingBox sbb, int // // for (int i = 0; i < 5; i++) // { -// placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), size / 2 - i, y - i, 1, rotation, sbb); -// placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), size / 2 - i, y - i, 2, rotation, sbb); -// placeBlockRotated(world, deco.blockID, deco.blockMeta, size / 2 - i + 1, y - i, 1, rotation, sbb); -// placeBlockRotated(world, deco.blockID, deco.blockMeta, size / 2 - i + 1, y - i, 2, rotation, sbb); -// placeBlockRotated(world, deco.blockID, deco.blockMeta, size / 2 - i + 1, y - i, 3, rotation, sbb); +// setBlockStateRotated(world, deco.stairID, getStairMeta(0 + rotation), size / 2 - i, y - i, 1, rotation, sbb); +// setBlockStateRotated(world, deco.stairID, getStairMeta(0 + rotation), size / 2 - i, y - i, 2, rotation, sbb); +// setBlockStateRotated(world, deco.blockID, deco.blockMeta, size / 2 - i + 1, y - i, 1, rotation, sbb); +// setBlockStateRotated(world, deco.blockID, deco.blockMeta, size / 2 - i + 1, y - i, 2, rotation, sbb); +// setBlockStateRotated(world, deco.blockID, deco.blockMeta, size / 2 - i + 1, y - i, 3, rotation, sbb); // // if (i > 0 && i < 4) // { -// placeBlockRotated(world, deco.accentID, deco.accentMeta, size / 2 - i, y - i, 3, rotation, sbb); -// placeBlockRotated(world, deco.fenceID, deco.fenceMeta, size / 2 - i, y - i + 1, 3, rotation, sbb); -// placeBlockRotated(world, deco.fenceID, deco.fenceMeta, size / 2 - i, y - i + 2, 3, rotation, sbb); +// setBlockStateRotated(world, deco.accentID, deco.accentMeta, size / 2 - i, y - i, 3, rotation, sbb); +// setBlockStateRotated(world, deco.fenceID, deco.fenceMeta, size / 2 - i, y - i + 1, 3, rotation, sbb); +// setBlockStateRotated(world, deco.fenceID, deco.fenceMeta, size / 2 - i, y - i + 2, 3, rotation, sbb); // } // else if (i == 4) // { -// placeBlockRotated(world, deco.stairID, getStairMeta(3 + rotation), size / 2 - i, y - i, 3, rotation, sbb); +// setBlockStateRotated(world, deco.stairID, getStairMeta(3 + rotation), size / 2 - i, y - i, 3, rotation, sbb); // } // } // } - protected void makeLargeStairsUp(World world, StructureBoundingBox sbb, int rotation, int y) { + protected void makeLargeStairsUp(World world, StructureBoundingBox sbb, Rotation rotation, int y) + { // stairs! //this.fillAirRotated(world, sbb, x, y, 1, x, y + 1, 2, rotation); - + for (int i = 0; i < 5; i++) { int z = size / 2 - i + 4; int sy = y + i + 1; - - placeBlockRotated(world, deco.stairID, getStairMeta(3 + rotation), 1, sy, z, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(3 + rotation), 2, sy, z, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, 1, sy, z - 1, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, 2, sy, z - 1, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, 3, sy, z - 1, rotation, sbb); - + + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), 1, sy, z, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), 2, sy, z, rotation, sbb); + setBlockStateRotated(world, deco.blockState, 1, sy, z - 1, rotation, sbb); + setBlockStateRotated(world, deco.blockState, 2, sy, z - 1, rotation, sbb); + setBlockStateRotated(world, deco.blockState, 3, sy, z - 1, rotation, sbb); + if (i > 0 && i < 4) { - placeBlockRotated(world, deco.accentID, deco.accentMeta, 3, sy, z, rotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 3, sy + 1, z, rotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 3, sy + 2, z, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 3, sy, z, rotation, sbb); + setBlockStateRotated(world, deco.fenceState, 3, sy + 1, z, rotation, sbb); + setBlockStateRotated(world, deco.fenceState, 3, sy + 2, z, rotation, sbb); } else if (i == 0) { - placeBlockRotated(world, deco.stairID, getStairMeta(2 + rotation), 3, sy, z, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, false), 3, sy, z, rotation, sbb); } } } - - private void decorateReappearingMaze(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + private void decorateReappearingMaze(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { // make maze object int mazeSize = 6; - TFMaze maze = new TFMaze(mazeSize, mazeSize); + TFMaze maze = new TFMaze(mazeSize, mazeSize); // set the seed to a fixed value based on this maze's x and z maze.setSeed(world.getSeed() + this.boundingBox.minX * 90342903 + y * 90342903 ^ this.boundingBox.minZ); - + // tell it not to make outside walls by making them "ROOMS" for (int i = 0; i < 13; i++) { @@ -617,94 +628,90 @@ private void decorateReappearingMaze(World world, Random decoRNG, StructureBound // we need to set this before generation maze.doorRarity = 0.3F; - + // set some areas out of bounds and make the maze depending on where we start switch (rotation) { - case 0: - for (int x = 1; x < 6; x++) - { - for (int z = 1; z < 6; z++) + case NONE: + for (int x = 1; x < 6; x++) { - maze.putRaw(x, z, TFMaze.ROOM); + for (int z = 1; z < 6; z++) + { + maze.putRaw(x, z, TFMaze.ROOM); + } } - } - maze.putRaw(1, 6, TFMaze.ROOM); - maze.putRaw(1, 7, TFMaze.ROOM); - maze.putRaw(1, 8, TFMaze.ROOM); - maze.putRaw(1, 9, TFMaze.ROOM); - maze.putRaw(1, 10, TFMaze.DOOR); - maze.putRaw(6, 1, TFMaze.ROOM); - maze.putRaw(7, 1, TFMaze.ROOM); - maze.putRaw(8, 1, TFMaze.DOOR); - maze.generateRecursiveBacktracker(0, 5); - break; - case 1: - for (int x = 7; x < 12; x++) - { - for (int z = 1; z < 6; z++) + maze.putRaw(1, 6, TFMaze.ROOM); + maze.putRaw(1, 7, TFMaze.ROOM); + maze.putRaw(1, 8, TFMaze.ROOM); + maze.putRaw(1, 9, TFMaze.ROOM); + maze.putRaw(1, 10, TFMaze.DOOR); + maze.putRaw(6, 1, TFMaze.ROOM); + maze.putRaw(7, 1, TFMaze.ROOM); + maze.putRaw(8, 1, TFMaze.DOOR); + maze.generateRecursiveBacktracker(0, 5); + break; + case CLOCKWISE_90: + for (int x = 7; x < 12; x++) { - maze.putRaw(x, z, TFMaze.ROOM); + for (int z = 1; z < 6; z++) + { + maze.putRaw(x, z, TFMaze.ROOM); + } } - } - maze.putRaw(6, 1, TFMaze.ROOM); - maze.putRaw(5, 1, TFMaze.ROOM); - maze.putRaw(4, 1, TFMaze.ROOM); - maze.putRaw(3, 1, TFMaze.ROOM); - maze.putRaw(2, 1, TFMaze.DOOR); - maze.putRaw(11, 6, TFMaze.ROOM); - maze.putRaw(11, 7, TFMaze.ROOM); - maze.putRaw(11, 8, TFMaze.DOOR); - maze.generateRecursiveBacktracker(0, 0); - break; - case 2: - for (int x = 7; x < 12; x++) - { - for (int z = 7; z < 12; z++) + maze.putRaw(6, 1, TFMaze.ROOM); + maze.putRaw(5, 1, TFMaze.ROOM); + maze.putRaw(4, 1, TFMaze.ROOM); + maze.putRaw(3, 1, TFMaze.ROOM); + maze.putRaw(2, 1, TFMaze.DOOR); + maze.putRaw(11, 6, TFMaze.ROOM); + maze.putRaw(11, 7, TFMaze.ROOM); + maze.putRaw(11, 8, TFMaze.DOOR); + maze.generateRecursiveBacktracker(0, 0); + break; + case CLOCKWISE_180: + for (int x = 7; x < 12; x++) { - maze.putRaw(x, z, TFMaze.ROOM); + for (int z = 7; z < 12; z++) + { + maze.putRaw(x, z, TFMaze.ROOM); + } } - } - maze.putRaw(11, 6, TFMaze.ROOM); - maze.putRaw(11, 5, TFMaze.ROOM); - maze.putRaw(11, 4, TFMaze.ROOM); - maze.putRaw(11, 3, TFMaze.ROOM); - maze.putRaw(11, 2, TFMaze.DOOR); - maze.putRaw(6, 11, TFMaze.ROOM); - maze.putRaw(5, 11, TFMaze.ROOM); - maze.putRaw(4, 11, TFMaze.DOOR); - maze.generateRecursiveBacktracker(5, 0); - break; - case 3: - for (int x = 1; x < 6; x++) - { - for (int z = 7; z < 12; z++) + maze.putRaw(11, 6, TFMaze.ROOM); + maze.putRaw(11, 5, TFMaze.ROOM); + maze.putRaw(11, 4, TFMaze.ROOM); + maze.putRaw(11, 3, TFMaze.ROOM); + maze.putRaw(11, 2, TFMaze.DOOR); + maze.putRaw(6, 11, TFMaze.ROOM); + maze.putRaw(5, 11, TFMaze.ROOM); + maze.putRaw(4, 11, TFMaze.DOOR); + maze.generateRecursiveBacktracker(5, 0); + break; + case COUNTERCLOCKWISE_90: + for (int x = 1; x < 6; x++) { - maze.putRaw(x, z, TFMaze.ROOM); + for (int z = 7; z < 12; z++) + { + maze.putRaw(x, z, TFMaze.ROOM); + } } - } - maze.putRaw(6, 11, TFMaze.ROOM); - maze.putRaw(7, 11, TFMaze.ROOM); - maze.putRaw(8, 11, TFMaze.ROOM); - maze.putRaw(9, 11, TFMaze.ROOM); - maze.putRaw(10, 11, TFMaze.DOOR); - maze.putRaw(1, 6, TFMaze.ROOM); - maze.putRaw(1, 5, TFMaze.ROOM); - maze.putRaw(1, 4, TFMaze.DOOR); - maze.generateRecursiveBacktracker(5, 5); - break; + maze.putRaw(6, 11, TFMaze.ROOM); + maze.putRaw(7, 11, TFMaze.ROOM); + maze.putRaw(8, 11, TFMaze.ROOM); + maze.putRaw(9, 11, TFMaze.ROOM); + maze.putRaw(10, 11, TFMaze.DOOR); + maze.putRaw(1, 6, TFMaze.ROOM); + maze.putRaw(1, 5, TFMaze.ROOM); + maze.putRaw(1, 4, TFMaze.DOOR); + maze.generateRecursiveBacktracker(5, 5); + break; } - - + + // copy the maze to us! - maze.wallBlockID = deco.blockID; - maze.wallBlockMeta = deco.blockMeta; - maze.headBlockID = deco.accentID; - maze.headBlockMeta = deco.accentMeta; - maze.pillarBlockID = deco.accentID; - maze.pillarBlockMeta = deco.accentMeta; - maze.doorBlockID = TFBlocks.towerDevice; - maze.doorBlockMeta = BlockTFTowerDevice.META_REAPPEARING_INACTIVE; + maze.wallBlockState = deco.blockState; + maze.headBlockState = deco.accentState; + maze.pillarBlockState = deco.accentState; + maze.doorBlockState = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.REAPPEARING_INACTIVE); maze.torchRarity = 0; maze.tall = 3; @@ -712,31 +719,35 @@ private void decorateReappearingMaze(World world, Random decoRNG, StructureBound maze.oddBias = 2; maze.copyToStructure(world, 0, y + 1, 0, this, sbb); - + decorateMazeDeadEnds(world, decoRNG, maze, y, rotation, sbb); } - + /** * Find dead ends and put something there */ - protected void decorateMazeDeadEnds(World world, Random decoRNG, TFMaze maze, int y, int rotation, StructureBoundingBox sbb) + protected void decorateMazeDeadEnds(World world, Random decoRNG, TFMaze maze, int y, Rotation rotation, StructureBoundingBox sbb) { - for(int x = 0; x < maze.width; x++) + for (int x = 0; x < maze.width; x++) { - for (int z = 0; z < maze.depth; z++) + for (int z = 0; z < maze.depth; z++) { // dead ends - if (!maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) { + if (!maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) + { decorateDeadEnd(world, decoRNG, maze, x, y, z, 3, rotation, sbb); } - if (maze.isWall(x, z, x - 1, z) && !maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) { + if (maze.isWall(x, z, x - 1, z) && !maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) + { decorateDeadEnd(world, decoRNG, maze, x, y, z, 1, rotation, sbb); } - if (maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && !maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) { + if (maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && !maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) + { decorateDeadEnd(world, decoRNG, maze, x, y, z, 0, rotation, sbb); } - if (maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && !maze.isWall(x, z, x, z + 1)) { + if (maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && !maze.isWall(x, z, x, z + 1)) + { decorateDeadEnd(world, decoRNG, maze, x, y, z, 2, rotation, sbb); } } @@ -746,42 +757,44 @@ protected void decorateMazeDeadEnds(World world, Random decoRNG, TFMaze maze, in /** * Decorate a specific maze dead end */ - private void decorateDeadEnd(World world, Random decoRNG, TFMaze maze, int mx, int y, int mz, int facing, int rotation, StructureBoundingBox sbb) { + private void decorateDeadEnd(World world, Random decoRNG, TFMaze maze, int mx, int y, int mz, int facing, Rotation rotation, StructureBoundingBox sbb) + { int x = mx * 3 + 1; int z = mz * 3 + 1; - + switch (facing) { - case 0: - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 0, y + 1, z + 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 1, y + 1, z + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.chest, 0, x + 0, y + 2, z + 1, sbb); - this.placeTreasureAtCurrentPosition(world, decoRNG, x + 1, y + 2, z + 1, TFTreasure.darktower_cache, sbb); - break; - case 1: - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 0, y + 1, z + 0, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 0, y + 1, z + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.chest, rotation, x + 0, y + 2, z + 0, sbb); - this.placeTreasureAtCurrentPosition(world, decoRNG, x + 0, y + 2, z + 1, TFTreasure.darktower_cache, sbb); - break; - case 2: - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 0, y + 1, z + 0, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 1, y + 1, z + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.chest, rotation, x + 0, y + 2, z + 0, sbb); - this.placeTreasureAtCurrentPosition(world, decoRNG, x + 1, y + 2, z + 0, TFTreasure.darktower_cache, sbb); - break; - case 3: - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 1, y + 1, z + 0, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 1, y + 1, z + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.chest, rotation, x + 1, y + 2, z + 0, sbb); - this.placeTreasureAtCurrentPosition(world, decoRNG, x + 1, y + 2, z + 1, TFTreasure.darktower_cache, sbb); - break; + case 0: + setBlockState(world, deco.accentState, x + 0, y + 1, z + 1, sbb); + setBlockState(world, deco.accentState, x + 1, y + 1, z + 1, sbb); + setBlockState(world, Blocks.CHEST.getDefaultState(), x + 0, y + 2, z + 1, sbb); + this.placeTreasureAtCurrentPosition(world, decoRNG, x + 1, y + 2, z + 1, TFTreasure.darktower_cache, sbb); + break; + case 1: + setBlockState(world, deco.accentState, x + 0, y + 1, z + 0, sbb); + setBlockState(world, deco.accentState, x + 0, y + 1, z + 1, sbb); + setBlockState(world, Blocks.CHEST.getDefaultState().withProperty(BlockChest.FACING, EnumFacing.SOUTH), x + 0, y + 2, z + 0, sbb); + this.placeTreasureAtCurrentPosition(world, decoRNG, x + 0, y + 2, z + 1, TFTreasure.darktower_cache, sbb); + break; + case 2: + setBlockState(world, deco.accentState, x + 0, y + 1, z + 0, sbb); + setBlockState(world, deco.accentState, x + 1, y + 1, z + 0, sbb); + setBlockState(world, Blocks.CHEST.getDefaultState().withProperty(BlockChest.FACING, EnumFacing.SOUTH), x + 0, y + 2, z + 0, sbb); + this.placeTreasureAtCurrentPosition(world, decoRNG, x + 1, y + 2, z + 0, TFTreasure.darktower_cache, sbb); + break; + case 3: + setBlockState(world, deco.accentState, x + 1, y + 1, z + 0, sbb); + setBlockState(world, deco.accentState, x + 1, y + 1, z + 1, sbb); + setBlockState(world, Blocks.CHEST.getDefaultState().withProperty(BlockChest.FACING, EnumFacing.SOUTH), x + 1, y + 2, z + 0, sbb); + this.placeTreasureAtCurrentPosition(world, decoRNG, x + 1, y + 2, z + 1, TFTreasure.darktower_cache, sbb); + break; } - + } - private void decorateUnbuilderMaze(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + private void decorateUnbuilderMaze(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { // fill in posts for (int x = size / 2; x < size - 1; x++) @@ -792,442 +805,456 @@ private void decorateUnbuilderMaze(World world, Random decoRNG, StructureBoundin { for (int py = 1; py < 5; py++) { - placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x, y + py, z, rotation, sbb); + setBlockStateRotated(world, deco.pillarState, x, y + py, z, rotation, sbb); } } else if (x % 2 == 1 || z % 2 == 1) { for (int py = 1; py < 5; py++) { - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, x, y + py, z, rotation, sbb); + setBlockStateRotated(world, deco.fenceState, x, y + py, z, rotation, sbb); } - + if (x != size / 2 && x != size - 2 && z != size - 2) { int ay = decoRNG.nextInt(4) + 1; - placeBlockRotated(world, Blocks.air, 0, x, y + ay, z, rotation, sbb); - + setBlockStateRotated(world, AIR, x, y + ay, z, rotation, sbb); + if (x > size - 7) { ay = decoRNG.nextInt(3) + 1; - placeBlockRotated(world, Blocks.air, 0, x, y + ay, z, rotation, sbb); + setBlockStateRotated(world, AIR, x, y + ay, z, rotation, sbb); } } } } } - + + final IBlockState antiBuilderBlockState = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.ANTIBUILDER); + // place unbuilders - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_ANTIBUILDER, 15, y + 2, 7, rotation, sbb); - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_ANTIBUILDER, 11, y + 3, 7, rotation, sbb); - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_ANTIBUILDER, 15, y + 2, 13, rotation, sbb); - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_ANTIBUILDER, 11, y + 3, 13, rotation, sbb); - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_ANTIBUILDER, 5, y + 3, 13, rotation, sbb); + setBlockStateRotated(world, antiBuilderBlockState, 15, y + 2, 7, rotation, sbb); + setBlockStateRotated(world, antiBuilderBlockState, 11, y + 3, 7, rotation, sbb); + setBlockStateRotated(world, antiBuilderBlockState, 15, y + 2, 13, rotation, sbb); + setBlockStateRotated(world, antiBuilderBlockState, 11, y + 3, 13, rotation, sbb); + setBlockStateRotated(world, antiBuilderBlockState, 5, y + 3, 13, rotation, sbb); } - private void decorateLounge(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + private void decorateLounge(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { // brewing area in corner - walls - this.fillBlocksRotated(world, sbb, 17, y + 1, 1, 17, y + 4, 6, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 1, 17, y + 4, 1, deco.pillarID, deco.pillarMeta, rotation); - + this.fillBlocksRotated(world, sbb, 17, y + 1, 1, 17, y + 4, 6, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 1, 17, y + 4, 1, deco.pillarState, rotation); + // floors - this.fillBlocksRotated(world, sbb, 13, y + 1, 2, 16, y + 1, 5, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 2, 12, y + 1, 6, deco.stairID, getStairMeta(0 + rotation), rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 6, 16, y + 1, 6, deco.stairID, getStairMeta(3 + rotation), rotation); + this.fillBlocksRotated(world, sbb, 13, y + 1, 2, 16, y + 1, 5, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 2, 12, y + 1, 6, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 6, 16, y + 1, 6, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), rotation); // furnaces - this.makeDispenserPillar(world, deco, 13, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeDispenserPillar(world, deco, 15, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeDispenserPillar(world, deco, 17, y, 3, getStairMeta(0 + rotation), rotation, sbb); - this.makeDispenserPillar(world, deco, 17, y, 5, getStairMeta(0 + rotation), rotation, sbb); - + this.makeDispenserPillar(world, deco, 13, y, 1, EnumFacing.SOUTH, rotation, sbb); + this.makeDispenserPillar(world, deco, 15, y, 1, EnumFacing.SOUTH, rotation, sbb); + this.makeDispenserPillar(world, deco, 17, y, 3, EnumFacing.WEST, rotation, sbb); + this.makeDispenserPillar(world, deco, 17, y, 5, EnumFacing.WEST, rotation, sbb); + // framing pillars - this.makeStonePillar(world, deco, 12, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeStonePillar(world, deco, 17, y, 6, getStairMeta(0 + rotation), rotation, sbb); - + this.makeStonePillar(world, deco, 12, y, 1, EnumFacing.NORTH, rotation, sbb); + this.makeStonePillar(world, deco, 17, y, 6, EnumFacing.EAST, rotation, sbb); + // cauldron and brewing stand - this.placeBlockRotated(world, Blocks.brewing_stand, 0, 13, y + 2, 5, rotation, sbb); - this.placeBlockRotated(world, Blocks.cauldron, 3, 15, y + 2, 3, rotation, sbb); - + this.setBlockStateRotated(world, Blocks.BREWING_STAND.getDefaultState(), 13, y + 2, 5, rotation, sbb); + this.setBlockStateRotated(world, Blocks.CAULDRON.getDefaultState().withProperty(BlockCauldron.LEVEL, 3), 15, y + 2, 3, rotation, sbb); + // bookshelves in corner - this.fillBlocksRotated(world, sbb, 10, y + 1, 17, 17, y + 4, 17, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 17, y + 1, 10, 17, y + 4, 17, deco.blockID, deco.blockMeta, rotation); - - this.fillBlocksRotated(world, sbb, 11, y + 1, 17, 12, y + 4, 17, Blocks.bookshelf, 0, rotation); - this.fillBlocksRotated(world, sbb, 14, y + 1, 17, 15, y + 4, 17, Blocks.bookshelf, 0, rotation); - this.fillBlocksRotated(world, sbb, 17, y + 1, 11, 17, y + 4, 12, Blocks.bookshelf, 0, rotation); - this.fillBlocksRotated(world, sbb, 17, y + 1, 14, 17, y + 4, 15, Blocks.bookshelf, 0, rotation); - + this.fillBlocksRotated(world, sbb, 10, y + 1, 17, 17, y + 4, 17, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 17, y + 1, 10, 17, y + 4, 17, deco.blockState, rotation); + + this.fillBlocksRotated(world, sbb, 11, y + 1, 17, 12, y + 4, 17, Blocks.BOOKSHELF.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, 14, y + 1, 17, 15, y + 4, 17, Blocks.BOOKSHELF.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, 17, y + 1, 11, 17, y + 4, 12, Blocks.BOOKSHELF.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, 17, y + 1, 14, 17, y + 4, 15, Blocks.BOOKSHELF.getDefaultState(), rotation); + // table - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation) + 4, 13, y + 1, 14, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(3 + rotation) + 4, 14, y + 1, 14, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(2 + rotation) + 4, 14, y + 1, 13, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, getStairMeta(1 + rotation) + 4, 13, y + 1, 13, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, true), 13, y + 1, 14, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, true), 14, y + 1, 14, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, true), 14, y + 1, 13, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, WEST, rotation, true), 13, y + 1, 13, rotation, sbb); // chair 1 - this.placeBlockRotated(world, deco.stairID, getStairMeta(2 + rotation), 11, y + 1, 13, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, false), 11, y + 1, 13, rotation, sbb); // chair 2 - this.placeBlockRotated(world, deco.stairID, getStairMeta(3 + rotation), 13, y + 1, 11, rotation, sbb); - + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), 13, y + 1, 11, rotation, sbb); + // center lamp - placeBlockRotated(world, Blocks.redstone_lamp, 0, 8, y + 3, 8, rotation, sbb); - placeBlockRotated(world, Blocks.lever, decoRNG.nextBoolean() ? 0 : 7, 8, y + 2, 8, rotation, sbb); - + setBlockStateRotated(world, Blocks.REDSTONE_LAMP.getDefaultState(), 8, y + 3, 8, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), decoRNG.nextBoolean() ? BlockLever.EnumOrientation.DOWN_X : BlockLever.EnumOrientation.DOWN_Z, rotation, false), 8, y + 2, 8, rotation, sbb); + // planter for trees placeTreePlanter(world, decoRNG.nextInt(5), 6, y + 1, 12, rotation, sbb); } - - private void makeDispenserPillar(World world, StructureTFDecorator forgeDeco, int x, int y, int z, int stairMeta, int rotation, StructureBoundingBox sbb) { - this.placeBlockRotated(world, forgeDeco.stairID, stairMeta + 4, x, y + 2, z, rotation, sbb); - this.placeBlockRotated(world, Blocks.dispenser, stairMeta + 4, x, y + 3, z, rotation, sbb); - this.placeBlockRotated(world, forgeDeco.stairID, stairMeta, x, y + 4, z, rotation, sbb); + + private void makeDispenserPillar(World world, StructureTFDecorator forgeDeco, int x, int y, int z, EnumFacing stairMeta, Rotation rotation, StructureBoundingBox sbb) + { + this.setBlockStateRotated(world, getStairState(forgeDeco.stairState, stairMeta, rotation, true), x, y + 2, z, rotation, sbb); + this.setBlockStateRotated(world, Blocks.DISPENSER.getDefaultState().withProperty(BlockDispenser.FACING, stairMeta), x, y + 3, z, rotation, sbb); + this.setBlockStateRotated(world, getStairState(forgeDeco.stairState, stairMeta, rotation, false), x, y + 4, z, rotation, sbb); } - private void decorateBossSpawner(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) { - this.placeBlockRotated(world, TFBlocks.bossSpawner, 3, 9, y + 4, 9, rotation, sbb); + private void decorateBossSpawner(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) + { + this.setBlockStateRotated(world, TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.UR_GHAST), 9, y + 4, 9, rotation, sbb); } - private void decorateExperiment(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + private void decorateExperiment(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { + final IBlockState obsidian = Blocks.OBSIDIAN.getDefaultState(); + final IBlockState netherrack = Blocks.NETHERRACK.getDefaultState(); + final IBlockState redstone = Blocks.REDSTONE_BLOCK.getDefaultState(); + final IBlockState inactiveReactor = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.REACTOR_INACTIVE); + // crafting area in corner - walls - this.fillBlocksRotated(world, sbb, 17, y + 1, 1, 17, y + 4, 6, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 1, 17, y + 4, 1, deco.pillarID, deco.pillarMeta, rotation); - + this.fillBlocksRotated(world, sbb, 17, y + 1, 1, 17, y + 4, 6, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 1, 17, y + 4, 1, deco.pillarState, rotation); + // floors - this.fillBlocksRotated(world, sbb, 13, y + 1, 2, 16, y + 1, 5, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 2, 12, y + 1, 6, deco.stairID, getStairMeta(0 + rotation), rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 6, 16, y + 1, 6, deco.stairID, getStairMeta(3 + rotation), rotation); - - this.makeWoodPillar(world, deco, 13, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeWoodPillar(world, deco, 15, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeWoodPillar(world, deco, 17, y, 3, getStairMeta(0 + rotation), rotation, sbb); - this.makeWoodPillar(world, deco, 17, y, 5, getStairMeta(0 + rotation), rotation, sbb); - + this.fillBlocksRotated(world, sbb, 13, y + 1, 2, 16, y + 1, 5, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 2, 12, y + 1, 6, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 6, 16, y + 1, 6, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), rotation); + + this.makeWoodPillar(world, deco, 13, y, 1, rotation, sbb); + this.makeWoodPillar(world, deco, 15, y, 1, rotation, sbb); + this.makeWoodPillar(world, deco, 17, y, 3, rotation, sbb); + this.makeWoodPillar(world, deco, 17, y, 5, rotation, sbb); + // framing pillars - this.makeStonePillar(world, deco, 12, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeStonePillar(world, deco, 17, y, 6, getStairMeta(0 + rotation), rotation, sbb); - + this.makeStonePillar(world, deco, 12, y, 1, EnumFacing.NORTH, rotation, sbb); + this.makeStonePillar(world, deco, 17, y, 6, EnumFacing.EAST, rotation, sbb); + // workbench - placeBlockRotated(world, Blocks.crafting_table, 0, 14, y + 2, 4, rotation, sbb); + setBlockStateRotated(world, Blocks.CRAFTING_TABLE.getDefaultState(), 14, y + 2, 4, rotation, sbb); // recipes in frames? - placeItemFrameRotated(world, 13, y + 2, 1, rotation, 0, new ItemStack(TFItems.borerEssence), sbb); - placeItemFrameRotated(world, 14, y + 2, 1, rotation, 0, new ItemStack(Items.redstone), sbb); - placeItemFrameRotated(world, 15, y + 2, 1, rotation, 0, new ItemStack(TFItems.borerEssence), sbb); - placeItemFrameRotated(world, 13, y + 3, 1, rotation, 0, new ItemStack(Items.redstone), sbb); - placeItemFrameRotated(world, 14, y + 3, 1, rotation, 0, new ItemStack(Items.ghast_tear), sbb); - placeItemFrameRotated(world, 15, y + 3, 1, rotation, 0, new ItemStack(Items.redstone), sbb); - placeItemFrameRotated(world, 13, y + 4, 1, rotation, 0, new ItemStack(TFItems.borerEssence), sbb); - placeItemFrameRotated(world, 14, y + 4, 1, rotation, 0, new ItemStack(Items.redstone), sbb); - placeItemFrameRotated(world, 15, y + 4, 1, rotation, 0, new ItemStack(TFItems.borerEssence), sbb); - - placeItemFrameRotated(world, 17, y + 2, 3, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 1), sbb); - placeItemFrameRotated(world, 17, y + 2, 4, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 0), sbb); - placeItemFrameRotated(world, 17, y + 2, 5, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 1), sbb); - placeItemFrameRotated(world, 17, y + 3, 3, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 0), sbb); - placeItemFrameRotated(world, 17, y + 3, 4, rotation, 1, new ItemStack(TFItems.carminite), sbb); - placeItemFrameRotated(world, 17, y + 3, 5, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 0), sbb); - placeItemFrameRotated(world, 17, y + 4, 3, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 1), sbb); - placeItemFrameRotated(world, 17, y + 4, 4, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 0), sbb); - placeItemFrameRotated(world, 17, y + 4, 5, rotation, 1, new ItemStack(TFBlocks.towerWood, 1, 1), sbb); - + placeItemFrameRotated(world, 13, y + 2, 1, rotation, EnumFacing.SOUTH, new ItemStack(TFItems.borer_essence), sbb); + placeItemFrameRotated(world, 14, y + 2, 1, rotation, EnumFacing.SOUTH, new ItemStack(Items.REDSTONE), sbb); + placeItemFrameRotated(world, 15, y + 2, 1, rotation, EnumFacing.SOUTH, new ItemStack(TFItems.borer_essence), sbb); + placeItemFrameRotated(world, 13, y + 3, 1, rotation, EnumFacing.SOUTH, new ItemStack(Items.REDSTONE), sbb); + placeItemFrameRotated(world, 14, y + 3, 1, rotation, EnumFacing.SOUTH, new ItemStack(Items.GHAST_TEAR), sbb); + placeItemFrameRotated(world, 15, y + 3, 1, rotation, EnumFacing.SOUTH, new ItemStack(Items.REDSTONE), sbb); + placeItemFrameRotated(world, 13, y + 4, 1, rotation, EnumFacing.SOUTH, new ItemStack(TFItems.borer_essence), sbb); + placeItemFrameRotated(world, 14, y + 4, 1, rotation, EnumFacing.SOUTH, new ItemStack(Items.REDSTONE), sbb); + placeItemFrameRotated(world, 15, y + 4, 1, rotation, EnumFacing.SOUTH, new ItemStack(TFItems.borer_essence), sbb); + + placeItemFrameRotated(world, 17, y + 2, 3, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 1), sbb); + placeItemFrameRotated(world, 17, y + 2, 4, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 0), sbb); + placeItemFrameRotated(world, 17, y + 2, 5, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 1), sbb); + placeItemFrameRotated(world, 17, y + 3, 3, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 0), sbb); + placeItemFrameRotated(world, 17, y + 3, 4, rotation, WEST, new ItemStack(TFItems.carminite), sbb); + placeItemFrameRotated(world, 17, y + 3, 5, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 0), sbb); + placeItemFrameRotated(world, 17, y + 4, 3, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 1), sbb); + placeItemFrameRotated(world, 17, y + 4, 4, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 0), sbb); + placeItemFrameRotated(world, 17, y + 4, 5, rotation, WEST, new ItemStack(TFBlocks.tower_wood, 1, 1), sbb); + if (y < this.height - 13) { // device bottom - placeBlockRotated(world, Blocks.obsidian, 0, 13, y + 1, 13, rotation, sbb); - placeBlockRotated(world, Blocks.obsidian, 0, 15, y + 1, 13, rotation, sbb); - placeBlockRotated(world, Blocks.obsidian, 0, 13, y + 1, 15, rotation, sbb); - placeBlockRotated(world, Blocks.obsidian, 0, 15, y + 1, 15, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 13, y + 1, 14, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 14, y + 1, 13, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 15, y + 1, 14, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 14, y + 1, 15, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_block, 0, 14, y + 1, 14, rotation, sbb); + setBlockStateRotated(world, obsidian, 13, y + 1, 13, rotation, sbb); + setBlockStateRotated(world, obsidian, 15, y + 1, 13, rotation, sbb); + setBlockStateRotated(world, obsidian, 13, y + 1, 15, rotation, sbb); + setBlockStateRotated(world, obsidian, 15, y + 1, 15, rotation, sbb); + setBlockStateRotated(world, netherrack, 13, y + 1, 14, rotation, sbb); + setBlockStateRotated(world, netherrack, 14, y + 1, 13, rotation, sbb); + setBlockStateRotated(world, netherrack, 15, y + 1, 14, rotation, sbb); + setBlockStateRotated(world, netherrack, 14, y + 1, 15, rotation, sbb); + setBlockStateRotated(world, redstone, 14, y + 1, 14, rotation, sbb); // middle - placeBlockRotated(world, Blocks.netherrack, 0, 13, y + 2, 13, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 15, y + 2, 13, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 13, y + 2, 15, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 15, y + 2, 15, rotation, sbb); - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_REACTOR_INACTIVE, 14, y + 2, 14, rotation, sbb); + setBlockStateRotated(world, netherrack, 13, y + 2, 13, rotation, sbb); + setBlockStateRotated(world, netherrack, 15, y + 2, 13, rotation, sbb); + setBlockStateRotated(world, netherrack, 13, y + 2, 15, rotation, sbb); + setBlockStateRotated(world, netherrack, 15, y + 2, 15, rotation, sbb); + setBlockStateRotated(world, inactiveReactor, 14, y + 2, 14, rotation, sbb); //device top - placeBlockRotated(world, Blocks.obsidian, 0, 13, y + 3, 13, rotation, sbb); - placeBlockRotated(world, Blocks.obsidian, 0, 15, y + 3, 13, rotation, sbb); - placeBlockRotated(world, Blocks.obsidian, 0, 13, y + 3, 15, rotation, sbb); - placeBlockRotated(world, Blocks.obsidian, 0, 15, y + 3, 15, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 13, y + 3, 14, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 14, y + 3, 13, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 15, y + 3, 14, rotation, sbb); - placeBlockRotated(world, Blocks.netherrack, 0, 14, y + 3, 15, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_block, 0, 14, y + 3, 14, rotation, sbb); + setBlockStateRotated(world, obsidian, 13, y + 3, 13, rotation, sbb); + setBlockStateRotated(world, obsidian, 15, y + 3, 13, rotation, sbb); + setBlockStateRotated(world, obsidian, 13, y + 3, 15, rotation, sbb); + setBlockStateRotated(world, obsidian, 15, y + 3, 15, rotation, sbb); + setBlockStateRotated(world, netherrack, 13, y + 3, 14, rotation, sbb); + setBlockStateRotated(world, netherrack, 14, y + 3, 13, rotation, sbb); + setBlockStateRotated(world, netherrack, 15, y + 3, 14, rotation, sbb); + setBlockStateRotated(world, netherrack, 14, y + 3, 15, rotation, sbb); + setBlockStateRotated(world, redstone, 14, y + 3, 14, rotation, sbb); } + // short piston plunger 1 - placeBlockRotated(world, deco.accentID, deco.accentMeta, 14, y + 1, 17, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 4), 13, y + 1, 17, rotation, sbb); - placeBlockRotated(world, Blocks.piston, 5 - getStairMeta(3 + rotation), 14, y + 2, 17, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_block, 0, 14, y + 2, 16, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 14, y + 1, 17, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.EAST, rotation, false), 13, y + 1, 17, rotation, sbb); + setBlockStateRotated(world, Blocks.PISTON.getDefaultState().withProperty(BlockPistonBase.FACING, EnumFacing.SOUTH), 14, y + 2, 17, rotation, sbb); + setBlockStateRotated(world, redstone, 14, y + 2, 16, rotation, sbb); + // short piston plunger 2 - placeBlockRotated(world, deco.accentID, deco.accentMeta, 17, y + 1, 14, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 2), 17, y + 1, 13, rotation, sbb); - placeBlockRotated(world, Blocks.piston, 5 - getStairMeta(2 + rotation), 17, y + 2, 14, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_block, 0, 16, y + 2, 14, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 17, y + 1, 14, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.SOUTH, rotation, false), 17, y + 1, 13, rotation, sbb); + setBlockStateRotated(world, Blocks.PISTON.getDefaultState().withProperty(BlockPistonBase.FACING, EnumFacing.EAST), 17, y + 2, 14, rotation, sbb); + setBlockStateRotated(world, redstone, 16, y + 2, 14, rotation, sbb); // long piston plunger 1 - placeBlockRotated(world, Blocks.redstone_block, 0, 14, y + 2, 11, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, 14, y + 1, 11, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 4) + 8, 13, y + 1, 11, rotation, sbb); - placeBlockRotated(world, Blocks.piston, 5 - getStairMeta(1 + rotation), 14, y + 2, 10, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, 14, y + 1, 9, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 4), 13, y + 1, 9, rotation, sbb); - placeBlockRotated(world, Blocks.sticky_piston, 5 - getStairMeta(1 + rotation), 14, y + 2, 9, rotation, sbb); + setBlockStateRotated(world, redstone, 14, y + 2, 11, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 14, y + 1, 11, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.EAST, rotation, true), 13, y + 1, 11, rotation, sbb); + setBlockStateRotated(world, Blocks.PISTON.getDefaultState().withProperty(BlockPistonBase.FACING, EnumFacing.NORTH), 14, y + 2, 10, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 14, y + 1, 9, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.EAST, rotation, false), 13, y + 1, 9, rotation, sbb); + setBlockStateRotated(world, Blocks.STICKY_PISTON.getDefaultState().withProperty(BlockPistonBase.FACING, EnumFacing.NORTH), 14, y + 2, 9, rotation, sbb); // long piston plunger 2 - placeBlockRotated(world, Blocks.redstone_block, 0, 11, y + 2, 14, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, 11, y + 1, 14, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 2) + 8, 11, y + 1, 13, rotation, sbb); - placeBlockRotated(world, Blocks.piston, 5 - getStairMeta(0 + rotation), 10, y + 2, 14, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, 9, y + 1, 14, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 2), 9, y + 1, 13, rotation, sbb); - placeBlockRotated(world, Blocks.sticky_piston, 5 - getStairMeta(0 + rotation), 9, y + 2, 14, rotation, sbb); + setBlockStateRotated(world, redstone, 11, y + 2, 14, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 11, y + 1, 14, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.SOUTH, rotation, true), 11, y + 1, 13, rotation, sbb); + setBlockStateRotated(world, Blocks.PISTON.getDefaultState().withProperty(BlockPistonBase.FACING, EnumFacing.WEST), 10, y + 2, 14, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 9, y + 1, 14, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.SOUTH, rotation, false), 9, y + 1, 13, rotation, sbb); + setBlockStateRotated(world, Blocks.STICKY_PISTON.getDefaultState().withProperty(BlockPistonBase.FACING, EnumFacing.WEST), 9, y + 2, 14, rotation, sbb); } - private void makeWoodPillar(World world, StructureTFDecorator forgeDeco, int x, int y, int z, int stairMeta, int rotation, StructureBoundingBox sbb) { - this.placeBlockRotated(world, TFBlocks.log, 3, x, y + 2, z, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.log, 3, x, y + 3, z, rotation, sbb); - this.placeBlockRotated(world, TFBlocks.log, 3, x, y + 4, z, rotation, sbb); + private void makeWoodPillar(World world, StructureTFDecorator forgeDeco, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) + { + final IBlockState log = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.DARK); + this.setBlockStateRotated(world, log, x, y + 2, z, rotation, sbb); + this.setBlockStateRotated(world, log, x, y + 3, z, rotation, sbb); + this.setBlockStateRotated(world, log, x, y + 4, z, rotation, sbb); } - private void placeItemFrameRotated(World world, int x, int y, int z, int rotation, int direction, ItemStack itemStack, StructureBoundingBox sbb) { - - int dx = getXWithOffsetAsIfRotated(x, z, rotation); + private void placeItemFrameRotated(World world, int x, int y, int z, Rotation rotation, EnumFacing direction, ItemStack itemStack, StructureBoundingBox sbb) + { + + int dx = getXWithOffsetRotated(x, z, rotation); int dy = getYWithOffset(y); - int dz = getZWithOffsetAsIfRotated(x, z, rotation); - if(sbb.isVecInside(dx, dy, dz)) + int dz = getZWithOffsetRotated(x, z, rotation); + EnumFacing facing = this.rotation.add(rotation).rotate(direction).getOpposite(); + final BlockPos pos = new BlockPos(dx, dy, dz).offset(facing); + if (sbb.isVecInside(pos)) { - EntityItemFrame frame = new EntityItemFrame(world, dx, dy, dz, (this.getCoordBaseMode() + direction + rotation) % 4); - if (itemStack != null) + EntityItemFrame frame = new EntityItemFrame(world, pos, facing); + if (!itemStack.isEmpty()) { frame.setDisplayedItem(itemStack); } - + // check if the frame is on a valid surface or not? The wall may not have been generated yet, on a chunk boundry - world.spawnEntityInWorld(frame); + world.spawnEntity(frame); } } - private void decorateAquarium(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + private void decorateAquarium(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { // main aquarium makePillarFrame(world, sbb, this.deco, rotation, 12, y, 3, 4, 4, 13, false); - this.fillBlocksRotated(world, sbb, 13, y + 4, 4, 14, y + 4, 14, Blocks.flowing_water, 0, rotation); + this.fillBlocksRotated(world, sbb, 13, y + 4, 4, 14, y + 4, 14, Blocks.FLOWING_WATER.getDefaultState(), rotation); // little one makePillarFrame(world, sbb, this.deco, rotation, 6, y, 12, 4, 4, 4, false); - this.fillBlocksRotated(world, sbb, 6, y + 5, 12, 9, y + 5, 15, deco.accentID, deco.accentMeta, rotation); - this.fillBlocksRotated(world, sbb, 7, y + 4, 13, 8, y + 5, 14, Blocks.flowing_water, 0, rotation); + this.fillBlocksRotated(world, sbb, 6, y + 5, 12, 9, y + 5, 15, deco.accentState, rotation); + this.fillBlocksRotated(world, sbb, 7, y + 4, 13, 8, y + 5, 14, Blocks.FLOWING_WATER.getDefaultState(), rotation); } - - private void decorateForge(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + + private void decorateForge(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { // StructureTFDecorator forgeDeco = new StructureTFDecorator(); -// forgeDeco = Blocks.cobblestone; -// forgeDeco.pillarID = Blocks.stonebrick; -// forgeDeco.stairID = Blocks.stairCompactCobblestone; +// forgeDeco = Blocks.COBBLESTONE; +// forgeDeco.pillarID = Blocks.STONEBRICK; +// forgeDeco.stairID = Blocks.STAIRCOMPACTCOBBLESTONE; StructureTFDecorator forgeDeco = this.deco; // stone walls in corner - this.fillBlocksRotated(world, sbb, 17, y + 1, 1, 17, y + 4, 6, forgeDeco.pillarID, forgeDeco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 1, 17, y + 4, 1, forgeDeco.pillarID, forgeDeco.pillarMeta, rotation); - - this.fillBlocksRotated(world, sbb, 12, y + 1, 17, 17, y + 4, 17, forgeDeco.pillarID, forgeDeco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 17, y + 1, 12, 17, y + 4, 17, forgeDeco.pillarID, forgeDeco.pillarMeta, rotation); - + this.fillBlocksRotated(world, sbb, 17, y + 1, 1, 17, y + 4, 6, forgeDeco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 1, 17, y + 4, 1, forgeDeco.pillarState, rotation); + + this.fillBlocksRotated(world, sbb, 12, y + 1, 17, 17, y + 4, 17, forgeDeco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 17, y + 1, 12, 17, y + 4, 17, forgeDeco.pillarState, rotation); + // floors - this.fillBlocksRotated(world, sbb, 13, y + 1, 2, 16, y + 1, 5, forgeDeco.blockID, forgeDeco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 2, 12, y + 1, 6, forgeDeco.stairID, getStairMeta(0 + rotation), rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 6, 16, y + 1, 6, forgeDeco.stairID, getStairMeta(3 + rotation), rotation); - - this.fillBlocksRotated(world, sbb, 13, y + 1, 13, 16, y + 1, 16, forgeDeco.blockID, forgeDeco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 12, 12, y + 1, 16, forgeDeco.stairID, getStairMeta(0 + rotation), rotation); - this.fillBlocksRotated(world, sbb, 12, y + 1, 12, 16, y + 1, 12, forgeDeco.stairID, getStairMeta(1 + rotation), rotation); + this.fillBlocksRotated(world, sbb, 13, y + 1, 2, 16, y + 1, 5, forgeDeco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 2, 12, y + 1, 6, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 6, 16, y + 1, 6, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), rotation); + + this.fillBlocksRotated(world, sbb, 13, y + 1, 13, 16, y + 1, 16, forgeDeco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 12, 12, y + 1, 16, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), rotation); + this.fillBlocksRotated(world, sbb, 12, y + 1, 12, 16, y + 1, 12, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), rotation); + // furnaces - this.makeFurnacePillar(world, forgeDeco, decoRNG, 13, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeFurnacePillar(world, forgeDeco, decoRNG, 15, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 3, getStairMeta(0 + rotation), rotation, sbb); - this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 5, getStairMeta(0 + rotation), rotation, sbb); - - this.makeFurnacePillar(world, forgeDeco, decoRNG, 13, y, 17, getStairMeta(1 + rotation), rotation, sbb); - this.makeFurnacePillar(world, forgeDeco, decoRNG, 15, y, 17, getStairMeta(1 + rotation), rotation, sbb); - this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 13, getStairMeta(0 + rotation), rotation, sbb); - this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 15, getStairMeta(0 + rotation), rotation, sbb); - + this.makeFurnacePillar(world, forgeDeco, decoRNG, 13, y, 1, EnumFacing.SOUTH, rotation, sbb); + this.makeFurnacePillar(world, forgeDeco, decoRNG, 15, y, 1, EnumFacing.SOUTH, rotation, sbb); + this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 3, EnumFacing.WEST, rotation, sbb); + this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 5, EnumFacing.WEST, rotation, sbb); + + this.makeFurnacePillar(world, forgeDeco, decoRNG, 13, y, 17, EnumFacing.NORTH, rotation, sbb); + this.makeFurnacePillar(world, forgeDeco, decoRNG, 15, y, 17, EnumFacing.NORTH, rotation, sbb); + this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 13, EnumFacing.WEST, rotation, sbb); + this.makeFurnacePillar(world, forgeDeco, decoRNG, 17, y, 15, EnumFacing.WEST, rotation, sbb); + // framing pillars - this.makeStonePillar(world, forgeDeco, 12, y, 1, getStairMeta(3 + rotation), rotation, sbb); - this.makeStonePillar(world, forgeDeco, 17, y, 6, getStairMeta(0 + rotation), rotation, sbb); - - this.makeStonePillar(world, forgeDeco, 12, y, 17, getStairMeta(1 + rotation), rotation, sbb); - this.makeStonePillar(world, forgeDeco, 17, y, 12, getStairMeta(0 + rotation), rotation, sbb); - + //this.makeStonePillar(world, forgeDeco, 12, y, 1, EnumFacing.SOUTH, rotation, sbb); + this.makeStonePillar(world, forgeDeco, 17, y, 6, EnumFacing.WEST, rotation, sbb); + + this.makeStonePillar(world, forgeDeco, 12, y, 17, EnumFacing.NORTH, rotation, sbb); + this.makeStonePillar(world, forgeDeco, 17, y, 12, EnumFacing.WEST, rotation, sbb); + // extra pillars - this.makeStonePillar(world, forgeDeco, 17, y, 9, getStairMeta(0 + rotation), rotation, sbb); - this.makeStonePillar(world, forgeDeco, 9, y, 17, getStairMeta(1 + rotation), rotation, sbb); + this.makeStonePillar(world, forgeDeco, 17, y, 9, EnumFacing.WEST, rotation, sbb); + this.makeStonePillar(world, forgeDeco, 9, y, 17, EnumFacing.NORTH, rotation, sbb); // anvils - this.placeBlockRotated(world, Blocks.anvil, decoRNG.nextInt(16), 13, y + 2, 5, rotation, sbb); - this.placeBlockRotated(world, Blocks.anvil, decoRNG.nextInt(16), 13, y + 2, 13, rotation, sbb); - + IBlockState anvil = Blocks.ANVIL.getDefaultState() + .withProperty(BlockAnvil.DAMAGE, decoRNG.nextInt(2)) + .withProperty(BlockAnvil.FACING, EnumFacing.HORIZONTALS[decoRNG.nextInt(4)]); + this.setBlockStateRotated(world, anvil, 13, y + 2, 5, rotation, sbb); + anvil = Blocks.ANVIL.getDefaultState() + .withProperty(BlockAnvil.DAMAGE, decoRNG.nextInt(2)) + .withProperty(BlockAnvil.FACING, EnumFacing.HORIZONTALS[decoRNG.nextInt(4)]); + this.setBlockStateRotated(world, anvil, 13, y + 2, 13, rotation, sbb); + // fire pit makeFirePit(world, forgeDeco, 6, y + 1, 12, rotation, sbb); } - - private void makeFurnacePillar(World world, StructureTFDecorator forgeDeco, Random rand, int x, int y, int z, int stairMeta, int rotation, StructureBoundingBox sbb) { - this.placeBlockRotated(world, forgeDeco.stairID, stairMeta + 4, x, y + 2, z, rotation, sbb); - this.placeBlockRotated(world, Blocks.furnace, stairMeta + 4, x, y + 3, z, rotation, sbb); - + + private void makeFurnacePillar(World world, StructureTFDecorator forgeDeco, Random rand, int x, int y, int z, EnumFacing direction, Rotation rotation, StructureBoundingBox sbb) + { + + this.setBlockStateRotated(world, getStairState(deco.stairState, direction, rotation, true), x, y + 2, z, rotation, sbb); + this.setBlockStateRotated(world, Blocks.FURNACE.getDefaultState().withProperty(BlockFurnace.FACING, direction), x, y + 3, z, rotation, sbb); + // randomly put some charcoal in the furnace burn slot int amount = rand.nextBoolean() ? rand.nextInt(5) + 4 : 0; if (amount > 0) { - int dx = getXWithOffsetAsIfRotated(x, z, rotation); + int dx = getXWithOffsetRotated(x, z, rotation); int dy = getYWithOffset(y + 3); - int dz = getZWithOffsetAsIfRotated(x, z, rotation); - if(sbb.isVecInside(dx, dy, dz) && world.getBlock(dx, dy, dz) == Blocks.furnace) + int dz = getZWithOffsetRotated(x, z, rotation); + + BlockPos pos = new BlockPos(dx, dy, dz); + + if (sbb.isVecInside(pos) && world.getBlockState(pos).getBlock() == Blocks.FURNACE) { // put charcoal in the oven - IInventory inv = (IInventory) world.getTileEntity(dx, dy, dz); + IInventory inv = (IInventory)world.getTileEntity(pos); - inv.setInventorySlotContents(1, new ItemStack(Items.coal, amount, 1)); + inv.setInventorySlotContents(1, new ItemStack(Items.COAL, amount, 1)); } } - this.placeBlockRotated(world, forgeDeco.stairID, stairMeta, x, y + 4, z, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, direction, rotation, false), x, y + 4, z, rotation, sbb); } - private void makeStonePillar(World world, StructureTFDecorator forgeDeco, int x, int y, int z, int stairMeta, int rotation, StructureBoundingBox sbb) { + private void makeStonePillar(World world, StructureTFDecorator forgeDeco, int x, int y, int z, EnumFacing stairDirection, Rotation rotation, StructureBoundingBox sbb) + { for (int py = 1; py <= 4; py++) { - this.placeBlockRotated(world, forgeDeco.pillarID, forgeDeco.pillarMeta, x, y + py, z, rotation, sbb); + this.setBlockStateRotated(world, forgeDeco.pillarState, x, y + py, z, rotation, sbb); } - - int sx = getXWithOffsetAsIfRotated(x, z, rotation); - int sy = getYWithOffset(y + 1); - int sz = getZWithOffsetAsIfRotated(x, z, rotation); - - switch (stairMeta) - { - case 0: - sx--; - break; - case 1: - sx++; - break; - case 2: - sz--; - break; - case 3: - sz++; - break; - } - - if (sbb.isVecInside(sx, sy, sz)) - { - world.setBlock(sx, sy + 0, sz, forgeDeco.stairID, stairMeta, 0); - world.setBlock(sx, sy + 3, sz, forgeDeco.stairID, stairMeta + 4, 0); - } + // we used to have caps here, but the code was too complex to be worthwhile } - private void makeFirePit(World world, StructureTFDecorator myDeco, int x, int y, int z, int rotation, StructureBoundingBox sbb) { - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x + 1, y, z + 1, rotation, sbb); - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x + 1, y, z - 1, rotation, sbb); - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x - 1, y, z + 1, rotation, sbb); - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x - 1, y, z - 1, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(0 + rotation), x - 1, y, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(2 + rotation), x + 1, y, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(3 + rotation), x + 0, y, z + 1, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(1 + rotation), x + 0, y, z - 1, rotation, sbb); - - placeBlockRotated(world, Blocks.netherrack, 0, x, y, z, rotation, sbb); - placeBlockRotated(world, Blocks.fire, 0, x, y + 1, z, rotation, sbb); + private void makeFirePit(World world, StructureTFDecorator myDeco, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) + { + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), x - 1, y, z + 0, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, false), x + 1, y, z + 0, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), x + 0, y, z + 1, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), x + 0, y, z - 1, rotation, sbb); + setBlockStateRotated(world, myDeco.pillarState, x + 1, y, z + 1, rotation, sbb); + setBlockStateRotated(world, myDeco.pillarState, x + 1, y, z - 1, rotation, sbb); + setBlockStateRotated(world, myDeco.pillarState, x - 1, y, z + 1, rotation, sbb); + setBlockStateRotated(world, myDeco.pillarState, x - 1, y, z - 1, rotation, sbb); + + setBlockStateRotated(world, Blocks.NETHERRACK.getDefaultState(), x, y, z, rotation, sbb); + setBlockStateRotated(world, Blocks.FIRE.getDefaultState(), x, y + 1, z, rotation, sbb); } - private void decorateNetherwart(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y, boolean isTop) + private void decorateNetherwart(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y, boolean isTop) { // StructureTFDecorator netherDeco = new StructureTFDecorator(); -// netherDeco = Blocks.netherBrick; -// netherDeco.pillarID = Blocks.netherBrick; -// netherDeco.stairID = Blocks.stairsNetherBrick; -// netherDeco.fenceID = Blocks.netherFence; +// netherDeco = Blocks.NETHERBRICK; +// netherDeco.pillarID = Blocks.NETHERBRICK; +// netherDeco.stairID = Blocks.STAIRSNETHERBRICK; +// netherDeco.fenceID = Blocks.NETHERFENCE; StructureTFDecorator netherDeco = this.deco; // // lava container // makePillarFrame(world, sbb, netherDeco, rotation, 12, y, 3, 4, 4, 4, true); -// this.fillBlocksRotated(world, sbb, 13, y + 1, 4, 14, y + 1, 5, Blocks.lavaMoving, 0, rotation); +// this.fillBlocksRotated(world, sbb, 13, y + 1, 4, 14, y + 1, 5, Blocks.LAVAMOVING, 0, rotation); // this.fillBlocksRotated(world, sbb, 12, y + 3, 3, 15, y + 4, 6, 0, 0, rotation); - + //makeNetherburst(world, decoRNG, 8, 100, 20, 12, y + 3, 3, rotation, sbb); - + // wart container makePillarFrame(world, sbb, netherDeco, rotation, 12, y, 9, 4, 4, 7, true); - this.fillBlocksRotated(world, sbb, 13, y + 1, 10, 14, y + 1, 14, Blocks.soul_sand, 0, rotation); - this.fillBlocksRotated(world, sbb, 13, y + 2, 10, 14, y + 2, 14, Blocks.nether_wart, 0, rotation); - this.fillBlocksRotated(world, sbb, 13, y + 4, 10, 14, y + 4, 14, Blocks.soul_sand, 0, rotation); - + this.fillBlocksRotated(world, sbb, 13, y + 1, 10, 14, y + 1, 14, Blocks.SOUL_SAND.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, 13, y + 2, 10, 14, y + 2, 14, Blocks.NETHER_WART.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, 13, y + 4, 10, 14, y + 4, 14, Blocks.SOUL_SAND.getDefaultState(), rotation); + // blaze container makePillarFrame(world, sbb, netherDeco, rotation, 5, y, 12, 3, (isTop ? 4 : 9), 3, true); - this.placeBlockRotated(world, netherDeco.blockID, netherDeco.blockMeta, 6, y + 1, 13, rotation, sbb); - this.placeBlockRotated(world, netherDeco.blockID, netherDeco.blockMeta, 6, y + (isTop ? 4 : 9), 13, rotation, sbb); - - this.placeSpawnerRotated(world, 6, y + 3, 13, rotation, "Blaze", sbb); - - + this.setBlockStateRotated(world, netherDeco.blockState, 6, y + 1, 13, rotation, sbb); + this.setBlockStateRotated(world, netherDeco.blockState, 6, y + (isTop ? 4 : 9), 13, rotation, sbb); + + this.setSpawnerRotated(world, 6, y + 3, 13, rotation, VanillaEntityNames.BLAZE, sbb); + + // destruction blob destroyTower(world, decoRNG, 12, y, 3, 2, sbb); - + } - private void decorateBotanical(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + private void decorateBotanical(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { // main part makePillarFrame(world, sbb, this.deco, rotation, 12, y, 12, 4, 4, 4, true); - this.fillBlocksRotated(world, sbb, 13, y + 1, 13, 14, y + 1, 14, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, 13, y + 4, 13, 14, y + 4, 14, deco.blockID, deco.blockMeta, rotation); - + this.fillBlocksRotated(world, sbb, 13, y + 1, 13, 14, y + 1, 14, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 13, y + 4, 13, 14, y + 4, 14, deco.blockState, rotation); + placeRandomPlant(world, decoRNG, 13, y + 2, 13, rotation, sbb); placeRandomPlant(world, decoRNG, 13, y + 2, 14, rotation, sbb); placeRandomPlant(world, decoRNG, 14, y + 2, 13, rotation, sbb); placeRandomPlant(world, decoRNG, 14, y + 2, 14, rotation, sbb); - + // toolbench for (int py = 1; py <= 4; py++) { - placeBlockRotated(world, deco.pillarID, deco.pillarMeta, 12, y + py, 4, rotation, sbb); - placeBlockRotated(world, deco.pillarID, deco.pillarMeta, 15, y + py, 4, rotation, sbb); + setBlockStateRotated(world, deco.pillarState, 12, y + py, 4, rotation, sbb); + setBlockStateRotated(world, deco.pillarState, 15, y + py, 4, rotation, sbb); } - placeBlockRotated(world, deco.stairID, getStairMeta(2 + rotation) + 4, 13, y + 1, 4, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation) + 4, 14, y + 1, 4, rotation, sbb); - - //placeBlockRotated(world, Blocks.chest, 0, 13, y + 2, 4, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, true), 13, y + 1, 4, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, true), 14, y + 1, 4, rotation, sbb); + + //setBlockStateRotated(world, Blocks.CHEST, 0, 13, y + 2, 4, rotation, sbb); placeTreasureRotated(world, 13, y + 2, 4, rotation, TFTreasure.basement, sbb); - placeBlockRotated(world, Blocks.crafting_table, 0, 14, y + 2, 4, rotation, sbb); + setBlockStateRotated(world, Blocks.CRAFTING_TABLE.getDefaultState(), 14, y + 2, 4, rotation, sbb); + + IBlockState slab = Blocks.WOODEN_SLAB.getDefaultState() + .withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP) + .withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.SPRUCE); // bench 2 - placeBlockRotated(world, deco.stairID, getStairMeta(2 + rotation) + 4, 12, y + 1, 7, rotation, sbb); - placeBlockRotated(world, Blocks.wooden_slab, 1 + 8, 13, y + 1, 7, rotation, sbb); - placeBlockRotated(world, Blocks.wooden_slab, 1 + 8, 14, y + 1, 7, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation) + 4, 15, y + 1, 7, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, true), 12, y + 1, 7, rotation, sbb); + setBlockStateRotated(world, slab, 13, y + 1, 7, rotation, sbb); + setBlockStateRotated(world, slab, 14, y + 1, 7, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, true), 15, y + 1, 7, rotation, sbb); // bench 2 - placeBlockRotated(world, deco.stairID, getStairMeta(2 + rotation) + 4, 12, y + 1, 10, rotation, sbb); - placeBlockRotated(world, Blocks.wooden_slab, 1 + 8, 13, y + 1, 10, rotation, sbb); - placeBlockRotated(world, Blocks.wooden_slab, 1 + 8, 14, y + 1, 10, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation) + 4, 15, y + 1, 10, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, true), 12, y + 1, 10, rotation, sbb); + setBlockStateRotated(world, slab, 13, y + 1, 10, rotation, sbb); + setBlockStateRotated(world, slab, 14, y + 1, 10, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, true), 15, y + 1, 10, rotation, sbb); // plants on benches for (int x = 12; x <= 15; x++) @@ -1235,112 +1262,107 @@ private void decorateBotanical(World world, Random decoRNG, StructureBoundingBox placeRandomPlant(world, decoRNG, x, y + 2, 7, rotation, sbb); placeRandomPlant(world, decoRNG, x, y + 2, 10, rotation, sbb); } - + // planter for trees placeTreePlanter(world, decoRNG.nextInt(5), 6, y + 1, 12, rotation, sbb); } - private void placeTreePlanter(World world, int treeNum, int x, int y, int z, int rotation, StructureBoundingBox sbb) + private void placeTreePlanter(World world, int treeNum, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) { - placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x + 1, y, z + 1, rotation, sbb); - placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x + 1, y, z - 1, rotation, sbb); - placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x - 1, y, z + 1, rotation, sbb); - placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x - 1, y, z - 1, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), x - 1, y, z + 0, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(2 + rotation), x + 1, y, z + 0, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(3 + rotation), x + 0, y, z + 1, rotation, sbb); - placeBlockRotated(world, deco.stairID, getStairMeta(1 + rotation), x + 0, y, z - 1, rotation, sbb); - - placeBlockRotated(world, Blocks.dirt, 0, x, y, z, rotation, sbb); - - - int dx = getXWithOffsetAsIfRotated(x, z, rotation); - int dy = getYWithOffset(y + 1); - int dz = getZWithOffsetAsIfRotated(x, z, rotation); - if (sbb.isVecInside(dx, dy, dz)) - { - WorldGenerator treeGen; - // grow a tree - switch (treeNum) - { - case 0: - default: - // oak tree - treeGen = new WorldGenTrees(false); - break; - case 1: - // jungle tree - treeGen = new WorldGenTrees(true, 3, 3, 3, false); - break; - case 2: - // birch - treeGen = new WorldGenForest(true, false); - break; - case 3: - treeGen = new TFGenSmallTwilightOak(false); - break; - case 4: - treeGen = new TFGenSmallRainboak(false); - break; - } - - for (int i = 0; i < 100; i++) - { - if (treeGen.generate(world, world.rand, dx, dy, dz)) - { - break; - } - -// if (i == 99) -// { -// System.out.println("Never generated " + treeGen); -// } - } - } - - } + setBlockStateRotated(world, deco.pillarState, x + 1, y, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.pillarState, x + 1, y, z - 1, rotation, sbb); + setBlockStateRotated(world, deco.pillarState, x - 1, y, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.pillarState, x - 1, y, z - 1, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), x - 1, y, z + 0, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.EAST, rotation, false), x + 1, y, z + 0, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), x + 0, y, z + 1, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), x + 0, y, z - 1, rotation, sbb); + + setBlockStateRotated(world, Blocks.DIRT.getDefaultState(), x, y, z, rotation, sbb); + + + int dx = getXWithOffsetRotated(x, z, rotation); + int dy = getYWithOffset(y + 1); + int dz = getZWithOffsetRotated(x, z, rotation); + if (sbb.isVecInside(new BlockPos(dx, dy, dz))) + { + WorldGenerator treeGen; + // grow a tree + switch (treeNum) + { + case 0: + default: + // oak tree + treeGen = new WorldGenTrees(false); + break; + case 1: + final IBlockState leaves = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, false); + final IBlockState wood = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); + // jungle tree + treeGen = new WorldGenTrees(true, 3, wood, leaves, false); + break; + case 2: + // birch + treeGen = new WorldGenBirchTree(true, false); + break; + case 3: + treeGen = new TFGenSmallTwilightOak(false); + break; + case 4: + treeGen = new TFGenSmallRainboak(false); + break; + } + + for (int i = 0; i < 100; i++) + { + if (treeGen.generate(world, world.rand, new BlockPos(dx, dy, dz))) + { + break; + } + } + } - private void placeRandomPlant(World world, Random decoRNG, int x, int y, int z, int rotation, StructureBoundingBox sbb) - { - int potMeta = decoRNG.nextInt(12); - placeBlockRotated(world, Blocks.flower_pot, potMeta, x, y, z, rotation, sbb); } + private void placeRandomPlant(World world, Random decoRNG, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) + { + int potMeta = decoRNG.nextInt(15); // this seems to be the only way to set the flower pre-placement + final IBlockState flowerPotState = Blocks.FLOWER_POT.getDefaultState().withProperty(BlockFlowerPot.LEGACY_DATA, potMeta); + setBlockStateRotated(world, flowerPotState, x, y, z, rotation, sbb); + } - private void makeBottomEntrance(World world, Random decoRNG, StructureBoundingBox sbb, int rotation, int y) { + private void makeBottomEntrance(World world, Random decoRNG, StructureBoundingBox sbb, Rotation rotation, int y) + { makeFirePit(world, this.deco, 13, y + 1, 3, rotation, sbb); makeFirePit(world, this.deco, 3, y + 1, 13, rotation, sbb); makeFirePit(world, this.deco, 13, y + 1, 13, rotation, sbb); - + makePillarFrame(world, sbb, this.deco, rotation, 7, y, 7, 3, 4, 3, false); } - /** * Add a bunch of timber beams */ - protected void addTimberMaze(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) { - + protected void addTimberMaze(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) + { + int spacing = 5; - int floorside = 0; + Rotation floorside = Rotation.NONE; if (bottom == 0) { bottom += spacing; } - // fill with beam maze for (int y = bottom; y < top; y += spacing) { - floorside += 1; - floorside %= 4; - + floorside = floorside.add(Rotation.CLOCKWISE_90); makeTimberBeams(world, rand, sbb, floorside, y, y == bottom && bottom != spacing, y >= (top - spacing), top); } } @@ -1348,36 +1370,35 @@ protected void addTimberMaze(World world, Random rand, StructureBoundingBox sbb, /** * Make a lattice of log blocks - * @param top + * + * @param top */ - protected void makeTimberBeams(World world, Random rand, StructureBoundingBox sbb, int rotation, int y, boolean isBottom, boolean isTop, int top) + protected void makeTimberBeams(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y, boolean isBottom, boolean isTop, int top) { - Block beamID = TFBlocks.log; - int beamMetaBase = 3; + IBlockState beamID = TFBlocks.twilight_log.getDefaultState(); + IBlockState beamStateNS = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z); + IBlockState beamStateUD = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y); + IBlockState beamStateEW = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X); - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; - int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - int beamMetaUD = 0; - - // three beams going e/w + // three beams going n/s for (int z = 1; z < size - 1; z++) { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaEW, 4, y, z, rotation, sbb); - placeBlockRotated(world, beamID, beamMetaBase + beamMetaEW, 9, y, z, rotation, sbb); - placeBlockRotated(world, beamID, beamMetaBase + beamMetaEW, 14, y, z, rotation, sbb); + setBlockStateRotated(world, beamStateNS, 4, y, z, rotation, sbb); + setBlockStateRotated(world, beamStateNS, 9, y, z, rotation, sbb); + setBlockStateRotated(world, beamStateNS, 14, y, z, rotation, sbb); } // a few random cross beams int z = pickBetweenExcluding(3, size - 3, rand, 4, 9, 14); for (int x = 5; x < 9; x++) { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaNS, x, y, z, rotation, sbb); + setBlockStateRotated(world, beamStateEW, x, y, z, rotation, sbb); } z = pickBetweenExcluding(3, size - 3, rand, 4, 9, 14); for (int x = 10; x < 14; x++) { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaNS, x, y, z, rotation, sbb); + setBlockStateRotated(world, beamStateEW, x, y, z, rotation, sbb); } @@ -1393,42 +1414,41 @@ protected void makeTimberBeams(World world, Random rand, StructureBoundingBox sb { if (!isBottom || checkPost(world, x1, y - 5, z1, rotation, sbb)) { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, x1, y - by, z1, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2, rotation), x1 + 1, y - by, z1, rotation, sbb); + setBlockStateRotated(world, beamStateUD, x1, y - by, z1, rotation, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EnumFacing.WEST), x1 + 1, y - by, z1, rotation, sbb); } if (!isBottom || checkPost(world, x2, y - 5, z2, rotation, sbb)) { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, x2, y - by, z2, rotation, sbb); - } + setBlockStateRotated(world, beamStateUD, x2, y - by, z2, rotation, sbb); + } if (!isBottom || checkPost(world, x3, y - 5, z3, rotation, sbb)) { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, x3, y - by, z3, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(4, rotation), x3 - 1, y - by, z3, rotation, sbb); + setBlockStateRotated(world, beamStateUD, x3, y - by, z3, rotation, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EAST), x3 - 1, y - by, z3, rotation, sbb); } } // do we need a beam going up? if (isTop) { - int topFloorRotation = (this.boundingBox.minY + top + 1) % 4; - + Rotation topFloorRotation = RotationUtil.ROTATIONS[(this.boundingBox.minY + top + 1) % 4]; + int ladderX = 4; int ladderZ = 10; - int ladderMeta = 3; for (int by = 1; by < 5; by++) { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, ladderX, y + by, 9, topFloorRotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(ladderMeta, topFloorRotation), ladderX, y + by, ladderZ, topFloorRotation, sbb); + setBlockStateRotated(world, beamStateUD, ladderX, y + by, 9, topFloorRotation, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EnumFacing.NORTH), ladderX, y + by, ladderZ, topFloorRotation, sbb); } // fence thing - placeBlockRotated(world, Blocks.air, 0, ladderX, y + 6, 9, topFloorRotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, ladderX + 1, y + 5, ladderZ, topFloorRotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, ladderX - 1, y + 5, ladderZ, topFloorRotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, ladderX + 1, y + 6, ladderZ, topFloorRotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, ladderX - 1, y + 6, ladderZ, topFloorRotation, sbb); + setBlockStateRotated(world, AIR, ladderX, y + 6, 9, topFloorRotation, sbb); + setBlockStateRotated(world, deco.fenceState, ladderX + 1, y + 5, ladderZ, topFloorRotation, sbb); + setBlockStateRotated(world, deco.fenceState, ladderX - 1, y + 5, ladderZ, topFloorRotation, sbb); + setBlockStateRotated(world, deco.fenceState, ladderX + 1, y + 6, ladderZ, topFloorRotation, sbb); + setBlockStateRotated(world, deco.fenceState, ladderX - 1, y + 6, ladderZ, topFloorRotation, sbb); } - + if (!isBottom && !isTop) { // spawners @@ -1436,47 +1456,48 @@ protected void makeTimberBeams(World world, Random rand, StructureBoundingBox sb int sz = pickFrom(rand, 6, 11, 12); makeMiniGhastSpawner(world, rand, y, sx, sz, sbb); - + } // lamps int lx = pickFrom(rand, 2, 12, 16); int lz = 2 + rand.nextInt(15); - placeBlockRotated(world, Blocks.redstone_lamp, 0, lx, y + 2, lz, rotation, sbb); - placeBlockRotated(world, Blocks.lever, rand.nextBoolean() ? 0 : 7, lx, y + 1, lz, rotation, sbb); + setBlockStateRotated(world, Blocks.REDSTONE_LAMP.getDefaultState(), lx, y + 2, lz, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), rand.nextBoolean() ? BlockLever.EnumOrientation.DOWN_X : BlockLever.EnumOrientation.DOWN_Z, rotation, false), lx, y + 1, lz, rotation, sbb); } /** * Make a mini ghast spawner and then set the spawn range and max entities for that spawner */ - private void makeMiniGhastSpawner(World world, Random rand, int y, int sx, int sz, StructureBoundingBox sbb) + private void makeMiniGhastSpawner(World world, Random rand, int y, int sx, int sz, StructureBoundingBox sbb) { - TileEntityMobSpawner spawner = placeSpawnerAtCurrentPosition(world, rand, sx, y + 2, sz, TFCreatures.getSpawnerNameFor("Mini Ghast"), sbb); - + TileEntityMobSpawner spawner = setSpawner(world, sx, y + 2, sz, sbb, TFEntityNames.MINI_GHAST); + if (spawner != null) { // change the spawner detection range by this goofy process of writing to and reading from NBT tags - NBTTagCompound tags = new NBTTagCompound(); - spawner.writeToNBT(tags); - - tags.setShort("SpawnRange", (short) 16); - tags.setShort("MaxNearbyEntities", (short) 2);//(short) (world.difficultySetting)); - tags.setShort("SpawnCount", (short) 1); - - spawner.readFromNBT(tags); + NBTTagCompound tags = new NBTTagCompound(); + spawner.writeToNBT(tags); + + tags.setShort("SpawnRange", (short)16); + tags.setShort("MaxNearbyEntities", (short)2);//(short) (world.difficultySetting)); + tags.setShort("SpawnCount", (short)1); + + spawner.readFromNBT(tags); } } - + /** * Add a bunch of platforms accessible with the block builder */ - protected void addBuilderPlatforms(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) { - + protected void addBuilderPlatforms(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) + { + int spacing = 5; - int floorside = 0; + Rotation floorside = Rotation.NONE; if (bottom == 0) { bottom += spacing; @@ -1487,21 +1508,21 @@ protected void addBuilderPlatforms(World world, Random rand, StructureBoundingBo for (int y = bottom; y < (top - spacing); y += spacing) { makeBuilderPlatforms(world, rand, sbb, floorside, y, y == bottom && bottom != spacing, y >= (top - spacing)); - - floorside += 1 + rand.nextInt(3); - floorside %= 4; + floorside = floorside.add(Rotation.CLOCKWISE_90); + floorside = floorside.add(RotationUtil.ROTATIONS[rand.nextInt(3)]); } - + // add the bottom platforms - makeBuilderPlatform(world, rand, 1, bottom, 5, true, sbb); - makeBuilderPlatform(world, rand, 3, bottom, 5, true, sbb); - + makeBuilderPlatform(world, rand, Rotation.CLOCKWISE_90, bottom, 5, true, sbb); + makeBuilderPlatform(world, rand, Rotation.COUNTERCLOCKWISE_90, bottom, 5, true, sbb); + for (int y = bottom - 4; y < bottom; y++) { - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2, 1), 1, y, 5, 1, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2, 3), 1, y, 5, 3, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, WEST), 1, y, 5, Rotation.CLOCKWISE_90, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, WEST), 1, y, 5, Rotation.COUNTERCLOCKWISE_90, sbb); } - + + // top platform addTopBuilderPlatform(world, rand, bottom, top, spacing, sbb); @@ -1511,28 +1532,29 @@ protected void addBuilderPlatforms(World world, Random rand, StructureBoundingBo /** * Make platform with a block builder */ - protected void makeBuilderPlatforms(World world, Random rand, StructureBoundingBox sbb, int rotation, int y, boolean bottom, boolean top) + protected void makeBuilderPlatforms(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y, boolean bottom, boolean top) { int z = size / 2 + rand.nextInt(5) - rand.nextInt(5); - + // bottom platform makeBuilderPlatform(world, rand, rotation, y, z, false, sbb); - + // ladder - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2, rotation), 1, y + 1, z, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2, rotation), 1, y + 2, z, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2, rotation), 1, y + 3, z, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2, rotation), 1, y + 4, z, rotation, sbb); - + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EnumFacing.WEST), 1, y + 1, z, rotation, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EnumFacing.WEST), 1, y + 2, z, rotation, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EnumFacing.WEST), 1, y + 3, z, rotation, sbb); + setBlockStateRotated(world, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EnumFacing.WEST), 1, y + 4, z, rotation, sbb); + makeBuilderPlatform(world, rand, rotation, y + 5, z, true, sbb); - + if (y % 2 == 1) { // reverter blocks int sx = pickFrom(rand, 5, 9, 13); int sz = (sx == 9) ? (rand.nextBoolean() ? 5 : 13) : 9; - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_ANTIBUILDER, sx, y + 2, sz, rotation, sbb); + final IBlockState antibuilder = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.ANTIBUILDER); + setBlockStateRotated(world, antibuilder, sx, y + 2, sz, rotation, sbb); } else { @@ -1548,76 +1570,80 @@ protected void makeBuilderPlatforms(World world, Random rand, StructureBoundingB /** * Add the top floating platform in the builder platforms area */ - private void addTopBuilderPlatform(World world, Random rand, int bottom, int top, int spacing, StructureBoundingBox sbb) { - int rotation = (this.boundingBox.minY + top + 1) % 4; - + private void addTopBuilderPlatform(World world, Random rand, int bottom, int top, int spacing, StructureBoundingBox sbb) + { + Rotation rotation = RotationUtil.ROTATIONS[(this.boundingBox.minY + top + 1) % 4]; + // platform - this.fillBlocksRotated(world, sbb, 5, top - spacing, 9, 7, top - spacing, 11, deco.accentID, deco.accentMeta, rotation); + this.fillBlocksRotated(world, sbb, 5, top - spacing, 9, 7, top - spacing, 11, deco.accentState, rotation); // ladder ascender - this.fillBlocksRotated(world, sbb, 6, top - spacing, 9, 6, top, 9, deco.accentID, deco.accentMeta, rotation); - this.fillBlocksRotated(world, sbb, 6, top - spacing + 1, 10, 6, top - 1, 10, Blocks.ladder, getLadderMeta(3, rotation), rotation); - placeBlockRotated(world, Blocks.air, 0, 6, top + 1, 9, rotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 5, top + 0, 10, rotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 7, top + 0, 10, rotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 5, top + 1, 10, rotation, sbb); - placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 7, top + 1, 10, rotation, sbb); + this.fillBlocksRotated(world, sbb, 6, top - spacing, 9, 6, top, 9, deco.accentState, rotation); + this.fillBlocksRotated(world, sbb, 6, top - spacing + 1, 10, 6, top - 1, 10, Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, EnumFacing.NORTH), rotation); + setBlockStateRotated(world, AIR, 6, top + 1, 9, rotation, sbb); + setBlockStateRotated(world, deco.fenceState, 5, top + 0, 10, rotation, sbb); + setBlockStateRotated(world, deco.fenceState, 7, top + 0, 10, rotation, sbb); + setBlockStateRotated(world, deco.fenceState, 5, top + 1, 10, rotation, sbb); + setBlockStateRotated(world, deco.fenceState, 7, top + 1, 10, rotation, sbb); // builder & lever - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_BUILDER_INACTIVE, 7, top - spacing, 10, rotation, sbb); - placeBlockRotated(world, Blocks.lever, rand.nextBoolean() ? 5 : 6, 7, top - spacing + 1, 11, rotation, sbb); + final IBlockState inactiveBuilder = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.BUILDER_INACTIVE); + setBlockStateRotated(world, inactiveBuilder, 7, top - spacing, 10, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), rand.nextBoolean() ? BlockLever.EnumOrientation.UP_Z : BlockLever.EnumOrientation.UP_X, rotation, false), 7, top - spacing + 1, 11, rotation, sbb); + } - private void makeBuilderPlatform(World world, Random rand, int rotation, int y, int z, boolean hole, StructureBoundingBox sbb) { + private void makeBuilderPlatform(World world, Random rand, Rotation rotation, int y, int z, boolean hole, StructureBoundingBox sbb) + { // top platform - placeBlockRotated(world, deco.accentID, deco.accentMeta, 1, y, z - 1, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 1, y, z - 1, rotation, sbb); if (!hole) { - placeBlockRotated(world, deco.accentID, deco.accentMeta, 1, y, z - 0, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 1, y, z - 0, rotation, sbb); } - placeBlockRotated(world, deco.accentID, deco.accentMeta, 1, y, z + 1, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, 2, y, z - 1, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, 2, y, z - 0, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, 2, y, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 1, y, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 2, y, z - 1, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 2, y, z - 0, rotation, sbb); + setBlockStateRotated(world, deco.accentState, 2, y, z + 1, rotation, sbb); // builder & lever - placeBlockRotated(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_BUILDER_INACTIVE, 2, y, hole ? z + 1 : z - 1, rotation, sbb); - placeBlockRotated(world, Blocks.lever, rand.nextBoolean() ? 5 : 6, 2, y + 1, z + 0, rotation, sbb); + final IBlockState inactiveBuilder = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.BUILDER_INACTIVE); + setBlockStateRotated(world, inactiveBuilder, 2, y, hole ? z + 1 : z - 1, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), rand.nextBoolean() ? BlockLever.EnumOrientation.UP_Z : BlockLever.EnumOrientation.UP_X, rotation, false), 2, y + 1, z + 0, rotation, sbb); } - - /** * Make a cluster of redstone lamps w/ switches as decoration for the empty areas in towers */ - private void makeLampCluster(World world, Random rand, int sx, int y, int sz, int rotation, StructureBoundingBox sbb) + private void makeLampCluster(World world, Random rand, int sx, int y, int sz, Rotation rotation, StructureBoundingBox sbb) { int radius = 4; - + // make lamps for (int i = 0; i < 5; i++) { int lx = sx; int ly = y; int lz = sz; - + for (int move = 0; move < 10; move++) { // place lamp - placeBlockRotated(world, Blocks.redstone_lamp, 0, lx, ly, lz, rotation, sbb); - + setBlockStateRotated(world, Blocks.REDSTONE_LAMP.getDefaultState(), lx, ly, lz, rotation, sbb); + // move randomly int direction = rand.nextInt(8); - + if (direction > 5) - { + { direction -= 2; } + EnumFacing facing = EnumFacing.VALUES[direction]; + - - lx += Facing.offsetsXForSide[direction]; - ly += Facing.offsetsYForSide[direction]; - lz += Facing.offsetsZForSide[direction]; + lx += facing.getXOffset(); + ly += facing.getYOffset(); + lz += facing.getZOffset(); // if we are out of bounds, stop iterating if (lx > sx + radius || lx < sx - radius || ly > y + radius || ly < y - radius || lz > sz + radius || lz < sz - radius) @@ -1626,37 +1652,36 @@ private void makeLampCluster(World world, Random rand, int sx, int y, int sz, in } } } - + // make switches for (int i = 0; i < 5; i++) { int lx = sx; int ly = y; int lz = sz; - + // we need to always call rand.nextInt the same amount of times - int[] directions = new int[10]; + EnumFacing[] directions = new EnumFacing[10]; for (int move = 0; move < 10; move++) { - directions[move] = rand.nextInt(8); - - if (directions[move] > 5) - { - directions[move] -= 2; - } + int direction = rand.nextInt(8); + if (direction > 5) + { + direction -= 2; + } + directions[move] = EnumFacing.VALUES[direction]; } - + for (int move = 0; move < 10; move++) { // move randomly - int direction = directions[move]; - - - lx += Facing.offsetsXForSide[direction]; - ly += Facing.offsetsYForSide[direction]; - lz += Facing.offsetsZForSide[direction]; - + EnumFacing direction = directions[move]; + + lx += direction.getXOffset(); + ly += direction.getYOffset(); + lz += direction.getZOffset(); + // if we are out of bounds, stop iterating if (lx > sx + radius || lx < sx - radius || ly > y + radius || ly < y - radius || lz > sz + radius || lz < sz - radius) { @@ -1664,18 +1689,38 @@ private void makeLampCluster(World world, Random rand, int sx, int y, int sz, in } // if there is no lamp, place a switch and quit - if (getBlockIDRotated(world, lx, ly, lz, rotation, sbb) != Blocks.redstone_lamp) + if (getBlockStateFromPosRotated(world, lx, ly, lz, sbb, rotation).getBlock() != Blocks.REDSTONE_LAMP) { - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, direction), lx, ly, lz, rotation, sbb); + BlockLever.EnumOrientation orientation; + switch (direction) + { + case NORTH: + orientation = BlockLever.EnumOrientation.SOUTH; + break; + case SOUTH: + orientation = BlockLever.EnumOrientation.NORTH; + break; + case EAST: + orientation = BlockLever.EnumOrientation.WEST; + break; + case WEST: + orientation = BlockLever.EnumOrientation.EAST; + break; + case UP: + orientation = BlockLever.EnumOrientation.UP_Z; + break; + case DOWN: + default: + orientation = BlockLever.EnumOrientation.DOWN_X; + break; + } + + + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), orientation, rotation, false), lx, ly, lz, rotation, sbb); break; } } } - - } - - - - + } } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMainBridge.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMainBridge.java index 94cdf91274..50084b806d 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMainBridge.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerMainBridge.java @@ -1,29 +1,30 @@ package twilightforest.structures.darktower; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + import java.util.List; import java.util.Random; -import net.minecraft.world.gen.structure.StructureComponent; - public class ComponentTFDarkTowerMainBridge extends ComponentTFDarkTowerBridge { public ComponentTFDarkTowerMainBridge() { - super(); - // TODO Auto-generated constructor stub } - - protected ComponentTFDarkTowerMainBridge(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, 15, pHeight, direction); + protected ComponentTFDarkTowerMainBridge(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, 15, pHeight, direction); } - - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + + @Override + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // make another size 15 main tower - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 19, direction); - ComponentTFDarkTowerMain wing = new ComponentTFDarkTowerMain(null, rand, index, dx[0], dx[1], dx[2], direction); + ComponentTFDarkTowerMain wing = new ComponentTFDarkTowerMain(getFeatureType(), null, rand, index, dx[0], dx[1], dx[2], direction); list.add(wing); wing.buildComponent(this, list, rand); diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoof.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoof.java index d549f1c551..1006a9042c 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoof.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoof.java @@ -1,45 +1,40 @@ package twilightforest.structures.darktower; -import java.util.List; -import java.util.Random; - import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerRoof; import twilightforest.structures.lichtower.ComponentTFTowerWing; -public class ComponentTFDarkTowerRoof extends ComponentTFTowerRoof -{ +import java.util.List; +import java.util.Random; + +public class ComponentTFDarkTowerRoof extends ComponentTFTowerRoof { public ComponentTFDarkTowerRoof() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFDarkTowerRoof(int i, ComponentTFTowerWing wing) { - super(i, wing); + public ComponentTFDarkTowerRoof(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); // same alignment this.setCoordBaseMode(wing.getCoordBaseMode()); // same size this.size = wing.size; // assuming only square towers and roofs right now. this.height = 12; - + // just hang out at the very top of the tower makeCapBB(wing); - + // spawn list! this.spawnListIndex = 1; } - - @SuppressWarnings("rawtypes") + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) - { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } } @@ -47,23 +42,22 @@ public void buildComponent(StructureComponent parent, List list, Random rand) * A fence around the roof! */ @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) - { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // fence for (int x = 0; x <= size - 1; x++) { for (int z = 0; z <= size - 1; z++) { if (x == 0 || x == size - 1 || z == 0 || z == size - 1) { - placeBlockAtCurrentPosition(world, deco.fenceID, deco.fenceMeta, x, 1, z, sbb); + setBlockState(world, deco.fenceState, x, 1, z, sbb); } } } - - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, 0, 1, 0, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size - 1, 1, 0, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, 0, 1, size - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size - 1, 1, size - 1, sbb); - + + setBlockState(world, deco.accentState, 0, 1, 0, sbb); + setBlockState(world, deco.accentState, size - 1, 1, 0, sbb); + setBlockState(world, deco.accentState, 0, 1, size - 1, sbb); + setBlockState(world, deco.accentState, size - 1, 1, size - 1, sbb); + return true; - } + } } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofAntenna.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofAntenna.java index 6fe9a13be8..97146dd7a8 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofAntenna.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofAntenna.java @@ -1,21 +1,20 @@ package twilightforest.structures.darktower; -import java.util.Random; - import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.Random; + public class ComponentTFDarkTowerRoofAntenna extends ComponentTFDarkTowerRoof { public ComponentTFDarkTowerRoofAntenna() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFDarkTowerRoofAntenna(int i, ComponentTFTowerWing wing) { - super(i, wing); + public ComponentTFDarkTowerRoofAntenna(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); } /** @@ -24,30 +23,28 @@ public ComponentTFDarkTowerRoofAntenna(int i, ComponentTFTowerWing wing) { @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - + // antenna - for (int y = 1; y < 10; y++) - { - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, y, size / 2, sbb); + for (int y = 1; y < 10; y++) { + setBlockState(world, deco.accentState, size / 2, y, size / 2, sbb); } - - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, 1, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, 1, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 1, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 1, size / 2 + 1, sbb); - - for (int y = 7; y < 10; y++) - { - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, y, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, y, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, y, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, y, size / 2 + 1, sbb); + + setBlockState(world, deco.accentState, size / 2 - 1, 1, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, 1, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2, 1, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2, 1, size / 2 + 1, sbb); + + for (int y = 7; y < 10; y++) { + setBlockState(world, deco.accentState, size / 2 - 1, y, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, y, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2, y, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2, y, size / 2 + 1, sbb); } - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, 8, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, 8, size / 2 + 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, 8, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, 8, size / 2 + 1, sbb); + setBlockState(world, deco.accentState, size / 2 - 1, 8, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2 - 1, 8, size / 2 + 1, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, 8, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, 8, size / 2 + 1, sbb); return true; } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofCactus.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofCactus.java index 3ec8f33481..fbb419c43d 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofCactus.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofCactus.java @@ -1,69 +1,61 @@ package twilightforest.structures.darktower; -import java.util.Random; - import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.Random; + public class ComponentTFDarkTowerRoofCactus extends ComponentTFDarkTowerRoof { public ComponentTFDarkTowerRoofCactus() { - super(); - // TODO Auto-generated constructor stub } - - public ComponentTFDarkTowerRoofCactus(int i, ComponentTFTowerWing wing) - { - super(i, wing); + public ComponentTFDarkTowerRoofCactus(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); } - - /** - * cactussy thing - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - + // antenna - for (int y = 1; y < 10; y++) - { - placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, size / 2, y, size / 2, sbb); + for (int y = 1; y < 10; y++) { + setBlockState(world, deco.blockState, size / 2, y, size / 2, sbb); } - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 10, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2, 10, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, 1, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, 1, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 1, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 1, size / 2 + 1, sbb); + setBlockState(world, deco.accentState, size / 2 - 1, 1, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, 1, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2, 1, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2, 1, size / 2 + 1, sbb); // cactus things - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, 7, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 2, 7, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 2, 8, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 2, 9, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 3, 9, size / 2, sbb); - - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 6, size / 2 + 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 6, size / 2 + 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 7, size / 2 + 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 8, size / 2 + 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 8, size / 2 + 3, sbb); - - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, 5, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 2, 5, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 2, 6, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 2, 7, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 3, 7, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, 7, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 2, 7, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 2, 8, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 2, 9, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 3, 9, size / 2, sbb); + + setBlockState(world, deco.accentState, size / 2, 6, size / 2 + 1, sbb); + setBlockState(world, deco.accentState, size / 2, 6, size / 2 + 2, sbb); + setBlockState(world, deco.accentState, size / 2, 7, size / 2 + 2, sbb); + setBlockState(world, deco.accentState, size / 2, 8, size / 2 + 2, sbb); + setBlockState(world, deco.accentState, size / 2, 8, size / 2 + 3, sbb); + + setBlockState(world, deco.accentState, size / 2 - 1, 5, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 - 2, 5, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 - 2, 6, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 - 2, 7, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 - 3, 7, size / 2, sbb); + + setBlockState(world, deco.accentState, size / 2, 4, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2, 4, size / 2 - 2, sbb); + setBlockState(world, deco.accentState, size / 2, 5, size / 2 - 2, sbb); + setBlockState(world, deco.accentState, size / 2, 6, size / 2 - 2, sbb); + setBlockState(world, deco.accentState, size / 2, 6, size / 2 - 3, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 4, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 4, size / 2 - 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 5, size / 2 - 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 6, size / 2 - 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 6, size / 2 - 3, sbb); - return true; } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofFourPost.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofFourPost.java index e28fdb4403..002293a438 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofFourPost.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofFourPost.java @@ -1,54 +1,46 @@ package twilightforest.structures.darktower; -import java.util.Random; - import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.Random; + public class ComponentTFDarkTowerRoofFourPost extends ComponentTFDarkTowerRoof { public ComponentTFDarkTowerRoofFourPost() { - super(); - // TODO Auto-generated constructor stub } - - public ComponentTFDarkTowerRoofFourPost(int i, ComponentTFTowerWing wing) { - super(i, wing); + public ComponentTFDarkTowerRoofFourPost(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); } - - /** - * four posts - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - + makeSmallAntenna(world, sbb, 4, size - 2, size - 2); makeSmallAntenna(world, sbb, 5, 1, size - 2); makeSmallAntenna(world, sbb, 6, size - 2, 1); makeSmallAntenna(world, sbb, 7, 1, 1); - + return true; } - - protected void makeSmallAntenna(World world, StructureBoundingBox sbb, int height, int x, int z) { + private void makeSmallAntenna(World world, StructureBoundingBox sbb, int height, int x, int z) { // antenna - for (int y = 1; y < height; y++) - { - placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, x, y, z, sbb); + for (int y = 1; y < height; y++) { + setBlockState(world, deco.blockState, x, y, z, sbb); } - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, height + 0, z, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, height + 1, z, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x + 1, height + 1, z, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x - 1, height + 1, z, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, height + 1, z + 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, height + 1, z - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, height + 2, z, sbb); + setBlockState(world, deco.accentState, x, height + 0, z, sbb); + setBlockState(world, deco.accentState, x, height + 1, z, sbb); + setBlockState(world, deco.accentState, x + 1, height + 1, z, sbb); + setBlockState(world, deco.accentState, x - 1, height + 1, z, sbb); + setBlockState(world, deco.accentState, x, height + 1, z + 1, sbb); + setBlockState(world, deco.accentState, x, height + 1, z - 1, sbb); + setBlockState(world, deco.accentState, x, height + 2, z, sbb); } } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofRings.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofRings.java index 09512ecaa6..e3b985ea9b 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofRings.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerRoofRings.java @@ -1,45 +1,37 @@ package twilightforest.structures.darktower; -import java.util.Random; - import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.Random; + public class ComponentTFDarkTowerRoofRings extends ComponentTFDarkTowerRoof { public ComponentTFDarkTowerRoofRings() { - super(); - // TODO Auto-generated constructor stub } - - public ComponentTFDarkTowerRoofRings(int i, ComponentTFTowerWing wing) - { - super(i, wing); + public ComponentTFDarkTowerRoofRings(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); } - - /** - * ring a dings - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - + // antenna - for (int y = 1; y < 10; y++) - { - placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, size / 2, y, size / 2, sbb); + for (int y = 1; y < 10; y++) { + setBlockState(world, deco.blockState, size / 2, y, size / 2, sbb); } - - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 10, size / 2, sbb); - - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, 1, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, 1, size / 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 1, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2, 1, size / 2 + 1, sbb); + setBlockState(world, deco.accentState, size / 2, 10, size / 2, sbb); + + + setBlockState(world, deco.accentState, size / 2 - 1, 1, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, 1, size / 2, sbb); + setBlockState(world, deco.accentState, size / 2, 1, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2, 1, size / 2 + 1, sbb); makeARing(world, 6, sbb); makeARing(world, 8, sbb); @@ -50,17 +42,17 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox protected void makeARing(World world, int y, StructureBoundingBox sbb) { - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 2, y, size / 2 + 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 2, y, size / 2 + 0, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 2, y, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 2, y, size / 2 + 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 2, y, size / 2 + 0, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 2, y, size / 2 - 1, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, y, size / 2 - 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 0, y, size / 2 - 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, y, size / 2 - 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 1, y, size / 2 + 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 + 0, y, size / 2 + 2, sbb); - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, size / 2 - 1, y, size / 2 + 2, sbb); + setBlockState(world, deco.accentState, size / 2 - 2, y, size / 2 + 1, sbb); + setBlockState(world, deco.accentState, size / 2 - 2, y, size / 2 + 0, sbb); + setBlockState(world, deco.accentState, size / 2 - 2, y, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2 + 2, y, size / 2 + 1, sbb); + setBlockState(world, deco.accentState, size / 2 + 2, y, size / 2 + 0, sbb); + setBlockState(world, deco.accentState, size / 2 + 2, y, size / 2 - 1, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, y, size / 2 - 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 0, y, size / 2 - 2, sbb); + setBlockState(world, deco.accentState, size / 2 - 1, y, size / 2 - 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 1, y, size / 2 + 2, sbb); + setBlockState(world, deco.accentState, size / 2 + 0, y, size / 2 + 2, sbb); + setBlockState(world, deco.accentState, size / 2 - 1, y, size / 2 + 2, sbb); } } diff --git a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerWing.java b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerWing.java index f5c7e1c299..0d4499325f 100644 --- a/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerWing.java +++ b/src/main/java/twilightforest/structures/darktower/ComponentTFDarkTowerWing.java @@ -1,26 +1,33 @@ package twilightforest.structures.darktower; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.BlockLadder; +import net.minecraft.block.BlockLever; +import net.minecraft.block.BlockLog; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockRedstoneRepeater; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.BlockStairs; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFLog; import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; -import twilightforest.item.TFItems; -import twilightforest.structures.StructureTFComponent; +import twilightforest.enums.TowerDeviceVariant; +import twilightforest.enums.WoodVariant; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.StructureTFDecorator; import twilightforest.structures.lichtower.ComponentTFTowerRoof; import twilightforest.structures.lichtower.ComponentTFTowerRoofAttachedSlab; @@ -28,133 +35,106 @@ import twilightforest.structures.lichtower.ComponentTFTowerRoofGableForwards; import twilightforest.structures.lichtower.ComponentTFTowerRoofSlabForwards; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import twilightforest.util.RotationUtil; +import twilightforest.util.TFEntityNames; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; -public class ComponentTFDarkTowerWing extends ComponentTFTowerWing -{ - +public class ComponentTFDarkTowerWing extends ComponentTFTowerWing { protected boolean keyTower = false; protected ArrayList openingTypes = new ArrayList(); public ComponentTFDarkTowerWing() { - super(); - // TODO Auto-generated constructor stub } - - protected ComponentTFDarkTowerWing(int i, int x, int y, int z, int pSize, int pHeight, int direction) - { - super(i, x, y, z, pSize, pHeight, direction); + protected ComponentTFDarkTowerWing(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("keyTower", this.keyTower); - - par1NBTTagCompound.setIntArray("doorTypeInts", this.getDoorsTypesAsIntArray()); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("keyTower", this.keyTower); + + tagCompound.setIntArray("doorTypeInts", this.getDoorsTypesAsIntArray()); } - /** * Turn the openings array into an array of ints. */ private int[] getDoorsTypesAsIntArray() { - IntBuffer ibuffer = IntBuffer.allocate(this.openingTypes.size()); - - for (EnumDarkTowerDoor doorType : openingTypes) - { - ibuffer.put(doorType.ordinal()); + int[] ret = new int[this.openingTypes.size()]; + + int idx = 0; + + for (EnumDarkTowerDoor doorType : openingTypes) { + ret[idx++] = doorType.ordinal(); } - - return ibuffer.array(); + + return ret; } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.keyTower = par1NBTTagCompound.getBoolean("keyTower"); - - this.readDoorsTypesFromArray(par1NBTTagCompound.getIntArray("doorTypeInts")); - } + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.keyTower = tagCompound.getBoolean("keyTower"); + + this.readDoorsTypesFromArray(tagCompound.getIntArray("doorTypeInts")); + } /** * Read in opening types from int array */ private void readDoorsTypesFromArray(int[] intArray) { - for (int typeInt : intArray) - { + for (int typeInt : intArray) { this.openingTypes.add(EnumDarkTowerDoor.values()[typeInt]); } } - - /** - * Read in openings from int array - */ - @SuppressWarnings("unused") - private void readOpeningsFromArray(int[] intArray) { - for (int i = 0; i < intArray.length; i += 3) - { - ChunkCoordinates door = new ChunkCoordinates(intArray[i], intArray[i + 1], intArray[i + 2]); - - this.openings.add(door); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - + // we should have a door where we started - addOpening(0, 1, size / 2, 2); - + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); + // add a roof? makeARoof(parent, list, rand); // add a beard makeABeard(parent, list, rand); - - + + if (size > 10) { // sub towers - for (int direction = 0; direction < 4; direction++) { + for (Rotation direction : RotationUtil.ROTATIONS) { int[] dest = getValidOpening(rand, direction); int childSize = size - 2; int childHeight = validateChildHeight(height - 4 + rand.nextInt(10) - rand.nextInt(10), childSize); - + boolean madeWing = makeTowerWing(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], size - 2, childHeight, direction); - + // occasional balcony - if (!madeWing && (direction == 2 || rand.nextBoolean())) - { + if (!madeWing && (direction == Rotation.CLOCKWISE_180 || rand.nextBoolean())) { makeTowerBalcony(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], direction); } } - } - else if (rand.nextInt(4) == 0) - { + } else if (rand.nextInt(4) == 0) { // occasional balcony on small towers too - int direction = rand.nextInt(4); + Rotation direction = RotationUtil.ROTATIONS[rand.nextInt(4)]; int[] dest = getValidOpening(rand, direction); makeTowerBalcony(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], direction); } - - + + } - - protected int validateChildHeight(int childHeight, int childSize) - { + + protected int validateChildHeight(int childHeight, int childSize) { return (childHeight / 4) * 4 + 1; // if (childSize > 9) @@ -166,129 +146,121 @@ protected int validateChildHeight(int childHeight, int childSize) // return (childHeight / 3) * 3; // } } - + /** * Attach a roof to this tower. */ @Override - public void makeARoof(StructureComponent parent, List list, Random rand) - { + public void makeARoof(StructureComponent parent, List list, Random rand) { int index = this.getComponentType(); - + ComponentTFTowerRoof roof; - - switch (rand.nextInt(5)) - { - case 0: - case 1: - default: - roof = new ComponentTFDarkTowerRoofAntenna(index, this); - break; - case 2: - roof = new ComponentTFDarkTowerRoofCactus(index, this); - break; - case 3: - roof = new ComponentTFDarkTowerRoofRings(index, this); - break; - case 4: - roof = new ComponentTFDarkTowerRoofFourPost(index, this); - break; + + switch (rand.nextInt(5)) { + case 0: + case 1: + default: + roof = new ComponentTFDarkTowerRoofAntenna(getFeatureType(), index, this); + break; + case 2: + roof = new ComponentTFDarkTowerRoofCactus(getFeatureType(), index, this); + break; + case 3: + roof = new ComponentTFDarkTowerRoofRings(getFeatureType(), index, this); + break; + case 4: + roof = new ComponentTFDarkTowerRoofFourPost(getFeatureType(), index, this); + break; } list.add(roof); roof.buildComponent(this, list, rand); roofType = roof.getClass(); } - + + @Override protected void makeAttachedRoof(List list, Random rand) { int index = this.getComponentType(); ComponentTFTowerRoof roof; - + // this is our preferred roof type: if (roofType == null && rand.nextInt(32) != 0) { - tryToFitRoof(list, rand, new ComponentTFTowerRoofGableForwards(index + 1, this)); + tryToFitRoof(list, rand, new ComponentTFTowerRoofGableForwards(getFeatureType(), index + 1, this)); } - + // this is for roofs that don't fit. if (roofType == null && rand.nextInt(8) != 0) { - tryToFitRoof(list, rand, new ComponentTFTowerRoofSlabForwards(index + 1, this)); + tryToFitRoof(list, rand, new ComponentTFTowerRoofSlabForwards(getFeatureType(), index + 1, this)); } - + // finally, if we're cramped for space, try this if (roofType == null && rand.nextInt(32) != 0) { // fall through to this next roof - roof = new ComponentTFTowerRoofAttachedSlab(index + 1, this); + roof = new ComponentTFTowerRoofAttachedSlab(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } - + // last resort if (roofType == null) { // fall through to this next roof - roof = new ComponentTFTowerRoofFence(index + 1, this); + roof = new ComponentTFTowerRoofFence(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } } - + /** * Add a beard to this structure. There is only one type of beard. */ @Override public void makeABeard(StructureComponent parent, List list, Random rand) { - ComponentTFDarkTowerBeard beard = new ComponentTFDarkTowerBeard(this.getComponentType() + 1, this); + ComponentTFDarkTowerBeard beard = new ComponentTFDarkTowerBeard(getFeatureType(), this.getComponentType() + 1, this); list.add(beard); beard.buildComponent(this, list, rand); } - + /** * Make another wing just like this one */ @Override - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) - { + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // kill too-small towers if (wingHeight < 8) { return false; } - - int direction = (getCoordBaseMode() + rotation) % 4; + + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 5, direction); - - if (dx[1] + wingHeight > 250) - { + + if (dx[1] + wingHeight > 250) { // end of the world! return false; } - - ComponentTFDarkTowerBridge bridge = new ComponentTFDarkTowerBridge(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + + ComponentTFDarkTowerBridge bridge = new ComponentTFDarkTowerBridge(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, bridge.getBoundingBox()); - if (intersect == null || intersect == this) - { + if (intersect == null || intersect == this) { intersect = StructureComponent.findIntersecting(list, bridge.getWingBB()); - } - else - { + } else { return false; - } + } if (intersect == null || intersect == this) { list.add(bridge); bridge.buildComponent(this, list, rand); addOpening(x, y, z, rotation); return true; } else { -// System.out.println("Planned wing intersects with " + intersect); return false; } } - - protected boolean makeTowerBalcony(List list, Random rand, int index, int x, int y, int z, int rotation) - { - int direction = (getCoordBaseMode() + rotation) % 4; + + protected boolean makeTowerBalcony(List list, Random rand, int index, int x, int y, int z, Rotation rotation) { + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 5, direction); - - - ComponentTFDarkTowerBalcony balcony = new ComponentTFDarkTowerBalcony(index, dx[0], dx[1], dx[2], direction); + + + ComponentTFDarkTowerBalcony balcony = new ComponentTFDarkTowerBalcony(getFeatureType(), index, dx[0], dx[1], dx[2], direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, balcony.getBoundingBox()); if (intersect == null || intersect == this) { @@ -297,7 +269,6 @@ protected boolean makeTowerBalcony(List list, Random rand, i addOpening(x, y, z, rotation, EnumDarkTowerDoor.REAPPEARING); return true; } else { -// System.out.println("Planned wing intersects with " + intersect); return false; } @@ -310,56 +281,47 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox // make walls makeEncasedWalls(world, rand, sbb, 0, 0, 0, size - 1, height - 1, size - 1); - + // clear inside fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); // sky light nullifySkyLightForBoundingBox(world); - - if (this.size > 9) - { + + if (this.size > 9) { // half floors, always starting at y = 4 addHalfFloors(world, decoRNG, sbb, 4, height - 1); - } - else - { - if (decoRNG.nextInt(3) == 0) - { + } else { + if (decoRNG.nextInt(3) == 0) { addSmallTimberBeams(world, decoRNG, sbb, 4, height - 1); - } - else - { + } else { addHalfFloors(world, decoRNG, sbb, 4, height - 1); } } - // openings - makeOpenings(world, sbb); - - // destroy some towers - if (decoRNG.nextBoolean() && !this.isKeyTower() && this.height > 8) - { - int blobs = 1; - - if (this.size > 9 && decoRNG.nextBoolean()) - { - blobs++; - } - - for (int i = 0; i < blobs; i++) - { - - // find a random spot in the tower - int x = decoRNG.nextInt(size); - int y = decoRNG.nextInt(height - 7) + 2; - int z = decoRNG.nextInt(size); - - destroyTower(world, decoRNG, x, y, z, 3, sbb); - } - - } - + // openings + makeOpenings(world, sbb); + + // destroy some towers + if (decoRNG.nextBoolean() && !this.isKeyTower() && this.height > 8) { + int blobs = 1; + + if (this.size > 9 && decoRNG.nextBoolean()) { + blobs++; + } + + for (int i = 0; i < blobs; i++) { + + // find a random spot in the tower + int x = decoRNG.nextInt(size); + int y = decoRNG.nextInt(height - 7) + 2; + int z = decoRNG.nextInt(size); + + destroyTower(world, decoRNG, x, y, z, 3, sbb); + } + + } + return true; } @@ -368,47 +330,38 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox */ protected void destroyTower(World world, Random decoRNG, int x, int y, int z, int amount, StructureBoundingBox sbb) { //makeNetherburst(world, decoRNG, 16, 100, 40, x, y, z, 0, sbb); - + int initialRadius = decoRNG.nextInt(amount) + amount; - - drawBlob(world, x, y, z, initialRadius, Blocks.air, 0, sbb); - - for (int i = 0; i < 3; i++) - { + + drawBlob(world, x, y, z, initialRadius, AIR, sbb); + + for (int i = 0; i < 3; i++) { int dx = x + (initialRadius - 1) * (decoRNG.nextBoolean() ? 1 : -1); int dy = y + (initialRadius - 1) * (decoRNG.nextBoolean() ? 1 : -1); int dz = z + (initialRadius - 1) * (decoRNG.nextBoolean() ? 1 : -1); netherTransformBlob(world, decoRNG, dx, dy, dz, initialRadius - 1, sbb); - drawBlob(world, dx, dy, dz, initialRadius - 2, Blocks.air, 0, sbb); + drawBlob(world, dx, dy, dz, initialRadius - 2, AIR, sbb); } } - + private void netherTransformBlob(World world, Random inRand, int sx, int sy, int sz, int rad, StructureBoundingBox sbb) { - + Random rand = new Random(inRand.nextLong()); - + // then trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dy = 0; dy <= rad; dy++) - { - for (byte dz = 0; dz <= rad; dz++) - { + for (byte dx = 0; dx <= rad; dx++) { + for (byte dy = 0; dy <= rad; dy++) { + for (byte dz = 0; dz <= rad; dz++) { // determine how far we are from the center. byte dist = 0; - if (dx >= dy && dx >= dz) - { - dist = (byte) (dx + (byte)((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); - } - else if (dy >= dx && dy >= dz) - { - dist = (byte) (dy + (byte)((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); - } - else - { - dist = (byte) (dz + (byte)((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); + if (dx >= dy && dx >= dz) { + dist = (byte) (dx + (byte) ((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); + } else if (dy >= dx && dy >= dz) { + dist = (byte) (dy + (byte) ((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); + } else { + dist = (byte) (dz + (byte) ((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); } @@ -432,13 +385,11 @@ else if (dy >= dx && dy >= dz) private void testAndChangeToNetherrack(World world, Random rand, int x, int y, int z, StructureBoundingBox sbb) { - if (this.getBlockAtCurrentPosition(world, x, y, z, sbb) != Blocks.air) - { - this.placeBlockAtCurrentPosition(world, Blocks.netherrack, 0, x, y, z, sbb); - - if (this.getBlockAtCurrentPosition(world, x, y + 1, z, sbb) == Blocks.air && rand.nextBoolean()) - { - this.placeBlockAtCurrentPosition(world, Blocks.fire, 0, x, y + 1, z, sbb); + if (this.getBlockStateFromPos(world, x, y, z, sbb).getBlock() != Blocks.AIR) { + this.setBlockState(world, Blocks.NETHERRACK.getDefaultState(), x, y, z, sbb); + + if (this.getBlockStateFromPos(world, x, y + 1, z, sbb).getBlock() == Blocks.AIR && rand.nextBoolean()) { + this.setBlockState(world, Blocks.FIRE.getDefaultState(), x, y + 1, z, sbb); } } } @@ -447,121 +398,101 @@ private void testAndChangeToNetherrack(World world, Random rand, int x, int y, i /** * Draw a giant blob of whatevs (okay, it's going to be leaves). */ - public void drawBlob(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue, StructureBoundingBox sbb) { + private void drawBlob(World world, int sx, int sy, int sz, int rad, IBlockState state, StructureBoundingBox sbb) { // then trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dy = 0; dy <= rad; dy++) - { - for (byte dz = 0; dz <= rad; dz++) - { + for (byte dx = 0; dx <= rad; dx++) { + for (byte dy = 0; dy <= rad; dy++) { + for (byte dz = 0; dz <= rad; dz++) { // determine how far we are from the center. byte dist = 0; - if (dx >= dy && dx >= dz) - { - dist = (byte) (dx + (byte)((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); - } - else if (dy >= dx && dy >= dz) - { - dist = (byte) (dy + (byte)((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); - } - else - { - dist = (byte) (dz + (byte)((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); + if (dx >= dy && dx >= dz) { + dist = (byte) (dx + (byte) ((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); + } else if (dy >= dx && dy >= dz) { + dist = (byte) (dy + (byte) ((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); + } else { + dist = (byte) (dz + (byte) ((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); } // if we're inside the blob, fill it if (dist <= rad) { // do eight at a time for easiness! - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx + dx, sy + dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx + dx, sy + dy, sz - dz, sbb); - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx - dx, sy + dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx - dx, sy + dy, sz - dz, sbb); - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx + dx, sy - dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx + dx, sy - dy, sz - dz, sbb); - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx - dx, sy - dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, sx - dx, sy - dy, sz - dz, sbb); + this.setBlockState(world, state, sx + dx, sy + dy, sz + dz, sbb); + this.setBlockState(world, state, sx + dx, sy + dy, sz - dz, sbb); + this.setBlockState(world, state, sx - dx, sy + dy, sz + dz, sbb); + this.setBlockState(world, state, sx - dx, sy + dy, sz - dz, sbb); + this.setBlockState(world, state, sx + dx, sy - dy, sz + dz, sbb); + this.setBlockState(world, state, sx + dx, sy - dy, sz - dz, sbb); + this.setBlockState(world, state, sx - dx, sy - dy, sz + dz, sbb); + this.setBlockState(world, state, sx - dx, sy - dy, sz - dz, sbb); } } } } } - /** * Add a bunch of random half floors */ - protected void addHalfFloors(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) { - + private void addHalfFloors(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) { + int spacing = 4;//this.size > 9 ? 4 : 3; - int rotation = (this.boundingBox.minY + bottom) % 3; + Rotation rotation = RotationUtil.ROTATIONS[(this.boundingBox.minY + bottom) % 3]; - if (bottom == 0) - { + if (bottom == 0) { bottom += spacing; } // fill with half floors - for (int y = bottom; y < top; y += spacing) - { - rotation += 2;//rand.nextInt(3) > 0 ? 1 : 3; - rotation %= 4; - - if (y >= top - spacing) - { + for (int y = bottom; y < top; y += spacing) { + rotation = rotation.add(Rotation.CLOCKWISE_180); + + if (y >= top - spacing) { makeFullFloor(world, sbb, rotation, y, spacing); - if (isDeadEnd()) - { + if (isDeadEnd()) { decorateTreasureRoom(world, sbb, rotation, y, 4, this.deco); } - } - else - { + } else { makeHalfFloor(world, sbb, rotation, y, spacing); - + // decorate - switch (rand.nextInt(8)) - { - case 0: - if (this.size < 11) - { - decorateReappearingFloor(world, rand, sbb, rotation, y); + switch (rand.nextInt(8)) { + case 0: + if (this.size < 11) { + decorateReappearingFloor(world, rand, sbb, rotation, y); + break; + } + case 1: + decorateSpawner(world, rand, sbb, rotation, y); + break; + case 2: + decorateLounge(world, rand, sbb, rotation, y); + break; + case 3: + decorateLibrary(world, rand, sbb, rotation, y); + break; + case 4: + decorateExperimentPulser(world, rand, sbb, rotation, y); + break; + case 5: + decorateExperimentLamp(world, rand, sbb, rotation, y); + break; + case 6: + decoratePuzzleChest(world, rand, sbb, rotation, y); break; - } - case 1: - decorateSpawner(world, rand, sbb, rotation, y); - break; - case 2: - decorateLounge(world, rand, sbb, rotation, y); - break; - case 3: - decorateLibrary(world, rand, sbb, rotation, y); - break; - case 4: - decorateExperimentPulser(world, rand, sbb, rotation, y); - break; - case 5: - decorateExperimentLamp(world, rand, sbb, rotation, y); - break; - case 6: - decoratePuzzleChest(world, rand, sbb, rotation, y); - break; } - + } - + addStairsDown(world, sbb, rotation, y, size - 2, spacing); - if (this.size > 9) - { + if (this.size > 9) { // double wide staircase addStairsDown(world, sbb, rotation, y, size - 3, spacing); } } - - rotation += 2;//rand.nextInt(3) > 0 ? 1 : 3; - rotation %= 4; - + + rotation = rotation.add(Rotation.CLOCKWISE_180); + // stairs to roof addStairsDown(world, sbb, rotation, this.height - 1, size - 2, spacing); } @@ -569,205 +500,212 @@ protected void addHalfFloors(World world, Random rand, StructureBoundingBox sbb, /** * Dark tower half floors */ - protected void makeHalfFloor(World world, StructureBoundingBox sbb, int rotation, int y, int spacing) - { - this.fillBlocksRotated(world, sbb, size / 2, y, 1, size - 2, y, size - 2, deco.blockID, deco.blockMeta, rotation); - this.fillBlocksRotated(world, sbb, size / 2 - 1, y, 1, size / 2 - 1, y, size - 2, deco.accentID, deco.accentMeta, rotation); + protected void makeHalfFloor(World world, StructureBoundingBox sbb, Rotation rotation, int y, int spacing) { + this.fillBlocksRotated(world, sbb, size / 2, y, 1, size - 2, y, size - 2, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, size / 2 - 1, y, 1, size / 2 - 1, y, size - 2, deco.accentState, rotation); } - + /** * Dark tower full floors */ - protected void makeFullFloor(World world, StructureBoundingBox sbb, int rotation, int y, int spacing) - { + protected void makeFullFloor(World world, StructureBoundingBox sbb, Rotation rotation, int y, int spacing) { // half floor - this.fillWithMetadataBlocks(world, sbb, 1, y, 1, size - 2, y, size - 2, deco.blockID, deco.blockMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, size / 2, y, 1, size / 2, y, size - 2, deco.accentID, deco.accentMeta, Blocks.air, 0, true); + this.fillWithBlocks(world, sbb, 1, y, 1, size - 2, y, size - 2, deco.blockState, Blocks.AIR.getDefaultState(), false); + this.fillWithBlocks(world, sbb, size / 2, y, 1, size / 2, y, size - 2, deco.accentState, Blocks.AIR.getDefaultState(), true); } - + /** * Dark tower treasure rooms! - * @param myDeco + * + * @param myDeco */ - protected void decorateTreasureRoom(World world, StructureBoundingBox sbb, int rotation, int y, int spacing, StructureTFDecorator myDeco) - { + protected void decorateTreasureRoom(World world, StructureBoundingBox sbb, Rotation rotation, int y, int spacing, StructureTFDecorator myDeco) { //treasure chest! int x = this.size / 2; int z = this.size / 2; - - for (int dy = 1; dy < spacing; dy++) - { - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x - 1, y + dy, z - 1, rotation, sbb); - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x + 1, y + dy, z - 1, rotation, sbb); - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x - 1, y + dy, z + 1, rotation, sbb); - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x + 1, y + dy, z + 1, rotation, sbb); - } - - placeBlockRotated(world, myDeco.stairID, getStairMeta(1 + rotation), x + 0, y + 1, z - 1, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(0 + rotation), x - 1, y + 1, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(2 + rotation), x + 1, y + 1, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(3 + rotation), x + 0, y + 1, z + 1, rotation, sbb); - - for (int dy = 2; dy < spacing - 1; dy++) - { - placeBlockRotated(world, myDeco.fenceID, myDeco.fenceMeta, x + 0, y + dy, z - 1, rotation, sbb); - placeBlockRotated(world, myDeco.fenceID, myDeco.fenceMeta, x - 1, y + dy, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.fenceID, myDeco.fenceMeta, x + 1, y + dy, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.fenceID, myDeco.fenceMeta, x + 0, y + dy, z + 1, rotation, sbb); - } - - placeBlockRotated(world, myDeco.stairID, getStairMeta(1 + rotation) + 4, x + 0, y + spacing - 1, z - 1, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(0 + rotation) + 4, x - 1, y + spacing - 1, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(2 + rotation) + 4, x + 1, y + spacing - 1, z + 0, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(3 + rotation) + 4, x + 0, y + spacing - 1, z + 1, rotation, sbb); - placeBlockRotated(world, myDeco.platformID, myDeco.platformMeta, x, y + 1, z, rotation, sbb); + this.makePillarFrame(world, sbb, this.deco, rotation, x - 1, y, z - 1, true); + + setBlockStateRotated(world, myDeco.platformState, x, y + 1, z, rotation, sbb); placeTreasureAtCurrentPosition(world, null, x, y + 2, z, this.isKeyTower() ? TFTreasure.darktower_key : TFTreasure.darktower_cache, sbb); - if (this.isKeyTower()) - { - putItemInTreasure(world, x, y + 2, z, new ItemStack(TFItems.towerKey), sbb); - } } - private void decorateSpawner(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) - { + private void decorateSpawner(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) { int x = this.size > 9 ? 4 : 3; int z = this.size > 9 ? 5 : 4; - - String mobID; - - if (this.size > 9) - { - mobID = rand.nextBoolean() ? TFCreatures.getSpawnerNameFor("Tower Golem") : TFCreatures.getSpawnerNameFor("Redscale Broodling"); - } - else - { - mobID = TFCreatures.getSpawnerNameFor("Redscale Broodling"); + + ResourceLocation mobID; + + if (this.size > 9) { + mobID = rand.nextBoolean() ? TFEntityNames.TOWER_GOLEM : TFEntityNames.TOWER_BROODLING; + } else { + mobID = TFEntityNames.TOWER_BROODLING; } - + // pillar frame this.makePillarFrame(world, sbb, this.deco, rotation, x, y, z, true); - this.placeSpawnerRotated(world, x + 1, y + 2, z + 1, rotation, mobID, sbb); + this.setSpawnerRotated(world, x + 1, y + 2, z + 1, rotation, mobID, sbb); } /** * A lounge with a couch and table */ - private void decorateLounge(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) - { + private void decorateLounge(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) { int cx = this.size > 9 ? 9 : 7; int cz = this.size > 9 ? 4 : 3; - - placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), cx, y + 1, cz + 0, rotation, sbb); - placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), cx, y + 1, cz + 1, rotation, sbb); - placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation), cx, y + 1, cz + 2, rotation, sbb); - + + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), cx, y + 1, cz + 0, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), cx, y + 1, cz + 1, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), cx, y + 1, cz + 2, rotation, sbb); + cx = this.size > 9 ? 5 : 3; - - placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, cx, y + 1, cz + 0, rotation, sbb); - placeBlockRotated(world, Blocks.wooden_slab, 1 + 8, cx, y + 1, cz + 1, rotation, sbb); - placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation) + 4, cx, y + 1, cz + 2, rotation, sbb); + + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, true), cx, y + 1, cz + 0, rotation, sbb); + setBlockStateRotated(world, getSlabState(Blocks.WOODEN_SLAB.getDefaultState(), BlockPlanks.EnumType.SPRUCE, BlockSlab.EnumBlockHalf.TOP), cx, y + 1, cz + 1, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, true), cx, y + 1, cz + 2, rotation, sbb); } /** * Decorate with a pressure plate triggered reappearing floor. Only suitable for small towers */ - private void decorateReappearingFloor(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) { + private void decorateReappearingFloor(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) { + final IBlockState inactiveReappearing = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.REAPPEARING_INACTIVE); + final IBlockState woodenPressurePlate = Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(); // floor - this.fillBlocksRotated(world, sbb, 4, y, 3, 7, y, 5, TFBlocks.towerDevice, BlockTFTowerDevice.META_REAPPEARING_INACTIVE, rotation); + this.fillBlocksRotated(world, sbb, 4, y, 3, 7, y, 5, inactiveReappearing, rotation); // plates - this.fillBlocksRotated(world, sbb, 4, y + 1, 2, 7, y + 1, 2, Blocks.wooden_pressure_plate, 0, rotation); - this.fillBlocksRotated(world, sbb, 4, y + 1, 6, 7, y + 1, 6, Blocks.wooden_pressure_plate, 0, rotation); + this.fillBlocksRotated(world, sbb, 4, y + 1, 2, 7, y + 1, 2, woodenPressurePlate, rotation); + this.fillBlocksRotated(world, sbb, 4, y + 1, 6, 7, y + 1, 6, woodenPressurePlate, rotation); } /** * Decorate with a redstone device that turns a lamp on or off */ - private void decorateExperimentLamp(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) { - + private void decorateExperimentLamp(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) { + int cx = this.size > 9 ? 5 : 3; int cz = this.size > 9 ? 5 : 4; - - placeBlockRotated(world, Blocks.sticky_piston, 1, cx, y + 1, cz, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_lamp, 0, cx, y + 2, cz, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, cx, y + 1, cz + 1, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 3), cx, y + 1, cz + 2, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, cx, y + 3, cz - 1, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 2) + 8, cx, y + 3, cz - 2, rotation, sbb); + + final IBlockState redstoneLamp = Blocks.REDSTONE_LAMP.getDefaultState(); + + setBlockStateRotated(world, Blocks.STICKY_PISTON.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.UP), cx, y + 1, cz, rotation, sbb); + setBlockStateRotated(world, redstoneLamp, cx, y + 2, cz, rotation, sbb); + setBlockStateRotated(world, deco.accentState, cx, y + 1, cz + 1, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.NORTH, rotation, false), cx, y + 1, cz + 2, rotation, sbb); + setBlockStateRotated(world, deco.accentState, cx, y + 3, cz - 1, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.SOUTH, rotation, true), cx, y + 3, cz - 2, rotation, sbb); } - + + protected static IBlockState getLeverState(IBlockState initialState, BlockLever.EnumOrientation direction, Rotation rotation, boolean isPowered) { + switch (direction) { + case NORTH: + case SOUTH: + case EAST: + case WEST: + // ignore rotation, as this is handled deeper in the structure code + break; + case UP_X: + if (rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90) { + direction = BlockLever.EnumOrientation.UP_Z; + } + break; + case UP_Z: + if (rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90) { + direction = BlockLever.EnumOrientation.UP_X; + } + break; + case DOWN_X: + if (rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90) { + direction = BlockLever.EnumOrientation.DOWN_Z; + } + break; + case DOWN_Z: + if (rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90) { + direction = BlockLever.EnumOrientation.DOWN_X; + } + break; + } + return initialState.withProperty(BlockLever.FACING, direction) + .withProperty(BlockLever.POWERED, isPowered); + } + /** * Decorate with a redstone device that pulses a block back and forth */ - private void decorateExperimentPulser(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) { - + private void decorateExperimentPulser(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) { + int cx = this.size > 9 ? 6 : 5; int cz = this.size > 9 ? 4 : 3; - - placeBlockRotated(world, Blocks.sticky_piston, 5 - getStairMeta(3 + rotation), cx, y + 1, cz + 1, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, cx, y + 1, cz, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_wire, 0, cx + 1, y + 1, cz, rotation, sbb); - placeBlockRotated(world, Blocks.wooden_pressure_plate, 0, cx + 2, y + 1, cz, rotation, sbb); - placeBlockRotated(world, Blocks.unpowered_repeater, (rotation + 1) % 4 + 4, cx - 1, y + 1, cz, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_wire, 0, cx - 2, y + 1, cz, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_wire, 0, cx - 2, y + 1, cz + 1, rotation, sbb); - placeBlockRotated(world, Blocks.redstone_wire, 0, cx - 1, y + 1, cz + 1, rotation, sbb); + IBlockState redstoneWire = Blocks.REDSTONE_WIRE.getDefaultState(); + IBlockState woodenPressurePlate = Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(); + IBlockState stickyPiston = Blocks.STICKY_PISTON.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.SOUTH); + IBlockState unpoweredRepeater = Blocks.UNPOWERED_REPEATER.getDefaultState().withProperty(BlockHorizontal.FACING, EnumFacing.WEST).withProperty(BlockRedstoneRepeater.DELAY, 2); + + setBlockStateRotated(world, stickyPiston, cx, y + 1, cz + 1, rotation, sbb); + setBlockStateRotated(world, deco.accentState, cx, y + 1, cz, rotation, sbb); + setBlockStateRotated(world, redstoneWire, cx + 1, y + 1, cz, rotation, sbb); + setBlockStateRotated(world, woodenPressurePlate, cx + 2, y + 1, cz, rotation, sbb); + setBlockStateRotated(world, unpoweredRepeater, cx - 1, y + 1, cz, rotation, sbb); + setBlockStateRotated(world, redstoneWire, cx - 2, y + 1, cz, rotation, sbb); + setBlockStateRotated(world, redstoneWire, cx - 2, y + 1, cz + 1, rotation, sbb); + setBlockStateRotated(world, redstoneWire, cx - 1, y + 1, cz + 1, rotation, sbb); } /** * Decorate with some bookshelves */ - private void decorateLibrary(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) { + private void decorateLibrary(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) { int bx = this.size > 9 ? 4 : 3; int bz = this.size > 9 ? 3 : 2; - + makeSmallBookshelf(world, sbb, rotation, y, bx, bz); - + bx = this.size > 9 ? 9 : 7; bz = this.size > 9 ? 3 : 2; makeSmallBookshelf(world, sbb, rotation, y, bx, bz); } - protected void makeSmallBookshelf(World world, StructureBoundingBox sbb, int rotation, int y, int bx, int bz) { - placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation) + 0, bx, y + 1, bz + 0, rotation, sbb); - placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation) + 4, bx, y + 2, bz + 0, rotation, sbb); - placeBlockRotated(world, Blocks.bookshelf, 0, bx, y + 1, bz + 1, rotation, sbb); - placeBlockRotated(world, Blocks.bookshelf, 0, bx, y + 2, bz + 1, rotation, sbb); - placeBlockRotated(world, Blocks.bookshelf, 0, bx, y + 1, bz + 2, rotation, sbb); - placeBlockRotated(world, Blocks.bookshelf, 0, bx, y + 2, bz + 2, rotation, sbb); - placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 0, bx, y + 1, bz + 3, rotation, sbb); - placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, bx, y + 2, bz + 3, rotation, sbb); + protected void makeSmallBookshelf(World world, StructureBoundingBox sbb, Rotation rotation, int y, int bx, int bz) { + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), bx, y + 1, bz + 0, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, true), bx, y + 2, bz + 0, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false), bx, y + 1, bz + 3, rotation, sbb); + setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, true), bx, y + 2, bz + 3, rotation, sbb); + final IBlockState bookshelf = Blocks.BOOKSHELF.getDefaultState(); + setBlockStateRotated(world, bookshelf, bx, y + 1, bz + 1, rotation, sbb); + setBlockStateRotated(world, bookshelf, bx, y + 2, bz + 1, rotation, sbb); + setBlockStateRotated(world, bookshelf, bx, y + 1, bz + 2, rotation, sbb); + setBlockStateRotated(world, bookshelf, bx, y + 2, bz + 2, rotation, sbb); } /** * A chest with an extremely simple puzzle */ - private void decoratePuzzleChest(World world, Random rand, StructureBoundingBox sbb, int rotation, int y) { + private void decoratePuzzleChest(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y) { int x = this.size > 9 ? 4 : 3; int z = this.size > 9 ? 5 : 4; - // pillar frame + // pillar frameframe this.makePillarFrame(world, sbb, this.deco, rotation, x, y, z, true); - + // reinforce with towerwood - placeBlockRotated(world, deco.platformID, deco.platformMeta, x + 1, y + 1, z + 1, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 2, y + 1, z + 1, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 0, y + 1, z + 1, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 1, y + 1, z + 2, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 1, y + 1, z + 0, rotation, sbb); - - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 2, y + 3, z + 1, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 0, y + 3, z + 1, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 1, y + 3, z + 2, rotation, sbb); - placeBlockRotated(world, Blocks.air, 0, x + 1, y + 3, z + 0, rotation, sbb); - placeBlockRotated(world, deco.blockID, deco.blockMeta, x + 1, y + 3, z + 1, rotation, sbb); - placeBlockRotated(world, Blocks.sticky_piston, 5 - getStairMeta(1 + rotation), x + 1, y + 3, z - 1, rotation, sbb); - placeBlockRotated(world, deco.accentID, deco.accentMeta, x + 1, y + 3, z - 2, rotation, sbb); - placeBlockRotated(world, Blocks.lever, getLeverMeta(rotation, 5), x + 2, y + 3, z - 2, rotation, sbb); - + setBlockStateRotated(world, deco.platformState, x + 1, y + 1, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.blockState, x + 2, y + 1, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.blockState, x + 0, y + 1, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.blockState, x + 1, y + 1, z + 2, rotation, sbb); + setBlockStateRotated(world, deco.blockState, x + 1, y + 1, z + 0, rotation, sbb); + + setBlockStateRotated(world, deco.blockState, x + 2, y + 3, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.blockState, x + 0, y + 3, z + 1, rotation, sbb); + setBlockStateRotated(world, deco.blockState, x + 1, y + 3, z + 2, rotation, sbb); + setBlockStateRotated(world, AIR, x + 1, y + 3, z + 0, rotation, sbb); + setBlockStateRotated(world, deco.blockState, x + 1, y + 3, z + 1, rotation, sbb); + setBlockStateRotated(world, Blocks.STICKY_PISTON.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.NORTH), x + 1, y + 3, z - 1, rotation, sbb); + setBlockStateRotated(world, deco.accentState, x + 1, y + 3, z - 2, rotation, sbb); + setBlockStateRotated(world, getLeverState(Blocks.LEVER.getDefaultState(), BlockLever.EnumOrientation.WEST, rotation, false), x + 2, y + 3, z - 2, rotation, sbb); + placeTreasureRotated(world, x + 1, y + 2, z + 1, rotation, TFTreasure.darktower_cache, sbb); } @@ -775,55 +713,43 @@ private void decoratePuzzleChest(World world, Random rand, StructureBoundingBox /** * Make a 3x3x3 pillar frame */ - protected void makePillarFrame(World world, StructureBoundingBox sbb, StructureTFDecorator myDeco, int rotation, int x, int y, int z, boolean fenced) - { + protected void makePillarFrame(World world, StructureBoundingBox sbb, StructureTFDecorator myDeco, Rotation rotation, int x, int y, int z, boolean fenced) { makePillarFrame(world, sbb, myDeco, rotation, x, y, z, 3, 3, 3, fenced); } - + /** * Place one of the architectural features that I frequently overuse in my structures */ - protected void makePillarFrame(World world, StructureBoundingBox sbb, StructureTFDecorator myDeco, int rotation, int x, int y, int z, int width, int height, int length, boolean fenced) { + protected void makePillarFrame(World world, StructureBoundingBox sbb, StructureTFDecorator myDeco, Rotation rotation, int x, int y, int z, int width, int height, int length, boolean fenced) { // fill in posts - for (int dx = 0; dx < width; dx++) - { - for (int dz = 0; dz < length; dz++) - { - if ((dx % 3 == 0 || dx == width - 1) && (dz % 3 == 0 || dz == length - 1)) - { - for (int py = 1; py <= height; py++) - { - placeBlockRotated(world, myDeco.pillarID, myDeco.pillarMeta, x + dx, y + py, z + dz, rotation, sbb); - } - } - else - { - if (dx == 0) - { - placeBlockRotated(world, myDeco.stairID, getStairMeta(0 + rotation), x + dx, y + 1, z + dz, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(0 + rotation) + 4, x + dx, y + height, z + dz, rotation, sbb); + for (int dx = 0; dx < width; dx++) { + for (int dz = 0; dz < length; dz++) { + if ((dx % 3 == 0 || dx == width - 1) && (dz % 3 == 0 || dz == length - 1)) { + for (int py = 1; py <= height; py++) { + setBlockStateRotated(world, myDeco.pillarState, x + dx, y + py, z + dz, rotation, sbb); } - else if (dx == width - 1) - { - placeBlockRotated(world, myDeco.stairID, getStairMeta(2 + rotation), x + dx, y + 1, z + dz, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(2 + rotation) + 4, x + dx, y + height, z + dz, rotation, sbb); + } else { + if (dx == 0) { + final IBlockState southStairs = getStairState(deco.stairState, EnumFacing.WEST, rotation, false); + setBlockStateRotated(world, southStairs, x + dx, y + 1, z + dz, rotation, sbb); + setBlockStateRotated(world, southStairs.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP), x + dx, y + height, z + dz, rotation, sbb); + } else if (dx == width - 1) { + final IBlockState northStairs = getStairState(deco.stairState, EnumFacing.EAST, rotation, false); + setBlockStateRotated(world, northStairs, x + dx, y + 1, z + dz, rotation, sbb); + setBlockStateRotated(world, northStairs.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP), x + dx, y + height, z + dz, rotation, sbb); + } else if (dz == 0) { + final IBlockState westStairs = getStairState(deco.stairState, EnumFacing.NORTH, rotation, false); + setBlockStateRotated(world, westStairs, x + dx, y + 1, z + dz, rotation, sbb); + setBlockStateRotated(world, westStairs.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP), x + dx, y + height, z + dz, rotation, sbb); + } else if (dz == length - 1) { + final IBlockState eastStairs = getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false); + setBlockStateRotated(world, eastStairs, x + dx, y + 1, z + dz, rotation, sbb); + setBlockStateRotated(world, eastStairs.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP), x + dx, y + height, z + dz, rotation, sbb); } - else if (dz == 0) - { - placeBlockRotated(world, myDeco.stairID, getStairMeta(1 + rotation), x + dx, y + 1, z + dz, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(1 + rotation) + 4, x + dx, y + height, z + dz, rotation, sbb); - } - else if (dz == length - 1) - { - placeBlockRotated(world, myDeco.stairID, getStairMeta(3 + rotation), x + dx, y + 1, z + dz, rotation, sbb); - placeBlockRotated(world, myDeco.stairID, getStairMeta(3 + rotation) + 4, x + dx, y + height, z + dz, rotation, sbb); - } - - if (fenced && (dx == 0 || dx == width - 1 || dz == 0 || dz == length - 1)) - { - for (int fy = 2; fy <= height - 1; fy++) - { - placeBlockRotated(world, myDeco.fenceID, myDeco.fenceMeta, x + dx, y + fy, z + dz, rotation, sbb); + + if (fenced && (dx == 0 || dx == width - 1 || dz == 0 || dz == length - 1)) { + for (int fy = 2; fy <= height - 1; fy++) { + setBlockStateRotated(world, myDeco.fenceState, x + dx, y + fy, z + dz, rotation, sbb); } } } @@ -831,199 +757,115 @@ else if (dz == length - 1) } } - /** - * Find the treasure chest at the specified location and add the specified item to it, if it is not there already - */ - protected void putItemInTreasure(World world, int x, int y, int z, ItemStack itemToAdd, StructureBoundingBox sbb) - { - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz)) - { - TileEntity tileEntity = world.getTileEntity(dx, dy, dz); - if (tileEntity != null && tileEntity instanceof IInventory) - { - IInventory inventory = (IInventory)tileEntity; - - // check to see if the item is there, also count empty slots - boolean alreadyPresent = false; - int emptySlots = 0; - - for (int i = 0; i < inventory.getSizeInventory(); i++) - { - ItemStack inSlot = inventory.getStackInSlot(i); - - if (inSlot == null) - { - emptySlots++; - } - else - { - if (ItemStack.areItemStacksEqual(inSlot, itemToAdd)) - { - alreadyPresent = true; - break; // may as we;; - } - } - } - - // okay, add it? - if (!alreadyPresent && emptySlots > 0) - { - int slotsUntilPlaced = world.rand.nextInt(emptySlots); - for (int i = 0; i < inventory.getSizeInventory(); i++) - { - ItemStack inSlot = inventory.getStackInSlot(i); - - if (inSlot == null) - { - if (slotsUntilPlaced == 0) - { - inventory.setInventorySlotContents(i, itemToAdd); - break; - } - else - { - slotsUntilPlaced--; - } - } - - } - } - - } - } - } - - /** * Dark tower half floors */ - protected void addStairsDown(World world, StructureBoundingBox sbb, int rotation, int y, int sz, int spacing) { + protected void addStairsDown(World world, StructureBoundingBox sbb, Rotation rotation, int y, int sz, int spacing) { // stairs - for (int i = 0; i < spacing; i++) - { + for (int i = 0; i < spacing; i++) { int sx = size - 3 - i; - this.placeBlockRotated(world, deco.stairID, getStairMeta(0 + rotation), sx, y - i, sz, rotation, sbb); - this.placeBlockRotated(world, deco.accentID, deco.accentMeta, sx, y - 1 - i, sz, rotation, sbb); - this.placeBlockRotated(world, Blocks.air, 0, sx, y + 1 - i, sz, rotation, sbb); - this.placeBlockRotated(world, Blocks.air, 0, sx, y + 2 - i, sz, rotation, sbb); - this.placeBlockRotated(world, Blocks.air, 0, sx - 1, y + 2 - i, sz, rotation, sbb); - this.placeBlockRotated(world, Blocks.air, 0, sx, y + 3 - i, sz, rotation, sbb); - this.placeBlockRotated(world, Blocks.air, 0, sx - 1, y + 3 - i, sz, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), sx, y - i, sz, rotation, sbb); + this.setBlockStateRotated(world, deco.accentState, sx, y - 1 - i, sz, rotation, sbb); + this.setBlockStateRotated(world, AIR, sx, y + 1 - i, sz, rotation, sbb); + this.setBlockStateRotated(world, AIR, sx, y + 2 - i, sz, rotation, sbb); + this.setBlockStateRotated(world, AIR, sx - 1, y + 2 - i, sz, rotation, sbb); + this.setBlockStateRotated(world, AIR, sx, y + 3 - i, sz, rotation, sbb); + this.setBlockStateRotated(world, AIR, sx - 1, y + 3 - i, sz, rotation, sbb); } } - + /** * Add a bunch of timber beams */ protected void addSmallTimberBeams(World world, Random rand, StructureBoundingBox sbb, int bottom, int top) { - + int spacing = 4; - int rotation = 0; - if (bottom == 0) - { + Rotation rotation = Rotation.NONE; + if (bottom == 0) { bottom += spacing; } // fill with 3/4 floors - for (int y = bottom; y < top; y += spacing) - { - rotation += 1; - rotation %= 4; - - if (y >= top - spacing && isDeadEnd()) - { + for (int y = bottom; y < top; y += spacing) { + rotation = rotation.add(Rotation.CLOCKWISE_90); + + if (y >= top - spacing && isDeadEnd()) { makeTimberFloor(world, rand, sbb, rotation, y, spacing); - + StructureTFDecorator logDeco = new StructureDecoratorDarkTower(); - - logDeco.pillarID = TFBlocks.log; - logDeco.pillarMeta = 3; - - logDeco.platformID = TFBlocks.log; - logDeco.pillarMeta = 3; - + + logDeco.pillarState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.DARK); + logDeco.platformState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.DARK); + decorateTreasureRoom(world, sbb, rotation, y, 4, logDeco); - } - else - { + } else { makeSmallTimberBeams(world, rand, sbb, rotation, y, y == bottom && bottom != spacing, y >= (top - spacing)); } } - - + + } /** * Make a mostly soid timber floor */ - protected void makeTimberFloor(World world, Random rand, StructureBoundingBox sbb, int rotation, int y, int spacing) - { - Block beamID = TFBlocks.log; - int beamMetaBase = 3; - - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; - int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - int beamMetaUD = 0; - - for (int z = 1; z < size - 1; z++) - { - for (int x = 1; x < size - 1; x++) - { - if (x < z) - { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaNS, x, y, z, rotation, sbb); - } - else - { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaEW, x, y, z, rotation, sbb); + protected void makeTimberFloor(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y, int spacing) { + IBlockState beamID = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.DARK); + IBlockState beamStateNS = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z); + IBlockState beamStateUD = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y); + IBlockState beamStateEW = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X); + + for (int z = 1; z < size - 1; z++) { + for (int x = 1; x < size - 1; x++) { + if (x < z) { + setBlockStateRotated(world, beamStateNS, x, y, z, rotation, sbb); + } else { + setBlockStateRotated(world, beamStateEW, x, y, z, rotation, sbb); } } } - + // beams going down - for (int by = 1; by < 4; by++) - { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, 2, y - by, 2, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2 + rotation), 2 + 1, y - by, 2, rotation, sbb); - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, 6, y - by, 6, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(4 + rotation), 6 - 1, y - by, 6, rotation, sbb); + for (int by = 1; by < 4; by++) { + IBlockState ladder = Blocks.LADDER.getDefaultState(); + setBlockStateRotated(world, beamStateUD, 2, y - by, 2, rotation, sbb); + setBlockStateRotated(world, ladder.withProperty(BlockLadder.FACING, EnumFacing.WEST), 2 + 1, y - by, 2, rotation, sbb); + setBlockStateRotated(world, beamStateUD, 6, y - by, 6, rotation, sbb); + setBlockStateRotated(world, ladder.withProperty(BlockLadder.FACING, EnumFacing.EAST), 6 - 1, y - by, 6, rotation, sbb); } - + // holes for entrance - placeBlockRotated(world, Blocks.air, 0, 3, y, 2, rotation, sbb); - placeBlockRotated(world, Blocks.air, 0, 5, y, 6, rotation, sbb); + setBlockStateRotated(world, AIR, 3, y, 2, rotation, sbb); + setBlockStateRotated(world, AIR, 5, y, 6, rotation, sbb); } /** * Make a lattice of log blocks */ - protected void makeSmallTimberBeams(World world, Random rand, StructureBoundingBox sbb, int rotation, int y, boolean bottom, boolean top) - { - Block beamID = TFBlocks.log; - int beamMetaBase = 3; + protected void makeSmallTimberBeams(World world, Random rand, StructureBoundingBox sbb, Rotation rotation, int y, boolean bottom, boolean top) { + IBlockState beamID = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.DARK); + IBlockState beamStateNS = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X); + IBlockState beamStateUD = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y); + IBlockState beamStateEW = beamID.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z); - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; + /*int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - int beamMetaUD = 0; + int beamMetaUD = 0;*/ + // two beams going e/w - for (int z = 1; z < size - 1; z++) - { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaEW, 2, y, z, rotation, sbb); - placeBlockRotated(world, beamID, beamMetaBase + beamMetaEW, 6, y, z, rotation, sbb); + for (int z = 1; z < size - 1; z++) { + setBlockStateRotated(world, beamStateEW, 2, y, z, rotation, sbb); + setBlockStateRotated(world, beamStateEW, 6, y, z, rotation, sbb); } // a few random cross beams int z = pickBetweenExcluding(3, size - 3, rand, 2, 2, 6); - for (int x = 3; x < 6; x++) - { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaNS, x, y, z, rotation, sbb); + for (int x = 3; x < 6; x++) { + setBlockStateRotated(world, beamStateNS, x, y, z, rotation, sbb); } // beams going down @@ -1032,18 +874,18 @@ protected void makeSmallTimberBeams(World world, Random rand, StructureBoundingB int x3 = 6; int z3 = rand.nextBoolean() ? 2 : 6; - for (int by = 1; by < 4; by++) - { - if (!bottom || checkPost(world, x1, y - 4, z1, rotation, sbb)) - { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, x1, y - by, z1, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(2 + rotation), x1 + 1, y - by, z1, rotation, sbb); + for (int by = 1; by < 4; by++) { + final IBlockState ladder = Blocks.LADDER.getDefaultState(); + if (!bottom || checkPost(world, x1, y - 4, z1, rotation, sbb)) { + setBlockStateRotated(world, beamStateUD, x1, y - by, z1, rotation, sbb); + setBlockStateRotated(world, ladder.withProperty(BlockLadder.FACING, EnumFacing.WEST), x1 + 1, y - by, z1, rotation, sbb); } - if (!bottom || checkPost(world, x3, y - 4, z3, rotation, sbb)) - { - placeBlockRotated(world, beamID, beamMetaBase + beamMetaUD, x3, y - by, z3, rotation, sbb); - placeBlockRotated(world, Blocks.ladder, getLadderMeta(4 + rotation), x3 - 1, y - by, z3, rotation, sbb); + if (!bottom || checkPost(world, x3, y - 4, z3, rotation, sbb)) { + setBlockStateRotated(world, beamStateUD, x3, y - by, z3, rotation, sbb); + setBlockStateRotated(world, ladder.withProperty(BlockLadder.FACING, EnumFacing.EAST), x3 - 1, y - by, z3, rotation, sbb); } + + } // // do we need a beam going up? @@ -1054,16 +896,16 @@ protected void makeSmallTimberBeams(World world, Random rand, StructureBoundingB // int ladderMeta = (ladderZ == 10) ? 3 : 5; // for (int by = 1; by < 5; by++) // { -// placeBlockAtCurrentPosition(world, beamID, beamMetaBase + beamMetaUD, ladderX, y + by, 9, sbb); -// placeBlockAtCurrentPosition(world, Blocks.ladder, getLadderMeta(ladderMeta), ladderX, y + by, ladderZ, sbb); +// setBlockState(world, beamID, beamMetaBase + beamMetaUD, ladderX, y + by, 9, sbb); +// setBlockState(world, Blocks.LADDER, getLadderMeta(ladderMeta), ladderX, y + by, ladderZ, sbb); // } // // // fence thing -// placeBlockAtCurrentPosition(world, Blocks.air, 0, ladderX, y + 6, 9, sbb); -// placeBlockAtCurrentPosition(world, deco.fenceID, deco.fenceMeta, ladderX + 1, y + 5, ladderZ, sbb); -// placeBlockAtCurrentPosition(world, deco.fenceID, deco.fenceMeta, ladderX - 1, y + 5, ladderZ, sbb); -// placeBlockAtCurrentPosition(world, deco.fenceID, deco.fenceMeta, ladderX + 1, y + 6, ladderZ, sbb); -// placeBlockAtCurrentPosition(world, deco.fenceID, deco.fenceMeta, ladderX - 1, y + 6, ladderZ, sbb); +// setBlockState(world, AIR, ladderX, y + 6, 9, sbb); +// setBlockState(world, deco.fenceID, deco.fenceMeta, ladderX + 1, y + 5, ladderZ, sbb); +// setBlockState(world, deco.fenceID, deco.fenceMeta, ladderX - 1, y + 5, ladderZ, sbb); +// setBlockState(world, deco.fenceID, deco.fenceMeta, ladderX + 1, y + 6, ladderZ, sbb); +// setBlockState(world, deco.fenceID, deco.fenceMeta, ladderX - 1, y + 6, ladderZ, sbb); // } // // if (!bottom && !top) @@ -1085,25 +927,22 @@ protected void makeSmallTimberBeams(World world, Random rand, StructureBoundingB // int lx = pickFrom(rand, 2, 12, 16); // int lz = 2 + rand.nextInt(15); // -// placeBlockAtCurrentPosition(world, Blocks.redstone_lamp, 0, lx, y + 2, lz, sbb); -// placeBlockAtCurrentPosition(world, Blocks.lever, 7, lx, y + 1, lz, sbb); +// setBlockState(world, Blocks.REDSTONE_LAMP, 0, lx, y + 2, lz, sbb); +// setBlockState(world, Blocks.LEVER, 7, lx, y + 1, lz, sbb); } - /** * Utility function to pick a random number between two values, excluding three specified values */ - protected int pickBetweenExcluding(int low, int high, Random rand, int k, int l, int m) - { + protected int pickBetweenExcluding(int low, int high, Random rand, int k, int l, int m) { int result; - - do - { + + do { result = rand.nextInt(high - low) + low; } while (result == k || result == l || result == m); - + return result; } @@ -1112,106 +951,96 @@ protected int pickBetweenExcluding(int low, int high, Random rand, int k, int l, * Pick one of the three specified values at random */ protected int pickFrom(Random rand, int i, int j, int k) { - switch (rand.nextInt(3)) - { - case 0: - default: - return i; - case 1 : - return j; - case 2: - return k; + switch (rand.nextInt(3)) { + case 0: + default: + return i; + case 1: + return j; + case 2: + return k; } } - + /** * Utility function for beam maze that checks if we should build a beam all the way down -- is there a valid spot to end it? */ - protected boolean checkPost(World world, int x, int y, int z, int rotation, StructureBoundingBox sbb) - { - int worldX = this.getXWithOffsetAsIfRotated(x, z, rotation); + protected boolean checkPost(World world, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) { + int worldX = this.getXWithOffsetRotated(x, z, rotation); int worldY = this.getYWithOffset(y); - int worldZ = this.getZWithOffsetAsIfRotated(x, z, rotation); - - Block blockID = sbb.isVecInside(worldX, worldY, worldZ) ? world.getBlock(worldX, worldY, worldZ) : Blocks.air; - - return !(blockID == Blocks.air || (blockID == deco.accentID && world.getBlockMetadata(worldX, worldY, worldZ) == deco.accentMeta)); + int worldZ = this.getZWithOffsetRotated(x, z, rotation); + final BlockPos vec = new BlockPos(worldX, worldY, worldZ); + if (!sbb.isVecInside(vec)) return false; + IBlockState blockState = world.getBlockState(vec); + return blockState.getBlock() != Blocks.AIR && blockState != deco.accentState; } /** * Generate walls for the tower with the distinct pattern of blocks and accent blocks - * @param rand + * + * @param rand */ - protected void makeEncasedWalls(World world, Random rand, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) - { - - for (int x = minX; x <= maxX; x++) - { - for (int y = minY; y <= maxY; y++) - { - for (int z = minZ; z <= maxZ; z++) - { - if (x != minX && x != maxX && y != minY && y != maxY && z != minZ && z != maxZ) - { + protected void makeEncasedWalls(World world, Random rand, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + + for (int x = minX; x <= maxX; x++) { + for (int y = minY; y <= maxY; y++) { + for (int z = minZ; z <= maxZ; z++) { + if (x != minX && x != maxX && y != minY && y != maxY && z != minZ && z != maxZ) { ; - } - else - { + } else { // wall if (((x == minY || x == maxX) && ((y == minY || y == maxY) || (z == minZ || z == maxZ))) || ((y == minY || y == maxY) && ((x == minY || x == maxX) || (z == minZ || z == maxZ))) - || ((z == minZ || z == maxZ) && ((x == minY || x == maxX) || (y == minY || y == maxY)))) - { - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, x, y, z, sbb); + || ((z == minZ || z == maxZ) && ((x == minY || x == maxX) || (y == minY || y == maxY)))) { + this.setBlockState(world, deco.accentState, x, y, z, sbb); } // else if (this.isKeyTower()) // { -// this.placeBlockAtCurrentPosition(world, Blocks.diamond_block, 0, x, y, z, sbb); +// this.setBlockState(world, Blocks.DIAMOND_BLOCK, 0, x, y, z, sbb); // } - else - { + else { StructureComponent.BlockSelector blocker = deco.randomBlocks; - + blocker.selectBlocks(rand, x, y, z, true); - this.placeBlockAtCurrentPosition(world, blocker.func_151561_a(), blocker.getSelectedBlockMetaData(), x, y, z, sbb); + this.setBlockState(world, blocker.getBlockState(), x, y, z, sbb); - - //this.placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, x, y, z, sbb); + + //this.setBlockState(world, deco.blockID, deco.blockMeta, x, y, z, sbb); } } } } } - + // corners - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, minY + 1, minZ, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, minY + 1, maxZ, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, minY + 1, minZ, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, minY + 1, maxZ, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, maxY - 1, minZ, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, maxY - 1, maxZ, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, maxY - 1, minZ, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, maxY - 1, maxZ, sbb); - - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX, minY + 1, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX, minY + 1, maxZ - 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX, minY + 1, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX, minY + 1, maxZ - 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX, maxY - 1, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX, maxY - 1, maxZ - 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX, maxY - 1, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX, maxY - 1, maxZ - 1, sbb); - - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, minY, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, minY, maxZ - 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, minY, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, minY, maxZ - 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, maxY, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, minX + 1, maxY, maxZ - 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, maxY, minZ + 1, sbb); - this.placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, maxX - 1, maxY, maxZ - 1, sbb); + this.setBlockState(world, deco.accentState, minX + 1, minY + 1, minZ, sbb); + this.setBlockState(world, deco.accentState, minX + 1, minY + 1, maxZ, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, minY + 1, minZ, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, minY + 1, maxZ, sbb); + this.setBlockState(world, deco.accentState, minX + 1, maxY - 1, minZ, sbb); + this.setBlockState(world, deco.accentState, minX + 1, maxY - 1, maxZ, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, maxY - 1, minZ, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, maxY - 1, maxZ, sbb); + + this.setBlockState(world, deco.accentState, minX, minY + 1, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, minX, minY + 1, maxZ - 1, sbb); + this.setBlockState(world, deco.accentState, maxX, minY + 1, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, maxX, minY + 1, maxZ - 1, sbb); + this.setBlockState(world, deco.accentState, minX, maxY - 1, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, minX, maxY - 1, maxZ - 1, sbb); + this.setBlockState(world, deco.accentState, maxX, maxY - 1, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, maxX, maxY - 1, maxZ - 1, sbb); + + this.setBlockState(world, deco.accentState, minX + 1, minY, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, minX + 1, minY, maxZ - 1, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, minY, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, minY, maxZ - 1, sbb); + this.setBlockState(world, deco.accentState, minX + 1, maxY, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, minX + 1, maxY, maxZ - 1, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, maxY, minZ + 1, sbb); + this.setBlockState(world, deco.accentState, maxX - 1, maxY, maxZ - 1, sbb); } @@ -1220,82 +1049,76 @@ protected void makeEncasedWalls(World world, Random rand, StructureBoundingBox s * Gets a random position in the specified direction that connects to a floor currently in the tower. */ @Override - public int[] getValidOpening(Random rand, int direction) { + public int[] getValidOpening(Random rand, Rotation direction) { int verticalOffset = this.size == 19 ? 5 : 4; - + // for directions 0 or 2, the wall lies along the z axis - if (direction == 0 || direction == 2) { - int rx = direction == 0 ? size - 1 : 0; + if (direction == Rotation.NONE || direction == Rotation.CLOCKWISE_180) { + int rx = direction == Rotation.NONE ? size - 1 : 0; int rz = this.size / 2; int ry = this.height - verticalOffset; - - return new int[] {rx, ry, rz}; + + return new int[]{rx, ry, rz}; } - + // for directions 1 or 3, the wall lies along the x axis - if (direction == 1 || direction == 3) { + if (direction == Rotation.CLOCKWISE_90 || direction == Rotation.COUNTERCLOCKWISE_90) { int rx = this.size / 2; - int rz = direction == 1 ? size - 1 : 0; + int rz = direction == Rotation.CLOCKWISE_90 ? size - 1 : 0; int ry = this.height - verticalOffset; - - return new int[] {rx, ry, rz}; + + return new int[]{rx, ry, rz}; } - - - return new int[] {0, 0, 0}; + + + return new int[]{0, 0, 0}; } /** * Add an opening to the outside (or another tower) in the specified direction. */ - public void addOpening(int dx, int dy, int dz, int direction) { + @Override + public void addOpening(int dx, int dy, int dz, Rotation direction) { this.addOpening(dx, dy, dz, direction, EnumDarkTowerDoor.VANISHING); } - - + + /** * Add an opening where we keep track of the kind of opening * TODO: we could make a type of object that stores all these values * TODO: also use an Enum for the kinds of openings? */ - protected void addOpening(int dx, int dy, int dz, int direction, EnumDarkTowerDoor type) - { + protected void addOpening(int dx, int dy, int dz, Rotation direction, EnumDarkTowerDoor type) { super.addOpening(dx, dy, dz, direction); - this.openingTypes.add(openings.indexOf(new ChunkCoordinates(dx, dy, dz)), type); + this.openingTypes.add(openings.indexOf(new BlockPos(dx, dy, dz)), type); } /** * Iterate through the openings on our list and add them to the tower */ @Override - protected void makeOpenings(World world, StructureBoundingBox sbb) - { - for (int i = 0; i < openings.size(); i++) - { - ChunkCoordinates doorCoords = openings.get(i); - + protected void makeOpenings(World world, StructureBoundingBox sbb) { + for (int i = 0; i < openings.size(); i++) { + BlockPos doorCoords = openings.get(i); + EnumDarkTowerDoor doorType; - if (openingTypes.size() > i) - { + if (openingTypes.size() > i) { doorType = openingTypes.get(i); - } - else - { + } else { doorType = EnumDarkTowerDoor.VANISHING; } - - switch (doorType) - { - case VANISHING : - default: - makeDoorOpening(world, doorCoords.posX, doorCoords.posY, doorCoords.posZ, sbb); - break; - case REAPPEARING : - makeReappearingDoorOpening(world, doorCoords.posX, doorCoords.posY, doorCoords.posZ, sbb); - break; - case LOCKED : - makeLockedDoorOpening(world, doorCoords.posX, doorCoords.posY, doorCoords.posZ, sbb); - break; + + switch (doorType) { + case VANISHING: + default: + makeDoorOpening(world, doorCoords.getX(), doorCoords.getY(), doorCoords.getZ(), sbb); + break; + case REAPPEARING: + makeReappearingDoorOpening(world, doorCoords.getX(), doorCoords.getY(), doorCoords.getZ(), sbb); + break; + case LOCKED: + makeLockedDoorOpening(world, doorCoords.getX(), doorCoords.getY(), doorCoords.getZ(), sbb); + break; } } @@ -1306,40 +1129,39 @@ protected void makeOpenings(World world, StructureBoundingBox sbb) */ @Override protected void makeDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { - // nullify sky light - nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); - - // clear the door - if (dx == 0 || dx == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 3, dz + 2, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 2, dz + 1, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_INACTIVE, Blocks.air, 0, false); + // nullify sky light + nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); + + final IBlockState inactiveVanish = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.VANISH_INACTIVE); + + // clear the door + if (dx == 0 || dx == size - 1) { + this.fillWithBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 3, dz + 2, deco.accentState, AIR, false); + this.fillWithBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 2, dz + 1, inactiveVanish, AIR, false); } - if (dz == 0 || dz == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 3, dz, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 2, dz, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_INACTIVE, Blocks.air, 0, false); + if (dz == 0 || dz == size - 1) { + this.fillWithBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 3, dz, deco.accentState, AIR, false); + this.fillWithBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 2, dz, inactiveVanish, AIR, false); } } /** * Make a 3x3 tower door that reappears */ - protected void makeReappearingDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) - { - // nullify sky light - nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); - - // clear the door - if (dx == 0 || dx == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 3, dz + 2, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 2, dz + 1, TFBlocks.towerDevice, BlockTFTowerDevice.META_REAPPEARING_INACTIVE, Blocks.air, 0, false); + protected void makeReappearingDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { + // nullify sky light + nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); + + final IBlockState inactiveReappearing = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.REAPPEARING_INACTIVE); + + // clear the door + if (dx == 0 || dx == size - 1) { + this.fillWithBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 3, dz + 2, deco.accentState, AIR, false); + this.fillWithBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 2, dz + 1, inactiveReappearing, AIR, false); } - if (dz == 0 || dz == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 3, dz, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 2, dz, TFBlocks.towerDevice, BlockTFTowerDevice.META_REAPPEARING_INACTIVE, Blocks.air, 0, false); + if (dz == 0 || dz == size - 1) { + this.fillWithBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 3, dz, deco.accentState, AIR, false); + this.fillWithBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 2, dz, inactiveReappearing, AIR, false); } } @@ -1347,146 +1169,59 @@ protected void makeReappearingDoorOpening(World world, int dx, int dy, int dz, S /** * Make a 3x3 tower door that is locked */ - protected void makeLockedDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) - { - // nullify sky light - nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); - - // clear the door - if (dx == 0 || dx == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 3, dz + 2, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 2, dz + 1, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_INACTIVE, Blocks.air, 0, false); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx, dy + 0, dz + 1, sbb); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx, dy + 0, dz - 1, sbb); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx, dy + 2, dz + 1, sbb); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx, dy + 2, dz - 1, sbb); + protected void makeLockedDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { + // nullify sky light + nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); + + // clear the door + final IBlockState lockedVanish = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.VANISH_LOCKED); + final IBlockState inactiveVanish = TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.VANISH_INACTIVE); + + if (dx == 0 || dx == size - 1) { + this.fillWithBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 3, dz + 2, deco.accentState, AIR, false); + this.fillWithBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 2, dz + 1, inactiveVanish, AIR, false); + this.setBlockState(world, lockedVanish, dx, dy + 0, dz + 1, sbb); + this.setBlockState(world, lockedVanish, dx, dy + 0, dz - 1, sbb); + this.setBlockState(world, lockedVanish, dx, dy + 2, dz + 1, sbb); + this.setBlockState(world, lockedVanish, dx, dy + 2, dz - 1, sbb); } - if (dz == 0 || dz == size - 1) - { - this.fillWithMetadataBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 3, dz, deco.accentID, deco.accentMeta, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 2, dz, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_INACTIVE, Blocks.air, 0, false); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx + 1, dy + 0, dz, sbb); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx - 1, dy + 0, dz, sbb); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx + 1, dy + 2, dz, sbb); - this.placeBlockAtCurrentPosition(world, TFBlocks.towerDevice, BlockTFTowerDevice.META_VANISH_LOCKED, dx - 1, dy + 2, dz, sbb); + if (dz == 0 || dz == size - 1) { + this.fillWithBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 3, dz, deco.accentState, AIR, false); + this.fillWithBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 2, dz, inactiveVanish, AIR, false); + this.setBlockState(world, lockedVanish, dx + 1, dy + 0, dz, sbb); + this.setBlockState(world, lockedVanish, dx - 1, dy + 0, dz, sbb); + this.setBlockState(world, lockedVanish, dx + 1, dy + 2, dz, sbb); + this.setBlockState(world, lockedVanish, dx - 1, dy + 2, dz, sbb); } } - - + + /** * Returns true if this tower has only one exit. - * + *

* TODO: is this really the best way? */ - public boolean isDeadEnd() - { + @Override + public boolean isDeadEnd() { // we have to modify this to ignore door type 2 since that leads to balconies int nonBalconies = 0; - - for (EnumDarkTowerDoor type : openingTypes) - { - if (type != EnumDarkTowerDoor.REAPPEARING) - { + + for (EnumDarkTowerDoor type : openingTypes) { + if (type != EnumDarkTowerDoor.REAPPEARING) { nonBalconies++; } } - + return nonBalconies <= 1; } - public boolean isKeyTower() - { + public boolean isKeyTower() { return keyTower; } - public void setKeyTower(boolean keyTower) - { + public void setKeyTower(boolean keyTower) { this.keyTower = keyTower; } - - /** - * WHY ARE LEVERS SO DUMMM? - */ - protected int getLeverMeta(int rotation, int direction) - { - if (direction == 0) - { - return 0; - } - if (direction == 1) - { - return 5; - } - - rotation += this.getCoordBaseMode(); - rotation %= 4; - - if (rotation == 0) - { - switch (direction) - { - case 2: - return 4; - case 3: - return 3; - case 4: - return 2; - case 5: - return 1; - } - } - else if (rotation == 1) - { - switch (direction) - { - case 2: - return 1; - case 3: - return 2; - case 4: - return 4; - case 5: - return 3; - } - } - else if (rotation == 2) - { - switch (direction) - { - case 2: - return 3; - case 3: - return 4; - case 4: - return 1; - case 5: - return 2; - } - } - else if (rotation == 3) - { - switch (direction) - { - case 2: - return 2; - case 3: - return 1; - case 4: - return 3; - case 5: - return 4; - } - } - - return -1; // NOOO - } - - - - - - } diff --git a/src/main/java/twilightforest/structures/darktower/EnumDarkTowerDoor.java b/src/main/java/twilightforest/structures/darktower/EnumDarkTowerDoor.java index e473e11318..fc8aac8f58 100644 --- a/src/main/java/twilightforest/structures/darktower/EnumDarkTowerDoor.java +++ b/src/main/java/twilightforest/structures/darktower/EnumDarkTowerDoor.java @@ -1,7 +1,6 @@ package twilightforest.structures.darktower; -public enum EnumDarkTowerDoor -{ +public enum EnumDarkTowerDoor { VANISHING, REAPPEARING, LOCKED diff --git a/src/main/java/twilightforest/structures/darktower/StructureDecoratorDarkTower.java b/src/main/java/twilightforest/structures/darktower/StructureDecoratorDarkTower.java index b311459c1d..6e231d2d91 100644 --- a/src/main/java/twilightforest/structures/darktower/StructureDecoratorDarkTower.java +++ b/src/main/java/twilightforest/structures/darktower/StructureDecoratorDarkTower.java @@ -1,30 +1,20 @@ package twilightforest.structures.darktower; import net.minecraft.init.Blocks; +import twilightforest.block.BlockTFTowerWood; import twilightforest.block.TFBlocks; +import twilightforest.enums.TowerWoodVariant; import twilightforest.structures.StructureTFDecorator; -public class StructureDecoratorDarkTower extends StructureTFDecorator -{ - - public StructureDecoratorDarkTower() - { - this.blockID = TFBlocks.towerWood; - this.blockMeta = 0; - - this.accentID = TFBlocks.towerWood; - this.accentMeta = 1; - - this.fenceID = Blocks.fence; - - this.stairID = Blocks.spruce_stairs; - - this.pillarID = TFBlocks.towerWood; - this.pillarMeta = 1; - - this.platformID = TFBlocks.towerWood;; - this.platformMeta = 1; +public class StructureDecoratorDarkTower extends StructureTFDecorator { + public StructureDecoratorDarkTower() { + this.blockState = TFBlocks.tower_wood.getDefaultState(); + this.accentState = TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.ENCASED); + this.fenceState = Blocks.OAK_FENCE.getDefaultState(); + this.stairState = Blocks.SPRUCE_STAIRS.getDefaultState(); + this.pillarState = TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.ENCASED); + this.platformState = TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.ENCASED); this.randomBlocks = new StructureTFTowerWoods(); } diff --git a/src/main/java/twilightforest/structures/darktower/StructureTFTowerWoods.java b/src/main/java/twilightforest/structures/darktower/StructureTFTowerWoods.java index f3df540905..fa78ffeb90 100644 --- a/src/main/java/twilightforest/structures/darktower/StructureTFTowerWoods.java +++ b/src/main/java/twilightforest/structures/darktower/StructureTFTowerWoods.java @@ -1,42 +1,32 @@ package twilightforest.structures.darktower; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.block.BlockTFTowerWood; import twilightforest.block.TFBlocks; +import twilightforest.enums.TowerWoodVariant; + +import java.util.Random; public class StructureTFTowerWoods extends StructureComponent.BlockSelector { @Override - public void selectBlocks(Random par1Random, int x, int y, int z, boolean isWall) { - if (!isWall) - { - this.field_151562_a = Blocks.air; - this.selectedBlockMetaData = 0; - } - else - { - this.field_151562_a = TFBlocks.towerWood; - float randFloat = par1Random.nextFloat(); + public void selectBlocks(Random random, int x, int y, int z, boolean isWall) { + if (!isWall) { + this.blockstate = Blocks.AIR.getDefaultState(); + } else { + float randFloat = random.nextFloat(); - if (randFloat < 0.1F) - { - this.selectedBlockMetaData = 2; - } - else if (randFloat < 0.2F) - { - this.selectedBlockMetaData = 3; - } - else if (randFloat < 0.225F) - { - this.selectedBlockMetaData = 4; - } - else - { - this.selectedBlockMetaData = 0; - } - } + if (randFloat < 0.1F) { + this.blockstate = TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.CRACKED); + } else if (randFloat < 0.2F) { + this.blockstate = TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.MOSSY); + } else if (randFloat < 0.225F) { + this.blockstate = TFBlocks.tower_wood.getDefaultState().withProperty(BlockTFTowerWood.VARIANT, TowerWoodVariant.INFESTED); + } else { + this.blockstate = TFBlocks.tower_wood.getDefaultState(); + } + } } } diff --git a/src/main/java/twilightforest/structures/darktower/TFDarkTowerPieces.java b/src/main/java/twilightforest/structures/darktower/TFDarkTowerPieces.java index a7d6c45519..2470adaef3 100644 --- a/src/main/java/twilightforest/structures/darktower/TFDarkTowerPieces.java +++ b/src/main/java/twilightforest/structures/darktower/TFDarkTowerPieces.java @@ -1,28 +1,30 @@ package twilightforest.structures.darktower; import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartDarkTower; public class TFDarkTowerPieces { - public static void registerPieces() - { - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerBalcony.class, "TFDTBal"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerBeard.class, "TFDTBea"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerBossBridge.class, "TFDTBB"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerBossTrap.class, "TFDTBT"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerBridge.class, "TFDTBri"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerEntrance.class, "TFDTEnt"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerEntranceBridge.class, "TFDTEB"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerMain.class, "TFDTMai"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerMainBridge.class, "TFDTMB"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerRoof.class, "TFDTRooS"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerRoofAntenna.class, "TFDTRA"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerRoofCactus.class, "TFDTRC"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerRoofFourPost.class, "TFDTRFP"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerRoofRings.class, "TFDTRR"); - MapGenStructureIO.func_143031_a(ComponentTFDarkTowerWing.class, "TFDTWin"); + public static void registerPieces() { + MapGenStructureIO.registerStructure(StructureStartDarkTower.class, "TFDT"); + + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerBalcony.class, "TFDTBal"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerBeard.class, "TFDTBea"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerBossBridge.class, "TFDTBB"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerBossTrap.class, "TFDTBT"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerBridge.class, "TFDTBri"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerEntrance.class, "TFDTEnt"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerEntranceBridge.class, "TFDTEB"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerMain.class, "TFDTMai"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerMainBridge.class, "TFDTMB"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerRoof.class, "TFDTRooS"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerRoofAntenna.class, "TFDTRA"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerRoofCactus.class, "TFDTRC"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerRoofFourPost.class, "TFDTRFP"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerRoofRings.class, "TFDTRR"); + MapGenStructureIO.registerStructureComponent(ComponentTFDarkTowerWing.class, "TFDTWin"); + + } - } - } \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBellFoundation21.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBellFoundation21.java new file mode 100644 index 0000000000..6e4ded0628 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBellFoundation21.java @@ -0,0 +1,56 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.Random; + +/** + * A larger foundation that comes all the way from the top of a tower + * + * @author benma_000 + */ +public class ComponentTFFinalCastleBellFoundation21 extends ComponentTFFinalCastleFoundation13 { + + public ComponentTFFinalCastleBellFoundation21() {} + + public ComponentTFFinalCastleBellFoundation21(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, rand, i, sideTower); + + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY, sideTower.getBoundingBox().maxZ + 2); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + + int mid = 16; + int low = 32; + + // assume square + int size = this.boundingBox.maxX - this.boundingBox.minX; + + for (Rotation rotation : RotationUtil.ROTATIONS) { + // do corner + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 2, -1, 1, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 2, -mid, 0, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 1, -1, 2, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 0, -mid, 2, rotation, sbb); + + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 1, -low, 1, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 0, -low, 1, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 1, -low, 0, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 0, -low, 0, rotation, sbb); + + for (int x = 6; x < (size - 3); x += 4) { + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, x, -1, 1, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, x, -mid, 0, rotation, sbb); + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBellTower21.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBellTower21.java new file mode 100644 index 0000000000..a4ffa24f20 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBellTower21.java @@ -0,0 +1,91 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.BlockTFForceField; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleBellTower21 extends ComponentTFFinalCastleMazeTower13 { + + private static final int FLOORS = 8; + + public ComponentTFFinalCastleBellTower21() { + } + + public ComponentTFFinalCastleBellTower21(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction) { + super(feature, rand, i, x, y, z, FLOORS, 1, BlockTFCastleMagic.VALID_COLORS.get(1), direction); + this.size = 21; + int floors = FLOORS; + this.height = floors * 8 + 1; + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox2(x, y, z, -6, -8, -this.size / 2, this.size - 1, this.height, this.size - 1, direction); + this.openings.clear(); + addOpening(0, 9, size / 2, Rotation.CLOCKWISE_180); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + // add foundation + ComponentTFFinalCastleBellFoundation21 foundation = new ComponentTFFinalCastleBellFoundation21(getFeatureType(), rand, 4, this); + list.add(foundation); + foundation.buildComponent(this, list, rand); + + // add roof + StructureTFComponentOld roof = new ComponentTFFinalCastleRoof13Crenellated(getFeatureType(), rand, 4, this); + list.add(roof); + roof.buildComponent(this, list, rand); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + super.addComponentParts(world, rand, sbb); + + // openings! + IBlockState fieldBlock = TFBlocks.force_field + .getDefaultState() + .withProperty(BlockTFForceField.COLOR, BlockTFForceField.VALID_COLORS.get(4)); + for (Rotation rotation : RotationUtil.ROTATIONS) { + int y = 48; + for (int x = 5; x < this.size - 4; x += 2) { +// for (int wy = 0; wy < 15; wy++) { +// fieldMeta = rand.nextInt(4) + 1; +// this.setBlockStateRotated(world, fieldBlock, fieldMeta, x, y + wy, 0, rotation, sbb); +// } +// fieldMeta = rand.nextInt(5); + this.fillBlocksRotated(world, sbb, x, y, 0, x, y + 14, 0, fieldBlock, rotation); + } + y = 24; + for (int x = 1; x < this.size - 1; x += 8) { +// for (int wy = 0; wy < 15; wy++) { +// fieldMeta = rand.nextInt(4) + 1; +// this.setBlockStateRotated(world, fieldBlock, fieldMeta, x, y + wy, 0, rotation, sbb); +// fieldMeta = rand.nextInt(4) + 1; +// this.setBlockStateRotated(world, fieldBlock, fieldMeta, x + 2, y + wy, 0, rotation, sbb); +// } +// fieldMeta = rand.nextInt(5); + this.fillBlocksRotated(world, sbb, x, y, 0, x, y + 14, 0, fieldBlock, rotation); +// fieldMeta = rand.nextInt(5); + this.fillBlocksRotated(world, sbb, x + 2, y, 0, x + 2, y + 14, 0, fieldBlock, rotation); + } + } + + // sign + this.placeSignAtCurrentPosition(world, 7, 9, 8, "Parkour area 2", "mini-boss 1", sbb); + + return true; + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBossGazebo.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBossGazebo.java new file mode 100644 index 0000000000..caebe55ffd --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBossGazebo.java @@ -0,0 +1,67 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.BlockTFForceField; +import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleBossGazebo extends StructureTFComponentOld { + + @SuppressWarnings("unused") + public ComponentTFFinalCastleBossGazebo() { + } + + public ComponentTFFinalCastleBossGazebo(TFFeature feature, Random rand, int i, StructureTFComponentOld keep) { + super(feature, i); + this.spawnListIndex = -1; // no monsters + + this.setCoordBaseMode(keep.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(keep.getBoundingBox().minX + 14, keep.getBoundingBox().maxY + 2, keep.getBoundingBox().minZ + 14, keep.getBoundingBox().maxX - 14, keep.getBoundingBox().maxY + 13, keep.getBoundingBox().maxZ - 14); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + this.deco = new StructureTFDecoratorCastle(); + this.deco.blockState = TFBlocks.castle_rune_brick.getDefaultState().withProperty(BlockTFCastleMagic.COLOR, EnumDyeColor.BLUE); + + this.deco.fenceState = TFBlocks.force_field.getDefaultState().withProperty(BlockTFForceField.COLOR, EnumDyeColor.PURPLE); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // walls + for (Rotation rotation : RotationUtil.ROTATIONS) { + this.fillBlocksRotated(world, sbb, 0, 0, 0, 0, 10, 20, deco.fenceState, rotation); + } + + // roof + this.fillWithBlocks(world, sbb, 0, 11, 0, 20, 11, 20, deco.fenceState, deco.fenceState, false); + + //this.placeSignAtCurrentPosition(world, 10, 0, 10, sbb, "Final Boss Here", "You win!", "discord.gg/6v3z26B"); + + setInvisibleTextEntity(world, 10, 0, 10, sbb, "Final Boss Here", true, 2.3f); + setInvisibleTextEntity(world, 10, 0, 10, sbb, "You win!", true, 2.0f); + setInvisibleTextEntity(world, 10, 0, 10, sbb, "You can join the Twilight Forest Discord server to follow",true, 1.0f); + setInvisibleTextEntity(world, 10, 0, 10, sbb, "the latest updates on this castle and other content at:",true, 0.7f); + setInvisibleTextEntity(world, 10, 0, 10, sbb, "discord.experiment115.com", true, 0.4f); + + setBlockState(world, TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.FINAL_BOSS), 10, 1, 10, sbb); + + return true; + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBridge.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBridge.java new file mode 100644 index 0000000000..7742a3ac2c --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleBridge.java @@ -0,0 +1,76 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleBridge extends StructureTFComponentOld { + public ComponentTFFinalCastleBridge() { + } + + public ComponentTFFinalCastleBridge(TFFeature feature, int i, int x, int y, int z, int length, EnumFacing direction) { + super(feature, i); + this.setCoordBaseMode(direction); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox2(x, y, z, 0, -1, -3, length - 1, 5, 6, direction); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + int length = (this.coordBaseMode == EnumFacing.SOUTH || this.coordBaseMode == EnumFacing.NORTH) ? this.boundingBox.maxX - this.boundingBox.minX : this.boundingBox.maxZ - this.boundingBox.minZ; + + // span + fillWithRandomizedBlocks(world, sbb, 0, 0, 0, length, 1, 6, false, rand, deco.randomBlocks); + // rails + //fillWithRandomizedBlocks(world, sbb, 0, 1, 0, length, 2, 0, false, rand, deco.randomBlocks); + //fillWithRandomizedBlocks(world, sbb, 0, 1, 6, length, 2, 6, false, rand, deco.randomBlocks); + IBlockState castlePillar = TFBlocks.castle_pillar.getDefaultState().withProperty(BlockLog.LOG_AXIS, (this.rotation == Rotation.NONE || this.rotation == Rotation.CLOCKWISE_180) ? BlockLog.EnumAxis.X : BlockLog.EnumAxis.Z); + + fillWithBlocks(world, sbb, 0, 2, 0, length, 2, 0, castlePillar, castlePillar, false); + fillWithBlocks(world, sbb, 0, 2, 6, length, 2, 6, castlePillar, castlePillar, false); + + + + // supports + int l3 = length / 3; + for (int i = 0; i < l3; i++) { + int sl = l3 - (int) (MathHelper.cos((float) (l3 - i) / (float) l3 * 1.6F) * (float) l3); // this could be better, maybe? + fillWithRandomizedBlocks(world, sbb, i, -sl, 0, i, 0, 0, false, rand, deco.randomBlocks); + fillWithRandomizedBlocks(world, sbb, i, -sl, 6, i, 0, 6, false, rand, deco.randomBlocks); + fillWithRandomizedBlocks(world, sbb, length - i, -sl, 0, length - i, 0, 0, false, rand, deco.randomBlocks); + fillWithRandomizedBlocks(world, sbb, length - i, -sl, 6, length - i, 0, 6, false, rand, deco.randomBlocks); + } + + // doorframes + this.fillWithBlocks(world, sbb, 0, 2, 1, 0, 7, 1, deco.pillarState, deco.pillarState, false); + this.fillWithBlocks(world, sbb, 0, 2, 5, 0, 7, 5, deco.pillarState, deco.pillarState, false); + this.fillWithBlocks(world, sbb, 0, 6, 2, 0, 6, 4, deco.accentState, deco.accentState, false); + this.setBlockState(world, deco.pillarState, 0, 7, 3, sbb); + + this.fillWithBlocks(world, sbb, length, 2, 1, length, 7, 1, deco.pillarState, deco.pillarState, false); + this.fillWithBlocks(world, sbb, length, 2, 5, length, 7, 5, deco.pillarState, deco.pillarState, false); + this.fillWithBlocks(world, sbb, length, 6, 2, length, 6, 4, deco.accentState, deco.accentState, false); + this.setBlockState(world, deco.pillarState, length, 7, 3, sbb); + + return true; + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDamagedTower.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDamagedTower.java new file mode 100644 index 0000000000..12695a2f16 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDamagedTower.java @@ -0,0 +1,126 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleDamagedTower extends ComponentTFFinalCastleMazeTower13 { + public ComponentTFFinalCastleDamagedTower() { + } + + public ComponentTFFinalCastleDamagedTower(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction) { + super(feature, rand, i, x, y, z, BlockTFCastleMagic.VALID_COLORS.get(2), direction); //TODO: change rune color + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + // add foundation + ComponentTFFinalCastleFoundation13 foundation = new ComponentTFFinalCastleFoundation13(getFeatureType(), rand, 0, this); + list.add(foundation); + foundation.buildComponent(this, list, rand); + + // add thorns + ComponentTFFinalCastleFoundation13 thorns = new ComponentTFFinalCastleFoundation13Thorns(getFeatureType(), rand, 0, this); + list.add(thorns); + thorns.buildComponent(this, list, rand); + +// // add roof +// StructureTFComponentOld roof = rand.nextBoolean() ? new Roof13Conical(rand, 4, this) : new Roof13Crenellated(rand, 4, this); +// list.add(roof); +// roof.buildComponent(this, list, rand); + + + // keep on building? + this.buildNonCriticalTowers(parent, list, rand); + } + + + @Override + protected ComponentTFFinalCastleMazeTower13 makeNewDamagedTower(Random rand, EnumFacing facing, BlockPos tc) { + return new ComponentTFFinalCastleWreckedTower(getFeatureType(), rand, this.getComponentType() + 1, tc.getX(), tc.getY(), tc.getZ(), facing); + } + + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + super.addComponentParts(world, rand, sbb); + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + this.destroyTower(world, decoRNG, sbb); + + return true; + } + + public void destroyTower(World world, Random rand, StructureBoundingBox sbb) { + + // make list of destroyed areas + ArrayList areas = makeInitialDestroyList(rand); + + boolean hitDeadRock = false; + + // go down from the top of the tower to the ground, taking out rectangular chunks + //for (int y = this.boundingBox.maxY; y > this.boundingBox.minY; y--) { + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + for (int y = this.boundingBox.maxY; !hitDeadRock && y > 64; y--) { + for (int x = this.boundingBox.minX - 2; x <= this.boundingBox.maxX + 2; x++) { + for (int z = this.boundingBox.minZ - 2; z <= this.boundingBox.maxZ + 2; z++) { + pos.setPos(x, y, z); + if (sbb.isVecInside(pos)) { + if (world.getBlockState(pos).getBlock() == TFBlocks.deadrock) { + hitDeadRock = true; + } + determineBlockDestroyed(world, areas, y, x, z); + } + } + } + + // check to see if any of our DestroyAreas are entirely above the current y value + DestroyArea removeArea = null; + + for (DestroyArea dArea : areas) { + if (dArea == null || dArea.isEntirelyAbove(y)) { + removeArea = dArea; + } + } + // if so, replace them with new ones + if (removeArea != null) { + areas.remove(removeArea); + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, y, areas)); + + } + } + } + + protected ArrayList makeInitialDestroyList(Random rand) { + ArrayList areas = new ArrayList(2); + + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); + return areas; + } + + protected void determineBlockDestroyed(World world, ArrayList areas, int y, int x, int z) { + BlockPos pos = new BlockPos(x, y, z); + for (DestroyArea dArea : areas) { + if (dArea != null && dArea.isVecInside(pos)) { + world.setBlockToAir(pos); + } + } + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonEntrance.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonEntrance.java new file mode 100644 index 0000000000..52e2d9f5e5 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonEntrance.java @@ -0,0 +1,81 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.BlockStairs; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleDoor; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.BlockTFForceField; +import twilightforest.block.TFBlocks; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleDungeonEntrance extends ComponentTFFinalCastleDungeonRoom31 { + + public boolean hasExit = false; + + public ComponentTFFinalCastleDungeonEntrance() {} + + public ComponentTFFinalCastleDungeonEntrance(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction, int level) { + super(feature, rand, i, x, y, z, direction, level); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + this.deco = new StructureTFDecoratorCastle(); + this.deco.blockState = TFBlocks.castle_rune_brick + .getDefaultState() + .withProperty(BlockTFCastleMagic.COLOR, BlockTFCastleMagic.VALID_COLORS.get(2)); + + this.deco.fenceState = TFBlocks.force_field + .getDefaultState() + .withProperty(BlockTFForceField.COLOR, BlockTFForceField.VALID_COLORS.get(1)); + + // this is going to be the parent for all rooms on this level + super.buildComponent(this, list, rand); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + + if (!super.addComponentParts(world, rand, sbb)) { + return false; + } + + final IBlockState stairs = deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.SOUTH); + final IBlockState deadRock = TFBlocks.deadrock.getDefaultState(); + // stairs + for (int y = 0; y <= this.height; y++) { + int x = (this.size / 2) - 2; + int z = (this.size / 2) - y + 2; + + this.fillWithBlocks(world, sbb, x, 0, z, x + 4, y - 1, z, deadRock, deadRock, false); + this.fillWithBlocks(world, sbb, x, y, z, x + 4, y, z, stairs, stairs, false); + this.fillWithAir(world, sbb, x, y + 1, z, x + 4, y + 6, z); + } + + // door + final IBlockState castleDoor = TFBlocks.castle_door.getDefaultState() + .withProperty(BlockTFCastleDoor.LOCK_INDEX, 2); + this.fillWithBlocks(world, sbb, 23, 0, 12, 23, 3, 14, castleDoor, AIR, false); + this.fillWithBlocks(world, sbb, 23, 4, 12, 23, 4, 14, deco.blockState, deco.blockState, false); + + return true; + } + + @Override + protected EnumDyeColor getForceFieldColor(Random decoRNG) { + return BlockTFForceField.VALID_COLORS.get(1); + } + + @Override + protected EnumDyeColor getRuneColor(EnumDyeColor fieldColor) { + return BlockTFCastleMagic.VALID_COLORS.get(0); + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonExit.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonExit.java new file mode 100644 index 0000000000..9a9f80b2c9 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonExit.java @@ -0,0 +1,95 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleDoor; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.BlockTFForceField; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.StructureBoundingBoxUtils; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleDungeonExit extends ComponentTFFinalCastleDungeonRoom31 { + + public ComponentTFFinalCastleDungeonExit() {} + + public ComponentTFFinalCastleDungeonExit(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction, int level) { + super(feature, rand, i, x, y, z, direction, level); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + // no need for additional rooms, we're along the outside anyways + + // add stairway down + Rotation bestDir = this.findStairDirectionTowards(parent.getBoundingBox().minX, parent.getBoundingBox().minZ); + + ComponentTFFinalCastleDungeonSteps steps0 = new ComponentTFFinalCastleDungeonSteps(rand, 5, boundingBox.minX + 15, boundingBox.minY, boundingBox.minZ + 15, bestDir.rotate(EnumFacing.SOUTH)); + list.add(steps0); + steps0.buildComponent(this, list, rand); + + // another level!? + if (this.level == 1) { + steps0.buildLevelUnder(parent, list, rand, this.level + 1); + } else { + steps0.buildBossRoomUnder(parent, list, rand); + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + + if (!super.addComponentParts(world, rand, sbb)) { + return false; + } + + // door + final IBlockState castleDoor = TFBlocks.castle_door.getDefaultState() + .withProperty(BlockTFCastleDoor.LOCK_INDEX, 2); + + this.fillWithBlocks(world, sbb, 7, 0, 16, 7, 3, 18, castleDoor, AIR, false); + this.fillWithBlocks(world, sbb, 7, 4, 16, 7, 4, 18, deco.blockState, deco.blockState, false); + + return true; + } + + public Rotation findStairDirectionTowards(int x, int z) { + Vec3i center = StructureBoundingBoxUtils.getCenter(this.boundingBox); + // difference + int dx = center.getX() - x; + int dz = center.getZ() - z; + + Rotation absoluteDir; + if (Math.abs(dz) >= Math.abs(dx)) { + absoluteDir = (dz >= 0) ? Rotation.CLOCKWISE_180 : Rotation.NONE; + } else { + absoluteDir = (dx >= 0) ? Rotation.COUNTERCLOCKWISE_90 : Rotation.CLOCKWISE_90; + } + + return absoluteDir; + } + + @Override + protected EnumDyeColor getForceFieldColor(Random decoRNG) { + return BlockTFForceField.VALID_COLORS.get(1); + } + + @Override + protected EnumDyeColor getRuneColor(EnumDyeColor fieldColor) { + return BlockTFCastleMagic.VALID_COLORS.get(0); + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonForgeRoom.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonForgeRoom.java new file mode 100644 index 0000000000..69cf49e80f --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonForgeRoom.java @@ -0,0 +1,33 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.Random; + +public class ComponentTFFinalCastleDungeonForgeRoom extends StructureTFComponentOld { + public ComponentTFFinalCastleDungeonForgeRoom() { + } + + public ComponentTFFinalCastleDungeonForgeRoom(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction) { + super(feature, i); + this.spawnListIndex = 3; // forge monsters + this.setCoordBaseMode(direction); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox2(x, y, z, -15, 0, -15, 50, 30, 50, direction); + } + + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + this.fillWithAir(world, sbb, 0, 0, 0, 50, 30, 50); + + // sign + this.placeSignAtCurrentPosition(world, 25, 0, 25, "Mini-boss 2", "Gives talisman", sbb); + + return true; + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonRoom31.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonRoom31.java new file mode 100644 index 0000000000..a68d804246 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonRoom31.java @@ -0,0 +1,205 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.biomes.TFBiomes; +import twilightforest.block.BlockTFCastleBlock; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.BlockTFForceField; +import twilightforest.block.TFBlocks; +import twilightforest.enums.CastleBrickVariant; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.structures.lichtower.ComponentTFTowerWing; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; + +public class ComponentTFFinalCastleDungeonRoom31 extends ComponentTFTowerWing { + + public int level; // this is not serialized, since it's only used during build, which should be all one step + + public ComponentTFFinalCastleDungeonRoom31() {} + + public ComponentTFFinalCastleDungeonRoom31(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction, int level) { + super(feature, i); + this.setCoordBaseMode(direction); + this.spawnListIndex = 2; // dungeon monsters + this.size = 31; + this.height = 7; + this.level = level; + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -15, 0, -15, this.size - 1, this.height - 1, this.size - 1, EnumFacing.SOUTH); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + int mySpread = this.getComponentType() - parent.getComponentType(); + int maxSpread = (this.level == 1) ? 2 : 3; + + // add exit if we're far enough away and don't have one + if (mySpread == maxSpread && !isExitBuildForLevel(parent)) { + Rotation direction = RotationUtil.getRandomRotation(rand); + for (int i = 0; i < 8 && !isExitBuildForLevel(parent); i++) { + direction = direction.add(RotationUtil.ROTATIONS[i & 3]); + if (this.addDungeonExit(parent, list, rand, direction)) { + this.setExitBuiltForLevel(parent, true); + } + } + } + + // add other rooms + if (mySpread < maxSpread) { + Rotation direction = RotationUtil.getRandomRotation(rand); + for (int i = 0; i < 12; i++) { + direction = direction.add(RotationUtil.ROTATIONS[i & 3]); + this.addDungeonRoom(parent, list, rand, direction, this.level); + } + } + } + + private boolean isExitBuildForLevel(StructureComponent parent) { + if (parent instanceof ComponentTFFinalCastleDungeonEntrance) { + return ((ComponentTFFinalCastleDungeonEntrance) parent).hasExit; + } + return false; + } + + private void setExitBuiltForLevel(StructureComponent parent, boolean exit) { + if (parent instanceof ComponentTFFinalCastleDungeonEntrance) { + ((ComponentTFFinalCastleDungeonEntrance) parent).hasExit = exit; + } + } + + protected boolean addDungeonRoom(StructureComponent parent, List list, Random rand, Rotation rotation, int level) { + rotation = rotation.add(this.rotation); + + BlockPos rc = this.getNewRoomCoords(rand, rotation); + + ComponentTFFinalCastleDungeonRoom31 dRoom = new ComponentTFFinalCastleDungeonRoom31(getFeatureType(), rand, this.componentType + 1, rc.getX(), rc.getY(), rc.getZ(), rotation.rotate(EnumFacing.SOUTH), level); + + StructureBoundingBox largerBB = new StructureBoundingBox(dRoom.getBoundingBox()); + + int expand = 0; + largerBB.minX -= expand; + largerBB.minZ -= expand; + largerBB.maxX += expand; + largerBB.maxZ += expand; + + StructureComponent intersect = StructureTFComponentOld.findIntersectingExcluding(list, largerBB, this); + if (intersect == null) { + list.add(dRoom); + dRoom.buildComponent(parent, list, rand); + return true; + } + return false; + } + + protected boolean addDungeonExit(StructureComponent parent, List list, Random rand, Rotation rotation) { + + //TODO: check if we are sufficiently near the castle center + + rotation = rotation.add(this.rotation); + BlockPos rc = this.getNewRoomCoords(rand, rotation); + ComponentTFFinalCastleDungeonExit dRoom = new ComponentTFFinalCastleDungeonExit(getFeatureType(), rand, this.componentType + 1, rc.getX(), rc.getY(), rc.getZ(), rotation.rotate(EnumFacing.SOUTH), this.level); + StructureComponent intersect = StructureTFComponentOld.findIntersectingExcluding(list, dRoom.getBoundingBox(), this); + if (intersect == null) { + list.add(dRoom); + dRoom.buildComponent(this, list, rand); + return true; + } + return false; + } + + private BlockPos getNewRoomCoords(Random rand, Rotation rotation) { + // make the rooms connect around the corners, not the centers + int offset = rand.nextInt(15) - 9; + if (rand.nextBoolean()) { + offset += this.size; + } + + switch (rotation) { + default: + case NONE: + return new BlockPos(this.boundingBox.maxX + 9, this.boundingBox.minY, this.boundingBox.minZ + offset); + case CLOCKWISE_90: + return new BlockPos(this.boundingBox.minX + offset, this.boundingBox.minY, this.boundingBox.maxZ + 9); + case CLOCKWISE_180: + return new BlockPos(this.boundingBox.minX - 9, this.boundingBox.minY, this.boundingBox.minZ + offset); + case COUNTERCLOCKWISE_90: + return new BlockPos(this.boundingBox.minX + offset, this.boundingBox.minY, this.boundingBox.minZ - 9); + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + + if (this.isBoundingBoxOutsideBiomes(world, sbb, plateauBiomes)) { + return false; + } + + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + this.fillWithAir(world, sbb, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1, state -> state.getMaterial() == Material.ROCK); + + IBlockState floor = TFBlocks.castle_brick.getDefaultState(); + IBlockState border = floor.withProperty(BlockTFCastleBlock.VARIANT, CastleBrickVariant.FRAME); + + Predicate replacing = state -> { + Material material = state.getMaterial(); + return material == Material.ROCK || material == Material.AIR; + }; + + final int cs = 7; + + this.fillWithBlocks(world, sbb, cs , -1, cs, this.size - 1 - cs, -1, this.size - 1 - cs, border, floor, replacing); + this.fillWithBlocks(world, sbb, cs , this.height, cs, this.size - 1 - cs, this.height, this.size - 1 - cs, border, floor, replacing); + + EnumDyeColor forceFieldColor = this.getForceFieldColor(decoRNG); + EnumDyeColor runeColor = getRuneColor(forceFieldColor); + + IBlockState forceField = TFBlocks.force_field.getDefaultState() + .withProperty(BlockTFForceField.COLOR, forceFieldColor); + IBlockState castleMagic = TFBlocks.castle_rune_brick.getDefaultState() + .withProperty(BlockTFCastleMagic.COLOR, runeColor); + + for (Rotation rotation : RotationUtil.ROTATIONS) { + + this.fillBlocksRotated(world, sbb, cs, 0, cs + 1, cs, this.height - 1, this.size - 2 - cs, forceField, rotation); + // verticals + for (int z = cs; z < ((this.size - 1) - cs); z += 4) { + + this.fillBlocksRotated(world, sbb, cs, 0, z, cs, this.height - 1, z, castleMagic, rotation); + // horizontals + int y = ((z - cs) % 8 == 0) ? decoRNG.nextInt(3) + 0 : decoRNG.nextInt(3) + 4; + this.fillBlocksRotated(world, sbb, cs, y, z + 1, cs, y, z + 3, castleMagic, rotation); + } + } + + return true; + } + + protected static final Predicate plateauBiomes = biome -> + biome == TFBiomes.highlandsCenter || biome == TFBiomes.thornlands; + + protected EnumDyeColor getRuneColor(EnumDyeColor forceFieldColor) { + return BlockTFCastleMagic.VALID_COLORS.get(forceFieldColor == BlockTFForceField.VALID_COLORS.get(4) ? 1 : 2); + } + + protected EnumDyeColor getForceFieldColor(Random decoRNG) { + return BlockTFForceField.VALID_COLORS.get(decoRNG.nextInt(2) + 3); + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonSteps.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonSteps.java new file mode 100644 index 0000000000..0325b926e7 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleDungeonSteps.java @@ -0,0 +1,122 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.BlockStairs; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleDungeonSteps extends StructureTFComponentOld { + public ComponentTFFinalCastleDungeonSteps() { + } + + public ComponentTFFinalCastleDungeonSteps(Random rand, int i, int x, int y, int z, EnumFacing rotation) { + this.spawnListIndex = 2; // dungeon monsters + + this.setCoordBaseMode(rotation); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox2(x, y, z, -2, -15, -3, 5, 15, 20, rotation); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + /** + * build more steps towards the specified direction + */ + public ComponentTFFinalCastleDungeonSteps buildMoreStepsTowards(StructureComponent parent, List list, Random rand, Rotation rotation) { + + EnumFacing direction = getStructureRelativeRotation(rotation); + + int sx = 2; + int sy = 0; + int sz = 17; + + switch (rotation) { + case NONE: + sz -= 5; + break; + case CLOCKWISE_90: + sx -= 5; + break; + case CLOCKWISE_180: + sz += 5; + break; + case COUNTERCLOCKWISE_90: + sx += 6; + break; + } + + // find center of landing + int dx = this.getXWithOffset(sx, sz); + int dy = this.getYWithOffset(sy); + int dz = this.getZWithOffset(sx, sz); + + + // build a new stairway there + ComponentTFFinalCastleDungeonSteps steps = new ComponentTFFinalCastleDungeonSteps(rand, this.componentType + 1, dx, dy, dz, direction); + list.add(steps); + steps.buildComponent(this, list, rand); + + return steps; + } + + /** + * build a new level under the exit + */ + public ComponentTFFinalCastleDungeonEntrance buildLevelUnder(StructureComponent parent, List list, Random rand, int level) { + // find center of landing + int dx = this.getXWithOffset(2, 19); + int dy = this.getYWithOffset(-7); + int dz = this.getZWithOffset(2, 19); + + // build a new dungeon level under there + ComponentTFFinalCastleDungeonEntrance room = new ComponentTFFinalCastleDungeonEntrance(getFeatureType(), rand, 8, dx, dy, dz, getCoordBaseMode(), level); + list.add(room); + room.buildComponent(this, list, rand); + + return room; + } + + /** + * build the boss room + */ + public ComponentTFFinalCastleDungeonForgeRoom buildBossRoomUnder(StructureComponent parent, List list, Random rand) { + // find center of landing + int dx = this.getXWithOffset(2, 19); + int dy = this.getYWithOffset(-31); + int dz = this.getZWithOffset(2, 19); + + // build a new dungeon level under there + ComponentTFFinalCastleDungeonForgeRoom room = new ComponentTFFinalCastleDungeonForgeRoom(getFeatureType(), rand, 8, dx, dy, dz, this.coordBaseMode); + list.add(room); + room.buildComponent(this, list, rand); + + return room; + } + + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + final IBlockState stairState = deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.SOUTH); + for (int z = 0; z < 15; z++) { + int y = 14 - z; + + this.fillWithBlocks(world, sbb, 0, y, z, 4, y, z, stairState, stairState, false); + this.fillWithAir(world, sbb, 0, y + 1, z, 4, y + 6, z); + } + this.fillWithAir(world, sbb, 0, 0, 15, 4, 5, 19); + + return true; + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceBottomTower.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceBottomTower.java new file mode 100644 index 0000000000..9c92aed7f2 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceBottomTower.java @@ -0,0 +1,64 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleEntranceBottomTower extends ComponentTFFinalCastleMazeTower13 { + public ComponentTFFinalCastleEntranceBottomTower() { + } + + public ComponentTFFinalCastleEntranceBottomTower(TFFeature feature, Random rand, int i, int x, int y, int z, int floors, int entranceFloor, EnumFacing direction) { + super(feature, rand, i, x, y, z, floors, entranceFloor, BlockTFCastleMagic.VALID_COLORS.get(0), direction); + +// addOpening(12, 1, size / 2, 0); +// addOpening(size / 2, 1, 0, 1); +// addOpening(0, 1, size / 2, 2); +// addOpening(size / 2, 1, 12, 3); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + // stairs + addStairs(list, rand, this.getComponentType() + 1, this.size - 1, 1, size / 2, Rotation.NONE); + addStairs(list, rand, this.getComponentType() + 1, 0, 1, size / 2, Rotation.CLOCKWISE_180); + addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, 0, Rotation.COUNTERCLOCKWISE_90); + addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, this.size - 1, Rotation.CLOCKWISE_90); + + } + + + /** + * Add some stairs leading to this tower + */ + private boolean addStairs(List list, Random rand, int index, int x, int y, int z, Rotation rotation) { + // add door + this.addOpening(x, y, z, rotation); + + EnumFacing direction = getStructureRelativeRotation(rotation); + BlockPos dx = offsetTowerCCoords(x, y, z, 0, direction); + + ComponentTFFinalCastleEntranceStairs stairs = new ComponentTFFinalCastleEntranceStairs(getFeatureType(), index, dx.getX(), dx.getY(), dx.getZ(), direction); + + list.add(stairs); + stairs.buildComponent(list.get(0), list, rand); + return true; + } + + @Override + protected boolean hasAccessibleRoof() { + return false; + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceSideTower.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceSideTower.java new file mode 100644 index 0000000000..ef7118b687 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceSideTower.java @@ -0,0 +1,40 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleEntranceSideTower extends ComponentTFFinalCastleMazeTower13 { + public ComponentTFFinalCastleEntranceSideTower() { + } + + public ComponentTFFinalCastleEntranceSideTower(TFFeature feature, Random rand, int i, int x, int y, int z, int floors, int entranceFloor, EnumFacing direction) { + super(feature, rand, i, x, y, z, floors, entranceFloor, BlockTFCastleMagic.VALID_COLORS.get(0), direction); + + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + // add foundation + ComponentTFFinalCastleFoundation13 foundation = new ComponentTFFinalCastleFoundation13(getFeatureType(), rand, 4, this); + list.add(foundation); + foundation.buildComponent(this, list, rand); + + // add roof + StructureTFComponentOld roof = new ComponentTFFinalCastleRoof13Peaked(getFeatureType(), rand, 4, this); + list.add(roof); + roof.buildComponent(this, list, rand); + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceStairs.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceStairs.java new file mode 100644 index 0000000000..a46b8d062f --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceStairs.java @@ -0,0 +1,73 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.BlockStairs; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; + +/** + * Stair blocks heading to the entrance tower doors + */ +public class ComponentTFFinalCastleEntranceStairs extends StructureTFComponentOld { + + public ComponentTFFinalCastleEntranceStairs() { + } + + public ComponentTFFinalCastleEntranceStairs(TFFeature feature, int index, int x, int y, int z, EnumFacing direction) { + super(feature, index); + this.setCoordBaseMode(direction); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox2(x, y, z, 0, -1, -5, 12, 0, 12, direction); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + + int size = 13; + + for (int x = 1; x < size; x++) { + + this.placeStairs(world, sbb, x, 1 - x, 5, EnumFacing.EAST); + + for (int z = 0; z <= x; z++) { + + if (z > 0 && z <= size / 2) { + this.placeStairs(world, sbb, x, 1 - x, 5 - z, EnumFacing.EAST); + this.placeStairs(world, sbb, x, 1 - x, 5 + z, EnumFacing.EAST); + } + + if (x <= size / 2) { + this.placeStairs(world, sbb, z, 1 - x, 5 - x, EnumFacing.NORTH); + this.placeStairs(world, sbb, z, 1 - x, 5 + x, EnumFacing.SOUTH); + } + } + } + + this.replaceAirAndLiquidDownwards(world, deco.blockState, 0, 0, 5, sbb); + + + return true; + } + + private void placeStairs(World world, StructureBoundingBox sbb, int x, int y, int z, EnumFacing facing) { + if (this.getBlockStateFromPos(world, x, y, z, sbb).getBlock().isReplaceable(world, this.getBlockPosWithOffset(x, y, z))) { + //this.setBlockState(world, deco.blockState, x, y, z, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockStairs.FACING, facing), x, y, z, sbb); + this.replaceAirAndLiquidDownwards(world, deco.blockState, x, y - 1, z, sbb); + } + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceTower.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceTower.java new file mode 100644 index 0000000000..0d82a0e0f8 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleEntranceTower.java @@ -0,0 +1,124 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleEntranceTower extends ComponentTFFinalCastleMazeTower13 { + + public ComponentTFFinalCastleEntranceTower() { + } + + public ComponentTFFinalCastleEntranceTower(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction) { + super(feature, rand, i, x, y, z, 3, 2, BlockTFCastleMagic.VALID_COLORS.get(0), direction); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + // add foundation + ComponentTFFinalCastleFoundation13 foundation = new ComponentTFFinalCastleFoundation13(getFeatureType(), rand, 4, this); + list.add(foundation); + foundation.buildComponent(this, list, rand); + + // add roof + StructureTFComponentOld roof = new ComponentTFFinalCastleRoof13Peaked(getFeatureType(), rand, 4, this); + list.add(roof); + roof.buildComponent(this, list, rand); + + // how many floors until the bottom? + int missingFloors = (this.boundingBox.minY - 127) / 8; + + // place half on the bottom + int bottomFloors = missingFloors / 2; + // how many are left for the middle? + int middleFloors = missingFloors - bottomFloors; + + // what direction can we put the side tower in, if any? + EnumFacing facing = Rotation.CLOCKWISE_90.rotate(this.getCoordBaseMode()); + int howFar = 20; + if (!this.buildSideTower(list, rand, middleFloors + 1, facing, howFar)) { + facing = Rotation.COUNTERCLOCKWISE_90.rotate(this.getCoordBaseMode()); + if (!this.buildSideTower(list, rand, middleFloors + 1, facing, howFar)) { + facing = Rotation.NONE.rotate(this.getCoordBaseMode()); + if (!this.buildSideTower(list, rand, middleFloors + 1, facing, howFar)) { + // side tower no worky + } + } + } + + // add bottom tower + ComponentTFFinalCastleEntranceBottomTower eTower = new ComponentTFFinalCastleEntranceBottomTower(getFeatureType(), rand, this.getComponentType() + 1, this.boundingBox.minX + 6, this.boundingBox.minY - (middleFloors) * 8, this.boundingBox.minZ + 6, bottomFloors + 1, bottomFloors, facing.getOpposite()); + list.add(eTower); + eTower.buildComponent(this, list, rand); + + // add bridge to bottom + BlockPos opening = this.getValidOpeningCC(rand, facing); + opening = opening.down(middleFloors * 8); + + BlockPos bc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), 1, facing); + ComponentTFFinalCastleBridge bridge = new ComponentTFFinalCastleBridge(getFeatureType(), this.getComponentType() + 1, bc.getX(), bc.getY(), bc.getZ(), howFar - 7, facing); + list.add(bridge); + bridge.buildComponent(this, list, rand); + } + + private boolean buildSideTower(List list, Random rand, int middleFloors, EnumFacing facing, int howFar) { + BlockPos opening = this.getValidOpeningCC(rand, facing); + + // build towards + BlockPos tc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), howFar, facing); + + ComponentTFFinalCastleEntranceSideTower eTower = new ComponentTFFinalCastleEntranceSideTower(getFeatureType(), rand, this.getComponentType() + 1, tc.getX(), tc.getY(), tc.getZ(), middleFloors, middleFloors - 1, facing); + + StructureBoundingBox largerBB = new StructureBoundingBox(eTower.getBoundingBox()); + + largerBB.minX -= 6; + largerBB.minZ -= 6; + largerBB.maxX += 6; + largerBB.maxZ += 6; + + StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); + + if (intersect == null) { + list.add(eTower); + eTower.buildComponent(this, list, rand); + // add bridge + BlockPos bc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), 1, facing); + ComponentTFFinalCastleBridge bridge = new ComponentTFFinalCastleBridge(getFeatureType(), this.getComponentType() + 1, bc.getX(), bc.getY(), bc.getZ(), howFar - 7, facing); + list.add(bridge); + bridge.buildComponent(this, list, rand); + + // opening + addOpening(opening.getX(), opening.getY() + 1, opening.getZ(), facing); + + return true; + } else { + TwilightForestMod.LOGGER.info("side entrance tower blocked"); + return false; + } + + } + + /** + * Gets a random position in the specified direction that connects to a floor currently in the tower. + */ + @Override + public BlockPos getValidOpeningCC(Random rand, EnumFacing facing) { + BlockPos opening = super.getValidOpeningCC(rand, facing); + return new BlockPos(opening.getX(), 0, opening.getZ()); + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation13.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation13.java new file mode 100644 index 0000000000..79fa6997c9 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation13.java @@ -0,0 +1,75 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; + +public class ComponentTFFinalCastleFoundation13 extends StructureTFComponentOld { + + protected int groundLevel = -1; + + public ComponentTFFinalCastleFoundation13() {} + + public ComponentTFFinalCastleFoundation13(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, i); + + this.setCoordBaseMode(sideTower.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().minY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().minY, sideTower.getBoundingBox().maxZ + 2); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // offset bounding box to average ground level + if (this.groundLevel < 0) { + this.groundLevel = this.findGroundLevel(world, sbb, 150, isDeadrock); // is 150 a good place to start? :) + + if (this.groundLevel < 0) { + return true; + } + } + + // how tall are we + int height = this.boundingBox.maxY - this.groundLevel; + int mid = height / 2; + + // assume square + int size = this.boundingBox.maxX - this.boundingBox.minX; + + for (Rotation rotation : RotationUtil.ROTATIONS) { + // do corner + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 1, -1, 1, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 2, -1, 1, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 2, -mid, 0, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 1, -1, 2, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 0, -mid, 2, rotation, sbb); + + for (int x = 6; x < (size - 3); x += 4) { + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, x, -1, 1, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, x, -mid, 0, rotation, sbb); + } + + } + + return true; + } + + protected static final Predicate isDeadrock = state -> state.getBlock() == TFBlocks.deadrock; +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation13Thorns.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation13Thorns.java new file mode 100644 index 0000000000..159a890b1a --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation13Thorns.java @@ -0,0 +1,159 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFThorns; +import twilightforest.block.TFBlocks; +import twilightforest.enums.ThornVariant; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.Random; + +/** + * Foundation that makes thorns go all through the tower + * + * @author benma_000 + */ +public class ComponentTFFinalCastleFoundation13Thorns extends ComponentTFFinalCastleFoundation13 { + public ComponentTFFinalCastleFoundation13Thorns() { + } + + public ComponentTFFinalCastleFoundation13Thorns(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, rand, i, sideTower); + + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 5, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 5, sideTower.getBoundingBox().maxX + 5, sideTower.getBoundingBox().maxY, sideTower.getBoundingBox().maxZ + 5); + + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // thorns + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + for (Rotation i : RotationUtil.ROTATIONS) { + this.makeThornVine(world, decoRNG, i, sbb); + } + + return true; + } + + private void makeThornVine(World world, Random decoRNG, Rotation rotation, StructureBoundingBox sbb) { + + int x = 3 + decoRNG.nextInt(13); + int z = 3 + decoRNG.nextInt(13); + + int y = this.boundingBox.getYSize() + 5; + + int twist = decoRNG.nextInt(4); + int twistMod = 3 + decoRNG.nextInt(3); + + final IBlockState thorns = TFBlocks.thorns.getDefaultState(); + + while (this.getBlockStateFromPosRotated(world, x, y, z, sbb, rotation).getBlock() != TFBlocks.deadrock && this.getYWithOffset(y) > 60) { + this.setBlockStateRotated(world, thorns, x, y, z, rotation, sbb); + // twist vines around the center block + switch (twist) { + case 0: + this.setBlockStateRotated(world, thorns, x + 1, y, z, rotation, sbb); + this.setBlockStateRotated(world, thorns, x, y, z + 1, rotation, sbb); + this.setBlockStateRotated(world, thorns, x + 1, y, z + 1, rotation, sbb); + break; + case 1: + this.setBlockStateRotated(world, thorns, x + 1, y, z, rotation, sbb); + this.setBlockStateRotated(world, thorns, x, y, z - 1, rotation, sbb); + this.setBlockStateRotated(world, thorns, x + 1, y, z - 1, rotation, sbb); + break; + case 2: + this.setBlockStateRotated(world, thorns, x - 1, y, z, rotation, sbb); + this.setBlockStateRotated(world, thorns, x, y, z - 1, rotation, sbb); + this.setBlockStateRotated(world, thorns, x - 1, y, z - 1, rotation, sbb); + break; + case 3: + this.setBlockStateRotated(world, thorns, x - 1, y, z, rotation, sbb); + this.setBlockStateRotated(world, thorns, x, y, z + 1, rotation, sbb); + this.setBlockStateRotated(world, thorns, x - 1, y, z + 1, rotation, sbb); + break; + } + + if (Math.abs(y % twistMod) == 1) { + // make branch + this.makeThornBranch(world, x, y, z, rotation, sbb); + } + + // twist randomly + if (y % twistMod == 0) { + twist++; + twist = twist % 4; + } + + y--; + } + } + + private void makeThornBranch(World world, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) { + Random rand = new Random(world.getSeed() + (x * 321534781) ^ (y * 756839) + z); + + // pick a direction + Rotation dir = RotationUtil.getRandomRotation(rand); + + // initialize direction variables + int dx = 0; + int dz = 0; + + switch (dir) { + case NONE: + dx = +1; + break; + case CLOCKWISE_90: + dz = +1; + break; + case CLOCKWISE_180: + dx = -1; + break; + case COUNTERCLOCKWISE_90: + dz = -1; + break; + } + + // how far do we branch? + int dist = 2 + rand.nextInt(3); + + // check to make sure there's room + int destX = x + (dist * dx); + int destZ = z + (dist * dz); + + if (destX > 0 && destX < this.boundingBox.getXSize() && destZ > 0 && destZ < this.boundingBox.getZSize()) { + for (int i = 0; i < dist; i++) { + // go out that far + final Rotation add = dir.add(rotation).add(this.rotation); + IBlockState thorns = TFBlocks.thorns.getDefaultState() + .withProperty(BlockTFThorns.VARIANT, ThornVariant.GREEN) + .withProperty( + BlockTFThorns.AXIS, + add == Rotation.NONE || add == Rotation.CLOCKWISE_180 ? EnumFacing.Axis.X : EnumFacing.Axis.Z + ); + if (i > 0) { + this.setBlockStateRotated(world, thorns, x + (dx * i), y, z + (dz * i), rotation, sbb); + } + // go up that far + this.setBlockStateRotated(world, thorns.withProperty(BlockTFThorns.AXIS, EnumFacing.Axis.Y), destX, y + i, destZ, rotation, sbb); + // go back half that far + if (i > (dist / 2)) { + this.setBlockStateRotated(world, thorns, x + (dx * i), y + dist - 1, z + (dz * i), rotation, sbb); + } + + + } + + + } + + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation48.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation48.java new file mode 100644 index 0000000000..0bdb59773f --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleFoundation48.java @@ -0,0 +1,84 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleFoundation48 extends StructureTFComponentOld { + + public ComponentTFFinalCastleFoundation48() { + } + + public ComponentTFFinalCastleFoundation48(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, i); + + this.setCoordBaseMode(sideTower.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX, sideTower.getBoundingBox().minY, sideTower.getBoundingBox().minZ, sideTower.getBoundingBox().maxX, sideTower.getBoundingBox().minY - 1, sideTower.getBoundingBox().maxZ); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // foundation + for (int x = 4; x < 45; x++) { + for (int z = 4; z < 45; z++) { + this.replaceAirAndLiquidDownwards(world, deco.blockState, x, -1, z, sbb); + } + + } + + int mid = 16; + for (Rotation rotation : RotationUtil.ROTATIONS) { + // do corner + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 3, -2, 3, rotation, sbb); + + // directly under castle + this.fillBlocksRotated(world, sbb, 2, -2, 1, 46, -1, 1, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 2, -4, 2, 45, -1, 2, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 4, -6, 3, 44, -1, 3, deco.blockState, rotation); + + // pilings + for (int i = 9; i < 45; i += 6) { + makePiling(world, sbb, mid, rotation, i); + } + + makePiling(world, sbb, mid, rotation, 4); + makePiling(world, sbb, mid, rotation, 44); + + } + +// add supports for entrance bridge + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 21, -2, 0, Rotation.CLOCKWISE_90, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 21, -4, 1, Rotation.CLOCKWISE_90, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 21, -6, 2, Rotation.CLOCKWISE_90, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 27, -2, 0, Rotation.CLOCKWISE_90, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 27, -4, 1, Rotation.CLOCKWISE_90, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, 27, -6, 2, Rotation.CLOCKWISE_90, sbb); + + return true; + } + + private void makePiling(World world, StructureBoundingBox sbb, int mid, Rotation rotation, int i) { + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, i, -7, 3, rotation, sbb); + this.replaceAirAndLiquidDownwardsRotated(world, deco.blockState, i, -mid, 2, rotation, sbb); + + this.setBlockStateRotated(world, deco.blockState, i, -1, 0, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, i, -3, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, i, -5, 2, rotation, sbb); + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleLargeTower.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleLargeTower.java new file mode 100644 index 0000000000..13ff4aecb2 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleLargeTower.java @@ -0,0 +1,78 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleDoor; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.structures.lichtower.ComponentTFTowerWing; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleLargeTower extends ComponentTFTowerWing { + + public ComponentTFFinalCastleLargeTower() { + } + + public ComponentTFFinalCastleLargeTower(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i); + this.setCoordBaseMode(rotation); + this.size = 13; + this.height = 61; + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -6, 0, -6, 12, 60, 12, EnumFacing.SOUTH); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + // add crown + ComponentTFFinalCastleRoof9Crenellated roof = new ComponentTFFinalCastleRoof9Crenellated(getFeatureType(), rand, 4, this); + list.add(roof); + roof.buildComponent(this, list, rand); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + fillWithRandomizedBlocks(world, sbb, 0, 0, 0, 12, 59, 12, false, rand, deco.randomBlocks); + + // add branching runes + int numBranches = 6 + decoRNG.nextInt(4); + for (int i = 0; i < numBranches; i++) { + makeGlyphBranches(world, decoRNG, this.getGlyphMeta(), sbb); + } + + // beard + for (int i = 1; i < 4; i++) { + fillWithRandomizedBlocks(world, sbb, i, 0 - (i * 2), i, 8 - i, 1 - (i * 2), 8 - i, false, rand, deco.randomBlocks); + } + this.setBlockState(world, deco.blockState, 4, -7, 4, sbb); + + // door, first floor + final IBlockState castleDoor = TFBlocks.castle_door.getDefaultState() + .withProperty(BlockTFCastleDoor.LOCK_INDEX, 0); //this.getGlyphMeta()? + this.fillWithBlocks(world, sbb, 0, 1, 1, 0, 4, 3, castleDoor, AIR, false); + + this.placeSignAtCurrentPosition(world, 6, 1, 6, "Parkour area 1", "Unique monster?", sbb); + + return true; + } + + + public EnumDyeColor getGlyphMeta() { + return BlockTFCastleMagic.VALID_COLORS.get(0); + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMain.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMain.java new file mode 100644 index 0000000000..de64856afc --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMain.java @@ -0,0 +1,351 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.BlockTFForceField; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + +import static twilightforest.block.BlockTFCastleDoor.LOCK_INDEX; + +public class ComponentTFFinalCastleMain extends StructureTFComponentOld { + public ComponentTFFinalCastleMain() { + } + + public ComponentTFFinalCastleMain(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.SOUTH); + this.spawnListIndex = 1; // main monsters + + x = ((x + 127) >> 8) << 8; + z = ((z + 127) >> 8) << 8; + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -24, 120, -24, 48, 40, 48, EnumFacing.SOUTH); + + BlockPos cc = TFFeature.getNearestCenterXYZ(x >> 4, z >> 4, world); + + int cx = (x >> 8) << 8; + int cz = (z >> 8) << 8; + + TwilightForestMod.LOGGER.debug("Making castle at {}, {}. center is {}, {}", x, z, cc.getX(), cc.getZ()); + TwilightForestMod.LOGGER.debug("Natural center at {}, {}", cx, cz); + + // decorator + if (this.deco == null) { + this.deco = new StructureTFDecoratorCastle(); + } + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + // add foundation + ComponentTFFinalCastleFoundation48 foundation = new ComponentTFFinalCastleFoundation48(getFeatureType(), rand, 4, this); + list.add(foundation); + foundation.buildComponent(this, list, rand); + + // add roof + StructureTFComponentOld roof = new ComponentTFFinalCastleRoof48Crenellated(getFeatureType(), rand, 4, this); + list.add(roof); + roof.buildComponent(this, list, rand); + + // boss gazebo on roof + StructureTFComponentOld gazebo = new ComponentTFFinalCastleBossGazebo(getFeatureType(), rand, 5, this); + list.add(gazebo); + gazebo.buildComponent(this, list, rand); + + + // build 4 towers on sides + ComponentTFFinalCastleStairTower tower0 = new ComponentTFFinalCastleStairTower(getFeatureType(), rand, 3, boundingBox.minX, boundingBox.minY + 3, boundingBox.minZ, EnumFacing.NORTH); + list.add(tower0); + tower0.buildComponent(this, list, rand); + + ComponentTFFinalCastleLargeTower tower1 = new ComponentTFFinalCastleLargeTower(getFeatureType(), rand, 3, boundingBox.maxX, boundingBox.minY + 3, boundingBox.minZ, EnumFacing.EAST); + list.add(tower1); + tower1.buildComponent(this, list, rand); + + ComponentTFFinalCastleStairTower tower2 = new ComponentTFFinalCastleStairTower(getFeatureType(), rand, 3, boundingBox.minX, boundingBox.minY + 3, boundingBox.maxZ, EnumFacing.WEST); + list.add(tower2); + tower2.buildComponent(this, list, rand); + + ComponentTFFinalCastleStairTower tower3 = new ComponentTFFinalCastleStairTower(getFeatureType(), rand, 3, boundingBox.maxX, boundingBox.minY + 3, boundingBox.maxZ, EnumFacing.SOUTH); + list.add(tower3); + tower3.buildComponent(this, list, rand); + + // tower maze towards entrance + BlockPos dest = new BlockPos(boundingBox.minX - 4, boundingBox.maxY, boundingBox.minZ - 24); + buildTowerMaze(list, rand, 48, 0, 24, 60, EnumFacing.SOUTH, BlockTFCastleMagic.VALID_COLORS.get(0), dest); + + + // another tower/bridge maze towards the clock tower + dest = new BlockPos(boundingBox.maxX + 4, boundingBox.minY, boundingBox.maxZ + 24); + buildTowerMaze(list, rand, 0, 30, 24, 60, EnumFacing.NORTH, BlockTFCastleMagic.VALID_COLORS.get(1), dest); + + + // initial stairs down towards dungeon + ComponentTFFinalCastleDungeonSteps steps0 = new ComponentTFFinalCastleDungeonSteps(rand, 5, boundingBox.minX + 18, boundingBox.minY + 1, boundingBox.minZ + 18, EnumFacing.SOUTH); + list.add(steps0); + steps0.buildComponent(this, list, rand); + + // continued steps + ComponentTFFinalCastleDungeonSteps steps1 = steps0.buildMoreStepsTowards(parent, list, rand, Rotation.COUNTERCLOCKWISE_90); + ComponentTFFinalCastleDungeonSteps steps2 = steps1.buildMoreStepsTowards(parent, list, rand, Rotation.COUNTERCLOCKWISE_90); + ComponentTFFinalCastleDungeonSteps steps3 = steps2.buildMoreStepsTowards(parent, list, rand, Rotation.COUNTERCLOCKWISE_90); + + // start dungeon + steps3.buildLevelUnder(parent, list, rand, 1); + + // mural on front + BlockPos mc = this.offsetTowerCCoords(48, 23, 25, 1, EnumFacing.SOUTH); + ComponentTFFinalCastleMural mural0 = new ComponentTFFinalCastleMural(getFeatureType(), rand, 7, mc.getX(), mc.getY(), mc.getZ(), 35, 30, EnumFacing.SOUTH); + list.add(mural0); + mural0.buildComponent(this, list, rand); + + // mural inside + BlockPos mc1 = this.offsetTowerCCoords(48, 33, 24, -1, EnumFacing.SOUTH); + ComponentTFFinalCastleMural mural1 = new ComponentTFFinalCastleMural(getFeatureType(), rand, 7, mc1.getX(), mc1.getY(), mc.getZ(), 19, 12, EnumFacing.NORTH); + list.add(mural1); + mural1.buildComponent(this, list, rand); + + } + + /** + * Build a side tower, then tell it to start building towards the destination + */ + private void buildTowerMaze(List list, Random rand, int x, int y, int z, int howFar, EnumFacing direction, EnumDyeColor type, BlockPos dest) { + boolean complete = false; + int iterations = 0; + while (!complete && iterations < 15) { + iterations++; + // duplicate list + List before = new LinkedList<>(list); + + // build + BlockPos tc = this.offsetTowerCCoords(x, y, z, howFar, direction); + ComponentTFFinalCastleMazeTower13 sTower = new ComponentTFFinalCastleMazeTower13(getFeatureType(), rand, 3, tc.getX(), tc.getY(), tc.getZ(), type, direction); + + // add bridge + BlockPos bc = this.offsetTowerCCoords(x, y, z, 1, direction); + ComponentTFFinalCastleBridge bridge = new ComponentTFFinalCastleBridge(getFeatureType(), this.getComponentType() + 1, bc.getX(), bc.getY(), bc.getZ(), howFar - 7, direction); + + list.add(bridge); + bridge.buildComponent(this, list, rand); + + // don't check if the bounding box is clear, there's either nothing there or we've made a terrible mistake + list.add(sTower); + sTower.buildTowards(this, list, rand, dest); + + // check if we've successfully built the end tower + TwilightForestMod.LOGGER.debug("Working towards {},{},{}", dest.getX(), dest.getY(), dest.getZ()); + if (this.isMazeComplete(list, type)) { + TwilightForestMod.LOGGER.debug("Tower maze color {} complete!", type); + complete = true; + } else { + // TODO: add limit on retrying, in case of infinite loop? + TwilightForestMod.LOGGER.info("Tower maze color {} INCOMPLETE, retrying!", type); + list.clear(); + list.addAll(before); + //this.buildTowerMaze(list, rand, x, y, z, howFar, direction, color, dest); + } + } + } + + private boolean isMazeComplete(List list, EnumDyeColor type) { + if (list.size() > 60) { + TwilightForestMod.LOGGER.warn("Maze of color {} is getting a bit excessive.", type); + } + for (StructureComponent structurecomponent : list) { + StructureBoundingBox boundingBox = structurecomponent.getBoundingBox(); + int x = (boundingBox.maxX - boundingBox.minX / 2) + boundingBox.minX; + int y = (boundingBox.maxY - boundingBox.minY / 2) + boundingBox.minY; + int z = (boundingBox.maxZ - boundingBox.minZ / 2) + boundingBox.minZ; + TwilightForestMod.LOGGER.debug("Component {} at {},{},{}", structurecomponent.getClass().getSimpleName(), x, y, z); + if (type == BlockTFCastleMagic.VALID_COLORS.get(0) && structurecomponent instanceof ComponentTFFinalCastleEntranceTower) { + return true; + } + if (type == BlockTFCastleMagic.VALID_COLORS.get(1) && structurecomponent instanceof ComponentTFFinalCastleBellTower21) { + return true; + } + } + return false; + } + + /** + * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. + */ + @Override + protected BlockPos offsetTowerCCoords(int x, int y, int z, int howFar, EnumFacing direction) { + + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + + switch (direction) { + case SOUTH: + dx += howFar; + break; + case WEST: + dz += howFar; + break; + case NORTH: + dx -= howFar; + break; + case EAST: + dz -= howFar; + break; + default: + break; + } + + // ugh? + return new BlockPos(dx, dy, dz); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // walls + fillWithRandomizedBlocks(world, sbb, 0, 0, 0, 48, 40, 48, false, rand, deco.randomBlocks); + + // 2M + fillWithRandomizedBlocks(world, sbb, 13, 30, 1, 47, 30, 12, false, rand, deco.randomBlocks); + this.fillWithBlocks(world, sbb, 13, 31, 12, 36, 31, 12, deco.fenceState, deco.fenceState, false); + fillWithRandomizedBlocks(world, sbb, 13, 30, 36, 47, 30, 47, false, rand, deco.randomBlocks); + this.fillWithBlocks(world, sbb, 13, 31, 36, 36, 31, 36, deco.fenceState, deco.fenceState, false); + fillWithRandomizedBlocks(world, sbb, 1, 30, 1, 12, 30, 47, false, rand, deco.randomBlocks); + this.fillWithBlocks(world, sbb, 12, 31, 12, 12, 31, 36, deco.fenceState, deco.fenceState, false); + + // second floor stairs to mezzanine + fillWithRandomizedBlocks(world, sbb, 38, 25, 13, 47, 25, 35, false, rand, deco.randomBlocks); + + for (int i = 0; i < 5; i++) { + int y = 30 - i; + + makeMezzTopStairs(world, sbb, y, 10 + i, EnumFacing.SOUTH); + makeMezzTopStairs(world, sbb, y, 38 - i, EnumFacing.NORTH); + + y = 25 - i; + int x = 37 - i; + final IBlockState stairState = getStairState(deco.stairState, EnumFacing.WEST, rotation, false); + this.fillWithBlocks(world, sbb, x, y, 14, x, y, 22, stairState, stairState, false); + this.fillWithBlocks(world, sbb, x, y - 1, 14, x, y - 1, 22, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, x, y, 26, x, y, 34, stairState, stairState, false); + this.fillWithBlocks(world, sbb, x, y - 1, 26, x, y - 1, 34, deco.blockState, deco.blockState, false); + } + + + // pillars + for (int x = 11; x < 47; x += 12) { + for (int z = 11; z < 47; z += 12) { + this.fillWithBlocks(world, sbb, x, 1, z, x + 2, 40, z + 2, deco.pillarState, deco.blockState, false); + + makePillarBase(world, sbb, x, z, 1, false); + makePillarBase(world, sbb, x, z, 19, true); + makePillarBase(world, sbb, x, z, 21, false); + makePillarBase(world, sbb, x, z, 39, true); + + + } + } + + // side pillars + for (Rotation rotation : RotationUtil.ROTATIONS) { + for (int z = 11; z < 47; z += 12) { + + // no middle pillars on walls with entrances + if (z == 23 && (rotation == Rotation.NONE || rotation == Rotation.CLOCKWISE_180)) { + continue; + } + + this.fillBlocksRotated(world, sbb, 1, 1, z, 1, 40, z + 2, deco.pillarState, rotation); + makeHalfPillarBase(world, sbb, rotation, 1, z, false); + makeHalfPillarBase(world, sbb, rotation, 19, z, true); + makeHalfPillarBase(world, sbb, rotation, 21, z, false); + makeHalfPillarBase(world, sbb, rotation, 39, z, true); + } + } + + // second floor + fillWithRandomizedBlocks(world, sbb, 1, 20, 1, 47, 20, 47, false, rand, deco.randomBlocks); + + // force field around dungeon stairs + IBlockState fieldBlock = TFBlocks.force_field.getDefaultState().withProperty(BlockTFForceField.COLOR, EnumDyeColor.PINK); + this.fillWithBlocks(world, sbb, 12, 1, 12, 24, 10, 12, fieldBlock, fieldBlock, false); + this.fillWithBlocks(world, sbb, 12, 1, 12, 12, 10, 24, fieldBlock, fieldBlock, false); + this.fillWithBlocks(world, sbb, 24, 1, 12, 24, 10, 24, fieldBlock, fieldBlock, false); + this.fillWithBlocks(world, sbb, 12, 1, 24, 24, 10, 24, fieldBlock, fieldBlock, false); + + this.fillWithBlocks(world, sbb, 12, 10, 12, 24, 10, 24, fieldBlock, fieldBlock, false); + + // doors in dungeon force field + final IBlockState castleDoor = TFBlocks.castle_door.getDefaultState(); + this.fillWithBlocks(world, sbb, 17, 1, 12, 19, 4, 12, castleDoor.withProperty(LOCK_INDEX, 2), AIR, false); + this.fillWithBlocks(world, sbb, 17, 1, 24, 19, 4, 24, castleDoor.withProperty(LOCK_INDEX, 2), AIR, false); + + // stairs to stair towers + makeSmallTowerStairs(world, sbb, Rotation.NONE); + makeSmallTowerStairs(world, sbb, Rotation.CLOCKWISE_90); + makeSmallTowerStairs(world, sbb, Rotation.COUNTERCLOCKWISE_90); + makeLargeTowerStairs(world, sbb, Rotation.CLOCKWISE_180); + + // door, first floor + this.fillWithBlocks(world, sbb, 48, 1, 23, 48, 4, 25, castleDoor.withProperty(LOCK_INDEX, 0), AIR, false); + + // door, second floor + this.fillWithBlocks(world, sbb, 0, 31, 23, 0, 34, 25, castleDoor.withProperty(LOCK_INDEX, 1), AIR, false); + + return true; + } + + private void makeSmallTowerStairs(World world, StructureBoundingBox sbb, Rotation rotation) { + for (int y = 1; y < 4; y++) { + int z = 40 + y; + this.fillBlocksRotated(world, sbb, 1, 1, z, 4, y, z, deco.blockState, rotation); + + this.fillBlocksRotated(world, sbb, 2, y, z, 3, y, z, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), rotation); + } + } + + private void makeLargeTowerStairs(World world, StructureBoundingBox sbb, Rotation rotation) { + final IBlockState stairState = getStairState(deco.stairState, EnumFacing.NORTH, rotation, false); + for (int y = 1; y < 4; y++) { + int z = 38 + y; + this.fillBlocksRotated(world, sbb, 2, 1, z, 6, y, z, deco.blockState, rotation); + this.fillBlocksRotated(world, sbb, 3, y, z, 5, y, z, stairState, rotation); + } + } + + private void makeMezzTopStairs(World world, StructureBoundingBox sbb, int y, int z, EnumFacing stairMeta) { + final IBlockState stairState = getStairState(deco.stairState, stairMeta, rotation, false); + this.fillWithBlocks(world, sbb, 38, y, z, 46, y, z, stairState, stairState, false); + this.fillWithBlocks(world, sbb, 38, y - 1, z, 46, y - 1, z, deco.blockState, deco.blockState, false); + this.fillWithAir(world, sbb, 38, y + 1, z, 46, y + 3, z); + } + + private void makeHalfPillarBase(World world, StructureBoundingBox sbb, Rotation rotation, int y, int z, boolean isFlipped) { + this.fillBlocksRotated(world, sbb, 2, y, z - 1, 2, y, z + 3, getStairState(deco.stairState, EnumFacing.EAST, rotation, isFlipped), rotation); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, isFlipped), 1, y, z - 1, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, isFlipped), 1, y, z + 3, rotation, sbb); + } + + private void makePillarBase(World world, StructureBoundingBox sbb, int x, int z, int y, boolean isFlipped) { + this.fillWithBlocks(world, sbb, x + 0, y, z + 3, x + 3, y, z + 3, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, isFlipped), AIR, false); + this.fillWithBlocks(world, sbb, x - 1, y, z - 1, x + 2, y, z - 1, getStairState(deco.stairState, EnumFacing.NORTH, rotation, isFlipped), AIR, false); + + this.fillWithBlocks(world, sbb, x + 3, y, z - 1, x + 3, y, z + 2, getStairState(deco.stairState, EnumFacing.EAST, rotation, isFlipped), AIR, false); + this.fillWithBlocks(world, sbb, x - 1, y, z + 0, x - 1, y, z + 3, getStairState(deco.stairState, EnumFacing.WEST, rotation, isFlipped), AIR, false); + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMazeTower13.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMazeTower13.java new file mode 100644 index 0000000000..bee2bf42d9 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMazeTower13.java @@ -0,0 +1,586 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.block.BlockTFCastleDoor; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.structures.lichtower.ComponentTFTowerWing; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleMazeTower13 extends ComponentTFTowerWing { + + public static final int LOWEST_DOOR = 144; + public static final int HIGHEST_DOOR = 222; + + public EnumDyeColor color; + + public ComponentTFFinalCastleMazeTower13() { + } + + public ComponentTFFinalCastleMazeTower13(TFFeature feature, Random rand, int i, int x, int y, int z, EnumDyeColor color, EnumFacing direction) { + super(feature, i); + this.setCoordBaseMode(direction); + this.color = color; + this.size = 13; + + // decide a number of floors, 2-5 + int floors = rand.nextInt(3) + 2; + + this.height = floors * 8 + 1; + + // entrance should be on a random floor + int entranceFloor = rand.nextInt(floors); + + // rationalize entrance floor if the tower is going to be too low, put the entrance floor at bottom. Too high, put it at top + if ((y - (entranceFloor * 8)) < LOWEST_DOOR) { + //TwilightForestMod.LOGGER.info("Tower at " + x + ", " + z + " is getting too low, setting entrance to bottom floor."); + entranceFloor = 0; + } + if ((y + ((floors - entranceFloor) * 8)) > HIGHEST_DOOR) { + //TwilightForestMod.LOGGER.info("Tower at " + x + ", " + z + " is getting too high, setting entrance to floor " + (floors - 1) + "."); + entranceFloor = floors - 1; + } + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -6, 0 - (entranceFloor * 8), -6, this.size - 1, this.height, this.size - 1, EnumFacing.SOUTH); + + // we should have a door where we started + addOpening(0, entranceFloor * 8 + 1, size / 2, Rotation.CLOCKWISE_180); + + } + + public ComponentTFFinalCastleMazeTower13(TFFeature feature, Random rand, int i, int x, int y, int z, int floors, int entranceFloor, EnumDyeColor color, EnumFacing direction) { + super(feature, i); + this.setCoordBaseMode(direction); + this.color = color; + this.size = 13; + this.height = floors * 8 + 1; + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -6, 0 - (entranceFloor * 8), -6, this.size - 1, this.height, this.size - 1, EnumFacing.SOUTH); + addOpening(0, entranceFloor * 8 + 1, size / 2, Rotation.CLOCKWISE_180); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + + // add foundation + ComponentTFFinalCastleFoundation13 foundation = new ComponentTFFinalCastleFoundation13(getFeatureType(), rand, 4, this); + list.add(foundation); + foundation.buildComponent(this, list, rand); + + // add roof + StructureTFComponentOld roof = rand.nextBoolean() ? new ComponentTFFinalCastleRoof13Conical(getFeatureType(), rand, 4, this) : new ComponentTFFinalCastleRoof13Crenellated(getFeatureType(), rand, 4, this); + list.add(roof); + roof.buildComponent(this, list, rand); + } + + /** + * Build more components towards the destination + */ + public void buildTowards(StructureComponent parent, List list, Random rand, BlockPos dest) { + // regular building first, adds roof/foundation + this.buildComponent(parent, list, rand); + + if (this.getComponentType() < 20) { + + // are we there? + if (this.isWithinRange(dest.getX(), dest.getZ(), this.boundingBox.minX + 6, this.boundingBox.minZ + 6, 30)) { + TwilightForestMod.LOGGER.debug("We are within range of our destination, building final tower"); + int howFar = 20; + if (!buildEndTowerTowards(list, rand, dest, this.findBestDirectionTowards(dest), howFar)) { + if (!buildEndTowerTowards(list, rand, dest, this.findSecondDirectionTowards(dest), howFar)) { + if (!buildEndTowerTowards(list, rand, dest, this.findThirdDirectionTowards(dest), howFar)) { + TwilightForestMod.LOGGER.info("Could not build final tower"); + } + } + } + } else { + + int howFar = 14 + rand.nextInt(24); + EnumFacing facing = this.findBestDirectionTowards(dest); + + // build left or right, not straight if we can help it + if (facing == this.getCoordBaseMode() || !buildContinueTowerTowards(list, rand, dest, facing, howFar)) { + facing = this.findSecondDirectionTowards(dest); + if (facing == this.getCoordBaseMode() || !buildContinueTowerTowards(list, rand, dest, facing, howFar)) { + facing = this.findThirdDirectionTowards(dest); + if (facing == this.getCoordBaseMode() || !buildContinueTowerTowards(list, rand, dest, facing, howFar)) { + // fine, just go straight + if (!buildContinueTowerTowards(list, rand, dest, this.getCoordBaseMode(), howFar)) { + TwilightForestMod.LOGGER.info("Could not build tower randomly"); + } + } + } + } + } + } else { + TwilightForestMod.LOGGER.info("Built 15 towers without reaching destination"); + } + + // finally, now that the critical path is built, let's add some other towers for atmosphere and complication + this.buildNonCriticalTowers(parent, list, rand); + + } + + protected void buildNonCriticalTowers(StructureComponent parent, List list, Random rand) { + // pick a random direction + EnumFacing dir = RotationUtil.getRandomFacing(rand); + Rotation relativeRotation = RotationUtil.getRelativeRotation(this.getCoordBaseMode(), dir); + + // if there isn't something in that direction, check if we can add a wrecked tower + if (this.openingTowards[relativeRotation.ordinal()] == false) { + if (!buildDamagedTower(list, rand, dir)) { + dir = RotationUtil.getRandomFacing(rand); + if (!buildDamagedTower(list, rand, dir)) { + // maybe just a balcony? + //buildBalconyTowards(list, rand, dir); + } + } + } + + + } + + private EnumFacing findBestDirectionTowards(BlockPos dest) { + + // center of tower + int cx = this.boundingBox.minX + 6; + int cz = this.boundingBox.minZ + 6; + + // difference + int dx = cx - dest.getX(); + int dz = cz - dest.getZ(); + + EnumFacing absoluteDir; + if (Math.abs(dx) > Math.abs(dz)) { + absoluteDir = (dx >= 0) ? EnumFacing.EAST : EnumFacing.WEST; + } else { + absoluteDir = (dz >= 0) ? EnumFacing.SOUTH : EnumFacing.NORTH; + } + + TwilightForestMod.LOGGER.debug("Determining best direction! center is at {}, {} and dest is at {}. offset is {}, {} so the best absolute direction is {}", cx, cz, dest, dx, dz, absoluteDir); + + return absoluteDir; + } + + private EnumFacing findSecondDirectionTowards(BlockPos dest) { + + // center of tower + int cx = this.boundingBox.minX + 6; + int cz = this.boundingBox.minZ + 6; + + // difference + int dx = cx - dest.getX(); + int dz = cz - dest.getZ(); + + EnumFacing absoluteDir; + if (Math.abs(dx) < Math.abs(dz)) { // reversed from findBestDirectionTowards + absoluteDir = (dx >= 0) ? EnumFacing.EAST : EnumFacing.WEST; + } else { + absoluteDir = (dz >= 0) ? EnumFacing.SOUTH : EnumFacing.NORTH; + } + + TwilightForestMod.LOGGER.debug("Determining second direction! center is at {}, {} and dest is at {}. offset is {}, {} so the best absolute direction is {}", cx, cz, dest, dx, dz, absoluteDir); + + return absoluteDir; + } + + private EnumFacing findThirdDirectionTowards(BlockPos dest) { + EnumFacing first = this.findBestDirectionTowards(dest); + EnumFacing second = this.findSecondDirectionTowards(dest); + + EnumFacing[] cardinals = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST}; + + TwilightForestMod.LOGGER.debug("Determining third direction! first is {}, and second is {}", first, second); + + for (EnumFacing f : cardinals) { + if (f != first && f != second && f != Rotation.CLOCKWISE_180.rotate(this.getCoordBaseMode())) { + return f; + } + } + + // should not get here + return this.getCoordBaseMode(); + } + + private boolean buildContinueTowerTowards(List list, Random rand, BlockPos dest, EnumFacing facing, int howFar) { + BlockPos opening = this.getValidOpeningCC(rand, facing); + + // adjust opening towards dest.getY() if we are getting close to dest + int adjustmentRange = 60; + if (this.isWithinRange(dest.getX(), dest.getZ(), this.boundingBox.minX + 6, this.boundingBox.minZ + 6, adjustmentRange)) { + opening = new BlockPos( + opening.getX(), + this.adjustOpening(opening.getY(), dest), + opening.getZ() + ); + } + + TwilightForestMod.LOGGER.debug("original direction is {}", facing); + + // build towards + BlockPos tc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), howFar, facing); + TwilightForestMod.LOGGER.debug("Our coord mode is {}, and direction is {}, so our door is going to be at {} and the new tower will appear at {}", this.getCoordBaseMode(), facing, opening, tc); + + // find start + StructureComponent start = (StructureComponent) list.get(0); + + int centerX = ((start.getBoundingBox().minX + 128) >> 8) << 8; + int centerZ = ((start.getBoundingBox().minZ + 128) >> 8) << 8; + + TwilightForestMod.LOGGER.debug("Testing range, uncorrected center is at {}, {}", centerX, centerZ); + + if (isWithinRange(centerX, centerZ, tc.getX(), tc.getZ(), 128)) { + + ComponentTFFinalCastleMazeTower13 sTower = new ComponentTFFinalCastleMazeTower13(getFeatureType(), rand, this.getComponentType() + 1, tc.getX(), tc.getY(), tc.getZ(), this.color, facing); + + StructureBoundingBox largerBB = new StructureBoundingBox(sTower.getBoundingBox()); + + largerBB.minX -= 6; + largerBB.minZ -= 6; + largerBB.maxX += 6; + largerBB.maxZ += 6; + largerBB.minY = 0; + largerBB.maxY = 255; + + StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); + + if (intersect == null) { + TwilightForestMod.LOGGER.debug("tower success!"); + list.add(sTower); + sTower.buildTowards(this, list, rand, dest); + + // add bridge + BlockPos bc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), 1, facing); + ComponentTFFinalCastleBridge bridge = new ComponentTFFinalCastleBridge(getFeatureType(), this.getComponentType() + 1, bc.getX(), bc.getY(), bc.getZ(), howFar - 7, facing); + list.add(bridge); + bridge.buildComponent(this, list, rand); + + // opening + addOpening(opening.getX(), opening.getY() + 1, opening.getZ(), facing); + + return true; + } else { + TwilightForestMod.LOGGER.info("tower blocked by {}", intersect); + return false; + } + } else { + TwilightForestMod.LOGGER.info("tower out of range"); + return false; + } + } + + + protected boolean buildDamagedTower(List list, Random rand, EnumFacing facing) { + BlockPos opening = this.getValidOpeningCC(rand, facing); + + int howFar = 14 + rand.nextInt(24); + // build towards + BlockPos tc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), howFar, facing); + + // what color of tower? + ComponentTFFinalCastleMazeTower13 eTower = makeNewDamagedTower(rand, facing, tc); + + StructureBoundingBox largerBB = new StructureBoundingBox(eTower.getBoundingBox()); + + largerBB.minX -= 6; + largerBB.minZ -= 6; + largerBB.maxX += 6; + largerBB.maxZ += 6; + + StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); + + if (intersect == null) { + //TwilightForestMod.LOGGER.info("wreck tower success! tower is at " + tc.getX() + ", " + tc.getY() + ", " + tc.getZ()); + list.add(eTower); + eTower.buildComponent(this, list, rand); + // add bridge + BlockPos bc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), 1, facing); + ComponentTFFinalCastleBridge bridge = new ComponentTFFinalCastleBridge(getFeatureType(), this.getComponentType() + 1, bc.getX(), bc.getY(), bc.getZ(), howFar - 7, facing); + list.add(bridge); + bridge.buildComponent(this, list, rand); + + // opening + addOpening(opening.getX(), opening.getY() + 1, opening.getZ(), facing); + + return true; + } else { + //TwilightForestMod.LOGGER.info("damaged tower blocked"); + return false; + } + } + + protected ComponentTFFinalCastleMazeTower13 makeNewDamagedTower(Random rand, EnumFacing facing, BlockPos tc) { + return new ComponentTFFinalCastleDamagedTower(getFeatureType(), rand, this.getComponentType() + 1, tc.getX(), tc.getY(), tc.getZ(), facing); + } + + private int adjustOpening(int posY, BlockPos dest) { + int openY = posY; + + int realOpeningY = this.getYWithOffset(openY); + if (realOpeningY - dest.getY() < 12) { + // if it is too low, move it to the top floor + openY = this.height - 9; + } else if (dest.getY() - realOpeningY < 12) { + // if the opening is too high, move it to the bottom floor + openY = 0; + } + + return openY; + } + + private boolean buildEndTowerTowards(List list, Random rand, BlockPos dest, EnumFacing facing, int howFar) { + BlockPos opening = this.getValidOpeningCC(rand, facing); + opening = new BlockPos( + opening.getX(), + // adjust opening towards dest.getY() + this.adjustOpening(opening.getY(), dest), + opening.getZ() + ); + + // build towards + BlockPos tc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), howFar, facing); + + //TwilightForestMod.LOGGER.info("Our coord mode is " + this.getCoordBaseMode() + ", and direction is " + direction + ", so our door is going to be at " + opening + " and the new tower will appear at " + tc); + + // what color of tower? + ComponentTFFinalCastleMazeTower13 eTower; + if (this.color == BlockTFCastleMagic.VALID_COLORS.get(0)) { + eTower = new ComponentTFFinalCastleEntranceTower(getFeatureType(), rand, this.getComponentType() + 1, tc.getX(), tc.getY(), tc.getZ(), facing); + } else { + eTower = new ComponentTFFinalCastleBellTower21(getFeatureType(), rand, this.getComponentType() + 1, tc.getX(), tc.getY(), tc.getZ(), facing); + } + + StructureBoundingBox largerBB = new StructureBoundingBox(eTower.getBoundingBox()); + + largerBB.minX -= 6; + largerBB.minZ -= 6; + largerBB.maxX += 6; + largerBB.maxZ += 6; + + StructureComponent intersect = StructureComponent.findIntersecting(list, largerBB); + + if (intersect == null) { + //TwilightForestMod.LOGGER.info("entrance tower success! tower is at " + tc.getX() + ", " + tc.getY() + ", " + tc.getZ() + " and dest is " + dest.getX() + ", " + dest.getY() + ", " + dest.getZ()); + list.add(eTower); + eTower.buildComponent(this, list, rand); + // add bridge + BlockPos bc = this.offsetTowerCCoords(opening.getX(), opening.getY(), opening.getZ(), 1, facing); + ComponentTFFinalCastleBridge bridge = new ComponentTFFinalCastleBridge(getFeatureType(), this.getComponentType() + 1, bc.getX(), bc.getY(), bc.getZ(), howFar - 7, facing); + list.add(bridge); + bridge.buildComponent(this, list, rand); + + // opening + addOpening(opening.getX(), opening.getY() + 1, opening.getZ(), facing); + + return true; + } else { + //TwilightForestMod.LOGGER.info("end tower blocked"); + return false; + } + + } + + private boolean isWithinRange(int centerX, int centerZ, int posX, int posZ, int range) { + boolean inRange = Math.abs(centerX - posX) < range && Math.abs(centerZ - posZ) < range; + + if (!inRange) { +// TwilightForestMod.LOGGER.info("Tested range, center is at " + centerX + ", " + centerZ + " and tower is " + posX + ", " + posZ + " so distance is " + Math.max(Math.abs(centerX - posX), Math.abs(centerZ - posZ))); + } + + return inRange; + } + + /** + * Gets a random position in the specified direction that connects to a floor currently in the tower. + */ + public BlockPos getValidOpeningCC(Random rand, EnumFacing facing) { + Rotation relative = RotationUtil.getRelativeRotation(this.getCoordBaseMode(), facing); + int floors = (this.height / 8); + + // for directions 0 or 2, the wall lies along the z axis + if (relative == Rotation.NONE || relative == Rotation.CLOCKWISE_180) { + int rx = relative == Rotation.NONE ? 12 : 0; + int rz = 6; + int ry = rand.nextInt(floors) * 8; + + return new BlockPos(rx, ry, rz); + } + + // for directions 1 or 3, the wall lies along the x axis + if (relative == Rotation.CLOCKWISE_90 || relative == Rotation.COUNTERCLOCKWISE_90) { + int rx = 6; + int rz = relative == Rotation.CLOCKWISE_90 ? 12 : 0; + int ry = rand.nextInt(floors) * 8; + + return new BlockPos(rx, ry, rz); + } + + + return new BlockPos(0, 0, 0); + } + + /** + * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. + */ + @Override + protected BlockPos offsetTowerCCoords(int x, int y, int z, int howFar, EnumFacing direction) { + + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + + switch (direction) { + case SOUTH: + dx += howFar; + break; + case WEST: + dz += howFar; + break; + case NORTH: + dx -= howFar; + break; + case EAST: + dz -= howFar; + break; + default: + break; + } + + // ugh? + return new BlockPos(dx, dy, dz); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + // walls + fillWithRandomizedBlocks(world, sbb, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1, false, rand, deco.randomBlocks); + + // stone to ground + for (int x = 0; x < this.size; x++) { + for (int z = 0; z < this.size; z++) { + this.replaceAirAndLiquidDownwards(world, deco.blockState, x, -1, z, sbb); + } + + } + + // add branching runes + int numBranches = 2 + decoRNG.nextInt(4) + +decoRNG.nextInt(3); + for (int i = 0; i < numBranches; i++) { + makeGlyphBranches(world, decoRNG, this.getGlyphColour(), sbb); + } + + // floors + addFloors(world, decoRNG, sbb); + + // openings + makeOpenings(world, sbb); + + + return true; + } + + public EnumDyeColor getGlyphColour() { + if (color == null) { + TwilightForestMod.LOGGER.warn("Final Castle tower has null for glyph color, this is a bug."); + return EnumDyeColor.BLUE; + } else { + return color; + } + } + + private void addFloors(World world, Random rand, StructureBoundingBox sbb) { + // only add floors up to highest opening + int floors = (this.highestOpening / 8) + 1; + + Rotation rotation = Rotation.CLOCKWISE_90; + for (int i = 1; i < floors; i++) { + this.fillWithBlocks(world, sbb, 1, i * 8, 1, 11, i * 8, 11, deco.blockState, deco.blockState, false); + rotation = rotation.add(Rotation.CLOCKWISE_180); + // stairs + addStairsDown(world, sbb, rotation, i * 8); + } + + if (hasAccessibleRoof()) { + // add stairs to roof + addStairsDown(world, sbb, RotationUtil.ROTATIONS[(floors + 2) & 3], this.height - 1); + } + + } + + protected boolean hasAccessibleRoof() { + return this.height - this.highestOpening < 9; + } + + private void addStairsDown(World world, StructureBoundingBox sbb, Rotation rotation, int y) { + // top flight + for (int i = 0; i < 4; i++) { + int sx = 8 - i; + int sy = y - i; + int sz = 9; + + + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), sx, sy, sz, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx, sy - 1, sz, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), sx, sy, sz - 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx, sy - 1, sz - 1, rotation, sbb); + this.fillAirRotated(world, sbb, sx, sy + 1, sz - 1, sx, sy + 3, sz, rotation); + } + // landing + this.fillBlocksRotated(world, sbb, 3, y - 4, 8, 4, y - 4, 9, deco.blockState, rotation); + + + // bottom flight + for (int i = 0; i < 4; i++) { + int sx = 4; + int sy = y - i - 4; + int sz = 7 - i; + + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), sx, sy, sz, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx, sy - 1, sz, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, false), sx - 1, sy, sz, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx - 1, sy - 1, sz, rotation, sbb); + this.fillAirRotated(world, sbb, sx, sy + 1, sz, sx - 1, sy + 3, sz, rotation); + } + + } + + /** + * Make an opening in this tower for a door. + */ + @Override + protected void makeDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { + // nullify sky light + //nullifySkyLightAtCurrentPosition(world, dx - 3, dy - 1, dz - 3, dx + 3, dy + 3, dz + 3); + + final IBlockState doorState = TFBlocks.castle_door.getDefaultState().withProperty(BlockTFCastleDoor.LOCK_INDEX, this.getGlyphColour().getMetadata() % 4); + + // clear the door + if (dx == 0 || dx == size - 1) { + this.fillWithBlocks(world, sbb, dx, dy - 1, dz - 2, dx, dy + 4, dz + 2, deco.accentState, AIR, false); + //this.fillWithAir(world, sbb, dx, dy, dz - 1, dx, dy + 3, dz + 1); + this.fillWithBlocks(world, sbb, dx, dy, dz - 1, dx, dy + 3, dz + 1, doorState, AIR, false); + } + if (dz == 0 || dz == size - 1) { + this.fillWithBlocks(world, sbb, dx - 2, dy - 1, dz, dx + 2, dy + 4, dz, deco.accentState, AIR, false); + //this.fillWithAir(world, sbb, dx - 1, dy, dz, dx + 1, dy + 3, dz); + this.fillWithBlocks(world, sbb, dx - 1, dy, dz, dx + 1, dy + 3, dz, doorState, AIR, false); + } + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMural.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMural.java new file mode 100644 index 0000000000..6064a7e56e --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleMural.java @@ -0,0 +1,242 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.Random; + +public class ComponentTFFinalCastleMural extends StructureTFComponentOld { + + private int height; + private int width; + + // we will model the mural in this byte array + private byte[][] mural; + + public ComponentTFFinalCastleMural() { + } + + public ComponentTFFinalCastleMural(TFFeature feature, Random rand, int i, int x, int y, int z, int width, int height, EnumFacing direction) { + super(feature, i); + this.setCoordBaseMode(direction); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox2(x, y, z, 0, -height / 2, -width / 2, 1, height - 1, width - 1, direction); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + this.height = this.boundingBox.getYSize(); + this.width = (this.coordBaseMode == EnumFacing.SOUTH || this.coordBaseMode == EnumFacing.NORTH) ? this.boundingBox.getZSize() : this.boundingBox.getXSize(); + + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + if (mural == null) { + // only make it once + mural = new byte[width][height]; + + int startX = width / 2 - 1; + int startY = 2; + + // make mural, fill in dot by start + for (int x = -1; x < 2; x++) { + for (int y = -1; y < 2; y++) { + mural[startX + x][startY + y] = 1; + } + } + + // side branches + makeHorizontalTree(decoRNG, mural, startX + 1, startY, decoRNG.nextInt(width / 6) + width / 6, true); + makeHorizontalTree(decoRNG, mural, startX - 1, startY, decoRNG.nextInt(width / 6) + width / 6, false); + + // main tree + makeVerticalTree(decoRNG, mural, startX, startY + 1, decoRNG.nextInt(height / 6) + height / 6, true); + + // stripes + makeStripes(decoRNG, mural); + } + + final IBlockState castleMagic = TFBlocks.castle_rune_brick.getDefaultState() + .withProperty(BlockTFCastleMagic.COLOR, BlockTFCastleMagic.VALID_COLORS.get(1)); + + // copy mural to world + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + if (mural[x][y] > 0) { + + this.setBlockState(world, castleMagic, 0, y, x, sbb); + } else { + //this.setBlockState(world, TFBlocks.forceField, 0, 0, y, x, sbb); + } + } + } + + return true; + } + + private void makeHorizontalTree(Random decoRNG, byte[][] mural, int centerX, int centerY, int branchLength, boolean positive) { + this.fillHorizontalLine(mural, centerX, centerY, branchLength, positive); + + this.makeHorizontalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, true); + this.makeHorizontalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, false); + } + + private void makeVerticalTree(Random decoRNG, byte[][] mural, int centerX, int centerY, int branchLength, boolean positive) { + this.fillVerticalLine(mural, centerX, centerY, branchLength, positive); + + this.makeVerticalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, true); + this.makeVerticalBranch(mural, decoRNG, centerX, centerY, branchLength, positive, false); + } + + private boolean makeHorizontalBranch(byte[][] mural, Random rand, int sx, int sy, int length, boolean plusX, boolean plusY) { + int downLine = (length / 2) + 1 + rand.nextInt(Math.max(length / 2, 2)); + int branchLength = rand.nextInt(width / 8) + width / 8; + + // check if the area is clear + boolean clear = true; + for (int i = 0; i <= branchLength; i++) { + int cx = sx + (plusX ? downLine - 1 + i : -(downLine - 1 + i)); + int cy = sy + (plusY ? 2 : -2); + if (cx < 0 || cx >= width || cy < 0 || cy >= height || mural[cx][cy] > 0) { + clear = false; + break; + } + } + if (clear) { + int bx = sx + (plusX ? downLine : -downLine); + int by = sy; + + // jag + this.fillVerticalLine(mural, bx, by, 1, plusY); + + by += (plusY ? 2 : -2); + + this.fillHorizontalLine(mural, bx, by, branchLength, plusX); + + // recurse? + if (bx > 0 && bx < width && by > 0 && by < height) { + if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true)) { + if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true)) { + if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true)) { + this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, true); + } + } + } + if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false)) { + if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false)) { + if (!this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false)) { + this.makeHorizontalBranch(mural, rand, bx, by, branchLength, plusX, false); + } + } + } + } + return true; + } else { + return false; + } + } + + private boolean makeVerticalBranch(byte[][] mural, Random rand, int sx, int sy, int length, boolean plusY, boolean plusX) { + int downLine = (length / 2) + 1 + rand.nextInt(Math.max(length / 2, 2)); + int branchLength = rand.nextInt(height / 8) + height / 8; + + // check if the area is clear + boolean clear = true; + for (int i = 0; i <= branchLength; i++) { + int cx = sx + (plusX ? 2 : -2); + int cy = sy + (plusY ? downLine - 1 + i : -(downLine - 1 + i)); + if (cx < 0 || cx >= width || cy < 0 || cy >= height || mural[cx][cy] > 0) { + clear = false; + break; + } + } + if (clear) { + int bx = sx; + int by = sy + (plusY ? downLine : -downLine); + ; + + // jag + this.fillHorizontalLine(mural, bx, by, 1, plusX); + + bx += (plusX ? 2 : -2); + + this.fillVerticalLine(mural, bx, by, branchLength, plusY); + + // recurse? + if (bx > 0 && bx < width && by > 0 && by < height) { + if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true)) { + if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true)) { + if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true)) { + this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, true); + } + } + } + if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false)) { + if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false)) { + if (!this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false)) { + this.makeVerticalBranch(mural, rand, bx, by, branchLength, plusY, false); + } + } + } + } + return true; + } else { + return false; + } + } + + private void fillHorizontalLine(byte[][] mural, int sx, int sy, int length, boolean positive) { + int x = sx; + int y = sy; + + for (int i = 0; i <= length; i++) { + if (x >= 0 && x < width && y >= 0 && y < height) { + mural[x][y] = (byte) (positive ? 1 : 4); + + x += positive ? 1 : -1; + } + } + } + + private void fillVerticalLine(byte[][] mural, int sx, int sy, int length, boolean positive) { + int x = sx; + int y = sy; + + for (int i = 0; i <= length; i++) { + if (x >= 0 && x < width && y >= 0 && y < height) { + mural[x][y] = (byte) (positive ? 2 : 3); + + y += positive ? 1 : -1; + } + } + } + + private void makeStripes(Random decoRNG, byte[][] mural2) { + // stagger slightly on our way down + for (int y = this.height - 2; y > this.height / 3; y -= (2 + decoRNG.nextInt(2))) { + makeSingleStripe(mural2, y); + } + } + + private void makeSingleStripe(byte[][] mural2, int y) { + for (int x = 0; x < this.width - 2; x++) { + if (mural[x + 1][y] == 0 && mural[x + 1][y + 1] == 0) { + mural[x][y] = 1; + } else { + break; + } + } + for (int x = this.width - 1; x > 2; x--) { + if (mural[x - 1][y] == 0 && mural[x - 1][y + 1] == 0) { + mural[x][y] = 1; + } else { + break; + } + } + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Conical.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Conical.java new file mode 100644 index 0000000000..0011f7a75c --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Conical.java @@ -0,0 +1,90 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +/** + * Pointy cone roof with variable height + */ +public class ComponentTFFinalCastleRoof13Conical extends StructureTFComponentOld { + + public int slope; + + public ComponentTFFinalCastleRoof13Conical() { + } + + public ComponentTFFinalCastleRoof13Conical(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, i); + + this.slope = 2 + rand.nextInt(3) + rand.nextInt(3); + + int height = slope * 4; + + this.setCoordBaseMode(sideTower.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); + + } + + @Override + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + tagCompound.setInteger("slope", this.slope); + } + + @Override + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.slope = tagCompound.getInteger("slope"); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + for (Rotation rotation : RotationUtil.ROTATIONS) { + this.fillBlocksRotated(world, sbb, 0, -1, 0, 3, 2, 3, deco.blockState, rotation); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 2, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 2, -2, 1, rotation, sbb); + + this.fillBlocksRotated(world, sbb, 4, 0, 1, 12, 1, 1, deco.blockState, rotation); + + // more teeny crenellations + for (int i = 3; i < 13; i += 2) { + this.fillBlocksRotated(world, sbb, i, -1, 1, i, 2, 1, deco.blockState, rotation); + } + + // cone roof + for (int i = 2; i < 9; i++) { + int base = 2 - slope; + if (i < 7) { + this.fillBlocksRotated(world, sbb, i - 1, ((i - 1) * slope) + base, i - 1, i, (i * slope) + base - 1, i, deco.blockState, rotation); + } else { + this.fillBlocksRotated(world, sbb, 16 - i, ((i - 1) * slope) + base, i, 16 - i, (i * slope) + base - 1, i, deco.roofState, rotation); + } + this.fillBlocksRotated(world, sbb, i + 1, ((i - 1) * slope) + base, i, 15 - i, (i * slope) + base - 1, i, deco.roofState, rotation); + } + + // point! + this.fillBlocksRotated(world, sbb, 8, (slope * 6) + 2, 8, 8, (slope * 7) + 2, 8, deco.roofState, rotation); + + } + + return true; + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Crenellated.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Crenellated.java new file mode 100644 index 0000000000..2010ca6379 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Crenellated.java @@ -0,0 +1,60 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleRoof13Crenellated extends StructureTFComponentOld { + public ComponentTFFinalCastleRoof13Crenellated() { + } + + public ComponentTFFinalCastleRoof13Crenellated(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, i); + + int height = 5; + + this.setCoordBaseMode(sideTower.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // assume square + int size = this.boundingBox.maxX - this.boundingBox.minX; + + for (Rotation rotation : RotationUtil.ROTATIONS) { + // corner + this.fillBlocksRotated(world, sbb, 0, -1, 0, 3, 3, 3, deco.blockState, rotation); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 2, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 2, -2, 1, rotation, sbb); + + // walls + this.fillBlocksRotated(world, sbb, 4, 0, 1, size - 4, 1, 1, deco.blockState, rotation); + + // smaller crenellations + for (int x = 5; x < size - 5; x += 4) { + this.fillBlocksRotated(world, sbb, x, 0, 0, x + 2, 3, 2, deco.blockState, rotation); + this.setBlockStateRotated(world, deco.blockState, x + 1, -1, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, x + 1, -2, 1, rotation, sbb); + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Peaked.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Peaked.java new file mode 100644 index 0000000000..679a0e509f --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof13Peaked.java @@ -0,0 +1,103 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleRoof13Peaked extends StructureTFComponentOld { + public ComponentTFFinalCastleRoof13Peaked() { + } + + public ComponentTFFinalCastleRoof13Peaked(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, i); + + int height = 18; + + this.setCoordBaseMode(sideTower.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + +// peaky roof, loop unrolled as it was getting dumb + for (int i = 0; i < 3; i++) { + this.fillWithBlocks(world, sbb, 1, i, i, 15, i, i, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, i, 16 - i, 15, i, 16 - i, deco.roofState, deco.roofState, false); + } + + for (int i = 0; i < 3; i++) { + int dz = 3 + i; + this.fillWithBlocks(world, sbb, 2, 5 + ((i - 1) * 2), dz, 14, 4 + (i * 2), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 1, dz, 1, 5 + ((i - 1) * 2), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 5 + ((i - 1) * 2), dz - 1, 1, 4 + (i * 2), dz, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, 15, 1, dz, 15, 5 + ((i - 1) * 2), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 15, 5 + ((i - 1) * 2), dz - 1, 15, 4 + (i * 2), dz, deco.blockState, deco.blockState, false); + + dz = 13 - i; + this.fillWithBlocks(world, sbb, 2, 5 + ((i - 1) * 2), dz, 14, 4 + (i * 2), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 1, dz, 1, 5 + ((i - 1) * 2), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 5 + ((i - 1) * 2), dz, 1, 4 + (i * 2), dz + 1, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, 15, 1, dz, 15, 5 + ((i - 1) * 2), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 15, 5 + ((i - 1) * 2), dz, 15, 4 + (i * 2), dz + 1, deco.blockState, deco.blockState, false); + } + + for (int i = 0; i < 3; i++) { + int dz = 6 + i; + this.fillWithBlocks(world, sbb, 2, 12 + ((i - 1) * 3), dz, 14, 11 + (i * 3), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 1, dz, 1, 12 + ((i - 1) * 3), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 12 + ((i - 1) * 3), dz - 1, 1, 11 + (i * 3), dz, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, 15, 1, dz, 15, 12 + ((i - 1) * 3), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 15, 12 + ((i - 1) * 3), dz - 1, 15, 11 + (i * 3), dz, deco.blockState, deco.blockState, false); + + dz = 10 - i; + this.fillWithBlocks(world, sbb, 2, 12 + ((i - 1) * 3), dz, 14, 11 + (i * 3), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 1, dz, 1, 12 + ((i - 1) * 3), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 1, 12 + ((i - 1) * 3), dz, 1, 11 + (i * 3), dz + 1, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, 15, 1, dz, 15, 12 + ((i - 1) * 3), dz, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 15, 12 + ((i - 1) * 3), dz, 15, 11 + (i * 3), dz + 1, deco.blockState, deco.blockState, false); + } + + // top roof bobbles + this.fillWithBlocks(world, sbb, 1, 18, 8, 5, 18, 8, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 11, 18, 8, 14, 18, 8, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 0, 17, 8, 1, 19, 8, deco.roofState, deco.roofState, false); + this.fillWithBlocks(world, sbb, 15, 17, 8, 16, 19, 8, deco.roofState, deco.roofState, false); + + + for (Rotation rotation : new Rotation[]{Rotation.CLOCKWISE_90, Rotation.COUNTERCLOCKWISE_90}) { + // this might be one of my more confusing instances of code recycling + this.fillBlocksRotated(world, sbb, 4, 0, 1, 12, 1, 1, deco.blockState, rotation); + // more teeny crenellations + for (int i = 3; i < 13; i += 2) { + this.fillBlocksRotated(world, sbb, i, -1, 1, i, 2, 1, deco.blockState, rotation); + } + } + + // corners + for (Rotation rotation : RotationUtil.ROTATIONS) { + this.fillBlocksRotated(world, sbb, 0, -1, 0, 3, 2, 3, deco.blockState, rotation); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 2, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 2, -2, 1, rotation, sbb); + } + + return true; + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof48Crenellated.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof48Crenellated.java new file mode 100644 index 0000000000..de55e54f9c --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof48Crenellated.java @@ -0,0 +1,58 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleRoof48Crenellated extends StructureTFComponentOld { + public ComponentTFFinalCastleRoof48Crenellated() { + } + + public ComponentTFFinalCastleRoof48Crenellated(TFFeature feature, Random rand, int i, StructureTFComponentOld keep) { + super(feature, i); + + int height = 5; + + this.setCoordBaseMode(keep.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(keep.getBoundingBox().minX - 2, keep.getBoundingBox().maxY - 1, keep.getBoundingBox().minZ - 2, keep.getBoundingBox().maxX + 2, keep.getBoundingBox().maxY + height - 1, keep.getBoundingBox().maxZ + 2); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // add second layer of floor + final IBlockState castleMagic = TFBlocks.castle_rune_brick.getDefaultState() + .withProperty(BlockTFCastleMagic.COLOR, BlockTFCastleMagic.VALID_COLORS.get(3)); + this.fillWithBlocks(world, sbb, 2, 2, 2, 50, 2, 50, castleMagic, castleMagic, false); + + // crenellations + for (Rotation rotation : RotationUtil.ROTATIONS) { + this.fillBlocksRotated(world, sbb, 3, 1, 1, 45, 3, 1, deco.blockState, rotation); + + for (int i = 10; i < 41; i += 5) { + this.fillBlocksRotated(world, sbb, i, 1, 0, i + 2, 5, 2, deco.blockState, rotation); + this.setBlockStateRotated(world, deco.blockState, i + 1, 0, 1, rotation, sbb); + } + } + + return true; + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof9Crenellated.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof9Crenellated.java new file mode 100644 index 0000000000..d8f94ee9d1 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleRoof9Crenellated.java @@ -0,0 +1,61 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleRoof9Crenellated extends StructureTFComponentOld { + public ComponentTFFinalCastleRoof9Crenellated() { + } + + public ComponentTFFinalCastleRoof9Crenellated(TFFeature feature, Random rand, int i, StructureTFComponentOld sideTower) { + super(feature, i); + + int height = 5; + + this.setCoordBaseMode(sideTower.getCoordBaseMode()); + this.boundingBox = new StructureBoundingBox(sideTower.getBoundingBox().minX - 2, sideTower.getBoundingBox().maxY - 1, sideTower.getBoundingBox().minZ - 2, sideTower.getBoundingBox().maxX + 2, sideTower.getBoundingBox().maxY + height - 1, sideTower.getBoundingBox().maxZ + 2); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + for (Rotation rotation : RotationUtil.ROTATIONS) { + this.fillBlocksRotated(world, sbb, 0, -1, 0, 2, 3, 2, deco.blockState, rotation); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 2, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 1, -2, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 2, -2, 1, rotation, sbb); + + this.setBlockStateRotated(world, deco.blockState, 3, 0, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 3, 1, 1, rotation, sbb); + + this.fillBlocksRotated(world, sbb, 4, 0, 0, 5, 3, 2, deco.blockState, rotation); + + this.setBlockStateRotated(world, deco.blockState, 6, 0, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 6, 1, 1, rotation, sbb); + + this.fillBlocksRotated(world, sbb, 7, 0, 0, 8, 3, 2, deco.blockState, rotation); + + this.setBlockStateRotated(world, deco.blockState, 9, 0, 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, 9, 1, 1, rotation, sbb); + } + + return true; + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleStairTower.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleStairTower.java new file mode 100644 index 0000000000..13bfc71544 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleStairTower.java @@ -0,0 +1,139 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleDoor; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.block.TFBlocks; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.structures.lichtower.ComponentTFTowerWing; + +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleStairTower extends ComponentTFTowerWing { + + public ComponentTFFinalCastleStairTower() { + } + + public ComponentTFFinalCastleStairTower(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i); + this.setCoordBaseMode(rotation); + this.size = 9; + this.height = 51; + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -4, 0, -4, 8, 50, 8, EnumFacing.SOUTH); + + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + // add crown + ComponentTFFinalCastleRoof9Crenellated roof = new ComponentTFFinalCastleRoof9Crenellated(getFeatureType(), rand, 4, this); + list.add(roof); + roof.buildComponent(this, list, rand); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + fillWithRandomizedBlocks(world, sbb, 0, 0, 0, 8, 49, 8, false, rand, deco.randomBlocks); + + // add branching runes + int numBranches = 6 + decoRNG.nextInt(4); + for (int i = 0; i < numBranches; i++) { + makeGlyphBranches(world, decoRNG, this.getGlyphMeta(), sbb); + } + + // beard + for (int i = 1; i < 4; i++) { + fillWithRandomizedBlocks(world, sbb, i, 0 - (i * 2), i, 8 - i, 1 - (i * 2), 8 - i, false, rand, deco.randomBlocks); + } + this.setBlockState(world, deco.blockState, 4, -7, 4, sbb); + + + // door, first floor + final IBlockState castleDoor = TFBlocks.castle_door.getDefaultState() + .withProperty(BlockTFCastleDoor.LOCK_INDEX, BlockTFCastleMagic.VALID_COLORS.indexOf(getGlyphMeta())); //TODO: WTF do I do here...? + this.fillWithBlocks(world, sbb, 0, 1, 1, 0, 3, 2, castleDoor, AIR, false); + + // stairs + Rotation rotation = Rotation.CLOCKWISE_90; + for (int f = 0; f < 5; f++) { + //int rotation = (f + 2) % 4; + rotation = rotation.add(Rotation.CLOCKWISE_90); + int y = f * 3 + 1; + for (int i = 0; i < 3; i++) { + int sx = 3 + i; + int sy = y + i; + int sz = 1; + + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), sx, sy, sz, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx, sy - 1, sz, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), sx, sy, sz + 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx, sy - 1, sz + 1, rotation, sbb); + } + // landing + this.fillBlocksRotated(world, sbb, 6, y + 2, 1, 7, y + 2, 2, deco.blockState, rotation); + } + + // door, second floor + this.fillWithBlocks(world, sbb, 1, 18, 0, 2, 20, 0, castleDoor, AIR, false); + + IBlockState stairState = getStairState(deco.stairState, EnumFacing.SOUTH, rotation, false); + + // second floor landing + this.fillWithBlocks(world, sbb, 1, 17, 1, 3, 17, 3, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, 1, 17, 4, 2, 17, 4, stairState, stairState, false); + this.fillWithBlocks(world, sbb, 1, 16, 4, 2, 16, 4, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, 1, 16, 5, 2, 16, 5, stairState, stairState, false); + this.fillWithBlocks(world, sbb, 1, 15, 5, 2, 15, 5, deco.blockState, deco.blockState, false); + + // door, roof + this.fillWithBlocks(world, sbb, 1, 39, 0, 2, 41, 0, castleDoor, AIR, false); + + // stairs + rotation = Rotation.COUNTERCLOCKWISE_90; + for (int f = 0; f < 7; f++) { + //int rotation = (f + 0) % 4; + rotation = rotation.add(Rotation.CLOCKWISE_90); + int y = f * 3 + 18; + for (int i = 0; i < 3; i++) { + int sx = 3 + i; + int sy = y + i; + int sz = 1; + + + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), sx, sy, sz, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx, sy - 1, sz, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, false), sx, sy, sz + 1, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, sx, sy - 1, sz + 1, rotation, sbb); + } + // landing + this.fillBlocksRotated(world, sbb, 6, y + 2, 1, 7, y + 2, 2, deco.blockState, rotation); + } + + // roof access landing + this.fillWithBlocks(world, sbb, 1, 38, 1, 3, 38, 5, deco.blockState, deco.blockState, false); + this.fillWithBlocks(world, sbb, 3, 39, 1, 3, 39, 5, deco.fenceState, deco.fenceState, false); + + + return true; + } + + + public EnumDyeColor getGlyphMeta() { + return BlockTFCastleMagic.VALID_COLORS.get(1); + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleWreckedTower.java b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleWreckedTower.java new file mode 100644 index 0000000000..d21da1275b --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/ComponentTFFinalCastleWreckedTower.java @@ -0,0 +1,89 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.item.EnumDyeColor; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFCastleMagic; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class ComponentTFFinalCastleWreckedTower extends ComponentTFFinalCastleDamagedTower { + public ComponentTFFinalCastleWreckedTower() { + } + + public ComponentTFFinalCastleWreckedTower(TFFeature feature, Random rand, int i, int x, int y, int z, EnumFacing direction) { + super(feature, rand, i, x, y, z, direction); + } + + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + +// // add foundation +// Foundation13 foundation = new Foundation13(rand, 4, this); +// list.add(foundation); +// foundation.buildComponent(this, list, rand); + + + // add thorns + ComponentTFFinalCastleFoundation13 thorns = new ComponentTFFinalCastleFoundation13Thorns(getFeatureType(), rand, 0, this); + list.add(thorns); + thorns.buildComponent(this, list, rand); + + +// // add roof +// StructureTFComponentOld roof = rand.nextBoolean() ? new Roof13Conical(rand, 4, this) : new Roof13Crenellated(rand, 4, this); +// list.add(roof); +// roof.buildComponent(this, list, rand); + + + // keep on building? +// this.buildNonCriticalTowers(parent, list, rand); + } + + @Override + public EnumDyeColor getGlyphColour() { + return BlockTFCastleMagic.VALID_COLORS.get(1); + } + + + @Override + protected void determineBlockDestroyed(World world, ArrayList areas, int y, int x, int z) { + boolean isInside = false; + + BlockPos pos = new BlockPos(x, y, z); + + for (DestroyArea dArea : areas) { + if (dArea != null && dArea.isVecInside(pos)) { + isInside = true; + } + } + + if (!isInside) { + world.setBlockToAir(pos); + } + + } + + + @Override + protected ArrayList makeInitialDestroyList(Random rand) { + ArrayList areas = new ArrayList(2); + + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); + areas.add(DestroyArea.createNonIntersecting(this.getBoundingBox(), rand, this.getBoundingBox().maxY - 1, areas)); + return areas; + } + + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/DestroyArea.java b/src/main/java/twilightforest/structures/finalcastle/DestroyArea.java new file mode 100644 index 0000000000..8d91214b42 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/DestroyArea.java @@ -0,0 +1,62 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.structure.StructureBoundingBox; + +import java.util.ArrayList; +import java.util.Random; + +/** + * An area that we're going to destroy. Default is just a StructureBoundingBox + */ +public class DestroyArea { + + StructureBoundingBox destroyBox; + + public DestroyArea(StructureBoundingBox tower, Random rand, int y) { + // make a 4x4 area that's entirely within the tower bounding box + + int bx = tower.minX - 2 + rand.nextInt(tower.getXSize()); + int bz = tower.minZ - 2 + rand.nextInt(tower.getZSize()); + + this.destroyBox = new StructureBoundingBox(bx, y - 10, bz, bx + 4, y, bz + 4); + } + + public boolean isEntirelyAbove(int y) { + return this.destroyBox.minY > y; + } + + public boolean isVecInside(BlockPos pos) { + return destroyBox.isVecInside(pos); + } + + /** + * construct a new area that does not intersect any other areas in the list + */ + public static DestroyArea createNonIntersecting(StructureBoundingBox tower, Random rand, int y, ArrayList otherAreas) { + int attempts = 100; + + DestroyArea area = null; + for (int i = 0; i < attempts && area == null; i++) { + DestroyArea testArea = new DestroyArea(tower, rand, y); + + if (otherAreas.size() == 0) { + area = testArea; + } else { + for (DestroyArea otherArea : otherAreas) { + if (otherArea == null || !testArea.intersectsWith(otherArea)) { + area = testArea; + } + } + } + } + return area; + } + + /** + * We check if the box would intersect even if it was one block larger in the x and z directions + */ + private boolean intersectsWith(DestroyArea otherArea) { + return this.destroyBox.intersectsWith(otherArea.destroyBox.minX - 1, otherArea.destroyBox.minZ - 1, otherArea.destroyBox.maxX + 1, otherArea.destroyBox.maxX + 1); + } +} diff --git a/src/main/java/twilightforest/structures/finalcastle/StructureTFCastleBlocks.java b/src/main/java/twilightforest/structures/finalcastle/StructureTFCastleBlocks.java new file mode 100644 index 0000000000..7355f89ec1 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/StructureTFCastleBlocks.java @@ -0,0 +1,33 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.init.Blocks; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.block.BlockTFCastleBlock; +import twilightforest.block.TFBlocks; +import twilightforest.enums.CastleBrickVariant; + +import java.util.Random; + +public class StructureTFCastleBlocks extends StructureComponent.BlockSelector { + + @Override + public void selectBlocks(Random random, int x, int y, int z, boolean isWall) { + if (!isWall) { + blockstate = Blocks.AIR.getDefaultState(); + } else { + float randFloat = random.nextFloat(); + CastleBrickVariant variant = null; + + if (randFloat < 0.1F) { + variant = CastleBrickVariant.WORN; + } else if (randFloat < 0.2F) { + variant = CastleBrickVariant.CRACKED; + } else { + variant = CastleBrickVariant.NORMAL; + } + + blockstate = TFBlocks.castle_brick.getDefaultState().withProperty(BlockTFCastleBlock.VARIANT, variant); + } + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/StructureTFDecoratorCastle.java b/src/main/java/twilightforest/structures/finalcastle/StructureTFDecoratorCastle.java new file mode 100644 index 0000000000..3743def290 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/StructureTFDecoratorCastle.java @@ -0,0 +1,24 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.block.BlockQuartz; +import net.minecraft.init.Blocks; +import twilightforest.block.BlockTFCastleBlock; +import twilightforest.block.BlockTFCastlePillar; +import twilightforest.block.TFBlocks; +import twilightforest.enums.CastleBrickVariant; +import twilightforest.enums.CastlePillarVariant; +import twilightforest.structures.StructureTFDecorator; + +public class StructureTFDecoratorCastle extends StructureTFDecorator { + + public StructureTFDecoratorCastle() { + this.blockState = TFBlocks.castle_brick.getDefaultState(); + this.accentState = Blocks.QUARTZ_BLOCK.getDefaultState().withProperty(BlockQuartz.VARIANT, BlockQuartz.EnumType.CHISELED); + this.roofState = TFBlocks.castle_brick.getDefaultState().withProperty(BlockTFCastleBlock.VARIANT, CastleBrickVariant.ROOF); + this.pillarState = TFBlocks.castle_pillar.getDefaultState().withProperty(BlockTFCastlePillar.VARIANT, CastlePillarVariant.BOLD); + this.fenceState = Blocks.OAK_FENCE.getDefaultState(); + this.stairState = TFBlocks.castle_stairs_brick.getDefaultState(); + this.randomBlocks = new StructureTFCastleBlocks(); + } + +} diff --git a/src/main/java/twilightforest/structures/finalcastle/TFFinalCastlePieces.java b/src/main/java/twilightforest/structures/finalcastle/TFFinalCastlePieces.java new file mode 100644 index 0000000000..ee250e8fb2 --- /dev/null +++ b/src/main/java/twilightforest/structures/finalcastle/TFFinalCastlePieces.java @@ -0,0 +1,39 @@ +package twilightforest.structures.finalcastle; + +import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartFinalCastle; + +public class TFFinalCastlePieces { + public static void registerFinalCastlePieces() { + MapGenStructureIO.registerStructure(StructureStartFinalCastle.class, "TFFC"); + + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleMain.class, "TFFCMain"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleStairTower.class, "TFFCStTo"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleLargeTower.class, "TFFCLaTo"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleMural.class, "TFFCMur"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleFoundation48.class, "TFFCToF48"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleRoof48Crenellated.class, "TFFCRo48Cr"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleBossGazebo.class, "TFFCBoGaz"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleMazeTower13.class, "TFFCSiTo"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleDungeonSteps.class, "TFFCDunSt"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleDungeonEntrance.class, "TFFCDunEn"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleDungeonRoom31.class, "TFFCDunR31"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleDungeonExit.class, "TFFCDunEx"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleDungeonForgeRoom.class, "TFFCDunBoR"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleRoof9Crenellated.class, "TFFCRo9Cr"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleRoof13Crenellated.class, "TFFCRo13Cr"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleRoof13Conical.class, "TFFCRo13Con"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleRoof13Peaked.class, "TFFCRo13Pk"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleEntranceTower.class, "TFFCEnTo"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleEntranceSideTower.class, "TFFCEnSiTo"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleEntranceBottomTower.class, "TFFCEnBoTo"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleEntranceStairs.class, "TFFCEnSt"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleBellTower21.class, "TFFCBelTo"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleBridge.class, "TFFCBri"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleFoundation13.class, "TFFCToF13"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleBellFoundation21.class, "TFFCBeF21"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleFoundation13Thorns.class, "TFFCFTh21"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleDamagedTower.class, "TFFCDamT"); + MapGenStructureIO.registerStructureComponent(ComponentTFFinalCastleWreckedTower.class, "TFFCWrT"); + } +} diff --git a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLargeBranch.java b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLargeBranch.java index 10ed21efc1..aef0219054 100644 --- a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLargeBranch.java +++ b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLargeBranch.java @@ -1,18 +1,23 @@ package twilightforest.structures.hollowtree; -import java.util.List; -import java.util.Random; - -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenerator; +import twilightforest.world.feature.TFGenerator; + +import java.util.List; +import java.util.Random; + +import static net.minecraft.block.BlockLog.LOG_AXIS; public class ComponentTFHollowTreeLargeBranch extends ComponentTFHollowTreeMedBranch { - + private static final int LEAF_DUNGEON_CHANCE = 8; public boolean hasLeafDungeon = false; @@ -20,107 +25,100 @@ public ComponentTFHollowTreeLargeBranch() { super(); } - protected ComponentTFHollowTreeLargeBranch(int i, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { - super(i, sx, sy, sz, length, angle, tilt, leafy); + protected ComponentTFHollowTreeLargeBranch(TFFeature feature, int i, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { + super(feature, i, sx, sy, sz, length, angle, tilt, leafy); } - + /** * Add other structure components to this one if needed */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random rand) { + public void buildComponent(StructureComponent structurecomponent, List list, Random rand) { int index = getComponentType(); + this.hasLeafDungeon = (rand.nextInt(LEAF_DUNGEON_CHANCE) == 0); + + if (this.hasLeafDungeon) { + // go 1-2 blocks past the end of the branch + BlockPos dpos = TFGenerator.translate(this.dest, 2, this.angle, this.tilt); + makeLeafDungeon(list, rand, index + 1, dpos); + } + // go about halfway out and make a few medium branches. // the number of medium branches we can support depends on the length of the big branch // every other branch switches sides - int numMedBranches = rand.nextInt((int)(length / 6)) + (int)(length / 8); - - for(int i = 0; i <= numMedBranches; i++) { - + int numMedBranches = rand.nextInt((int) (length / 6)) + (int) (length / 8); + + for (int i = 0; i <= numMedBranches; i++) { + double outVar = (rand.nextDouble() * 0.3) + 0.3; double angleVar = rand.nextDouble() * 0.225 * ((i & 1) == 0 ? 1.0 : -1.0); - ChunkCoordinates bsrc = TFGenerator.translateCoords(src.posX, src.posY, src.posZ, length * outVar, angle, tilt); - - makeMedBranch(list, rand, index + 2 + i, bsrc.posX, bsrc.posY, bsrc.posZ, length * 0.6, angle + angleVar, tilt, leafy); - } - -// // make 1-2 small ones near the base -// int numSmallBranches = rand.nextInt(2) + 1; -// for(int i = 0; i <= numSmallBranches; i++) { -// -// double outVar = (rand.nextDouble() * 0.25) + 0.25; -// double angleVar = rand.nextDouble() * 0.25 * ((i & 1) == 0 ? 1.0 : -1.0); -// ChunkCoordinates bsrc = TFGenerator.translateCoords(src.posX, src.posY, src.posZ, length * outVar, angle, tilt); -// -// makeSmallBranch(list, rand, index + numMedBranches + 1 + i, bsrc.posX, bsrc.posY, bsrc.posZ, Math.max(length * 0.3, 2), angle + angleVar, tilt, leafy); -// } - - this.hasLeafDungeon = (rand.nextInt(LEAF_DUNGEON_CHANCE) == 0); - - if (this.hasLeafDungeon) - { - makeLeafDungeon(list, rand, index + 1, dest.posX, dest.posY, dest.posZ); - } + BlockPos bsrc = TFGenerator.translate(src, length * outVar, angle, tilt); + makeMedBranch(list, rand, index + 2 + i, bsrc.getX(), bsrc.getY(), bsrc.getZ(), length * 0.6, angle + angleVar, tilt, leafy); + } } - - public void makeLeafDungeon(List list, Random rand, int index, int x, int y, int z) { - ComponentTFHollowTreeLeafDungeon dungeon = new ComponentTFHollowTreeLeafDungeon(index, x, y, z, 4); - list.add(dungeon); - dungeon.buildComponent(this, list, rand); + + public void makeLeafDungeon(List list, Random rand, int index, BlockPos pos) { + ComponentTFHollowTreeLeafDungeon dungeon = new ComponentTFHollowTreeLeafDungeon(getFeatureType(), index, pos.getX(), pos.getY(), pos.getZ(), 4); + list.add(dungeon); + dungeon.buildComponent(this, list, rand); } - - public void makeMedBranch(List list, Random rand, int index, int x, int y, int z, double branchLength, double branchRotation, double branchAngle, boolean leafy) { - ComponentTFHollowTreeMedBranch branch = new ComponentTFHollowTreeMedBranch(index, x, y, z, branchLength, branchRotation, branchAngle, leafy); - list.add(branch); - branch.buildComponent(this, list, rand); + + public void makeMedBranch(List list, Random rand, int index, int x, int y, int z, double branchLength, double branchRotation, double branchAngle, boolean leafy) { + ComponentTFHollowTreeMedBranch branch = new ComponentTFHollowTreeMedBranch(getFeatureType(), index, x, y, z, branchLength, branchRotation, branchAngle, leafy); + if (!branchIntersectsDungeon(branch, list)) + { + list.add(branch); + branch.buildComponent(this, list, rand); + } } - -// public void makeSmallBranch(List list, Random rand, int index, int x, int y, int z, double branchLength, double branchRotation, double branchAngle, boolean leafy) { -// ComponentTFHollowTreeSmallBranch branch = new ComponentTFHollowTreeSmallBranch(index, x, y, z, branchLength, branchRotation, branchAngle, leafy); -// list.add(branch); -// branch.buildComponent(this, list, rand); -// } - - /** - * Draw this branch - */ @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - - ChunkCoordinates rsrc = new ChunkCoordinates(src.posX - boundingBox.minX, src.posY - boundingBox.minY, src.posZ - boundingBox.minZ); - ChunkCoordinates rdest = new ChunkCoordinates(dest.posX - boundingBox.minX, dest.posY - boundingBox.minY, dest.posZ - boundingBox.minZ); - - // main branch - drawBresehnam(world, sbb, rsrc.posX, rsrc.posY, rsrc.posZ, rdest.posX, rdest.posY, rdest.posZ, TFBlocks.log, 12); - - // reinforce it - int reinforcements = 4; - for(int i = 0; i <= reinforcements; i++) { - int vx = (i & 2) == 0 ? 1 : 0; - int vy = (i & 1) == 0 ? 1 : -1; - int vz = (i & 2) == 0 ? 0 : 1; - drawBresehnam(world, sbb, rsrc.posX + vx, rsrc.posY + vy, rsrc.posZ + vz, rdest.posX, rdest.posY, rdest.posZ, TFBlocks.log, 12); + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) + { + return this.addComponentParts(world, random, sbb, false); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb, boolean drawLeaves) { + + BlockPos rsrc = src.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); + BlockPos rdest = dest.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); + + if (!drawLeaves) + { + // main branch + final IBlockState defaultState = TFBlocks.twilight_log.getDefaultState(); + drawBresehnam(world, sbb, rsrc.getX(), rsrc.getY(), rsrc.getZ(), rdest.getX(), rdest.getY(), rdest.getZ(), defaultState.withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE)); + + // reinforce it + int reinforcements = 4; + for (int i = 0; i <= reinforcements; i++) + { + int vx = (i & 2) == 0 ? 1 : 0; + int vy = (i & 1) == 0 ? 1 : -1; + int vz = (i & 2) == 0 ? 0 : 1; + drawBresehnam(world, sbb, rsrc.getX() + vx, rsrc.getY() + vy, rsrc.getZ() + vz, rdest.getX(), rdest.getY(), rdest.getZ(), defaultState.withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE)); + } } - + // make 1-2 small branches near the base Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); int numSmallBranches = decoRNG.nextInt(2) + 1; - for(int i = 0; i <= numSmallBranches; i++) { - + for (int i = 0; i <= numSmallBranches; i++) { + double outVar = (decoRNG.nextFloat() * 0.25F) + 0.25F; double angleVar = decoRNG.nextFloat() * 0.25F * ((i & 1) == 0 ? 1.0F : -1.0F); - ChunkCoordinates bsrc = TFGenerator.translateCoords(rsrc.posX, rsrc.posY, rsrc.posZ, length * outVar, angle, tilt); - - drawSmallBranch(world, sbb, bsrc.posX, bsrc.posY, bsrc.posZ, Math.max(length * 0.3F, 2F), angle + angleVar, tilt, leafy); + BlockPos bsrc = TFGenerator.translate(rsrc, length * outVar, angle, tilt); + + drawSmallBranch(world, sbb, bsrc.getX(), bsrc.getY(), bsrc.getZ(), Math.max(length * 0.3F, 2F), angle + angleVar, tilt, drawLeaves); } - if (leafy && !this.hasLeafDungeon) { + if (drawLeaves && !this.hasLeafDungeon) { // leaf blob at the end - makeLeafBlob(world, sbb, rdest.posX, rdest.posY, rdest.posZ, 3); + makeLeafBlob(world, sbb, rdest.getX(), rdest.getY(), rdest.getZ(), 3); } return true; diff --git a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLeafDungeon.java b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLeafDungeon.java index f80c91cf1f..23ba948f49 100644 --- a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLeafDungeon.java +++ b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeLeafDungeon.java @@ -1,61 +1,60 @@ package twilightforest.structures.hollowtree; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityList; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFLog; import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; -import twilightforest.structures.StructureTFComponent; +import twilightforest.entity.EntityTFSwarmSpider; +import java.util.Random; /** - * A blob of leaves used to make trees - * - * @author Ben + * A blob of leaves used to make trees * + * @author Ben */ -public class ComponentTFHollowTreeLeafDungeon extends StructureTFComponent { - - int radius; // radius +public class ComponentTFHollowTreeLeafDungeon extends StructureTFTreeComponent +{ + int radius; - public ComponentTFHollowTreeLeafDungeon() { super(); } /** * Make a blob of leaves - * + * * @param index * @param x * @param y * @param z * @param radius */ - protected ComponentTFHollowTreeLeafDungeon(int index, int x, int y, int z, int radius) { - super(index); - - this.setCoordBaseMode(0); - + protected ComponentTFHollowTreeLeafDungeon(TFFeature feature, int index, int x, int y, int z, int radius) { + super(feature, index); + this.setCoordBaseMode(EnumFacing.SOUTH); boundingBox = new StructureBoundingBox(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius); this.radius = radius; } - + + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("leafRadius", this.radius); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("leafRadius", this.radius); } @@ -63,89 +62,74 @@ protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); - this.radius = par1NBTTagCompound.getInteger("leafRadius"); + this.radius = tagCompound.getInteger("leafRadius"); } - - /** - * Add other structure components to this one if needed - */ + @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random rand) { - // the bounding box should be cubical, so we can rotate freely - this.setCoordBaseMode(rand.nextInt(4)); + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) + { + return this.addComponentParts(world, random, sbb, false); } - /** - * Draw a giant blob of whatevs (okay, it's going to be leaves). - */ @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - - // leaves on the outside - drawBlockBlob(world, sbb, radius, radius, radius, 4, TFBlocks.leaves, 0, true); - // then wood - drawBlockBlob(world, sbb, radius, radius, radius, 3, TFBlocks.log, 12, false); - // then air - drawBlockBlob(world, sbb, radius, radius, radius, 2, Blocks.air, 0, false); - - // then treasure chest - // which direction is this chest in? - this.placeTreasureAtCurrentPosition(world, rand, radius + 2, radius - 1, radius, TFTreasure.tree_cache, sbb); - - // then spawner - placeSpawnerAtCurrentPosition(world, rand, radius, radius, radius, TFCreatures.getSpawnerNameFor("Swarm Spider"), sbb); - + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb, boolean drawLeaves) { + if (!drawLeaves) { + // wood + drawHollowBlob(world, sbb, radius, radius, radius, 3, 2, TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.NONE), false); + // then treasure chest + // which direction is this chest in? + this.placeTreasureAtCurrentPosition(world, random, radius + 2, radius - 1, radius, TFTreasure.tree_cache, sbb); + + // then spawner + setSpawner(world, radius, radius, radius, sbb, EntityList.getKey(EntityTFSwarmSpider.class)); + } else { + // hollow sphere of leaves on the outside + drawHollowBlob(world, sbb, radius, radius, radius, 4, 2, TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false), true); + } return true; } - private void drawBlockBlob(World world, StructureBoundingBox sbb, int sx, int sy, int sz, int blobRadius, Block blockID, int metadata, boolean isLeaves) { + private void drawHollowBlob(World world, StructureBoundingBox sbb, int sx, int sy, int sz, int blobRadius, int hollowRadius, IBlockState blockState, boolean isLeaves) { // then trace out a quadrant - for (byte dx = 0; dx <= blobRadius; dx++) - { - for (byte dy = 0; dy <= blobRadius; dy++) - { - for (byte dz = 0; dz <= blobRadius; dz++) - { + for (byte dx = 0; dx <= blobRadius; dx++) { + for (byte dy = 0; dy <= blobRadius; dy++) { + for (byte dz = 0; dz <= blobRadius; dz++) { // determine how far we are from the center. byte dist = 0; if (dx >= dy && dx >= dz) { - dist = (byte) (dx + (byte)((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); - } else if (dy >= dx && dy >= dz) - { - dist = (byte) (dy + (byte)((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); + dist = (byte) (dx + (byte) ((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); + } else if (dy >= dx && dy >= dz) { + dist = (byte) (dy + (byte) ((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); } else { - dist = (byte) (dz + (byte)((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); + dist = (byte) (dz + (byte) ((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); } // if we're inside the blob, fill it - if (dist <= blobRadius) { + if (dist > hollowRadius && dist <= blobRadius) { // do eight at a time for easiness! - if (isLeaves) - { - placeLeafBlock(world, blockID, metadata, sx + dx, sy + dy, sz + dz, sbb); - placeLeafBlock(world, blockID, metadata, sx + dx, sy + dy, sz - dz, sbb); - placeLeafBlock(world, blockID, metadata, sx - dx, sy + dy, sz + dz, sbb); - placeLeafBlock(world, blockID, metadata, sx - dx, sy + dy, sz - dz, sbb); - placeLeafBlock(world, blockID, metadata, sx + dx, sy - dy, sz + dz, sbb); - placeLeafBlock(world, blockID, metadata, sx + dx, sy - dy, sz - dz, sbb); - placeLeafBlock(world, blockID, metadata, sx - dx, sy - dy, sz + dz, sbb); - placeLeafBlock(world, blockID, metadata, sx - dx, sy - dy, sz - dz, sbb); - } - else - { - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx + dx, sy + dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx + dx, sy + dy, sz - dz, sbb); - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx - dx, sy + dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx - dx, sy + dy, sz - dz, sbb); - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx + dx, sy - dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx + dx, sy - dy, sz - dz, sbb); - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx - dx, sy - dy, sz + dz, sbb); - this.placeBlockAtCurrentPosition(world, blockID, metadata, sx - dx, sy - dy, sz - dz, sbb); + if (isLeaves) { + placeLeafBlock(world, blockState, sx + dx, sy + dy, sz + dz, sbb); + placeLeafBlock(world, blockState, sx + dx, sy + dy, sz - dz, sbb); + placeLeafBlock(world, blockState, sx - dx, sy + dy, sz + dz, sbb); + placeLeafBlock(world, blockState, sx - dx, sy + dy, sz - dz, sbb); + placeLeafBlock(world, blockState, sx + dx, sy - dy, sz + dz, sbb); + placeLeafBlock(world, blockState, sx + dx, sy - dy, sz - dz, sbb); + placeLeafBlock(world, blockState, sx - dx, sy - dy, sz + dz, sbb); + placeLeafBlock(world, blockState, sx - dx, sy - dy, sz - dz, sbb); + } else { + this.setBlockState(world, blockState, sx + dx, sy + dy, sz + dz, sbb); + this.setBlockState(world, blockState, sx + dx, sy + dy, sz - dz, sbb); + this.setBlockState(world, blockState, sx - dx, sy + dy, sz + dz, sbb); + this.setBlockState(world, blockState, sx - dx, sy + dy, sz - dz, sbb); + this.setBlockState(world, blockState, sx + dx, sy - dy, sz + dz, sbb); + this.setBlockState(world, blockState, sx + dx, sy - dy, sz - dz, sbb); + this.setBlockState(world, blockState, sx - dx, sy - dy, sz + dz, sbb); + this.setBlockState(world, blockState, sx - dx, sy - dy, sz - dz, sbb); } @@ -154,25 +138,4 @@ private void drawBlockBlob(World world, StructureBoundingBox sbb, int sx, int sy } } } - - /** - * Puts a block only if leaves can go there. - */ - protected void placeLeafBlock(World world, Block blockID, int meta, int x, int y, int z, StructureBoundingBox sbb) { - - int offX = this.getXWithOffset(x, z); - int offY = this.getYWithOffset(y); - int offZ = this.getZWithOffset(x, z); - - if (sbb.isVecInside(offX, offY, offZ)) - { - Block whatsThere = world.getBlock(offX, offY, offZ); - - if (whatsThere == null || whatsThere.canBeReplacedByLeaves(world, offX, offY, offZ)) - { - world.setBlock(offX, offY, offZ, blockID, meta, 2); - } - } - } - } diff --git a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeMedBranch.java b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeMedBranch.java index 4d13425134..2e471bdfe4 100644 --- a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeMedBranch.java +++ b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeMedBranch.java @@ -1,78 +1,83 @@ package twilightforest.structures.hollowtree; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; -import twilightforest.world.TFGenerator; +import twilightforest.world.feature.TFGenerator; + +import java.util.List; +import java.util.Random; + +import static net.minecraft.block.BlockLog.LOG_AXIS; -public class ComponentTFHollowTreeMedBranch extends StructureTFComponent { - - ChunkCoordinates src, dest; // source and destination of branch, array of 3 ints representing x, y, z +public class ComponentTFHollowTreeMedBranch extends StructureTFTreeComponent { + + BlockPos src, dest; // source and destination of branch, array of 3 ints representing x, y, z double length; double angle; double tilt; boolean leafy; - + public ComponentTFHollowTreeMedBranch() { super(); } - protected ComponentTFHollowTreeMedBranch(int i, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { - super(i); - - this.src = new ChunkCoordinates(sx, sy, sz); - this.dest = TFGenerator.translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); + protected ComponentTFHollowTreeMedBranch(TFFeature feature, int i, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { + super(feature, i); + + this.src = new BlockPos(sx, sy, sz); + this.dest = TFGenerator.translate(src, length, angle, tilt); this.length = length; this.angle = angle; this.tilt = tilt; this.leafy = leafy; - - this.setCoordBaseMode(0); - - this.boundingBox = new StructureBoundingBox(Math.min(src.posX, dest.posX), Math.min(src.posY, dest.posY), Math.min(src.posZ, dest.posZ), Math.max(src.posX, dest.posX), Math.max(src.posY, dest.posY), Math.max(src.posZ, dest.posZ)); - + + this.setCoordBaseMode(EnumFacing.SOUTH); + + this.boundingBox = new StructureBoundingBox(src, dest); + this.boundingBox.expandTo(makeExpandedBB(0.5F, length, angle, tilt)); this.boundingBox.expandTo(makeExpandedBB(0.1F, length, 0.225, tilt)); this.boundingBox.expandTo(makeExpandedBB(0.1F, length, -0.225, tilt)); } - - private StructureBoundingBox makeExpandedBB(double outVar, double branchLength, double branchAngle, double branchTilt) - { - ChunkCoordinates branchSrc = TFGenerator.translateCoords(src.posX, src.posY, src.posZ, this.length * outVar, this.angle, this.tilt); - ChunkCoordinates branchDest = TFGenerator.translateCoords(branchSrc.posX, branchSrc.posY, branchSrc.posZ, branchLength, branchAngle, branchTilt); - - return new StructureBoundingBox(Math.min(branchSrc.posX, branchDest.posX), Math.min(branchSrc.posY, branchDest.posY), Math.min(branchSrc.posZ, branchDest.posZ), Math.max(branchSrc.posX, branchDest.posX), Math.max(branchSrc.posY, branchDest.posY), Math.max(branchSrc.posZ, branchDest.posZ)); + + private StructureBoundingBox makeExpandedBB(double outVar, double branchLength, double branchAngle, double branchTilt) { + BlockPos branchSrc = TFGenerator.translate(src, this.length * outVar, this.angle, this.tilt); + BlockPos branchDest = TFGenerator.translate(branchSrc, branchLength, branchAngle, branchTilt); + + return new StructureBoundingBox(branchSrc, branchDest); } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("srcPosX", this.src.posX); - par1NBTTagCompound.setInteger("srcPosY", this.src.posY); - par1NBTTagCompound.setInteger("srcPosZ", this.src.posZ); - par1NBTTagCompound.setInteger("destPosX", this.dest.posX); - par1NBTTagCompound.setInteger("destPosY", this.dest.posY); - par1NBTTagCompound.setInteger("destPosZ", this.dest.posZ); - par1NBTTagCompound.setDouble("branchLength", this.length); - par1NBTTagCompound.setDouble("branchAngle", this.angle); - par1NBTTagCompound.setDouble("branchTilt", this.tilt); - par1NBTTagCompound.setBoolean("branchLeafy", this.leafy); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("srcPosX", this.src.getX()); + tagCompound.setInteger("srcPosY", this.src.getY()); + tagCompound.setInteger("srcPosZ", this.src.getZ()); + tagCompound.setInteger("destPosX", this.dest.getX()); + tagCompound.setInteger("destPosY", this.dest.getY()); + tagCompound.setInteger("destPosZ", this.dest.getZ()); + tagCompound.setDouble("branchLength", this.length); + tagCompound.setDouble("branchAngle", this.angle); + tagCompound.setDouble("branchTilt", this.tilt); + tagCompound.setBoolean("branchLeafy", this.leafy); } @@ -80,138 +85,95 @@ protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - - - this.src = new ChunkCoordinates(par1NBTTagCompound.getInteger("srcPosX"), par1NBTTagCompound.getInteger("srcPosY"), par1NBTTagCompound.getInteger("srcPosZ")); - this.dest = new ChunkCoordinates(par1NBTTagCompound.getInteger("destPosX"), par1NBTTagCompound.getInteger("destPosY"), par1NBTTagCompound.getInteger("destPosZ")); - - this.length = par1NBTTagCompound.getDouble("branchLength"); - this.angle = par1NBTTagCompound.getDouble("branchAngle"); - this.tilt = par1NBTTagCompound.getDouble("branchTilt"); - this.leafy = par1NBTTagCompound.getBoolean("branchLeafy"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + + + this.src = new BlockPos(tagCompound.getInteger("srcPosX"), tagCompound.getInteger("srcPosY"), tagCompound.getInteger("srcPosZ")); + this.dest = new BlockPos(tagCompound.getInteger("destPosX"), tagCompound.getInteger("destPosY"), tagCompound.getInteger("destPosZ")); + + this.length = tagCompound.getDouble("branchLength"); + this.angle = tagCompound.getDouble("branchAngle"); + this.tilt = tagCompound.getDouble("branchTilt"); + this.leafy = tagCompound.getBoolean("branchLeafy"); } - /** - * Add a leaf ball to the end - * TODO: go back to adding more leaves if this is successful? - */ - @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random rand) { - int index = getComponentType(); - -// // with leaves! -// if (leafy) { -// int numLeafBalls = Math.min(rand.nextInt(3) + 1, (int)(length / 5)); -// for(int i = 0; i < numLeafBalls; i++) { -// -// double slength = (rand.nextDouble() * 0.6 + 0.2) * length; -// int[] bdst = TFGenerator.translate(src.posX, src.posY, src.posZ, slength, angle, tilt); -// -// //drawBlob(bdst[0], bdst[1], bdst[2], 2, leafBlock, false); -// ComponentTFLeafSphere leafBlob = new ComponentTFLeafSphere(index + 1, bdst[0], bdst[1], bdst[2], 2); -// list.add(leafBlob); -// leafBlob.buildComponent(this, list, rand); // doesn't really need to be here for leaves. -// } -// -// -// ComponentTFLeafSphere leafBlob = new ComponentTFLeafSphere(index + 1, dest.posX, dest.posY, dest.posZ, 2); -// list.add(leafBlob); -// leafBlob.buildComponent(this, list, rand); // doesn't really need to be here for leaves. -// } -// -// // and several small branches -// int numShoots = Math.min(rand.nextInt(3) + 1, (int)(length / 5)); -// double angleInc, angleVar, outVar, tiltVar; -// -// angleInc = 0.8 / numShoots; -// -// for(int i = 0; i < numShoots; i++) { -// -// angleVar = (angleInc * i) - 0.4; -// outVar = (rand.nextDouble() * 0.8) + 0.2; -// tiltVar = (rand.nextDouble() * 0.75) + 0.15; -// -// ChunkCoordinates bSrc = TFGenerator.translateCoords(src.posX, src.posY, src.posZ, length * outVar, angle, tilt); -// double slength = length * 0.4; -// -// makeSmallBranch(list, rand, index + 1, bSrc.posX, bSrc.posY, bSrc.posZ, slength, angle + angleVar, tilt * tiltVar, leafy); -// } + public void makeSmallBranch(List list, Random rand, int index, int x, int y, int z, double branchLength, double branchRotation, double branchAngle, boolean leafy) { + ComponentTFHollowTreeSmallBranch branch = new ComponentTFHollowTreeSmallBranch(getFeatureType(), index, x, y, z, branchLength, branchRotation, branchAngle, leafy); + list.add(branch); + branch.buildComponent(this, list, rand); } - - public void makeSmallBranch(List list, Random rand, int index, int x, int y, int z, double branchLength, double branchRotation, double branchAngle, boolean leafy) { - ComponentTFHollowTreeSmallBranch branch = new ComponentTFHollowTreeSmallBranch(index, x, y, z, branchLength, branchRotation, branchAngle, leafy); - list.add(branch); - branch.buildComponent(this, list, rand); + + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) + { + return this.addComponentParts(world, random, sbb, false); } - - @Override - public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) { - - ChunkCoordinates rSrc = new ChunkCoordinates(src.posX - boundingBox.minX, src.posY - boundingBox.minY, src.posZ - boundingBox.minZ); - ChunkCoordinates rDest = new ChunkCoordinates(dest.posX - boundingBox.minX, dest.posY - boundingBox.minY, dest.posZ - boundingBox.minZ); + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb, boolean drawLeaves) { -// placeVoid(world, sbb, boundingBox.minX, boundingBox.minY, boundingBox.minZ, boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ, TFBlocks.wood, 0, false); -// System.out.println("Drawing a medium branch from " + rsrc.posX + ", " + rsrc.posY + ", " + rsrc.posZ + " to " + rdest.posX + ", " + rdest.posY + ", " + rdest.posZ); -// System.out.println("My bounding box is " + boundingBox.minX + ", " + boundingBox.minY + ", " + boundingBox.minZ + " to " + boundingBox.maxX + ", " + boundingBox.maxY + ", " + boundingBox.maxZ); -// System.out.println("Draw bounding box is " + sbb.minX + ", " + sbb.minY + ", " + sbb.minZ + " to " + sbb.maxX + ", " + sbb.maxY + ", " + sbb.maxZ); + BlockPos rSrc = src.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); + BlockPos rDest = dest.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); - drawBresehnam(world, sbb, rSrc.posX, rSrc.posY, rSrc.posZ, rDest.posX, rDest.posY, rDest.posZ, TFBlocks.log, 12); - drawBresehnam(world, sbb, rSrc.posX, rSrc.posY + 1, rSrc.posZ, rDest.posX, rDest.posY, rDest.posZ, TFBlocks.log, 12); + if (!drawLeaves) + { + IBlockState log = TFBlocks.twilight_log.getDefaultState().withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE); + drawBresehnam(world, sbb, rSrc.getX(), rSrc.getY(), rSrc.getZ(), rDest.getX(), rDest.getY(), rDest.getZ(), log); + drawBresehnam(world, sbb, rSrc.getX(), rSrc.getY() + 1, rSrc.getZ(), rDest.getX(), rDest.getY(), rDest.getZ(), log); + } Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); // and several small branches - int numShoots = Math.min(decoRNG.nextInt(3) + 1, (int)(length / 5)); - double angleInc, angleVar, outVar, tiltVar; + int numShoots = Math.min(decoRNG.nextInt(3) + 1, (int) (length / 5)); + double angleInc, angleVar, outVar; angleInc = 0.8 / numShoots; - for(int i = 0; i < numShoots; i++) { + for (int i = 0; i < numShoots; i++) { angleVar = (angleInc * i) - 0.4; outVar = (decoRNG.nextDouble() * 0.8) + 0.2; - tiltVar = (decoRNG.nextDouble() * 0.75) + 0.15; - ChunkCoordinates bSrc = TFGenerator.translateCoords(rSrc.posX, rSrc.posY, rSrc.posZ, length * outVar, angle, tilt); - double slength = length * 0.4; + BlockPos bSrc = TFGenerator.translate(rSrc, length * outVar, angle, tilt); - drawSmallBranch(world, sbb, bSrc.posX, bSrc.posY, bSrc.posZ, Math.max(length * 0.3F, 2F), angle + angleVar, tilt, leafy); + drawSmallBranch(world, sbb, bSrc.getX(), bSrc.getY(), bSrc.getZ(), Math.max(length * 0.3F, 2F), angle + angleVar, tilt, drawLeaves); } - - // with leaves! - if (leafy) { - int numLeafBalls = Math.min(decoRNG.nextInt(3) + 1, (int)(length / 5)); - for(int i = 0; i < numLeafBalls; i++) { - double slength = (decoRNG.nextFloat() * 0.6F + 0.2F) * length; - ChunkCoordinates bdst = TFGenerator.translateCoords(rSrc.posX, rSrc.posY, rSrc.posZ, slength, angle, tilt); + // leaves, if we're doing that right now + if (drawLeaves) { + int numLeafBalls = Math.min(decoRNG.nextInt(3) + 1, (int) (length / 5)); + for (int i = 0; i < numLeafBalls; i++) { - makeLeafBlob(world, sbb, bdst.posX, bdst.posY, bdst.posZ, decoRNG.nextBoolean() ? 2 : 3); + double slength = (decoRNG.nextFloat() * 0.6F + 0.2F) * length; + BlockPos bdst = TFGenerator.translate(rSrc, slength, angle, tilt); + makeLeafBlob(world, sbb, bdst.getX(), bdst.getY(), bdst.getZ(), decoRNG.nextBoolean() ? 2 : 3); } - - makeLeafBlob(world, sbb, rDest.posX, rDest.posY, rDest.posZ, 3); + makeLeafBlob(world, sbb, rDest.getX(), rDest.getY(), rDest.getZ(), 3); } - return true; } - + /** * Draws a line */ - protected void drawBresehnam(World world, StructureBoundingBox sbb, int x1, int y1, int z1, int x2, int y2, int z2, Block blockValue, int metaValue) { - ChunkCoordinates lineCoords[] = TFGenerator.getBresehnamArrayCoords(x1, y1, z1, x2, y2, z2); - - for (ChunkCoordinates coords : lineCoords) - { - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, coords.posX, coords.posY, coords.posZ, sbb); + protected void drawBresehnam(World world, StructureBoundingBox sbb, int x1, int y1, int z1, int x2, int y2, int z2, IBlockState blockState) { + if (x1 == x2 && z1 == z2) { + int l = Math.max(y1, y2); + for (int i = Math.min(y1, y2); i < l; i++) { + this.setBlockState(world, blockState, x1, i, z1, sbb); + } + } else { + BlockPos lineCoords[] = TFGenerator.getBresehnamArrays(x1, y1, z1, x2, y2, z2); + + for (BlockPos coords : lineCoords) { + this.setBlockState(world, blockState, coords.getX(), coords.getY(), coords.getZ(), sbb); + } } } @@ -220,25 +182,17 @@ protected void drawBresehnam(World world, StructureBoundingBox sbb, int x1, int */ protected void makeLeafBlob(World world, StructureBoundingBox sbb, int sx, int sy, int sz, int radius) { // then trace out a quadrant - for (int dx = 0; dx <= radius; dx++) - { - for (int dy = 0; dy <= radius; dy++) - { - for (int dz = 0; dz <= radius; dz++) - { + for (int dx = 0; dx <= radius; dx++) { + for (int dy = 0; dy <= radius; dy++) { + for (int dz = 0; dz <= radius; dz++) { // determine how far we are from the center. int dist = 0; - if (dx >= dy && dx >= dz) - { + if (dx >= dy && dx >= dz) { dist = (int) (dx + ((Math.max(dy, dz) * 0.5F) + (Math.min(dy, dz) * 0.25F))); - } - else if (dy >= dx && dy >= dz) - { + } else if (dy >= dx && dy >= dz) { dist = (int) (dy + ((Math.max(dx, dz) * 0.5F) + (Math.min(dx, dz) * 0.25F))); - } - else - { + } else { dist = (int) (dz + ((Math.max(dx, dy) * 0.5F) + (Math.min(dx, dy) * 0.25F))); } @@ -246,14 +200,15 @@ else if (dy >= dx && dy >= dz) // if we're inside the blob, fill it if (dist <= radius) { // do eight at a time for easiness! - placeLeafBlock(world, TFBlocks.leaves, 0, sx + dx, sy + dy, sz + dz, sbb); - placeLeafBlock(world, TFBlocks.leaves, 0, sx + dx, sy + dy, sz - dz, sbb); - placeLeafBlock(world, TFBlocks.leaves, 0, sx - dx, sy + dy, sz + dz, sbb); - placeLeafBlock(world, TFBlocks.leaves, 0, sx - dx, sy + dy, sz - dz, sbb); - placeLeafBlock(world, TFBlocks.leaves, 0, sx + dx, sy - dy, sz + dz, sbb); - placeLeafBlock(world, TFBlocks.leaves, 0, sx + dx, sy - dy, sz - dz, sbb); - placeLeafBlock(world, TFBlocks.leaves, 0, sx - dx, sy - dy, sz + dz, sbb); - placeLeafBlock(world, TFBlocks.leaves, 0, sx - dx, sy - dy, sz - dz, sbb); + final IBlockState leaves = TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false); + placeLeafBlock(world, leaves, sx + dx, sy + dy, sz + dz, sbb); + placeLeafBlock(world, leaves, sx + dx, sy + dy, sz - dz, sbb); + placeLeafBlock(world, leaves, sx - dx, sy + dy, sz + dz, sbb); + placeLeafBlock(world, leaves, sx - dx, sy + dy, sz - dz, sbb); + placeLeafBlock(world, leaves, sx + dx, sy - dy, sz + dz, sbb); + placeLeafBlock(world, leaves, sx + dx, sy - dy, sz - dz, sbb); + placeLeafBlock(world, leaves, sx - dx, sy - dy, sz + dz, sbb); + placeLeafBlock(world, leaves, sx - dx, sy - dy, sz - dz, sbb); } } @@ -262,37 +217,21 @@ else if (dy >= dx && dy >= dz) } /** - * Puts a block only if leaves can go there. + * This is like the small branch component, but we're just drawing it directly into the world */ - protected void placeLeafBlock(World world, Block blockID, int meta, int x, int y, int z, StructureBoundingBox sbb) { - - int offX = this.getXWithOffset(x, z); - int offY = this.getYWithOffset(y); - int offZ = this.getZWithOffset(x, z); + protected void drawSmallBranch(World world, StructureBoundingBox sbb, int sx, int sy, int sz, double branchLength, double branchAngle, double branchTilt, boolean drawLeaves) { + // draw a line + BlockPos branchDest = TFGenerator.translate(new BlockPos(sx, sy, sz), branchLength, branchAngle, branchTilt); - if (sbb.isVecInside(offX, offY, offZ)) + if (!drawLeaves) { - Block whatsThere = world.getBlock(offX, offY, offZ); - - if (whatsThere == null || whatsThere.canBeReplacedByLeaves(world, offX, offY, offZ)) - { - world.setBlock(offX, offY, offZ, blockID, meta, 2); - } + IBlockState log = TFBlocks.twilight_log.getDefaultState().withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE); + drawBresehnam(world, sbb, sx, sy, sz, branchDest.getX(), branchDest.getY(), branchDest.getZ(), log); + } + else + { + makeLeafBlob(world, sbb, branchDest.getX(), branchDest.getY(), branchDest.getZ(), 2); } - } - - /** - * This is like the small branch component, but we're just drawing it directly into the world - */ - protected void drawSmallBranch(World world, StructureBoundingBox sbb, int sx, int sy, int sz, double branchLength, double branchAngle, double branchTilt, boolean leafy) { - // draw a line - ChunkCoordinates branchDest = TFGenerator.translateCoords(sx, sy, sz, branchLength, branchAngle, branchTilt); - - drawBresehnam(world, sbb, sx, sy, sz, branchDest.posX, branchDest.posY, branchDest.posZ, TFBlocks.log, 12); - - // leaf blob at the end - makeLeafBlob(world, sbb, branchDest.posX, branchDest.posY, branchDest.posZ, 2); - } diff --git a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeRoot.java b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeRoot.java index 695aac05e9..c36562b6ae 100644 --- a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeRoot.java +++ b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeRoot.java @@ -1,87 +1,86 @@ package twilightforest.structures.hollowtree; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockLog; import net.minecraft.block.material.Material; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; -import twilightforest.world.TFGenerator; +import twilightforest.world.feature.TFGenerator; -public class ComponentTFHollowTreeRoot extends ComponentTFHollowTreeMedBranch { +import java.util.Random; +import java.util.function.Predicate; - private int groundLevel = -1; +import static net.minecraft.block.BlockLog.LOG_AXIS; +public class ComponentTFHollowTreeRoot extends ComponentTFHollowTreeMedBranch { + + protected int groundLevel = -1; public ComponentTFHollowTreeRoot() { super(); } - public ComponentTFHollowTreeRoot(int i, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { - super(i, sx, sy, sz, length, angle, tilt, leafy); - this.boundingBox = new StructureBoundingBox(Math.min(src.posX, dest.posX), Math.min(src.posY, dest.posY), Math.min(src.posZ, dest.posZ), Math.max(src.posX, dest.posX), Math.max(src.posY, dest.posY), Math.max(src.posZ, dest.posZ)); + public ComponentTFHollowTreeRoot(TFFeature feature, int i, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { + super(feature, i, sx, sy, sz, length, angle, tilt, leafy); + this.boundingBox = new StructureBoundingBox(src, dest); } - @Override - public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) { - - // offset bounding box to average ground level - if (this.groundLevel < 0) - { - int rootHeight = this.boundingBox.maxY - this.boundingBox.minY; - - this.groundLevel = this.getSampledDirtLevel(world, sbb); - - if (this.groundLevel < 0) - { - return true; - } - - src.posY = this.groundLevel + 5; - - //System.out.println("Adjusting root bounding box to " + this.boundingBox.minY); - } - - ChunkCoordinates rSrc = new ChunkCoordinates(src.posX - boundingBox.minX, src.posY - boundingBox.minY, src.posZ - boundingBox.minZ); - ChunkCoordinates rDest = new ChunkCoordinates(dest.posX - boundingBox.minX, dest.posY - boundingBox.minY, dest.posZ - boundingBox.minZ); - - drawRootLine(world, sbb, rSrc.posX, rSrc.posY, rSrc.posZ, rDest.posX, rDest.posY, rDest.posZ, TFBlocks.root, 0); - drawRootLine(world, sbb, rSrc.posX, rSrc.posY - 1, rSrc.posZ, rDest.posX, rDest.posY - 1, rDest.posZ, TFBlocks.root, 0); + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb, boolean drawLeaves) { + if (!drawLeaves) { + // offset bounding box to average ground level + if (this.groundLevel < 0) { + this.groundLevel = this.findGroundLevel(world, sbb, 90, isGround); // is 90 like a good place to start? :) + + if (this.groundLevel < 0) { + return true; + } + + int dy = groundLevel + 5 - src.getY(); + src = src.add(0, dy, 0); + dest = dest.add(0, dy, 0); + } + + BlockPos rSrc = src.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); + BlockPos rDest = dest.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); + + drawRootLine(world, sbb, rSrc.getX(), rSrc.getY(), rSrc.getZ(), rDest.getX(), rDest.getY(), rDest.getZ(), TFBlocks.root.getDefaultState()); + drawRootLine(world, sbb, rSrc.getX(), rSrc.getY() - 1, rSrc.getZ(), rDest.getX(), rDest.getY() - 1, rDest.getZ(), TFBlocks.root.getDefaultState()); + } return true; } - - /** * Draws a line */ - protected void drawRootLine(World world, StructureBoundingBox sbb, int x1, int y1, int z1, int x2, int y2, int z2, Block blockValue, int metaValue) { - ChunkCoordinates lineCoords[] = TFGenerator.getBresehnamArrayCoords(x1, y1, z1, x2, y2, z2); - - for (ChunkCoordinates coords : lineCoords) - { - Block block = this.getBlockAtCurrentPosition(world, coords.posX, coords.posY, coords.posZ, sbb); - + protected void drawRootLine(World world, StructureBoundingBox sbb, int x1, int y1, int z1, int x2, int y2, int z2, IBlockState blockValue) { + BlockPos lineCoords[] = TFGenerator.getBresehnamArrays(x1, y1, z1, x2, y2, z2); + + for (BlockPos coords : lineCoords) { + IBlockState block = this.getBlockStateFromPos(world, coords.getX(), coords.getY(), coords.getZ(), sbb); + // three choices here - if (!block.isNormalCube(world, coords.posX, coords.posY, coords.posZ) || (block != null && block.getMaterial() == Material.grass)) - { + if (!block.isNormalCube() || block.getBlock() != Blocks.AIR && block.getMaterial() == Material.GRASS) { + // air, other non-solid, or grass, make wood block - this.placeBlockAtCurrentPosition(world, TFBlocks.log, 12, coords.posX, coords.posY, coords.posZ, sbb); - } - else if (block != null && block.getMaterial() == Material.wood) - { + IBlockState log = TFBlocks.twilight_log.getDefaultState().withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE); + this.setBlockState(world, log, coords.getX(), coords.getY(), coords.getZ(), sbb); + } else if (block.getBlock() != Blocks.AIR && block.getMaterial() == Material.WOOD) { // wood, do nothing - - } - else - { + } else { // solid, make root block - this.placeBlockAtCurrentPosition(world, blockValue, metaValue, coords.posX, coords.posY, coords.posZ, sbb); + this.setBlockState(world, blockValue, coords.getX(), coords.getY(), coords.getZ(), sbb); } } } + + protected static final Predicate isGround = state -> { + Material material = state.getMaterial(); + return material == Material.GROUND || material == Material.ROCK || material == Material.GRASS; + }; } diff --git a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeSmallBranch.java b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeSmallBranch.java index 2c902f236b..e16de62c6a 100644 --- a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeSmallBranch.java +++ b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeSmallBranch.java @@ -1,14 +1,17 @@ package twilightforest.structures.hollowtree; -import java.util.List; -import java.util.Random; - -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; +import java.util.Random; + +import static net.minecraft.block.BlockLog.LOG_AXIS; + public class ComponentTFHollowTreeSmallBranch extends ComponentTFHollowTreeMedBranch { @@ -17,43 +20,30 @@ public ComponentTFHollowTreeSmallBranch() { super(); } - protected ComponentTFHollowTreeSmallBranch(int i, int sx, int sy, int sz, - double length, double angle, double tilt, boolean leafy) { - super(i, sx, sy, sz, length, angle, tilt, leafy); + protected ComponentTFHollowTreeSmallBranch(TFFeature feature, int i, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { + super(feature, i, sx, sy, sz, length, angle, tilt, leafy); } - - /** - * Add a leaf ball to the end - */ - @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random rand) { -// int index = getComponentType(); -// -// if (leafy) { -// int leafRad = rand.nextInt(2) + 1; -// ComponentTFLeafSphere leafBlob = new ComponentTFLeafSphere(index + 1, dest.posX, dest.posY, dest.posZ, leafRad); -// list.add(leafBlob); -// leafBlob.buildComponent(this, list, rand); // doesn't really need to be here for leaves. -// } - } - @Override - public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) { - - ChunkCoordinates rSrc = new ChunkCoordinates(src.posX - boundingBox.minX, src.posY - boundingBox.minY, src.posZ - boundingBox.minZ); - ChunkCoordinates rDest = new ChunkCoordinates(dest.posX - boundingBox.minX, dest.posY - boundingBox.minY, dest.posZ - boundingBox.minZ); - - drawBresehnam(world, sbb, rSrc.posX, rSrc.posY, rSrc.posZ, rDest.posX, rDest.posY, rDest.posZ, TFBlocks.log, 12); - - // with leaves! - if (leafy) { - int leafRad = random.nextInt(2) + 1; - makeLeafBlob(world, sbb, rDest.posX, rDest.posY, rDest.posZ, leafRad); + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) + { + return this.addComponentParts(world, random, sbb, false); + } - } + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb, boolean drawLeaves) { + BlockPos rSrc = src.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); + BlockPos rDest = dest.add(-boundingBox.minX, -boundingBox.minY, -boundingBox.minZ); + if (!drawLeaves) + { + IBlockState log = TFBlocks.twilight_log.getDefaultState().withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE); + drawBresehnam(world, sbb, rSrc.getX(), rSrc.getY(), rSrc.getZ(), rDest.getX(), rDest.getY(), rDest.getZ(), log); + } else { + int leafRad = random.nextInt(2) + 1; + makeLeafBlob(world, sbb, rDest.getX(), rDest.getY(), rDest.getZ(), leafRad); + } return true; } diff --git a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeTrunk.java b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeTrunk.java index 4910bdfe3c..0e14b8c976 100644 --- a/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeTrunk.java +++ b/src/main/java/twilightforest/structures/hollowtree/ComponentTFHollowTreeTrunk.java @@ -1,52 +1,57 @@ package twilightforest.structures.hollowtree; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.BlockVine; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; -import twilightforest.world.TFGenerator; +import twilightforest.world.feature.TFGenerator; + +import java.util.List; +import java.util.Random; -public class ComponentTFHollowTreeTrunk extends StructureTFComponent { - +public class ComponentTFHollowTreeTrunk extends StructureTFTreeComponent { + int radius; int height; - int groundLevel = -1; + int groundLevel = -1; + + enum BranchSize {SMALL, MEDIUM, LARGE, ROOT}; public ComponentTFHollowTreeTrunk() { super(); } public ComponentTFHollowTreeTrunk(World world, Random rand, int index, int x, int y, int z) { - super(index); + super(TFFeature.NOTHING, index); height = rand.nextInt(64) + 32; - radius = rand.nextInt(4) + 1; + radius = rand.nextInt(4) + 1; + + this.setCoordBaseMode(EnumFacing.SOUTH); - this.setCoordBaseMode(0); - - boundingBox = new StructureBoundingBox(x, y, z, (x + radius * 2) + 2, y + height, (z + radius * 2) + 2); } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("trunkRadius", this.radius); - par1NBTTagCompound.setInteger("trunkHeight", this.height); - par1NBTTagCompound.setInteger("trunkGroundLevel", this.groundLevel); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("trunkRadius", this.radius); + tagCompound.setInteger("trunkHeight", this.height); + tagCompound.setInteger("trunkGroundLevel", this.groundLevel); } @@ -54,236 +59,223 @@ protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); - this.radius = par1NBTTagCompound.getInteger("trunkRadius"); - this.height = par1NBTTagCompound.getInteger("trunkHeight"); - this.groundLevel = par1NBTTagCompound.getInteger("trunkGroundLevel"); + this.radius = tagCompound.getInteger("trunkRadius"); + this.height = tagCompound.getInteger("trunkHeight"); + this.groundLevel = tagCompound.getInteger("trunkGroundLevel"); } /** * Add on the various bits and doo-dads we need to succeed */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random rand) { + public void buildComponent(StructureComponent structurecomponent, List list, Random rand) { int index = getComponentType(); // 3-5 couple branches on the way up... int numBranches = rand.nextInt(3) + 3; for (int i = 0; i <= numBranches; i++) { - int branchHeight = (int)(height * rand.nextDouble() * 0.9) + (height / 10); + int branchHeight = (int) (height * rand.nextDouble() * 0.5) + (height / 10); double branchRotation = rand.nextDouble(); makeSmallBranch(list, rand, index + i + 1, branchHeight, 4, branchRotation, 0.35D, true); } - + // build the crown buildFullCrown(list, rand, index + numBranches + 1); - + // roots // 3-5 roots at the bottom - buildBranchRing(list, rand, index, 3, 2, 6, 0, 0.75D, 0, 3, 5, 3, false); + buildBranchRing(list, rand, index, 3, 2, 6, 0.75D, 0.1,3, 5, BranchSize.ROOT, false); // several more taproots - buildBranchRing(list, rand, index, 1, 2, 8, 0, 0.9D, 0, 3, 5, 3, false); + buildBranchRing(list, rand, index, 1, 2, 8, 0.9D, 0.1,3, 5, BranchSize.ROOT, false); } - + /** * Build the crown of the tree */ - protected void buildFullCrown(List list, Random rand, int index) { + protected void buildFullCrown(List list, Random rand, int index) { int crownRadius = radius * 4 + 4; - int bvar = radius + 2; - + int minBranches = radius + 3; + // okay, let's do 3-5 main branches starting at the bottom of the crown - index += buildBranchRing(list, rand, index, height - crownRadius, 0, crownRadius, 0, 0.35D, 0, bvar, bvar + 2, 2, true); + index += buildBranchRing(list, rand, index, height - crownRadius, 4, crownRadius, 0.35, 0.1, minBranches, minBranches + 2, BranchSize.LARGE, true); // then, let's do 3-5 medium branches at the crown middle - index += buildBranchRing(list, rand, index, height - (crownRadius / 2), 0, crownRadius, 0, 0.28D, 0, bvar, bvar + 2, 1, true); - - // finally, let's do 2-4 main branches at the crown top - index += buildBranchRing(list, rand, index, height, 0, crownRadius, 0, 0.15D, 0, 2, 4, 2, true); - - // and extra finally, let's do 3-6 medium branches going straight up - index += buildBranchRing(list, rand, index, height, 0, (crownRadius / 2), 0, 0.05D, 0, bvar, bvar + 2, 1, true); + index += buildBranchRing(list, rand, index, height - (crownRadius / 2), 4, (int)(crownRadius * 0.8), 0.25,0.2, minBranches, minBranches + 2, BranchSize.MEDIUM, true); + + // finally, let's do some medium branches going straight up + index += buildBranchRing(list, rand, index, height - 2, 2, (crownRadius / 2), 0.05, 0.2, minBranches, minBranches + 2, BranchSize.MEDIUM, true); } /** * Build a ring of branches around the tree - * size 0 = small, 1 = med, 2 = large, 3 = root */ - protected int buildBranchRing(List list, Random rand, int index, int branchHeight, int heightVar, int length, int lengthVar, double tilt, double tiltVar, int minBranches, int maxBranches, int size, boolean leafy) { + protected int buildBranchRing(List list, Random rand, int index, int branchHeight, int heightVar, int length, double tilt, double tiltVar, int minBranches, int maxBranches, BranchSize size, boolean leafy) { //let's do this! int numBranches = rand.nextInt(maxBranches - minBranches + 1) + minBranches; - double branchRotation = 1.0 / numBranches; + double rotationPerBranch = 1.0 / numBranches; double branchOffset = rand.nextDouble(); - - for (int i = 0; i <= numBranches; i++) { - int dHeight; - if (heightVar > 0) { - dHeight = branchHeight - heightVar + rand.nextInt(2 * heightVar); - } else { - dHeight = branchHeight; - } - - if (size == 2) { - makeLargeBranch(list, rand, index, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); - } else if (size == 1) { - makeMedBranch(list, rand, index, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); - } else if (size == 3) { - makeRoot(list, rand, index, dHeight, length, i * branchRotation + branchOffset, tilt); - } else { - makeSmallBranch(list, rand, index, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); + double branchTilt = tilt + rand.nextDouble() * tiltVar; + + for (int i = 0; i < numBranches; i++) { + int dHeight = branchHeight - heightVar + (heightVar > 0 ? rand.nextInt(2 * heightVar) : 0); + double branchRotation = (i * rotationPerBranch) + branchOffset; + + BlockPos pos = getBranchSrc(dHeight, branchRotation); + StructureTFTreeComponent branch = branchFor(index, pos, length, branchRotation, branchTilt, leafy, size); + if (!branchIntersectsDungeon(branch, list)) + { + list.add(branch); + branch.buildComponent(this, list, rand); + } else if (size == BranchSize.LARGE || size == BranchSize.MEDIUM) { + // try at half length? + branch = branchFor(index, pos, length / 2, branchRotation, branchTilt, leafy, BranchSize.MEDIUM); + if (!branchIntersectsDungeon(branch, list)) + { + list.add(branch); + branch.buildComponent(this, list, rand); + } } } - - return numBranches; - } - - - public void makeSmallBranch(List list, Random rand, int index, int branchHeight, int branchLength, double branchRotation, double branchAngle, boolean leafy) { - ChunkCoordinates bSrc = getBranchSrc(branchHeight, branchRotation); - ComponentTFHollowTreeSmallBranch branch = new ComponentTFHollowTreeSmallBranch(index, bSrc.posX, bSrc.posY, bSrc.posZ, branchLength, branchRotation, branchAngle, leafy); - list.add(branch); - branch.buildComponent(this, list, rand); - } - public void makeMedBranch(List list, Random rand, int index, int branchHeight, int branchLength, double branchRotation, double branchAngle, boolean leafy) { - ChunkCoordinates bSrc = getBranchSrc(branchHeight, branchRotation); - ComponentTFHollowTreeMedBranch branch = new ComponentTFHollowTreeMedBranch(index, bSrc.posX, bSrc.posY, bSrc.posZ, branchLength, branchRotation, branchAngle, leafy); - list.add(branch); - branch.buildComponent(this, list, rand); + return numBranches; } - public void makeLargeBranch(List list, Random rand, int index, int branchHeight, int branchLength, double branchRotation, double branchAngle, boolean leafy) { - ChunkCoordinates bSrc = getBranchSrc(branchHeight, branchRotation); - ComponentTFHollowTreeMedBranch branch = new ComponentTFHollowTreeLargeBranch(index, bSrc.posX, bSrc.posY, bSrc.posZ, branchLength, branchRotation, branchAngle, leafy); - list.add(branch); - branch.buildComponent(this, list, rand); + public StructureTFTreeComponent branchFor(int index, BlockPos pos, int branchLength, double branchRotation, double branchAngle, boolean leafy, BranchSize size) { + switch(size) { + case LARGE: + return new ComponentTFHollowTreeLargeBranch(getFeatureType(), index, pos.getX(), pos.getY(), pos.getZ(), branchLength, branchRotation, branchAngle, leafy); + case SMALL: + default: + return new ComponentTFHollowTreeSmallBranch(getFeatureType(), index, pos.getX(), pos.getY(), pos.getZ(), branchLength, branchRotation, branchAngle, leafy); + case MEDIUM: + return new ComponentTFHollowTreeMedBranch(getFeatureType(), index, pos.getX(), pos.getY(), pos.getZ(), branchLength, branchRotation, branchAngle, leafy); + case ROOT: + return new ComponentTFHollowTreeRoot(getFeatureType(), index, pos.getX(), pos.getY(), pos.getZ(), branchLength, branchRotation, branchAngle, false); + } } - - public void makeRoot(List list, Random rand, int index, int branchHeight, int branchLength, double branchRotation, double branchAngle) { - ChunkCoordinates bSrc = getBranchSrc(branchHeight, branchRotation); - ComponentTFHollowTreeRoot branch = new ComponentTFHollowTreeRoot(index, bSrc.posX, bSrc.posY, bSrc.posZ, branchLength, branchRotation, branchAngle, false); - list.add(branch); - branch.buildComponent(this, list, rand); + public void makeSmallBranch(List list, Random rand, int index, int branchHeight, int branchLength, double branchRotation, double branchAngle, boolean leafy) { + BlockPos bSrc = getBranchSrc(branchHeight, branchRotation); + ComponentTFHollowTreeSmallBranch branch = new ComponentTFHollowTreeSmallBranch(getFeatureType(), index, bSrc.getX(), bSrc.getY(), bSrc.getZ(), branchLength, branchRotation, branchAngle, leafy); + if (!branchIntersectsDungeon(branch, list)) + { + list.add(branch); + branch.buildComponent(this, list, rand); + } } /** * Where should we start this branch? */ - private ChunkCoordinates getBranchSrc(int branchHeight, double branchRotation) { - return TFGenerator.translateCoords(boundingBox.minX + radius + 1, boundingBox.minY + branchHeight, boundingBox.minZ + radius + 1, radius, branchRotation, 0.5); + private BlockPos getBranchSrc(int branchHeight, double branchRotation) { + return TFGenerator.translate(new BlockPos(boundingBox.minX + radius + 1, boundingBox.minY + branchHeight, boundingBox.minZ + radius + 1), radius, branchRotation, 0.5); + } + + + @Override + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) + { + return this.addComponentParts(world, random, sbb, false); } /** * Generate the tree trunk */ @Override - public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) { - + public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb, boolean drawLeaves) { + // offset bounding box to average ground level - if (this.groundLevel < 0) - { - this.groundLevel = this.getAverageGroundLevel(world, sbb); + if (this.groundLevel < 0) { + this.groundLevel = this.getAverageGroundLevel(world, sbb); - if (this.groundLevel < 0) - { - return true; - } + if (this.groundLevel < 0) { + return true; + } - this.height = this.boundingBox.maxY - this.groundLevel; - this.boundingBox.minY = this.groundLevel; - } + this.height = this.boundingBox.maxY - this.groundLevel; + this.boundingBox.minY = this.groundLevel; + } int hollow = radius / 2; - - for (int dx = 0; dx <= 2 * radius; dx++) - { - for (int dz = 0; dz <= 2 * radius; dz++) - { + + for (int dx = 0; dx <= 2 * radius; dx++) { + for (int dz = 0; dz <= 2 * radius; dz++) { // determine how far we are from the center. int ax = Math.abs(dx - radius); int az = Math.abs(dz - radius); - int dist = (int)(Math.max(ax, az) + (Math.min(ax, az) * 0.5)); + int dist = (int) (Math.max(ax, az) + (Math.min(ax, az) * 0.5)); - for (int dy = 0; dy <= height; dy++) - { + for (int dy = 0; dy <= height; dy++) { // fill the body of the trunk if (dist <= radius && dist > hollow) { - this.placeBlockAtCurrentPosition(world, TFBlocks.log, 0, dx + 1, dy, dz + 1, sbb); // offset, since our BB is slightly larger than the trunk + this.setBlockState(world, TFBlocks.twilight_log.getDefaultState(), dx + 1, dy, dz + 1, sbb); // offset, since our BB is slightly larger than the trunk } } - + // fill to ground if (dist <= radius) { - this.func_151554_b(world, TFBlocks.log, 0, dx + 1, -1, dz + 1, sbb); + this.replaceAirAndLiquidDownwards(world, TFBlocks.twilight_log.getDefaultState(), dx + 1, -1, dz + 1, sbb); } - + // add vines if (dist == hollow && dx == hollow + radius) { - this.func_151554_b(world, Blocks.vine, 8, dx + 1, height, dz + 1, sbb); + this.replaceAirAndLiquidDownwards(world, Blocks.VINE.getDefaultState().withProperty(BlockVine.EAST, true), dx + 1, height, dz + 1, sbb); } } } - + // fireflies & cicadas int numInsects = random.nextInt(3 * radius) + random.nextInt(3 * radius) + 10; for (int i = 0; i <= numInsects; i++) { - int fHeight = (int)(height * random.nextDouble() * 0.9) + (height / 10); + int fHeight = (int) (height * random.nextDouble() * 0.9) + (height / 10); double fAngle = random.nextDouble(); addInsect(world, fHeight, fAngle, random, sbb); } return true; } - + /** * Add a random insect */ - protected void addInsect(World world, int fHeight, double fAngle, Random random, StructureBoundingBox sbb) - { - ChunkCoordinates bugSpot = TFGenerator.translateCoords(this.radius + 1, fHeight, this.radius + 1, this.radius + 1, fAngle, 0.5); - + protected void addInsect(World world, int fHeight, double fAngle, Random random, StructureBoundingBox sbb) { + BlockPos bugSpot = TFGenerator.translate(new BlockPos(this.radius + 1, fHeight, this.radius + 1), this.radius + 1, fAngle, 0.5); + fAngle = fAngle % 1.0; - int insectMeta = 0; - - if (fAngle > 0.875 || fAngle <= 0.125) - { - insectMeta = 3; - } - else if (fAngle > 0.125 && fAngle <= 0.375) - { - insectMeta = 1; + EnumFacing insectDirection = EnumFacing.DOWN; + + if (fAngle > 0.875 || fAngle <= 0.125) { + insectDirection = EnumFacing.SOUTH; + } else if (fAngle > 0.125 && fAngle <= 0.375) { + insectDirection = EnumFacing.EAST; + } else if (fAngle > 0.375 && fAngle <= 0.625) { + insectDirection = EnumFacing.NORTH; + } else if (fAngle > 0.625 && fAngle <= 0.875) { + insectDirection = EnumFacing.WEST; } - else if (fAngle > 0.375 && fAngle <= 0.625) - { - insectMeta = 4; - } - else if (fAngle > 0.625 && fAngle <= 0.875) - { - insectMeta = 2; - } - - addInsect(world, random.nextBoolean() ? TFBlocks.firefly : TFBlocks.cicada, insectMeta, bugSpot.posX, bugSpot.posY, bugSpot.posZ, sbb); + + final IBlockState block = (random.nextBoolean() ? TFBlocks.firefly : TFBlocks.cicada).getDefaultState(); + addInsect(world, block.withProperty(BlockDirectional.FACING, insectDirection), bugSpot.getX(), bugSpot.getY(), bugSpot.getZ(), sbb); } /** * Add an insect if we can at the position specified */ - private void addInsect(World world, Block blockID, int insectMeta, int posX, int posY, int posZ, StructureBoundingBox sbb) { - int ox = this.getXWithOffset(posX, posZ); - int oy = this.getYWithOffset(posY); - int oz = this.getZWithOffset(posX, posZ); - - if (sbb.isVecInside(ox, oy, oz) && blockID != null && blockID.canPlaceBlockAt(world, ox, oy, oz)) - { - world.setBlock(ox, oy, oz, blockID, insectMeta, 2); - } + private void addInsect(World world, IBlockState blockState, int posX, int posY, int posZ, StructureBoundingBox sbb) { + final BlockPos pos = getBlockPosWithOffset(posX, posY, posZ); + IBlockState whatsThere = world.getBlockState(pos); + + // don't overwrite wood or leaves + if (sbb.isVecInside(pos) && whatsThere == AIR && blockState.getBlock().canPlaceBlockAt(world, pos)) { + world.setBlockState(pos, blockState, 2); + } } } diff --git a/src/main/java/twilightforest/structures/hollowtree/ComponentTFLeafSphere.java b/src/main/java/twilightforest/structures/hollowtree/ComponentTFLeafSphere.java deleted file mode 100644 index 72b0a5ffe4..0000000000 --- a/src/main/java/twilightforest/structures/hollowtree/ComponentTFLeafSphere.java +++ /dev/null @@ -1,131 +0,0 @@ -package twilightforest.structures.hollowtree; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; - - -/** - * A blob of leaves used to make trees - * - * @author Ben - * - */ -public class ComponentTFLeafSphere extends StructureTFComponent { - - int radius; // radius - - - public ComponentTFLeafSphere() { - super(); - } - - /** - * Make a blob of leaves - * - * @param index - * @param x - * @param y - * @param z - * @param radius - */ - protected ComponentTFLeafSphere(int index, int x, int y, int z, int radius) { - super(index); - - this.setCoordBaseMode(0); - - boundingBox = new StructureBoundingBox(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius); - this.radius = radius; - } - - /** - * Save to NBT - */ - @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("leafRadius", this.radius); - - } - - /** - * Load from NBT - */ - @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - - this.radius = par1NBTTagCompound.getInteger("leafRadius"); - } - - /** - * Draw a giant blob of whatevs (okay, it's going to be leaves). - */ - @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - - - - int sx = radius; - int sy = radius; - int sz = radius; - - // then trace out a quadrant - for (byte dx = 0; dx <= radius; dx++) - { - for (byte dy = 0; dy <= radius; dy++) - { - for (byte dz = 0; dz <= radius; dz++) - { - // determine how far we are from the center. - byte dist = 0; - - if (dx >= dy && dx >= dz) { - dist = (byte) (dx + (byte)((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); - } else if (dy >= dx && dy >= dz) - { - dist = (byte) (dy + (byte)((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); - } else { - dist = (byte) (dz + (byte)((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); - } - - - // if we're inside the blob, fill it - if (dist <= radius) { - // do eight at a time for easiness! - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx + dx, sy + dy, sz + dz, sbb); - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx + dx, sy + dy, sz - dz, sbb); - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx - dx, sy + dy, sz + dz, sbb); - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx - dx, sy + dy, sz - dz, sbb); - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx + dx, sy - dy, sz + dz, sbb); - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx + dx, sy - dy, sz - dz, sbb); - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx - dx, sy - dy, sz + dz, sbb); - placeBlockIfEmpty(world, TFBlocks.leaves, 0, sx - dx, sy - dy, sz - dz, sbb); - - } - } - } - } - - return true; - } - - /** - * Puts a block only if the block that's there is air. - * - * TODO: This could be more efficient by combining the duplicate logic of the getBlockAtCurrentPosition and placeBlockAtCurrentPosition functions. - */ - protected void placeBlockIfEmpty(World world, Block blockID, int meta, int x, int y, int z, StructureBoundingBox sbb) { - if (getBlockAtCurrentPosition(world, x, y, z, sbb) == Blocks.air) { - placeBlockAtCurrentPosition(world, blockID, meta, x, y, z, sbb); - } - } - -} diff --git a/src/main/java/twilightforest/structures/hollowtree/StructureTFHollowTreeStart.java b/src/main/java/twilightforest/structures/hollowtree/StructureTFHollowTreeStart.java index 0b151ccb83..f3a6d90d8f 100644 --- a/src/main/java/twilightforest/structures/hollowtree/StructureTFHollowTreeStart.java +++ b/src/main/java/twilightforest/structures/hollowtree/StructureTFHollowTreeStart.java @@ -1,28 +1,48 @@ package twilightforest.structures.hollowtree; -import java.util.Random; - import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; import net.minecraft.world.gen.structure.StructureStart; import twilightforest.structures.StructureTFComponent; import twilightforest.world.TFWorld; - - +import java.util.Random; public class StructureTFHollowTreeStart extends StructureStart { - - public StructureTFHollowTreeStart() {} + + public StructureTFHollowTreeStart() { + } public StructureTFHollowTreeStart(World world, Random rand, int chunkX, int chunkZ) { int x = (chunkX << 4) + 8; int z = (chunkZ << 4) + 8; - int y = TFWorld.SEALEVEL + 1;;//world.getTopSolidOrLiquidBlock(x, z); - + int y = TFWorld.SEALEVEL + 1; + StructureTFComponent trunk = new ComponentTFHollowTreeTrunk(world, rand, 0, x, y, z); components.add(trunk); trunk.buildComponent(trunk, components, rand); - updateBoundingBox(); + updateBoundingBox(); } + /** + * Do everything except leaves before we do leaves. + */ + @Override + public void generateStructure(World worldIn, Random rand, StructureBoundingBox sbb) + { + // first wood + for (StructureComponent sc : components) { + if (sc.getBoundingBox().intersectsWith(sbb) && sc instanceof StructureTFTreeComponent) { + ((StructureTFTreeComponent)sc).addComponentParts(worldIn, rand, sbb, false); + } + } + + // now leaves + for (StructureComponent sc : components) { + if (sc.getBoundingBox().intersectsWith(sbb) && sc instanceof StructureTFTreeComponent) { + ((StructureTFTreeComponent)sc).addComponentParts(worldIn, rand, sbb, true); + } + } + } } diff --git a/src/main/java/twilightforest/structures/hollowtree/StructureTFTreeComponent.java b/src/main/java/twilightforest/structures/hollowtree/StructureTFTreeComponent.java new file mode 100644 index 0000000000..fe79e41d5a --- /dev/null +++ b/src/main/java/twilightforest/structures/hollowtree/StructureTFTreeComponent.java @@ -0,0 +1,52 @@ +package twilightforest.structures.hollowtree; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; + +public abstract class StructureTFTreeComponent extends StructureTFComponentOld +{ + public StructureTFTreeComponent() {} + + public StructureTFTreeComponent(TFFeature feature, int i) { + super(feature, i); + } + + public abstract boolean addComponentParts(World world, Random random, StructureBoundingBox sbb, boolean drawLeaves); + + /** + * Checks a potential branch bounding box to see if it intersects a leaf dungeon + */ + protected boolean branchIntersectsDungeon(StructureTFTreeComponent branch, List list) + { + for (StructureComponent component : list) { + if (component instanceof ComponentTFHollowTreeLeafDungeon && component.getBoundingBox().intersectsWith(branch.getBoundingBox())) { + return true; + } + } + // did not find intersecting dungeon + return false; + } + + /** + * Puts a block only if leaves can go there. + */ + protected void placeLeafBlock(World world, IBlockState blockState, int x, int y, int z, StructureBoundingBox sbb) { + final BlockPos pos = getBlockPosWithOffset(x, y, z); + + if (sbb.isVecInside(pos)) { + IBlockState whatsThere = world.getBlockState(pos); + + if (whatsThere.getBlock().canBeReplacedByLeaves(whatsThere, world, pos) && whatsThere.getBlock() != blockState.getBlock()) { + world.setBlockState(pos, blockState, 2); + } + } + } +} diff --git a/src/main/java/twilightforest/structures/hollowtree/TFHollowTreePieces.java b/src/main/java/twilightforest/structures/hollowtree/TFHollowTreePieces.java index 08c616cc17..0a634c68b6 100644 --- a/src/main/java/twilightforest/structures/hollowtree/TFHollowTreePieces.java +++ b/src/main/java/twilightforest/structures/hollowtree/TFHollowTreePieces.java @@ -5,14 +5,14 @@ public class TFHollowTreePieces { public static void registerPieces() { - MapGenStructureIO.func_143031_a(ComponentTFHollowTreeLargeBranch.class, "TFHTLB"); - MapGenStructureIO.func_143031_a(ComponentTFHollowTreeMedBranch.class, "TFHTMB"); - MapGenStructureIO.func_143031_a(ComponentTFHollowTreeSmallBranch.class, "TFHTSB"); - MapGenStructureIO.func_143031_a(ComponentTFHollowTreeTrunk.class, "TFHTTr"); - MapGenStructureIO.func_143031_a(ComponentTFLeafSphere.class, "TFHTLS"); - MapGenStructureIO.func_143031_a(ComponentTFHollowTreeRoot.class, "TFHTRo"); - MapGenStructureIO.func_143031_a(StructureTFHollowTreeStart.class, "TFHTLSt"); - MapGenStructureIO.func_143031_a(ComponentTFHollowTreeLeafDungeon.class, "TFHTLD"); + MapGenStructureIO.registerStructure(StructureTFHollowTreeStart.class, "TFHTLSt"); + + MapGenStructureIO.registerStructureComponent(ComponentTFHollowTreeLargeBranch.class, "TFHTLB"); + MapGenStructureIO.registerStructureComponent(ComponentTFHollowTreeMedBranch.class, "TFHTMB"); + MapGenStructureIO.registerStructureComponent(ComponentTFHollowTreeSmallBranch.class, "TFHTSB"); + MapGenStructureIO.registerStructureComponent(ComponentTFHollowTreeTrunk.class, "TFHTTr"); + MapGenStructureIO.registerStructureComponent(ComponentTFHollowTreeRoot.class, "TFHTRo"); + MapGenStructureIO.registerStructureComponent(ComponentTFHollowTreeLeafDungeon.class, "TFHTLD"); } } diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBeard.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBeard.java index efe56e8049..bae8ba9984 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBeard.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBeard.java @@ -1,55 +1,58 @@ package twilightforest.structures.icetower; -import java.util.Random; - import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerWing; -public class ComponentTFIceTowerBeard extends StructureTFComponent { +import java.util.Random; + +public class ComponentTFIceTowerBeard extends StructureTFComponentOld { protected int size; protected int height; - - public ComponentTFIceTowerBeard() {} - - public ComponentTFIceTowerBeard(int i, ComponentTFTowerWing wing) { - super(i); - + + public ComponentTFIceTowerBeard() { + } + + public ComponentTFIceTowerBeard(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i); + // same alignment this.setCoordBaseMode(wing.getCoordBaseMode()); // same size this.size = wing.size; // assuming only square towers and roofs right now. this.height = Math.round(this.size * 1.414F); - + this.deco = wing.deco; - + // just hang out at the very bottom of the tower this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX, wing.getBoundingBox().minY - this.height, wing.getBoundingBox().minZ, wing.getBoundingBox().maxX, wing.getBoundingBox().minY, wing.getBoundingBox().maxZ); } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("beardSize", this.size); - par1NBTTagCompound.setInteger("beardHeight", this.height); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("beardSize", this.size); + tagCompound.setInteger("beardHeight", this.height); } - + /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.size = par1NBTTagCompound.getInteger("beardSize"); - this.height = par1NBTTagCompound.getInteger("beardHeight"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.size = tagCompound.getInteger("beardSize"); + this.height = tagCompound.getInteger("beardHeight"); } @@ -57,21 +60,20 @@ protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { * Makes a dark tower type beard */ @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) - { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { for (int x = 0; x < this.size; x++) { for (int z = 0; z < this.size; z++) { //int rHeight = this.size - (int) MathHelper.sqrt_float(x * z); // interesting office building pattern - int rHeight = Math.round(MathHelper.sqrt_float(x * x + z * z)); + int rHeight = Math.round(MathHelper.sqrt(x * x + z * z)); //int rHeight = MathHelper.ceiling_float_int(Math.min(x * x / 9F, z * z / 9F)); - + for (int y = 0; y < rHeight; y++) { - this.placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, x, this.height - y, z, sbb); + this.setBlockState(world, deco.blockState, x, this.height - y, z, sbb); } } } - return true; + return true; } } diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBossWing.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBossWing.java index 81035f329c..2361475d86 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBossWing.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBossWing.java @@ -1,12 +1,17 @@ package twilightforest.structures.icetower; -import java.util.Random; - -import twilightforest.block.TFBlocks; -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; + +import java.util.Random; public class ComponentTFIceTowerBossWing extends ComponentTFIceTowerWing { @@ -15,83 +20,88 @@ public ComponentTFIceTowerBossWing() { // no spawns this.spawnListIndex = -1; } - - public ComponentTFIceTowerBossWing(int index, int x, int y, int z, int wingSize, int wingHeight, int direction) { - super(index, x, y, z, wingSize, wingHeight, direction); + + public ComponentTFIceTowerBossWing(TFFeature feature, int index, int x, int y, int z, int wingSize, int wingHeight, EnumFacing direction) { + super(feature, index, x, y, z, wingSize, wingHeight, direction); // no spawns this.spawnListIndex = -1; } - + + @Override protected boolean shouldHaveBase(Random rand) { return false; } - + /** * Put down planks or whatevs for a floor */ + @Override protected void placeFloor(World world, Random rand, StructureBoundingBox sbb, int floorHeight, int floor) { for (int x = 1; x < size - 1; x++) { for (int z = 1; z < size - 1; z++) { - - Block ice = rand.nextInt(4) == 0 ? Blocks.ice : Blocks.packed_ice; + + IBlockState ice = (rand.nextInt(4) == 0 ? Blocks.ICE : Blocks.PACKED_ICE).getDefaultState(); int thickness = 1 + rand.nextInt(2) + rand.nextInt(2) + rand.nextInt(2); - + for (int y = 0; y < thickness; y++) { - placeBlockAtCurrentPosition(world, ice, 0, x, (floor * floorHeight) + floorHeight - y, z, sbb); + setBlockState(world, ice, x, (floor * floorHeight) + floorHeight - y, z, sbb); } } } } - + /** * Called to decorate each floor. This is responsible for adding a ladder up, the stub of the ladder going down, then picking a theme for each floor and executing it. - * + * * @param floor * @param bottom * @param top * @param ladderUpDir - * @param laddderDownDir + * @param ladderDownDir */ - protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + @Override + protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { + Rotation r = ladderDownDir; for (int y = 0; y < 3; y++) { - int rotation = (ladderDownDir + y) % 4; - int rotation2 = (ladderDownDir + y + 2) % 4; - - placeIceStairs(world, sbb, rand, bottom + (y * 3), rotation); - placeIceStairs(world, sbb, rand, bottom + (y * 3), rotation2); - + placeIceStairs(world, sbb, rand, bottom + (y * 3), r); + placeIceStairs(world, sbb, rand, bottom + (y * 3), r.add(Rotation.CLOCKWISE_180)); + r = r.add(Rotation.CLOCKWISE_90); } - + } - private void placeIceStairs(World world, StructureBoundingBox sbb, Random rand, int y, int rotation) { - this.fillBlocksRotated(world, sbb, 8, y + 1, 1, 10, y + 1, 3, Blocks.packed_ice, 0, rotation); + private void placeIceStairs(World world, StructureBoundingBox sbb, Random rand, int y, Rotation rotation) { + final IBlockState packedIce = Blocks.PACKED_ICE.getDefaultState(); + this.fillBlocksRotated(world, sbb, 8, y + 1, 1, 10, y + 1, 3, packedIce, rotation); if (y > 1) { - this.randomlyFillBlocksRotated(world, sbb, rand, 0.5F, 8, y + 0, 1, 10, y + 0, 3, Blocks.packed_ice, 0, Blocks.air, 0, rotation); + this.randomlyFillBlocksRotated(world, sbb, rand, 0.5F, 8, y + 0, 1, 10, y + 0, 3, packedIce, AIR, rotation); } - this.fillBlocksRotated(world, sbb, 11, y + 2, 1, 13, y + 2, 3, Blocks.packed_ice, 0, rotation); - this.randomlyFillBlocksRotated(world, sbb, rand, 0.5F, 11, y + 1, 1, 13, y + 1, 3, Blocks.packed_ice, 0, Blocks.air, 0, rotation); - this.fillBlocksRotated(world, sbb, 11, y + 3, 4, 13, y + 3, 6, Blocks.packed_ice, 0, rotation); - this.randomlyFillBlocksRotated(world, sbb, rand, 0.5F, 11, y + 2, 4, 13, y + 2, 6, Blocks.packed_ice, 0, Blocks.air, 0, rotation); + this.fillBlocksRotated(world, sbb, 11, y + 2, 1, 13, y + 2, 3, packedIce, rotation); + this.randomlyFillBlocksRotated(world, sbb, rand, 0.5F, 11, y + 1, 1, 13, y + 1, 3, packedIce, AIR, rotation); + this.fillBlocksRotated(world, sbb, 11, y + 3, 4, 13, y + 3, 6, packedIce, rotation); + this.randomlyFillBlocksRotated(world, sbb, rand, 0.5F, 11, y + 2, 4, 13, y + 2, 6, packedIce, AIR, rotation); } - - protected void decorateTopFloor(World world, Random rand, int floor, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + + @Override + protected void decorateTopFloor(World world, Random rand, int floor, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { for (int x = 1; x < size - 1; x++) { for (int z = 1; z < size - 1; z++) { - - Block ice = rand.nextInt(10) == 0 ? Blocks.glowstone : Blocks.packed_ice; + + IBlockState ice = (rand.nextInt(10) == 0 ? Blocks.GLOWSTONE : Blocks.PACKED_ICE).getDefaultState(); int thickness = rand.nextInt(2) + rand.nextInt(2); - + for (int y = 0; y < thickness; y++) { - placeBlockAtCurrentPosition(world, ice, 0, x, top - 1 - y, z, sbb); + setBlockState(world, ice, x, top - 1 - y, z, sbb); } } } - - this.placeBlockRotated(world, TFBlocks.bossSpawner, 5, 7, top - 6, 7, 0, sbb); - + + final IBlockState snowQueenSpawner = TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.SNOW_QUEEN); + + this.setBlockStateRotated(world, snowQueenSpawner, 7, top - 6, 7, Rotation.NONE, sbb); + this.fillWithAir(world, sbb, 5, top - 3, 5, 9, top - 1, 9); } } diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBridge.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBridge.java index 64f6cfeff9..32000adaf0 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBridge.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerBridge.java @@ -1,15 +1,18 @@ package twilightforest.structures.icetower; -import java.util.List; -import java.util.Random; - import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; -public class ComponentTFIceTowerBridge extends StructureTFComponent { +public class ComponentTFIceTowerBridge extends StructureTFComponentOld { private int length; @@ -18,61 +21,50 @@ public ComponentTFIceTowerBridge() { super(); } - - public ComponentTFIceTowerBridge(int index, int x, int y, int z, int length, int direction) { - super(index); + + public ComponentTFIceTowerBridge(TFFeature feature, int index, int x, int y, int z, int length, EnumFacing direction) { + super(feature, index); this.length = length; this.setCoordBaseMode(direction); - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, length, 6, 5, direction); + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, length, 6, 5, direction); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("bridgeLength", this.length); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("bridgeLength", this.length); } - - /** - * Load from NBT - */ + @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.length = par1NBTTagCompound.getInteger("bridgeLength"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.length = tagCompound.getInteger("bridgeLength"); } - - @SuppressWarnings({ "rawtypes" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) - { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } } - @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { fillWithAir(world, sbb, 0, 1, 0, length, 5, 4); - + // make floor/ceiling - fillWithBlocks(world, sbb, 0, 0, 0, length, 0, 4, deco.blockID, deco.blockID, false); - fillWithBlocks(world, sbb, 0, 6, 0, length, 6, 4, deco.blockID, deco.blockID, false); - + fillWithBlocks(world, sbb, 0, 0, 0, length, 0, 4, deco.blockState, deco.blockState, false); + fillWithBlocks(world, sbb, 0, 6, 0, length, 6, 4, deco.blockState, deco.blockState, false); + // pillars for (int x = 2; x < length; x += 3) { - fillWithMetadataBlocks(world, sbb, x, 1, 0, x, 5, 0, deco.pillarID, deco.pillarMeta, deco.pillarID, deco.pillarMeta, false); - fillWithMetadataBlocks(world, sbb, x, 1, 4, x, 5, 4, deco.pillarID, deco.pillarMeta, deco.pillarID, deco.pillarMeta, false); + fillWithBlocks(world, sbb, x, 1, 0, x, 5, 0, deco.pillarState, deco.pillarState, false); + fillWithBlocks(world, sbb, x, 1, 4, x, 5, 4, deco.pillarState, deco.pillarState, false); } - + return true; } } diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerEntrance.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerEntrance.java index 1e00b9a5ec..534ec0a714 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerEntrance.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerEntrance.java @@ -1,43 +1,48 @@ package twilightforest.structures.icetower; -import java.util.List; -import java.util.Random; - -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; public class ComponentTFIceTowerEntrance extends ComponentTFIceTowerWing { - public ComponentTFIceTowerEntrance() {} + public ComponentTFIceTowerEntrance() { + } - public ComponentTFIceTowerEntrance(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); + public ComponentTFIceTowerEntrance(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - - + + + @Override protected boolean shouldHaveBase(Random rand) { return true; } - - - @SuppressWarnings({ "rawtypes", "unchecked" }) + + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - + // we should have a door where we started - addOpening(0, 1, size / 2, 2); + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); // stairs - addStairs(list, rand, this.getComponentType() + 1, this.size - 1, 1, size / 2, 0); - addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, 0, 3); - addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, this.size - 1, 1); + addStairs(list, rand, this.getComponentType() + 1, this.size - 1, 1, size / 2, Rotation.NONE); + addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, 0, Rotation.COUNTERCLOCKWISE_90); + addStairs(list, rand, this.getComponentType() + 1, this.size / 2, 1, this.size - 1, Rotation.CLOCKWISE_90); // should we build a base this.hasBase = this.shouldHaveBase(rand); @@ -49,14 +54,14 @@ public void buildComponent(StructureComponent parent, List list, Random rand) { /** * Add some stairs leading to this tower */ - private boolean addStairs(List list, Random rand, int index, int x, int y, int z, int rotation) { + private boolean addStairs(List list, Random rand, int index, int x, int y, int z, Rotation rotation) { // add door this.addOpening(x, y, z, rotation); - int direction = (getCoordBaseMode() + rotation) % 4; - ChunkCoordinates dx = offsetTowerCCoords(x, y, z, this.size, direction); + EnumFacing direction = getStructureRelativeRotation(rotation); + BlockPos dx = offsetTowerCCoords(x, y, z, this.size, direction); - ComponentTFIceTowerStairs entrance = new ComponentTFIceTowerStairs(index, dx.posX, dx.posY, dx.posZ, this.size, this.height, direction); + ComponentTFIceTowerStairs entrance = new ComponentTFIceTowerStairs(getFeatureType(), index, dx.getX(), dx.getY(), dx.getZ(), this.size, this.height, direction); list.add(entrance); entrance.buildComponent(list.get(0), list, rand); @@ -66,35 +71,36 @@ private boolean addStairs(List list, Random rand, int index, /** * Make a new wing */ - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + @Override + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { return false; } - + /** * No floors */ + @Override protected void makeFloorsForTower(World world, Random rand, StructureBoundingBox sbb) { - - decoratePillarsCornersHigh(world, rand, 0, 11, 0, sbb); + + decoratePillarsCornersHigh(world, rand, 0, 11, Rotation.NONE, sbb); } - - protected void decoratePillarsCornersHigh(World world, Random rand, int bottom, int top, int rotation, StructureBoundingBox sbb) { - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; - int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 9, bottom + 5, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 5, 7, 9, bottom + 5, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - + + protected void decoratePillarsCornersHigh(World world, Random rand, int bottom, int top, Rotation rotation, StructureBoundingBox sbb) { + final IBlockState pillarXAxis = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.X); + final IBlockState pillarZAxis = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.Z); + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 9, pillarZAxis, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 9, pillarZAxis, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 9, bottom + 5, 3, pillarXAxis, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 5, 7, 9, bottom + 5, 7, pillarXAxis, rotation); + this.fillAirRotated(world, sbb, 3, bottom + 5, 3, 7, bottom + 5, 7, rotation); - + // pillars connected only to ceiling - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 3, 3, top - 1, 3, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 5, 3, 7, top - 1, 3, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 7, 3, top - 1, 7, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 5, 7, 7, top - 1, 7, deco.pillarID, deco.pillarMeta, rotation); + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 3, 3, top - 1, 3, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 5, 3, 7, top - 1, 3, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 7, 3, top - 1, 7, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 5, 7, 7, top - 1, 7, deco.pillarState, rotation); } } diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerMain.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerMain.java index 930fe7de80..c265f539ed 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerMain.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerMain.java @@ -1,114 +1,114 @@ package twilightforest.structures.icetower; -import java.util.List; -import java.util.Random; - import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; -public class ComponentTFIceTowerMain extends ComponentTFIceTowerWing -{ +public class ComponentTFIceTowerMain extends ComponentTFIceTowerWing { public boolean hasBossWing = false; - + public ComponentTFIceTowerMain() { super(); } - public ComponentTFIceTowerMain(World world, Random rand, int index, int x, int y, int z) { - this(world, rand, index, x + SIZE, y + 40, z + SIZE, 2); + public ComponentTFIceTowerMain(TFFeature feature, World world, Random rand, int index, int x, int y, int z) { + this(feature, world, rand, index, x + SIZE, y + 40, z + SIZE, EnumFacing.NORTH); } - - public ComponentTFIceTowerMain(World world, Random rand, int index, int x, int y, int z, int rotation) { - super(index, x, y, z, SIZE, 31 + (rand.nextInt(3) * 10), rotation); + + public ComponentTFIceTowerMain(TFFeature feature, World world, Random rand, int index, int x, int y, int z, EnumFacing rotation) { + super(feature, index, x, y, z, SIZE, 31 + (rand.nextInt(3) * 10), rotation); // decorator - if (this.deco == null) - { + if (this.deco == null) { this.deco = new StructureDecoratorIceTower(); } } - - protected ComponentTFIceTowerMain(int i, int x, int y, int z, int pSize, int pHeight, int direction) - { - super(i, x, y, z, pSize, pHeight, direction); + + protected ComponentTFIceTowerMain(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("hasBossWing", this.hasBossWing); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("hasBossWing", this.hasBossWing); } /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.hasBossWing = par1NBTTagCompound.getBoolean("hasBossWing"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.hasBossWing = tagCompound.getBoolean("hasBossWing"); } - - @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { + public void buildComponent(StructureComponent parent, List list, Random rand) { super.buildComponent(parent, list, rand); - + // add entrance tower StructureBoundingBox towerBB = StructureBoundingBox.getNewBoundingBox(); - for (StructureComponent structurecomponent : (List)list) { - towerBB.expandTo(structurecomponent.getBoundingBox()); - } - - // TODO: make this more general - ChunkCoordinates myDoor = this.openings.get(0); - ChunkCoordinates entranceDoor = new ChunkCoordinates(myDoor); - - - if (myDoor.posX == 0) { - int length = this.getBoundingBox().minX - towerBB.minX; - //System.out.println("Offset for door -x = " + length); - if (length >= 0) { - entranceDoor.posX -= length; - makeEntranceBridge(list, rand, this.getComponentType() + 1, myDoor.posX, myDoor.posY, myDoor.posZ, length, 2); - } - } - if (myDoor.posX == this.size - 1) { - entranceDoor.posX += towerBB.maxX - this.getBoundingBox().maxX; - } - if (myDoor.posZ == 0) { - entranceDoor.posZ += towerBB.minZ - this.getBoundingBox().minZ; - } - if (myDoor.posX == this.size - 1) { - entranceDoor.posZ += towerBB.maxZ - this.getBoundingBox().maxZ; - } - - makeEntranceTower(list, rand, this.getComponentType() + 1, entranceDoor.posX, entranceDoor.posY, entranceDoor.posZ, SIZE, 11, this.getCoordBaseMode()); + for (StructureComponent structurecomponent : list) { + towerBB.expandTo(structurecomponent.getBoundingBox()); + } + + // TODO: make this more general + BlockPos myDoor = this.openings.get(0); + BlockPos entranceDoor = new BlockPos(myDoor); + + + if (myDoor.getX() == 0) { + int length = this.getBoundingBox().minX - towerBB.minX; + if (length >= 0) { + entranceDoor = entranceDoor.west(length); + makeEntranceBridge(list, rand, this.getComponentType() + 1, myDoor.getX(), myDoor.getY(), myDoor.getZ(), length, Rotation.CLOCKWISE_180); + } + } + if (myDoor.getX() == this.size - 1) { + entranceDoor = entranceDoor.east(towerBB.maxX - this.getBoundingBox().maxX); + } + if (myDoor.getZ() == 0) { + entranceDoor = entranceDoor.south(towerBB.minZ - this.getBoundingBox().minZ); + } + //FIXME: AtomicBlom I don't get it, should this not be getZ, and entranceDoor.north? + if (myDoor.getX() == this.size - 1) { + entranceDoor = entranceDoor.south(towerBB.maxZ - this.getBoundingBox().maxZ); + } + + makeEntranceTower(list, rand, this.getComponentType() + 1, entranceDoor.getX(), entranceDoor.getY(), entranceDoor.getZ(), SIZE, 11, this.rotation); } - private void makeEntranceBridge(List list, Random rand, int index, int x, int y, int z, int length, int rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; - ChunkCoordinates dest = offsetTowerCCoords(x, y, z, 5, direction); + private void makeEntranceBridge(List list, Random rand, int index, int x, int y, int z, int length, Rotation rotation) { + EnumFacing direction = getStructureRelativeRotation(rotation); + BlockPos dest = offsetTowerCCoords(x, y, z, 5, direction); - ComponentTFIceTowerBridge bridge = new ComponentTFIceTowerBridge(index, dest.posX, dest.posY, dest.posZ, length, direction); + ComponentTFIceTowerBridge bridge = new ComponentTFIceTowerBridge(getFeatureType(), index, dest.getX(), dest.getY(), dest.getZ(), length, direction); list.add(bridge); bridge.buildComponent(list.get(0), list, rand); } - public boolean makeEntranceTower(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; + public boolean makeEntranceTower(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - ComponentTFIceTowerWing entrance = new ComponentTFIceTowerEntrance(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFIceTowerWing entrance = new ComponentTFIceTowerEntrance(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); list.add(entrance); entrance.buildComponent(list.get(0), list, rand); diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerRoof.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerRoof.java index 5abe5ef454..051fdccd34 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerRoof.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerRoof.java @@ -1,53 +1,55 @@ package twilightforest.structures.icetower; -import java.util.Random; - -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.structures.lichtower.ComponentTFTowerRoof; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.Random; + public class ComponentTFIceTowerRoof extends ComponentTFTowerRoof { - public ComponentTFIceTowerRoof() {} - - public ComponentTFIceTowerRoof(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFIceTowerRoof() { + } + + public ComponentTFIceTowerRoof(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // same alignment this.setCoordBaseMode(wing.getCoordBaseMode()); // same size this.size = wing.size; // assuming only square towers and roofs right now. this.height = 12; - + this.deco = wing.deco; - + // just hang out at the very top of the tower makeCapBB(wing); } - + /** * Swoopy ice roof */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - + for (int x = 0; x < this.size; x++) { for (int z = 0; z < this.size; z++) { //int rHeight = this.size - (int) MathHelper.sqrt_float(x * z); // interesting office building pattern - int rHeight = Math.round(MathHelper.sqrt_float(x * x + z * z)); + int rHeight = Math.round(MathHelper.sqrt(x * x + z * z)); //int rHeight = MathHelper.ceiling_float_int(Math.min(x * x / 9F, z * z / 9F)); - + for (int y = 0; y < rHeight; y++) { - this.placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, x, y, z, sbb); + this.setBlockState(world, deco.blockState, x, y, z, sbb); } } } - + return true; } diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerStairs.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerStairs.java index 5c1be9b017..5122830320 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerStairs.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerStairs.java @@ -1,40 +1,43 @@ package twilightforest.structures.icetower; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.List; +import java.util.Random; + public class ComponentTFIceTowerStairs extends ComponentTFTowerWing { - - public ComponentTFIceTowerStairs() { } + + public ComponentTFIceTowerStairs() { + } - public ComponentTFIceTowerStairs(int index, int x, int y, int z, int size, int height, int direction) { - super(index, x, y, z, size, height, direction); + public ComponentTFIceTowerStairs(TFFeature feature, int index, int x, int y, int z, int size, int height, EnumFacing direction) { + super(feature, index, x, y, z, size, height, direction); } - @SuppressWarnings({ "rawtypes" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - + for (int x = 1; x < this.size; x++) { - + this.placeStairs(world, sbb, x, 1 - x, 5, 2); for (int z = 0; z <= x; z++) { - + if (z > 0 && z <= this.size / 2) { this.placeStairs(world, sbb, x, 1 - x, 5 - z, 2); this.placeStairs(world, sbb, x, 1 - x, 5 + z, 2); @@ -46,20 +49,21 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox } } - + } - - this.func_151554_b(world, deco.blockID, deco.blockMeta, 0, 0, 5, sbb); - + this.setBlockState(world, deco.blockState, 0, 0, 5, sbb); + + return true; } private void placeStairs(World world, StructureBoundingBox sbb, int x, int y, int z, int stairMeta) { - if (this.getBlockAtCurrentPosition(world, x, y, z, sbb).isReplaceable(world, x, y, z)) { - this.placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, x, y, z, sbb); - //this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(stairMeta), x, y, z, sbb); - this.func_151554_b(world, deco.blockID, deco.blockMeta, x, y - 1, z, sbb); + BlockPos pos = new BlockPos(x, y, z); + if (this.getBlockStateFromPos(world, x, y, z, sbb).getBlock().isReplaceable(world, pos)) { + this.setBlockState(world, deco.blockState, x, y, z, sbb); + //this.setBlockState(world, deco.stairID, this.getStairMeta(stairMeta), x, y, z, sbb); + this.setBlockState(world, deco.blockState, x, y - 1, z, sbb); } } } diff --git a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerWing.java b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerWing.java index 2098268095..d313bc0858 100644 --- a/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerWing.java +++ b/src/main/java/twilightforest/structures/icetower/ComponentTFIceTowerWing.java @@ -1,109 +1,113 @@ package twilightforest.structures.icetower; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import twilightforest.util.RotationUtil; -public class ComponentTFIceTowerWing extends ComponentTFTowerWing -{ +import java.util.List; +import java.util.Random; + +public class ComponentTFIceTowerWing extends ComponentTFTowerWing { protected static final int SIZE = 11; private static final int RANGE = (int) (SIZE * 1.6F); - + boolean hasBase = false; - protected int treasureFloor = -1; + protected int treasureFloor = -1; public ComponentTFIceTowerWing() { super(); } - protected ComponentTFIceTowerWing(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); + protected ComponentTFIceTowerWing(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("hasBase", this.hasBase); - par1NBTTagCompound.setInteger("treasureFloor", this.treasureFloor); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("hasBase", this.hasBase); + tagCompound.setInteger("treasureFloor", this.treasureFloor); } /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.hasBase = par1NBTTagCompound.getBoolean("hasBase"); - this.treasureFloor = par1NBTTagCompound.getInteger("treasureFloor"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.hasBase = tagCompound.getBoolean("hasBase"); + this.treasureFloor = tagCompound.getInteger("treasureFloor"); } - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - + // we should have a door where we started - addOpening(0, 1, size / 2, 2); - + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); + // should we build a base this.hasBase = this.shouldHaveBase(rand); - + // limit sprawl to a reasonable amount if (this.getComponentType() < 5) { - - int dirOffset = rand.nextInt(4); - + + Rotation dirOffset = RotationUtil.ROTATIONS[rand.nextInt(RotationUtil.ROTATIONS.length)]; + // make sub towers - for (int i = 0; i < 4; i++) { - - int dir = (dirOffset + i) % 4; - + for (final Rotation rotation : RotationUtil.ROTATIONS) { + + Rotation dir = dirOffset.add(rotation); + // if (rand.nextInt(6) < this.getComponentType()) // { // continue; // } - + int[] dest = getValidOpening(rand, dir); - if (this.getComponentType() == 4 && (parent instanceof ComponentTFIceTowerMain) && !((ComponentTFIceTowerMain)parent).hasBossWing) { - //System.out.println("Making boss tower"); + if (this.getComponentType() == 4 && (parent instanceof ComponentTFIceTowerMain) && !((ComponentTFIceTowerMain) parent).hasBossWing) { boolean hasBoss = makeBossTowerWing(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], 15, 41, dir); - ((ComponentTFIceTowerMain)parent).hasBossWing = hasBoss; + ((ComponentTFIceTowerMain) parent).hasBossWing = hasBoss; } else { int childHeight = (rand.nextInt(2) + rand.nextInt(2) + 2) * 10 + 1; makeTowerWing(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], SIZE, childHeight, dir); } } } - + // figure out where the treasure goes int floors = this.height / 10; - + // set treasure to a floor if we need to if (this.treasureFloor == -1 && floors > 1) { this.treasureFloor = rand.nextInt(floors - 1); } - + // add a roof? makeARoof(parent, list, rand); - + // beard? if (!this.hasBase) { makeABeard(parent, list, rand); @@ -119,31 +123,28 @@ protected boolean shouldHaveBase(Random rand) { * Have we strayed more than range blocks away from the center? */ private boolean isOutOfRange(StructureComponent parent, int nx, int ny, int nz, int range) { - -// System.out.println("x range is " + Math.abs(nx - parent.getBoundingBox().minX)); -// System.out.println("z range is " + Math.abs(nz - parent.getBoundingBox().minZ)); -// System.out.println("nz is " + nz + ", parent.minz is " + parent.getBoundingBox().minZ); - - return Math.abs(nx - parent.getBoundingBox().getCenterX()) > range - || Math.abs(nz - parent.getBoundingBox().getCenterZ()) > range; + final StructureBoundingBox sbb = parent.getBoundingBox(); + final int centerX = sbb.minX + (sbb.maxX - sbb.minX + 1) / 2; + final int centerZ = sbb.minZ + (sbb.maxZ - sbb.minZ + 1) / 2; + + return Math.abs(nx - centerX) > range + || Math.abs(nz - centerZ) > range; } /** * Make a new wing */ - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; + @Override + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - - //System.out.println("Making tower, index = " + index + ", list.size() = " + list.size()); // stop if out of range - if (isOutOfRange((StructureComponent) list.get(0), dx[0], dx[1], dx[2], RANGE)) - { + if (isOutOfRange((StructureComponent) list.get(0), dx[0], dx[1], dx[2], RANGE)) { return false; } - ComponentTFIceTowerWing wing = new ComponentTFIceTowerWing(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFIceTowerWing wing = new ComponentTFIceTowerWing(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, wing.getBoundingBox()); if (intersect == null || intersect == this) { @@ -151,9 +152,7 @@ public boolean makeTowerWing(List list, Random rand, int ind wing.buildComponent(list.get(0), list, rand); addOpening(x, y, z, rotation); return true; - } - else - { + } else { return false; } @@ -162,12 +161,12 @@ public boolean makeTowerWing(List list, Random rand, int ind /** * Make a new wing */ - public boolean makeBossTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + public boolean makeBossTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - ComponentTFIceTowerWing wing = new ComponentTFIceTowerBossWing(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFIceTowerWing wing = new ComponentTFIceTowerBossWing(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, wing.getBoundingBox()); if (intersect == null || intersect == this) { @@ -175,9 +174,7 @@ public boolean makeBossTowerWing(List list, Random rand, int wing.buildComponent(list.get(0), list, rand); addOpening(x, y, z, rotation); return true; - } - else - { + } else { return false; } @@ -188,52 +185,51 @@ public boolean makeBossTowerWing(List list, Random rand, int * Gets a Y value where the stairs meet the specified X coordinate. * Also works for Z coordinates. */ - protected int getYByStairs(int rx, Random rand, int direction) { - + @Override + protected int getYByStairs(int rx, Random rand, Rotation direction) { + int floors = this.height / 10; - + return 11 + (rand.nextInt(floors - 1) * 10); } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - + // make walls - //fillWithMetadataBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, deco.blockID, deco.blockMeta, Blocks.air, 0, false); + //fillWithMetadataBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, deco.blockID, deco.blockMeta, AIR, false); fillWithRandomizedBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, false, rand, deco.randomBlocks); // clear inside fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); - - if (this.hasBase) - { + + if (this.hasBase) { // deco to ground - for (int x = 0; x < this.size; x++) - { - for (int z = 0; z < this.size; z++) - { - this.func_151554_b(world, deco.blockID, deco.blockMeta, x, -1, z, sbb); + for (int x = 0; x < this.size; x++) { + for (int z = 0; z < this.size; z++) { + this.replaceAirAndLiquidDownwards(world, deco.blockState, x, -1, z, sbb); } } } - - // nullify sky light + + // nullify sky light this.nullifySkyLightForBoundingBox(world); - + // make floors makeFloorsForTower(world, decoRNG, sbb); - - // openings - makeOpenings(world, sbb); - - - return true; - } - + + // openings + makeOpenings(world, sbb); + + + return true; + } + /** * Nullify all the sky light in this component bounding box */ + @Override public void nullifySkyLightForBoundingBox(World world) { this.nullifySkyLight(world, boundingBox.minX + 1, boundingBox.minY + 1, boundingBox.minZ + 1, boundingBox.maxX - 1, boundingBox.maxY - 1, boundingBox.maxZ - 1); } @@ -241,8 +237,8 @@ public void nullifySkyLightForBoundingBox(World world) { protected void makeFloorsForTower(World world, Random decoRNG, StructureBoundingBox sbb) { int floors = this.height / 10; - int ladderDir = 3; - int downLadderDir = -1; + Rotation ladderDir = Rotation.COUNTERCLOCKWISE_90; + Rotation downLadderDir = null; // divide the tower into floors int floorHeight = 10; @@ -250,14 +246,11 @@ protected void makeFloorsForTower(World world, Random decoRNG, StructureBounding // put down a ceiling placeFloor(world, decoRNG, sbb, floorHeight, i); - downLadderDir = ladderDir; - ladderDir++; - ladderDir %= 4; - + downLadderDir = ladderDir.add(Rotation.CLOCKWISE_90); decorateFloor(world, decoRNG, i, (i * floorHeight), (i * floorHeight) + floorHeight, ladderDir, downLadderDir, sbb); } - + int topFloor = floors - 1; decorateTopFloor(world, decoRNG, topFloor, (topFloor * floorHeight), (topFloor * floorHeight) + floorHeight, ladderDir, downLadderDir, sbb); @@ -269,437 +262,449 @@ protected void makeFloorsForTower(World world, Random decoRNG, StructureBounding protected void placeFloor(World world, Random rand, StructureBoundingBox sbb, int floorHeight, int floor) { for (int x = 1; x < size - 1; x++) { for (int z = 1; z < size - 1; z++) { - placeBlockAtCurrentPosition(world, deco.floorID, deco.floorMeta, x, (floor * floorHeight) + floorHeight, z, sbb); + setBlockState(world, deco.floorState, x, (floor * floorHeight) + floorHeight, z, sbb); } } } - + /** * Make an opening in this tower for a door. This now only makes one opening, so you need two */ + @Override protected void makeDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { super.makeDoorOpening(world, dx, dy, dz, sbb); - - if (getBlockAtCurrentPosition(world, dx, dy + 2, dz, sbb) != Blocks.air) { - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, dx, dy + 2, dz, sbb); - } + + if (getBlockStateFromPos(world, dx, dy + 2, dz, sbb).getBlock() != Blocks.AIR) { + setBlockState(world, deco.accentState, dx, dy + 2, dz, sbb); + } } - + /** * Called to decorate each floor. This is responsible for adding a ladder up, the stub of the ladder going down, then picking a theme for each floor and executing it. - * + * * @param floor * @param bottom * @param top * @param ladderUpDir - * @param laddderDownDir + * @param ladderDownDir */ - protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + @Override + protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { boolean hasTreasure = (this.treasureFloor == floor); - + switch (rand.nextInt(8)) { - case 0: - //this.fillBlocksRotated(world, sbb, 9, bottom + 5, 1, 10, top + 1, 7, Blocks.wool, ladderUpDir, ladderUpDir); - if (isNoDoorAreaRotated(9, bottom + 5, 1, 10, top + 1, 7, ladderUpDir)) { - decorateWraparoundWallSteps(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + case 0: + //this.fillBlocksRotated(world, sbb, 9, bottom + 5, 1, 10, top + 1, 7, Blocks.WOOL, ladderUpDir, ladderUpDir); + if (isNoDoorAreaRotated(9, bottom + 5, 1, 10, top + 1, 7, ladderUpDir)) { + decorateWraparoundWallSteps(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + break; + } // fall through otherwise + case 1: + //this.fillBlocksRotated(world, sbb, 7, bottom, 0, 10, top + 1, 10, Blocks.WOOL, ladderUpDir, ladderUpDir); + if (isNoDoorAreaRotated(7, bottom, 0, 10, top + 1, 10, ladderUpDir)) { + decorateFarWallSteps(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + break; + } // fall through otherwise + case 2: + if (isNoDoorAreaRotated(9, bottom + 5, 1, 10, top + 1, 7, ladderUpDir)) { + decorateWraparoundWallStepsPillars(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + break; + } // fall through otherwise + case 3: + decoratePlatform(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + break; + case 4: + decoratePillarParkour(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); break; - } // fall through otherwise - case 1: - //this.fillBlocksRotated(world, sbb, 7, bottom, 0, 10, top + 1, 10, Blocks.wool, ladderUpDir, ladderUpDir); - if (isNoDoorAreaRotated(7, bottom, 0, 10, top + 1, 10, ladderUpDir)) { - decorateFarWallSteps(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + case 5: + decoratePillarPlatforms(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); break; - } // fall through otherwise - case 2: - if (isNoDoorAreaRotated(9, bottom + 5, 1, 10, top + 1, 7, ladderUpDir)) { - decorateWraparoundWallStepsPillars(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + case 6: + decoratePillarPlatformsOutside(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); break; - } // fall through otherwise - case 3: - decoratePlatform(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); - break; - case 4: - decoratePillarParkour(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); - break; - case 5: - decoratePillarPlatforms(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); - break; - case 6: - decoratePillarPlatformsOutside(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); - break; - case 7: - default: - decorateQuadPillarStairs(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); - break; - } - - } - - private boolean isNoDoorAreaRotated(int minX, int minY, int minZ, int maxX, int maxY, int maxZ, int rotation) { + case 7: + default: + decorateQuadPillarStairs(world, rand, bottom, top, ladderUpDir, ladderDownDir, hasTreasure, sbb); + break; + } + + } + + private boolean isNoDoorAreaRotated(int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Rotation rotation) { boolean isClear = true; - // make a bounding box of the area + // make a bounding box of the area StructureBoundingBox exclusionBox; switch (rotation) { - case 0: - default: - exclusionBox = new StructureBoundingBox(minX, minY, minZ, maxX, maxY, maxZ); - break; - case 1: - exclusionBox = new StructureBoundingBox(this.size - 1 - maxZ, minY, minX, this.size - 1 - minZ, maxY, maxX); - break; - case 2: - exclusionBox = new StructureBoundingBox(this.size - 1 - maxX, minY, this.size - 1 - maxZ, this.size - 1 - minX, maxY, this.size - 1 - minZ); - break; - case 3: - exclusionBox = new StructureBoundingBox(minZ, minY, this.size - 1 - maxX, maxZ, maxY, this.size - 1 - minX); - break; - } - - for (ChunkCoordinates door : this.openings) { - if (exclusionBox.isVecInside(door.posX, door.posY, door.posZ)) { + case NONE: + default: + exclusionBox = new StructureBoundingBox(minX, minY, minZ, maxX, maxY, maxZ); + break; + case CLOCKWISE_90: + exclusionBox = new StructureBoundingBox(this.size - 1 - maxZ, minY, minX, this.size - 1 - minZ, maxY, maxX); + break; + case CLOCKWISE_180: + exclusionBox = new StructureBoundingBox(this.size - 1 - maxX, minY, this.size - 1 - maxZ, this.size - 1 - minX, maxY, this.size - 1 - minZ); + break; + case COUNTERCLOCKWISE_90: + exclusionBox = new StructureBoundingBox(minZ, minY, this.size - 1 - maxX, maxZ, maxY, this.size - 1 - minX); + break; + } + + for (BlockPos door : this.openings) { + if (exclusionBox.isVecInside(door)) { isClear = false; - - //System.out.println("Found door in exclusion box, door = " + door); } } - + return isClear; } - protected void decorateTopFloor(World world, Random rand, int floor, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateTopFloor(World world, Random rand, int floor, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { if (rand.nextBoolean()) { decoratePillarsCorners(world, rand, bottom, top, ladderDownDir, sbb); } else { decoratePillarsGrid(world, rand, bottom, top, ladderDownDir, sbb); } - + // generate treasure last so it doesn't get deleted if (this.isDeadEnd()) { decorateTopFloorTreasure(world, rand, bottom, top, ladderDownDir, sbb); } - + } - private void decorateTopFloorTreasure(World world, Random rand, int bottom, int top, int rotation, StructureBoundingBox sbb) { - this.fillBlocksRotated(world, sbb, 5, bottom + 1, 5, 5, bottom + 4, 5, deco.pillarID, deco.pillarMeta, rotation); + private void decorateTopFloorTreasure(World world, Random rand, int bottom, int top, Rotation rotation, StructureBoundingBox sbb) { + this.fillBlocksRotated(world, sbb, 5, bottom + 1, 5, 5, bottom + 4, 5, deco.pillarState, rotation); this.placeTreasureAtCurrentPosition(world, null, 5, bottom + 5, 5, TFTreasure.aurora_room, sbb); } - private void decoratePillars(World world, Random rand, int bottom, int top, int rotation, StructureBoundingBox sbb) { - this.fillBlocksRotated(world, sbb, 3, bottom + 1, 3, 3, top - 1, 3, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 1, 3, 7, top - 1, 3, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 3, bottom + 1, 7, 3, top - 1, 7, deco.pillarID, deco.pillarMeta, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 1, 7, 7, top - 1, 7, deco.pillarID, deco.pillarMeta, rotation); + private void decoratePillars(World world, Random rand, int bottom, int top, Rotation rotation, StructureBoundingBox sbb) { + this.fillBlocksRotated(world, sbb, 3, bottom + 1, 3, 3, top - 1, 3, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 1, 3, 7, top - 1, 3, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 3, bottom + 1, 7, 3, top - 1, 7, deco.pillarState, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 1, 7, 7, top - 1, 7, deco.pillarState, rotation); } - private void decoratePillarsGrid(World world, Random rand, int bottom, int top, int rotation, StructureBoundingBox sbb) { - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; - int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 9, bottom + 5, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 5, 7, 9, bottom + 5, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - + private void decoratePillarsGrid(World world, Random rand, int bottom, int top, Rotation rotation, StructureBoundingBox sbb) { + //int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; + //int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; + final IBlockState pillarEW = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.Z); + final IBlockState pillarNS = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.X); + + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 9, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 9, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 9, bottom + 5, 3, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 5, 7, 9, bottom + 5, 7, pillarNS, rotation); + this.decoratePillars(world, rand, bottom, top, rotation, sbb); } - private void decoratePillarsCorners(World world, Random rand, int bottom, int top, int rotation, StructureBoundingBox sbb) { - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; - int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 9, bottom + 5, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 5, 7, 9, bottom + 5, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - + private void decoratePillarsCorners(World world, Random rand, int bottom, int top, Rotation rotation, StructureBoundingBox sbb) { + //int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; + //int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; + final IBlockState pillarEW = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.Z); + final IBlockState pillarNS = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.X); + + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 9, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 9, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 9, bottom + 5, 3, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 5, 7, 9, bottom + 5, 7, pillarNS, rotation); + this.fillAirRotated(world, sbb, 3, bottom + 5, 3, 7, bottom + 5, 7, rotation); - + this.decoratePillars(world, rand, bottom, top, rotation, sbb); } - private void decorateFarWallSteps(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { - + private void decorateFarWallSteps(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + // far set of stairs - for (int z = 1; z < 10; z++) - { + for (int z = 1; z < 10; z++) { int y = bottom + 10 - (z / 2); - this.placeBlockRotated(world, (z % 2 == 0) ? deco.pillarID : deco.platformID, (z % 2 == 0) ? deco.pillarMeta : deco.platformMeta, 9, y, z, ladderUpDir, sbb); - for (int by = bottom + 1; by < y; by++) - { - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, 9, by, z, ladderUpDir, sbb); + this.setBlockStateRotated(world, (z % 2 == 0) ? deco.pillarState : deco.platformState, 9, y, z, ladderUpDir, sbb); + for (int by = bottom + 1; by < y; by++) { + this.setBlockStateRotated(world, deco.pillarState, 9, by, z, ladderUpDir, sbb); } } - + // near set of stairs - for (int z = 1; z < 10; z++) - { + for (int z = 1; z < 10; z++) { int y = bottom + 1 + (z / 2); - this.placeBlockRotated(world, (z % 2 == 0) ? deco.platformID : deco.pillarID, (z % 2 == 0) ? deco.platformMeta : deco.pillarMeta, 8, y, z, ladderUpDir, sbb); - for (int by = bottom + 1; by < y; by++) - { - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, 8, by, z, ladderUpDir, sbb); + this.setBlockStateRotated(world, (z % 2 == 0) ? deco.platformState : deco.pillarState, 8, y, z, ladderUpDir, sbb); + for (int by = bottom + 1; by < y; by++) { + this.setBlockStateRotated(world, deco.pillarState, 8, by, z, ladderUpDir, sbb); } } - + // entry stair - this.placeBlockRotated(world, deco.platformID, deco.platformMeta, 7, bottom + 1, 1, ladderUpDir, sbb); + this.setBlockStateRotated(world, deco.platformState, 7, bottom + 1, 1, ladderUpDir, sbb); + - // clear floor above - for (int z = 2; z < 7; z++) - { - this.placeBlockRotated(world, Blocks.air, 0, 9, top, z, ladderUpDir, sbb); + for (int z = 2; z < 7; z++) { + this.setBlockStateRotated(world, AIR, 9, top, z, ladderUpDir, sbb); } - + + final IBlockState pillarNS = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.X); // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 1, bottom + 8, 5, ladderUpDir, TFTreasure.aurora_cache, false, sbb); - int beamMetaNS = ((this.coordBaseMode + ladderUpDir) % 2 == 0) ? 4 : 8; - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta + beamMetaNS, 1, bottom + 7, 5, ladderUpDir, sbb); + //int beamMetaNS = ((this.coordBaseMode + ladderUpDir) % 2 == 0) ? 4 : 8; + this.setBlockStateRotated(world, pillarNS, 1, bottom + 7, 5, ladderUpDir, sbb); } } - private void decorateWraparoundWallSteps(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { - + private void decorateWraparoundWallSteps(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + IBlockState topPlatform = deco.platformState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP); + IBlockState bottomPlatform = deco.platformState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.BOTTOM); + // far set of stairs - for (int z = 1; z < 10; z++) - { + for (int z = 1; z < 10; z++) { int y = bottom + 10 - (z / 2); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((z % 2 == 0) ? 8 : 0), 9, y, z, ladderUpDir, sbb); + this.setBlockStateRotated(world, ((z % 2 == 0) ? topPlatform : bottomPlatform), 9, y, z, ladderUpDir, sbb); } - + // right set of stairs - for (int x = 1; x < 9; x++) - { + for (int x = 1; x < 9; x++) { int y = bottom + 2 + ((x - 1) / 2); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((x % 2 == 0) ? 8 : 0), x, y, 9, ladderUpDir, sbb); + this.setBlockStateRotated(world, ((x % 2 == 0) ? topPlatform : bottomPlatform), x, y, 9, ladderUpDir, sbb); } - + // entry stairs - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + 8, 1, bottom + 1, 8, ladderUpDir, sbb); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta, 1, bottom + 1, 7, ladderUpDir, sbb); + this.setBlockStateRotated(world, topPlatform, 1, bottom + 1, 8, ladderUpDir, sbb); + this.setBlockStateRotated(world, deco.platformState, 1, bottom + 1, 7, ladderUpDir, sbb); + - // clear floor above - for (int z = 2; z < 7; z++) - { - this.placeBlockRotated(world, Blocks.air, 0, 9, top, z, ladderUpDir, sbb); + for (int z = 2; z < 7; z++) { + this.setBlockStateRotated(world, AIR, 9, top, z, ladderUpDir, sbb); } - + // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 1, bottom + 5, 5, ladderUpDir, TFTreasure.aurora_cache, false, sbb); - int beamMetaNS = ((this.coordBaseMode + ladderUpDir) % 2 == 0) ? 4 : 8; - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta + beamMetaNS, 1, bottom + 4, 5, ladderUpDir, sbb); + //int beamMetaNS = ((this.coordBaseMode + ladderUpDir) % 2 == 0) ? 4 : 8; + final IBlockState pillarNS = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.X); + this.setBlockStateRotated(world, pillarNS, 1, bottom + 4, 5, ladderUpDir, sbb); } } - - private void decorateWraparoundWallStepsPillars(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { - int rotation = ladderDownDir; - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; - int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - + + private void decorateWraparoundWallStepsPillars(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + Rotation rotation = ladderDownDir; + //int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; + //int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; + final IBlockState pillarEW = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.Z); + final IBlockState pillarNS = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.X); + this.decorateWraparoundWallSteps(world, rand, bottom, top, ladderUpDir, ladderDownDir, false, sbb); this.decoratePillars(world, rand, bottom, top, rotation, sbb); - - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 2, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 2, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 8, bottom + 5, 3, 9, bottom + 5, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 8, bottom + 5, 7, 9, bottom + 5, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - - this.fillBlocksRotated(world, sbb, 1, bottom + 2, 3, 2, bottom + 2, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 6, 3, 2, bottom + 6, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 4, 7, 2, bottom + 4, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 8, 7, 2, bottom + 8, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 3, bottom + 6, 8, 3, bottom + 6, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 8, 8, 7, bottom + 8, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); + + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 2, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 5, 1, 7, bottom + 5, 2, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 8, bottom + 5, 3, 9, bottom + 5, 3, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 8, bottom + 5, 7, 9, bottom + 5, 7, pillarNS, rotation); + + this.fillBlocksRotated(world, sbb, 1, bottom + 2, 3, 2, bottom + 2, 3, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 6, 3, 2, bottom + 6, 3, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 4, 7, 2, bottom + 4, 7, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 8, 7, 2, bottom + 8, 7, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 3, bottom + 6, 8, 3, bottom + 6, 9, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 8, 8, 7, bottom + 8, 9, pillarEW, rotation); // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 7, bottom + 6, 1, ladderUpDir, TFTreasure.aurora_cache, false, sbb); } } - - private void decoratePlatform(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + + private void decoratePlatform(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + IBlockState topPlatform = deco.platformState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP); + IBlockState bottomPlatform = deco.platformState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.BOTTOM); + this.decoratePillars(world, rand, bottom, top, ladderDownDir, sbb); - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 3, 7, bottom + 5, 7, deco.floorID, deco.floorMeta, ladderDownDir); + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 3, 7, bottom + 5, 7, deco.floorState, ladderDownDir); // one flight for (int z = 6; z < 10; z++) { int y = bottom - 2 + (z / 2); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((z % 2 == 1) ? 8 : 0), 1, y, z, ladderDownDir, sbb); + this.setBlockStateRotated(world, ((z % 2 == 1) ? topPlatform : bottomPlatform), 1, y, z, ladderDownDir, sbb); } // two flight - for (int x = 2; x < 6; x++) - { + for (int x = 2; x < 6; x++) { int y = bottom + 2 + (x / 2); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((x % 2 == 1) ? 8 : 0), x, y, 9, ladderDownDir, sbb); + this.setBlockStateRotated(world, ((x % 2 == 1) ? topPlatform : bottomPlatform), x, y, 9, ladderDownDir, sbb); } // connector - this.placeBlockRotated(world, deco.platformID, deco.platformMeta, 5, bottom + 5, 8, ladderDownDir, sbb); - + this.setBlockStateRotated(world, deco.platformState, 5, bottom + 5, 8, ladderDownDir, sbb); + // connector - this.placeBlockRotated(world, deco.platformID, deco.platformMeta, 5, bottom + 6, 2, ladderUpDir, sbb); + this.setBlockStateRotated(world, deco.platformState, 5, bottom + 6, 2, ladderUpDir, sbb); // two flight - for (int x = 5; x < 10; x++) - { + for (int x = 5; x < 10; x++) { int y = bottom + 4 + (x / 2); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((x % 2 == 1) ? 8 : 0), x, y, 1, ladderUpDir, sbb); + this.setBlockStateRotated(world, ((x % 2 == 1) ? topPlatform : bottomPlatform), x, y, 1, ladderUpDir, sbb); if (x > 6) { - this.placeBlockRotated(world, Blocks.air, 0, x, top, 1, ladderUpDir, sbb); + this.setBlockStateRotated(world, AIR, x, top, 1, ladderUpDir, sbb); } } // one flight for (int z = 2; z < 5; z++) { int y = bottom + 8 + (z / 2); - this.placeBlockRotated(world, Blocks.air, 0, 9, top, z, ladderUpDir, sbb); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((z % 2 == 1) ? 8 : 0), 9, y, z, ladderUpDir, sbb); + this.setBlockStateRotated(world, AIR, 9, top, z, ladderUpDir, sbb); + this.setBlockStateRotated(world, ((z % 2 == 1) ? topPlatform : bottomPlatform), 9, y, z, ladderUpDir, sbb); } - + // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 3, bottom + 6, 5, ladderDownDir, TFTreasure.aurora_cache, false, sbb); } } - - private void decorateQuadPillarStairs(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + + private void decorateQuadPillarStairs(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { this.decoratePillars(world, rand, bottom, top, ladderDownDir, sbb); + IBlockState topPlatform = deco.platformState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP); + IBlockState bottomPlatform = deco.platformState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.BOTTOM); + // one flight for (int z = 6; z < 9; z++) { int y = bottom - 2 + (z / 2); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((z % 2 == 1) ? 8 : 0), 2, y, z, ladderDownDir, sbb); + this.setBlockStateRotated(world, z % 2 == 1 ? topPlatform : bottomPlatform, 2, y, z, ladderDownDir, sbb); } // two flight - for (int x = 3; x < 9; x++) - { + for (int x = 3; x < 9; x++) { int y = bottom + 1 + (x / 2); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((x % 2 == 1) ? 8 : 0), x, y, 8, ladderDownDir, sbb); + this.setBlockStateRotated(world, x % 2 == 1 ? topPlatform : bottomPlatform, x, y, 8, ladderDownDir, sbb); } // three flight for (int z = 7; z > 1; z--) { int y = top - 2 - ((z - 1) / 2); if (z < 4) { - this.placeBlockRotated(world, Blocks.air, 0, 8, top, z, ladderDownDir, sbb); + this.setBlockStateRotated(world, AIR, 8, top, z, ladderDownDir, sbb); } - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((z % 2 == 1) ? 8 : 0), 8, y, z, ladderDownDir, sbb); + this.setBlockStateRotated(world, ((z % 2 == 1) ? topPlatform : bottomPlatform), 8, y, z, ladderDownDir, sbb); } // last flight for (int x = 7; x > 3; x--) { int y = top + 1 - ((x - 1) / 2); - this.placeBlockRotated(world, Blocks.air, 0, x, top, 2, ladderDownDir, sbb); - this.placeBlockRotated(world, deco.platformID, deco.platformMeta + ((x % 2 == 1) ? 8 : 0), x, y, 2, ladderDownDir, sbb); + this.setBlockStateRotated(world, AIR, x, top, 2, ladderDownDir, sbb); + this.setBlockStateRotated(world, ((x % 2 == 1) ? topPlatform : bottomPlatform), x, y, 2, ladderDownDir, sbb); } - + // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 3, bottom + 7, 7, ladderUpDir, TFTreasure.aurora_cache, false, sbb); } } - - private void decoratePillarPlatforms(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + + private void decoratePillarPlatforms(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { // platforms + Rotation r = ladderUpDir; for (int i = 1; i < 10; i++) { - int rotation = (ladderUpDir + i) % 4; - this.fillBlocksRotated(world, sbb, 2, bottom + i, 2, 4, bottom + i, 4, deco.floorID, deco.floorMeta, rotation); + r = r.add(Rotation.CLOCKWISE_90); + this.fillBlocksRotated(world, sbb, 2, bottom + i, 2, 4, bottom + i, 4, deco.floorState, rotation); } - + // clear this.fillAirRotated(world, sbb, 2, top, 2, 8, top, 4, ladderUpDir); this.fillAirRotated(world, sbb, 2, top, 2, 4, top, 6, ladderUpDir); - + // extra pillar tops - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, 7, top, 3, ladderUpDir, sbb); - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, 3, top, 3, ladderUpDir, sbb); - + this.setBlockStateRotated(world, deco.platformState, 7, top, 3, ladderUpDir, sbb); + this.setBlockStateRotated(world, deco.platformState, 3, top, 3, ladderUpDir, sbb); + this.decoratePillars(world, rand, bottom, top, ladderUpDir, sbb); - + // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 3, bottom + 5, 2, ladderUpDir, TFTreasure.aurora_cache, false, sbb); } } - - private void decoratePillarPlatformsOutside(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + + private void decoratePillarPlatformsOutside(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { // platforms - for (int i = 1; i < 8; i++) { - int rotation = (ladderUpDir + i) % 4; - this.fillBlocksRotated(world, sbb, 1, bottom + i, 1, 3, bottom + i, 3, deco.platformID, deco.platformMeta, rotation); - this.fillBlocksRotated(world, sbb, 4, bottom + i, 1, 6, bottom + i, 3, deco.floorID, deco.floorMeta, rotation); + for (int i = 0; i < 2; i++) { + for (Rotation r : RotationUtil.ROTATIONS) { + if (i == 0 && r == Rotation.NONE) continue; + Rotation rotation = ladderUpDir.add(r); + this.fillBlocksRotated(world, sbb, 1, bottom + i, 1, 3, bottom + i, 3, deco.platformState, rotation); + this.fillBlocksRotated(world, sbb, 4, bottom + i, 1, 6, bottom + i, 3, deco.floorState, rotation); + } } - + // stairs - int rotation = (ladderUpDir + 2) % 4; + Rotation rotation = ladderUpDir.add(Rotation.CLOCKWISE_180); this.fillAirRotated(world, sbb, 5, top, 8, 9, top, 9, rotation); this.fillAirRotated(world, sbb, 8, top, 6, 9, top, 9, rotation); - - this.fillBlocksRotated(world, sbb, 8, top - 2, 7, 9, top - 2, 7, deco.platformID, deco.platformMeta, rotation); - this.fillBlocksRotated(world, sbb, 8, top - 2, 8, 9, top - 2, 9, deco.floorID, deco.floorMeta, rotation); - this.fillBlocksRotated(world, sbb, 7, top - 1, 8, 7, top - 1, 9, deco.platformID, deco.platformMeta, rotation); - this.fillBlocksRotated(world, sbb, 6, top - 1, 8, 6, top - 1, 9, deco.platformID, deco.platformMeta | 8, rotation); - this.fillBlocksRotated(world, sbb, 5, top - 0, 8, 5, top - 0, 9, deco.platformID, deco.platformMeta, rotation); + + this.fillBlocksRotated(world, sbb, 8, top - 2, 7, 9, top - 2, 7, deco.platformState, rotation); + this.fillBlocksRotated(world, sbb, 8, top - 2, 8, 9, top - 2, 9, deco.floorState, rotation); + this.fillBlocksRotated(world, sbb, 7, top - 1, 8, 7, top - 1, 9, deco.platformState, rotation); + this.fillBlocksRotated(world, sbb, 6, top - 1, 8, 6, top - 1, 9, deco.platformState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP), rotation); + this.fillBlocksRotated(world, sbb, 5, top - 0, 8, 5, top - 0, 9, deco.platformState, rotation); this.decoratePillars(world, rand, bottom, top, ladderUpDir, sbb); - + // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 3, bottom + 5, 2, ladderUpDir, TFTreasure.aurora_cache, false, sbb); } } - - private void decoratePillarParkour(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { - int rotation = ladderDownDir; - int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; - int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; - + + private void decoratePillarParkour(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, boolean hasTreasure, StructureBoundingBox sbb) { + Rotation rotation = ladderDownDir; + //int beamMetaNS = ((this.coordBaseMode + rotation) % 2 == 0) ? 4 : 8; + //int beamMetaEW = (beamMetaNS == 4) ? 8 : 4; + + final IBlockState pillarEW = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.Z); + final IBlockState pillarNS = deco.pillarState.withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.X); + // 4 pillars this.decoratePillars(world, rand, bottom, top, rotation, sbb); // center pillar - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, 5, bottom + 1, 5, rotation, sbb); - + this.setBlockStateRotated(world, deco.pillarState, 5, bottom + 1, 5, rotation, sbb); + // pillar 2 - this.fillBlocksRotated(world, sbb, 5, bottom + 2, 7, 5, bottom + 2, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - + this.fillBlocksRotated(world, sbb, 5, bottom + 2, 7, 5, bottom + 2, 9, pillarEW, rotation); + // gap 3 - this.fillBlocksRotated(world, sbb, 1, bottom + 3, 7, 2, bottom + 3, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 3, bottom + 3, 8, 3, bottom + 3, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 7, 7, 2, bottom + 7, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 3, bottom + 7, 8, 3, bottom + 7, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 3, 7, 2, bottom + 3, 7, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 3, bottom + 3, 8, 3, bottom + 3, 9, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 7, 7, 2, bottom + 7, 7, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 3, bottom + 7, 8, 3, bottom + 7, 9, pillarEW, rotation); this.fillAirRotated(world, sbb, 3, bottom + 4, 7, 3, bottom + 6, 7, rotation); - + // pillar 4 - this.fillBlocksRotated(world, sbb, 1, bottom + 4, 5, 2, bottom + 4, 5, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 4, 5, 2, bottom + 4, 5, pillarNS, rotation); // gap 5 - this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 2, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 2, bottom + 5, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); + this.fillBlocksRotated(world, sbb, 3, bottom + 5, 1, 3, bottom + 5, 2, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 1, bottom + 5, 3, 2, bottom + 5, 3, pillarNS, rotation); this.fillAirRotated(world, sbb, 3, bottom + 6, 3, 3, bottom + 8, 3, rotation); // pillar 6 - this.fillBlocksRotated(world, sbb, 5, bottom + 6, 1, 5, bottom + 6, 2, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); + this.fillBlocksRotated(world, sbb, 5, bottom + 6, 1, 5, bottom + 6, 2, pillarEW, rotation); // gap 7 this.fillAirRotated(world, sbb, 7, bottom + 8, 3, 7, bottom + 10, 3, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 7, 1, 7, bottom + 7, 2, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); - this.fillBlocksRotated(world, sbb, 8, bottom + 7, 3, 9, bottom + 7, 3, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - + this.fillBlocksRotated(world, sbb, 7, bottom + 7, 1, 7, bottom + 7, 2, pillarEW, rotation); + this.fillBlocksRotated(world, sbb, 8, bottom + 7, 3, 9, bottom + 7, 3, pillarNS, rotation); + // pillar 8 - this.fillBlocksRotated(world, sbb, 8, bottom + 8, 5, 9, bottom + 8, 5, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - + this.fillBlocksRotated(world, sbb, 8, bottom + 8, 5, 9, bottom + 8, 5, pillarNS, rotation); + // gap 9 (no gap?) //this.fillAirRotated(world, sbb, 7, bottom + 10, 7, 7, bottom + 10, 7, rotation); - this.fillBlocksRotated(world, sbb, 8, bottom + 9, 7, 9, bottom + 9, 7, deco.pillarID, deco.pillarMeta + beamMetaNS, rotation); - this.fillBlocksRotated(world, sbb, 7, bottom + 9, 8, 7, bottom + 9, 9, deco.pillarID, deco.pillarMeta + beamMetaEW, rotation); + this.fillBlocksRotated(world, sbb, 8, bottom + 9, 7, 9, bottom + 9, 7, pillarNS, rotation); + this.fillBlocksRotated(world, sbb, 7, bottom + 9, 8, 7, bottom + 9, 9, pillarEW, rotation); // holes in ceiling this.fillAirRotated(world, sbb, 2, top, 2, 8, top, 4, ladderUpDir); this.fillAirRotated(world, sbb, 2, top, 2, 4, top, 6, ladderUpDir); - + // treasure! if (hasTreasure) { this.placeTreasureRotated(world, 8, bottom + 8, 7, ladderUpDir, TFTreasure.aurora_cache, false, sbb); @@ -708,21 +713,23 @@ private void decoratePillarParkour(World world, Random rand, int bottom, int top /** * Attach a roof to this tower. - * + *

* This function keeps trying roofs starting with the largest and fanciest, and then keeps trying smaller and plainer ones */ + @Override public void makeARoof(StructureComponent parent, List list, Random rand) { int index = this.getComponentType(); - tryToFitRoof(list, rand, new ComponentTFIceTowerRoof(index + 1, this)); + tryToFitRoof(list, rand, new ComponentTFIceTowerRoof(getFeatureType(), index + 1, this)); } /** * Add a beard to this structure. There is only one type of beard. */ + @Override public void makeABeard(StructureComponent parent, List list, Random rand) { int index = this.getComponentType(); ComponentTFIceTowerBeard beard; - beard = new ComponentTFIceTowerBeard(index + 1, this); + beard = new ComponentTFIceTowerBeard(getFeatureType(), index + 1, this); list.add(beard); beard.buildComponent(this, list, rand); } diff --git a/src/main/java/twilightforest/structures/icetower/StructureDecoratorIceTower.java b/src/main/java/twilightforest/structures/icetower/StructureDecoratorIceTower.java index 469f21df7a..0aefdbfbf7 100644 --- a/src/main/java/twilightforest/structures/icetower/StructureDecoratorIceTower.java +++ b/src/main/java/twilightforest/structures/icetower/StructureDecoratorIceTower.java @@ -1,32 +1,23 @@ package twilightforest.structures.icetower; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.BlockWoodSlab; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import twilightforest.block.TFBlocks; import twilightforest.structures.StructureTFDecorator; public class StructureDecoratorIceTower extends StructureTFDecorator { - public StructureDecoratorIceTower() - { - this.blockID = TFBlocks.auroraBlock; - this.blockMeta = 0; - - this.accentID = Blocks.planks; - this.accentMeta = 2; - - this.fenceID = Blocks.fence; - - this.stairID = Blocks.birch_stairs; - - this.pillarID = TFBlocks.auroraPillar; - this.pillarMeta = 0; - - this.platformID = Blocks.wooden_slab; - this.platformMeta = 2; - - this.floorID = Blocks.planks; - this.floorMeta = 2; - + public StructureDecoratorIceTower() { + this.blockState = TFBlocks.aurora_block.getDefaultState(); + this.accentState = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + this.fenceState = Blocks.OAK_FENCE.getDefaultState(); + this.stairState = Blocks.BIRCH_STAIRS.getDefaultState(); + this.pillarState = TFBlocks.aurora_pillar.getDefaultState().withProperty(BlockRotatedPillar.AXIS, EnumFacing.Axis.Y); + this.platformState = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockWoodSlab.VARIANT, BlockPlanks.EnumType.BIRCH); + this.floorState = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); this.randomBlocks = new StructureTFAuroraBricks(); } diff --git a/src/main/java/twilightforest/structures/icetower/StructureTFAuroraBricks.java b/src/main/java/twilightforest/structures/icetower/StructureTFAuroraBricks.java index 08c6ce7ae5..a73d6f7b2c 100644 --- a/src/main/java/twilightforest/structures/icetower/StructureTFAuroraBricks.java +++ b/src/main/java/twilightforest/structures/icetower/StructureTFAuroraBricks.java @@ -1,25 +1,24 @@ package twilightforest.structures.icetower; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.block.BlockTFAuroraBrick; import twilightforest.block.TFBlocks; +import java.util.Random; + public class StructureTFAuroraBricks extends StructureComponent.BlockSelector { @Override - public void selectBlocks(Random par1Random, int x, int y, int z, boolean wall) { - if (!wall) - { - this.field_151562_a = Blocks.air; - this.selectedBlockMetaData = 0; - } - else - { - this.field_151562_a = TFBlocks.auroraBlock; - this.selectedBlockMetaData = Math.abs(x + z) % 16; - } + public void selectBlocks(Random random, int x, int y, int z, boolean wall) { + if (!wall) { + this.blockstate = Blocks.AIR.getDefaultState(); + } else { + this.blockstate = TFBlocks.aurora_block.getDefaultState().withProperty( + BlockTFAuroraBrick.VARIANT, + Math.abs(x + z) % 16 + ); + } } } diff --git a/src/main/java/twilightforest/structures/icetower/TFIceTowerPieces.java b/src/main/java/twilightforest/structures/icetower/TFIceTowerPieces.java index 2a4fdc9565..cb4b9c0763 100644 --- a/src/main/java/twilightforest/structures/icetower/TFIceTowerPieces.java +++ b/src/main/java/twilightforest/structures/icetower/TFIceTowerPieces.java @@ -1,18 +1,21 @@ package twilightforest.structures.icetower; import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartAuroraPalace; + public class TFIceTowerPieces { - public static void registerPieces() - { - MapGenStructureIO.func_143031_a(ComponentTFIceTowerMain.class, "TFITMai"); - MapGenStructureIO.func_143031_a(ComponentTFIceTowerWing.class, "TFITWin"); - MapGenStructureIO.func_143031_a(ComponentTFIceTowerRoof.class, "TFITRoof"); - MapGenStructureIO.func_143031_a(ComponentTFIceTowerBeard.class, "TFITBea"); - MapGenStructureIO.func_143031_a(ComponentTFIceTowerBossWing.class, "TFITBoss"); - MapGenStructureIO.func_143031_a(ComponentTFIceTowerEntrance.class, "TFITEnt"); - MapGenStructureIO.func_143031_a(ComponentTFIceTowerBridge.class, "TFITBri"); - MapGenStructureIO.func_143031_a(ComponentTFIceTowerStairs.class, "TFITSt"); - } + public static void registerPieces() { + MapGenStructureIO.registerStructure(StructureStartAuroraPalace.class, "TFAP"); + + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerMain.class, "TFITMai"); + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerWing.class, "TFITWin"); + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerRoof.class, "TFITRoof"); + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerBeard.class, "TFITBea"); + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerBossWing.class, "TFITBoss"); + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerEntrance.class, "TFITEnt"); + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerBridge.class, "TFITBri"); + MapGenStructureIO.registerStructureComponent(ComponentTFIceTowerStairs.class, "TFITSt"); + } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeard.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeard.java index e66ab85cc5..f3359f740c 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeard.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeard.java @@ -1,54 +1,55 @@ package twilightforest.structures.lichtower; -import java.util.Random; - import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import java.util.Random; -public class ComponentTFTowerBeard extends StructureTFComponent { + +public class ComponentTFTowerBeard extends StructureTFComponentOld { int size; int height; public ComponentTFTowerBeard() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerBeard(int i, ComponentTFTowerWing wing) { - super(i); - + public ComponentTFTowerBeard(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i); + this.setCoordBaseMode(wing.getCoordBaseMode()); this.size = wing.size - 2; this.height = size / 2; - + // just hang out at the very bottom of the tower this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX + 1, wing.getBoundingBox().minY - this.height - 1, wing.getBoundingBox().minZ + 1, wing.getBoundingBox().maxX - 1, wing.getBoundingBox().minY - 1, wing.getBoundingBox().maxZ - 1); } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("beardSize", this.size); - par1NBTTagCompound.setInteger("beardHeight", this.height); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("beardSize", this.size); + tagCompound.setInteger("beardHeight", this.height); } - + /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.size = par1NBTTagCompound.getInteger("beardSize"); - this.height = par1NBTTagCompound.getInteger("beardHeight"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.size = tagCompound.getInteger("beardSize"); + this.height = tagCompound.getInteger("beardHeight"); } /** @@ -60,13 +61,13 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox } private boolean makePyramidBeard(World world, Random rand, StructureBoundingBox sbb) { - for (int y = 0; y <= height ; y++) { + for (int y = 0; y <= height; y++) { int min = y; int max = size - y - 1; - - fillWithRandomizedBlocks(world, sbb, min, height - y, min, max, height - y, max, false, rand, StructureTFComponent.getStrongholdStones()); - } - return true; + + fillWithRandomizedBlocks(world, sbb, min, height - y, min, max, height - y, max, false, rand, StructureTFComponentOld.getStrongholdStones()); + } + return true; } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeardAttached.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeardAttached.java index 019721d42a..529545ab21 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeardAttached.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBeardAttached.java @@ -1,23 +1,23 @@ package twilightforest.structures.lichtower; -import java.util.Random; - import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.Random; public class ComponentTFTowerBeardAttached extends ComponentTFTowerBeard { public ComponentTFTowerBeardAttached() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerBeardAttached(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFTowerBeardAttached(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // just hang out at the very bottom of the tower this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX, wing.getBoundingBox().minY - this.height - 1, wing.getBoundingBox().minZ, wing.getBoundingBox().maxX, wing.getBoundingBox().minY - 1, wing.getBoundingBox().maxZ); @@ -33,11 +33,11 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox } private boolean makeAttachedBeard(World world, Random rand, StructureBoundingBox sbb) { - for (int y = 0; y <= height ; y++) { + for (int y = 0; y <= height; y++) { int min = y + 1; int max = size - y; - - fillWithRandomizedBlocks(world, sbb, 0, height - y, min, max, height - y, max, false, rand, StructureTFComponent.getStrongholdStones()); + + fillWithRandomizedBlocks(world, sbb, 0, height - y, min, max, height - y, max, false, rand, StructureTFComponentOld.getStrongholdStones()); } return true; } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBridge.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBridge.java index 7daf3b122f..cceffa469e 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBridge.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerBridge.java @@ -1,13 +1,16 @@ package twilightforest.structures.lichtower; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; public class ComponentTFTowerBridge extends ComponentTFTowerWing { @@ -15,73 +18,67 @@ public class ComponentTFTowerBridge extends ComponentTFTowerWing { int dSize; int dHeight; - + public ComponentTFTowerBridge() { super(); - // TODO Auto-generated constructor stub } - protected ComponentTFTowerBridge(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, 3, 3, direction); - + protected ComponentTFTowerBridge(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, 3, 3, direction); + this.dSize = pSize; this.dHeight = pHeight; } - - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - - - int[] dest = new int[] {2, 1, 1};//getValidOpening(rand, 0); - - makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], dSize, dHeight, 0); + public void buildComponent(StructureComponent parent, List list, Random rand) { + int[] dest = new int[]{2, 1, 1};//getValidOpening(rand, 0); + makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], dSize, dHeight, Rotation.NONE); } - + /** * Gets the bounding box of the tower wing we would like to make. + * * @return */ public StructureBoundingBox getWingBB() { int[] dest = offsetTowerCoords(2, 1, 1, dSize, this.getCoordBaseMode()); - return StructureTFComponent.getComponentToAddBoundingBox(dest[0], dest[1], dest[2], 0, 0, 0, dSize - 1, dHeight - 1, dSize - 1, this.getCoordBaseMode()); + return StructureTFComponentOld.getComponentToAddBoundingBox(dest[0], dest[1], dest[2], 0, 0, 0, dSize - 1, dHeight - 1, dSize - 1, this.getCoordBaseMode()); } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make walls for (int x = 0; x < 3; x++) { - placeBlockAtCurrentPosition(world, Blocks.fence, 0, x, 2, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, x, 2, 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, x, 1, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, x, 1, 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, x, 0, 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, x, 0, 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, x, 0, 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, x, -1, 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x, 2, 0, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x, 2, 2, sbb); + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), x, 1, 0, sbb); + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), x, 1, 2, sbb); + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), x, 0, 0, sbb); + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), x, 0, 1, sbb); + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), x, 0, 2, sbb); + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), x, -1, 1, sbb); } - + // try two blocks outside the boundries - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, -1, -1, 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, 3, -1, 1, sbb); - + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), -1, -1, 1, sbb); + setBlockState(world, Blocks.STONEBRICK.getDefaultState(), 3, -1, 1, sbb); + // clear bridge walkway this.fillWithAir(world, sbb, 0, 1, 1, 2, 2, 1); - // marker blocks -// placeBlockAtCurrentPosition(world, Blocks.wool, this.coordBaseMode, size / 2, 2, size / 2, sbb); -// placeBlockAtCurrentPosition(world, Blocks.gold_block, 0, 0, 0, 0, sbb); - - // door opening? + // marker blocks +// setBlockState(world, Blocks.WOOL, this.coordBaseMode, size / 2, 2, size / 2, sbb); +// setBlockState(world, Blocks.GOLD_BLOCK, 0, 0, 0, 0, sbb); + + // door opening? // makeDoorOpening(world, sbb); - - - + + return true; } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerMain.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerMain.java index 947fe9229d..a2986929df 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerMain.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerMain.java @@ -1,148 +1,161 @@ package twilightforest.structures.lichtower; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.BlockTorch; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFBossSpawner; import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; -import twilightforest.structures.StructureTFComponent; +import twilightforest.enums.BossVariant; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; +import twilightforest.util.TFEntityNames; +import twilightforest.util.VanillaEntityNames; + +import java.util.List; +import java.util.Random; public class ComponentTFTowerMain extends ComponentTFTowerWing { public ComponentTFTowerMain() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerMain(World world, Random rand, int index, int x, int y, int z) { + public ComponentTFTowerMain(TFFeature feature, World world, Random rand, int index, int x, int y, int z) { // some of these are subject to change if the ground level is > 30. - super(index, x, y, z, 15, 55 + rand.nextInt(32), 0); + super(feature, index, x, y, z, 15, 55 + rand.nextInt(32), EnumFacing.SOUTH); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { + public void buildComponent(StructureComponent parent, List list, Random rand) { // add a roof? makeARoof(parent, list, rand); // sub towers - for (int i = 0; i < 4; i++) { - int[] dest = getValidOpening(rand, i); - + for (final Rotation rotation : RotationUtil.ROTATIONS) { + int[] dest = getValidOpening(rand, rotation); + // adjust height if we're too low at this point if (dest[1] < height / 2) { dest[1] += 20; } - + int childHeight = Math.min(21 + rand.nextInt(10), this.height - dest[1] - 3); - - if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 9, childHeight, i)) { - makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 7, childHeight, i); + + if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 9, childHeight, rotation)) { + makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 7, childHeight, rotation); } } // try one more time for large towers - for (int i = 0; i < 4; i++) { - int[] dest = getValidOpening(rand, i); - + for (final Rotation rotation : RotationUtil.ROTATIONS) { + int[] dest = getValidOpening(rand, rotation); + // adjust height if we're too low at this point if (dest[1] < height / 2) { dest[1] += 10; } - + int childHeight = Math.min(21 + rand.nextInt(10), this.height - dest[1] - 3); - - if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 9, childHeight, i)) { - makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 7, childHeight, i); + + if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 9, childHeight, rotation)) { + makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 7, childHeight, rotation); } } // another set, if possible - for (int i = 0; i < 4; i++) { - int[] dest = getValidOpening(rand, i); - + for (final Rotation rotation : RotationUtil.ROTATIONS) { + int[] dest = getValidOpening(rand, rotation); + int childHeight = Math.min(7 + rand.nextInt(6), this.height - dest[1] - 3); - - if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 5, childHeight, i)) { - makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 3, childHeight, i); + + if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 5, childHeight, rotation)) { + makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 3, childHeight, rotation); } } - + // outbuildings - for (int i = 0; i < 4; i++) { - int[] dest = getOutbuildingOpening(rand, i); - + for (final Rotation rotation : RotationUtil.ROTATIONS) { + int[] dest = getOutbuildingOpening(rand, rotation); + int childHeight = 11 + rand.nextInt(10); int childSize = 7 + (rand.nextInt(2) * 2); - - makeTowerOutbuilding(list, rand, 1, dest[0], dest[1], dest[2], childSize, childHeight, i); + + makeTowerOutbuilding(list, rand, 1, dest[0], dest[1], dest[2], childSize, childHeight, rotation); } - + // TINY TOWERS! - for (int i = 0; i < 16; i++) { - int[] dest = getValidOpening(rand, i % 4); - int childHeight = 6 + rand.nextInt(5); - if (rand.nextInt(3) == 0 || !makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 5, childHeight, i % 4)) { - makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 3, childHeight, i % 4); + for (int i = 0; i < 4; i++) { + for (final Rotation towerRotation : RotationUtil.ROTATIONS) { + int[] dest = getValidOpening(rand, towerRotation); + int childHeight = 6 + rand.nextInt(5); + if (rand.nextInt(3) == 0 || !makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 5, childHeight, towerRotation)) { + makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], 3, childHeight, towerRotation); + } } + } - + } - + /** * Gets a random position in the specified direction that we can make an outbuilding at */ - public int[] getOutbuildingOpening(Random rand, int rotation) { - + public int[] getOutbuildingOpening(Random rand, Rotation rotation) { + int rx = 0; int ry = 1; int rz = 0; - + switch (rotation) { - case 0: - // for directions 0 or 2, the wall lies along the z axis - rx = size -1; - rz = 6 + rand.nextInt(8); - break; - case 1: - // for directions 1 or 3, the wall lies along the x axis - rx = 1 + rand.nextInt(11); - rz = size - 1; - break; - case 2: - rx = 0; - rz = 1 + rand.nextInt(8); - break; - case 3: - rx = 3 + rand.nextInt(11); - rz = 0; - break; + case NONE: + // for directions 0 or 2, the wall lies along the z axis + rx = size - 1; + rz = 6 + rand.nextInt(8); + break; + case CLOCKWISE_90: + // for directions 1 or 3, the wall lies along the x axis + rx = 1 + rand.nextInt(11); + rz = size - 1; + break; + case CLOCKWISE_180: + rx = 0; + rz = 1 + rand.nextInt(8); + break; + case COUNTERCLOCKWISE_90: + rx = 3 + rand.nextInt(11); + rz = 0; + break; } - return new int[] {rx, ry, rz}; + return new int[]{rx, ry, rz}; } - - public boolean makeTowerOutbuilding(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; + + public boolean makeTowerOutbuilding(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - ComponentTFTowerOutbuilding outbuilding = new ComponentTFTowerOutbuilding(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFTowerOutbuilding outbuilding = new ComponentTFTowerOutbuilding(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, outbuilding.getBoundingBox()); - if (intersect == null || intersect == this) { + if (intersect == null) { list.add(outbuilding); outbuilding.buildComponent(this, list, rand); addOpening(x, y, z, rotation); return true; } else { -// System.out.println("Planned outbuilding intersects with " + intersect); return false; } } @@ -151,53 +164,50 @@ public boolean makeTowerOutbuilding(List list, Random rand, @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make walls - fillWithRandomizedBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, false, rand, StructureTFComponent.getStrongholdStones()); - + fillWithRandomizedBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, false, rand, StructureTFComponentOld.getStrongholdStones()); + // clear inside fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); - + final IBlockState defaultState = Blocks.COBBLESTONE.getDefaultState(); // stone to ground - for (int x = 0; x < this.size; x++) - { - for (int z = 0; z < this.size; z++) - { - this.func_151554_b(world, Blocks.cobblestone, 0, x, -1, z, sbb); + for (int x = 0; x < this.size; x++) { + for (int z = 0; z < this.size; z++) { + this.replaceAirAndLiquidDownwards(world, defaultState, x, -1, z, sbb); } } - - // nullify sky light + + // nullify sky light nullifySkyLightForBoundingBox(world); - - // fix highestOpening parameter so we don't get a ginormous lich room - if ((height - highestOpening) > 15) { - highestOpening = height - 15; - } - + + // fix highestOpening parameter so we don't get a ginormous lich room + if ((height - highestOpening) > 15) { + highestOpening = height - 15; + } + // stairs! makeStairs(world, rand, sbb); // throw a bunch of opening markers in there -// makeOpeningMarkers(world, rand, 100, sbb); + //makeOpeningMarkers(world, rand, 100, sbb); // openings makeOpenings(world, sbb); - // decorate? + // decorate? decorateStairFloor(world, rand, sbb); - + // stairway crossings makeStairwayCrossings(world, rand, sbb); - + // LICH TIME makeLichRoom(world, rand, sbb); - + // extra paintings in main tower makeTowerPaintings(world, rand, sbb); - return true; } @@ -206,74 +216,72 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox */ protected void makeStairwayCrossings(World world, Random rand, StructureBoundingBox sbb) { int flights = (this.highestOpening / 5) - 2; - + for (int i = 2 + rand.nextInt(2); i < flights; i += 1 + rand.nextInt(5)) { makeStairCrossing(world, rand, i, sbb); } } protected void makeStairCrossing(World world, Random rand, int flight, StructureBoundingBox sbb) { - int temp = this.getCoordBaseMode(); + EnumFacing temp = this.getCoordBaseMode(); if (flight % 2 == 0) { - this.setCoordBaseMode((getCoordBaseMode() + 1) % 4); + this.setCoordBaseMode(getStructureRelativeRotation(Rotation.CLOCKWISE_90)); } - - int floorMeta = rand.nextInt(2) == 0 ? 0 : 2; - int floorLevel = 0 + flight * 5; - + // place platform + int floorLevel = 0 + flight * 5; + IBlockState crossingfloor = rand.nextBoolean() ? Blocks.DOUBLE_STONE_SLAB.getDefaultState() : Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); for (int dx = 6; dx <= 8; dx++) { for (int dz = 4; dz <= 10; dz++) { - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, floorMeta, dx, floorLevel, dz, sbb); + setBlockState(world, crossingfloor, dx, floorLevel, dz, sbb); } } - + // put fences floorLevel++; int dx = 6; for (int dz = 3; dz <= 11; dz++) { - placeBlockAtCurrentPosition(world, Blocks.fence, 0, dx, floorLevel, dz, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), dx, floorLevel, dz, sbb); } dx++; for (int dz = 3; dz <= 11; dz++) { - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, floorLevel, dz, sbb); + setBlockState(world, AIR, dx, floorLevel, dz, sbb); } dx++; for (int dz = 3; dz <= 11; dz++) { - placeBlockAtCurrentPosition(world, Blocks.fence, 0, dx, floorLevel, dz, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), dx, floorLevel, dz, sbb); } // we need 2 extra blocks and 2 extra fences to look good - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, floorMeta, 6, floorLevel - 1, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, floorMeta, 8, floorLevel - 1, 3, sbb); - - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 5, floorLevel, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 9, floorLevel, 3, sbb); - + setBlockState(world, crossingfloor, 6, floorLevel - 1, 11, sbb); + setBlockState(world, crossingfloor, 8, floorLevel - 1, 3, sbb); + + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), 5, floorLevel, 11, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), 9, floorLevel, 3, sbb); + // place spawner in the middle - String mobID = "Skeleton"; - switch (rand.nextInt(4)) - { - case 0: - case 1: - mobID = "Skeleton"; - break; - case 2: - mobID = "Zombie"; - break; - case 3: - mobID = TFCreatures.getSpawnerNameFor("Swarm Spider"); - break; + ResourceLocation mobID = VanillaEntityNames.SKELETON; + switch (rand.nextInt(4)) { + case 0: + case 1: + mobID = VanillaEntityNames.SKELETON; + break; + case 2: + mobID = VanillaEntityNames.ZOMBIE; + break; + case 3: + mobID = TFEntityNames.SWARM_SPIDER; + break; } - placeSpawnerAtCurrentPosition(world, rand, 7, floorLevel + 2, 7, mobID, sbb); - + setSpawner(world, 7, floorLevel + 2, 7, sbb, mobID); + // make a fence arch support for the spawner - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 6, floorLevel + 1, 7, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 8, floorLevel + 1, 7, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 6, floorLevel + 2, 7, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 8, floorLevel + 2, 7, sbb); - - + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), 6, floorLevel + 1, 7, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), 8, floorLevel + 1, 7, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), 6, floorLevel + 2, 7, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), 8, floorLevel + 2, 7, sbb); + + this.setCoordBaseMode(temp); } @@ -284,19 +292,20 @@ protected void makeLichRoom(World world, Random rand, StructureBoundingBox sbb) // figure out where the stairs end int floorLevel = 2 + (this.highestOpening / 5) * 5; // we need a floor - makeLichFloor(world, floorLevel, (this.highestOpening / 5) % 2, sbb); - + final Rotation i = (this.highestOpening / 5) % 2 == 0 ? Rotation.NONE : Rotation.CLOCKWISE_90; + makeLichFloor(world, floorLevel, i, sbb); + // now a chandelier decorateLichChandelier(world, floorLevel, sbb); - - // make paintings - decoratePaintings(world, rand, floorLevel, sbb); - + // and wall torches decorateTorches(world, rand, floorLevel, sbb); - + + // make paintings + decoratePaintings(world, rand, floorLevel, sbb); + // seems like we should have a spawner - placeBlockAtCurrentPosition(world, TFBlocks.bossSpawner, 1, size / 2, floorLevel + 2, size / 2, sbb); + setBlockState(world, TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.LICH), size / 2, floorLevel + 2, size / 2, sbb); } @@ -304,30 +313,36 @@ protected void makeTowerPaintings(World world, Random rand, StructureBoundingBox int howMany = 10; // do wall 0. - generatePaintingsOnWall(world, rand, howMany, 0, 0, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 0, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 0, 0, sbb); - + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.WEST, 48, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.WEST, 32, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.WEST, 0, sbb); + // do wall 1. - generatePaintingsOnWall(world, rand, howMany, 0, 1, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 1, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 1, 0, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.EAST, 48, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.EAST, 32, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.EAST, 0, sbb); // do wall 2. - generatePaintingsOnWall(world, rand, howMany, 0, 2, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 2, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 2, 0, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.NORTH, 48, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.NORTH, 32, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.NORTH, 0, sbb); // do wall 3. - generatePaintingsOnWall(world, rand, howMany, 0, 3, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 3, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, 0, 3, 0, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.SOUTH, 48, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.SOUTH, 32, sbb); + generatePaintingsOnWall(world, rand, howMany, 0, EnumFacing.SOUTH, 0, sbb); } /** * Make the floor for the liches room */ - protected void makeLichFloor(World world, int floorLevel, int rotation, StructureBoundingBox sbb) { - int temp = this.getCoordBaseMode(); - this.setCoordBaseMode((this.getCoordBaseMode() + rotation) % 4); + protected void makeLichFloor(World world, int floorLevel, Rotation rotation, StructureBoundingBox sbb) { + EnumFacing temp = this.getCoordBaseMode(); + this.setCoordBaseMode(getStructureRelativeRotation(rotation)); + + BlockPlanks.EnumType birch = BlockPlanks.EnumType.BIRCH; + IBlockState birchSlab = Blocks.WOODEN_SLAB.getDefaultState() + .withProperty(BlockPlanks.VARIANT, birch) + .withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP); + IBlockState birchPlank = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, birch); // place a platform there for (int fx = 1; fx < 14; fx++) { @@ -336,52 +351,46 @@ protected void makeLichFloor(World world, int floorLevel, int rotation, Structur // blank, leave room for stairs if (fz == 6) { // upside down plank slabs - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 10, fx, floorLevel, fz, sbb); + setBlockState(world, birchSlab, fx, floorLevel, fz, sbb); } - } - else if ((fx == 12 || fx == 13) && (fz >= 3 && fz <= 8)) { + } else if ((fx == 12 || fx == 13) && (fz >= 3 && fz <= 8)) { // blank, leave room for stairs if (fz == 8) { // upside down plank slabs - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 10, fx, floorLevel, fz, sbb); + setBlockState(world, birchSlab, fx, floorLevel, fz, sbb); } - } - else if ((fx >= 4 && fx <= 10) && (fz >= 4 && fz <= 10)) { + } else if ((fx >= 4 && fx <= 10) && (fz >= 4 && fz <= 10)) { // glass floor in center, aside from 2 corners if ((fx == 4 && fz == 4) || (fx == 10 && fz == 10)) { - placeBlockAtCurrentPosition(world, Blocks.planks, 2, fx, floorLevel, fz, sbb); - } - else { - placeBlockAtCurrentPosition(world, Blocks.glass, 0, fx, floorLevel, fz, sbb); + setBlockState(world, birchPlank, fx, floorLevel, fz, sbb); + } else { + setBlockState(world, Blocks.GLASS.getDefaultState(), fx, floorLevel, fz, sbb); } - } - else if ((fx == 2 || fx == 3) && (fz == 2 || fz == 3)) { + } else if ((fx == 2 || fx == 3) && (fz == 2 || fz == 3)) { // glass blocks in the corners - placeBlockAtCurrentPosition(world, Blocks.glass, 0, fx, floorLevel, fz, sbb); - } - else if ((fx == 11 || fx == 12) && (fz == 11 || fz == 12)) { + setBlockState(world, Blocks.GLASS.getDefaultState(), fx, floorLevel, fz, sbb); + } else if ((fx == 11 || fx == 12) && (fz == 11 || fz == 12)) { // glass blocks in the corners - placeBlockAtCurrentPosition(world, Blocks.glass, 0, fx, floorLevel, fz, sbb); - } - else { - placeBlockAtCurrentPosition(world, Blocks.planks, 2, fx, floorLevel, fz, sbb); + setBlockState(world, Blocks.GLASS.getDefaultState(), fx, floorLevel, fz, sbb); + } else { + setBlockState(world, birchPlank, fx, floorLevel, fz, sbb); } } } - + // eliminate the railings - placeBlockAtCurrentPosition(world, Blocks.air, 0, 3, floorLevel + 1, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, 3, floorLevel + 1, 10, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, 3, floorLevel + 2, 11, sbb); - - placeBlockAtCurrentPosition(world, Blocks.air, 0, 11, floorLevel + 1, 3, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, 11, floorLevel + 1, 4, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, 11, floorLevel + 2, 3, sbb); - + setBlockState(world, AIR, 3, floorLevel + 1, 11, sbb); + setBlockState(world, AIR, 3, floorLevel + 1, 10, sbb); + setBlockState(world, AIR, 3, floorLevel + 2, 11, sbb); + + setBlockState(world, AIR, 11, floorLevel + 1, 3, sbb); + setBlockState(world, AIR, 11, floorLevel + 1, 4, sbb); + setBlockState(world, AIR, 11, floorLevel + 2, 3, sbb); + this.setCoordBaseMode(temp); } - + /** * Make a fancy chandelier for the lich's room */ @@ -390,41 +399,41 @@ protected void decorateLichChandelier(World world, int floorLevel, StructureBoun int cy = floorLevel + 4; int cz = size / 2; - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 1, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 2, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 1, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy, cz + 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx - 1, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx - 1, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx - 2, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx - 1, cy, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy, cz - 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 1, cy, cz - 1, sbb); - + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 1, cy, cz + 0, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 2, cy, cz + 0, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 1, cy, cz + 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 0, cy, cz + 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 0, cy, cz + 2, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx - 1, cy, cz + 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx - 1, cy, cz + 0, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx - 2, cy, cz + 0, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx - 1, cy, cz - 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 0, cy, cz - 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 0, cy, cz - 2, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 1, cy, cz - 1, sbb); + cy++; - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 1, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 2, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 1, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 0, cy, cz + 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx - 1, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx - 1, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx - 2, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx - 1, cy, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 0, cy, cz - 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 1, cy, cz - 1, sbb); - + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 1, cy, cz + 0, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 2, cy, cz + 0, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 1, cy, cz + 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 0, cy, cz + 1, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 0, cy, cz + 2, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx - 1, cy, cz + 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx - 1, cy, cz + 0, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx - 2, cy, cz + 0, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx - 1, cy, cz - 1, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 0, cy, cz - 1, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 0, cy, cz - 2, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 1, cy, cz - 1, sbb); + cy++; - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 1, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 0, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx - 1, cy, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 0, cy, cz - 1, sbb); - + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 1, cy, cz + 0, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 0, cy, cz + 1, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx - 1, cy, cz + 0, sbb); + setBlockState(world, Blocks.TORCH.getDefaultState(), cx + 0, cy, cz - 1, sbb); + for (int y = floorLevel + 5; y < height - 1; y++) { - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, y, cz + 0, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), cx + 0, y, cz + 0, sbb); } } @@ -434,72 +443,49 @@ protected void decorateLichChandelier(World world, int floorLevel, StructureBoun protected void decoratePaintings(World world, Random rand, int floorLevel, StructureBoundingBox sbb) { int howMany = 100; - // do wall 0. - generatePaintingsOnWall(world, rand, howMany, floorLevel, 0, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 0, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 0, 0, sbb); - - // do wall 1. - generatePaintingsOnWall(world, rand, howMany, floorLevel, 1, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 1, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 1, 0, sbb); - // do wall 2. - generatePaintingsOnWall(world, rand, howMany, floorLevel, 2, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 2, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 2, 0, sbb); - // do wall 3. - generatePaintingsOnWall(world, rand, howMany, floorLevel, 3, 48, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 3, 32, sbb); - generatePaintingsOnWall(world, rand, howMany, floorLevel, 3, 0, sbb); - + for (final EnumFacing horizontal : EnumFacing.HORIZONTALS) { + // do wall 0. + generatePaintingsOnWall(world, rand, howMany, floorLevel, horizontal, 48, sbb); + generatePaintingsOnWall(world, rand, howMany, floorLevel, horizontal, 32, sbb); + generatePaintingsOnWall(world, rand, howMany, floorLevel, horizontal, 0, sbb); + } } - + /** * Put torches on each wall */ protected void decorateTorches(World world, Random rand, int floorLevel, StructureBoundingBox sbb) { - generateTorchesOnWall(world, rand, floorLevel, 0, sbb); - generateTorchesOnWall(world, rand, floorLevel, 1, sbb); - generateTorchesOnWall(world, rand, floorLevel, 2, sbb); - generateTorchesOnWall(world, rand, floorLevel, 3, sbb); + generateTorchesOnWall(world, rand, floorLevel, EnumFacing.SOUTH, sbb); + generateTorchesOnWall(world, rand, floorLevel, EnumFacing.EAST, sbb); + generateTorchesOnWall(world, rand, floorLevel, EnumFacing.NORTH, sbb); + generateTorchesOnWall(world, rand, floorLevel, EnumFacing.WEST, sbb); } /** - * Place up to 10 torches (with fence holders) on the wall, checking that they don't overlap any paintings or other torches + * Place up to 5 torches (with fence holders) on the wall, checking that they don't overlap any paintings or other torches */ protected void generateTorchesOnWall(World world, Random rand, - int floorLevel, int direction, StructureBoundingBox sbb) { - for (int i = 0; i < 10; i++) { + int floorLevel, EnumFacing direction, StructureBoundingBox sbb) { + for (int i = 0; i < 5; i++) { // get some random coordinates on the wall in the chunk - ChunkCoordinates wCoords = getRandomWallSpot(rand, floorLevel, direction, sbb); + BlockPos wCoords = getRandomWallSpot(rand, floorLevel, direction, sbb); // offset to see where the fence should be - ChunkCoordinates tCoords = new ChunkCoordinates(wCoords); - if (direction == 0) { - tCoords.posZ++; - } - if (direction == 1) { - tCoords.posX--; - } - if (direction == 2) { - tCoords.posZ--; - } - if (direction == 3) { - tCoords.posX++; - } - + BlockPos.MutableBlockPos tCoords = new BlockPos.MutableBlockPos(wCoords); // is there a painting or another torch there? - AxisAlignedBB torchBox = AxisAlignedBB.getBoundingBox(tCoords.posX, tCoords.posY, tCoords.posZ, tCoords.posX + 1.0, tCoords.posY + 2.0, tCoords.posZ + 1.0); - if (world.getBlock(tCoords.posX, tCoords.posY, tCoords.posZ) == Blocks.air && world.getBlock(tCoords.posX, tCoords.posY + 1, tCoords.posZ) == Blocks.air && world.getEntitiesWithinAABBExcludingEntity(null, torchBox).size() == 0) - { - // if not, place a torch - world.setBlock(tCoords.posX, tCoords.posY, tCoords.posZ, Blocks.fence, 0, 2); - world.setBlock(tCoords.posX, tCoords.posY + 1, tCoords.posZ, Blocks.torch, 5, 2); + AxisAlignedBB torchBox = new AxisAlignedBB(tCoords.getX(), tCoords.getY(), tCoords.getZ(), tCoords.getX() + 1.0, tCoords.getY() + 2.0, tCoords.getZ() + 1.0); + IBlockState blockState = world.getBlockState(tCoords); + IBlockState aboveBlockState = world.getBlockState(tCoords.up()); + if (blockState.getMaterial() == Material.AIR && + aboveBlockState.getMaterial() == Material.AIR && + world.getEntitiesWithinAABBExcludingEntity(null, torchBox).size() == 0) { + // if not, place a torch + world.setBlockState(tCoords, Blocks.OAK_FENCE.getDefaultState(), 2); + world.setBlockState(tCoords.up(), Blocks.TORCH.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.UP), 2); } } } - } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerOutbuilding.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerOutbuilding.java index 489745a53e..c36408b87e 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerOutbuilding.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerOutbuilding.java @@ -1,24 +1,26 @@ package twilightforest.structures.lichtower; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFTowerOutbuilding extends ComponentTFTowerWing { public ComponentTFTowerOutbuilding() { super(); - // TODO Auto-generated constructor stub } - protected ComponentTFTowerOutbuilding(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); - // TODO Auto-generated constructor stub + protected ComponentTFTowerOutbuilding(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } /** @@ -33,27 +35,24 @@ public void makeABeard(StructureComponent parent, List list, * Outbuildings should not make new wings close to the ground. */ @Override - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int direction) { + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation direction) { if (y > 7) { return super.makeTowerWing(list, rand, index, x, y, z, wingSize, wingHeight, direction); - } - else { + } else { return false; } } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - for (int x = 0; x < this.size; x++) - { - for (int z = 0; z < this.size; z++) - { - this.func_151554_b(world, Blocks.cobblestone, 0, x, -1, z, sbb); + final IBlockState cobblestone = Blocks.COBBLESTONE.getDefaultState(); + for (int x = 0; x < this.size; x++) { + for (int z = 0; z < this.size; z++) { + this.replaceAirAndLiquidDownwards(world, cobblestone, x, -1, z, sbb); } } return super.addComponentParts(world, rand, sbb); } - - + } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoof.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoof.java index 4a7672254f..372d3e61a7 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoof.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoof.java @@ -1,91 +1,94 @@ package twilightforest.structures.lichtower; -import java.util.List; -import java.util.Random; - import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; -public abstract class ComponentTFTowerRoof extends StructureTFComponent { - +public abstract class ComponentTFTowerRoof extends StructureTFComponentOld { + protected int size; protected int height; public ComponentTFTowerRoof() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoof(int i, ComponentTFTowerWing wing) { - super(i); - + public ComponentTFTowerRoof(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i); + this.spawnListIndex = -1; - + // inheritors need to add a bounding box or die~! } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("roofSize", this.size); - par1NBTTagCompound.setInteger("roofHeight", this.height); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("roofSize", this.size); + tagCompound.setInteger("roofHeight", this.height); } /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.size = par1NBTTagCompound.getInteger("roofSize"); - this.height = par1NBTTagCompound.getInteger("roofHeight"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.size = tagCompound.getInteger("roofSize"); + this.height = tagCompound.getInteger("roofHeight"); } - + /** - * Makes a bounding box that hangs forwards off of the tower wing we are on. This is for attached roofs. - * + * Makes a bounding box that hangs forwards off of the tower wing we are on. This is for attached roofs. + * * @param wing */ protected void makeAttachedOverhangBB(ComponentTFTowerWing wing) { // just hang out at the very top of the tower switch (getCoordBaseMode()) { - case 0: - this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ - 1, wing.getBoundingBox().maxX + 1, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ + 1); - break; - case 1: - this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - 1, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ, wing.getBoundingBox().maxX + 1, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ + 1); - break; - case 2: - this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - 1, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ - 1, wing.getBoundingBox().maxX, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ + 1); - break; - case 3: - this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - 1, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ - 1, wing.getBoundingBox().maxX + 1, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ); - break; + case SOUTH: + this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ - 1, wing.getBoundingBox().maxX + 1, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ + 1); + break; + case WEST: + this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - 1, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ, wing.getBoundingBox().maxX + 1, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ + 1); + break; + case EAST: + this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - 1, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ - 1, wing.getBoundingBox().maxX, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ + 1); + break; + case NORTH: + this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - 1, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ - 1, wing.getBoundingBox().maxX + 1, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ); + break; + default: + break; } } - + /** * Makes a bounding box that sits at the top of the tower. Works for attached or freestanding roofs. - * + * * @param wing */ protected void makeCapBB(ComponentTFTowerWing wing) { this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ, wing.getBoundingBox().maxX, wing.getBoundingBox().maxY + this.height, wing.getBoundingBox().maxZ); } - + /** - * Make a bounding box that hangs over the sides of the tower 1 block. Freestanding towers only. - * + * Make a bounding box that hangs over the sides of the tower 1 block. Freestanding towers only. + * * @param wing */ protected void makeOverhangBB(ComponentTFTowerWing wing) { @@ -93,10 +96,8 @@ protected void makeOverhangBB(ComponentTFTowerWing wing) { } - - @Override - public boolean addComponentParts(World world, Random random,StructureBoundingBox structureboundingbox) { + public boolean addComponentParts(World world, Random random, StructureBoundingBox structureboundingbox) { return false; } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofAttachedSlab.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofAttachedSlab.java index f0cc8879e5..ad6f5c3b2e 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofAttachedSlab.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofAttachedSlab.java @@ -1,20 +1,21 @@ package twilightforest.structures.lichtower; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFTowerRoofAttachedSlab extends ComponentTFTowerRoofSlab { public ComponentTFTowerRoofAttachedSlab() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofAttachedSlab(int i, ComponentTFTowerWing wing) { - super(i, wing); + public ComponentTFTowerRoofAttachedSlab(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); } /** @@ -22,7 +23,6 @@ public ComponentTFTowerRoofAttachedSlab(int i, ComponentTFTowerWing wing) { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - int slabMeta = 2; - return makeConnectedCap(world, slabMeta, sbb); + return makeConnectedCap(world, BlockPlanks.EnumType.BIRCH, sbb); } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofFence.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofFence.java index 0800098c4c..be658a7b6a 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofFence.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofFence.java @@ -1,28 +1,28 @@ package twilightforest.structures.lichtower; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFTowerRoofFence extends ComponentTFTowerRoof { public ComponentTFTowerRoofFence() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofFence(int i, ComponentTFTowerWing wing) { - super(i, wing); + public ComponentTFTowerRoofFence(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); // same alignment this.setCoordBaseMode(wing.getCoordBaseMode()); // same size this.size = wing.size; // assuming only square towers and roofs right now. this.height = 0; - + // just hang out at the very top of the tower makeCapBB(wing); } @@ -36,7 +36,7 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox for (int x = 0; x <= size - 1; x++) { for (int z = 0; z <= size - 1; z++) { if (x == 0 || x == size - 1 || z == 0 || z == size - 1) { - placeBlockAtCurrentPosition(world, Blocks.fence, 0, x, y, z, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x, y, z, sbb); } } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofGableForwards.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofGableForwards.java index 5b30c7cf08..a654b4981a 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofGableForwards.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofGableForwards.java @@ -1,28 +1,31 @@ package twilightforest.structures.lichtower; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFTowerRoofGableForwards extends ComponentTFTowerRoof { public ComponentTFTowerRoofGableForwards() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofGableForwards(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFTowerRoofGableForwards(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // same facing this.setCoordBaseMode(wing.getCoordBaseMode()); this.size = wing.size + 2; // assuming only square towers and roofs right now. this.height = size; - + // just hang out at the very top of the tower this.makeAttachedOverhangBB(wing); @@ -33,55 +36,53 @@ public ComponentTFTowerRoofGableForwards(int i, ComponentTFTowerWing wing) { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - int slabMeta = 2; + IBlockState birchSlab = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + IBlockState birchPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + int slopeChange = slopeChangeForSize(size); for (int y = 0; y <= height; y++) { int min, max; if (y < slopeChange) { min = y; max = size - y - 1; - } - else { + } else { min = (y + slopeChange) / 2; max = size - ((y + slopeChange) / 2) - 1; } for (int x = 0; x <= size - 2; x++) { for (int z = min; z <= max; z++) { if (z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, x, y, z, sbb); - } - else if (x < size - 2) { - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, x, y, z, sbb); + setBlockState(world, birchPlanks, x, y, z, sbb); + } else if (x < size - 2) { + setBlockState(world, birchPlanks, x, y, z, sbb); } } } - } - + } + // put on the little figurehead-like "cap" - + // where is even the top of our roof? int top = (size + 1) - slopeChange; int zMid = size / 2; - - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, slabMeta | 0xA, size - 1, top - 1, zMid, sbb); - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, slabMeta, 0, top, zMid, sbb); - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, slabMeta, size - 3, top, zMid, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, size - 2, top, zMid, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, size - 1, top, zMid, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, size - 1, top + 1, zMid, sbb); - + + setBlockState(world, birchSlab.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP), size - 1, top - 1, zMid, sbb); + setBlockState(world, birchSlab, 0, top, zMid, sbb); + setBlockState(world, birchSlab, size - 3, top, zMid, sbb); + setBlockState(world, birchPlanks, size - 2, top, zMid, sbb); + setBlockState(world, birchPlanks, size - 1, top, zMid, sbb); + setBlockState(world, birchPlanks, size - 1, top + 1, zMid, sbb); + return true; } - + public int slopeChangeForSize(int pSize) { if (size > 10) { return 3; - } - else if (size > 6) { + } else if (size > 6) { return 2; - } - else { + } else { return 1; } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointy.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointy.java index 1748ffd249..2829cd44cc 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointy.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointy.java @@ -1,28 +1,30 @@ package twilightforest.structures.lichtower; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFTowerRoofPointy extends ComponentTFTowerRoof { public ComponentTFTowerRoofPointy() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofPointy(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFTowerRoofPointy(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // same facing, but it doesn't matter this.setCoordBaseMode(wing.getCoordBaseMode()); this.size = wing.size; // assuming only square towers and roofs right now. this.height = size; - + // just hang out at the very top of the tower makeCapBB(wing); @@ -33,46 +35,44 @@ public ComponentTFTowerRoofPointy(int i, ComponentTFTowerWing wing) { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - int slabMeta = 2; - + IBlockState birchSlab = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + IBlockState birchPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + for (int y = 0; y <= height; y++) { int min, mid, max; int slopeChange = slopeChangeForSize(size); if (y < slopeChange) { min = y; max = size - y - 1; - } - else { + } else { min = (y + slopeChange) / 2; max = size - ((y + slopeChange) / 2) - 1; } mid = min + ((max - min) / 2); for (int x = min; x <= max; x++) { for (int z = min; z <= max; z++) { - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, x, y, z, sbb); + setBlockState(world, birchPlanks, x, y, z, sbb); // some of these are unnecessary and will just be overwritten by a normal block, but whatevs. if ((x == min && (z == min || z == max)) || (x == max && (z == min || z == max))) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, slabMeta, x, y + 1, z, sbb); + setBlockState(world, birchSlab, x, y + 1, z, sbb); } // mid blocks if (((((x == min || x == max) && z == mid) && x % 2 == 0) || (((z == min || z == max) && x == mid) && z % 2 == 0)) && mid != min + 1) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, slabMeta, x, y + 1, z, sbb); + setBlockState(world, birchSlab, x, y + 1, z, sbb); } } } - } + } return true; } - + public int slopeChangeForSize(int pSize) { if (size > 10) { return 3; - } - else if (size > 6) { + } else if (size > 6) { return 2; - } - else { + } else { return 1; } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointyOverhang.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointyOverhang.java index edb057d473..f1c64b061e 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointyOverhang.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofPointyOverhang.java @@ -1,22 +1,23 @@ package twilightforest.structures.lichtower; +import twilightforest.TFFeature; + public class ComponentTFTowerRoofPointyOverhang extends ComponentTFTowerRoofPointy { public ComponentTFTowerRoofPointyOverhang() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofPointyOverhang(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFTowerRoofPointyOverhang(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // same facing, but it doesn't matter this.setCoordBaseMode(wing.getCoordBaseMode()); this.size = wing.size + 2; // assuming only square towers and roofs right now. this.height = size; - + // just hang out at the very top of the tower makeOverhangBB(wing); diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlab.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlab.java index 3d164bf16e..23c5e74d26 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlab.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlab.java @@ -1,31 +1,33 @@ package twilightforest.structures.lichtower; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFTowerRoofSlab extends ComponentTFTowerRoof { public ComponentTFTowerRoofSlab() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofSlab(int i, ComponentTFTowerWing wing) { - super(i, wing); + public ComponentTFTowerRoofSlab(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); // same alignment this.setCoordBaseMode(wing.getCoordBaseMode()); // same size this.size = wing.size; // assuming only square towers and roofs right now. this.height = size / 2; - + // just hang out at the very top of the tower makeCapBB(wing); - + } /** @@ -33,46 +35,49 @@ public ComponentTFTowerRoofSlab(int i, ComponentTFTowerWing wing) { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - int slabMeta = 2; - return makePyramidCap(world, slabMeta, sbb); + BlockPlanks.EnumType woodType = BlockPlanks.EnumType.BIRCH; + + return makePyramidCap(world, woodType, sbb); } - protected boolean makePyramidCap(World world, int slabMeta, StructureBoundingBox sbb) { + protected boolean makePyramidCap(World world, BlockPlanks.EnumType woodType, StructureBoundingBox sbb) { + IBlockState woodenSlab = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, woodType); + IBlockState woodenPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, woodType); for (int y = 0; y <= height; y++) { int min = 2 * y; int max = size - (2 * y) - 1; for (int x = min; x <= max; x++) { for (int z = min; z <= max; z++) { if (x == min || x == max || z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, slabMeta, x, y, z, sbb); - } - else - { - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, x, y, z, sbb); + + setBlockState(world, woodenSlab, x, y, z, sbb); + } else { + setBlockState(world, woodenPlanks, x, y, z, sbb); } } } - } - return true; + } + return true; } - protected boolean makeConnectedCap(World world, int slabMeta, StructureBoundingBox sbb) { + protected boolean makeConnectedCap(World world, BlockPlanks.EnumType woodType, StructureBoundingBox sbb) { + IBlockState woodenSlab = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, woodType); + IBlockState woodenPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, woodType); + for (int y = 0; y < height; y++) { int min = 2 * y; int max = size - (2 * y) - 1; for (int x = 0; x <= max; x++) { for (int z = min; z <= max; z++) { if (x == max || z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, slabMeta, x, y, z, sbb); - } - else - { - placeBlockAtCurrentPosition(world, Blocks.planks, slabMeta, x, y, z, sbb); + setBlockState(world, woodenSlab, x, y, z, sbb); + } else { + setBlockState(world, woodenPlanks, x, y, z, sbb); } } } - } - return true; + } + return true; } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlabForwards.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlabForwards.java index 4d5fa47adb..2e29e1e5b7 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlabForwards.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofSlabForwards.java @@ -1,34 +1,35 @@ package twilightforest.structures.lichtower; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; /** * A flat tower roof using slabs that is larger than the tower under it. - * - * @author Ben * + * @author Ben */ public class ComponentTFTowerRoofSlabForwards extends ComponentTFTowerRoofSlab { public ComponentTFTowerRoofSlabForwards() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofSlabForwards(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFTowerRoofSlabForwards(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // same alignment this.setCoordBaseMode(wing.getCoordBaseMode()); // the overhang roof is like a cap roof that's 2 sizes bigger this.size = wing.size + 2; // assuming only square towers and roofs right now. this.height = size / 2; - + // bounding box makeAttachedOverhangBB(wing); @@ -39,21 +40,22 @@ public ComponentTFTowerRoofSlabForwards(int i, ComponentTFTowerWing wing) { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + IBlockState birchSlab = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + IBlockState birchDoubleSlab = Blocks.DOUBLE_WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + for (int y = 0; y <= height; y++) { int min = 2 * y; int max = size - (2 * y) - 1; for (int x = 0; x <= max - 1; x++) { for (int z = min; z <= max; z++) { if (x == max - 1 || z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, x, y, z, sbb); - } - else - { - placeBlockAtCurrentPosition(world, Blocks.double_wooden_slab, 2, x, y, z, sbb); + setBlockState(world, birchSlab, x, y, z, sbb); + } else { + setBlockState(world, birchDoubleSlab, x, y, z, sbb); } } } - } - return true; + } + return true; } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairs.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairs.java index b75690a018..f284b8a005 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairs.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairs.java @@ -1,28 +1,32 @@ package twilightforest.structures.lichtower; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockStairs; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFTowerRoofStairs extends ComponentTFTowerRoof { public ComponentTFTowerRoofStairs() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofStairs(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFTowerRoofStairs(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // always facing = 0. This roof cannot rotate, due to stair facing issues. - this.setCoordBaseMode(0); + this.setCoordBaseMode(EnumFacing.SOUTH); this.size = wing.size; // assuming only square towers and roofs right now. this.height = size / 2; - + // just hang out at the very top of the tower makeCapBB(wing); @@ -33,6 +37,14 @@ public ComponentTFTowerRoofStairs(int i, ComponentTFTowerWing wing) { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + IBlockState birchSlab = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + IBlockState birchPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + + IBlockState birchStairsNorth = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.NORTH); + IBlockState birchStairsSouth = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.SOUTH); + IBlockState birchStairsEast = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.EAST); + IBlockState birchStairsWest = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.WEST); + for (int y = 0; y <= height; y++) { int min = y; int max = size - y - 1; @@ -40,35 +52,27 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox for (int z = min; z <= max; z++) { if (x == min) { if (z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, x, y, z, sbb); - } - else - { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 0, x, y, z, sbb); + setBlockState(world, birchSlab, x, y, z, sbb); + } else { + setBlockState(world, birchStairsWest, x, y, z, sbb); } - } - else if (x == max) { + } else if (x == max) { if (z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, x, y, z, sbb); - } - else - { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 1, x, y, z, sbb); + setBlockState(world, birchSlab, x, y, z, sbb); + } else { + setBlockState(world, birchStairsEast, x, y, z, sbb); } - } - else if (z == max) { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 3, x, y, z, sbb); - } - else if (z == min) { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 2, x, y, z, sbb); - } - else { - placeBlockAtCurrentPosition(world, Blocks.planks, 2, x, y, z, sbb); + } else if (z == max) { + setBlockState(world, birchStairsSouth, x, y, z, sbb); + } else if (z == min) { + setBlockState(world, birchStairsNorth, x, y, z, sbb); + } else { + setBlockState(world, birchPlanks, x, y, z, sbb); } } } - } - return true; + } + return true; } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairsOverhang.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairsOverhang.java index fc01da3313..f3b3a013d5 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairsOverhang.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerRoofStairsOverhang.java @@ -1,28 +1,32 @@ package twilightforest.structures.lichtower; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockStairs; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFTowerRoofStairsOverhang extends ComponentTFTowerRoof { public ComponentTFTowerRoofStairsOverhang() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFTowerRoofStairsOverhang(int i, ComponentTFTowerWing wing) { - super(i, wing); - + public ComponentTFTowerRoofStairsOverhang(TFFeature feature, int i, ComponentTFTowerWing wing) { + super(feature, i, wing); + // always facing = 0. This roof cannot rotate, due to stair facing issues. - this.setCoordBaseMode(0); + this.setCoordBaseMode(EnumFacing.SOUTH); this.size = wing.size + 2; // assuming only square towers and roofs right now. this.height = size / 2; - + // just hang out at the very top of the tower this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - 1, wing.getBoundingBox().maxY, wing.getBoundingBox().minZ - 1, wing.getBoundingBox().maxX + 1, wing.getBoundingBox().maxY + this.height - 1, wing.getBoundingBox().maxZ + 1); @@ -33,6 +37,14 @@ public ComponentTFTowerRoofStairsOverhang(int i, ComponentTFTowerWing wing) { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + IBlockState woodenSlab = Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + IBlockState woodenPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + + IBlockState birchStairsNorth = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.NORTH); + IBlockState birchStairsSouth = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.SOUTH); + IBlockState birchStairsEast = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.EAST); + IBlockState birchStairsWest = Blocks.BIRCH_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, EnumFacing.WEST); + for (int y = 0; y <= height; y++) { int min = y; int max = size - y - 1; @@ -40,35 +52,27 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox for (int z = min; z <= max; z++) { if (x == min) { if (z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, x, y, z, sbb); - } - else - { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 0, x, y, z, sbb); + setBlockState(world, woodenSlab, x, y, z, sbb); + } else { + setBlockState(world, birchStairsWest, x, y, z, sbb); } - } - else if (x == max) { + } else if (x == max) { if (z == min || z == max) { - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, x, y, z, sbb); - } - else - { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 1, x, y, z, sbb); + setBlockState(world, woodenSlab, x, y, z, sbb); + } else { + setBlockState(world, birchStairsEast, x, y, z, sbb); } - } - else if (z == max) { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 3, x, y, z, sbb); - } - else if (z == min) { - placeBlockAtCurrentPosition(world, Blocks.birch_stairs, 2, x, y, z, sbb); - } - else { - placeBlockAtCurrentPosition(world, Blocks.planks, 2, x, y, z, sbb); + } else if (z == max) { + setBlockState(world, birchStairsSouth, x, y, z, sbb); + } else if (z == min) { + setBlockState(world, birchStairsNorth, x, y, z, sbb); + } else { + setBlockState(world, woodenPlanks, x, y, z, sbb); } } } - } - return true; + } + return true; } } diff --git a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerWing.java b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerWing.java index a8ab89190f..4b61cebbc0 100644 --- a/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerWing.java +++ b/src/main/java/twilightforest/structures/lichtower/ComponentTFTowerWing.java @@ -1,35 +1,44 @@ package twilightforest.structures.lichtower; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockMushroom; -import net.minecraft.block.BlockSapling; -import net.minecraft.block.BlockSlab; +import net.minecraft.block.*; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityHanging; import net.minecraft.entity.item.EntityPainting; import net.minecraft.entity.item.EntityPainting.EnumArt; import net.minecraft.init.Blocks; +import net.minecraft.item.EnumDyeColor; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.structures.StructureTFHelper; +import twilightforest.util.RotationUtil; +import twilightforest.util.TFEntityNames; +import twilightforest.util.VanillaEntityNames; + +import javax.annotation.Nullable; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static net.minecraft.block.BlockStoneSlab.EnumType.SMOOTHBRICK; +import static twilightforest.block.BlockTFCastleMagic.COLOR; +public class ComponentTFTowerWing extends StructureTFComponentOld { -public class ComponentTFTowerWing extends StructureTFComponent { - public ComponentTFTowerWing() { super(); // TODO Auto-generated constructor stub @@ -38,45 +47,42 @@ public ComponentTFTowerWing() { public int size; protected int height; protected Class roofType; - - protected ArrayList openings = new ArrayList(); + + protected ArrayList openings = new ArrayList(); protected int highestOpening; - protected boolean [] openingTowards = new boolean[] {false, false, true, false}; - - protected ComponentTFTowerWing(int i) { - super(i); + protected boolean[] openingTowards = new boolean[]{false, false, true, false}; + + protected ComponentTFTowerWing(TFFeature feature, int i) { + super(feature, i); this.highestOpening = 0; } - protected ComponentTFTowerWing(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i); - + protected ComponentTFTowerWing(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i); + this.size = pSize; this.height = pHeight; this.setCoordBaseMode(direction); - + this.highestOpening = 0; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, size - 1, direction); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, size - 1, direction); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("towerSize", this.size); - par1NBTTagCompound.setInteger("towerHeight", this.height); - - par1NBTTagCompound.setIntArray("doorInts", this.getDoorsAsIntArray()); - - par1NBTTagCompound.setInteger("highestOpening", this.highestOpening); - par1NBTTagCompound.setBoolean("openingTowards0", this.openingTowards[0]); - par1NBTTagCompound.setBoolean("openingTowards1", this.openingTowards[1]); - par1NBTTagCompound.setBoolean("openingTowards2", this.openingTowards[2]); - par1NBTTagCompound.setBoolean("openingTowards3", this.openingTowards[3]); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("towerSize", this.size); + tagCompound.setInteger("towerHeight", this.height); + + tagCompound.setIntArray("doorInts", this.getDoorsAsIntArray()); + + tagCompound.setInteger("highestOpening", this.highestOpening); + tagCompound.setBoolean("openingTowards0", this.openingTowards[0]); + tagCompound.setBoolean("openingTowards1", this.openingTowards[1]); + tagCompound.setBoolean("openingTowards2", this.openingTowards[2]); + tagCompound.setBoolean("openingTowards3", this.openingTowards[3]); } @@ -85,96 +91,85 @@ protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { */ private int[] getDoorsAsIntArray() { IntBuffer ibuffer = IntBuffer.allocate(this.openings.size() * 3); - - for (ChunkCoordinates door : openings) - { - ibuffer.put(door.posX); - ibuffer.put(door.posY); - ibuffer.put(door.posZ); - } - + + for (BlockPos door : openings) { + ibuffer.put(door.getX()); + ibuffer.put(door.getY()); + ibuffer.put(door.getZ()); + } + return ibuffer.array(); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.size = par1NBTTagCompound.getInteger("towerSize"); - this.height = par1NBTTagCompound.getInteger("towerHeight"); - - this.readOpeningsFromArray(par1NBTTagCompound.getIntArray("doorInts")); - - this.highestOpening = par1NBTTagCompound.getInteger("highestOpening"); - // too lazy to do this as a loop - this.openingTowards[0] = par1NBTTagCompound.getBoolean("openingTowards0"); - this.openingTowards[1] = par1NBTTagCompound.getBoolean("openingTowards1"); - this.openingTowards[2] = par1NBTTagCompound.getBoolean("openingTowards2"); - this.openingTowards[3] = par1NBTTagCompound.getBoolean("openingTowards3"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.size = tagCompound.getInteger("towerSize"); + this.height = tagCompound.getInteger("towerHeight"); + + this.readOpeningsFromArray(tagCompound.getIntArray("doorInts")); + + this.highestOpening = tagCompound.getInteger("highestOpening"); + // too lazy to do this as a loop + this.openingTowards[0] = tagCompound.getBoolean("openingTowards0"); + this.openingTowards[1] = tagCompound.getBoolean("openingTowards1"); + this.openingTowards[2] = tagCompound.getBoolean("openingTowards2"); + this.openingTowards[3] = tagCompound.getBoolean("openingTowards3"); } /** * Read in openings from int array */ private void readOpeningsFromArray(int[] intArray) { - for (int i = 0; i < intArray.length; i += 3) - { - ChunkCoordinates door = new ChunkCoordinates(intArray[i], intArray[i + 1], intArray[i + 2]); - + for (int i = 0; i < intArray.length; i += 3) { + BlockPos door = new BlockPos(intArray[i], intArray[i + 1], intArray[i + 2]); + this.openings.add(door); } } - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { + public void buildComponent(StructureComponent parent, List list, Random rand) { // we should have a door where we started - addOpening(0, 1, size / 2, 2); + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); // add a roof? makeARoof(parent, list, rand); - + // add a beard makeABeard(parent, list, rand); - - + + if (size > 4) { // sub towers - for (int i = 0; i < 4; i++) { - if (i == 2) { - // no towers behind us - continue; - } - int[] dest = getValidOpening(rand, i); - if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], size - 2, height - 4, i) && this.size > 8) { - if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], size - 4, height - 6, i)) { - makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], size - 6, height - 12, i); + for (final Rotation towerRotation : RotationUtil.ROTATIONS) { + if (towerRotation == Rotation.CLOCKWISE_180) continue; + int[] dest = getValidOpening(rand, towerRotation); + if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], size - 2, height - 4, towerRotation) && this.size > 8) { + if (!makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], size - 4, height - 6, towerRotation)) { + makeTowerWing(list, rand, 1, dest[0], dest[1], dest[2], size - 6, height - 12, towerRotation); } } } } - - } - - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // kill too-small towers if (wingHeight < 6) { return false; } - - int direction = (getCoordBaseMode() + rotation) % 4; + + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - + if (rand.nextInt(6) == 0) { return makeBridge(list, rand, index, x, y, z, wingSize, wingHeight, rotation); // or I don't know if we just want to continue instead if the bridge fails. // I think there are very few circumstances where we can make a wing and not a bridge } - - ComponentTFTowerWing wing = new ComponentTFTowerWing(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + + ComponentTFTowerWing wing = new ComponentTFTowerWing(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, wing.boundingBox); if (intersect == null || intersect == this) { @@ -183,11 +178,9 @@ public boolean makeTowerWing(List list, Random rand, int ind addOpening(x, y, z, rotation); return true; } else { -// System.out.println("Planned wing intersects with " + intersect); if (rand.nextInt(3) > 0) { return makeBridge(list, rand, index, x, y, z, wingSize, wingHeight, rotation); - } - else { + } else { // I guess we're done for this branch return false; } @@ -195,22 +188,20 @@ public boolean makeTowerWing(List list, Random rand, int ind } - - protected boolean makeBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + protected boolean makeBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // bridges are size 3 always - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 3, direction); // adjust height for those stupid little things if (wingSize == 3 && wingHeight > 10) { wingHeight = 6 + rand.nextInt(5); } - ComponentTFTowerBridge bridge = new ComponentTFTowerBridge(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFTowerBridge bridge = new ComponentTFTowerBridge(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, bridge.boundingBox); if (intersect == null || intersect == this) { intersect = StructureComponent.findIntersecting(list, bridge.getWingBB()); - } - else { + } else { return false; } // okay, I think we can actually make one, as long as we're not still intersecting something. @@ -219,103 +210,100 @@ protected boolean makeBridge(List list, Random rand, int ind bridge.buildComponent(this, list, rand); addOpening(x, y, z, rotation); return true; - } - else { + } else { return false; } } - + /** * Add an opening to the outside (or another tower) in the specified direction. */ - public void addOpening(int dx, int dy, int dz, int direction) { - openingTowards[direction] = true; + public void addOpening(int dx, int dy, int dz, Rotation direction) { + openingTowards[direction.ordinal()] = true; if (dy > highestOpening) { highestOpening = dy; } - openings.add(new ChunkCoordinates(dx, dy, dz)); + openings.add(new BlockPos(dx, dy, dz)); + } + + /** + * Add an opening to the outside (or another tower) in the specified facing. + */ + public void addOpening(int dx, int dy, int dz, EnumFacing facing) { + this.addOpening(dx, dy, dz, RotationUtil.getRelativeRotation(this.getCoordBaseMode(), facing)); } - + /** * Add a beard to this structure. There is only one type of beard. */ public void makeABeard(StructureComponent parent, List list, Random rand) { - + boolean attached = parent.getBoundingBox().minY < this.boundingBox.minY; - + int index = this.getComponentType(); ComponentTFTowerBeard beard; if (attached) { - beard = new ComponentTFTowerBeardAttached(index + 1, this); - } - else { - beard = new ComponentTFTowerBeard(index + 1, this); + beard = new ComponentTFTowerBeardAttached(getFeatureType(), index + 1, this); + } else { + beard = new ComponentTFTowerBeard(getFeatureType(), index + 1, this); } list.add(beard); beard.buildComponent(this, list, rand); } - /** * Attach a roof to this tower. - * + *

* This function keeps trying roofs starting with the largest and fanciest, and then keeps trying smaller and plainer ones */ public void makeARoof(StructureComponent parent, List list, Random rand) { - + // we are attached if our parent is taller than we are boolean attached = parent.getBoundingBox().maxY > this.boundingBox.maxY; - + if (attached) { makeAttachedRoof(list, rand); - } - else { + } else { makeFreestandingRoof(list, rand); } } - protected void makeAttachedRoof(List list, Random rand) { int index = this.getComponentType(); ComponentTFTowerRoof roof; - + // this is our preferred roof type: if (roofType == null && rand.nextInt(32) != 0) { - tryToFitRoof(list, rand, new ComponentTFTowerRoofGableForwards(index + 1, this)); + tryToFitRoof(list, rand, new ComponentTFTowerRoofGableForwards(getFeatureType(), index + 1, this)); } - + // this is for roofs that don't fit. if (roofType == null && rand.nextInt(8) != 0) { - tryToFitRoof(list, rand, new ComponentTFTowerRoofSlabForwards(index + 1, this)); + tryToFitRoof(list, rand, new ComponentTFTowerRoofSlabForwards(getFeatureType(), index + 1, this)); } - + // finally, if we're cramped for space, try this if (roofType == null && rand.nextInt(32) != 0) { // fall through to this next roof - roof = new ComponentTFTowerRoofAttachedSlab(index + 1, this); + roof = new ComponentTFTowerRoofAttachedSlab(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } - + // last resort if (roofType == null) { // fall through to this next roof - roof = new ComponentTFTowerRoofFence(index + 1, this); + roof = new ComponentTFTowerRoofFence(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } } - /** * Check to see if this roof fits. If it does: * Add the specified roof to this tower and set the roofType variable. - * - * @param list - * @param rand - * @param roof */ protected void tryToFitRoof(List list, Random rand, ComponentTFTowerRoof roof) { if (roof.fits(this, list, rand)) { @@ -328,75 +316,73 @@ protected void tryToFitRoof(List list, Random rand, Componen protected void makeFreestandingRoof(List list, Random rand) { int index = this.getComponentType(); ComponentTFTowerRoof roof; - + // most roofs that fit fancy roofs will be this if (roofType == null && rand.nextInt(8) != 0) { - roof = new ComponentTFTowerRoofPointyOverhang(index + 1, this); + roof = new ComponentTFTowerRoofPointyOverhang(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } - + // don't pass by this one if it fits if (roofType == null) { - roof = new ComponentTFTowerRoofStairsOverhang(index + 1, this); + roof = new ComponentTFTowerRoofStairsOverhang(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } - + // don't pass by this one if it fits if (roofType == null) { - roof = new ComponentTFTowerRoofStairs(index + 1, this); + roof = new ComponentTFTowerRoofStairs(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } - + if (roofType == null && rand.nextInt(53) != 0) { // fall through to this next roof - roof = new ComponentTFTowerRoofSlab(index + 1, this); + roof = new ComponentTFTowerRoofSlab(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } - + if (roofType == null) { // fall through to this next roof - roof = new ComponentTFTowerRoofFence(index + 1, this); + roof = new ComponentTFTowerRoofFence(getFeatureType(), index + 1, this); tryToFitRoof(list, rand, roof); } } - - @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make walls - fillWithRandomizedBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, false, rand, StructureTFComponent.getStrongholdStones()); - + fillWithRandomizedBlocks(world, sbb, 0, 0, 0, size - 1, height - 1, size - 1, false, rand, StructureTFComponentOld.getStrongholdStones()); + // clear inside fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); // sky light nullifySkyLightForBoundingBox(world); - - // marker blocks -// placeBlockAtCurrentPosition(world, Blocks.wool, this.coordBaseMode, size / 2, 2, size / 2, sbb); -// placeBlockAtCurrentPosition(world, Blocks.gold_block, 0, 0, 0, 0, sbb); - - // stairs! - if (highestOpening > 1) { - makeStairs(world, rand, sbb); - } - - // decorate? - decorateThisTower(world, rand, sbb); - - - // windows - makeWindows(world, rand, sbb, size < 4); - - // throw a bunch of opening markers in there + + // marker blocks +// setBlockState(world, Blocks.WOOL, this.coordBaseMode, size / 2, 2, size / 2, sbb); +// setBlockState(world, Blocks.GOLD_BLOCK, 0, 0, 0, 0, sbb); + + // stairs! + if (highestOpening > 1) { + makeStairs(world, rand, sbb); + } + + // decorate? + decorateThisTower(world, rand, sbb); + + + // windows + makeWindows(world, rand, sbb, size < 4); + + // throw a bunch of opening markers in there // makeOpeningMarkers(world, rand, 100, sbb); - // openings - makeOpenings(world, sbb); - + // openings + makeOpenings(world, sbb); + // // relight // for (int lx = -1; lx < 3; lx++) { // for (int lz = -1; lz < 3; lz++) { @@ -411,59 +397,59 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox /** * Puts some colorful markers by possible openings in this tower. Debug only. - * + * * @param numMarkers How many markers to make */ protected void makeOpeningMarkers(World world, Random rand, int numMarkers, StructureBoundingBox sbb) { if (size > 4) { - for (int i = 0; i < numMarkers; i++) { - int[] spot = getValidOpening(rand, 0); - placeBlockAtCurrentPosition(world, Blocks.wool, 0, spot[0], spot[1], spot[2], sbb); - } - for (int i = 0; i < numMarkers; i++) { - int[] spot = getValidOpening(rand, 1); - placeBlockAtCurrentPosition(world, Blocks.wool, 1, spot[0], spot[1], spot[2], sbb); - } - for (int i = 0; i < numMarkers; i++) { - int[] spot = getValidOpening(rand, 2); - placeBlockAtCurrentPosition(world, Blocks.wool, 2, spot[0], spot[1], spot[2], sbb); - } - for (int i = 0; i < numMarkers; i++) { - int[] spot = getValidOpening(rand, 3); - placeBlockAtCurrentPosition(world, Blocks.wool, 3, spot[0], spot[1], spot[2], sbb); - } - } + final IBlockState woolWhite = Blocks.WOOL.getDefaultState().withProperty(BlockColored.COLOR, EnumDyeColor.WHITE); + final IBlockState woolOrange = Blocks.WOOL.getDefaultState().withProperty(BlockColored.COLOR, EnumDyeColor.ORANGE); + final IBlockState woolMagenta = Blocks.WOOL.getDefaultState().withProperty(BlockColored.COLOR, EnumDyeColor.MAGENTA); + final IBlockState woolLightBlue = Blocks.WOOL.getDefaultState().withProperty(BlockColored.COLOR, EnumDyeColor.LIGHT_BLUE); + + for (int i = 0; i < numMarkers; i++) { + int[] spot = getValidOpening(rand, Rotation.NONE); + setBlockState(world, woolWhite, spot[0], spot[1], spot[2], sbb); + } + for (int i = 0; i < numMarkers; i++) { + int[] spot = getValidOpening(rand, Rotation.CLOCKWISE_90); + setBlockState(world, woolOrange, spot[0], spot[1], spot[2], sbb); + } + for (int i = 0; i < numMarkers; i++) { + int[] spot = getValidOpening(rand, Rotation.CLOCKWISE_180); + setBlockState(world, woolMagenta, spot[0], spot[1], spot[2], sbb); + } + for (int i = 0; i < numMarkers; i++) { + int[] spot = getValidOpening(rand, Rotation.COUNTERCLOCKWISE_90); + setBlockState(world, woolLightBlue, spot[0], spot[1], spot[2], sbb); + } + } } - /** * Add some appropriate decorations to this tower - * - * @param world - * @param rand - * @param sbb */ protected void decorateThisTower(World world, Random rand, StructureBoundingBox sbb) { Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) * (this.boundingBox.minZ * 756839)); - + if (size > 3) { // only decorate towers with more than one available square inside. if (isDeadEnd()) { decorateDeadEnd(world, decoRNG, sbb); - } - else { + } else { // for now we'll just assume that any tower with more than one exit is a stair tower decorateStairTower(world, decoRNG, sbb); } } } - + /** * Decorates a dead end tower. These towers have no stairs, and will be the focus of our interior design. */ protected void decorateDeadEnd(World world, Random rand, StructureBoundingBox sbb) { + final IBlockState birchPlanks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); int floors = (this.height - 1) / 5; // divide the tower into floors @@ -472,18 +458,18 @@ protected void decorateDeadEnd(World world, Random rand, StructureBoundingBox sb // put down a floor for (int x = 1; x < size - 1; x++) { for (int z = 1; z < size - 1; z++) { - placeBlockAtCurrentPosition(world, Blocks.planks, 2, x, (i * floorHeight), z, sbb); + setBlockState(world, birchPlanks, x, (i * floorHeight), z, sbb); } } } - - + + if (floors > 1) { - int ladderDir = 3; - int downLadderDir = -1; + Rotation ladderDir = Rotation.COUNTERCLOCKWISE_90; + Rotation downLadderDir; // decorate bottom floor - decorateFloor(world, rand, 0, 1, floorHeight, ladderDir, -1, sbb); + decorateFloor(world, rand, 0, 1, floorHeight, ladderDir, null, sbb); // decorate middle floors for (int i = 1; i < floors - 1; i++) { @@ -491,79 +477,65 @@ protected void decorateDeadEnd(World world, Random rand, StructureBoundingBox sb int top = floorHeight * (i + 1); downLadderDir = ladderDir; - ladderDir++; - ladderDir %= 4; + ladderDir = ladderDir.add(Rotation.CLOCKWISE_90); decorateFloor(world, rand, i, bottom, top, ladderDir, downLadderDir, sbb); } // decorate top floor - decorateFloor(world, rand, floors, 1 + floorHeight * (floors - 1), height - 1, -1, ladderDir, sbb); - } - else { + decorateFloor(world, rand, floors, 1 + floorHeight * (floors - 1), height - 1, null, ladderDir, sbb); + } else { // just one floor, decorate that, no ladders - decorateFloor(world, rand, 0, 1, height - 1, -1, -1, sbb); + decorateFloor(world, rand, 0, 1, height - 1, null, null, sbb); } } - + /** * Called to decorate each floor. This is responsible for adding a ladder up, the stub of the ladder going down, then picking a theme for each floor and executing it. - * - * @param floor - * @param bottom - * @param top - * @param ladderUpDir - * @param laddderDownDir */ - protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { - - if (ladderUpDir > -1) { + protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, @Nullable Rotation ladderUpDir, @Nullable Rotation ladderDownDir, StructureBoundingBox sbb) { + + final IBlockState ladder = Blocks.LADDER.getDefaultState(); + if (ladderUpDir != null) { // add ladder going up - int meta = getLadderMeta(ladderUpDir); + final IBlockState ladderUp = ladder.withProperty(BlockLadder.FACING, ladderUpDir.rotate(EnumFacing.EAST)); + int dx = getLadderX(ladderUpDir); int dz = getLadderZ(ladderUpDir); for (int dy = bottom; dy < top; dy++) { - placeBlockAtCurrentPosition(world, Blocks.ladder, meta, dx, dy, dz, sbb); + setBlockState(world, ladderUp, dx, dy, dz, sbb); } } - - if (ladderDownDir > -1) { + + if (ladderDownDir != null) { // add ladder going down - int meta = getLadderMeta(ladderDownDir); + final IBlockState ladderDown = ladder.withProperty(BlockLadder.FACING, ladderDownDir.rotate(EnumFacing.EAST)); int dx = getLadderX(ladderDownDir); int dz = getLadderZ(ladderDownDir); for (int dy = bottom - 1; dy < bottom + 2; dy++) { - placeBlockAtCurrentPosition(world, Blocks.ladder, meta, dx, dy, dz, sbb); + setBlockState(world, ladderDown, dx, dy, dz, sbb); } } - - // pick a decoration? - if (rand.nextInt(7) == 0 && ladderDownDir == -1) { + + // some of these go only on the bottom floor (ladderDownDir == null) and some go only on upper floors + if (rand.nextInt(7) == 0 && ladderDownDir == null) { decorateWell(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else if (rand.nextInt(7) == 0 && ladderDownDir == -1) { + } else if (rand.nextInt(7) == 0 && ladderDownDir == null) { decorateSkeletonRoom(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else if (rand.nextInt(6) == 0 && ladderDownDir == -1) { + } else if (rand.nextInt(6) == 0 && ladderDownDir == null) { decorateZombieRoom(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else if (rand.nextInt(5) == 0 && ladderDownDir == -1) { + } else if (rand.nextInt(5) == 0 && ladderDownDir == null) { decorateCactusRoom(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else if (rand.nextInt(4) == 0 && ladderDownDir > -1) { + } else if (rand.nextInt(4) == 0 && ladderDownDir != null) { decorateTreasureChest(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else if (rand.nextInt(5) == 0) { + } else if (rand.nextInt(5) == 0) { decorateSpiderWebs(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else if (rand.nextInt(12) == 0 && ladderDownDir > -1) { + } else if (rand.nextInt(12) == 0 && ladderDownDir != null) { // these are annoying decorateSolidRock(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else if (rand.nextInt(3) == 0) { + } else if (rand.nextInt(3) == 0) { decorateFullLibrary(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); - } - else { + } else { decorateLibrary(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); // if (ladderDownDir == -1) { // // trap it! @@ -573,69 +545,71 @@ else if (rand.nextInt(3) == 0) { } - - /** * Decorate this floor with a scenic well. */ - protected void decorateWell(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateWell(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { int cx = size / 2; int cz = cx; int cy = bottom; - - Block waterOrLava = rand.nextInt(4) == 0 ? Blocks.lava : Blocks.water; - + + IBlockState waterOrLava = rand.nextInt(4) == 0 ? Blocks.LAVA.getDefaultState() : Blocks.WATER.getDefaultState(); + if (size > 5) { // actual well structure - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, cy + 0, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx - 1, cy + 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 0, cy + 0, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, cy + 0, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx + 1, cy + 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, waterOrLava, 0, cx + 0, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, cy + 0, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx - 1, cy + 1, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 0, cy + 0, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, cy + 0, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx + 1, cy + 1, cz + 1, sbb); + final IBlockState stoneBricks = Blocks.STONEBRICK.getDefaultState(); + final IBlockState stoneSlabs = StructureTFHelper.stoneSlab + .withProperty(BlockStoneSlab.VARIANT, SMOOTHBRICK); + + setBlockState(world, stoneBricks, cx - 1, cy + 0, cz - 1, sbb); + setBlockState(world, stoneSlabs, cx - 1, cy + 1, cz - 1, sbb); + setBlockState(world, stoneBricks, cx + 0, cy + 0, cz - 1, sbb); + setBlockState(world, stoneBricks, cx + 1, cy + 0, cz - 1, sbb); + setBlockState(world, stoneSlabs, cx + 1, cy + 1, cz - 1, sbb); + setBlockState(world, stoneBricks, cx - 1, cy + 0, cz + 0, sbb); + setBlockState(world, waterOrLava, cx + 0, cy + 0, cz + 0, sbb); + setBlockState(world, stoneBricks, cx + 1, cy + 0, cz + 0, sbb); + setBlockState(world, stoneBricks, cx - 1, cy + 0, cz + 1, sbb); + setBlockState(world, stoneSlabs, cx - 1, cy + 1, cz + 1, sbb); + setBlockState(world, stoneBricks, cx + 0, cy + 0, cz + 1, sbb); + setBlockState(world, stoneBricks, cx + 1, cy + 0, cz + 1, sbb); + setBlockState(world, stoneSlabs, cx + 1, cy + 1, cz + 1, sbb); } - - placeBlockAtCurrentPosition(world, waterOrLava, 0, cx + 0, cy - 1, cz + 0, sbb); + + setBlockState(world, waterOrLava, cx + 0, cy - 1, cz + 0, sbb); } /** * Add a skeleton spawner on this floor and decorate it in an appropriately scary manner. */ - protected void decorateSkeletonRoom(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateSkeletonRoom(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { // skeleton spawner - placeSpawnerAtCurrentPosition(world, rand, size / 2, bottom + 2, size / 2, "Skeleton", sbb); + setSpawner(world, size / 2, bottom + 2, size / 2, sbb, VanillaEntityNames.SKELETON); // floor-to-ceiling chains - ArrayList chainList = new ArrayList(); - chainList.add(new ChunkCoordinates(size / 2, bottom + 2, size / 2)); // don't block the spawner + ArrayList chainList = new ArrayList(); + chainList.add(new BlockPos(size / 2, bottom + 2, size / 2)); // don't block the spawner for (int i = 0; i < size + 2; i++) { - ChunkCoordinates chain = new ChunkCoordinates(2 + rand.nextInt(size - (4)), height - 2, 2 + rand.nextInt(size - (4))); + BlockPos chain = new BlockPos(2 + rand.nextInt(size - (4)), height - 2, 2 + rand.nextInt(size - (4))); if (!chainCollides(chain, chainList)) { // if it doesn't collide, manufacture it and add it to the list for (int dy = bottom; dy < top; dy++) { - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, chain.posX, dy, chain.posZ, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), chain.getX(), dy, chain.getZ(), sbb); } chainList.add(chain); } } - + // spider webs in the corner for (int dx = 1; dx <= size - 2; dx++) { for (int dz = 1; dz <= size - 2; dz++) { - if (dx == 1 || dx == size - 2 || dz == 1 || dz == size -2) { + if (dx == 1 || dx == size - 2 || dz == 1 || dz == size - 2) { // side of the room if (!isWindowPos(dx, dz) && !isLadderPos(dx, dz, ladderUpDir, ladderDownDir)) { // not an occupied position - placeBlockAtCurrentPosition(world, Blocks.web, 0, dx, top - 1, dz, sbb); + setBlockState(world, Blocks.WEB.getDefaultState(), dx, top - 1, dz, sbb); } } } @@ -647,32 +621,36 @@ protected void decorateSkeletonRoom(World world, Random rand, int bottom, int to /** * Add a zombie spawner on this floor and decorate it in an appropriately scary manner. */ - protected void decorateZombieRoom(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateZombieRoom(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { // zombie spawner - placeSpawnerAtCurrentPosition(world, rand, size / 2, bottom + 2, size / 2, "Zombie", sbb); - + setSpawner(world, size / 2, bottom + 2, size / 2, sbb, VanillaEntityNames.ZOMBIE); + final IBlockState ironBars = Blocks.IRON_BARS.getDefaultState(); + final IBlockState soulSand = Blocks.SOUL_SAND.getDefaultState(); + final IBlockState brownMushroom = Blocks.BROWN_MUSHROOM.getDefaultState(); + // random brown mushrooms for (int dx = 1; dx <= size - 2; dx++) { for (int dz = 1; dz <= size - 2; dz++) { if (!isWindowPos(dx, dz) && !isLadderPos(dx, dz, ladderUpDir, ladderDownDir)) { // not an occupied position if (rand.nextInt(5) == 0) { - placeBlockAtCurrentPosition(world, Blocks.brown_mushroom, 0, dx, bottom, dz, sbb); + setBlockState(world, brownMushroom, dx, bottom, dz, sbb); } } } } // slab tables - ArrayList slabList = new ArrayList(); - slabList.add(new ChunkCoordinates(size / 2, bottom + 2, size / 2)); // don't block the spawner + ArrayList slabList = new ArrayList(); + slabList.add(new BlockPos(size / 2, bottom + 2, size / 2)); // don't block the spawner for (int i = 0; i < size - 1; i++) { - ChunkCoordinates slab = new ChunkCoordinates(2 + rand.nextInt(size - (4)), height - 2, 2 + rand.nextInt(size - (4))); + BlockPos slab = new BlockPos(2 + rand.nextInt(size - (4)), height - 2, 2 + rand.nextInt(size - (4))); if (!chainCollides(slab, slabList)) { // if it doesn't collide, manufacture it and add it to the list - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, slab.posX, bottom + 0, slab.posZ, sbb); - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, slab.posX, bottom + 1, slab.posZ, sbb); - placeBlockAtCurrentPosition(world, Blocks.soul_sand, 0, slab.posX, bottom + 2, slab.posZ, sbb); + + setBlockState(world, ironBars, slab.getX(), bottom + 0, slab.getZ(), sbb); + setBlockState(world, StructureTFHelper.birchSlab, slab.getX(), bottom + 1, slab.getZ(), sbb); + setBlockState(world, soulSand, slab.getX(), bottom + 2, slab.getZ(), sbb); slabList.add(slab); } } @@ -681,30 +659,30 @@ protected void decorateZombieRoom(World world, Random rand, int bottom, int top, /** * Fill this room with sand and floor-to-ceiling cacti */ - protected void decorateCactusRoom(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateCactusRoom(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { // sand & random dead bush for (int dx = 1; dx <= size - 2; dx++) { for (int dz = 1; dz <= size - 2; dz++) { // sand - placeBlockAtCurrentPosition(world, Blocks.sand, 0, dx, bottom - 1, dz, sbb); + setBlockState(world, Blocks.SAND.getDefaultState(), dx, bottom - 1, dz, sbb); if (!isWindowPos(dx, dz) && !isLadderPos(dx, dz, ladderUpDir, ladderDownDir)) { // not an occupied position if (rand.nextInt(4) == 0) { - placeBlockAtCurrentPosition(world, Blocks.deadbush, 0, dx, bottom, dz, sbb); + setBlockState(world, Blocks.DEADBUSH.getDefaultState(), dx, bottom, dz, sbb); } } } } // cacti - ArrayList cactusList = new ArrayList(); - cactusList.add(new ChunkCoordinates(size / 2, bottom + 2, size / 2)); // don't block the spawner + ArrayList cactusList = new ArrayList(); + cactusList.add(new BlockPos(size / 2, bottom + 2, size / 2)); // don't block the spawner for (int i = 0; i < size + 12; i++) { - ChunkCoordinates cactus = new ChunkCoordinates(2 + rand.nextInt(size - (4)), height - 2, 2 + rand.nextInt(size - (4))); + BlockPos cactus = new BlockPos(2 + rand.nextInt(size - (4)), height - 2, 2 + rand.nextInt(size - (4))); if (!chainCollides(cactus, cactusList)) { // if it doesn't collide, manufacture it and add it to the list for (int dy = bottom; dy < top; dy++) { - placeBlockAtCurrentPosition(world, Blocks.cactus, 0, cactus.posX, dy, cactus.posZ, sbb); + setBlockState(world, Blocks.CACTUS.getDefaultState(), cactus.getX(), dy, cactus.getZ(), sbb); } cactusList.add(cactus); } @@ -712,107 +690,79 @@ protected void decorateCactusRoom(World world, Random rand, int bottom, int top, } - - /** * Decorate this floor with an enticing treasure chest. */ - protected void decorateTreasureChest(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateTreasureChest(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { int cx = size / 2; int cz = cx; - + final IBlockState stoneBrick = Blocks.STONEBRICK.getDefaultState(); + // bottom decoration - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(1), cx + 0, bottom, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(0), cx - 1, bottom, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(2), cx + 1, bottom, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(3), cx + 0, bottom, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 0, bottom, cz + 0, sbb); - - if (size > 5) - { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, bottom, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, bottom, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, bottom, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, bottom, cz + 1, sbb); - } - - // top decoration - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(1) + 4, cx + 0, top - 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(0) + 4, cx - 1, top - 1, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(2) + 4, cx + 1, top - 1, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, getStairMeta(3) + 4, cx + 0, top - 1, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 0, top - 1, cz + 0, sbb); - - if (size > 5) - { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, top - 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, top - 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, top - 1, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, top - 1, cz + 1, sbb); - } - - if (size > 5) - { + final IBlockState stoneBrickStairs = Blocks.STONE_BRICK_STAIRS.getDefaultState(); + final IBlockState topStoneBrickStairs = stoneBrickStairs.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP); + + setBlockState(world, stoneBrick, cx, bottom, cz, sbb); + setBlockState(world, stoneBrick, cx, top-1, cz, sbb); + if(size < 6) { + surroundBlockCardinalRotated(world, stoneBrickStairs, cx, bottom, cz, sbb); + + surroundBlockCardinalRotated(world, topStoneBrickStairs, cx, top-1, cz, sbb); + } else { + surroundBlockCardinalRotated(world, stoneBrickStairs, cx, bottom, cz, sbb); + surroundBlockCorners(world, stoneBrick, cx, bottom, cz, sbb); + // pillars for (int cy = bottom + 1; cy < top - 1; cy++) { - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 5, cx - 1, cy, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 5, cx + 1, cy, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 5, cx - 1, cy, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 5, cx + 1, cy, cz + 1, sbb); + surroundBlockCorners(world, stoneBrick, cx, cy, cz, sbb); } - } - placeTreasureAtCurrentPosition(world, rand, cx + 0, bottom + 1, cz + 0, TFTreasure.tower_room, sbb); - - for (int i = 0; i < 4; i++) { - //TODO if there is no ladder or window in the specified direction, put a painting - - // surrounded by torches - + surroundBlockCardinalRotated(world, topStoneBrickStairs, cx, top-1, cz, sbb); + surroundBlockCorners(world, stoneBrick, cx, top-1, cz, sbb); } + placeTreasureAtCurrentPosition(world, rand, cx, bottom + 1, cz, TFTreasure.tower_room, sbb); } /** * Decorate this floor with a mass of messy spider webs. */ - protected void decorateSpiderWebs(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateSpiderWebs(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { for (int dy = bottom; dy < top; dy++) { int chance = (top - dy + 2); for (int dx = 1; dx <= size - 2; dx++) { for (int dz = 1; dz <= size - 2; dz++) { if (!isLadderPos(dx, dz, ladderUpDir, ladderDownDir) && rand.nextInt(chance) == 0) { - placeBlockAtCurrentPosition(world, Blocks.web, 0, dx, dy, dz, sbb); + setBlockState(world, Blocks.WEB.getDefaultState(), dx, dy, dz, sbb); } } } } - + // 20% chance of a spider spawner! if (rand.nextInt(5) == 0) { - String spiderName; - switch(rand.nextInt(4)) { - case 3: - spiderName = "CaveSpider"; - break; - case 2: - spiderName = TFCreatures.getSpawnerNameFor("Swarm Spider"); - break; - case 1: - spiderName = TFCreatures.getSpawnerNameFor("Hedge Spider"); - break; - case 0: - default: - spiderName = "Spider"; - break; + ResourceLocation spiderName; + switch (rand.nextInt(4)) { + case 3: + spiderName = VanillaEntityNames.CAVE_SPIDER; + break; + case 2: + spiderName = TFEntityNames.SWARM_SPIDER; + break; + case 1: + spiderName = TFEntityNames.HEDGE_SPIDER; + break; + case 0: + default: + spiderName = VanillaEntityNames.SPIDER; + break; } - - placeSpawnerAtCurrentPosition(world, rand, size / 2, bottom + 2, size / 2, spiderName, sbb); - - } - else { + setSpawner(world, size / 2, bottom + 2, size / 2, sbb, spiderName); + + + } else { decorateFurniture(world, rand, bottom, size - 2, sbb); } } @@ -824,22 +774,23 @@ protected void decorateSpiderWebs(World world, Random rand, int bottom, int top, protected void decorateFurniture(World world, Random rand, int bottom, int freeSpace, StructureBoundingBox sbb) { // 66% chance of a table if (rand.nextInt(3) > 0) { - placeBlockAtCurrentPosition(world, Blocks.fence, 0, size / 2, bottom, size / 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.wooden_pressure_plate, 0, size / 2, bottom + 1, size / 2, sbb); + setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), size / 2, bottom, size / 2, sbb); + setBlockState(world, Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(), size / 2, bottom + 1, size / 2, sbb); } - + // chairs! + final IBlockState spruceStairs = Blocks.SPRUCE_STAIRS.getDefaultState(); if (rand.nextInt(3) == 0 && freeSpace > 1) { - placeBlockAtCurrentPosition(world, Blocks.spruce_stairs, getStairMeta(0), size / 2 + 1, bottom, size / 2, sbb); + setBlockState(world, spruceStairs.withProperty(BlockStairs.FACING, EnumFacing.WEST), size / 2 + 1, bottom, size / 2, sbb); } if (rand.nextInt(3) == 0 && freeSpace > 1) { - placeBlockAtCurrentPosition(world, Blocks.spruce_stairs, getStairMeta(1), size / 2, bottom, size / 2 + 1, sbb); + setBlockState(world, spruceStairs.withProperty(BlockStairs.FACING, EnumFacing.NORTH), size / 2, bottom, size / 2 + 1, sbb); } if (rand.nextInt(3) == 0 && freeSpace > 1) { - placeBlockAtCurrentPosition(world, Blocks.spruce_stairs, getStairMeta(2), size / 2 - 1, bottom, size / 2, sbb); + setBlockState(world, spruceStairs.withProperty(BlockStairs.FACING, EnumFacing.EAST), size / 2 - 1, bottom, size / 2, sbb); } if (rand.nextInt(3) == 0 && freeSpace > 1) { - placeBlockAtCurrentPosition(world, Blocks.spruce_stairs, getStairMeta(3), size / 2, bottom, size / 2 - 1, sbb); + setBlockState(world, spruceStairs.withProperty(BlockStairs.FACING, EnumFacing.SOUTH), size / 2, bottom, size / 2 - 1, sbb); } } @@ -847,35 +798,34 @@ protected void decorateFurniture(World world, Random rand, int bottom, int freeS /** * Decorate this floor with solid rock */ - protected void decorateSolidRock(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateSolidRock(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { for (int dy = bottom; dy < top; dy++) { for (int dx = 1; dx <= size - 2; dx++) { for (int dz = 1; dz <= size - 2; dz++) { if (!isLadderPos(dx, dz, ladderUpDir, ladderDownDir) && rand.nextInt(9) != 0) { - placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx, dy, dz, sbb); + setBlockState(world, Blocks.STONE.getDefaultState(), dx, dy, dz, sbb); } } } } - + //TODO: maybe seed a few ores in there. } - /** * Decorate this floor with an orderly library */ - protected void decorateLibrary(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateLibrary(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { // put some bookshelves around the room for (int dx = 1; dx <= size - 2; dx++) { for (int dz = 1; dz <= size - 2; dz++) { - for (int dy = bottom; dy < top -1; dy++) { - if (dx == 1 || dx == size - 2 || dz == 1 || dz == size -2) { + for (int dy = bottom; dy < top - 1; dy++) { + if (dx == 1 || dx == size - 2 || dz == 1 || dz == size - 2) { // side of the room if (!isWindowPos(dx, dz) && !isLadderPos(dx, dz, ladderUpDir, ladderDownDir)) { // not an occupied position - placeBlockAtCurrentPosition(world, Blocks.bookshelf, 0, dx, dy, dz, sbb); + setBlockState(world, Blocks.BOOKSHELF.getDefaultState(), dx, dy, dz, sbb); } } } @@ -893,40 +843,39 @@ protected void decorateLibrary(World world, Random rand, int bottom, int top, in } - /** * Place a library treasure chest somewhere in the library */ - protected void decorateLibraryTreasure(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateLibraryTreasure(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { switch (rand.nextInt(4)) { - case 0: - default: - if (!isLadderPos(2, 1, ladderUpDir, ladderDownDir)) { - placeTreasureAtCurrentPosition(world, rand, 2, top - 2, 1, TFTreasure.tower_library, sbb); - break; - } - case 1: - if (!isLadderPos(size - 2, 2, ladderUpDir, ladderDownDir)) { - placeTreasureAtCurrentPosition(world, rand, size - 2, top - 2, 2, TFTreasure.tower_library, sbb); - break; - } - case 2: - if (!isLadderPos(size - 3, size - 2, ladderUpDir, ladderDownDir)) { - placeTreasureAtCurrentPosition(world, rand, size - 3, top - 2, size - 2, TFTreasure.tower_library, sbb); - break; - } - case 3: - if (!isLadderPos(1, size - 3, ladderUpDir, ladderDownDir)) { - placeTreasureAtCurrentPosition(world, rand, 1, top - 2, size - 3, TFTreasure.tower_library, sbb); - break; - } + case 0: + default: + if (!isLadderPos(2, 1, ladderUpDir, ladderDownDir)) { + placeTreasureAtCurrentPosition(world, rand, 2, top - 2, 1, TFTreasure.tower_library, sbb); + break; + } + case 1: + if (!isLadderPos(size - 2, 2, ladderUpDir, ladderDownDir)) { + placeTreasureAtCurrentPosition(world, rand, size - 2, top - 2, 2, TFTreasure.tower_library, sbb); + break; + } + case 2: + if (!isLadderPos(size - 3, size - 2, ladderUpDir, ladderDownDir)) { + placeTreasureAtCurrentPosition(world, rand, size - 3, top - 2, size - 2, TFTreasure.tower_library, sbb); + break; + } + case 3: + if (!isLadderPos(1, size - 3, ladderUpDir, ladderDownDir)) { + placeTreasureAtCurrentPosition(world, rand, 1, top - 2, size - 3, TFTreasure.tower_library, sbb); + break; + } } } /** * Decorate this floor with an overflowing library */ - protected void decorateFullLibrary(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + protected void decorateFullLibrary(World world, Random rand, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { // put some bookshelves around the room for (int dx = 1; dx <= size - 2; dx++) { for (int dz = 1; dz <= size - 2; dz++) { @@ -936,7 +885,7 @@ protected void decorateFullLibrary(World world, Random rand, int bottom, int top // concentric rings if (!isWindowPos(dx, dy, dz) && !isOpeningPos(dx, dy, dz) && !isLadderPos(dx, dz, ladderUpDir, ladderDownDir)) { // not an occupied position - placeBlockAtCurrentPosition(world, Blocks.bookshelf, 0, dx, dy, dz, sbb); + setBlockState(world, Blocks.BOOKSHELF.getDefaultState(), dx, dy, dz, sbb); } } } @@ -947,32 +896,29 @@ protected void decorateFullLibrary(World world, Random rand, int bottom, int top decorateLibraryTreasure(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); } } - + /** * "Decorate" with a lot of TNT. - * + *

* This is not called at the moment, since I added monsters and the monsters set off the trap. Perhaps I need a better way of activating it. - * */ protected void decorateTrap(World world, Random rand, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { for (int dx = 2; dx <= size - 3; dx++) { for (int dz = 2; dz <= size - 3; dz++) { - if (dx == 2 || dx == size - 3 || dz == 2 || dz == size -3) { - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, dx, -1, dz, sbb); + if (dx == 2 || dx == size - 3 || dz == 2 || dz == size - 3) { + setBlockState(world, Blocks.TNT.getDefaultState(), dx, -1, dz, sbb); } } } for (int dy = bottom - 2; dy < top - 2; dy++) { - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 1, dy, 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 1, dy, size - 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, size - 2, dy, 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, size - 2, dy, size - 2, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), 1, dy, 1, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), 1, dy, size - 2, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), size - 2, dy, 1, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), size - 2, dy, size - 2, sbb); } } - - /** * Checks if there is a window at the specified x and z. Does not check the Y. */ @@ -989,7 +935,7 @@ protected boolean isWindowPos(int x, int z) { if (x == size / 2 && z == size - 2) { return true; } - + // okay, looks good return false; } @@ -999,25 +945,21 @@ protected boolean isWindowPos(int x, int z) { */ protected boolean isWindowPos(int x, int y, int z) { int checkYDir = -1; - + if (x == 1 && z == size / 2) { checkYDir = 2; - } - else if (x == size - 2 && z == size / 2) { + } else if (x == size - 2 && z == size / 2) { checkYDir = 0; - } - else if (x == size / 2 && z == 1) { + } else if (x == size / 2 && z == 1) { checkYDir = 3; - } - else if (x == size / 2 && z == size - 2) { + } else if (x == size / 2 && z == size - 2) { checkYDir = 1; } - + if (checkYDir > -1) { // check if we are at one of the Y positions with a window. return !openingTowards[checkYDir] && (y == 2 || y == 3 || (height > 8 && (y == height - 3 || y == height - 4))); - } - else { + } else { // okay, looks good return false; } @@ -1028,25 +970,20 @@ else if (x == size / 2 && z == size - 2) { * TODO: this could be much smarter. Although since there's usually only one opening, I guess it's not bad. */ protected boolean isOpeningPos(int x, int y, int z) { - Iterator itr = openings.iterator(); - while(itr.hasNext()){ - ChunkCoordinates door = itr.next(); + for (BlockPos door : openings) { // determine which wall we're at - ChunkCoordinates inside = new ChunkCoordinates(door); - if (inside.posX == 0) { - inside.posX++; - } - else if (inside.posX == size - 1) { - inside.posX--; - } - else if (inside.posZ == 0) { - inside.posZ++; - } - else if (inside.posZ == size - 1) { - inside.posZ--; + BlockPos.MutableBlockPos inside = new BlockPos.MutableBlockPos(door); + if (inside.getX() == 0) { + inside.move(EnumFacing.EAST); + } else if (inside.getX() == size - 1) { + inside.move(EnumFacing.WEST); + } else if (inside.getZ() == 0) { + inside.move(EnumFacing.SOUTH); + } else if (inside.getZ() == size - 1) { + inside.move(EnumFacing.NORTH); } // check the block - if (inside.posX == x && inside.posZ == z && (inside.posY == y || inside.posY + 1 == y)) { + if (inside.getX() == x && inside.getZ() == z && (inside.getY() == y || inside.getY() + 1 == y)) { return true; } } @@ -1054,73 +991,66 @@ else if (inside.posZ == size - 1) { return false; } - - - protected boolean isLadderPos(int x, int z, int ladderUpDir, int ladderDownDir) { - if (x == getLadderX(ladderUpDir) && z == getLadderZ(ladderUpDir)) { + + protected boolean isLadderPos(int x, int z, Rotation ladderUpDir, Rotation ladderDownDir) { + if (ladderUpDir != null && x == getLadderX(ladderUpDir) && z == getLadderZ(ladderUpDir)) { return true; } - if (x == getLadderX(ladderDownDir) && z == getLadderZ(ladderDownDir)) { + if (ladderDownDir != null && x == getLadderX(ladderDownDir) && z == getLadderZ(ladderDownDir)) { return true; } - + // okay, looks good return false; } /** * Gets the X coordinate of the ladder on the specified wall. - * - * @param ladderDir - * @return */ - protected int getLadderX(int ladderDir) { + protected int getLadderX(Rotation ladderDir) { switch (ladderDir) { - case 0: - return size - 2; - case 1: - return size / 2 + 1; - case 2: - return 1; - case 3: - return size / 2 - 1; - default: - return size / 2; - } - } - + case NONE: + return size - 2; + case CLOCKWISE_90: + return size / 2 + 1; + case CLOCKWISE_180: + return 1; + case COUNTERCLOCKWISE_90: + return size / 2 - 1; + default: + return size / 2; + } + } + /** * Gets the Z coordinate of the ladder on the specified wall. - * - * @param ladderDir - * @return */ - protected int getLadderZ(int ladderDir) { - + protected int getLadderZ(Rotation ladderDir) { + switch (ladderDir) { - case 0: - return size / 2 - 1; - case 1: - return size - 2; - case 2: - return size / 2 + 1; - case 3: - return 1; - default: - return size / 2; + case NONE: + return size / 2 - 1; + case CLOCKWISE_90: + return size - 2; + case CLOCKWISE_180: + return size / 2 + 1; + case COUNTERCLOCKWISE_90: + return 1; + default: + return size / 2; } } /** * Decorate a tower with stairs. - * - * We have two schemes here. We can either decorate the whole tower with a + *

+ * We have two schemes here. We can either decorate the whole tower with a * decoration that rises the entire height of the tower (such as a pillar) - * or we can divide the tower into the "stair" section on the bottom and the + * or we can divide the tower into the "stair" section on the bottom and the * "attic" section at the top and decorate those seperately. - * */ protected void decorateStairTower(World world, Random rand, StructureBoundingBox sbb) { + // if it's tall enough, consider adding extra floors onto the top. if (height - highestOpening > 8) { int base = highestOpening + 3; @@ -1132,22 +1062,21 @@ protected void decorateStairTower(World world, Random rand, StructureBoundingBox // put down a floor for (int x = 1; x < size - 1; x++) { for (int z = 1; z < size - 1; z++) { - placeBlockAtCurrentPosition(world, Blocks.planks, 2, x, (i * floorHeight + base), z, sbb); + setBlockState(world, StructureTFHelper.birchPlanks, x, (i * floorHeight + base), z, sbb); } } } + Rotation ladderDir = Rotation.NONE; + Rotation downLadderDir; - int ladderDir = 3; - int downLadderDir = -1; - // place a ladder going up //TODO: make this ladder connect better to the stairs - int meta = getLadderMeta(ladderDir); int dx = getLadderX(ladderDir); int dz = getLadderZ(ladderDir); + final IBlockState defaultState = Blocks.LADDER.getDefaultState().withProperty(BlockLadder.FACING, ladderDir.rotate(EnumFacing.EAST)); for (int dy = 1; dy < 3; dy++) { - placeBlockAtCurrentPosition(world, Blocks.ladder, meta, dx, base - dy, dz, sbb); + setBlockState(world, defaultState, dx, base - dy, dz, sbb); } // decorate middle floors @@ -1156,75 +1085,70 @@ protected void decorateStairTower(World world, Random rand, StructureBoundingBox int top = base + floorHeight * (i + 1); downLadderDir = ladderDir; - ladderDir++; - ladderDir %= 4; + ladderDir = ladderDir.add(Rotation.CLOCKWISE_90); decorateFloor(world, rand, i, bottom, top, ladderDir, downLadderDir, sbb); } // decorate top floor - decorateFloor(world, rand, floors, base + 1 + floorHeight * (floors - 1), height - 1, -1, ladderDir, sbb); - + decorateFloor(world, rand, floors, base + 1 + floorHeight * (floors - 1), height - 1, null, ladderDir, sbb); + // decorate below the bottom floor, into the stairs - if (base > 8) - { + if (base > 8) { switch (rand.nextInt(4)) { - case 0: - decorateChandelier(world, rand, base + 1, sbb); - break; - case 1: - decorateHangingChains(world, rand, base + 1, sbb); - break; - case 2: - decorateFloatingBooks(world, rand, base + 1, sbb); - break; - case 3: - decorateFloatingVines(world, rand, base + 1, sbb); - break; + case 0: + decorateChandelier(world, rand, base + 1, sbb); + break; + case 1: + decorateHangingChains(world, rand, base + 1, sbb); + break; + case 2: + decorateFloatingBooks(world, rand, base + 1, sbb); + break; + case 3: + decorateFloatingVines(world, rand, base + 1, sbb); + break; } } - } - else { + } else { // decorate the top normally if (size > 5) { switch (rand.nextInt(4)) { - case 0: - decorateChandelier(world, rand, height, sbb); - break; - case 1: - decorateHangingChains(world, rand, height, sbb); - break; - case 2: - decorateFloatingBooks(world, rand, height, sbb); - break; - case 3: - decorateFloatingVines(world, rand, height, sbb); - break; + case 0: + decorateChandelier(world, rand, height, sbb); + break; + case 1: + decorateHangingChains(world, rand, height, sbb); + break; + case 2: + decorateFloatingBooks(world, rand, height, sbb); + break; + case 3: + decorateFloatingVines(world, rand, height, sbb); + break; } - } - else if (size > 3) - { + } else if (size > 3) { switch (rand.nextInt(3)) { - case 0: - decorateHangingChains(world, rand, height, sbb); - break; - case 1: - decorateFloatingBooks(world, rand, height, sbb); - break; - case 2: - decorateFloatingVines(world, rand, height, sbb); - break; + case 0: + decorateHangingChains(world, rand, height, sbb); + break; + case 1: + decorateFloatingBooks(world, rand, height, sbb); + break; + case 2: + decorateFloatingVines(world, rand, height, sbb); + break; } } } - + decorateStairFloor(world, rand, sbb); } /** * Decorate the bottom floor of this tower. - * + *

* This is for towers with stairs at the bottom, not towers divided into floors */ protected void decorateStairFloor(World world, Random rand, StructureBoundingBox sbb) { @@ -1232,8 +1156,7 @@ protected void decorateStairFloor(World world, Random rand, StructureBoundingBox if (size > 5) { if (rand.nextInt(3) == 0) { decorateStairWell(world, rand, sbb); - } - else if (rand.nextInt(3) > 0 || this.size >= 15) { + } else if (rand.nextInt(3) > 0 || this.size >= 15) { // a few empty bottoms decoratePlanter(world, rand, sbb); } @@ -1241,313 +1164,221 @@ else if (rand.nextInt(3) > 0 || this.size >= 15) { } - - - /** * Make a chandelier. The chandelier hangs down a random amount between the top of the tower and the highest opening. */ protected void decorateChandelier(World world, Random rand, int decoTop, StructureBoundingBox sbb) { - if (decoTop < 8 || size < 8) - { - //System.out.println("Trying to put a chandelier in a size " + decoTop + " space. FAIL!"); + if (decoTop < 8 || size < 8) { return; } - + int cx = size / 2; int cy = decoTop - rand.nextInt(decoTop - 7) - 2; int cz = size / 2; - - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx - 1, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 1, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy + 0, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy + 0, cz + 1, sbb); - - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, cy + 1, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx - 1, cy + 1, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 1, cy + 1, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 0, cy + 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.torch, 0, cx + 0, cy + 1, cz + 1, sbb); - + + final IBlockState oakFence = Blocks.OAK_FENCE.getDefaultState(); + + //setDebugEntity(world, cx, cy, cz, sbb, "TowerWing.decorateChandelier"); + surroundBlockCardinal(world, oakFence, cx, cy, cz, sbb); + surroundBlockCardinal(world, oakFence, cx, cy + 1, cz, sbb); + for (int y = cy; y < decoTop - 1; y++) { - placeBlockAtCurrentPosition(world, Blocks.fence, 0, cx + 0, y, cz + 0, sbb); + setBlockState(world, oakFence, cx, y, cz, sbb); } } - /** * Decorates a tower with chains hanging down. - * + *

* The chains go from the ceiling to just above the highest doorway. - * @param decoTop */ protected void decorateHangingChains(World world, Random rand, int decoTop, StructureBoundingBox sbb) { // a list of existing chains - ArrayList chainList = new ArrayList(); + ArrayList chainList = new ArrayList(); // try size + 2 times to find a chain that does not collide for (int i = 0; i < size + 2; i++) { int filled = size < 15 ? 2 : 4; - ChunkCoordinates chain = new ChunkCoordinates(filled + rand.nextInt(size - (filled * 2)), decoTop - 2, filled + rand.nextInt(size - (filled * 2))); + BlockPos chain = new BlockPos(filled + rand.nextInt(size - (filled * 2)), decoTop - 2, filled + rand.nextInt(size - (filled * 2))); if (!chainCollides(chain, chainList)) { // if it doesn't collide, manufacture it and add it to the list int length = 1 + rand.nextInt(decoTop - 7); - decorateOneChain(world, rand, chain.posX, decoTop, length, chain.posZ, sbb); + decorateOneChain(world, rand, chain.getX(), decoTop, length, chain.getZ(), sbb); chainList.add(chain); } } - + } - + /** * Return true if the specified coords are orthogonally adjacent to any other coords on the list. */ - protected boolean chainCollides(ChunkCoordinates coords, List list) { - Iterator itr = list.iterator(); - while (itr.hasNext()) { - ChunkCoordinates existing = itr.next(); - // if x is within 1 and z is equal, we collide - if (coords.posZ == existing.posZ && Math.abs(coords.posX - existing.posX) <= 1) { - return true; - } - // similarly, if z is within 1 and x is equal, we collide - if (coords.posX == existing.posX && Math.abs(coords.posZ - existing.posZ) <= 1) { - return true; - } - } - // we're good - return false; - } - - /** - * Puts one chain in a tower at the specified coordinates. - * - * @param dx - * @param length - * @param dz - * @param posZ - */ + protected boolean chainCollides(BlockPos coords, List list) { + for (BlockPos existing : list) { + // if x is within 1 and z is equal, we collide + if (coords.getZ() == existing.getZ() && Math.abs(coords.getX() - existing.getX()) <= 1) { + return true; + } + // similarly, if z is within 1 and x is equal, we collide + if (coords.getX() == existing.getX() && Math.abs(coords.getZ() - existing.getZ()) <= 1) { + return true; + } + } + // we're good + return false; + } + protected void decorateOneChain(World world, Random rand, int dx, int decoTop, int length, int dz, StructureBoundingBox sbb) { for (int y = 1; y <= length; y++) { - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx, decoTop - y - 1, dz, sbb); - } + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx, decoTop - y - 1, dz, sbb); + } // make the "ball" at the end. - Block ballBlock; - int ballMeta; + IBlockState ballBlock; switch (rand.nextInt(10)) { - case 0: - ballBlock = Blocks.iron_block; - ballMeta = 0; - break; - case 1: - ballBlock = Blocks.bookshelf; - ballMeta = 0; - break; - case 2: - ballBlock = Blocks.netherrack; - ballMeta = 0; - break; - case 3: - ballBlock = Blocks.soul_sand; - ballMeta = 0; - break; - case 4: - ballBlock = Blocks.glass; - ballMeta = 0; - break; - case 5: - ballBlock = Blocks.lapis_block; - ballMeta = 0; - break; - case 6: - ballBlock = Blocks.monster_egg; - ballMeta = 2; - break; - case 7: - default: - ballBlock = Blocks.glowstone; - ballMeta = 0; - break; - } - placeBlockAtCurrentPosition(world, ballBlock, ballMeta, dx, decoTop - length - 2, dz, sbb); + case 0: + ballBlock = Blocks.IRON_BLOCK.getDefaultState(); + break; + case 1: + ballBlock = Blocks.BOOKSHELF.getDefaultState(); + break; + case 2: + ballBlock = Blocks.NETHERRACK.getDefaultState(); + break; + case 3: + ballBlock = Blocks.SOUL_SAND.getDefaultState(); + break; + case 4: + ballBlock = Blocks.GLASS.getDefaultState(); + break; + case 5: + ballBlock = Blocks.LAPIS_BLOCK.getDefaultState(); + break; + case 6: + ballBlock = Blocks.MONSTER_EGG.getDefaultState() + .withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONEBRICK); + break; + case 7: + default: + ballBlock = Blocks.GLOWSTONE.getDefaultState(); + break; + } + setBlockState(world, ballBlock, dx, decoTop - length - 2, dz, sbb); } /** * Decorates a tower with an array of floating bookshelves. - * @param decoTop */ protected void decorateFloatingBooks(World world, Random rand, int decoTop, StructureBoundingBox sbb) { // a list of existing bookshelves - ArrayList shelfList = new ArrayList(); + ArrayList shelfList = new ArrayList(); // try size + 2 times to find a shelf that does not collide for (int i = 0; i < size + 2; i++) { int filled = size < 15 ? 2 : 4; - ChunkCoordinates shelf = new ChunkCoordinates(filled + rand.nextInt(size - (filled * 2)), decoTop - 2, filled + rand.nextInt(size - (filled * 2))); + BlockPos shelf = new BlockPos(filled + rand.nextInt(size - (filled * 2)), decoTop - 2, filled + rand.nextInt(size - (filled * 2))); if (!chainCollides(shelf, shelfList)) { // if it doesn't collide, manufacture it and add it to the list int bottom = 2 + rand.nextInt(decoTop - 7); int top = rand.nextInt(bottom - 1) + 2; for (int y = top; y <= bottom; y++) { - placeBlockAtCurrentPosition(world, Blocks.bookshelf, 0, shelf.posX, decoTop - y, shelf.posZ, sbb); - } + setBlockState(world, Blocks.BOOKSHELF.getDefaultState(), shelf.getX(), decoTop - y, shelf.getZ(), sbb); + } shelfList.add(shelf); } } } - - + + /** * Decorates a tower with an array of floating vines, attached to mossy cobblestone. - * @param decoTop */ protected void decorateFloatingVines(World world, Random rand, int decoTop, StructureBoundingBox sbb) { + final IBlockState mossyCobbleStone = Blocks.MOSSY_COBBLESTONE.getDefaultState(); + final IBlockState vine = Blocks.VINE.getDefaultState(); + final IBlockState vineNorth = vine.withProperty(BlockVine.NORTH, true); + final IBlockState vineSouth = vine.withProperty(BlockVine.SOUTH, true); + final IBlockState vineEast = vine.withProperty(BlockVine.EAST, true); + final IBlockState vineWest = vine.withProperty(BlockVine.WEST, true); + // a list of existing blocks - ArrayList mossList = new ArrayList(); + ArrayList mossList = new ArrayList(); // try size + 2 times to find a rock pillar that does not collide for (int i = 0; i < size + 2; i++) { int filled = size < 15 ? 2 : 4; - ChunkCoordinates moss = new ChunkCoordinates(filled + rand.nextInt(size - (filled * 2)), decoTop - 2, filled + rand.nextInt(size - (filled * 2))); + BlockPos moss = new BlockPos(filled + rand.nextInt(size - (filled * 2)), decoTop - 2, filled + rand.nextInt(size - (filled * 2))); if (!chainCollides(moss, mossList)) { // if it doesn't collide, manufacture it and add it to the list int bottom = 2 + rand.nextInt(decoTop - 7); int top = rand.nextInt(bottom - 1) + 2; for (int y = top; y <= bottom; y++) { - placeBlockAtCurrentPosition(world, Blocks.mossy_cobblestone, 0, moss.posX, decoTop - y, moss.posZ, sbb); + setBlockState(world, mossyCobbleStone, moss.getX(), decoTop - y, moss.getZ(), sbb); // surround it with vines - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(2), moss.posX + 1, decoTop - y, moss.posZ + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(0), moss.posX - 1, decoTop - y, moss.posZ + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(3), moss.posX + 0, decoTop - y, moss.posZ + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(1), moss.posX + 0, decoTop - y, moss.posZ - 1, sbb); - } + setBlockState(world, vineEast, moss.getX() + 1, decoTop - y, moss.getZ() + 0, sbb); + setBlockState(world, vineWest, moss.getX() - 1, decoTop - y, moss.getZ() + 0, sbb); + setBlockState(world, vineSouth, moss.getX() + 0, decoTop - y, moss.getZ() + 1, sbb); + setBlockState(world, vineNorth, moss.getX() + 0, decoTop - y, moss.getZ() - 1, sbb); + } mossList.add(moss); } } - + // put vines on the sides of the tower. for (int y = highestOpening + 3; y < decoTop - 1; y++) { for (int x = 1; x < size - 1; x++) { if (rand.nextInt(3) == 0) { - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(3), x, y, 1, sbb); + setBlockState(world, vineSouth, x, y, 1, sbb); } if (rand.nextInt(3) == 0) { - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(1), x, y, size - 2, sbb); + setBlockState(world, vineNorth, x, y, size - 2, sbb); } } for (int z = 1; z < size - 1; z++) { if (rand.nextInt(3) == 0) { - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(2), 1, y, z, sbb); + setBlockState(world, vineEast, 1, y, z, sbb); } if (rand.nextInt(3) == 0) { - placeBlockAtCurrentPosition(world, Blocks.vine, getVineMeta(0), size - 2, y, z, sbb); + setBlockState(world, vineWest, size - 2, y, z, sbb); } } } } - - - /** - * Gets the metadata necessary to stick the vines on the specified wall. - * - * @param vineDir - * @return - */ - protected int getVineMeta(int vineDir) { - switch ((this.getCoordBaseMode() + vineDir) % 4) { - case 0: - return 8; - case 1: - return 1; - case 2: - return 2; - case 3: - return 4; - default: - return -1; // this is impossible - } - } - - - + /** * Makes a planter. Depending on the situation, it can be filled with trees, flowers, or crops */ protected void decoratePlanter(World world, Random rand, StructureBoundingBox sbb) { int cx = size / 2; int cz = cx; - - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, cx + 0, 1, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, cx + 0, 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, cx + 1, 1, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, cx - 1, 1, cz + 0, sbb); + + surroundBlockCardinal(world, StructureTFHelper.stoneSlab, cx, 1, cz, sbb); if (size > 7) - { - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, cx - 1, 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, cx + 1, 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, cx + 1, 1, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, cx - 1, 1, cz + 1, sbb); - } + surroundBlockCorners(world, StructureTFHelper.stoneSlabDouble, cx, 1, cz, sbb); + // place a cute planted thing - placeBlockAtCurrentPosition(world, Blocks.grass, 0, cx + 0, 1, cz + 0, sbb); - - Block planterBlock; - int planterMeta; - switch (rand.nextInt(6)) { - case 0: - planterBlock = Blocks.sapling; - planterMeta = 0; - break; - case 1: - planterBlock = Blocks.sapling; - planterMeta = 1; - break; - case 2: - planterBlock = Blocks.sapling; - planterMeta = 2; - break; - case 3: - planterBlock = Blocks.sapling; - planterMeta = 3; - break; - case 4: - planterBlock = Blocks.brown_mushroom; - planterMeta = 0; - break; - case 5: - default: - planterBlock = Blocks.red_mushroom; - planterMeta = 0; - break; - } - placeBlockAtCurrentPosition(world, planterBlock, planterMeta, cx + 0, 2, cz + 0, sbb); - - // try to grow a tree - if (planterBlock == Blocks.sapling) { - int wx = getXWithOffset(cx, cz); - int wy = getYWithOffset(2); - int wz = getZWithOffset(cx, cz); - ((BlockSapling)Blocks.sapling).func_149878_d(world, wx, wy, wz, world.rand); - } - // or a mushroom - if (planterBlock == Blocks.brown_mushroom || planterBlock == Blocks.red_mushroom) { - int wx = getXWithOffset(cx, cz); - int wy = getYWithOffset(2); - int wz = getZWithOffset(cx, cz); - ((BlockMushroom)planterBlock).updateTick(world, wx, wy, wz, world.rand); - } - + setBlockState(world, Blocks.GRASS.getDefaultState(), cx, 1, cz, sbb); + + int i = rand.nextInt(6); + boolean isTree = i > 4; + final IBlockState plant = isTree ? StructureTFHelper.randomSapling(i) : StructureTFHelper.randomMushroom(i); + + + setBlockState(world, plant, cx, 2, cz, sbb); + final BlockPos pos = getBlockPosWithOffset(cx, 2, cz); + + if(isTree) //grow tree + ((BlockSapling) Blocks.SAPLING).grow(world, pos, plant, world.rand); + else //grow sapling + plant.getBlock().updateTick(world, pos, plant, world.rand); + + // otherwise, place the block into a flowerpot - Block whatHappened = this.getBlockAtCurrentPosition(world, cx + 0, 2, cz + 0, sbb); - if (whatHappened == planterBlock || whatHappened == Blocks.air) - { - int potMeta = 0;//BlockFlowerPot.getMetaForPlant(new ItemStack(planterBlock, 1, planterMeta)); - placeBlockAtCurrentPosition(world, Blocks.flower_pot, potMeta, cx + 0, 2, cz + 0, sbb); - } + IBlockState whatHappened = this.getBlockStateFromPos(world, cx, 2, cz, sbb); + if (whatHappened.getBlock() == plant.getBlock() || whatHappened.getBlock() == Blocks.AIR) + setBlockState(world, Blocks.FLOWER_POT.getDefaultState(), cx, 2, cz, sbb); } - + /** * Decorate the floor of this stair tower with a scenic well. */ @@ -1555,31 +1386,32 @@ protected void decorateStairWell(World world, Random rand, StructureBoundingBox int cx = size / 2; int cz = cx; int cy = 1; - - Block waterOrLava = rand.nextInt(4) == 0 ? Blocks.lava : Blocks.water; - + + final IBlockState waterOrLava = rand.nextInt(4) == 0 ? Blocks.LAVA.getDefaultState() : Blocks.WATER.getDefaultState(); + + final IBlockState stoneSlab = Blocks.STONE_SLAB.getDefaultState().withProperty(BlockStoneSlab.VARIANT, SMOOTHBRICK); + final IBlockState stoneBrick = Blocks.STONEBRICK.getDefaultState(); + if (size > 7) { // actual well structure - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, cy + 0, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx - 1, cy + 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 0, cy + 0, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, cy + 0, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx + 1, cy + 1, cz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, waterOrLava, 0, cx + 0, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, cy + 0, cz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx - 1, cy + 0, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx - 1, cy + 1, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 0, cy + 0, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, cx + 1, cy + 0, cz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 5, cx + 1, cy + 1, cz + 1, sbb); + setBlockState(world, stoneBrick, cx - 1, cy + 0, cz - 1, sbb); + setBlockState(world, stoneSlab, cx - 1, cy + 1, cz - 1, sbb); + setBlockState(world, stoneBrick, cx + 0, cy + 0, cz - 1, sbb); + setBlockState(world, stoneBrick, cx + 1, cy + 0, cz - 1, sbb); + setBlockState(world, stoneSlab, cx + 1, cy + 1, cz - 1, sbb); + setBlockState(world, stoneBrick, cx - 1, cy + 0, cz + 0, sbb); + setBlockState(world, waterOrLava, cx + 0, cy + 0, cz + 0, sbb); + setBlockState(world, stoneBrick, cx + 1, cy + 0, cz + 0, sbb); + setBlockState(world, stoneBrick, cx - 1, cy + 0, cz + 1, sbb); + setBlockState(world, stoneSlab, cx - 1, cy + 1, cz + 1, sbb); + setBlockState(world, stoneBrick, cx + 0, cy + 0, cz + 1, sbb); + setBlockState(world, stoneBrick, cx + 1, cy + 0, cz + 1, sbb); + setBlockState(world, stoneSlab, cx + 1, cy + 1, cz + 1, sbb); } - - placeBlockAtCurrentPosition(world, waterOrLava, 0, cx + 0, cy - 1, cz + 0, sbb); - - } + setBlockState(world, waterOrLava, cx + 0, cy - 1, cz + 0, sbb); + } /** @@ -1597,10 +1429,10 @@ public boolean hasExitsOnAllWalls() { for (int i = 0; i < 4; i++) { exits += this.openingTowards[i] ? 1 : 0; } - + return exits == 4; } - + /** * Returns true if this tower has stairs */ @@ -1612,159 +1444,156 @@ public boolean hasStairs() { * Iterate through the openings on our list and add them to the tower */ protected void makeOpenings(World world, StructureBoundingBox sbb) { - for (ChunkCoordinates door : openings) - { - makeDoorOpening(world, door.posX, door.posY, door.posZ, sbb); + for (BlockPos door : openings) { + makeDoorOpening(world, door.getX(), door.getY(), door.getZ(), sbb); } } - - /** * Make an opening in this tower for a door. This now only makes one opening, so you need two */ protected void makeDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { - // try to add blocks outside this door + // try to add blocks outside this door // if (dx == 0) { -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx - 1, dy + 0, dz, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx - 1, dy + 1, dz, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx - 1, dy + 0, dz, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx - 1, dy + 1, dz, sbb); // } // if (dx == size - 1) { -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx + 1, dy + 0, dz, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx + 1, dy + 1, dz, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx + 1, dy + 0, dz, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx + 1, dy + 1, dz, sbb); // } // if (dz == 0) { -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx, dy + 0, dz - 1, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx, dy + 1, dz - 1, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx, dy + 0, dz - 1, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx, dy + 1, dz - 1, sbb); // } // if (dz == size - 1) { -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx, dy + 0, dz + 1, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx, dy + 1, dz + 1, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx, dy + 0, dz + 1, sbb); +// setBlockState(world, Blocks.STONE.getDefaultState(), dx, dy + 1, dz + 1, sbb); // } // - - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 0, dz, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 1, dz, sbb); + + setBlockState(world, AIR, dx, dy + 0, dz, sbb); + setBlockState(world, AIR, dx, dy + 1, dz, sbb); // updateLight(world, dx, dy + 0, dz); // updateLight(world, dx, dy + 1, dz); - - if (getBlockAtCurrentPosition(world, dx, dy + 2, dz, sbb) != Blocks.air) { - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, dx, dy + 2, dz, sbb); - } - - // clear the door + + if (getBlockStateFromPos(world, dx, dy + 2, dz, sbb).getBlock() != Blocks.AIR) { + IBlockState state = StructureTFHelper.stoneSlabDouble; + setBlockState(world, state, dx, dy + 2, dz, sbb); + } + + // clear the door if (dx == 0) { -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx - 1, dy + 0, dz, sbb); -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx - 1, dy + 1, dz, sbb); - updateLight(world, dx - 1, dy + 0, dz); - updateLight(world, dx - 1, dy + 1, dz); +// setBlockState(world, AIR, dx - 1, dy + 0, dz, sbb); +// setBlockState(world, AIR, dx - 1, dy + 1, dz, sbb); + updateLight(world, dx - 1, dy + 0, dz); + updateLight(world, dx - 1, dy + 1, dz); } if (dx == size - 1) { -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx + 1, dy + 0, dz, sbb); -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx + 1, dy + 1, dz, sbb); - updateLight(world, dx + 1, dy + 0, dz); - updateLight(world, dx + 1, dy + 1, dz); +// setBlockState(world, AIR, dx + 1, dy + 0, dz, sbb); +// setBlockState(world, AIR, dx + 1, dy + 1, dz, sbb); + updateLight(world, dx + 1, dy + 0, dz); + updateLight(world, dx + 1, dy + 1, dz); } if (dz == 0) { -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 0, dz - 1, sbb); -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 1, dz - 1, sbb); - updateLight(world, dx, dy + 0, dz - 1); - updateLight(world, dx, dy + 1, dz - 1); +// setBlockState(world, AIR, dx, dy + 0, dz - 1, sbb); +// setBlockState(world, AIR, dx, dy + 1, dz - 1, sbb); + updateLight(world, dx, dy + 0, dz - 1); + updateLight(world, dx, dy + 1, dz - 1); } if (dz == size - 1) { -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 0, dz + 1, sbb); -// placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 1, dz + 1, sbb); - updateLight(world, dx, dy + 0, dz + 1); - updateLight(world, dx, dy + 1, dz + 1); +// setBlockState(world, AIR, dx, dy + 0, dz + 1, sbb); +// setBlockState(world, AIR, dx, dy + 1, dz + 1, sbb); + updateLight(world, dx, dy + 0, dz + 1); + updateLight(world, dx, dy + 1, dz + 1); } } - - public void updateLight(World world, int dx, int dy, int dz) { + + protected void updateLight(World world, int dx, int dy, int dz) { //world.updateAllLightTypes(getXWithOffset(dx, dz), getYWithOffset(dy), getZWithOffset(dx, dz)); } - + /** * Gets a random position in the specified direction that connects to stairs currently in the tower. */ - public int[] getValidOpening(Random rand, int direction) { + public int[] getValidOpening(Random rand, Rotation direction) { // variables! int wLength = size - 2; // wall length int offset = 1; // wall thickness - + // size 15 towers have funny landings, so don't generate on the very edge if (this.size == 15) { wLength = 11; offset = 2; } - + // for directions 0 or 2, the wall lies along the z axis - if (direction == 0 || direction == 2) { - int rx = direction == 0 ? size - 1 : 0; + if (direction == Rotation.NONE || direction == Rotation.CLOCKWISE_180) { + int rx = direction == Rotation.NONE ? size - 1 : 0; int rz = offset + rand.nextInt(wLength); int ry = getYByStairs(rz, rand, direction); - - return new int[] {rx, ry, rz}; + + return new int[]{rx, ry, rz}; } - + // for directions 1 or 3, the wall lies along the x axis - if (direction == 1 || direction == 3) { + if (direction == Rotation.CLOCKWISE_90 || direction == Rotation.COUNTERCLOCKWISE_90) { int rx = offset + rand.nextInt(wLength); - int rz = direction == 1 ? size - 1 : 0; + int rz = direction == Rotation.CLOCKWISE_90 ? size - 1 : 0; int ry = getYByStairs(rx, rand, direction); - - return new int[] {rx, ry, rz}; + + return new int[]{rx, ry, rz}; } - - - return new int[] {0, 0, 0}; - } + return new int[]{0, 0, 0}; + } + /** * Gets a Y value where the stairs meet the specified X coordinate. * Also works for Z coordinates. */ - protected int getYByStairs(int rx, Random rand, int direction) { + protected int getYByStairs(int rx, Random rand, Rotation direction) { // initialize some variables int rise = 1; int base = 0; - + if (size == 15) { rise = 10; // we lie a little here to get the towers off the ground - base = (direction == 0 || direction == 2) ? 23 : 28; + base = (direction == Rotation.NONE || direction == Rotation.CLOCKWISE_180) ? 23 : 28; } if (size == 9) { rise = 6; - base = (direction == 0 || direction == 2) ? 2 : 5; + base = (direction == Rotation.NONE || direction == Rotation.CLOCKWISE_180) ? 2 : 5; } if (size == 7) { rise = 4; - base = (direction == 0 || direction == 2) ? 2 : 4; + base = (direction == Rotation.NONE || direction == Rotation.CLOCKWISE_180) ? 2 : 4; } if (size == 5) { rise = 4; // bleh, a switch. switch (direction) { - case 0: - base = 3; - break; - case 1: - base = 2; - break; - case 2: - base = 5; - break; - case 3: - base = 4; - break; + case NONE: + base = 3; + break; + case CLOCKWISE_90: + base = 2; + break; + case CLOCKWISE_180: + base = 5; + break; + case COUNTERCLOCKWISE_90: + base = 4; + break; } } - + int flights = ((height - 6 - base) / rise) + 1; - + if (base > 0 && flights > 0) { // pick a flight of stairs to be on int flightChosen = rand.nextInt(flights); @@ -1773,11 +1602,10 @@ protected int getYByStairs(int rx, Random rand, int direction) { // the staircase (a/de)scends across the room. if (size == 15) { // blech, another dumb kludge here - dy -= (direction == 0 || direction == 3) ? (rx - 2) / 2 : (size - rx - 3) / 2; - } - else { + dy -= (direction == Rotation.NONE || direction == Rotation.COUNTERCLOCKWISE_90) ? (rx - 2) / 2 : (size - rx - 3) / 2; + } else { // the rest are fairly normal - dy -= (direction == 0 || direction == 3) ? (rx - 1) / 2 : (size - rx - 2) / 2; + dy -= (direction == Rotation.NONE || direction == Rotation.COUNTERCLOCKWISE_90) ? (rx - 1) / 2 : (size - rx - 2) / 2; } // // even xs can be one higher if they want. // if (rx % 2 == 0 && size != 15) { @@ -1795,70 +1623,69 @@ protected int getYByStairs(int rx, Random rand, int direction) { } - /** * Makes 3 windows outside this tower. - * + *

* The function currently looks "outside" to see if the window will be blocked, but it can't see into the future, so a tower built after this one may block it. - * + *

* Maybe this could eventually have access to the list of bounding boxes for better accuracy? */ protected void makeWindows(World world, Random rand, StructureBoundingBox sbb, boolean real) { - - - for (int i = 0; i < 4; i++) { - boolean realWindows = real && !openingTowards[i]; - makeWindowBlock(world, size - 1, 2, size / 2, i, sbb, realWindows); - makeWindowBlock(world, size - 1, 3, size / 2, i, sbb, realWindows); - makeWindowBase(world, size - 1, 1, size / 2, i, sbb); + + + //for (int i = 0; i < 4; i++) { + for (Rotation rotation : RotationUtil.ROTATIONS) { + boolean realWindows = real && !openingTowards[rotation.ordinal()]; + makeWindowBlock(world, size - 1, 2, size / 2, rotation, sbb, realWindows); + makeWindowBlock(world, size - 1, 3, size / 2, rotation, sbb, realWindows); + makeWindowBase(world, size - 1, 1, size / 2, rotation, sbb); if (height > 8) { - makeWindowBlock(world, size - 1, height - 3, size / 2, i, sbb, realWindows); - makeWindowBlock(world, size - 1, height - 4, size / 2, i, sbb, realWindows); - makeWindowBase(world, size - 1, height - 5, size / 2, i, sbb); + makeWindowBlock(world, size - 1, height - 3, size / 2, rotation, sbb, realWindows); + makeWindowBlock(world, size - 1, height - 4, size / 2, rotation, sbb, realWindows); + makeWindowBase(world, size - 1, height - 5, size / 2, rotation, sbb); } } } - /** - * Makes a window block. Specify a point in a wall, and this function checks to + * Makes a window block. Specify a point in a wall, and this function checks to * see if it is blocked on the inside or outside, and if not, adds a pane of glass. */ - protected void makeWindowBlock(World world, int x, int y, int z, int rotation, StructureBoundingBox sbb, boolean realWindows) { - int temp = this.getCoordBaseMode(); - this.setCoordBaseMode((this.getCoordBaseMode() + rotation) % 4); - + protected void makeWindowBlock(World world, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb, boolean realWindows) { + EnumFacing temp = this.getCoordBaseMode(); + this.setCoordBaseMode(rotation.rotate(temp)); + // look outside - Block outside = getBlockAtCurrentPosition(world, x + 1, y, z, sbb); - + Block outside = getBlockStateFromPos(world, x + 1, y, z, sbb).getBlock(); + // look inside - Block inside = getBlockAtCurrentPosition(world, x - 1, y, z, sbb); - + Block inside = getBlockStateFromPos(world, x - 1, y, z, sbb).getBlock(); + // make a window! - if (realWindows && inside == Blocks.air && outside == Blocks.air) { - placeBlockAtCurrentPosition(world, Blocks.glass_pane, 0, x, y, z, sbb); - } - else { + if (realWindows && inside == Blocks.AIR && outside == Blocks.AIR) { + setBlockState(world, Blocks.GLASS_PANE.getDefaultState(), x, y, z, sbb); + } else { // cobblestone where the window might have been - placeBlockAtCurrentPosition(world, Blocks.cobblestone, 0, x, y, z, sbb); + setBlockState(world, Blocks.COBBLESTONE.getDefaultState(), x, y, z, sbb); } - + this.setCoordBaseMode(temp); - + } - + /** * Makes a window base */ - protected void makeWindowBase(World world, int x, int y, int z, int rotation, StructureBoundingBox sbb) { - int temp = this.getCoordBaseMode(); - this.setCoordBaseMode((this.getCoordBaseMode() + rotation) % 4); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, x, y, z, sbb); + protected void makeWindowBase(World world, int x, int y, int z, Rotation rotation, StructureBoundingBox sbb) { + EnumFacing temp = this.getCoordBaseMode(); + this.setCoordBaseMode(rotation.rotate(temp)); + IBlockState state = StructureTFHelper.stoneSlabDouble; + setBlockState(world, state, x, y, z, sbb); this.setCoordBaseMode(temp); - + } - + /** * Add stairs to this tower. */ @@ -1888,29 +1715,30 @@ protected boolean makeStairs5(World world, Random rand, StructureBoundingBox sbb // int numFlights = ((this.height - 3) / rise) - 1; int numFlights = (highestOpening / rise); for (int i = 0; i < numFlights; i++) { - makeStairs5flight(world, rand, sbb, i * rise, 0 + (i * 3), 2); + makeStairs5flight(world, rand, sbb, i * rise, getRotation(Rotation.NONE, i * 3), true); } return true; } - + /** * Function called by makeStairs5 to place stair blocks - * - * @param height - * @param rotation */ - protected void makeStairs5flight(World world, Random rand, StructureBoundingBox sbb, int height, int rotation, int meta) { - int temp = this.getCoordBaseMode(); - - this.setCoordBaseMode((this.getCoordBaseMode() + rotation) % 4); - - BlockSlab singleSlabBlock = meta == 0 ? Blocks.stone_slab : Blocks.wooden_slab; - Block doubleSlabBlock = meta == 0 ? Blocks.double_stone_slab : Blocks.planks; - - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 2, 1 + height, 3, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 3, 1 + height, 3, sbb); - + protected void makeStairs5flight(World world, Random rand, StructureBoundingBox sbb, int height, Rotation rotation, boolean useBirchWood) { + EnumFacing temp = this.getCoordBaseMode(); + + this.setCoordBaseMode(rotation.rotate(temp)); + + final IBlockState bottomSlab = useBirchWood ? + StructureTFHelper.birchSlab : + StructureTFHelper.stoneSlab; + final IBlockState topSlab = useBirchWood ? + StructureTFHelper.birchSlabTop : + StructureTFHelper.stoneSlabTop; + + setBlockState(world, bottomSlab, 2, 1 + height, 3, sbb); + setBlockState(world, topSlab, 3, 1 + height, 3, sbb); + this.setCoordBaseMode(temp); } @@ -1919,43 +1747,42 @@ protected void makeStairs5flight(World world, Random rand, StructureBoundingBox */ protected boolean makeStairs7(World world, Random rand, StructureBoundingBox sbb) { // foot of stairs - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, 1, 1, 4, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 1, 1, 5, sbb); - - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, 5, 1, 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 5, 1, 1, sbb); - + setBlockState(world, StructureTFHelper.birchSlab, 1, 1, 4, sbb); + setBlockState(world, StructureTFHelper.birchSlabTop, 1, 1, 5, sbb); + + setBlockState(world, StructureTFHelper.stoneSlab, 5, 1, 2, sbb); + setBlockState(world, StructureTFHelper.stoneSlabTop, 5, 1, 1, sbb); + // staircases rotating around the tower int rise = 2; -// int numFlights = ((this.height - 3) / rise) - 1; int numFlights = (highestOpening / rise); for (int i = 0; i < numFlights; i++) { - makeStairs7flight(world, rand, sbb, 1 + i * rise, 0 + (i * 3), 2); - makeStairs7flight(world, rand, sbb, 1 + i * rise, 2 + (i * 3), 0); + makeStairs7flight(world, rand, sbb, 1 + i * rise, getRotation(Rotation.NONE, i * 3), true); + makeStairs7flight(world, rand, sbb, 1 + i * rise, getRotation(Rotation.CLOCKWISE_180, i * 3), false); } return true; } - + /** * Function called by makeStairs7 to place stair blocks - * - * @param height - * @param rotation */ - protected void makeStairs7flight(World world, Random rand, StructureBoundingBox sbb, int height, int rotation, int meta) { - int temp = this.getCoordBaseMode(); - - this.setCoordBaseMode((this.getCoordBaseMode() + rotation) % 4); - - BlockSlab singleSlabBlock = meta == 0 ? Blocks.stone_slab : Blocks.wooden_slab; - Block doubleSlabBlock = meta == 0 ? Blocks.double_stone_slab : Blocks.planks; - - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 2, 1 + height, 5, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 3, 1 + height, 5, sbb); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 4, 2 + height, 5, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 5, 2 + height, 5, sbb); - + protected void makeStairs7flight(World world, Random rand, StructureBoundingBox sbb, int height, Rotation rotation, boolean useBirchWood) { + final EnumFacing temp = this.getCoordBaseMode(); + + this.setCoordBaseMode(rotation.rotate(temp)); + final IBlockState slabBottom = useBirchWood ? + StructureTFHelper.birchSlab : + StructureTFHelper.stoneSlab; + final IBlockState slabTop = useBirchWood ? + StructureTFHelper.birchSlabTop : + StructureTFHelper.stoneSlabTop; + + setBlockState(world, slabBottom, 2, 1 + height, 5, sbb); + setBlockState(world, slabTop, 3, 1 + height, 5, sbb); + setBlockState(world, slabBottom, 4, 2 + height, 5, sbb); + setBlockState(world, slabTop, 5, 2 + height, 5, sbb); + this.setCoordBaseMode(temp); } @@ -1963,46 +1790,48 @@ protected void makeStairs7flight(World world, Random rand, StructureBoundingBox * Stair maker for a size 9 tower */ protected boolean makeStairs9(World world, Random rand, StructureBoundingBox sbb) { + // foot of stairs - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, 1, 1, 6, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 1, 1, 7, sbb); + setBlockState(world, StructureTFHelper.birchSlab, 1, 1, 6, sbb); + setBlockState(world, StructureTFHelper.birchSlabTop, 1, 1, 7, sbb); + + setBlockState(world, StructureTFHelper.stoneSlab, 7, 1, 2, sbb); + setBlockState(world, StructureTFHelper.stoneSlabTop, 7, 1, 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, 7, 1, 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 7, 1, 1, sbb); - // staircases rotating around the tower int rise = 3; -// int numFlights = ((this.height - 3) / rise) - 1; int numFlights = (highestOpening / rise); for (int i = 0; i < numFlights; i++) { - makeStairs9flight(world, rand, sbb, 1 + i * rise, 0 + (i * 3), 2); - makeStairs9flight(world, rand, sbb, 1 + i * rise, 2 + (i * 3), 0); + makeStairs9flight(world, rand, sbb, 1 + i * rise, getRotation(Rotation.NONE, i * 3), true); + makeStairs9flight(world, rand, sbb, 1 + i * rise, getRotation(Rotation.CLOCKWISE_180, i * 3), false); } - + return true; } - + /** * Function called by makeStairs7 to place stair blocks - * - * @param height - * @param rotation + * */ - protected void makeStairs9flight(World world, Random rand, StructureBoundingBox sbb, int height, int rotation, int meta) { - int temp = this.getCoordBaseMode(); - - this.setCoordBaseMode((this.getCoordBaseMode() + rotation) % 4); - - Block singleSlabBlock = meta == 0 ? Blocks.stone_slab : Blocks.wooden_slab; - Block doubleSlabBlock = meta == 0 ? Blocks.double_stone_slab : Blocks.planks; - - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 2, 1 + height, 7, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 3, 1 + height, 7, sbb); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 4, 2 + height, 7, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 5, 2 + height, 7, sbb); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 6, 3 + height, 7, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 7, 3 + height, 7, sbb); - + protected void makeStairs9flight(World world, Random rand, StructureBoundingBox sbb, int height, Rotation rotation, boolean useBirchWood) { + //TODO: Can we just... not do this? + EnumFacing temp = this.getCoordBaseMode(); + this.setCoordBaseMode(rotation.rotate(temp)); + + final IBlockState slabBot = useBirchWood ? + StructureTFHelper.birchSlab : + StructureTFHelper.stoneSlab; + final IBlockState slabTop = useBirchWood ? + StructureTFHelper.birchSlabTop : + StructureTFHelper.stoneSlabTop; + + setBlockState(world, slabBot, 2, 1 + height, 7, sbb); + setBlockState(world, slabTop, 3, 1 + height, 7, sbb); + setBlockState(world, slabBot, 4, 2 + height, 7, sbb); + setBlockState(world, slabTop, 5, 2 + height, 7, sbb); + setBlockState(world, slabBot, 6, 3 + height, 7, sbb); + setBlockState(world, slabTop, 7, 3 + height, 7, sbb); + this.setCoordBaseMode(temp); } @@ -2010,325 +1839,311 @@ protected void makeStairs9flight(World world, Random rand, StructureBoundingBox * Stair maker for a size 15 tower */ protected boolean makeStairs15(World world, Random rand, StructureBoundingBox sbb) { + final IBlockState planks = Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH); + final IBlockState oakFence = Blocks.OAK_FENCE.getDefaultState(); + final IBlockState birchSlab = StructureTFHelper.birchSlab; + final IBlockState stoneSlab = StructureTFHelper.stoneSlab; + final IBlockState doubleStoneSlab = StructureTFHelper.stoneSlabDouble; + // foot of stairs - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, 1, 1, 9, sbb); - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, 2, 1, 9, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 1, 1, 10, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 2, 1, 10, sbb); - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, 1, 2, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.wooden_slab, 2, 2, 2, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 1, 2, 12, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 2, 2, 12, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 1, 2, 13, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 2, 2, 13, sbb); - - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 3, 2, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 3, 3, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 3, 4, 11, sbb); -// placeBlockAtCurrentPosition(world, Blocks.torch, 0, 3, 5, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 3, 1, 10, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 3, 2, 10, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 3, 3, 10, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 2, 3, 1, 9, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 3, 2, 9, sbb); - - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, 13, 1, 5, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, 12, 1, 5, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 13, 1, 4, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 12, 1, 4, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, 13, 2, 3, sbb); - placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, 12, 2, 3, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 13, 2, 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 12, 2, 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 13, 2, 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 12, 2, 1, sbb); -// placeBlockAtCurrentPosition(world, Blocks.stone_slab, 0, 7, 1, 2, sbb); -// placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 7, 1, 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 11, 2, 3, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 11, 3, 3, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 11, 4, 3, sbb); -// placeBlockAtCurrentPosition(world, Blocks.torch, 0, 11, 5, 3, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 11, 1, 4, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 11, 2, 4, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 11, 3, 4, sbb); - placeBlockAtCurrentPosition(world, Blocks.double_stone_slab, 0, 11, 1, 5, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 11, 2, 5, sbb); - - + setBlockState(world, birchSlab, 1, 1, 9, sbb); + setBlockState(world, birchSlab, 2, 1, 9, sbb); + + setBlockState(world, planks, 1, 1, 10, sbb); + setBlockState(world, planks, 2, 1, 10, sbb); + setBlockState(world, birchSlab, 1, 2, 11, sbb); + setBlockState(world, birchSlab, 2, 2, 11, sbb); + setBlockState(world, planks, 1, 2, 12, sbb); + setBlockState(world, planks, 2, 2, 12, sbb); + setBlockState(world, planks, 1, 2, 13, sbb); + setBlockState(world, planks, 2, 2, 13, sbb); + + setBlockState(world, planks, 3, 2, 11, sbb); + setBlockState(world, oakFence, 3, 3, 11, sbb); + setBlockState(world, oakFence, 3, 4, 11, sbb); + setBlockState(world, planks, 3, 1, 10, sbb); + setBlockState(world, oakFence, 3, 2, 10, sbb); + setBlockState(world, oakFence, 3, 3, 10, sbb); + setBlockState(world, planks, 3, 1, 9, sbb); + setBlockState(world, oakFence, 3, 2, 9, sbb); + + setBlockState(world, stoneSlab, 13, 1, 5, sbb); + setBlockState(world, stoneSlab, 12, 1, 5, sbb); + setBlockState(world, doubleStoneSlab, 13, 1, 4, sbb); + setBlockState(world, doubleStoneSlab, 12, 1, 4, sbb); + setBlockState(world, stoneSlab, 13, 2, 3, sbb); + setBlockState(world, stoneSlab, 12, 2, 3, sbb); + setBlockState(world, doubleStoneSlab, 13, 2, 2, sbb); + setBlockState(world, doubleStoneSlab, 12, 2, 2, sbb); + setBlockState(world, doubleStoneSlab, 13, 2, 1, sbb); + setBlockState(world, doubleStoneSlab, 12, 2, 1, sbb); + setBlockState(world, doubleStoneSlab, 11, 2, 3, sbb); + setBlockState(world, oakFence, 11, 3, 3, sbb); + setBlockState(world, oakFence, 11, 4, 3, sbb); + setBlockState(world, doubleStoneSlab, 11, 1, 4, sbb); + setBlockState(world, oakFence, 11, 2, 4, sbb); + setBlockState(world, oakFence, 11, 3, 4, sbb); + setBlockState(world, doubleStoneSlab, 11, 1, 5, sbb); + setBlockState(world, oakFence, 11, 2, 5, sbb); + + // staircases rotating around the tower int rise = 5; -// int numFlights = ((this.height - 3) / rise) - 1; int numFlights = (highestOpening / rise); for (int i = 0; i < numFlights; i++) { - makeStairs15flight(world, rand, sbb, 2 + i * rise, 0 + (i * 3), 2); - makeStairs15flight(world, rand, sbb, 2 + i * rise, 2 + (i * 3), 0); + makeStairs15flight(world, rand, sbb, 2 + i * rise, getRotation(Rotation.NONE, i * 3), true); + makeStairs15flight(world, rand, sbb, 2 + i * rise, getRotation(Rotation.CLOCKWISE_180, i * 3), false); } - + return true; } - + + private Rotation getRotation(Rotation startRotation, int rotations) { + final int totalIncrements = startRotation.ordinal() + rotations; + return RotationUtil.ROTATIONS[totalIncrements & 3]; + } + /** * Function called by makeStairs7 to place stair blocks - * - * @param height - * @param rotation + * pretty sure this is the one that makes the main staircase */ - protected void makeStairs15flight(World world, Random rand, StructureBoundingBox sbb, int height, int rotation, int meta) { - int temp = this.getCoordBaseMode(); - - this.setCoordBaseMode((this.getCoordBaseMode() + rotation) % 4); - - Block singleSlabBlock = meta == 0 ? Blocks.stone_slab : Blocks.wooden_slab; - Block doubleSlabBlock = meta == 0 ? Blocks.double_stone_slab : Blocks.planks; - - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 3, 1 + height, 13, sbb); - randomlyPlaceBlock(world, sbb, rand, 0.9F, 4, 1 + height, 13, doubleSlabBlock, meta); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 5, 2 + height, 13, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 6, 2 + height, 13, sbb); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 7, 3 + height, 13, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 8, 3 + height, 13, sbb); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 9, 4 + height, 13, sbb); - randomlyPlaceBlock(world, sbb, rand, 0.9F, 10, 4 + height, 13, doubleSlabBlock, meta); - randomlyPlaceBlock(world, sbb, rand, 0.9F, 11, 5 + height, 13, singleSlabBlock, meta); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 12, 5 + height, 13, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 13, 5 + height, 13, sbb); - - randomlyPlaceBlock(world, sbb, rand, 0.9F, 3, 1 + height, 12, singleSlabBlock, meta); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 4, 1 + height, 12, sbb); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 5, 2 + height, 12, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 6, 2 + height, 12, sbb); - randomlyPlaceBlock(world, sbb, rand, 0.9F, 7, 3 + height, 12, singleSlabBlock, meta); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 8, 3 + height, 12, sbb); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 9, 4 + height, 12, sbb); - randomlyPlaceBlock(world, sbb, rand, 0.9F, 10, 4 + height, 12, doubleSlabBlock, meta); - placeBlockAtCurrentPosition(world, singleSlabBlock, meta, 11, 5 + height, 12, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 12, 5 + height, 12, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 13, 5 + height, 12, sbb); - - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 4, 1 + height, 11, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 5, 2 + height, 11, sbb); - randomlyPlaceBlock(world, sbb, rand, 0.9F, 6, 2 + height, 11, doubleSlabBlock, meta); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 7, 3 + height, 11, sbb); - randomlyPlaceBlock(world, sbb, rand, 0.9F, 8, 3 + height, 11, doubleSlabBlock, meta); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 9, 4 + height, 11, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 10, 4 + height, 11, sbb); - placeBlockAtCurrentPosition(world, doubleSlabBlock, meta, 11, 5 + height, 11, sbb); - - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 4, 2 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 5, 3 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 6, 3 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 7, 4 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 8, 4 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 9, 5 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 10, 5 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 11, 6 + height, 11, sbb); - - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 4, 3 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 6, 4 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 8, 5 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 10, 6 + height, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.fence, 0, 11, 7 + height, 11, sbb); - -// placeBlockAtCurrentPosition(world, Blocks.torch, 0, 11, 8 + height, 11, sbb); + protected void makeStairs15flight(World world, Random rand, StructureBoundingBox sbb, int height, Rotation rotation, boolean useBirchWood) { + EnumFacing temp = this.getCoordBaseMode(); + + this.setCoordBaseMode(rotation.rotate(temp)); + + final IBlockState oakFence = Blocks.OAK_FENCE.getDefaultState(); + + final IBlockState slabBot = useBirchWood ? + StructureTFHelper.birchSlab : + StructureTFHelper.stoneSlab; + final IBlockState slabTop = useBirchWood ? + StructureTFHelper.birchSlabTop : + StructureTFHelper.stoneSlabTop; + final IBlockState slabDoub = useBirchWood ? + StructureTFHelper.birchPlanks : + StructureTFHelper.stoneSlabDouble; + + setBlockState(world, slabBot, 3, 1 + height, 13, sbb); + randomlyPlaceBlock(world, sbb, rand, 0.9F, 4, 1 + height, 13, slabTop); + setBlockState(world, slabBot, 5, 2 + height, 13, sbb); + setBlockState(world, slabTop, 6, 2 + height, 13, sbb); + setBlockState(world, slabBot, 7, 3 + height, 13, sbb); + setBlockState(world, slabTop, 8, 3 + height, 13, sbb); + setBlockState(world, slabBot, 9, 4 + height, 13, sbb); + randomlyPlaceBlock(world, sbb, rand, 0.9F, 10, 4 + height, 13, slabTop); + randomlyPlaceBlock(world, sbb, rand, 0.9F, 11, 5 + height, 13, slabBot); + setBlockState(world, slabTop, 12, 5 + height, 13, sbb); + setBlockState(world, slabTop, 13, 5 + height, 13, sbb); + + randomlyPlaceBlock(world, sbb, rand, 0.9F, 3, 1 + height, 12, slabBot); + setBlockState(world, slabTop, 4, 1 + height, 12, sbb); + setBlockState(world, slabBot, 5, 2 + height, 12, sbb); + setBlockState(world, slabTop, 6, 2 + height, 12, sbb); + randomlyPlaceBlock(world, sbb, rand, 0.9F, 7, 3 + height, 12, slabBot); + setBlockState(world, slabTop, 8, 3 + height, 12, sbb); + setBlockState(world, slabBot, 9, 4 + height, 12, sbb); + randomlyPlaceBlock(world, sbb, rand, 0.9F, 10, 4 + height, 12, slabTop); + setBlockState(world, slabBot, 11, 5 + height, 12, sbb); + setBlockState(world, slabTop, 12, 5 + height, 12, sbb); + setBlockState(world, slabTop, 13, 5 + height, 12, sbb); + + setBlockState(world, slabDoub, 4, 1 + height, 11, sbb); + setBlockState(world, slabDoub, 5, 2 + height, 11, sbb); + randomlyPlaceBlock(world, sbb, rand, 0.9F, 6, 2 + height, 11, slabTop); + setBlockState(world, slabDoub, 7, 3 + height, 11, sbb); + randomlyPlaceBlock(world, sbb, rand, 0.9F, 8, 3 + height, 11, slabTop); + setBlockState(world, slabDoub, 9, 4 + height, 11, sbb); + setBlockState(world, slabTop, 10, 4 + height, 11, sbb); + setBlockState(world, slabDoub, 11, 5 + height, 11, sbb); + + setBlockState(world, oakFence, 4, 2 + height, 11, sbb); + setBlockState(world, oakFence, 5, 3 + height, 11, sbb); + setBlockState(world, oakFence, 6, 3 + height, 11, sbb); + setBlockState(world, oakFence, 7, 4 + height, 11, sbb); + setBlockState(world, oakFence, 8, 4 + height, 11, sbb); + setBlockState(world, oakFence, 9, 5 + height, 11, sbb); + setBlockState(world, oakFence, 10, 5 + height, 11, sbb); + setBlockState(world, oakFence, 11, 6 + height, 11, sbb); + + setBlockState(world, oakFence, 4, 3 + height, 11, sbb); + setBlockState(world, oakFence, 6, 4 + height, 11, sbb); + setBlockState(world, oakFence, 8, 5 + height, 11, sbb); + setBlockState(world, oakFence, 10, 6 + height, 11, sbb); + setBlockState(world, oakFence, 11, 7 + height, 11, sbb); this.setCoordBaseMode(temp); } - - - - /** * Makes paintings of the minimum size or larger on the specified wall */ - protected void generatePaintingsOnWall(World world, Random rand, int howMany, int floorLevel, int direction, int minSize, StructureBoundingBox sbb) { + protected void generatePaintingsOnWall(World world, Random rand, int howMany, int floorLevel, EnumFacing direction, int minSize, StructureBoundingBox sbb) { for (int i = 0; i < howMany; i++) { // get some random coordinates on the wall in the chunk - ChunkCoordinates pCoords = getRandomWallSpot(rand, floorLevel, direction, sbb); - + BlockPos pCoords = getRandomWallSpot(rand, floorLevel, direction, sbb); + // initialize a painting object - EntityPainting painting = new EntityPainting(world, pCoords.posX, pCoords.posY, pCoords.posZ, direction); - painting.art = getPaintingOfSize(rand, minSize); - painting.setDirection(direction); - - // temporary function, make a real bounding box for the painting - + EnumArt art = getPaintingOfSize(rand, minSize); + EntityPainting painting = new EntityPainting(world, pCoords, direction); + painting.art = art; + painting.setPosition(pCoords.getX(), pCoords.getY(), pCoords.getZ()); // this is done to refresh the bounding box after changing the art + // check if we can fit a painting there if (checkPainting(world, painting, sbb)) { // place the painting - //System.out.println("Painting success " + painting.art.title + " at " + painting.xPosition + " , " + painting.yPosition + ", " + painting.zPosition + " : " + painting.field_82332_a); - world.spawnEntityInWorld(painting); - } - else { - //System.out.println("Painting fail!! " + painting.art.title + " at " + painting.xPosition + " , " + painting.yPosition + ", " + painting.zPosition + " : " + painting.field_82332_a); + world.spawnEntity(painting); } } } - + /** * At least one of the painting's parameters must be the specified size or greater */ protected EnumArt getPaintingOfSize(Random rand, int minSize) { - ArrayList valid = new ArrayList(); + ArrayList valid = new ArrayList(); - for (EnumArt art : EnumArt.values()) { - if (art.sizeX >= minSize || art.sizeY >= minSize) - { - valid.add(art); - } - } + for (EnumArt art : EnumArt.values()) { + if (art.sizeX >= minSize || art.sizeY >= minSize) { + valid.add(art); + } + } - if (valid.size() > 0) - { - return valid.get(rand.nextInt(valid.size())); - } - else { - return null; - } + if (valid.size() > 0) { + return valid.get(rand.nextInt(valid.size())); + } else { + return null; + } } /** * This is similar to EntityPainting.isOnValidSurface, except that it does not check for a solid wall behind the painting. */ - @SuppressWarnings("unchecked") protected boolean checkPainting(World world, EntityPainting painting, StructureBoundingBox sbb) { - + if (painting == null) { return false; } - - //TODO: this is a temporary workaround to fix the bad painting bounding boxes - - AxisAlignedBB largerBox; - if (painting.hangingDirection == 0 || painting.hangingDirection == 2) { - largerBox = painting.boundingBox.expand(1, 1, 0.06); - } - else { - largerBox = painting.boundingBox.expand(0.06, 1, 1); - } - - if (world.getCollidingBoundingBoxes(painting, largerBox).size() > 0) - { - return false; - } - - List collidingEntities = world.getEntitiesWithinAABBExcludingEntity(painting, largerBox); - for (Entity entityOnList : collidingEntities) - { - if (entityOnList instanceof EntityHanging) - { - return false; - } - } + final AxisAlignedBB largerBox = painting.getEntityBoundingBox(); - return true; + if (!world.getCollisionBoxes(painting, largerBox).isEmpty()) { + return false; + } else { + List collidingEntities = world.getEntitiesWithinAABBExcludingEntity(painting, largerBox); + for (Entity entityOnList : collidingEntities) { + if (entityOnList instanceof EntityHanging) { + return false; + } + } + return true; + } } /** * This returns the real-world coordinates of a possible painting or torch spot on the specified wall of this tower. */ - protected ChunkCoordinates getRandomWallSpot(Random rand, int floorLevel, int direction, StructureBoundingBox sbb) { + protected BlockPos getRandomWallSpot(Random rand, int floorLevel, EnumFacing direction, StructureBoundingBox sbb) { int minX = this.boundingBox.minX + 2; int maxX = this.boundingBox.maxX - 2; int minY = this.boundingBox.minY + floorLevel + 2; int maxY = this.boundingBox.maxY - 2; - + int minZ = this.boundingBox.minZ + 2; int maxZ = this.boundingBox.maxZ - 2; // constrain the paintings to one wall // these directions correspond to painting facing directions, not necessarily to the structure orienting directions - if (direction == 0) { + if (direction == EnumFacing.SOUTH) { minZ = this.boundingBox.minZ; maxZ = this.boundingBox.minZ; } - if (direction == 1) { + else if (direction == EnumFacing.WEST) { maxX = this.boundingBox.maxX; minX = this.boundingBox.maxX; } - if (direction == 2) { + else if (direction == EnumFacing.NORTH) { maxZ = this.boundingBox.maxZ; minZ = this.boundingBox.maxZ; } - if (direction == 3) { + else if (direction == EnumFacing.EAST) { minX = this.boundingBox.minX; maxX = this.boundingBox.minX; } - + // try 30 times to get a proper result for (int i = 0; i < 30; i++) { int cx = minX + (maxX > minX ? rand.nextInt(maxX - minX) : 0); int cy = minY + (maxY > minY ? rand.nextInt(maxY - minY) : 0); int cz = minZ + (maxZ > minZ ? rand.nextInt(maxZ - minZ) : 0); - - if (sbb.isVecInside(cx, cy, cz)) { -// System.out.println("Found a valid random spot on the wall. It's " + cx + ", " + cy + ", " + cz ); - return new ChunkCoordinates(cx, cy, cz); + + final BlockPos blockPos = new BlockPos(cx, cy, cz).offset(direction); + if (sbb.isVecInside(blockPos)) { + return blockPos; } } - + // I guess we didn't get one -// System.out.println("We didn't find a valid random spot on the wall."); + //TwilightForestMod.LOGGER.info("getRandomWallSpot - We didn't find a valid random spot on the wall."); return null; } /** - * This method is for final castle towers actually. + * This method is for final castle towers actually. * We need to break up this class into a more abstract tower class and a concrete lich tower class one day */ - protected void makeGlyphBranches(World world, Random rand, int meta, StructureBoundingBox sbb) { + protected void makeGlyphBranches(World world, Random rand, EnumDyeColor colour, StructureBoundingBox sbb) { // pick a random side of the tower - int rotation = rand.nextInt(4); - + Rotation rotation = RotationUtil.ROTATIONS[rand.nextInt(4)]; + // start somewhere in the lower part int startHeight = rand.nextInt((int) (this.height * 0.66F)); - + // near the middle int startZ = 3 + rand.nextInt(this.size - 6); - + + final IBlockState magicBlock = TFBlocks.castle_rune_brick.getDefaultState().withProperty(COLOR, colour); + // make a line all the way down to the foundation - int dx = this.getXWithOffsetAsIfRotated(0, startZ, rotation); - int dz = this.getZWithOffsetAsIfRotated(0, startZ, rotation); - if (sbb.isVecInside(dx, this.boundingBox.minY + 1, dz)) { + int dx = this.getXWithOffsetRotated(0, startZ, rotation); + int dz = this.getZWithOffsetRotated(0, startZ, rotation); + if (sbb.isVecInside(new BlockPos(dx, this.boundingBox.minY + 1, dz))) { for (int dy = this.getYWithOffset(startHeight); dy > 0; dy--) { - if (world.getBlock(dx, dy, dz) == TFBlocks.castleBlock) { - //System.out.println("placing glyph brick over " + world.getBlock(dx, dy, dz)); - world.setBlock(dx, dy, dz, TFBlocks.castleMagic, meta, 2); + final BlockPos pos = new BlockPos(dx, dy, dz); + if (world.getBlockState(pos).getBlock() == TFBlocks.castle_brick) { + world.setBlockState(pos, magicBlock, 2); } else { - //System.out.println("Stopping glyphs because block is " + world.getBlock(dx, dy, dz)); - //System.out.println("dy = " + dy + " because startHeight = " + startHeight + " and startZ = " + startZ); break; } } } - + // go left a little int leftOffset = startZ - (1 + rand.nextInt(3)); int leftHeight = rand.nextInt(this.height - startHeight); if (leftOffset >= 0) { for (int z = startZ; z > leftOffset; z--) { - this.placeBlockRotated(world, TFBlocks.castleMagic, meta, 0, startHeight, z, rotation, sbb); + this.setBlockStateRotated(world, magicBlock, 0, startHeight, z, rotation, sbb); } for (int y = startHeight; y < (startHeight + leftHeight); y++) { - this.placeBlockRotated(world, TFBlocks.castleMagic, meta, 0, y, leftOffset, rotation, sbb); + this.setBlockStateRotated(world, magicBlock, 0, y, leftOffset, rotation, sbb); } } - + // go right a little int rightOffset = startZ + (1 + rand.nextInt(3)); int rightHeight = rand.nextInt(this.height - startHeight); if (rightOffset < this.size - 1) { for (int z = startZ; z < rightOffset; z++) { - this.placeBlockRotated(world, TFBlocks.castleMagic, meta, 0, startHeight, z, rotation, sbb); + this.setBlockStateRotated(world, magicBlock, 0, startHeight, z, rotation, sbb); } for (int y = startHeight; y < (startHeight + rightHeight); y++) { - this.placeBlockRotated(world, TFBlocks.castleMagic, meta, 0, y, rightOffset, rotation, sbb); + this.setBlockStateRotated(world, magicBlock, 0, y, rightOffset, rotation, sbb); } } diff --git a/src/main/java/twilightforest/structures/lichtower/TFLichTowerPieces.java b/src/main/java/twilightforest/structures/lichtower/TFLichTowerPieces.java index e75ace6d1a..f10b3b6dba 100644 --- a/src/main/java/twilightforest/structures/lichtower/TFLichTowerPieces.java +++ b/src/main/java/twilightforest/structures/lichtower/TFLichTowerPieces.java @@ -1,27 +1,29 @@ package twilightforest.structures.lichtower; import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartLichTower; public class TFLichTowerPieces { - public static void registerPieces() - { - MapGenStructureIO.func_143031_a(ComponentTFTowerBeard.class, "TFLTBea"); - MapGenStructureIO.func_143031_a(ComponentTFTowerBeardAttached.class, "TFLTBA"); - MapGenStructureIO.func_143031_a(ComponentTFTowerBridge.class, "TFLTBri"); - MapGenStructureIO.func_143031_a(ComponentTFTowerMain.class, "TFLTMai"); - MapGenStructureIO.func_143031_a(ComponentTFTowerOutbuilding.class, "TFLTOut"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoof.class, "TFLTRoo"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofAttachedSlab.class, "TFLTRAS"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofFence.class, "TFLTRF"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofGableForwards.class, "TFLTRGF"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofPointy.class, "TFLTRP"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofPointyOverhang.class, "TFLTRPO"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofSlab.class, "TFLTRS"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofSlabForwards.class, "TFLTRSF"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofStairs.class, "TFLTRSt"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofStairsOverhang.class, "TFLTRStO"); - MapGenStructureIO.func_143031_a(ComponentTFTowerWing.class, "TFLTWin"); - - } + public static void registerPieces() { + MapGenStructureIO.registerStructure(StructureStartLichTower.class, "TFLT"); + + MapGenStructureIO.registerStructureComponent(ComponentTFTowerBeard.class, "TFLTBea"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerBeardAttached.class, "TFLTBA"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerBridge.class, "TFLTBri"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerMain.class, "TFLTMai"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerOutbuilding.class, "TFLTOut"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoof.class, "TFLTRoo"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofAttachedSlab.class, "TFLTRAS"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofFence.class, "TFLTRF"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofGableForwards.class, "TFLTRGF"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofPointy.class, "TFLTRP"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofPointyOverhang.class, "TFLTRPO"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofSlab.class, "TFLTRS"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofSlabForwards.class, "TFLTRSF"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofStairs.class, "TFLTRSt"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofStairsOverhang.class, "TFLTRStO"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerWing.class, "TFLTWin"); + + } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridor.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridor.java index 4f81ef7fef..6664a02b9b 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridor.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridor.java @@ -1,32 +1,33 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.Random; -public class ComponentTFMazeCorridor extends StructureTFComponent { +public class ComponentTFMazeCorridor extends StructureTFComponentOld { public ComponentTFMazeCorridor() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeCorridor(int i, int x, int y, int z, int rotation) { - super(i); - this.coordBaseMode = rotation; - this.boundingBox = new StructureBoundingBox(x, y, z, x + 5, y + 5, z + 5); + public ComponentTFMazeCorridor(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i); + this.setCoordBaseMode(rotation); + this.boundingBox = new StructureBoundingBox(x, y, z, x + 5, y + 5, z + 5); } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - + //arch - this.fillWithMetadataBlocks(world, sbb, 1, 1, 2, 4, 4, 3, Blocks.fence, 0, Blocks.air, 0, false); + this.fillWithBlocks(world, sbb, 1, 1, 2, 4, 4, 3, Blocks.OAK_FENCE.getDefaultState(), AIR, false); this.fillWithAir(world, sbb, 2, 1, 2, 3, 3, 3); - + return true; } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorIronFence.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorIronFence.java index af1e50c1cb..1f1bacaa8a 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorIronFence.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorIronFence.java @@ -1,28 +1,31 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; +import twilightforest.enums.MazestoneVariant; + +import java.util.Random; public class ComponentTFMazeCorridorIronFence extends ComponentTFMazeCorridor { public ComponentTFMazeCorridorIronFence() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeCorridorIronFence(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeCorridorIronFence(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - this.fillWithMetadataBlocks(world, sbb, 1, 4, 2, 4, 4, 3, TFBlocks.mazestone, 3, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 1, 1, 2, 4, 3, 3, TFBlocks.mazestone, 2, Blocks.air, 0, false); - this.fillWithBlocks(world, sbb, 2, 1, 2, 3, 3, 3, Blocks.iron_bars, Blocks.air, false); + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + this.fillWithBlocks(world, sbb, 1, 4, 2, 4, 4, 3, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + this.fillWithBlocks(world, sbb, 1, 1, 2, 4, 3, 3, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.CHISELED), AIR, false); + this.fillWithBlocks(world, sbb, 2, 1, 2, 3, 3, 3, Blocks.IRON_BARS.getDefaultState(), Blocks.AIR.getDefaultState(), false); return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorRoots.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorRoots.java index 7be0426c4b..dfbff29119 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorRoots.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorRoots.java @@ -1,52 +1,48 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; + +import java.util.Random; public class ComponentTFMazeCorridorRoots extends ComponentTFMazeCorridor { public ComponentTFMazeCorridorRoots() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeCorridorRoots(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeCorridorRoots(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - for (int x = 1; x < 5; x++) - { - for (int z = 0; z < 5; z++) - { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + for (int x = 1; x < 5; x++) { + for (int z = 0; z < 5; z++) { int freq = x; - if (rand.nextInt(freq + 2) > 0) - { + if (rand.nextInt(freq + 2) > 0) { int length = rand.nextInt(6); //place dirt above ceiling - this.placeBlockAtCurrentPosition(world, Blocks.dirt, 0, x, 6, z, sbb); - + this.setBlockState(world, Blocks.DIRT.getDefaultState(), x, 6, z, sbb); + // roots - for (int y = 6 - length; y < 6; y++) - { - this.placeBlockAtCurrentPosition(world, TFBlocks.plant, BlockTFPlant.META_ROOT_STRAND, x, y, z, sbb); + for (int y = 6 - length; y < 6; y++) { + this.setBlockState(world, TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.ROOT_STRAND), x, y, z, sbb); } - + // occasional gravel - if (rand.nextInt(freq + 1) > 1) - { - this.placeBlockAtCurrentPosition(world, Blocks.gravel, 0, x, 1, z, sbb); - - if (rand.nextInt(freq + 1) > 1) - { - this.placeBlockAtCurrentPosition(world, Blocks.gravel, 0, x, 2, z, sbb); + if (rand.nextInt(freq + 1) > 1) { + this.setBlockState(world, Blocks.GRAVEL.getDefaultState(), x, 1, z, sbb); + + if (rand.nextInt(freq + 1) > 1) { + this.setBlockState(world, Blocks.GRAVEL.getDefaultState(), x, 2, z, sbb); } } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorShrooms.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorShrooms.java index fcfa5dc29a..d8afabb12a 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorShrooms.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorShrooms.java @@ -1,57 +1,56 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFMazeCorridorShrooms extends ComponentTFMazeCorridor { public ComponentTFMazeCorridorShrooms() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeCorridorShrooms(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeCorridorShrooms(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // mycelium & mushrooms - for (int x = 1; x < 5; x++) - { - for (int z = 0; z < 5; z++) - { - if (rand.nextInt(2) > 0) - { - this.placeBlockAtCurrentPosition(world, Blocks.mycelium, 0, x, 0, z, sbb); + for (int x = 1; x < 5; x++) { + for (int z = 0; z < 5; z++) { + if (rand.nextInt(2) > 0) { + this.setBlockState(world, Blocks.MYCELIUM.getDefaultState(), x, 0, z, sbb); } - if (rand.nextInt(2) > 0) - { - this.placeBlockAtCurrentPosition(world, rand.nextBoolean() ? Blocks.red_mushroom : Blocks.brown_mushroom, 0, x, 1, z, sbb); + if (rand.nextInt(2) > 0) { + this.setBlockState(world, rand.nextBoolean() ? Blocks.RED_MUSHROOM.getDefaultState() : Blocks.BROWN_MUSHROOM.getDefaultState(), x, 1, z, sbb); } } } - + // brackets? - Block mushType = rand.nextBoolean() ? Blocks.red_mushroom_block : Blocks.brown_mushroom_block; + boolean mushFlag = rand.nextBoolean(); + IBlockState mushType = (mushFlag ? Blocks.RED_MUSHROOM_BLOCK : Blocks.BROWN_MUSHROOM_BLOCK).getDefaultState(); int mushY = rand.nextInt(4) + 1; int mushZ = rand.nextInt(4) + 1; - this.placeBlockAtCurrentPosition(world, mushType, 15, 1, mushY - 1, mushZ, sbb); - this.fillWithMetadataBlocks(world, sbb, 1, 1, mushZ, 1, mushY, mushZ, mushType, 10, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 1, mushY, mushZ - 1, 2, mushY, mushZ + 1, mushType, 14, Blocks.air, 0, false); + this.setBlockState(world, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_STEM), 1, mushY - 1, mushZ, sbb); + this.fillWithBlocks(world, sbb, 1, 1, mushZ, 1, mushY, mushZ, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM), AIR, false); + this.fillWithBlocks(world, sbb, 1, mushY, mushZ - 1, 2, mushY, mushZ + 1, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE), AIR, false); - mushType = mushType == Blocks.brown_mushroom_block ? Blocks.red_mushroom_block : Blocks.brown_mushroom_block; + mushType = (mushFlag ? Blocks.BROWN_MUSHROOM_BLOCK : Blocks.RED_MUSHROOM_BLOCK).getDefaultState(); mushY = rand.nextInt(4) + 1; mushZ = rand.nextInt(4) + 1; - this.fillWithMetadataBlocks(world, sbb, 4, 1, mushZ, 4, mushY, mushZ, mushType, 10, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 3, mushY, mushZ - 1, 4, mushY, mushZ + 1, mushType, 14, Blocks.air, 0, false); + this.fillWithBlocks(world, sbb, 4, 1, mushZ, 4, mushY, mushZ, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM), AIR, false); + this.fillWithBlocks(world, sbb, 3, mushY, mushZ - 1, 4, mushY, mushZ + 1, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE), AIR, false); + - return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEnd.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEnd.java index d7e2598c8a..8cc8adea89 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEnd.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEnd.java @@ -1,29 +1,30 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.Random; -public class ComponentTFMazeDeadEnd extends StructureTFComponent { +public class ComponentTFMazeDeadEnd extends StructureTFComponentOld { public ComponentTFMazeDeadEnd() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEnd(int i, int x, int y, int z, int rotation) { - super(i); - this.coordBaseMode = rotation; - this.boundingBox = new StructureBoundingBox(x, y, z, x + 5, y + 5, z + 5); + public ComponentTFMazeDeadEnd(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i); + this.setCoordBaseMode(rotation); + this.boundingBox = new StructureBoundingBox(x, y, z, x + 5, y + 5, z + 5); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - this.fillWithMetadataBlocks(world, sbb, 1, 1, 0, 4, 4, 0, Blocks.fence, 0, Blocks.air, 0, false); + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + this.fillWithBlocks(world, sbb, 1, 1, 0, 4, 4, 0, Blocks.OAK_FENCE.getDefaultState(), AIR, false); this.fillWithAir(world, sbb, 2, 1, 0, 3, 3, 0); return true; } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndChest.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndChest.java index 5c6467ae21..e7300de499 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndChest.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndChest.java @@ -1,50 +1,53 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.TFTreasure; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; +import twilightforest.enums.MazestoneVariant; + +import java.util.Random; public class ComponentTFMazeDeadEndChest extends ComponentTFMazeDeadEnd { public ComponentTFMazeDeadEndChest() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndChest(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); - + public ComponentTFMazeDeadEndChest(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); + // specify a non-existant high spawn list value to stop actual monster spawns this.spawnListIndex = Integer.MAX_VALUE; } - + @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { //super.addComponentParts(world, rand, sbb); - + // dais - this.placeBlockAtCurrentPosition(world, Blocks.planks, 0, 2, 1, 4, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.planks, 0, 3, 1, 4, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(1), 2, 1, 3, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(1), 3, 1, 3, sbb); - + this.setBlockState(world, Blocks.PLANKS.getDefaultState(), 2, 1, 4, sbb); + this.setBlockState(world, Blocks.PLANKS.getDefaultState(), 3, 1, 4, sbb); + this.setBlockState(world, getStairState(Blocks.OAK_STAIRS.getDefaultState(), EnumFacing.NORTH, rotation, false), 2, 1, 3, sbb); + this.setBlockState(world, getStairState(Blocks.OAK_STAIRS.getDefaultState(), EnumFacing.NORTH, rotation, false), 3, 1, 3, sbb); + // chest - this.placeBlockAtCurrentPosition(world, Blocks.chest, 0, 2, 2, 4, sbb); + this.setBlockState(world, Blocks.CHEST.getDefaultState(), 2, 2, 4, sbb); this.placeTreasureAtCurrentPosition(world, rand, 3, 2, 4, TFTreasure.labyrinth_deadend, sbb); - + // // torches -// this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 1, 3, 4, sbb); -// this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 4, 3, 4, sbb); - +// this.setBlockState(world, Blocks.TORCH, 0, 1, 3, 4, sbb); +// this.setBlockState(world, Blocks.TORCH, 0, 4, 3, 4, sbb); + // doorway w/ bars - this.fillWithMetadataBlocks(world, sbb, 1, 1, 0, 4, 3, 1, TFBlocks.mazestone, 2, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 1, 4, 0, 4, 4, 1, TFBlocks.mazestone, 3, Blocks.air, 0, false); - this.fillWithBlocks(world, sbb, 2, 1, 0, 3, 3, 1, Blocks.iron_bars, Blocks.air, false); - + this.fillWithBlocks(world, sbb, 1, 1, 0, 4, 3, 1, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.CHISELED), AIR, false); + this.fillWithBlocks(world, sbb, 1, 4, 0, 4, 4, 1, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + this.fillWithBlocks(world, sbb, 2, 1, 0, 3, 3, 1, Blocks.IRON_BARS.getDefaultState(), AIR, false); + return true; } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountain.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountain.java index e8866299d6..511bd8693b 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountain.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountain.java @@ -1,39 +1,42 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; +import twilightforest.enums.MazestoneVariant; + +import java.util.Random; public class ComponentTFMazeDeadEndFountain extends ComponentTFMazeDeadEnd { public ComponentTFMazeDeadEndFountain() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndFountain(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeDeadEndFountain(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // normal doorway super.addComponentParts(world, rand, sbb); - + // back wall brick - this.fillWithMetadataBlocks(world, sbb, 1, 1, 4, 4, 4, 4, TFBlocks.mazestone, 1, Blocks.air, 0, false); + this.fillWithBlocks(world, sbb, 1, 1, 4, 4, 4, 4, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BRICK), AIR, false); // water - this.placeBlockAtCurrentPosition(world, Blocks.flowing_water, 0, 2, 3, 4, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.flowing_water, 0, 3, 3, 4, sbb); + this.setBlockState(world, Blocks.FLOWING_WATER.getDefaultState(), 2, 3, 4, sbb); + this.setBlockState(world, Blocks.FLOWING_WATER.getDefaultState(), 3, 3, 4, sbb); // receptacle - this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 2, 0, 3, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 3, 0, 3, sbb); - + this.setBlockState(world, AIR, 2, 0, 3, sbb); + this.setBlockState(world, AIR, 3, 0, 3, sbb); + return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountainLava.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountainLava.java index 26f35d70e0..3e15f6a839 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountainLava.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountainLava.java @@ -1,35 +1,36 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFMazeDeadEndFountainLava extends ComponentTFMazeDeadEndFountain { - + public ComponentTFMazeDeadEndFountainLava() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndFountainLava(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeDeadEndFountainLava(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // normal fountain super.addComponentParts(world, rand, sbb); - + // remove water - this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 2, 3, 4, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 3, 3, 4, sbb); - + this.setBlockState(world, AIR, 2, 3, 4, sbb); + this.setBlockState(world, AIR, 3, 3, 4, sbb); + // lava instead of water - this.placeBlockAtCurrentPosition(world, Blocks.flowing_lava, 0, 2, 3, 4, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.flowing_lava, 0, 3, 3, 4, sbb); - + this.setBlockState(world, Blocks.FLOWING_LAVA.getDefaultState(), 2, 3, 4, sbb); + this.setBlockState(world, Blocks.FLOWING_LAVA.getDefaultState(), 3, 3, 4, sbb); + return true; } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndPainting.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndPainting.java index 9f8a4da181..a82249ca6f 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndPainting.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndPainting.java @@ -1,38 +1,40 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - +import net.minecraft.block.BlockTorch; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFMazeDeadEndPainting extends ComponentTFMazeDeadEnd { public ComponentTFMazeDeadEndPainting() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndPainting(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeDeadEndPainting(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // normal doorway super.addComponentParts(world, rand, sbb); - + // torches - this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 1, 3, 3, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.torch, 0, 4, 3, 3, sbb); - + this.setBlockState(world, Blocks.TORCH.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.WEST), 1, 3, 3, sbb); + this.setBlockState(world, Blocks.TORCH.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.EAST), 4, 3, 3, sbb); + // // painting // EntityPainting painting = new EntityPainting(world, pCoords.posX, pCoords.posY, pCoords.posZ, this.get); // painting.art = getPaintingOfSize(rand, minSize); // painting.setDirection(direction); // -// world.spawnEntityInWorld(painting); - +// world.spawnEntity(painting); + return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndRoots.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndRoots.java index 2d51e5d431..f44124d977 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndRoots.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndRoots.java @@ -1,59 +1,55 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; + +import java.util.Random; public class ComponentTFMazeDeadEndRoots extends ComponentTFMazeDeadEnd { public ComponentTFMazeDeadEndRoots() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndRoots(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeDeadEndRoots(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // no door - for (int x = 1; x < 5; x++) - { - for (int z = 0; z < 5; z++) - { + for (int x = 1; x < 5; x++) { + for (int z = 0; z < 5; z++) { // as we go +z, there are more vines - if (rand.nextInt(z + 2) > 0) - { + if (rand.nextInt(z + 2) > 0) { int length = rand.nextInt(6); //place dirt above ceiling - this.placeBlockAtCurrentPosition(world, Blocks.dirt, 0, x, 6, z, sbb); - + this.setBlockState(world, Blocks.DIRT.getDefaultState(), x, 6, z, sbb); + // roots - for (int y = 6 - length; y < 6; y++) - { - this.placeBlockAtCurrentPosition(world, TFBlocks.plant, BlockTFPlant.META_ROOT_STRAND, x, y, z, sbb); + for (int y = 6 - length; y < 6; y++) { + this.setBlockState(world, TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.ROOT_STRAND), x, y, z, sbb); } - + // occasional gravel - if (rand.nextInt(z + 1) > 1) - { - this.placeBlockAtCurrentPosition(world, Blocks.gravel, 0, x, 1, z, sbb); - - if (rand.nextInt(z + 1) > 1) - { - this.placeBlockAtCurrentPosition(world, Blocks.gravel, 0, x, 2, z, sbb); + if (rand.nextInt(z + 1) > 1) { + this.setBlockState(world, Blocks.GRAVEL.getDefaultState(), x, 1, z, sbb); + + if (rand.nextInt(z + 1) > 1) { + this.setBlockState(world, Blocks.GRAVEL.getDefaultState(), x, 2, z, sbb); } } } } } - + return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndShrooms.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndShrooms.java index f3beedb106..76385ecc9b 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndShrooms.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndShrooms.java @@ -1,63 +1,62 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFMazeDeadEndShrooms extends ComponentTFMazeDeadEndRoots { public ComponentTFMazeDeadEndShrooms() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndShrooms(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeDeadEndShrooms(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // no door - + // mycelium & mushrooms going back - for (int x = 1; x < 5; x++) - { - for (int z = 0; z < 5; z++) - { - if (rand.nextInt(z + 2) > 0) - { - this.placeBlockAtCurrentPosition(world, Blocks.mycelium, 0, x, 0, z, sbb); + for (int x = 1; x < 5; x++) { + for (int z = 0; z < 5; z++) { + if (rand.nextInt(z + 2) > 0) { + this.setBlockState(world, Blocks.MYCELIUM.getDefaultState(), x, 0, z, sbb); } - if (rand.nextInt(z + 2) > 0) - { - this.placeBlockAtCurrentPosition(world, rand.nextBoolean() ? Blocks.red_mushroom : Blocks.brown_mushroom, 0, x, 1, z, sbb); + if (rand.nextInt(z + 2) > 0) { + this.setBlockState(world, rand.nextBoolean() ? Blocks.RED_MUSHROOM.getDefaultState() : Blocks.BROWN_MUSHROOM.getDefaultState(), x, 1, z, sbb); } } } - + // brackets? - Block mushType = rand.nextBoolean() ? Blocks.red_mushroom_block : Blocks.brown_mushroom_block; + boolean mushFlag = rand.nextBoolean(); + IBlockState mushType = (mushFlag ? Blocks.RED_MUSHROOM_BLOCK : Blocks.BROWN_MUSHROOM_BLOCK).getDefaultState(); int mushY = rand.nextInt(4) + 1; int mushZ = rand.nextInt(3) + 1; - this.placeBlockAtCurrentPosition(world, mushType, 15, 1, mushY - 1, mushZ, sbb); - this.fillWithMetadataBlocks(world, sbb, 1, 1, mushZ, 1, mushY, mushZ, mushType, 10, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 1, mushY, mushZ - 1, 2, mushY, mushZ + 1, mushType, 14, Blocks.air, 0, false); + this.setBlockState(world, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_STEM), 1, mushY - 1, mushZ, sbb); + this.fillWithBlocks(world, sbb, 1, 1, mushZ, 1, mushY, mushZ, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM), AIR, false); + this.fillWithBlocks(world, sbb, 1, mushY, mushZ - 1, 2, mushY, mushZ + 1, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE), AIR, false); - mushType = mushType == Blocks.brown_mushroom_block ? Blocks.red_mushroom_block : Blocks.brown_mushroom_block; + mushType = (mushFlag ? Blocks.BROWN_MUSHROOM_BLOCK : Blocks.RED_MUSHROOM_BLOCK).getDefaultState(); mushY = rand.nextInt(4) + 1; mushZ = rand.nextInt(3) + 1; - this.fillWithMetadataBlocks(world, sbb, 4, 1, mushZ, 4, mushY, mushZ, mushType, 10, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 3, mushY, mushZ - 1, 4, mushY, mushZ + 1, mushType, 14, Blocks.air, 0, false); - - mushType = rand.nextBoolean() ? Blocks.red_mushroom_block : Blocks.brown_mushroom_block; + this.fillWithBlocks(world, sbb, 4, 1, mushZ, 4, mushY, mushZ, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM), AIR, false); + this.fillWithBlocks(world, sbb, 3, mushY, mushZ - 1, 4, mushY, mushZ + 1, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE), AIR, false); + + mushType = (rand.nextBoolean() ? Blocks.RED_MUSHROOM_BLOCK : Blocks.BROWN_MUSHROOM_BLOCK).getDefaultState(); mushY = rand.nextInt(4) + 1; int mushX = rand.nextInt(3) + 2; - this.fillWithMetadataBlocks(world, sbb, mushX, 1, 4, mushX, mushY, 4, mushType, 10, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, mushX - 1, mushY, 3, mushX + 1, mushY, 4, mushType, 14, Blocks.air, 0, false); - + this.fillWithBlocks(world, sbb, mushX, 1, 4, mushX, mushY, 4, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM), AIR, false); + this.fillWithBlocks(world, sbb, mushX - 1, mushY, 3, mushX + 1, mushY, 4, mushType.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE), AIR, false); + return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTorches.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTorches.java index 332f084168..de47a7191b 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTorches.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTorches.java @@ -1,33 +1,35 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - +import net.minecraft.block.BlockTorch; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFMazeDeadEndTorches extends ComponentTFMazeDeadEnd { public ComponentTFMazeDeadEndTorches() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndTorches(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeDeadEndTorches(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // normal doorway super.addComponentParts(world, rand, sbb); - + // torches! - this.fillWithMetadataBlocks(world, sbb, 2, 1, 4, 3, 4, 4, Blocks.torch, 0, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 1, 1, 1, 1, 4, 4, Blocks.torch, 0, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 4, 1, 1, 4, 4, 4, Blocks.torch, 0, Blocks.air, 0, false); + this.fillWithBlocks(world, sbb, 2, 1, 4, 3, 4, 4, Blocks.TORCH.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.SOUTH), AIR, false); + this.fillWithBlocks(world, sbb, 1, 1, 1, 1, 4, 4, Blocks.TORCH.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.WEST), AIR, false); + this.fillWithBlocks(world, sbb, 4, 1, 1, 4, 4, 4, Blocks.TORCH.getDefaultState().withProperty(BlockTorch.FACING, EnumFacing.EAST), AIR, false); + - return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTrappedChest.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTrappedChest.java index 337f79d870..d0991a9116 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTrappedChest.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTrappedChest.java @@ -1,55 +1,62 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; +import twilightforest.block.TFBlocks; +import twilightforest.enums.MazestoneVariant; +import twilightforest.loot.TFTreasure; + +import java.util.Random; -public class ComponentTFMazeDeadEndTrappedChest extends ComponentTFMazeDeadEndChest { +public class ComponentTFMazeDeadEndTrappedChest extends ComponentTFMazeDeadEnd { public ComponentTFMazeDeadEndTrappedChest() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeDeadEndTrappedChest(int i, int x, int y, int z, int rotation) { - super(i, x, y, z, rotation); + public ComponentTFMazeDeadEndTrappedChest(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); + + // specify a non-existant high spawn list value to stop actual monster spawns + this.spawnListIndex = Integer.MAX_VALUE; } @Override - public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - // normal chest room - super.addComponentParts(world, rand, sbb); - - // add tripwire hooks - this.placeBlockAtCurrentPosition(world, Blocks.tripwire_hook, getHookMeta(3), 1, 1, 2, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.tripwire_hook, getHookMeta(1), 4, 1, 2, sbb); - - // add string - this.placeBlockAtCurrentPosition(world, Blocks.tripwire, 0, 2, 1, 2, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.tripwire, 0, 3, 1, 2, sbb); - + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + //super.addComponentParts(world, rand, sbb); + + // dais + this.setBlockState(world, Blocks.PLANKS.getDefaultState(), 2, 1, 4, sbb); + this.setBlockState(world, Blocks.PLANKS.getDefaultState(), 3, 1, 4, sbb); + this.setBlockState(world, getStairState(Blocks.OAK_STAIRS.getDefaultState(), EnumFacing.NORTH, rotation, false), 2, 1, 3, sbb); + this.setBlockState(world, getStairState(Blocks.OAK_STAIRS.getDefaultState(), EnumFacing.NORTH, rotation, false), 3, 1, 3, sbb); + + // chest + this.setBlockState(world, Blocks.TRAPPED_CHEST.getDefaultState(), 2, 2, 4, sbb); + this.placeTreasureAtCurrentPosition(world, rand, 3, 2, 4, TFTreasure.labyrinth_deadend, true, sbb); + +// // torches +// this.setBlockState(world, Blocks.TORCH, 0, 1, 3, 4, sbb); +// this.setBlockState(world, Blocks.TORCH, 0, 4, 3, 4, sbb); + + // doorway w/ bars + this.fillWithBlocks(world, sbb, 1, 1, 0, 4, 3, 1, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.CHISELED), AIR, false); + this.fillWithBlocks(world, sbb, 1, 4, 0, 4, 4, 1, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + this.fillWithBlocks(world, sbb, 2, 1, 0, 3, 3, 1, Blocks.IRON_BARS.getDefaultState(), AIR, false); + // TNT! - this.placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 0, 0, 2, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 0, -1, 2, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.air, 0, 1, -1, 2, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 2, 0, 4, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 3, 0, 4, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 2, 0, 3, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 3, 0, 3, sbb); + IBlockState tnt = Blocks.TNT.getDefaultState(); + this.setBlockState(world, tnt, 2, 0, 3, sbb); + this.setBlockState(world, tnt, 3, 0, 3, sbb); + this.setBlockState(world, tnt, 2, 0, 4, sbb); + this.setBlockState(world, tnt, 3, 0, 4, sbb); return true; } - - /** - * Gets the metadata necessary to make stairs facing the proper direction. - * - * @param dir - * @return - */ - protected int getHookMeta(int dir) - { - return(this.getCoordBaseMode() + dir) % 4; - } + } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTripwireChest.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTripwireChest.java new file mode 100644 index 0000000000..77ac2dda21 --- /dev/null +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTripwireChest.java @@ -0,0 +1,45 @@ +package twilightforest.structures.minotaurmaze; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; + +public class ComponentTFMazeDeadEndTripwireChest extends ComponentTFMazeDeadEndChest { + + public ComponentTFMazeDeadEndTripwireChest() { + super(); + } + + public ComponentTFMazeDeadEndTripwireChest(TFFeature feature, int i, int x, int y, int z, EnumFacing rotation) { + super(feature, i, x, y, z, rotation); + } + + @Override + public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + // normal chest room + super.addComponentParts(world, rand, sbb); + + // add tripwire + this.placeTripwire(world, 1, 1, 2, 3, EnumFacing.EAST, sbb); + + // TNT! + IBlockState tnt = Blocks.TNT.getDefaultState(); + this.setBlockState(world, tnt, 0, 0, 2, sbb); + + // Air blocks are required underneath to maximize TNT destruction of chest + this.setBlockState(world, AIR, 0, -1, 2, sbb); + this.setBlockState(world, AIR, 1, -1, 2, sbb); + + this.setBlockState(world, tnt, 2, 0, 4, sbb); + this.setBlockState(world, tnt, 3, 0, 4, sbb); + this.setBlockState(world, tnt, 2, 0, 3, sbb); + this.setBlockState(world, tnt, 3, 0, 3, sbb); + + return true; + } +} diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeEntranceShaft.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeEntranceShaft.java index e14d3b6db8..1f0f946130 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeEntranceShaft.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeEntranceShaft.java @@ -1,101 +1,89 @@ package twilightforest.structures.minotaurmaze; -import java.util.List; -import java.util.Random; - -import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; +import twilightforest.enums.MazestoneVariant; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.world.TFWorld; -public class ComponentTFMazeEntranceShaft extends StructureTFComponent { +import java.util.List; +import java.util.Random; + +public class ComponentTFMazeEntranceShaft extends StructureTFComponentOld { public ComponentTFMazeEntranceShaft() { super(); - // TODO Auto-generated constructor stub } - private int averageGroundLevel = -1; - public ComponentTFMazeEntranceShaft(int i, Random rand, int x, int y, int z) { - super(i); - this.coordBaseMode = rand.nextInt(4); + public ComponentTFMazeEntranceShaft(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.HORIZONTALS[rand.nextInt(4)]); - this.boundingBox = new StructureBoundingBox(x, y, z, x + 6 - 1, y + 14, z + 6 - 1); + this.boundingBox = new StructureBoundingBox(x, y, z, x + 6 - 1, y + 14, z + 6 - 1); } /** * Initiates construction of the Structure Component picked, at the current Location of StructGen */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { + public void buildComponent(StructureComponent structurecomponent, List list, Random random) { ; } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.averageGroundLevel < 0) - { - this.averageGroundLevel = this.getAverageGroundLevel(world, sbb); - - if (this.averageGroundLevel < 0) - { - return true; - } - - this.boundingBox.offset(0, this.averageGroundLevel - this.boundingBox.maxY + 15 - 1, 0); - } - - - this.fillWithMetadataBlocks(world, sbb, 0, 0 - 10, 0, 5, 0 + 30, 5, TFBlocks.mazestone, 1, Blocks.air, 0, true); - this.fillWithAir(world, sbb, 1, 0 - 10, 1, 4, 0 + 30, 4); - - //System.out.println("Drawing entrance"); - - int var8 = this.getXWithOffset(0, 0); - int var9 = this.getYWithOffset(0); - int var10 = this.getZWithOffset(0, 0); - - //System.out.println("Drawing entrance at " + var8 + ", " + var9 + ", " + var10); - - + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(world, sbb); + + if (this.averageGroundLevel < 0) { + return true; + } + + this.boundingBox.maxY = this.averageGroundLevel; + this.boundingBox.minY = TFWorld.SEALEVEL - 10; + } + + + this.fillWithBlocks(world, sbb, 0, 0, 0, 5, this.boundingBox.getYSize(), 5, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BRICK), AIR, true); + this.fillWithAir(world, sbb, 1, 0, 1, 4, this.boundingBox.getYSize(), 4); + return true; } - - - /** - * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the - * levels in the BB's horizontal rectangle). - */ - protected int getAverageGroundLevel(World par1World, StructureBoundingBox par2StructureBoundingBox) - { - int var3 = 0; - int var4 = 0; - - for (int var5 = this.boundingBox.minZ; var5 <= this.boundingBox.maxZ; ++var5) - { - for (int var6 = this.boundingBox.minX; var6 <= this.boundingBox.maxX; ++var6) - { - if (par2StructureBoundingBox.isVecInside(var6, 64, var5)) - { - var3 += Math.max(par1World.getTopSolidOrLiquidBlock(var6, var5), par1World.provider.getAverageGroundLevel()); - ++var4; - } - } - } - - if (var4 == 0) - { - return -1; - } - else - { - return var3 / var4; - } - } + + /** + * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the + * levels in the BB's horizontal rectangle). + */ + @Override + protected int getAverageGroundLevel(World world, StructureBoundingBox boundingBox) { + int yTotal = 0; + int count = 0; + + for (int z = this.boundingBox.minZ; z <= this.boundingBox.maxZ; ++z) { + for (int x = this.boundingBox.minX; x <= this.boundingBox.maxX; ++x) { + BlockPos pos = new BlockPos(x, 64, z); + if (boundingBox.isVecInside(pos)) { + final BlockPos topBlock = world.getTopSolidOrLiquidBlock(pos); + yTotal += Math.max(topBlock.getY(), world.provider.getAverageGroundLevel()); + ++count; + } + } + } + + if (count == 0) { + return -1; + } else { + return yTotal / count; + } + } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMound.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMound.java index 2c1db9c4a1..05e24c8f28 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMound.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMound.java @@ -1,19 +1,21 @@ package twilightforest.structures.minotaurmaze; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; -public class ComponentTFMazeMound extends StructureTFComponent { +public class ComponentTFMazeMound extends StructureTFComponentOld { public ComponentTFMazeMound() { super(); - // TODO Auto-generated constructor stub } @@ -22,112 +24,100 @@ public ComponentTFMazeMound() { private ComponentTFMazeUpperEntrance mazeAbove; - public ComponentTFMazeMound(int i, Random rand, int x, int y, int z) { - super(i); - this.coordBaseMode = rand.nextInt(4); + public ComponentTFMazeMound(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.HORIZONTALS[rand.nextInt(4)]); - this.boundingBox = new StructureBoundingBox(x, y, z, x + DIAMETER, y + 8, z + DIAMETER); + this.boundingBox = new StructureBoundingBox(x, y, z, x + DIAMETER, y + 8, z + DIAMETER); } /** * Initiates construction of the Structure Component picked, at the current Location of StructGen */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { + public void buildComponent(StructureComponent structurecomponent, List list, Random random) { super.buildComponent(structurecomponent, list, random); - + // add aboveground maze entrance building - mazeAbove = new ComponentTFMazeUpperEntrance(3, random, boundingBox.minX + 10, boundingBox.minY + 0, boundingBox.minZ + 10); + mazeAbove = new ComponentTFMazeUpperEntrance(getFeatureType(), 3, random, boundingBox.minX + 10, boundingBox.minY + 0, boundingBox.minZ + 10); list.add(mazeAbove); - mazeAbove.buildComponent(this, list, random); + mazeAbove.buildComponent(this, list, random); } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - - if (this.averageGroundLevel < 0) - { - this.averageGroundLevel = this.getAverageGroundLevel(world, sbb); - - if (this.averageGroundLevel < 0) - { - return true; - } - - int offset = this.averageGroundLevel - this.boundingBox.maxY + 8 - 1; - - this.boundingBox.offset(0, offset, 0); - - if (this.mazeAbove != null) - { - mazeAbove.getBoundingBox().offset(0, offset, 0); - } - } - - - //this.fillWithBlocks(world, sbb, 0, 0, 0, 25, 8, 25, Blocks.dirt, 0, false); - - for (int x = 0; x < DIAMETER; x++) - { - for (int z = 0; z < DIAMETER; z++) - { - int cx = x - DIAMETER / 2; - int cz = z - DIAMETER / 2; - - int dist = (int) Math.sqrt(cx * cx + cz * cz); - int hheight = (int) (Math.cos((double)dist / DIAMETER * Math.PI) * (DIAMETER / 3)); - - // leave a hole in the middle - if (!(cx <= 2 && cx >= -1 && cz <= 2 && cz >= -1) && ((!(cx <= 2 && cx >= -1) && !(cz <= 2 && cz >= -1)) || hheight > 6)) - { - this.placeBlockAtCurrentPosition(world, Blocks.grass, 0, x, hheight, z, sbb); - - // only fill to the bottom when we're not in the entrances - if (!(cx <= 2 && cx >= -1) && !(cz <= 2 && cz >= -1)) - { - this.func_151554_b(world, Blocks.dirt, 0, x, hheight - 1, z, sbb); - } - else if (hheight > 6) - { - this.fillWithBlocks(world, sbb, x, 6, z, x, hheight - 1, z, Blocks.dirt, Blocks.air, false); - } - } - } - } - + + if (this.averageGroundLevel < 0) { + this.averageGroundLevel = this.getAverageGroundLevel(world, sbb); + + if (this.averageGroundLevel < 0) { + return true; + } + + int offset = this.averageGroundLevel - this.boundingBox.maxY + 8 - 1; + + this.boundingBox.offset(0, offset, 0); + + if (this.mazeAbove != null) { + mazeAbove.getBoundingBox().offset(0, offset, 0); + } + } + + + //this.fillWithBlocks(world, sbb, 0, 0, 0, 25, 8, 25, Blocks.DIRT, 0, false); + + for (int x = 0; x < DIAMETER; x++) { + for (int z = 0; z < DIAMETER; z++) { + int cx = x - DIAMETER / 2; + int cz = z - DIAMETER / 2; + + int dist = (int) Math.sqrt(cx * cx + cz * cz); + int hheight = (int) (Math.cos((double) dist / DIAMETER * Math.PI) * (DIAMETER / 3)); + + // leave a hole in the middle + if (!(cx <= 2 && cx >= -1 && cz <= 2 && cz >= -1) && ((!(cx <= 2 && cx >= -1) && !(cz <= 2 && cz >= -1)) || hheight > 6)) { + this.setBlockState(world, Blocks.GRASS.getDefaultState(), x, hheight, z, sbb); + + // only fill to the bottom when we're not in the entrances + if (!(cx <= 2 && cx >= -1) && !(cz <= 2 && cz >= -1)) { + this.setBlockState(world, Blocks.DIRT.getDefaultState(), x, hheight - 1, z, sbb); + } else if (hheight > 6) { + this.fillWithBlocks(world, sbb, x, 6, z, x, hheight - 1, z, Blocks.DIRT.getDefaultState(), AIR, false); + } + } + } + } + return true; } - /** - * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the - * levels in the BB's horizontal rectangle). - */ - protected int getAverageGroundLevel(World par1World, StructureBoundingBox par2StructureBoundingBox) - { - int totalHeight = 0; - int totalMeasures = 0; - - for (int var5 = this.boundingBox.minZ; var5 <= this.boundingBox.maxZ; ++var5) - { - for (int var6 = this.boundingBox.minX; var6 <= this.boundingBox.maxX; ++var6) - { - if (par2StructureBoundingBox.isVecInside(var6, 64, var5)) - { - totalHeight += Math.max(par1World.getTopSolidOrLiquidBlock(var6, var5), par1World.provider.getAverageGroundLevel()); - ++totalMeasures; - } - } - } - - if (totalMeasures == 0) - { - return -1; - } - else - { - return totalHeight / totalMeasures; - } - } + /** + * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the + * levels in the BB's horizontal rectangle). + */ + @Override + protected int getAverageGroundLevel(World world, StructureBoundingBox boundingBox) { + int totalHeight = 0; + int totalMeasures = 0; + + for (int z = this.boundingBox.minZ; z <= this.boundingBox.maxZ; ++z) { + for (int x = this.boundingBox.minX; x <= this.boundingBox.maxX; ++x) { + BlockPos pos = new BlockPos(x, 64, z); + + if (boundingBox.isVecInside(pos)) { + final BlockPos topPos = world.getTopSolidOrLiquidBlock(pos); + totalHeight += Math.max(topPos.getY(), world.provider.getAverageGroundLevel()); + ++totalMeasures; + } + } + } + + if (totalMeasures == 0) { + return -1; + } else { + return totalHeight / totalMeasures; + } + } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMushRoom.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMushRoom.java index cdd98d95f1..b893ec3e95 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMushRoom.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeMushRoom.java @@ -1,102 +1,103 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; + +import java.util.Random; public class ComponentTFMazeMushRoom extends ComponentTFMazeRoom { - + public ComponentTFMazeMushRoom() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeMushRoom(int i, Random rand, int x, int y, int z) { - super(i, rand, x, y, z); - - this.coordBaseMode = 0; // let's just make this easy on us? + public ComponentTFMazeMushRoom(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i, rand, x, y, z); + + this.setCoordBaseMode(EnumFacing.SOUTH); // let's just make this easy on us? } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - - for (int x = 1; x < 14; x++) - { - for (int z = 1; z < 14; z++) - { + + for (int x = 1; x < 14; x++) { + for (int z = 1; z < 14; z++) { // calculate distance from middle int dist = (int) Math.round(7 / Math.sqrt((7.5 - x) * (7.5 - x) + (7.5 - z) * (7.5 - z))); // make part of the floor mycelium - if (rand.nextInt(dist + 1) > 0) - { - this.placeBlockAtCurrentPosition(world, Blocks.mycelium, 0, x, 0, z, sbb); + if (rand.nextInt(dist + 1) > 0) { + this.setBlockState(world, Blocks.MYCELIUM.getDefaultState(), x, 0, z, sbb); } // add small mushrooms all over - if (rand.nextInt(dist) > 0) - { - this.placeBlockAtCurrentPosition(world, rand.nextBoolean() ? Blocks.red_mushroom : Blocks.brown_mushroom, 0, x, 1, z, sbb); + if (rand.nextInt(dist) > 0) { + this.setBlockState(world, (rand.nextBoolean() ? Blocks.RED_MUSHROOM : Blocks.BROWN_MUSHROOM).getDefaultState(), x, 1, z, sbb); } } } - + + final IBlockState redMushroomBlock = Blocks.RED_MUSHROOM_BLOCK.getDefaultState(); + final IBlockState brownMushroomBlock = Blocks.BROWN_MUSHROOM_BLOCK.getDefaultState(); + // add our medium mushrooms - makeMediumMushroom(world, sbb, 5, 2, 9, Blocks.red_mushroom_block); - makeMediumMushroom(world, sbb, 5, 3, 9, Blocks.red_mushroom_block); - makeMediumMushroom(world, sbb, 9, 2, 5, Blocks.red_mushroom_block); - makeMediumMushroom(world, sbb, 6, 3, 4, Blocks.brown_mushroom_block); - makeMediumMushroom(world, sbb, 10, 1, 9, Blocks.brown_mushroom_block); - + + makeMediumMushroom(world, sbb, 5, 2, 9, redMushroomBlock); + makeMediumMushroom(world, sbb, 5, 3, 9, redMushroomBlock); + makeMediumMushroom(world, sbb, 9, 2, 5, redMushroomBlock); + makeMediumMushroom(world, sbb, 6, 3, 4, brownMushroomBlock); + makeMediumMushroom(world, sbb, 10, 1, 9, brownMushroomBlock); + // bracket mushrooms on the wall - this.placeBlockAtCurrentPosition(world, Blocks.red_mushroom_block, 15, 1, 2, 1, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.red_mushroom_block, 5, 1, 3, 1, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.red_mushroom_block, 9, 2, 3, 1, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.red_mushroom_block, 9, 1, 3, 2, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_STEM), 1, 2, 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER), 1, 3, 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_WEST), 2, 3, 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_WEST), 1, 3, 2, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 15, 14, 3, 1, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 5, 14, 4, 1, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 7, 13, 4, 1, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 7, 14, 4, 2, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_STEM), 14, 3, 1, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER), 14, 4, 1, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_EAST), 13, 4, 1, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_EAST), 14, 4, 2, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 15, 1, 1, 14, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 5, 1, 2, 14, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 3, 2, 2, 14, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 3, 1, 2, 13, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_STEM), 1, 1, 14, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER), 1, 2, 14, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_WEST), 2, 2, 14, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_WEST), 1, 2, 13, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 5, 14, 1, 14, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 1, 13, 1, 14, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.brown_mushroom_block, 1, 14, 1, 13, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER), 14, 1, 14, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_EAST), 13, 1, 14, sbb); + this.setBlockState(world, brownMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_EAST), 14, 1, 13, sbb); // mushroom ceiling spots? - + return true; } /** * Make a 3x3 square mushroom centered on the specified coords. */ - private void makeMediumMushroom(World world, StructureBoundingBox sbb, int mx, int my, int mz, Block redMushroomBlock) { + private void makeMediumMushroom(World world, StructureBoundingBox sbb, int mx, int my, int mz, IBlockState redMushroomBlock) { // cap - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 5, mx + 0, my, mz + 0, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 6, mx + 1, my, mz + 0, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 9, mx + 1, my, mz + 1, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 8, mx + 0, my, mz + 1, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 7, mx - 1, my, mz + 1, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 4, mx - 1, my, mz + 0, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 1, mx - 1, my, mz - 1, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 2, mx + 0, my, mz - 1, sbb); - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 3, mx + 1, my, mz - 1, sbb); - + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER), mx + 0, my, mz + 0, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.WEST), mx + 1, my, mz + 0, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_WEST), mx + 1, my, mz + 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH), mx + 0, my, mz + 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_EAST), mx - 1, my, mz + 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.EAST), mx - 1, my, mz + 0, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_EAST), mx - 1, my, mz - 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH), mx + 0, my, mz - 1, sbb); + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_WEST), mx + 1, my, mz - 1, sbb); + // stem - for (int y = 1; y < my; y++) - { - this.placeBlockAtCurrentPosition(world, redMushroomBlock, 10, mx + 0, y, mz + 0, sbb); + for (int y = 1; y < my; y++) { + this.setBlockState(world, redMushroomBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM), mx + 0, y, mz + 0, sbb); } } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoom.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoom.java index 89d7b84d3c..c49228050d 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoom.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoom.java @@ -1,64 +1,64 @@ package twilightforest.structures.minotaurmaze; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; +import twilightforest.enums.MazestoneVariant; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; -public class ComponentTFMazeRoom extends StructureTFComponent { +public class ComponentTFMazeRoom extends StructureTFComponentOld { public ComponentTFMazeRoom() { super(); } - public ComponentTFMazeRoom(int i, Random rand, int x, int y, int z) { - super(i); - this.coordBaseMode = rand.nextInt(4); + public ComponentTFMazeRoom(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.HORIZONTALS[rand.nextInt(4)]); - this.boundingBox = new StructureBoundingBox(x, y, z, x + 15, y + 4, z + 15); + this.boundingBox = new StructureBoundingBox(x, y, z, x + 15, y + 4, z + 15); } /** * Initiates construction of the Structure Component picked, at the current Location of StructGen */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { + public void buildComponent(StructureComponent structurecomponent, List list, Random random) { ; } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // floor border - fillWithMetadataBlocks(world, sbb, 1, 0, 1, 14, 0, 14, TFBlocks.mazestone, 7, Blocks.air, 0, true); - fillWithMetadataBlocks(world, sbb, 2, 0, 2, 13, 0, 13, TFBlocks.mazestone, 6, Blocks.air, 0, true); + fillWithBlocks(world, sbb, 1, 0, 1, 14, 0, 14, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BORDER), AIR, true); + fillWithBlocks(world, sbb, 2, 0, 2, 13, 0, 13, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.MOSAIC), AIR, true); // doorways - if (this.getBlockAtCurrentPosition(world, 7, 1, 0, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 6, 1, 0, 9, 4, 0, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 7, 1, 0, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 6, 1, 0, 9, 4, 0, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 7, 1, 0, 8, 3, 0); } - if (this.getBlockAtCurrentPosition(world, 7, 1, 15, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 6, 1, 15, 9, 4, 15, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 7, 1, 15, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 6, 1, 15, 9, 4, 15, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 7, 1, 15, 8, 3, 15); } - if (this.getBlockAtCurrentPosition(world, 0, 1, 7, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 0, 1, 6, 0, 4, 9, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 0, 1, 7, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 0, 1, 6, 0, 4, 9, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 0, 1, 7, 0, 3, 8); } - if (this.getBlockAtCurrentPosition(world, 15, 1, 7, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 15, 1, 6, 15, 4, 9, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 15, 1, 7, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 15, 1, 6, 15, 4, 9, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 15, 1, 7, 15, 3, 8); } return true; diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomBoss.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomBoss.java index e117aa1e45..fe1182b414 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomBoss.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomBoss.java @@ -1,58 +1,54 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.TFTreasure; -import twilightforest.entity.boss.EntityTFMinoshroom; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFBossSpawner; +import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; + +import java.util.Random; public class ComponentTFMazeRoomBoss extends ComponentTFMazeRoom { public ComponentTFMazeRoomBoss() { super(); - // TODO Auto-generated constructor stub } - private boolean taurPlaced = false; - - - public ComponentTFMazeRoomBoss(int i, Random rand, int x, int y, int z) { - super(i, rand, x, y, z); + public ComponentTFMazeRoomBoss(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i, rand, x, y, z); } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // doorways - if (this.getBlockAtCurrentPosition(world, 7, 1, 0, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 6, 1, 0, 9, 4, 0, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 7, 1, 0, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 6, 1, 0, 9, 4, 0, Blocks.OAK_FENCE.getDefaultState(), AIR, false); } - if (this.getBlockAtCurrentPosition(world, 7, 1, 15, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 6, 1, 15, 9, 4, 15, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 7, 1, 15, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 6, 1, 15, 9, 4, 15, Blocks.OAK_FENCE.getDefaultState(), AIR, false); } - if (this.getBlockAtCurrentPosition(world, 0, 1, 7, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 0, 1, 6, 0, 4, 9, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 0, 1, 7, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 0, 1, 6, 0, 4, 9, Blocks.OAK_FENCE.getDefaultState(), AIR, false); } - if (this.getBlockAtCurrentPosition(world, 15, 1, 7, sbb) == Blocks.air) - { - fillWithBlocks(world, sbb, 15, 1, 6, 15, 4, 9, Blocks.fence, Blocks.air, false); + if (this.getBlockStateFromPos(world, 15, 1, 7, sbb).getBlock() == Blocks.AIR) { + fillWithBlocks(world, sbb, 15, 1, 6, 15, 4, 9, Blocks.OAK_FENCE.getDefaultState(), AIR, false); } // mycelium / small mushrooms on floor - for (int x = 1; x < 14; x++) - { - for (int z = 1; z < 14; z++) - { + for (int x = 1; x < 14; x++) { + for (int z = 1; z < 14; z++) { // calculate distance from middle int dist = (int) Math.round(7 / Math.sqrt((7.5 - x) * (7.5 - x) + (7.5 - z) * (7.5 - z))); boolean mycelium = rand.nextInt(dist + 1) > 0; @@ -60,66 +56,52 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox boolean mushRed = rand.nextBoolean(); // make part of the floor mycelium - if (mycelium) - { - this.placeBlockAtCurrentPosition(world, Blocks.mycelium, 0, x, 0, z, sbb); + if (mycelium) { + this.setBlockState(world, Blocks.MYCELIUM.getDefaultState(), x, 0, z, sbb); } // add small mushrooms all over - if (mushroom) - { - this.placeBlockAtCurrentPosition(world, mushRed ? Blocks.red_mushroom : Blocks.brown_mushroom, 0, x, 1, z, sbb); + if (mushroom) { + this.setBlockState(world, (mushRed ? Blocks.RED_MUSHROOM : Blocks.BROWN_MUSHROOM).getDefaultState(), x, 1, z, sbb); } } } - + // mushroom chest shelves in corner - fillWithMetadataBlocks(world, sbb, 1, 1, 1, 3, 1, 3, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 1, 2, 1, 1, 3, 4, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 2, 2, 1, 4, 3, 1, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 1, 4, 1, 3, 4, 3, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); + final IBlockState redMushroom = Blocks.RED_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE); + final IBlockState brownMushroom = Blocks.BROWN_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE); + + fillWithBlocks(world, sbb, 1, 1, 1, 3, 1, 3, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 1, 2, 1, 1, 3, 4, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 2, 2, 1, 4, 3, 1, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 1, 4, 1, 3, 4, 3, redMushroom, AIR, false); placeTreasureAtCurrentPosition(world, rand, 3, 2, 3, TFTreasure.labyrinth_room, sbb); - fillWithMetadataBlocks(world, sbb, 12, 1, 12, 14, 1, 14, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 14, 2, 11, 14, 3, 14, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 11, 2, 14, 14, 3, 14, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 12, 4, 12, 14, 4, 14, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); + fillWithBlocks(world, sbb, 12, 1, 12, 14, 1, 14, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 14, 2, 11, 14, 3, 14, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 11, 2, 14, 14, 3, 14, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 12, 4, 12, 14, 4, 14, redMushroom, AIR, false); placeTreasureAtCurrentPosition(world, rand, 12, 2, 12, TFTreasure.labyrinth_room, sbb); - fillWithMetadataBlocks(world, sbb, 1, 1, 12, 3, 1, 14, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 1, 2, 11, 1, 3, 14, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 2, 2, 14, 4, 3, 14, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 1, 4, 12, 3, 4, 14, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); + fillWithBlocks(world, sbb, 1, 1, 12, 3, 1, 14, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 1, 2, 11, 1, 3, 14, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 2, 2, 14, 4, 3, 14, redMushroom, AIR, false); + fillWithBlocks(world, sbb, 1, 4, 12, 3, 4, 14, redMushroom, AIR, false); placeTreasureAtCurrentPosition(world, rand, 3, 2, 12, TFTreasure.labyrinth_room, sbb); - fillWithMetadataBlocks(world, sbb, 12, 1, 1, 14, 1, 3, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 11, 2, 1, 14, 3, 1, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 14, 2, 2, 14, 3, 4, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 12, 4, 1, 14, 4, 3, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); + fillWithBlocks(world, sbb, 12, 1, 1, 14, 1, 3, brownMushroom, AIR, false); + fillWithBlocks(world, sbb, 11, 2, 1, 14, 3, 1, brownMushroom, AIR, false); + fillWithBlocks(world, sbb, 14, 2, 2, 14, 3, 4, brownMushroom, AIR, false); + fillWithBlocks(world, sbb, 12, 4, 1, 14, 4, 3, brownMushroom, AIR, false); placeTreasureAtCurrentPosition(world, rand, 12, 2, 3, TFTreasure.labyrinth_room, sbb); // a few more ceilingshrooms - fillWithMetadataBlocks(world, sbb, 5, 4, 5, 7, 5, 7, Blocks.brown_mushroom_block, 14, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 8, 4, 8, 10, 5, 10, Blocks.red_mushroom_block, 14, Blocks.air, 0, false); + fillWithBlocks(world, sbb, 5, 4, 5, 7, 5, 7, brownMushroom, AIR, false); + fillWithBlocks(world, sbb, 8, 4, 8, 10, 5, 10, redMushroom, AIR, false); - // the moo-cen-mino-shrom-taur! - if (!taurPlaced) { - int bx = this.getXWithOffset(7, 7); - int by = this.getYWithOffset(1); - int bz = this.getZWithOffset(7, 7); - - if (sbb.isVecInside(bx, by, bz)) { - taurPlaced = true; - - EntityTFMinoshroom taur = new EntityTFMinoshroom(world); - taur.setPosition(bx, by, bz); - taur.setHomeArea(bx, by, bz, 7); - - world.spawnEntityInWorld(taur); - } - } - - + final IBlockState taurSpawner = TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.MINOSHROOM); + setBlockStateRotated(world, taurSpawner, 7, 1, 7, Rotation.NONE, sbb); + return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomCollapse.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomCollapse.java index 5091e2a8fb..43284053aa 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomCollapse.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomCollapse.java @@ -1,53 +1,48 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.block.BlockTFPlant; import twilightforest.block.TFBlocks; +import java.util.Random; + +import static twilightforest.enums.PlantVariant.ROOT_STRAND; + public class ComponentTFMazeRoomCollapse extends ComponentTFMazeRoom { public ComponentTFMazeRoomCollapse() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeRoomCollapse(int i, Random rand, int x, int y, int z) { - super(i, rand, x, y, z); + public ComponentTFMazeRoomCollapse(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i, rand, x, y, z); } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - + // - for (int x = 1; x < 14; x++) - { - for (int z = 1; z < 14; z++) - { + for (int x = 1; x < 14; x++) { + for (int z = 1; z < 14; z++) { // calculate distance from middle int dist = (int) Math.round(7 / Math.sqrt((7.5 - x) * (7.5 - x) + (7.5 - z) * (7.5 - z))); int gravel = rand.nextInt(dist); int root = rand.nextInt(dist); - if (gravel > 0) - { + if (gravel > 0) { gravel++; // get it out of the floor - this.fillWithBlocks(world, sbb, x, 1, z, x, gravel, z, Blocks.gravel, Blocks.air, false); + this.fillWithBlocks(world, sbb, x, 1, z, x, gravel, z, Blocks.GRAVEL.getDefaultState(), AIR, false); this.fillWithAir(world, sbb, x, gravel, z, x, gravel + 5, z); - } - else if (root > 0) - { - this.fillWithBlocks(world, sbb, x, 5, z, x, 5 + root, z, Blocks.dirt, Blocks.air, true); - this.fillWithMetadataBlocks(world, sbb, x, 5 - rand.nextInt(5), z, x, 5, z, TFBlocks.plant, BlockTFPlant.META_ROOT_STRAND, Blocks.air, 0, false); - } - else if (rand.nextInt(dist + 1) > 0) - { + } else if (root > 0) { + this.fillWithBlocks(world, sbb, x, 5, z, x, 5 + root, z, Blocks.DIRT.getDefaultState(), AIR, true); + this.fillWithBlocks(world, sbb, x, 5 - rand.nextInt(5), z, x, 5, z, TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, ROOT_STRAND), AIR, false); + } else if (rand.nextInt(dist + 1) > 0) { // remove ceiling this.fillWithAir(world, sbb, x, 5, z, x, 5, z); } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomExit.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomExit.java index f25beb4821..eea2b06733 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomExit.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomExit.java @@ -1,21 +1,23 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; +import twilightforest.enums.MazestoneVariant; + +import java.util.Random; public class ComponentTFMazeRoomExit extends ComponentTFMazeRoom { public ComponentTFMazeRoomExit() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeRoomExit(int i, Random rand, int x, int y, int z) { - super(i, rand, x, y, z); + public ComponentTFMazeRoomExit(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i, rand, x, y, z); } @Override @@ -23,18 +25,12 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox super.addComponentParts(world, rand, sbb); // shaft down - this.fillWithMetadataBlocks(world, sbb, 5, -5, 5, 10, 0, 10, TFBlocks.mazestone, 1, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 5, 1, 5, 10, 1, 10, TFBlocks.mazestone, 3, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 5, 2, 5, 10, 3, 10, Blocks.iron_bars, 0, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 5, 4, 5, 10, 4, 10, TFBlocks.mazestone, 3, Blocks.air, 0, false); + this.fillWithBlocks(world, sbb, 5, -5, 5, 10, 0, 10, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BRICK), AIR, false); + this.fillWithBlocks(world, sbb, 5, 1, 5, 10, 1, 10, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + this.fillWithBlocks(world, sbb, 5, 2, 5, 10, 3, 10, Blocks.IRON_BARS.getDefaultState(), AIR, false); + this.fillWithBlocks(world, sbb, 5, 4, 5, 10, 4, 10, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); this.fillWithAir(world, sbb, 6, -5, 6, 9, 4, 9); -// int var8 = this.getXWithOffset(0, 0); -// int var9 = this.getYWithOffset(0); -// int var10 = this.getZWithOffset(0, 0); - - //System.out.println("Drawing exit at " + var8 + ", " + var9 + ", " + var10); - return true; } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomFountain.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomFountain.java index 2c1317332b..d20cc7f9b2 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomFountain.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomFountain.java @@ -1,31 +1,33 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; +import twilightforest.enums.MazestoneVariant; + +import java.util.Random; public class ComponentTFMazeRoomFountain extends ComponentTFMazeRoom { public ComponentTFMazeRoomFountain() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeRoomFountain(int i, Random rand, int x, int y, int z) { - super(i, rand, x, y, z); + public ComponentTFMazeRoomFountain(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i, rand, x, y, z); } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { super.addComponentParts(world, rand, sbb); - - this.fillWithMetadataBlocks(world, sbb, 5, 1, 5, 10, 1, 10, TFBlocks.mazestone, 3, Blocks.air, 0, false); - this.fillWithBlocks(world, sbb, 6, 1, 6, 9, 1, 9, Blocks.water, Blocks.air, false); + + this.fillWithBlocks(world, sbb, 5, 1, 5, 10, 1, 10, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + this.fillWithBlocks(world, sbb, 6, 1, 6, 9, 1, 9, Blocks.WATER.getDefaultState(), AIR, false); return true; } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomSpawnerChests.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomSpawnerChests.java index 5432e70f44..a18fd4d7c2 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomSpawnerChests.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomSpawnerChests.java @@ -1,23 +1,27 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.TFTreasure; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; +import twilightforest.enums.MazestoneVariant; +import twilightforest.util.TFEntityNames; + +import java.util.Random; public class ComponentTFMazeRoomSpawnerChests extends ComponentTFMazeRoom { public ComponentTFMazeRoomSpawnerChests() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeRoomSpawnerChests(int i, Random rand, int x, int y, int z) { - super(i, rand, x, y, z); + public ComponentTFMazeRoomSpawnerChests(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i, rand, x, y, z); } @Override @@ -31,56 +35,59 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox placePillarEnclosure(world, sbb, 10, 10); // spawner - placeSpawnerAtCurrentPosition(world, rand, 4, 2, 4, TFCreatures.getSpawnerNameFor("Minotaur"), sbb); - + setSpawner(world, 4, 2, 4, sbb, TFEntityNames.MINOTAUR); + // treasure this.placeTreasureAtCurrentPosition(world, rand, 4, 2, 11, TFTreasure.labyrinth_room, sbb); - + // treasure this.placeTreasureAtCurrentPosition(world, rand, 11, 2, 4, TFTreasure.labyrinth_room, sbb); - + // trap - placeBlockAtCurrentPosition(world, Blocks.wooden_pressure_plate, 0, 11, 1, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 10, 0, 11, sbb); - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 11, 0, 10, sbb); - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 11, 0, 12, sbb); - placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 12, 0, 11, sbb); + setBlockState(world, Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(), 11, 1, 11, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), 10, 0, 11, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), 11, 0, 10, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), 11, 0, 12, sbb); + setBlockState(world, Blocks.TNT.getDefaultState(), 12, 0, 11, sbb); return true; } private void placePillarEnclosure(World world, StructureBoundingBox sbb, - int dx, int dz) { - for (int y = 1; y < 5; y++) - { - placeBlockAtCurrentPosition(world, TFBlocks.mazestone, 2, dx + 0, y, dz + 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.mazestone, 2, dx + 2, y, dz + 0, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.mazestone, 2, dx + 0, y, dz + 2, sbb); - placeBlockAtCurrentPosition(world, TFBlocks.mazestone, 2, dx + 2, y, dz + 2, sbb); + int dx, int dz) { + for (int y = 1; y < 5; y++) { + final IBlockState chiselledMazeBlock = TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.CHISELED); + setBlockState(world, chiselledMazeBlock, dx + 0, y, dz + 0, sbb); + setBlockState(world, chiselledMazeBlock, dx + 2, y, dz + 0, sbb); + setBlockState(world, chiselledMazeBlock, dx + 0, y, dz + 2, sbb); + setBlockState(world, chiselledMazeBlock, dx + 2, y, dz + 2, sbb); } - placeBlockAtCurrentPosition(world, Blocks.planks, 0, dx + 1, 1, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.planks, 0, dx + 1, 4, dz + 1, sbb); - - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(1), dx + 1, 1, dz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(0), dx + 0, 1, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(2), dx + 2, 1, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(3), dx + 1, 1, dz + 2, sbb); - - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(1) + 4, dx + 1, 4, dz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(0) + 4, dx + 0, 4, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(2) + 4, dx + 2, 4, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.oak_stairs, getStairMeta(3) + 4, dx + 1, 4, dz + 2, sbb); - - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 1, 2, dz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 0, 2, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 2, 2, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 1, 2, dz + 2, sbb); - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 1, 3, dz + 0, sbb); - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 0, 3, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 2, 3, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.iron_bars, 0, dx + 1, 3, dz + 2, sbb); - - + setBlockState(world, Blocks.PLANKS.getDefaultState(), dx + 1, 1, dz + 1, sbb); + setBlockState(world, Blocks.PLANKS.getDefaultState(), dx + 1, 4, dz + 1, sbb); + + final IBlockState defaultState = Blocks.OAK_STAIRS.getDefaultState(); + + + setBlockState(world, getStairState(defaultState, EnumFacing.NORTH, rotation, false), dx + 1, 1, dz + 0, sbb); + setBlockState(world, getStairState(defaultState, EnumFacing.WEST, rotation, false), dx + 0, 1, dz + 1, sbb); + setBlockState(world, getStairState(defaultState, EnumFacing.EAST, rotation, false), dx + 2, 1, dz + 1, sbb); + setBlockState(world, getStairState(defaultState, EnumFacing.SOUTH, rotation, false), dx + 1, 1, dz + 2, sbb); + + setBlockState(world, getStairState(defaultState, EnumFacing.NORTH, rotation, true), dx + 1, 4, dz + 0, sbb); + setBlockState(world, getStairState(defaultState, EnumFacing.WEST, rotation, true), dx + 0, 4, dz + 1, sbb); + setBlockState(world, getStairState(defaultState, EnumFacing.EAST, rotation, true), dx + 2, 4, dz + 1, sbb); + setBlockState(world, getStairState(defaultState, EnumFacing.SOUTH, rotation, true), dx + 1, 4, dz + 2, sbb); + + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 1, 2, dz + 0, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 0, 2, dz + 1, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 2, 2, dz + 1, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 1, 2, dz + 2, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 1, 3, dz + 0, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 0, 3, dz + 1, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 2, 3, dz + 1, sbb); + setBlockState(world, Blocks.IRON_BARS.getDefaultState(), dx + 1, 3, dz + 2, sbb); + + } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomVault.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomVault.java index 9a03d53e43..67558e3d87 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomVault.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomVault.java @@ -1,68 +1,70 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.TFTreasure; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; +import twilightforest.enums.MazestoneVariant; + +import java.util.Random; public class ComponentTFMazeRoomVault extends ComponentTFMazeRoom { public ComponentTFMazeRoomVault() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeRoomVault(int i, Random rand, int x, int y, int z) { - super(i, rand, x, y, z); - + public ComponentTFMazeRoomVault(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i, rand, x, y, z); + // specify a non-existant high spawn list value to stop actual monster spawns this.spawnListIndex = Integer.MAX_VALUE; } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // fill room with bricks - fillWithMetadataBlocks(world, sbb, 0, 1, 0, 15, 4, 15, TFBlocks.mazestone, 3, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 0, 2, 0, 15, 3, 15, TFBlocks.mazestone, 1, Blocks.air, 0, false); + fillWithBlocks(world, sbb, 0, 1, 0, 15, 4, 15, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + fillWithBlocks(world, sbb, 0, 2, 0, 15, 3, 15, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BRICK), AIR, false); // 4x4 room in the middle fillWithAir(world, sbb, 6, 2, 6, 9, 3, 9); - + // pressure plates, sand & tnt - fillWithMetadataBlocks(world, sbb, 6, 2, 5, 9, 2, 5, Blocks.wooden_pressure_plate, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 6, 2, 10, 9, 2, 10, Blocks.wooden_pressure_plate, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 5, 2, 6, 5, 2, 9, Blocks.wooden_pressure_plate, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 10, 2, 6, 10, 2, 9, Blocks.wooden_pressure_plate, 0, Blocks.air, 0, false); - + fillWithBlocks(world, sbb, 6, 2, 5, 9, 2, 5, Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 6, 2, 10, 9, 2, 10, Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 5, 2, 6, 5, 2, 9, Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 10, 2, 6, 10, 2, 9, Blocks.WOODEN_PRESSURE_PLATE.getDefaultState(), AIR, false); + // unfair sand - fillWithMetadataBlocks(world, sbb, 6, 4, 5, 9, 4, 5, Blocks.sand, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 6, 4, 10, 9, 4, 10, Blocks.sand, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 5, 4, 6, 5, 4, 9, Blocks.sand, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 10, 4, 6, 10, 4, 9, Blocks.sand, 0, Blocks.air, 0, false); - - fillWithMetadataBlocks(world, sbb, 6, 0, 5, 9, 0, 5, Blocks.tnt, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 6, 0, 10, 9, 0, 10, Blocks.tnt, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 5, 0, 6, 5, 0, 9, Blocks.tnt, 0, Blocks.air, 0, false); - fillWithMetadataBlocks(world, sbb, 10, 0, 6, 10, 0, 9, Blocks.tnt, 0, Blocks.air, 0, false); - + fillWithBlocks(world, sbb, 6, 4, 5, 9, 4, 5, Blocks.SAND.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 6, 4, 10, 9, 4, 10, Blocks.SAND.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 5, 4, 6, 5, 4, 9, Blocks.SAND.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 10, 4, 6, 10, 4, 9, Blocks.SAND.getDefaultState(), AIR, false); + + fillWithBlocks(world, sbb, 6, 0, 5, 9, 0, 5, Blocks.TNT.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 6, 0, 10, 9, 0, 10, Blocks.TNT.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 5, 0, 6, 5, 0, 9, Blocks.TNT.getDefaultState(), AIR, false); + fillWithBlocks(world, sbb, 10, 0, 6, 10, 0, 9, Blocks.TNT.getDefaultState(), AIR, false); + // LEWTZ! - this.placeBlockAtCurrentPosition(world, Blocks.chest, 0, 7, 2, 6, sbb); + this.setBlockState(world, Blocks.CHEST.getDefaultState(), 7, 2, 6, sbb); this.placeTreasureAtCurrentPosition(world, rand, 8, 2, 6, TFTreasure.labyrinth_vault, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.chest, 0, 8, 2, 9, sbb); + this.setBlockState(world, Blocks.CHEST.getDefaultState(), 8, 2, 9, sbb); this.placeTreasureAtCurrentPosition(world, rand, 7, 2, 9, TFTreasure.labyrinth_vault, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.chest, 0, 6, 2, 7, sbb); + this.setBlockState(world, Blocks.CHEST.getDefaultState(), 6, 2, 7, sbb); this.placeTreasureAtCurrentPosition(world, rand, 6, 2, 8, TFTreasure.labyrinth_vault, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.chest, 0, 9, 2, 8, sbb); + this.setBlockState(world, Blocks.CHEST.getDefaultState(), 9, 2, 8, sbb); this.placeTreasureAtCurrentPosition(world, rand, 9, 2, 7, TFTreasure.labyrinth_vault, sbb); // mazebreaker! - - + + return true; } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRuins.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRuins.java index 0bd5f05cc2..a1ff13c3e6 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRuins.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeRuins.java @@ -1,64 +1,64 @@ package twilightforest.structures.minotaurmaze; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; /** * This component is the base for the maze/ruins combo feature. There are village-like ruins above and a maze underneath. - * - * @author Ben * + * @author Ben */ -public class ComponentTFMazeRuins extends StructureTFComponent { +public class ComponentTFMazeRuins extends StructureTFComponentOld { public ComponentTFMazeRuins() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeRuins(World world, Random rand, int i, int x, int y, int z) { - super(i); - this.setCoordBaseMode(0); + public ComponentTFMazeRuins(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.SOUTH); // I have no bounding box - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, 0, 0, 0, 0); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, 0, 0, 0, EnumFacing.SOUTH); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + + /** + * Initiates construction of the Structure Component picked, at the current Location of StructGen + */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { + public void buildComponent(StructureComponent structurecomponent, List list, Random random) { super.buildComponent(structurecomponent, list, random); - + // add a maze - ComponentTFMinotaurMaze maze = new ComponentTFMinotaurMaze(1, boundingBox.minX, boundingBox.minY - 14, boundingBox.minZ, 1); + ComponentTFMinotaurMaze maze = new ComponentTFMinotaurMaze(getFeatureType(), 1, boundingBox.minX, boundingBox.minY - 14, boundingBox.minZ, 1); list.add(maze); maze.buildComponent(this, list, random); - + // add maze entrance shaft - ComponentTFMazeEntranceShaft mazeEnter = new ComponentTFMazeEntranceShaft(2, random, boundingBox.minX + 1, boundingBox.minY, boundingBox.minZ + 1); + ComponentTFMazeEntranceShaft mazeEnter = new ComponentTFMazeEntranceShaft(getFeatureType(), 2, random, boundingBox.minX + 1, boundingBox.minY, boundingBox.minZ + 1); list.add(mazeEnter); mazeEnter.buildComponent(this, list, random); - + // add aboveground maze entrance building - ComponentTFMazeMound mazeAbove = new ComponentTFMazeMound(2, random, boundingBox.minX - 14, boundingBox.minY, boundingBox.minZ - 14); + ComponentTFMazeMound mazeAbove = new ComponentTFMazeMound(getFeatureType(), 2, random, boundingBox.minX - 14, boundingBox.minY, boundingBox.minZ - 14); list.add(mazeAbove); mazeAbove.buildComponent(this, list, random); - + } - /** - * second Part of Structure generating, this for example places Spiderwebs, Mob Spawners, it closes Mineshafts at - * the end, it adds Fences... - */ + /** + * second Part of Structure generating, this for example places Spiderwebs, Mob Spawners, it closes Mineshafts at + * the end, it adds Fences... + */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // I have no components diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeUpperEntrance.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeUpperEntrance.java index 03e5bd1e2e..30c9162409 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeUpperEntrance.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMazeUpperEntrance.java @@ -1,38 +1,39 @@ package twilightforest.structures.minotaurmaze; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; - -public class ComponentTFMazeUpperEntrance extends StructureTFComponent { +import twilightforest.enums.MazestoneVariant; +import twilightforest.structures.StructureTFComponentOld; - private int averageGroundLevel = -1; +import java.util.List; +import java.util.Random; +public class ComponentTFMazeUpperEntrance extends StructureTFComponentOld { public ComponentTFMazeUpperEntrance() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMazeUpperEntrance(int i, Random rand, int x, int y, int z) { - super(i); - this.coordBaseMode = rand.nextInt(4); + public ComponentTFMazeUpperEntrance(TFFeature feature, int i, Random rand, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.HORIZONTALS[rand.nextInt(4)]); - this.boundingBox = new StructureBoundingBox(x, y, z, x + 15, y + 4, z + 15); + this.boundingBox = new StructureBoundingBox(x, y, z, x + 15, y + 4, z + 15); } /** * Initiates construction of the Structure Component picked, at the current Location of StructGen */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { + public void buildComponent(StructureComponent structurecomponent, List list, Random random) { ; } @@ -40,82 +41,70 @@ public void buildComponent(StructureComponent structurecomponent, List list, Ran public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // ceiling - this.randomlyFillWithBlocks(world, sbb, rand, 0.7F, 0, 5, 0, 15, 5, 15, TFBlocks.mazestone, Blocks.air, true); + this.generateMaybeBox(world, sbb, rand, 0.7F, 0, 5, 0, 15, 5, 15, TFBlocks.maze_stone.getDefaultState(), AIR, true, 0); + + this.fillWithBlocks(world, sbb, 0, 0, 0, 15, 0, 15, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.MOSAIC), AIR, false); + this.fillWithBlocks(world, sbb, 0, 1, 0, 15, 1, 15, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, true); + this.fillWithBlocks(world, sbb, 0, 2, 0, 15, 3, 15, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BRICK), AIR, true); + this.fillWithBlocks(world, sbb, 0, 4, 0, 15, 4, 15, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, true); + this.generateMaybeBox(world, sbb, rand, 0.2F, 0, 0, 0, 15, 5, 15, Blocks.GRAVEL.getDefaultState(), AIR, true, 0); - this.fillWithMetadataBlocks(world, sbb, 0, 0, 0, 15, 0, 15, TFBlocks.mazestone, 6, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 0, 1, 0, 15, 1, 15, TFBlocks.mazestone, 3, Blocks.air, 0, true); - this.fillWithMetadataBlocks(world, sbb, 0, 2, 0, 15, 3, 15, TFBlocks.mazestone, 1, Blocks.air, 0, true); - this.fillWithMetadataBlocks(world, sbb, 0, 4, 0, 15, 4, 15, TFBlocks.mazestone, 3, Blocks.air, 0, true); - this.randomlyFillWithBlocks(world, sbb, rand, 0.2F, 0, 0, 0, 15, 5, 15, Blocks.gravel, Blocks.air, true); - // doorways - fillWithBlocks(world, sbb, 6, 1, 0, 9, 4, 0, Blocks.fence, Blocks.air, false); + fillWithBlocks(world, sbb, 6, 1, 0, 9, 4, 0, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 7, 1, 0, 8, 3, 0); - fillWithBlocks(world, sbb, 6, 1, 15, 9, 4, 15, Blocks.fence, Blocks.air, false); + fillWithBlocks(world, sbb, 6, 1, 15, 9, 4, 15, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 7, 1, 15, 8, 3, 15); - fillWithBlocks(world, sbb, 0, 1, 6, 0, 4, 9, Blocks.fence, Blocks.air, false); + fillWithBlocks(world, sbb, 0, 1, 6, 0, 4, 9, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 0, 1, 7, 0, 3, 8); - fillWithBlocks(world, sbb, 15, 1, 6, 15, 4, 9, Blocks.fence, Blocks.air, false); + fillWithBlocks(world, sbb, 15, 1, 6, 15, 4, 9, Blocks.OAK_FENCE.getDefaultState(), AIR, false); fillWithAir(world, sbb, 15, 1, 7, 15, 3, 8); - + // random holes // this.randomlyRareFillWithBlocks(world, sbb, 0, 1, 0, 15, 4, 15, 0, false); // this.randomlyRareFillWithBlocks(world, sbb, 0, 3, 0, 15, 4, 15, 0, true); // this.randomlyRareFillWithBlocks(world, sbb, 0, 4, 0, 15, 4, 15, 0, true); - this.fillWithAir(world, sbb, 1, 1, 1, 14, 4, 14); - - // entrance pit - this.fillWithMetadataBlocks(world, sbb, 5, 1, 5, 10, 1, 10, TFBlocks.mazestone, 3, Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 5, 4, 5, 10, 4, 10, TFBlocks.mazestone, 3, Blocks.air, 0, false); - this.randomlyFillWithBlocks(world, sbb, rand, 0.7F, 5, 2, 5, 10, 3, 10, Blocks.iron_bars, Blocks.air, false); -// this.fillWithMetadataBlocks(world, sbb, 5, 2, 5, 10, 3, 10, Blocks.iron_bars, 0, Blocks.air, 0, false); + this.fillWithAir(world, sbb, 1, 1, 1, 14, 4, 14); + // entrance pit + this.fillWithBlocks(world, sbb, 5, 1, 5, 10, 1, 10, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + this.fillWithBlocks(world, sbb, 5, 4, 5, 10, 4, 10, TFBlocks.maze_stone.getDefaultState().withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE), AIR, false); + this.generateMaybeBox(world, sbb, rand, 0.7F, 5, 2, 5, 10, 3, 10, Blocks.IRON_BARS.getDefaultState(), AIR, false, 0); +// this.fillWithBlocks(world, sbb, 5, 2, 5, 10, 3, 10, Blocks.IRON_BARS, 0, AIR, false); this.fillWithAir(world, sbb, 6, 0, 6, 9, 4, 9); - - -// int var8 = this.getXWithOffset(0, 0); -// int var9 = this.getYWithOffset(0); -// int var10 = this.getZWithOffset(0, 0); -// -// System.out.println("Drawing entrance at " + var8 + ", " + var9 + ", " + var10); - - + return true; } - /** - * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the - * levels in the BB's horizontal rectangle). - */ - protected int getAverageGroundLevel(World par1World, StructureBoundingBox par2StructureBoundingBox) - { - int var3 = 0; - int var4 = 0; - - for (int var5 = this.boundingBox.minZ; var5 <= this.boundingBox.maxZ; ++var5) - { - for (int var6 = this.boundingBox.minX; var6 <= this.boundingBox.maxX; ++var6) - { - if (par2StructureBoundingBox.isVecInside(var6, 64, var5)) - { - var3 += Math.max(par1World.getTopSolidOrLiquidBlock(var6, var5), par1World.provider.getAverageGroundLevel()); - ++var4; - } - } - } - - if (var4 == 0) - { - return -1; - } - else - { - return var3 / var4; - } - } + /** + * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the + * levels in the BB's horizontal rectangle). + */ + @Override + protected int getAverageGroundLevel(World world, StructureBoundingBox boundingBox) { + int yTotal = 0; + int count = 0; + + for (int z = this.boundingBox.minZ; z <= this.boundingBox.maxZ; ++z) { + for (int x = this.boundingBox.minX; x <= this.boundingBox.maxX; ++x) { + BlockPos pos = new BlockPos(x, 64, z); + + if (boundingBox.isVecInside(pos)) { + final BlockPos topPos = world.getTopSolidOrLiquidBlock(pos); + yTotal += Math.max(topPos.getY(), world.provider.getAverageGroundLevel()); + ++count; + } + } + } + + if (count == 0) { + return -1; + } else { + return yTotal / count; + } + } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMinotaurMaze.java b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMinotaurMaze.java index 5d7b828eb7..6ae488a1b0 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMinotaurMaze.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/ComponentTFMinotaurMaze.java @@ -1,38 +1,42 @@ package twilightforest.structures.minotaurmaze; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFConfig; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; +import twilightforest.enums.MazestoneVariant; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.TFMaze; +import java.util.List; +import java.util.Random; +public class ComponentTFMinotaurMaze extends StructureTFComponentOld { -public class ComponentTFMinotaurMaze extends StructureTFComponent { - - private static final int FLOOR_LEVEL = 1; TFMaze maze; int rcoords[]; private int level; - + public ComponentTFMinotaurMaze() { super(); } - public ComponentTFMinotaurMaze(int index, int x, int y, int z, int entranceX, int entranceZ, int level) { - super(index); - this.setCoordBaseMode(0); + public ComponentTFMinotaurMaze(TFFeature feature, int index, int x, int y, int z, int entranceX, int entranceZ, int level) { + super(feature, index); + this.setCoordBaseMode(EnumFacing.SOUTH); this.level = level; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -getRadius(), 0, -getRadius(), getRadius() * 2, 5, getRadius() * 2, 0); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -getRadius(), 0, -getRadius(), getRadius() * 2, 5, getRadius() * 2, EnumFacing.SOUTH); // make maze object - maze = new TFMaze(getMazeSize(), getMazeSize()); + maze = new TFMaze(getMazeSize(), getMazeSize()); // set the seed to a fixed value based on this maze's x and z setFixedMazeSeed(); @@ -52,19 +56,16 @@ private void addRoomsToMaze(int entranceX, int entranceZ, int nrooms) { rcoords[0] = entranceX; rcoords[1] = entranceZ; maze.carveRoom1(entranceX, entranceZ); - + // add room coordinates, trying to keep them separate from existing rooms - for (int i = 1; i < nrooms; i++) - { + for (int i = 1; i < nrooms; i++) { int rx, rz; do { rx = maze.rand.nextInt(getMazeSize() - 2) + 1; rz = maze.rand.nextInt(getMazeSize() - 2) + 1; - } while(isNearRoom(rx, rz, rcoords, i == 1 ? 7 : 4)); + } while (isNearRoom(rx, rz, rcoords, i == 1 ? 7 : 4)); maze.carveRoom1(rx, rz); - - //System.out.println("Initially carving room " + rx + ", " + rz); rcoords[i * 2] = rx; rcoords[i * 2 + 1] = rz; @@ -74,148 +75,126 @@ private void addRoomsToMaze(int entranceX, int entranceZ, int nrooms) { private void setFixedMazeSeed() { maze.setSeed(this.boundingBox.minX * 90342903 + this.boundingBox.minY * 90342903 ^ this.boundingBox.minZ); } - - public ComponentTFMinotaurMaze(int index, int x, int y, int z, int level) { - this(index, x, y, z, 11, 11, level); + + public ComponentTFMinotaurMaze(TFFeature feature, int index, int x, int y, int z, int level) { + this(feature, index, x, y, z, 11, 11, level); } /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("mazeLevel", this.level); - par1NBTTagCompound.setIntArray("roomCoords", this.rcoords); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("mazeLevel", this.level); + tagCompound.setIntArray("roomCoords", this.rcoords); } /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.level = par1NBTTagCompound.getInteger("mazeLevel"); - this.rcoords = par1NBTTagCompound.getIntArray("roomCoords"); - - // recreate maze object - maze = new TFMaze(getMazeSize(), getMazeSize()); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.level = tagCompound.getInteger("mazeLevel"); + this.rcoords = tagCompound.getIntArray("roomCoords"); + + // recreate maze object + maze = new TFMaze(getMazeSize(), getMazeSize()); setFixedMazeSeed(); - + // blank out rcoords above 1 so that the room generation works properly //TODO: re-do this. :) - for (int i = 2; i < rcoords.length; i++) - { + for (int i = 2; i < rcoords.length; i++) { this.rcoords[i] = 0; } - + // recreate rooms this.addRoomsToMaze(this.rcoords[0], this.rcoords[1], (this.rcoords.length + 1) / 2); - + // regenerate maze maze.generateRecursiveBacktracker(0, 0); } - - protected ComponentTFMazeRoom makeRoom(Random random, int i, int dx, int dz) { + + protected ComponentTFMazeRoom makeRoom(Random random, int i, int dx, int dz) { ComponentTFMazeRoom room = null; int worldX = boundingBox.minX + dx * 5 - 4; int worldY = boundingBox.minY; int worldZ = boundingBox.minZ + dz * 5 - 4; - if (i == 0) - { + if (i == 0) { // default room - room = new ComponentTFMazeRoom(3 + i, random, worldX, worldY, worldZ); - } - else if (i == 1) - { - if (this.level == 1) - { + room = new ComponentTFMazeRoom(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); + } else if (i == 1) { + if (this.level == 1) { // exit room - room = new ComponentTFMazeRoomExit(3 + i, random, worldX, worldY, worldZ); - } - else - { + room = new ComponentTFMazeRoomExit(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); + } else { // boss room - room = new ComponentTFMazeRoomBoss(3 + i, random, worldX, worldY, worldZ); + room = new ComponentTFMazeRoomBoss(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); } - } - else if (i == 2 || i == 3) - { - if (this.level == 1) - { + } else if (i == 2 || i == 3) { + if (this.level == 1) { // collapsed room - room = new ComponentTFMazeRoomCollapse(3 + i, random, worldX, worldY, worldZ); - } - else - { + room = new ComponentTFMazeRoomCollapse(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); + } else { // mush-room - room = new ComponentTFMazeMushRoom(3 + i, random, worldX, worldY, worldZ); + room = new ComponentTFMazeMushRoom(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); } - } - else if (i == 4) - { - if (this.level == 1) - { + } else if (i == 4) { + if (this.level == 1) { // fountain room - room = new ComponentTFMazeRoomFountain(3 + i, random, worldX, worldY, worldZ); - } - else - { + room = new ComponentTFMazeRoomFountain(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); + } else { // vault - room = new ComponentTFMazeRoomVault(3 + i, random, worldX, worldY, worldZ); + room = new ComponentTFMazeRoomVault(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); } + } else { + room = new ComponentTFMazeRoomSpawnerChests(getFeatureType(), 3 + i, random, worldX, worldY, worldZ); } - else - { - room = new ComponentTFMazeRoomSpawnerChests(3 + i, random, worldX, worldY, worldZ); - } - + return room; } /** * Find dead ends and put something there - * @param random - * @param list + * + * @param random + * @param list */ - protected void decorateDeadEndsCorridors(Random random, List list) - { - for(int x = 0; x < maze.width; x++) - { - for (int z = 0; z < maze.depth; z++) - { - StructureTFComponent component = null; - + protected void decorateDeadEndsCorridors(Random random, List list) { + for (int x = 0; x < maze.width; x++) { + for (int z = 0; z < maze.depth; z++) { + StructureTFComponentOld component = null; + // dead ends if (!maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) { - component = makeDeadEnd(random, x, z, 3); + component = makeDeadEnd(random, x, z, EnumFacing.EAST); } if (maze.isWall(x, z, x - 1, z) && !maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) { - component = makeDeadEnd(random, x, z, 1); + component = makeDeadEnd(random, x, z, EnumFacing.WEST); } if (maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && !maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1)) { - component = makeDeadEnd(random, x, z, 0); + component = makeDeadEnd(random, x, z, EnumFacing.SOUTH); } if (maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && !maze.isWall(x, z, x, z + 1)) { - component = makeDeadEnd(random, x, z, 2); + component = makeDeadEnd(random, x, z, EnumFacing.NORTH); } - + // corridors if (!maze.isWall(x, z, x - 1, z) && !maze.isWall(x, z, x + 1, z) && maze.isWall(x, z, x, z - 1) && maze.isWall(x, z, x, z + 1) && maze.isWall(x - 1, z, x - 1, z - 1) && maze.isWall(x - 1, z, x - 1, z + 1) && maze.isWall(x + 1, z, x + 1, z - 1) && maze.isWall(x + 1, z, x + 1, z + 1)) { - component = makeCorridor(random, x, z, 1); + component = makeCorridor(random, x, z, EnumFacing.WEST); } if (!maze.isWall(x, z, x, z - 1) && !maze.isWall(x, z, x, z + 1) && maze.isWall(x, z, x - 1, z) && maze.isWall(x, z, x + 1, z) && maze.isWall(x, z - 1, x - 1, z - 1) && maze.isWall(x, z - 1, x + 1, z - 1) && maze.isWall(x, z + 1, x - 1, z + 1) && maze.isWall(x, z + 1, x + 1, z + 1)) { - component = makeCorridor(random, x, z, 0); + component = makeCorridor(random, x, z, EnumFacing.SOUTH); } - - if (component != null) - { + + if (component != null) { list.add(component); component.buildComponent(this, list, random); } @@ -226,58 +205,56 @@ protected void decorateDeadEndsCorridors(Random random, List list) /** * Add a dead end structure at the specified coords */ - protected ComponentTFMazeDeadEnd makeDeadEnd(Random random, int dx, int dz, int rotation) { + protected ComponentTFMazeDeadEnd makeDeadEnd(Random random, int dx, int dz, EnumFacing rotation) { int worldX = boundingBox.minX + dx * 5 + 1; int worldY = boundingBox.minY; int worldZ = boundingBox.minZ + dz * 5 + 1; int decorationType = random.nextInt(8); - switch (decorationType) - { - default: - case 0: - // blank with fence doorway - return new ComponentTFMazeDeadEnd(4, worldX, worldY, worldZ, rotation); - case 1: - return new ComponentTFMazeDeadEndChest(4, worldX, worldY, worldZ, rotation); - case 2: - return new ComponentTFMazeDeadEndTrappedChest(4, worldX, worldY, worldZ, rotation); - case 3: - return new ComponentTFMazeDeadEndTorches(4, worldX, worldY, worldZ, rotation); - case 4: - return new ComponentTFMazeDeadEndFountain(4, worldX, worldY, worldZ, rotation); - case 5: - return new ComponentTFMazeDeadEndFountainLava(4, worldX, worldY, worldZ, rotation); - case 6: - return new ComponentTFMazeDeadEndPainting(4, worldX, worldY, worldZ, rotation); - case 7: - return this.level == 1 ? new ComponentTFMazeDeadEndRoots(4, worldX, worldY, worldZ, rotation) : new ComponentTFMazeDeadEndShrooms(4, worldX, worldY, worldZ, rotation); + switch (decorationType) { + default: + case 0: + // blank with fence doorway + return new ComponentTFMazeDeadEnd(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 1: + return new ComponentTFMazeDeadEndChest(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 2: + return random.nextBoolean() ? new ComponentTFMazeDeadEndTripwireChest(getFeatureType(), 4, worldX, worldY, worldZ, rotation) : new ComponentTFMazeDeadEndTrappedChest(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 3: + return new ComponentTFMazeDeadEndTorches(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 4: + return new ComponentTFMazeDeadEndFountain(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 5: + return new ComponentTFMazeDeadEndFountainLava(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 6: + return new ComponentTFMazeDeadEndPainting(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 7: + return this.level == 1 ? new ComponentTFMazeDeadEndRoots(getFeatureType(), 4, worldX, worldY, worldZ, rotation) : new ComponentTFMazeDeadEndShrooms(getFeatureType(), 4, worldX, worldY, worldZ, rotation); } } - protected ComponentTFMazeCorridor makeCorridor(Random random, int dx, int dz, int rotation) { + protected ComponentTFMazeCorridor makeCorridor(Random random, int dx, int dz, EnumFacing rotation) { int worldX = boundingBox.minX + dx * 5 + 1; int worldY = boundingBox.minY; int worldZ = boundingBox.minZ + dz * 5 + 1; int decorationType = random.nextInt(5); - switch (decorationType) - { - default: - case 0: - return null; - case 1: - return new ComponentTFMazeCorridor(4, worldX, worldY, worldZ, rotation); - case 2: - return new ComponentTFMazeCorridorIronFence(4, worldX, worldY, worldZ, rotation); - case 3: - return null; // painting - case 4: - return this.level == 1 ? new ComponentTFMazeCorridorRoots(4, worldX, worldY, worldZ, rotation) : new ComponentTFMazeCorridorShrooms(4, worldX, worldY, worldZ, rotation); + switch (decorationType) { + default: + case 0: + return null; + case 1: + return new ComponentTFMazeCorridor(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 2: + return new ComponentTFMazeCorridorIronFence(getFeatureType(), 4, worldX, worldY, worldZ, rotation); + case 3: + return null; // painting + case 4: + return this.level == 1 ? new ComponentTFMazeCorridorRoots(getFeatureType(), 4, worldX, worldY, worldZ, rotation) : new ComponentTFMazeCorridorShrooms(getFeatureType(), 4, worldX, worldY, worldZ, rotation); } } @@ -286,27 +263,25 @@ protected ComponentTFMazeCorridor makeCorridor(Random random, int dx, int dz, in * Initiates construction of the Structure Component picked, at the current Location of StructGen */ @Override - public void buildComponent(StructureComponent structurecomponent, List list, Random random) { + public void buildComponent(StructureComponent structurecomponent, List list, Random random) { super.buildComponent(structurecomponent, list, random); - + // add a second story - if (this.level == 1) - { + if (this.level == 1) { int centerX = boundingBox.minX + ((boundingBox.maxX - boundingBox.minX) / 2); int centerZ = boundingBox.minZ + ((boundingBox.maxZ - boundingBox.minZ) / 2); - - ComponentTFMinotaurMaze maze = new ComponentTFMinotaurMaze(1, centerX, boundingBox.minY - 10, centerZ, rcoords[2], rcoords[3], 2); + + ComponentTFMinotaurMaze maze = new ComponentTFMinotaurMaze(getFeatureType(), 1, centerX, boundingBox.minY - 10, centerZ, rcoords[2], rcoords[3], 2); list.add(maze); maze.buildComponent(this, list, random); } - - + + // add rooms where we have our coordinates - for (int i = 0; i < rcoords.length / 2; i++) - { + for (int i = 0; i < rcoords.length / 2; i++) { int dx = rcoords[i * 2]; int dz = rcoords[i * 2 + 1]; - + // add the room as a component ComponentTFMazeRoom room = makeRoom(random, i, dx, dz); list.add(room); @@ -319,31 +294,30 @@ public void buildComponent(StructureComponent structurecomponent, List list, Ran @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { + + IBlockState bedrock = Blocks.BEDROCK.getDefaultState(); + IBlockState stone = Blocks.STONE.getDefaultState(); + IBlockState mazestone = TFBlocks.maze_stone.getDefaultState(); + // level 2 maze surrounded by bedrock - if (level == 2) - { - fillWithBlocks(world, sbb, 0, -1, 0, getDiameter() + 2, 6, getDiameter() + 2, Blocks.bedrock, Blocks.air, false); + if (level == 2) { + fillWithBlocks(world, sbb, 0, -1, 0, getDiameter() + 2, 6, getDiameter() + 2, bedrock, AIR, false); } - + // clear the area fillWithAir(world, sbb, 1, 1, 1, getDiameter(), 4, getDiameter()); -// fillWithBlocks(world, sbb, 0, 0, 0, getDiameter(), 0, getDiameter(), TFBlocks.mazestone, Blocks.stone, false); -// fillWithBlocks(world, sbb, 0, 5, 0, getDiameter(), 5, getDiameter(), TFBlocks.mazestone, Blocks.stone, true); - fillWithMetadataBlocks(world, sbb, 1, 5, 1, getDiameter(), 5, getDiameter(), TFBlocks.mazestone, 0, Blocks.stone, 0, this.level == 1); - fillWithMetadataBlocks(world, sbb, 1, 0, 1, getDiameter(), 0, getDiameter(), TFBlocks.mazestone, 6, Blocks.stone, 0, false); - +// fillWithBlocks(world, sbb, 0, 0, 0, getDiameter(), 0, getDiameter(), TFBlocks.mazestone, Blocks.STONE, false); +// fillWithBlocks(world, sbb, 0, 5, 0, getDiameter(), 5, getDiameter(), TFBlocks.mazestone, Blocks.STONE, true); + boolean onlyReplaceCeiling = this.level == 1 && !TFConfig.dimension.skylightForest; + fillWithBlocks(world, sbb, 1, 5, 1, getDiameter(), 5, getDiameter(), mazestone.withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.PLAIN), stone, onlyReplaceCeiling); + fillWithBlocks(world, sbb, 1, 0, 1, getDiameter(), 0, getDiameter(), mazestone.withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.MOSAIC), stone, false); + // - maze.headBlockID = TFBlocks.mazestone; - maze.headBlockMeta = 3; - maze.wallBlockID = TFBlocks.mazestone; - maze.wallBlockMeta = 1; - maze.rootBlockID = TFBlocks.mazestone; - maze.rootBlockMeta = 3; - maze.pillarBlockID = TFBlocks.mazestone; - maze.pillarBlockMeta = 2; - maze.wallVar0ID = TFBlocks.mazestone; - maze.wallVar0Meta = 4; - maze.wallVarRarity = 0.2F; + maze.headBlockState = mazestone.withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE); + maze.wallBlockState = mazestone.withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.BRICK); + maze.rootBlockState = mazestone.withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.DECORATIVE); + maze.pillarBlockState = mazestone.withProperty(BlockTFMazestone.VARIANT, MazestoneVariant.CHISELED); + maze.wallBlocks = new StructureTFMazeStones(); maze.torchRarity = 0.05F; maze.tall = 2; maze.head = 1; @@ -353,21 +327,20 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox maze.copyToStructure(world, 1, 2, 1, this, sbb); return true; - } - + public int getMazeSize() { return 22; } - + public int getRadius() { return (int) (getMazeSize() * 2.5); } - + public int getDiameter() { return getMazeSize() * 5; } - + /** * @return true if the specified dx and dz are within 3 of a room specified in rcoords */ @@ -376,16 +349,15 @@ protected boolean isNearRoom(int dx, int dz, int[] rcoords, int range) { if (dx == 1 && dz == 1) { return true; } - - for (int i = 0; i < rcoords.length / 2; i++) - { + + for (int i = 0; i < rcoords.length / 2; i++) { int rx = rcoords[i * 2]; int rz = rcoords[i * 2 + 1]; - + if (rx == 0 && rz == 0) { continue; } - + if (Math.abs(dx - rx) < range && Math.abs(dz - rz) < range) { return true; } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/StructureTFMazeStones.java b/src/main/java/twilightforest/structures/minotaurmaze/StructureTFMazeStones.java index 6aea6095db..e8da1c2655 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/StructureTFMazeStones.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/StructureTFMazeStones.java @@ -1,38 +1,34 @@ package twilightforest.structures.minotaurmaze; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.block.BlockTFMazestone; import twilightforest.block.TFBlocks; +import java.util.Random; + +import static twilightforest.enums.MazestoneVariant.BRICK; +import static twilightforest.enums.MazestoneVariant.CRACKED; +import static twilightforest.enums.MazestoneVariant.MOSSY; + public class StructureTFMazeStones extends StructureComponent.BlockSelector { @Override - public void selectBlocks(Random par1Random, int par2, int par3, int par4, boolean wall) { - if (!wall) - { - this.field_151562_a = Blocks.air; - this.selectedBlockMetaData = 0; - } - else - { - this.field_151562_a = TFBlocks.mazestone; - float rf = par1Random.nextFloat(); + public void selectBlocks(Random random, int x, int y, int z, boolean wall) { + if (!wall) { + this.blockstate = Blocks.AIR.getDefaultState(); + } else { + this.blockstate = TFBlocks.maze_stone.getDefaultState(); + float rf = random.nextFloat(); - if (rf < 0.2F) - { - this.selectedBlockMetaData = 5; - } - else if (rf < 0.5F) - { - this.selectedBlockMetaData = 4; - } - else - { - this.selectedBlockMetaData = 1; - } - } + if (rf < 0.2F) { + this.blockstate = blockstate.withProperty(BlockTFMazestone.VARIANT, MOSSY); + } else if (rf < 0.5F) { + this.blockstate = blockstate.withProperty(BlockTFMazestone.VARIANT, CRACKED); + } else { + this.blockstate = blockstate.withProperty(BlockTFMazestone.VARIANT, BRICK); + } + } } } diff --git a/src/main/java/twilightforest/structures/minotaurmaze/TFMinotaurMazePieces.java b/src/main/java/twilightforest/structures/minotaurmaze/TFMinotaurMazePieces.java index 1be1b4d84d..a848ed1015 100644 --- a/src/main/java/twilightforest/structures/minotaurmaze/TFMinotaurMazePieces.java +++ b/src/main/java/twilightforest/structures/minotaurmaze/TFMinotaurMazePieces.java @@ -1,68 +1,42 @@ package twilightforest.structures.minotaurmaze; import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartLabyrinth; public class TFMinotaurMazePieces { - - public static void registerPieces() - { - MapGenStructureIO.func_143031_a(ComponentTFMazeCorridor.class, "TFMMC"); - MapGenStructureIO.func_143031_a(ComponentTFMazeCorridorIronFence.class, "TFMMCIF"); - MapGenStructureIO.func_143031_a(ComponentTFMazeCorridorRoots.class, "TFMMCR"); - MapGenStructureIO.func_143031_a(ComponentTFMazeCorridorShrooms.class, "TFMMCS"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEnd.class, "TFMMDE"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndChest.class, "TFMMDEC"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndFountain.class, "TFMMDEF"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndFountainLava.class, "TFMMDEFL"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndPainting.class, "TFMMDEP"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndRoots.class, "TFMMDER"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndShrooms.class, "TFMMDES"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndTorches.class, "TFMMDET"); - MapGenStructureIO.func_143031_a(ComponentTFMazeDeadEndTrappedChest.class, "TFMMDETC"); - MapGenStructureIO.func_143031_a(ComponentTFMazeEntranceShaft.class, "TFMMES"); - MapGenStructureIO.func_143031_a(ComponentTFMazeMound.class, "TFMMMound"); - MapGenStructureIO.func_143031_a(ComponentTFMazeMushRoom.class, "TFMMMR"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRoom.class, "TFMMR"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRoomBoss.class, "TFMMRB"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRoomCollapse.class, "TFMMRC"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRoomExit.class, "TFMMRE"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRoomFountain.class, "TFMMRF"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRoomSpawnerChests.class, "TFMMRSC"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRoomVault.class, "TFMMRV"); - MapGenStructureIO.func_143031_a(ComponentTFMazeRuins.class, "TFMMRuins"); - MapGenStructureIO.func_143031_a(ComponentTFMazeUpperEntrance.class, "TFMMUE"); - MapGenStructureIO.func_143031_a(ComponentTFMinotaurMaze.class, "TFMMaze"); -} -} -/* -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridor.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorIronFence.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorRoots.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeCorridorShrooms.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEnd.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndChest.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountain.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndFountainLava.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndPainting.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndRoots.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndShrooms.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTorches.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeDeadEndTrappedChest.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeEntranceShaft.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeMound.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeMushRoom.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRoom.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomBoss.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomCollapse.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomExit.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomFountain.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomSpawnerChests.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRoomVault.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeRuins.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMazeUpperEntrance.java -/Minecraft/src/twilightforest/structures/minotaurmaze/ComponentTFMinotaurMaze.java -/Minecraft/src/twilightforest/structures/minotaurmaze/TFMinotaurMazePieces.java -*/ \ No newline at end of file + public static void registerPieces() { + MapGenStructureIO.registerStructure(StructureStartLabyrinth.class, "TFLr"); + + MapGenStructureIO.registerStructureComponent(ComponentTFMazeCorridor.class, "TFMMC"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeCorridorIronFence.class, "TFMMCIF"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeCorridorRoots.class, "TFMMCR"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeCorridorShrooms.class, "TFMMCS"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEnd.class, "TFMMDE"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndChest.class, "TFMMDEC"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndFountain.class, "TFMMDEF"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndFountainLava.class, "TFMMDEFL"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndPainting.class, "TFMMDEP"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndRoots.class, "TFMMDER"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndShrooms.class, "TFMMDES"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndTorches.class, "TFMMDET"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndTrappedChest.class, "TFMMDETrC"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeDeadEndTripwireChest.class, "TFMMDETC"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeEntranceShaft.class, "TFMMES"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeMound.class, "TFMMMound"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeMushRoom.class, "TFMMMR"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRoom.class, "TFMMR"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRoomBoss.class, "TFMMRB"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRoomCollapse.class, "TFMMRC"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRoomExit.class, "TFMMRE"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRoomFountain.class, "TFMMRF"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRoomSpawnerChests.class, "TFMMRSC"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRoomVault.class, "TFMMRV"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeRuins.class, "TFMMRuins"); + MapGenStructureIO.registerStructureComponent(ComponentTFMazeUpperEntrance.class, "TFMMUE"); + MapGenStructureIO.registerStructureComponent(ComponentTFMinotaurMaze.class, "TFMMaze"); + } + +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerBridge.java b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerBridge.java index cc8bfaee46..b5d3f8b734 100644 --- a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerBridge.java +++ b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerBridge.java @@ -1,76 +1,77 @@ package twilightforest.structures.mushroomtower; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.List; +import java.util.Random; public class ComponentTFMushroomTowerBridge extends ComponentTFMushroomTowerWing { int dSize; int dHeight; - + public ComponentTFMushroomTowerBridge() { super(); - // TODO Auto-generated constructor stub } - protected ComponentTFMushroomTowerBridge(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, 3, direction); - + protected ComponentTFMushroomTowerBridge(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, 3, direction); + this.dSize = pSize; this.dHeight = pHeight; } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("destSize", this.dSize); - par1NBTTagCompound.setInteger("destHeight", this.dHeight); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("destSize", this.dSize); + tagCompound.setInteger("destHeight", this.dHeight); } /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.dSize = par1NBTTagCompound.getInteger("destSize"); - this.dHeight = par1NBTTagCompound.getInteger("destHeight"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.dSize = tagCompound.getInteger("destSize"); + this.dHeight = tagCompound.getInteger("destHeight"); } - + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - - int[] dest = new int[] {dSize - 1, 1, 1}; - - boolean madeWing = makeTowerWing(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], dSize, dHeight, 0); - - if (!madeWing) - { - int[] dx = offsetTowerCoords(dest[0], dest[1], dest[2], dSize, 0); - - System.out.println("Making tower wing failed when bridge was already made. Size = " + dSize + ", x = " + dx[0] + " z = " + dx[2]); + + int[] dest = new int[]{dSize - 1, 1, 1}; + boolean madeWing = makeTowerWing(list, rand, this.getComponentType(), dest[0], dest[1], dest[2], dSize, dHeight, Rotation.NONE); + + if (!madeWing) { + int[] dx = offsetTowerCoords(dest[0], dest[1], dest[2], dSize, EnumFacing.SOUTH); + TwilightForestMod.LOGGER.info("Making tower wing failed when bridge was already made. Size = {}, x = {}, z = {}", dSize, dx[0], dx[2]); } } public StructureBoundingBox getWingBB() { int[] dest = offsetTowerCoords(dSize - 1, 1, 1, dSize, this.getCoordBaseMode()); - return StructureTFComponent.getComponentToAddBoundingBox(dest[0], dest[1], dest[2], 0, 0, 0, dSize - 1, dHeight - 1, dSize - 1, this.getCoordBaseMode()); + return StructureTFComponentOld.getComponentToAddBoundingBox(dest[0], dest[1], dest[2], 0, 0, 0, dSize - 1, dHeight - 1, dSize - 1, this.getCoordBaseMode()); } @@ -79,10 +80,10 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox // make walls for (int x = 0; x < dSize; x++) { - placeBlockAtCurrentPosition(world, deco.fenceID, deco.fenceMeta, x, 1, 0, sbb); - placeBlockAtCurrentPosition(world, deco.fenceID, deco.fenceMeta, x, 1, 2, sbb); + setBlockState(world, deco.fenceState, x, 1, 0, sbb); + setBlockState(world, deco.fenceState, x, 1, 2, sbb); - placeBlockAtCurrentPosition(world, deco.floorID, this.isAscender ? 3 : deco.floorMeta, x, 0, 1, sbb); + setBlockState(world, this.isAscender ? deco.floorState.withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.JUNGLE) : deco.floorState, x, 0, 1, sbb); } // clear bridge walkway diff --git a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMain.java b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMain.java index d7607f3f0c..adc4e6811d 100644 --- a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMain.java +++ b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMain.java @@ -1,31 +1,33 @@ package twilightforest.structures.mushroomtower; -import java.util.List; -import java.util.Random; - -import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerRoof; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; + +public class ComponentTFMushroomTowerMain extends ComponentTFMushroomTowerWing { -public class ComponentTFMushroomTowerMain extends ComponentTFMushroomTowerWing -{ - public ComponentTFMushroomTowerMain() { super(); - // TODO Auto-generated constructor stub } - public ComponentTFMushroomTowerMain(World world, Random rand, int index, int x, int y, int z) { - this(world, rand, index, x + MAIN_SIZE, y + 4, z + MAIN_SIZE, 2); + public ComponentTFMushroomTowerMain(TFFeature feature, World world, Random rand, int index, int x, int y, int z) { + this(feature, world, rand, index, x + MAIN_SIZE, y + 4, z + MAIN_SIZE, EnumFacing.NORTH); } - - public ComponentTFMushroomTowerMain(World world, Random rand, int index, int x, int y, int z, int rotation) { - super(index, x, y, z, MAIN_SIZE, 8 + (rand.nextInt(3) * FLOOR_HEIGHT), rotation); - + + public ComponentTFMushroomTowerMain(TFFeature feature, World world, Random rand, int index, int x, int y, int z, EnumFacing rotation) { + super(feature, index, x, y, z, MAIN_SIZE, 8 + (rand.nextInt(3) * FLOOR_HEIGHT), rotation); + // // check to make sure we can build the whole tower // if (this.boundingBox.maxY > 245) // { @@ -38,53 +40,47 @@ public ComponentTFMushroomTowerMain(World world, Random rand, int index, int x, // } // decorator - if (this.deco == null) - { + if (this.deco == null) { this.deco = new StructureDecoratorMushroomTower(); } } - - protected ComponentTFMushroomTowerMain(int i, int x, int y, int z, int pSize, int pHeight, int direction) - { - super(i, x, y, z, pSize, pHeight, direction); + + protected ComponentTFMushroomTowerMain(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - + // we should have a door where we started - addOpening(0, 1, size / 2, 2); - + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); + // should we build a base? this.hasBase = true; - - int mainDir = -1; - + + Rotation mainDir = null; + // limit sprawl to a reasonable amount - if (this.getComponentType() < 3) - { + if (this.getComponentType() < 3) { // make a special sub-tower that will lead back here // try 6 times - for (int i = 0; i < 6; i++) - { + for (int i = 0; i < 6; i++) { mainDir = makeAscenderTower(list, rand); - - if (mainDir != -1) - { + + if (mainDir != null) { break; } } // make sub towers - for (int i = 0; i < 4; i++) { + //for (int i = 0; i < 4; i++) { + for (Rotation i : RotationUtil.ROTATIONS) { - if (i == mainDir) - { + if (i == mainDir) { continue; } @@ -94,9 +90,7 @@ public void buildComponent(StructureComponent parent, List list, Random rand) { makeBridge(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], size - 4, childHeight, i); } - } - else - { + } else { // add a roof? makeARoof(parent, list, rand); } @@ -104,39 +98,31 @@ public void buildComponent(StructureComponent parent, List list, Random rand) { } /** - * Make a new ascender tower. Return direction (0-4) if successful, -1 if not. + * Make a new ascender tower. Returns direction if successful, null if not. */ - private int makeAscenderTower(List list, Random rand) { - int mainDir; - int[] dest; - int childHeight; - mainDir = rand.nextInt(4); - - dest = getValidOpening(rand, mainDir); - - childHeight = (height - dest[1]) + ((rand.nextInt(2) + rand.nextInt(2) + 3) * FLOOR_HEIGHT) + 1; - - boolean madeIt = makeBridge(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], size - 4, childHeight, mainDir, true); - - if (madeIt) - { - System.out.println("Main tower made a bridge to another tower"); + private Rotation makeAscenderTower(List list, Random rand) { + + Rotation mainDir = RotationUtil.ROTATIONS[rand.nextInt(4)]; + int[] dest = getValidOpening(rand, mainDir); + int childHeight = (height - dest[1]) + ((rand.nextInt(2) + rand.nextInt(2) + 3) * FLOOR_HEIGHT) + 1; + boolean madeIt = makeBridge(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], size - 4, childHeight, mainDir, true); + + if (madeIt) { + TwilightForestMod.LOGGER.debug("Main tower made a bridge to another tower"); return mainDir; + } else { + TwilightForestMod.LOGGER.info("Main tower failed to branch off at index {}", this.componentType); + return null; } - else - { - System.out.println("Main tower failed to branch off at index " + this.componentType); - return -1; - } - + } - + /** * Make a mushroom roof! */ @Override - public void makeARoof(StructureComponent parent, List list, Random rand) { - ComponentTFTowerRoof roof = new ComponentTFTowerRoofMushroom(this.getComponentType() + 1, this, 1.6F); + public void makeARoof(StructureComponent parent, List list, Random rand) { + ComponentTFTowerRoof roof = new ComponentTFTowerRoofMushroom(getFeatureType(), this.getComponentType() + 1, this, 1.6F); list.add(roof); roof.buildComponent(this, list, rand); } @@ -145,27 +131,28 @@ public void makeARoof(StructureComponent parent, List list, Random rand) { /** * Make an opening in this tower for a door. This now only makes one opening, so you need two */ + @Override protected void makeDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { super.makeDoorOpening(world, dx, dy, dz, sbb); - - // try to remove blocks inside this door + + // try to remove blocks inside this door if (dx == 0) { - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx + 1, dy + 0, dz, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx + 1, dy + 1, dz, sbb); + setBlockState(world, AIR, dx + 1, dy + 0, dz, sbb); + setBlockState(world, AIR, dx + 1, dy + 1, dz, sbb); } if (dx == size - 1) { - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx - 1, dy + 0, dz, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx - 1, dy + 1, dz, sbb); + setBlockState(world, AIR, dx - 1, dy + 0, dz, sbb); + setBlockState(world, AIR, dx - 1, dy + 1, dz, sbb); } if (dz == 0) { - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 0, dz + 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 1, dz + 1, sbb); + setBlockState(world, AIR, dx, dy + 0, dz + 1, sbb); + setBlockState(world, AIR, dx, dy + 1, dz + 1, sbb); } if (dz == size - 1) { - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 0, dz - 1, sbb); - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx, dy + 1, dz - 1, sbb); + setBlockState(world, AIR, dx, dy + 0, dz - 1, sbb); + setBlockState(world, AIR, dx, dy + 1, dz - 1, sbb); } - + } diff --git a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMainBridge.java b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMainBridge.java index c171d9327f..f8b68bd2c4 100644 --- a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMainBridge.java +++ b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerMainBridge.java @@ -1,33 +1,35 @@ package twilightforest.structures.mushroomtower; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + import java.util.List; import java.util.Random; -import net.minecraft.world.gen.structure.StructureComponent; - public class ComponentTFMushroomTowerMainBridge extends ComponentTFMushroomTowerBridge { public ComponentTFMushroomTowerMainBridge() { super(); - // TODO Auto-generated constructor stub } - protected ComponentTFMushroomTowerMainBridge(int i, int x, int y, int z, int pSize, int pHeight, int direction) { + protected ComponentTFMushroomTowerMainBridge(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { // bridge only 11 long - super(i, x, y, z, 11, pHeight, direction); + super(feature, i, x, y, z, 11, pHeight, direction); } @Override - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { // make a new size 15 main tower - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 15, direction); - + // adjust coordinates to fit an existing tower dx = adjustCoordinates(dx[0], dx[1], dx[2], 15, direction, list); - ComponentTFMushroomTowerMain wing = new ComponentTFMushroomTowerMain(index, dx[0], dx[1], dx[2], 15, wingHeight, direction); + ComponentTFMushroomTowerMain wing = new ComponentTFMushroomTowerMain(getFeatureType(), index, dx[0], dx[1], dx[2], 15, wingHeight, direction); list.add(wing); wing.buildComponent((StructureComponent) list.get(0), list, rand); @@ -37,7 +39,4 @@ public boolean makeTowerWing(List list, Random rand, int index, int x, int y, in } - - - } diff --git a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerWing.java b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerWing.java index f1cc0a07e7..8b3a374ca7 100644 --- a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerWing.java +++ b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFMushroomTowerWing.java @@ -1,19 +1,25 @@ package twilightforest.structures.mushroomtower; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerRoof; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import twilightforest.util.RotationUtil; + +import java.util.List; +import java.util.Random; -public class ComponentTFMushroomTowerWing extends ComponentTFTowerWing -{ +public class ComponentTFMushroomTowerWing extends ComponentTFTowerWing { private static final int RANGE = 200; protected static final int FLOOR_HEIGHT = 4; @@ -26,213 +32,186 @@ public ComponentTFMushroomTowerWing() { super(); } - protected ComponentTFMushroomTowerWing(int i, int x, int y, int z, int pSize, int pHeight, int direction) { - super(i, x, y, z, pSize, pHeight, direction); + protected ComponentTFMushroomTowerWing(TFFeature feature, int i, int x, int y, int z, int pSize, int pHeight, EnumFacing direction) { + super(feature, i, x, y, z, pSize, pHeight, direction); } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("hasBase", this.hasBase); - par1NBTTagCompound.setBoolean("isAscender", this.isAscender); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("hasBase", this.hasBase); + tagCompound.setBoolean("isAscender", this.isAscender); } /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.hasBase = par1NBTTagCompound.getBoolean("hasBase"); - this.isAscender = par1NBTTagCompound.getBoolean("isAscender"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.hasBase = tagCompound.getBoolean("hasBase"); + this.isAscender = tagCompound.getBoolean("isAscender"); } @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } - + // we should have a door where we started - addOpening(0, 1, size / 2, 2); - + addOpening(0, 1, size / 2, Rotation.CLOCKWISE_180); + // should we build a base? this.hasBase = size > 3; - - // if we are an acender, build the destination tower - if (this.isAscender) - { - int[] dest = getValidOpening(rand, 2); - + + // if we are an ascender, build the destination tower + if (this.isAscender) { + + int[] dest = getValidOpening(rand, Rotation.CLOCKWISE_180); dest[1] = this.height - 3; - int childHeight = (rand.nextInt(3) + rand.nextInt(3) + 2) * FLOOR_HEIGHT + 1; - - - boolean madeIt = makeMainBridge(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], size + 4, childHeight, 2); - - if (!madeIt) - { - System.out.println("Did not make bridge back to new main"); - } - else - { - System.out.println("Made bridge back to new main"); + boolean madeIt = makeMainBridge(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], size + 4, childHeight, Rotation.CLOCKWISE_180); + + if (!madeIt) { + TwilightForestMod.LOGGER.info("Did not make bridge back to new main"); + } else { + TwilightForestMod.LOGGER.debug("Made bridge back to new main"); } } - + // limit sprawl to a reasonable amount - if (this.getComponentType() < 5 && this.size > 6) - { + if (this.getComponentType() < 5 && this.size > 6) { // make sub towers - for (int i = 0; i < 4; i++) { - - if (this.size < MAIN_SIZE && i == 2) - { + //for (int i = 0; i < 4; i++) { + for (Rotation i : RotationUtil.ROTATIONS) { + + if (this.size < MAIN_SIZE && i == Rotation.CLOCKWISE_180) { continue; } int[] dest = getValidOpening(rand, i); - + int childHeight = (rand.nextInt(2) + rand.nextInt(2) + 2) * FLOOR_HEIGHT + 1; - + makeBridge(list, rand, this.getComponentType() + 1, dest[0], dest[1], dest[2], size - 4, childHeight, i); } } - - if (this.isHighest(this.boundingBox, this.size, list) || !this.hasBase) - { + + if (this.isHighest(this.boundingBox, this.size, list) || !this.hasBase) { // add a roof? makeARoof(parent, list, rand); } - + } /** * Have we strayed more than range blocks away from the center? */ private boolean isOutOfRange(StructureComponent parent, int nx, int ny, int nz, int range) { - -// System.out.println("x range is " + Math.abs(nx - parent.getBoundingBox().minX)); -// System.out.println("z range is " + Math.abs(nz - parent.getBoundingBox().minZ)); -// System.out.println("nz is " + nz + ", parent.minz is " + parent.getBoundingBox().minZ); - - return Math.abs(nx - parent.getBoundingBox().getCenterX()) > range - || Math.abs(nz - parent.getBoundingBox().getCenterZ()) > range; + final StructureBoundingBox sbb = parent.getBoundingBox(); + final int centerX = sbb.minX + (sbb.maxX - sbb.minX + 1) / 2; + final int centerZ = sbb.minZ + (sbb.maxZ - sbb.minZ + 1) / 2; + return Math.abs(nx - centerX) > range + || Math.abs(nz - centerZ) > range; } /** * Make a new wing */ - public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + @Override + public boolean makeTowerWing(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, wingSize, direction); - + // stop if out of range - if (isOutOfRange((StructureComponent) list.get(0), dx[0], dx[1], dx[2], RANGE)) - { + if (isOutOfRange((StructureComponent) list.get(0), dx[0], dx[1], dx[2], RANGE)) { return false; } - + // adjust coordinates to fit an existing tower - if (wingSize > 3) - { + if (wingSize > 3) { dx = adjustCoordinates(dx[0], dx[1], dx[2], wingSize, direction, list); } - ComponentTFMushroomTowerWing wing = new ComponentTFMushroomTowerWing(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFMushroomTowerWing wing = new ComponentTFMushroomTowerWing(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, wing.getBoundingBox()); if (intersect == null || intersect == this || intersect instanceof ComponentTFTowerRoofMushroom) { - + // if we are coming from an ascender bridge, mark the destination component - if (this instanceof ComponentTFMushroomTowerBridge && this.isAscender) - { + if (this instanceof ComponentTFMushroomTowerBridge && this.isAscender) { wing.isAscender = true; } - + list.add(wing); wing.buildComponent((StructureComponent) list.get(0), list, rand); addOpening(x, y, z, rotation); return true; - } - else - { + } else { return false; } } - + /** * Adjust the coordinates for this tower to link up with any others within 3 */ - protected int[] adjustCoordinates(int x, int y, int z, int wingSize, int direction, List list) { - + protected int[] adjustCoordinates(int x, int y, int z, int wingSize, EnumFacing direction, List list) { + // go through list. if there are any same size towers within wingSize, return their xyz instead - - for (Object obj : list) - { - if (obj instanceof ComponentTFTowerWing && !(obj instanceof ComponentTFMushroomTowerBridge)) - { - ComponentTFTowerWing otherWing = (ComponentTFTowerWing)obj; - - if (wingSize == otherWing.size && otherWing.getBoundingBox().intersectsWith(x - 3, z - 3, x + 3, z + 3)) - { -// System.out.println("I found an intersecting thing : " + otherWing + ", size = " + wingSize + " direction = " + direction); -// System.out.println("x = " + x + ", z = " + z + " other.minX = " + otherWing.getBoundingBox().minX + " other.maxX = " + otherWing.getBoundingBox().maxX + " other.minZ = " + otherWing.getBoundingBox().minZ + " other.maxZ = " + otherWing.getBoundingBox().maxZ); - - switch (direction) - { - case 0: - return new int[] {otherWing.getBoundingBox().minX, y, otherWing.getBoundingBox().minZ}; - case 1: - return new int[] {otherWing.getBoundingBox().maxX, y, otherWing.getBoundingBox().minZ}; - case 2: - return new int[] {otherWing.getBoundingBox().maxX, y, otherWing.getBoundingBox().maxZ}; - case 3: - return new int[] {otherWing.getBoundingBox().minX, y, otherWing.getBoundingBox().maxZ}; + + for (Object obj : list) { + if (obj instanceof ComponentTFTowerWing && !(obj instanceof ComponentTFMushroomTowerBridge)) { + ComponentTFTowerWing otherWing = (ComponentTFTowerWing) obj; + + if (wingSize == otherWing.size && otherWing.getBoundingBox().intersectsWith(x - 3, z - 3, x + 3, z + 3)) { + switch (direction) { + case SOUTH: + return new int[]{otherWing.getBoundingBox().minX, y, otherWing.getBoundingBox().minZ}; + case WEST: + return new int[]{otherWing.getBoundingBox().maxX, y, otherWing.getBoundingBox().minZ}; + case NORTH: + return new int[]{otherWing.getBoundingBox().maxX, y, otherWing.getBoundingBox().maxZ}; + case EAST: + return new int[]{otherWing.getBoundingBox().minX, y, otherWing.getBoundingBox().maxZ}; + default: + return new int[]{x, y, z}; } } } } - - return new int[] {x, y, z}; + return new int[]{x, y, z}; } - + /** * Are there (not) any other towers below this bounding box? */ - private boolean isHighest(StructureBoundingBox boundingBox, int size, List list) { + private boolean isHighest(StructureBoundingBox boundingBox, int size, List list) { // go through list. if there are any same size towers within wingSize, return their xyz instead - + StructureBoundingBox boxAbove = new StructureBoundingBox(boundingBox); - + boxAbove.maxY = 256; - - for (Object obj : list) - { - if (this != obj && obj instanceof ComponentTFTowerWing && !(obj instanceof ComponentTFMushroomTowerBridge)) - { - ComponentTFTowerWing otherWing = (ComponentTFTowerWing)obj; - - if (size == otherWing.size && otherWing.getBoundingBox().intersectsWith(boxAbove)) - { - //System.out.println("This tower (" + boundingBox + ") is not the highest, there is " + otherWing + " at " + otherWing.getBoundingBox()); - + + for (Object obj : list) { + if (this != obj && obj instanceof ComponentTFTowerWing && !(obj instanceof ComponentTFMushroomTowerBridge)) { + ComponentTFTowerWing otherWing = (ComponentTFTowerWing) obj; + + if (size == otherWing.size && otherWing.getBoundingBox().intersectsWith(boxAbove)) { return false; } } } - + return true; } @@ -240,25 +219,19 @@ private boolean isHighest(StructureBoundingBox boundingBox, int size, List list) * Make a mushroom roof! */ @Override - public void makeARoof(StructureComponent parent, List list, Random rand) { - - ComponentTFTowerRoof roof = new ComponentTFTowerRoofMushroom(this.getComponentType() + 1, this, 1.6F); - if (StructureComponent.findIntersecting(list, roof.getBoundingBox()) instanceof ComponentTFTowerRoofMushroom) - { + public void makeARoof(StructureComponent parent, List list, Random rand) { + + ComponentTFTowerRoof roof = new ComponentTFTowerRoofMushroom(getFeatureType(), this.getComponentType() + 1, this, 1.6F); + if (StructureComponent.findIntersecting(list, roof.getBoundingBox()) instanceof ComponentTFTowerRoofMushroom) { list.add(roof); roof.buildComponent(this, list, rand); - } - else - { - roof = new ComponentTFTowerRoofMushroom(this.getComponentType() + 1, this, 1.0F); - if (StructureComponent.findIntersecting(list, roof.getBoundingBox()) instanceof ComponentTFTowerRoofMushroom) - { + } else { + roof = new ComponentTFTowerRoofMushroom(getFeatureType(), this.getComponentType() + 1, this, 1.0F); + if (StructureComponent.findIntersecting(list, roof.getBoundingBox()) instanceof ComponentTFTowerRoofMushroom) { list.add(roof); roof.buildComponent(this, list, rand); - } - else - { - roof = new ComponentTFTowerRoofMushroom(this.getComponentType() + 1, this, 0.6F); + } else { + roof = new ComponentTFTowerRoofMushroom(getFeatureType(), this.getComponentType() + 1, this, 0.6F); list.add(roof); roof.buildComponent(this, list, rand); } @@ -267,28 +240,28 @@ public void makeARoof(StructureComponent parent, List list, Random rand) { } - protected boolean makeBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { + @Override + protected boolean makeBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { return this.makeBridge(list, rand, index, x, y, z, wingSize, wingHeight, rotation, false); } - - protected boolean makeBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation, boolean ascender) { + + protected boolean makeBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation, boolean ascender) { // bridges are size always - int direction = (getCoordBaseMode() + rotation) % 4; + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 3, direction); - + // adjust height for those stupid little things if (wingSize == 3) { wingHeight = 4; } - - ComponentTFMushroomTowerBridge bridge = new ComponentTFMushroomTowerBridge(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + + ComponentTFMushroomTowerBridge bridge = new ComponentTFMushroomTowerBridge(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); bridge.isAscender = ascender; // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, bridge.getBoundingBox()); if (intersect == null || intersect == this) { intersect = StructureComponent.findIntersecting(list, bridge.getWingBB()); - } - else { + } else { return false; } // okay, I think we can actually make one, as long as we're not still intersecting something. @@ -297,18 +270,17 @@ protected boolean makeBridge(List list, Random rand, int index, int x, int y, in bridge.buildComponent(this, list, rand); addOpening(x, y, z, rotation); return true; - } - else { + } else { return false; } } - - private boolean makeMainBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, int rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; + private boolean makeMainBridge(List list, Random rand, int index, int x, int y, int z, int wingSize, int wingHeight, Rotation rotation) { + + EnumFacing direction = getStructureRelativeRotation(rotation); int[] dx = offsetTowerCoords(x, y, z, 3, direction); - ComponentTFMushroomTowerMainBridge bridge = new ComponentTFMushroomTowerMainBridge(index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); + ComponentTFMushroomTowerMainBridge bridge = new ComponentTFMushroomTowerMainBridge(getFeatureType(), index, dx[0], dx[1], dx[2], wingSize, wingHeight, direction); list.add(bridge); bridge.buildComponent(this, list, rand); @@ -320,31 +292,32 @@ private boolean makeMainBridge(List list, Random rand, int index, int x, int y, /** * Gets a random position in the specified direction that connects to stairs currently in the tower. */ - public int[] getValidOpening(Random rand, int direction) { + @Override + public int[] getValidOpening(Random rand, Rotation direction) { // variables! int wLength = Math.min(size / 3, 3); // wall length int offset = (size - wLength) / 2; // wall thickness - + // for directions 0 or 2, the wall lies along the z axis - if (direction == 0 || direction == 2) { - int rx = direction == 0 ? size - 1 : 0; + if (direction == Rotation.NONE || direction == Rotation.CLOCKWISE_180) { + int rx = direction == Rotation.NONE ? size - 1 : 0; int rz = offset + rand.nextInt(wLength); int ry = getYByStairs(rz, rand, direction); - - return new int[] {rx, ry, rz}; + + return new int[]{rx, ry, rz}; } - + // for directions 1 or 3, the wall lies along the x axis - if (direction == 1 || direction == 3) { + if (direction == Rotation.CLOCKWISE_90 || direction == Rotation.COUNTERCLOCKWISE_90) { int rx = offset + rand.nextInt(wLength); - int rz = direction == 1 ? size - 1 : 0; + int rz = direction == Rotation.CLOCKWISE_90 ? size - 1 : 0; int ry = getYByStairs(rx, rand, direction); - - return new int[] {rx, ry, rz}; + + return new int[]{rx, ry, rz}; } - - - return new int[] {0, 0, 0}; + + + return new int[]{0, 0, 0}; } @@ -352,83 +325,74 @@ public int[] getValidOpening(Random rand, int direction) { * Gets a Y value where the stairs meet the specified X coordinate. * Also works for Z coordinates. */ - protected int getYByStairs(int rx, Random rand, int direction) { - + @Override + protected int getYByStairs(int rx, Random rand, Rotation direction) { + int floors = this.height / FLOOR_HEIGHT; - + return FLOOR_HEIGHT + 1 + (rand.nextInt(floors - 1) * FLOOR_HEIGHT); } @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - + // // clear inside // fillWithAir(world, sbb, 1, 1, 1, size - 2, height - 2, size - 2); - + makeTrunk(world, sbb); - - + + // make floors makeFloorsForTower(world, decoRNG, sbb); - // nullify sky light + // nullify sky light this.nullifySkyLightForBoundingBox(world); - - // openings - makeOpenings(world, sbb); - - - return true; + // openings + makeOpenings(world, sbb); + + + return true; } private void makeTrunk(World world, StructureBoundingBox sbb) { int diameter = this.size / 2; - int hollow = (int)(diameter * 0.8); - + int hollow = (int) (diameter * 0.8); + int cx = diameter; int cz = diameter; // build the trunk upwards - for (int dx = -diameter; dx <= diameter; dx++) - { - for (int dz = -diameter; dz <= diameter; dz++) - { + for (int dx = -diameter; dx <= diameter; dx++) { + for (int dz = -diameter; dz <= diameter; dz++) { // determine how far we are from the center. int ax = Math.abs(dx); int az = Math.abs(dz); - int dist = (int)(Math.max(ax, az) + (Math.min(ax, az) * 0.4)); + int dist = (int) (Math.max(ax, az) + (Math.min(ax, az) * 0.4)); // make a trunk! - if (dist <= diameter) - { + if (dist <= diameter) { // make floor/ceiling - placeBlockAtCurrentPosition(world, deco.floorID, deco.floorMeta, dx + cx, 0, dz + cz, sbb); - placeBlockAtCurrentPosition(world, deco.floorID, deco.floorMeta, dx + cx, height, dz + cz, sbb); + setBlockState(world, deco.floorState, dx + cx, 0, dz + cz, sbb); + setBlockState(world, deco.floorState, dx + cx, height, dz + cz, sbb); // make walls - if (dist > hollow) - { - for (int dy = 0; dy <= height; dy++) - { - placeBlockAtCurrentPosition(world, deco.blockID, deco.blockMeta, dx + cx, dy, dz + cz, sbb); + if (dist > hollow) { + for (int dy = 0; dy <= height; dy++) { + setBlockState(world, deco.blockState, dx + cx, dy, dz + cz, sbb); } - } - else - { - for (int dy = 1; dy <= height - 1; dy++) - { - placeBlockAtCurrentPosition(world, Blocks.air, 0, dx + cx, dy, dz + cz, sbb); + } else { + for (int dy = 1; dy <= height - 1; dy++) { + setBlockState(world, AIR, dx + cx, dy, dz + cz, sbb); } } // make base - if (this.hasBase) - { - this.func_151554_b(world, deco.blockID, deco.blockMeta, dx + cx, -1, dz + cz, sbb); + if (this.hasBase) { + this.replaceAirAndLiquidDownwards(world, deco.blockState, dx + cx, -1, dz + cz, sbb); } } } @@ -444,44 +408,40 @@ private void makeFloorsForTower(World world, Random decoRNG, StructureBoundingBo // divide the tower into floors for (int i = 0; i < floors; i++) { - + placeFloor(world, i * FLOOR_HEIGHT, sbb); - downLadderDir = ladderDir; ladderDir++; ladderDir %= 4; - + // decorateFloor(world, decoRNG, i, (i * floorHeight), (i * floorHeight) + floorHeight, ladderDir, downLadderDir, sbb); } - - + + } private void placeFloor(World world, int dy, StructureBoundingBox sbb) { int diameter = this.size / 2; - int hollow = (int)(diameter * 0.8); - + int hollow = (int) (diameter * 0.8); + int cx = diameter; int cz = diameter; // build the trunk upwards - for (int dx = -diameter; dx <= diameter; dx++) - { - for (int dz = -diameter; dz <= diameter; dz++) - { + for (int dx = -diameter; dx <= diameter; dx++) { + for (int dz = -diameter; dz <= diameter; dz++) { // determine how far we are from the center. int ax = Math.abs(dx); int az = Math.abs(dz); - int dist = (int)(Math.max(ax, az) + (Math.min(ax, az) * 0.4)); + int dist = (int) (Math.max(ax, az) + (Math.min(ax, az) * 0.4)); // make a floor! - if (dist <= hollow) - { + if (dist <= hollow) { { - placeBlockAtCurrentPosition(world, deco.floorID, this.isAscender ? 3 : deco.floorMeta, dx + cx, dy, dz + cz, sbb); + setBlockState(world, this.isAscender ? deco.floorState.withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.JUNGLE) : deco.floorState, dx + cx, dy, dz + cz, sbb); } } } @@ -491,28 +451,29 @@ private void placeFloor(World world, int dy, StructureBoundingBox sbb) { /** * Make an opening in this tower for a door. This now only makes one opening, so you need two */ + @Override protected void makeDoorOpening(World world, int dx, int dy, int dz, StructureBoundingBox sbb) { super.makeDoorOpening(world, dx, dy, dz, sbb); - - if (getBlockAtCurrentPosition(world, dx, dy + 2, dz, sbb) != Blocks.air) { - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, dx, dy + 2, dz, sbb); - } + + if (getBlockStateFromPos(world, dx, dy + 2, dz, sbb).getBlock() != Blocks.AIR) { + setBlockState(world, deco.accentState, dx, dy + 2, dz, sbb); + } } - + /** * Called to decorate each floor. This is responsible for adding a ladder up, the stub of the ladder going down, then picking a theme for each floor and executing it. - * + * * @param floor * @param bottom * @param top * @param ladderUpDir - * @param laddderDownDir + * @param ladderDownDir */ - protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, int ladderUpDir, int ladderDownDir, StructureBoundingBox sbb) { + @Override + protected void decorateFloor(World world, Random rand, int floor, int bottom, int top, Rotation ladderUpDir, Rotation ladderDownDir, StructureBoundingBox sbb) { //decorateWraparoundWallSteps(world, rand, bottom, top, ladderUpDir, ladderDownDir, sbb); } - } diff --git a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFTowerRoofMushroom.java b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFTowerRoofMushroom.java index ecd8aa80d6..4cb7aaabd4 100644 --- a/src/main/java/twilightforest/structures/mushroomtower/ComponentTFTowerRoofMushroom.java +++ b/src/main/java/twilightforest/structures/mushroomtower/ComponentTFTowerRoofMushroom.java @@ -1,38 +1,39 @@ package twilightforest.structures.mushroomtower; -import java.util.List; -import java.util.Random; - -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; import twilightforest.structures.lichtower.ComponentTFTowerRoof; import twilightforest.structures.lichtower.ComponentTFTowerWing; +import java.util.List; +import java.util.Random; + public class ComponentTFTowerRoofMushroom extends ComponentTFTowerRoof { - public ComponentTFTowerRoofMushroom(int i, ComponentTFTowerWing wing, float pHang) { - super(i, wing); + public ComponentTFTowerRoofMushroom(TFFeature feature, int i, ComponentTFTowerWing wing, float pHang) { + super(feature, i, wing); this.height = wing.size; - - int overhang = (int)(wing.size * pHang); - + + int overhang = (int) (wing.size * pHang); + this.size = wing.size + (overhang * 2); - - this.setCoordBaseMode(0); - + + this.setCoordBaseMode(EnumFacing.SOUTH); + this.boundingBox = new StructureBoundingBox(wing.getBoundingBox().minX - overhang, wing.getBoundingBox().maxY + 2, wing.getBoundingBox().minZ - overhang, wing.getBoundingBox().maxX + overhang, wing.getBoundingBox().maxY + this.height + 1, wing.getBoundingBox().maxZ + overhang); } - + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; } } @@ -46,49 +47,42 @@ public ComponentTFTowerRoofMushroom() { */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - + for (int y = 0; y <= height; y++) { - - int radius = (int)(MathHelper.sin((y + height/1.2F) / (height * 2.05F) * 3.14F) * this.size / 2F); - int hollow = MathHelper.floor_float(radius * .9F); - - if ((height - y) < 3) - { + + int radius = (int) (MathHelper.sin((y + height / 1.2F) / (height * 2.05F) * 3.14F) * this.size / 2F); + int hollow = MathHelper.floor(radius * .9F); + + if ((height - y) < 3) { hollow = -1; } makeCircle(world, y, radius, hollow, sbb); - } - - return true; + } + + return true; } private void makeCircle(World world, int y, int radius, int hollow, StructureBoundingBox sbb) { - + int cx = size / 2; int cz = size / 2; // build the trunk upwards - for (int dx = -radius; dx <= radius; dx++) - { - for (int dz = -radius; dz <= radius; dz++) - { + for (int dx = -radius; dx <= radius; dx++) { + for (int dz = -radius; dz <= radius; dz++) { // determine how far we are from the center. // int ax = Math.abs(dx); // int az = Math.abs(dz); - float dist = MathHelper.sqrt_float(dx * dx + dz * dz); + float dist = MathHelper.sqrt(dx * dx + dz * dz); // make a trunk! - if (dist <= (radius + 0.5F)) - { - if (dist > hollow) - { - placeBlockAtCurrentPosition(world, deco.accentID, deco.accentMeta, dx + cx, y, dz + cz, sbb); - } - else - { + if (dist <= (radius + 0.5F)) { + if (dist > hollow) { + setBlockState(world, deco.accentState, dx + cx, y, dz + cz, sbb); + } else { // spore - placeBlockAtCurrentPosition(world, deco.accentID, 0, dx + cx, y, dz + cz, sbb); + setBlockState(world, deco.accentState.getBlock().getDefaultState(), dx + cx, y, dz + cz, sbb); } } diff --git a/src/main/java/twilightforest/structures/mushroomtower/StructureDecoratorMushroomTower.java b/src/main/java/twilightforest/structures/mushroomtower/StructureDecoratorMushroomTower.java index ea822b6070..5520b68d82 100644 --- a/src/main/java/twilightforest/structures/mushroomtower/StructureDecoratorMushroomTower.java +++ b/src/main/java/twilightforest/structures/mushroomtower/StructureDecoratorMushroomTower.java @@ -1,29 +1,19 @@ package twilightforest.structures.mushroomtower; +import net.minecraft.block.BlockHugeMushroom; import net.minecraft.init.Blocks; import twilightforest.structures.StructureTFDecorator; public class StructureDecoratorMushroomTower extends StructureTFDecorator { - - - public StructureDecoratorMushroomTower() - { - this.blockID = Blocks.red_mushroom_block; - this.blockMeta = 10; - - this.accentID = Blocks.red_mushroom_block; - this.accentMeta = 14; - - this.fenceID = Blocks.fence; - - this.stairID = Blocks.spruce_stairs; - - this.pillarID = Blocks.red_mushroom_block; - this.pillarMeta = 10; - - this.floorID = Blocks.planks; - this.floorMeta = 0; + + public StructureDecoratorMushroomTower() { + this.blockState = Blocks.RED_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM); + this.accentState = Blocks.RED_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_OUTSIDE); + this.fenceState = Blocks.OAK_FENCE.getDefaultState(); + this.stairState = Blocks.SPRUCE_STAIRS.getDefaultState(); + this.pillarState = Blocks.RED_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM); + this.floorState = Blocks.PLANKS.getDefaultState(); } - + } diff --git a/src/main/java/twilightforest/structures/mushroomtower/TFMushroomTowerPieces.java b/src/main/java/twilightforest/structures/mushroomtower/TFMushroomTowerPieces.java index 6fd211a1e3..bd6ad03205 100644 --- a/src/main/java/twilightforest/structures/mushroomtower/TFMushroomTowerPieces.java +++ b/src/main/java/twilightforest/structures/mushroomtower/TFMushroomTowerPieces.java @@ -1,15 +1,18 @@ package twilightforest.structures.mushroomtower; import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartMushroomTower; public class TFMushroomTowerPieces { public static void registerPieces() { - MapGenStructureIO.func_143031_a(ComponentTFMushroomTowerMain.class, "TFMTMai"); - MapGenStructureIO.func_143031_a(ComponentTFMushroomTowerWing.class, "TFMTWin"); - MapGenStructureIO.func_143031_a(ComponentTFMushroomTowerBridge.class, "TFMTBri"); - MapGenStructureIO.func_143031_a(ComponentTFMushroomTowerMainBridge.class, "TFMTMB"); - MapGenStructureIO.func_143031_a(ComponentTFTowerRoofMushroom.class, "TFMTRoofMush"); + MapGenStructureIO.registerStructure(StructureStartMushroomTower.class, "TFMT"); + + MapGenStructureIO.registerStructureComponent(ComponentTFMushroomTowerMain.class, "TFMTMai"); + MapGenStructureIO.registerStructureComponent(ComponentTFMushroomTowerWing.class, "TFMTWin"); + MapGenStructureIO.registerStructureComponent(ComponentTFMushroomTowerBridge.class, "TFMTBri"); + MapGenStructureIO.registerStructureComponent(ComponentTFMushroomTowerMainBridge.class, "TFMTMB"); + MapGenStructureIO.registerStructureComponent(ComponentTFTowerRoofMushroom.class, "TFMTRoofMush"); } } diff --git a/src/main/java/twilightforest/structures/package-info.java b/src/main/java/twilightforest/structures/package-info.java new file mode 100644 index 0000000000..a6cb34f1e9 --- /dev/null +++ b/src/main/java/twilightforest/structures/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.structures; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartAuroraPalace.java b/src/main/java/twilightforest/structures/start/StructureStartAuroraPalace.java new file mode 100644 index 0000000000..d7e0eb4e0f --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartAuroraPalace.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.icetower.ComponentTFIceTowerMain; + +import java.util.Random; + +import static twilightforest.TFFeature.ICE_TOWER; + +public class StructureStartAuroraPalace extends StructureStartTFFeatureAbstract { + public StructureStartAuroraPalace() { + super(); + } + + public StructureStartAuroraPalace(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFIceTowerMain(ICE_TOWER, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartCourtyard.java b/src/main/java/twilightforest/structures/start/StructureStartCourtyard.java new file mode 100644 index 0000000000..735dc4955d --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartCourtyard.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.courtyard.ComponentNagaCourtyardMain; + +import java.util.Random; + +import static twilightforest.TFFeature.NAGA_COURTYARD; + +public class StructureStartCourtyard extends StructureStartTFFeatureAbstract { + public StructureStartCourtyard() { + super(); + } + + public StructureStartCourtyard(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentNagaCourtyardMain(NAGA_COURTYARD, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartDarkTower.java b/src/main/java/twilightforest/structures/start/StructureStartDarkTower.java new file mode 100644 index 0000000000..12522ae975 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartDarkTower.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.darktower.ComponentTFDarkTowerMain; + +import java.util.Random; + +import static twilightforest.TFFeature.DARK_TOWER; + +public class StructureStartDarkTower extends StructureStartTFFeatureAbstract { + public StructureStartDarkTower() { + super(); + } + + public StructureStartDarkTower(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFDarkTowerMain(DARK_TOWER, world, rand, 0, x, y - 1, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartFinalCastle.java b/src/main/java/twilightforest/structures/start/StructureStartFinalCastle.java new file mode 100644 index 0000000000..bf87562a80 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartFinalCastle.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.finalcastle.ComponentTFFinalCastleMain; + +import java.util.Random; + +import static twilightforest.TFFeature.FINAL_CASTLE; + +public class StructureStartFinalCastle extends StructureStartTFFeatureAbstract { + public StructureStartFinalCastle() { + super(); + } + + public StructureStartFinalCastle(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFFinalCastleMain(FINAL_CASTLE, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartHedgeMaze.java b/src/main/java/twilightforest/structures/start/StructureStartHedgeMaze.java new file mode 100644 index 0000000000..d969a01023 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartHedgeMaze.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.ComponentTFHedgeMaze; + +import java.util.Random; + +import static twilightforest.TFFeature.HEDGE_MAZE; + +public class StructureStartHedgeMaze extends StructureStartTFFeatureAbstract { + public StructureStartHedgeMaze() { + super(); + } + + public StructureStartHedgeMaze(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFHedgeMaze(HEDGE_MAZE, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartHollowHill.java b/src/main/java/twilightforest/structures/start/StructureStartHollowHill.java new file mode 100644 index 0000000000..f1a6845d72 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartHollowHill.java @@ -0,0 +1,27 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.ComponentTFHollowHill; + +import java.util.Random; + +/** + * Created by Drullkus on 6/26/18. + */ +public class StructureStartHollowHill extends StructureStartTFFeatureAbstract { + + public StructureStartHollowHill() { + super(); + } + + public StructureStartHollowHill(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFHollowHill(feature, world, rand, 0, feature.size, x, y, z); + } +} diff --git a/src/main/java/twilightforest/structures/start/StructureStartHydraLair.java b/src/main/java/twilightforest/structures/start/StructureStartHydraLair.java new file mode 100644 index 0000000000..bd41a9443a --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartHydraLair.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.ComponentTFHydraLair; + +import java.util.Random; + +import static twilightforest.TFFeature.HYDRA_LAIR; + +public class StructureStartHydraLair extends StructureStartTFFeatureAbstract { + public StructureStartHydraLair() { + super(); + } + + public StructureStartHydraLair(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFHydraLair(HYDRA_LAIR, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartKnightStronghold.java b/src/main/java/twilightforest/structures/start/StructureStartKnightStronghold.java new file mode 100644 index 0000000000..c2b16038d0 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartKnightStronghold.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.stronghold.ComponentTFStrongholdEntrance; + +import java.util.Random; + +import static twilightforest.TFFeature.KNIGHT_STRONGHOLD; + +public class StructureStartKnightStronghold extends StructureStartTFFeatureAbstract { + public StructureStartKnightStronghold() { + super(); + } + + public StructureStartKnightStronghold(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFStrongholdEntrance(KNIGHT_STRONGHOLD, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartLabyrinth.java b/src/main/java/twilightforest/structures/start/StructureStartLabyrinth.java new file mode 100644 index 0000000000..a19e3c5ed9 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartLabyrinth.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.minotaurmaze.ComponentTFMazeRuins; + +import java.util.Random; + +import static twilightforest.TFFeature.LABYRINTH; + +public class StructureStartLabyrinth extends StructureStartTFFeatureAbstract { + public StructureStartLabyrinth() { + super(); + } + + public StructureStartLabyrinth(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFMazeRuins(LABYRINTH, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartLichTower.java b/src/main/java/twilightforest/structures/start/StructureStartLichTower.java new file mode 100644 index 0000000000..939c2a3894 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartLichTower.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.lichtower.ComponentTFTowerMain; + +import java.util.Random; + +import static twilightforest.TFFeature.LICH_TOWER; + +public class StructureStartLichTower extends StructureStartTFFeatureAbstract { + public StructureStartLichTower() { + super(); + } + + public StructureStartLichTower(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFTowerMain(LICH_TOWER, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartMushroomTower.java b/src/main/java/twilightforest/structures/start/StructureStartMushroomTower.java new file mode 100644 index 0000000000..7b14f1e98c --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartMushroomTower.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.mushroomtower.ComponentTFMushroomTowerMain; + +import java.util.Random; + +import static twilightforest.TFFeature.MUSHROOM_TOWER; + +public class StructureStartMushroomTower extends StructureStartTFFeatureAbstract { + public StructureStartMushroomTower() { + super(); + } + + public StructureStartMushroomTower(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFMushroomTowerMain(MUSHROOM_TOWER, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartNothing.java b/src/main/java/twilightforest/structures/start/StructureStartNothing.java new file mode 100644 index 0000000000..fcabec4f06 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartNothing.java @@ -0,0 +1,26 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +import java.util.Random; + +public class StructureStartNothing extends StructureStartTFAbstract { + public StructureStartNothing() { + super(); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + //TwilightForestMod.LOGGER.warn("Generating nothing at pos " + x + ", " + y + ", " + z + "!"); + + return null; + } + + public StructureStartNothing(World world, Random rand, int chunkX, int chunkZ) { + super(world, TFFeature.NOTHING, rand, chunkX, chunkZ); + TwilightForestMod.LOGGER.warn("Generated nothing at chunk [{}, {}]!", chunkX, chunkZ); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartQuestGrove.java b/src/main/java/twilightforest/structures/start/StructureStartQuestGrove.java new file mode 100644 index 0000000000..fcde3010c2 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartQuestGrove.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.ComponentTFQuestGrove; + +import java.util.Random; + +import static twilightforest.TFFeature.QUEST_GROVE; + +public class StructureStartQuestGrove extends StructureStartTFFeatureAbstract { + public StructureStartQuestGrove() { + super(); + } + + public StructureStartQuestGrove(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFQuestGrove(QUEST_GROVE, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartTFAbstract.java b/src/main/java/twilightforest/structures/start/StructureStartTFAbstract.java new file mode 100644 index 0000000000..e63e93e636 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartTFAbstract.java @@ -0,0 +1,74 @@ +package twilightforest.structures.start; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.StructureStart; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.biomes.TFBiomes; +import twilightforest.structures.StructureTFComponentTemplate; +import twilightforest.structures.darktower.ComponentTFDarkTowerMain; +import twilightforest.structures.lichtower.ComponentTFTowerMain; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public abstract class StructureStartTFAbstract extends StructureStart { + + public StructureStartTFAbstract() { + super(); + } + + public StructureStartTFAbstract(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(chunkX, chunkZ); + int x = (chunkX << 4) + 8; + int z = (chunkZ << 4) + 8; + int y = TFWorld.SEALEVEL + 1; //TODO: maybe a biome-specific altitude for some of them? + + StructureComponent firstComponent = makeFirstComponent(world, feature, rand, x, y, z); + components.add(firstComponent); + firstComponent.buildComponent(firstComponent, components, rand); + + updateBoundingBox(); + + if (firstComponent instanceof ComponentTFTowerMain || firstComponent instanceof ComponentTFDarkTowerMain) + moveToAvgGroundLevel(world, x, z); + + setupComponents(world); + } + + protected abstract StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z); + + /** + * Move the whole structure up or down + */ + protected void moveToAvgGroundLevel(World world, int x, int z) { + // determine the biome at the origin + Biome biomeAt = world.getBiome(new BlockPos(x, 0, z)); + + int offY = (int) ((biomeAt.getBaseHeight() + biomeAt.getHeightVariation()) * 8); + + // dark forest doesn't seem to get the right value. Why is my calculation so bad? + if (biomeAt == TFBiomes.darkForest) offY += 4; + + if (offY > 0) { + boundingBox.offset(0, offY, 0); + + for (StructureComponent com : getComponents()) { + com.getBoundingBox().offset(0, offY, 0); + } + } + } + + protected void setupComponents(World world) { + TemplateManager templateManager = world.getSaveHandler().getStructureTemplateManager(); + MinecraftServer server = world.getMinecraftServer(); + + for (StructureComponent component : components) + if (component instanceof StructureTFComponentTemplate) + ((StructureTFComponentTemplate) component).setup(templateManager, server); + } +} diff --git a/src/main/java/twilightforest/structures/start/StructureStartTFFeatureAbstract.java b/src/main/java/twilightforest/structures/start/StructureStartTFFeatureAbstract.java new file mode 100644 index 0000000000..2fe0fd8dc6 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartTFFeatureAbstract.java @@ -0,0 +1,68 @@ +package twilightforest.structures.start; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +import java.util.Random; + +public abstract class StructureStartTFFeatureAbstract extends StructureStartTFAbstract { + private static int NUM_LOCKS = 4; + public boolean isConquered; + public byte[] lockBytes = new byte[NUM_LOCKS]; + + @Deprecated + private TFFeature feature; + + public StructureStartTFFeatureAbstract() { + } + + public StructureStartTFFeatureAbstract(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + + this.isConquered = false; + this.feature = feature; + } + + @Override + public void writeToNBT(NBTTagCompound compound) { + super.writeToNBT(compound); + + compound.setBoolean("Conquered", this.isConquered); + compound.setByteArray("Locks", this.lockBytes); + + compound.setInteger("FeatureID", this.feature.ordinal()); + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + super.readFromNBT(compound); + + this.isConquered = compound.getBoolean("Conquered"); + this.lockBytes = compound.getByteArray("Locks"); + + this.feature = TFFeature.getFeatureByID(compound.getInteger("FeatureID")); + } + + public boolean isLocked(int lockIndex) { + if (lockIndex < this.lockBytes.length) { + TwilightForestMod.LOGGER.debug("Checking locks for lockIndex {}", lockIndex); + + for (int i = 0; i < this.lockBytes.length; i++) { + TwilightForestMod.LOGGER.debug("Lock {} = {}", i, this.lockBytes[i]); + } + + return this.lockBytes[lockIndex] != 0; + + } else { + TwilightForestMod.LOGGER.warn("Current lock index {} is beyond array bounds {}", lockIndex, this.lockBytes.length); + return false; + } + } + + @Override + public boolean isSizeableStructure() { + return feature.isStructureEnabled; + } +} diff --git a/src/main/java/twilightforest/structures/start/StructureStartTrollCave.java b/src/main/java/twilightforest/structures/start/StructureStartTrollCave.java new file mode 100644 index 0000000000..8da2c4ca0b --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartTrollCave.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.trollcave.ComponentTFTrollCaveMain; + +import java.util.Random; + +import static twilightforest.TFFeature.TROLL_CAVE; + +public class StructureStartTrollCave extends StructureStartTFFeatureAbstract { + public StructureStartTrollCave() { + super(); + } + + public StructureStartTrollCave(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFTrollCaveMain(TROLL_CAVE, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/StructureStartYetiCave.java b/src/main/java/twilightforest/structures/start/StructureStartYetiCave.java new file mode 100644 index 0000000000..394e1a9003 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/StructureStartYetiCave.java @@ -0,0 +1,25 @@ +package twilightforest.structures.start; + +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.ComponentTFYetiCave; + +import java.util.Random; + +import static twilightforest.TFFeature.YETI_CAVE; + +public class StructureStartYetiCave extends StructureStartTFFeatureAbstract { + public StructureStartYetiCave() { + super(); + } + + public StructureStartYetiCave(World world, TFFeature feature, Random rand, int chunkX, int chunkZ) { + super(world, feature, rand, chunkX, chunkZ); + } + + @Override + protected StructureComponent makeFirstComponent(World world, TFFeature feature, Random rand, int x, int y, int z) { + return new ComponentTFYetiCave(YETI_CAVE, world, rand, 0, x, y, z); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/start/package-info.java b/src/main/java/twilightforest/structures/start/package-info.java new file mode 100644 index 0000000000..bee63cf4b3 --- /dev/null +++ b/src/main/java/twilightforest/structures/start/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.structures.start; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAccessChamber.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAccessChamber.java index 00aca5a81c..e58a2b8d66 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAccessChamber.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAccessChamber.java @@ -1,85 +1,94 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockStoneBrick; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFTrophyPedestal; import twilightforest.block.TFBlocks; +import java.util.List; +import java.util.Random; + public class ComponentTFStrongholdAccessChamber extends StructureTFStrongholdComponent { public ComponentTFStrongholdAccessChamber() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdAccessChamber(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdAccessChamber(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } @Override - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) { + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -4, 1, 0, 9, 5, 9, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + + /** + * Initiates construction of the Structure Component picked, at the current Location of StructGen + */ @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + // make a random component in each direction - addNewUpperComponent(parent, list, random, 0, 4, 1, 9); - addNewUpperComponent(parent, list, random, 1, -1, 1, 4); - addNewUpperComponent(parent, list, random, 2, 4, 1, -1); - addNewUpperComponent(parent, list, random, 3, 9, 1, 4); - - } + addNewUpperComponent(parent, list, random, Rotation.NONE, 4, 1, 9); + addNewUpperComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 1, 4); + addNewUpperComponent(parent, list, random, Rotation.CLOCKWISE_180, 4, 1, -1); + addNewUpperComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 9, 1, 4); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { fillWithRandomizedBlocks(world, sbb, 0, 0, 0, 8, 4, 8, true, rand, deco.randomBlocks); - + // doors placeSmallDoorwayAt(world, rand, 0, 4, 1, 8, sbb); placeSmallDoorwayAt(world, rand, 1, 0, 1, 4, sbb); placeSmallDoorwayAt(world, rand, 2, 4, 1, 0, sbb); placeSmallDoorwayAt(world, rand, 3, 8, 1, 4, sbb); - + // shaft down - this.fillWithMetadataBlocks(world, sbb, 2, -2, 2, 6, 0, 6, Blocks.stonebrick, 1, Blocks.air, 0, false); + final IBlockState defaultState = Blocks.STONEBRICK + .getDefaultState() + .withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.MOSSY); + this.fillWithBlocks(world, sbb, 2, -2, 2, 6, 0, 6, defaultState, AIR, false); this.fillWithAir(world, sbb, 3, -2, 3, 5, 2, 5); - + // stairs surrounding shaft - this.fillWithMetadataBlocks(world, sbb, 2, 0, 3, 2, 0, 6, deco.stairID, this.getStairMeta(2), Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 6, 0, 2, 6, 0, 6, deco.stairID, this.getStairMeta(0), Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 3, 0, 2, 5, 0, 2, deco.stairID, this.getStairMeta(3), Blocks.air, 0, false); - this.fillWithMetadataBlocks(world, sbb, 3, 0, 6, 5, 0, 6, deco.stairID, this.getStairMeta(1), Blocks.air, 0, false); - + this.fillWithBlocks(world, sbb, 2, 0, 3, 2, 0, 6, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), AIR, false); + this.fillWithBlocks(world, sbb, 6, 0, 2, 6, 0, 6, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, false), AIR, false); + this.fillWithBlocks(world, sbb, 3, 0, 2, 5, 0, 2, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), AIR, false); + this.fillWithBlocks(world, sbb, 3, 0, 6, 5, 0, 6, getStairState(deco.stairState, Rotation.CLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), AIR, false); + // pillar - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, 2, 0, 2, sbb); - + this.setBlockState(world, deco.pillarState, 2, 0, 2, sbb); + // pedestal - this.placeBlockAtCurrentPosition(world, TFBlocks.trophyPedestal, 15, 2, 1, 2, sbb); - + final IBlockState blockstateIn = TFBlocks.trophy_pedestal + .getDefaultState() + .withProperty(BlockTFTrophyPedestal.LATENT, true) + //TODO: Atomic: Verify this facing. + .withProperty(BlockTFTrophyPedestal.FACING, EnumFacing.EAST); + this.setBlockState(world, blockstateIn, 2, 1, 2, sbb); + // block point - this.fillWithMetadataBlocks(world, sbb, 2, -1, 2, 6, -1, 6, TFBlocks.shield, 15, Blocks.air, 0, false); - + this.fillWithBlocks(world, sbb, 2, -1, 2, 6, -1, 6, TFBlocks.stronghold_shield.getDefaultState(), AIR, false); + return true; } - + /** * Does this component fall under block protection when progression is turned on, normally true */ + @Override public boolean isComponentProtected() { return false; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAtrium.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAtrium.java index 688b7075d5..86f975a3ab 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAtrium.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdAtrium.java @@ -1,100 +1,94 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockOldLeaf; +import net.minecraft.block.BlockOldLog; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenTrees; import net.minecraft.world.gen.feature.WorldGenerator; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.world.TFGenSmallRainboak; -import twilightforest.world.TFGenSmallTwilightOak; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.world.feature.TFGenSmallRainboak; +import twilightforest.world.feature.TFGenSmallTwilightOak; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdAtrium extends StructureTFStrongholdComponent { private boolean enterBottom; public ComponentTFStrongholdAtrium() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdAtrium(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdAtrium(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - + /** * Save to NBT */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("enterBottom", this.enterBottom); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("enterBottom", this.enterBottom); } /** * Load from NBT */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.enterBottom = par1NBTTagCompound.getBoolean("enterBottom"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.enterBottom = tagCompound.getBoolean("enterBottom"); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { - - if (y > 17) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { + + if (y > 17) { this.enterBottom = false; - } - else if (y < 11) - { + } else if (y < 11) { this.enterBottom = true; - } - else - { + } else { this.enterBottom = (z & 1) == 0; } - - if (enterBottom) - { + + if (enterBottom) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 18, 14, 18, facing); - } - else - { + } else { // enter on the top return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -13, -8, 0, 18, 14, 18, facing); } } - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + /** + * Initiates construction of the Structure Component picked, at the current Location of StructGen + */ @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - - if (this.enterBottom) - { + + if (this.enterBottom) { this.addDoor(4, 1, 0); - addNewComponent(parent, list, random, 2, 13, 8, -1); - } - else - { + addNewComponent(parent, list, random, Rotation.CLOCKWISE_180, 13, 8, -1); + } else { this.addDoor(13, 8, 0); - addNewComponent(parent, list, random, 2, 4, 1, -1); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_180, 4, 1, -1); } - - addNewComponent(parent, list, random, 0, 13, 1, 18); - addNewComponent(parent, list, random, 0, 4, 8, 18); + + addNewComponent(parent, list, random, Rotation.NONE, 13, 1, 18); + addNewComponent(parent, list, random, Rotation.NONE, 4, 8, 18); } @@ -104,26 +98,26 @@ public void buildComponent(StructureComponent parent, List list, Random random) @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 17, 13, 17, rand, deco.randomBlocks); - + // balcony this.fillWithRandomizedBlocks(world, sbb, 1, 6, 1, 16, 7, 16, false, rand, deco.randomBlocks); - this.fillWithBlocks(world, sbb, 5, 8, 5, 12, 8, 12, deco.fenceID, Blocks.air, false); + this.fillWithBlocks(world, sbb, 5, 8, 5, 12, 8, 12, deco.fenceState, AIR, false); this.fillWithAir(world, sbb, 6, 6, 6, 11, 8, 11); - + // balcony pillars - placeBalconyPillar(world, sbb, 0); - placeBalconyPillar(world, sbb, 1); - placeBalconyPillar(world, sbb, 2); - placeBalconyPillar(world, sbb, 3); - + placeBalconyPillar(world, sbb, Rotation.NONE); + placeBalconyPillar(world, sbb, Rotation.CLOCKWISE_90); + placeBalconyPillar(world, sbb, Rotation.CLOCKWISE_180); + placeBalconyPillar(world, sbb, Rotation.COUNTERCLOCKWISE_90); + // corner pillars this.fillWithRandomizedBlocks(world, sbb, 1, 1, 1, 1, 12, 2, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 2, 1, 1, 2, 12, 1, false, rand, deco.randomBlocks); - + this.fillWithRandomizedBlocks(world, sbb, 16, 1, 1, 16, 12, 2, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 15, 1, 1, 15, 12, 1, false, rand, deco.randomBlocks); - + this.fillWithRandomizedBlocks(world, sbb, 1, 1, 15, 1, 12, 16, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 2, 1, 16, 2, 12, 16, false, rand, deco.randomBlocks); @@ -131,12 +125,13 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox this.fillWithRandomizedBlocks(world, sbb, 15, 1, 16, 15, 12, 16, false, rand, deco.randomBlocks); // grass - this.randomlyFillWithBlocks(world, sbb, rand, 0.5F, 6, 0, 6, 11, 0, 11, Blocks.grass, Blocks.grass, false); - this.fillWithBlocks(world, sbb, 7, 0, 7, 10, 0, 10, Blocks.grass, Blocks.air, false); - + IBlockState grass = Blocks.GRASS.getDefaultState(); + this.generateMaybeBox(world, sbb, rand, 0.5F, 6, 0, 6, 11, 0, 11, grass, grass, false, 0); + this.fillWithBlocks(world, sbb, 7, 0, 7, 10, 0, 10, grass, AIR, false); + // tree this.spawnATree(world, rand.nextInt(5), 8, 1, 8, sbb); - + // statues placeCornerStatue(world, 2, 8, 2, 0, sbb); placeCornerStatue(world, 2, 1, 15, 1, sbb); @@ -145,67 +140,62 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox // doors placeDoors(world, rand, sbb); - + return true; } - - private void spawnATree(World world, int treeNum, int x, int y, int z, StructureBoundingBox sbb) - { - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if (sbb.isVecInside(dx, dy, dz)) - { - WorldGenerator treeGen; - // grow a tree - int minHeight = 8; - - switch (treeNum) - { - case 0: - default: - // oak tree - treeGen = new WorldGenTrees(true, minHeight, 0, 0, false); - break; - case 1: - // jungle tree - treeGen = new WorldGenTrees(true, minHeight, 3, 3, false); - break; - case 2: - // birch - treeGen = new WorldGenTrees(true, minHeight, 2, 2, false); - break; - case 3: - treeGen = new TFGenSmallTwilightOak(false, minHeight); - break; - case 4: - treeGen = new TFGenSmallRainboak(false); - break; - } - - for (int i = 0; i < 100; i++) - { - if (treeGen.generate(world, world.rand, dx, dy, dz)) - { - break; - } - - if (i == 99) - { - //System.out.println("Never generated " + treeGen); - } - } - } + + private void spawnATree(World world, int treeNum, int x, int y, int z, StructureBoundingBox sbb) { + BlockPos pos = getBlockPosWithOffset(x, y, z); + + if (sbb.isVecInside(pos)) { + WorldGenerator treeGen; + // grow a tree + int minHeight = 8; + + switch (treeNum) { + case 0: + default: + // oak tree + IBlockState oakWood = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.OAK); + IBlockState oakLeaves = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK).withProperty(BlockLeaves.CHECK_DECAY, false); + treeGen = new WorldGenTrees(true, minHeight, oakWood, oakLeaves, false); + break; + case 1: + // jungle tree + IBlockState jungleWood = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); + IBlockState jungleLeaves = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, false); + treeGen = new WorldGenTrees(true, minHeight, jungleWood, jungleLeaves, false); + break; + case 2: + // birch + IBlockState birchWood = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.BIRCH); + IBlockState birchLeaves = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.BIRCH).withProperty(BlockLeaves.CHECK_DECAY, false); + treeGen = new WorldGenTrees(true, minHeight, birchWood, birchLeaves, false); + break; + case 3: + treeGen = new TFGenSmallTwilightOak(false, minHeight); + break; + case 4: + treeGen = new TFGenSmallRainboak(false); + break; + } + + for (int i = 0; i < 100; i++) { + if (treeGen.generate(world, world.rand, pos)) { + break; + } + } + } } - - private void placeBalconyPillar(World world, StructureBoundingBox sbb, int rotation) { - this.fillBlocksRotated(world, sbb, 5, 1, 5, 5, 12, 5, deco.pillarID, deco.pillarMeta, rotation); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 5, 1, 6, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), 6, 1, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 5, 5, 6, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation) + 4, 6, 5, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 5, 12, 6, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation) + 4, 6, 12, 5, rotation, sbb); + + private void placeBalconyPillar(World world, StructureBoundingBox sbb, Rotation rotation) { + this.fillBlocksRotated(world, sbb, 5, 1, 5, 5, 12, 5, deco.pillarState, rotation); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), 5, 1, 6, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), 6, 1, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 5, 5, 6, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 6, 5, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 5, 12, 6, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 6, 12, 5, rotation, sbb); } } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBalconyRoom.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBalconyRoom.java index 2f106f9715..b2262ae8a5 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBalconyRoom.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBalconyRoom.java @@ -1,112 +1,91 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdBalconyRoom extends StructureTFStrongholdComponent { - + boolean enterBottom; public ComponentTFStrongholdBalconyRoom() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdBalconyRoom(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdBalconyRoom(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Save to NBT - */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("enterBottom", this.enterBottom); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("enterBottom", this.enterBottom); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.enterBottom = par1NBTTagCompound.getBoolean("enterBottom"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.enterBottom = tagCompound.getBoolean("enterBottom"); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { - - if (y > 17) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { + + if (y > 17) { this.enterBottom = false; - } - else if (y < 11) - { + } else if (y < 11) { this.enterBottom = true; - } - else - { + } else { this.enterBottom = (z & 1) == 0; } - - if (enterBottom) - { + + if (enterBottom) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 18, 14, 27, facing); - } - else - { + } else { // enter on the top return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -13, -8, 0, 18, 14, 27, facing); } } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + // lower left exit - addNewComponent(parent, list, random, 0, 13, 1, 27); - + addNewComponent(parent, list, random, Rotation.NONE, 13, 1, 27); + // lower middle right exit - addNewComponent(parent, list, random, 1, -1, 1, 13); - + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 1, 13); + // lower middle left exit - addNewComponent(parent, list, random, 3, 18, 1, 13); - + addNewComponent(parent, list, random, Rotation.CLOCKWISE_180, 18, 1, 13); + // upper left exit - addNewComponent(parent, list, random, 0, 4, 8, 27); - + addNewComponent(parent, list, random, Rotation.NONE, 4, 8, 27); + // upper close right exit - addNewComponent(parent, list, random, 1, -1, 8, 4); - + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 8, 4); + // upper far left exit - addNewComponent(parent, list, random, 3, 18, 8, 22); - - if (this.enterBottom) - { + addNewComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 18, 8, 22); + + if (this.enterBottom) { this.addDoor(4, 1, 0); //this.addDoor(4, 1, 1); - addNewComponent(parent, list, random, 2, 13, 8, -1); - } - else - { + addNewComponent(parent, list, random, Rotation.CLOCKWISE_180, 13, 8, -1); + } else { this.addDoor(13, 8, 0); //this.addDoor(13, 8, 1); - addNewComponent(parent, list, random, 2, 4, 1, -1); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_180, 4, 1, -1); } @@ -121,53 +100,51 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox // balcony this.fillWithRandomizedBlocks(world, sbb, 1, 6, 1, 16, 7, 25, false, rand, deco.randomBlocks); - this.fillWithBlocks(world, sbb, 4, 8, 4, 13, 8, 22, deco.fenceID, Blocks.air, false); + this.fillWithBlocks(world, sbb, 4, 8, 4, 13, 8, 22, deco.fenceState, Blocks.AIR.getDefaultState(), false); this.fillWithAir(world, sbb, 5, 6, 5, 12, 8, 21); - + // stairs & pillars - placeStairsAndPillars(world, sbb, 0); - placeStairsAndPillars(world, sbb, 2); + placeStairsAndPillars(world, sbb, Rotation.NONE); + placeStairsAndPillars(world, sbb, Rotation.CLOCKWISE_180); // doors placeDoors(world, rand, sbb); - + return true; } - private void placeStairsAndPillars(World world, StructureBoundingBox sbb, int rotation) { - this.fillBlocksRotated(world, sbb, 4, 1, 4, 4, 12, 4, deco.pillarID, deco.pillarMeta, rotation); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 4, 1, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), 5, 1, 4, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 4, 5, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation) + 4, 5, 5, 4, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 4, 12, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation) + 4, 5, 12, 4, rotation, sbb); - - this.fillBlocksRotated(world, sbb, 13, 1, 4, 13, 12, 4, deco.pillarID, deco.pillarMeta, rotation); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 13, 1, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), 12, 1, 4, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 13, 5, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation) + 4, 12, 5, 4, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 13, 12, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation) + 4, 12, 12, 4, rotation, sbb); - - this.fillBlocksRotated(world, sbb, 13, 1, 8, 13, 12, 8, deco.pillarID, deco.pillarMeta, rotation); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 13, 1, 9, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation), 13, 1, 7, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), 12, 1, 8, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 13, 5, 9, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation) + 4, 13, 5, 7, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 13, 12, 9, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation) + 4, 13, 12, 7, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation) + 4, 12, 12, 8, rotation, sbb); - - for (int y = 1; y < 8; y++) - { - for (int z = 5; z < 8; z++) - { - this.placeBlockRotated(world, Blocks.air, 0, y + 6, y + 1, z, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), y + 6, y, z, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, y + 6, y - 1, z, rotation, sbb); + private void placeStairsAndPillars(World world, StructureBoundingBox sbb, Rotation rotation) { + this.fillBlocksRotated(world, sbb, 4, 1, 4, 4, 12, 4, deco.pillarState, rotation); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), 4, 1, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), 5, 1, 4, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 4, 5, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 5, 5, 4, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 4, 12, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 5, 12, 4, rotation, sbb); + + this.fillBlocksRotated(world, sbb, 13, 1, 4, 13, 12, 4, deco.pillarState, rotation); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), 13, 1, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, false), 12, 1, 4, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 13, 5, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, true), 12, 5, 4, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 13, 12, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, true), 12, 12, 4, rotation, sbb); + + this.fillBlocksRotated(world, sbb, 13, 1, 8, 13, 12, 8, deco.pillarState, rotation); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), 13, 1, 9, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), 13, 1, 7, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, false), 12, 1, 8, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 13, 5, 9, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 13, 5, 7, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 13, 12, 9, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 13, 12, 7, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, true), 12, 12, 8, rotation, sbb); + + for (int y = 1; y < 8; y++) { + for (int z = 5; z < 8; z++) { + this.setBlockStateRotated(world, AIR, y + 6, y + 1, z, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, false), y + 6, y, z, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, y + 6, y - 1, z, rotation, sbb); } } } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBossRoom.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBossRoom.java index 36ea2c048f..55da1e2992 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBossRoom.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdBossRoom.java @@ -1,64 +1,57 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntitySign; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.block.BlockTFBossSpawner; import twilightforest.block.TFBlocks; +import twilightforest.enums.BossVariant; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdBossRoom extends StructureTFStrongholdComponent { - + public ComponentTFStrongholdBossRoom() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdBossRoom(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdBossRoom(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); this.spawnListIndex = Integer.MAX_VALUE; } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -13, -1, 0, 27, 7, 27, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); this.addDoor(13, 1, 0); } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 26, 6, 26, rand, deco.randomBlocks); - + // inner walls this.fillWithRandomizedBlocks(world, sbb, 1, 1, 1, 3, 5, 25, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 23, 1, 1, 25, 5, 25, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 4, 1, 1, 22, 5, 3, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 4, 1, 23, 22, 5, 25, false, rand, deco.randomBlocks); - + // obsidian filler - this.fillWithMetadataBlocks(world, sbb, 1, 1, 1, 2, 5, 25, Blocks.obsidian, 0, Blocks.obsidian, 0, false); - this.fillWithMetadataBlocks(world, sbb, 24, 1, 1, 25, 5, 25, Blocks.obsidian, 0, Blocks.obsidian, 0, false); - this.fillWithMetadataBlocks(world, sbb, 4, 1, 1, 22, 5, 2, Blocks.obsidian, 0, Blocks.obsidian, 0, false); - this.fillWithMetadataBlocks(world, sbb, 4, 1, 24, 22, 5, 25, Blocks.obsidian, 0, Blocks.obsidian, 0, false); - + this.fillWithBlocks(world, sbb, 1, 1, 1, 2, 5, 25, Blocks.OBSIDIAN.getDefaultState(), Blocks.OBSIDIAN.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 24, 1, 1, 25, 5, 25, Blocks.OBSIDIAN.getDefaultState(), Blocks.OBSIDIAN.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 4, 1, 1, 22, 5, 2, Blocks.OBSIDIAN.getDefaultState(), Blocks.OBSIDIAN.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 4, 1, 24, 22, 5, 25, Blocks.OBSIDIAN.getDefaultState(), Blocks.OBSIDIAN.getDefaultState(), false); + // corner pillars this.fillWithRandomizedBlocks(world, sbb, 4, 1, 4, 4, 5, 7, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 5, 1, 4, 5, 5, 5, false, rand, deco.randomBlocks); @@ -75,135 +68,103 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox this.fillWithRandomizedBlocks(world, sbb, 22, 1, 19, 22, 5, 22, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 21, 1, 21, 21, 5, 22, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 19, 1, 22, 20, 5, 22, false, rand, deco.randomBlocks); - + // pillar decorations (stairs) - placePillarDecorations(world, sbb, 0); - placePillarDecorations(world, sbb, 1); - placePillarDecorations(world, sbb, 2); - placePillarDecorations(world, sbb, 3); - + placePillarDecorations(world, sbb, Rotation.NONE); + placePillarDecorations(world, sbb, Rotation.CLOCKWISE_90); + placePillarDecorations(world, sbb, Rotation.CLOCKWISE_180); + placePillarDecorations(world, sbb, Rotation.COUNTERCLOCKWISE_90); + // sarcophagi - placeSarcophagus(world, sbb, 8, 1, 8, 0); - placeSarcophagus(world, sbb, 13, 1, 8, 0); - placeSarcophagus(world, sbb, 18, 1, 8, 0); + placeSarcophagus(world, sbb, 8, 1, 8, Rotation.NONE); + placeSarcophagus(world, sbb, 13, 1, 8, Rotation.NONE); + placeSarcophagus(world, sbb, 18, 1, 8, Rotation.NONE); + + placeSarcophagus(world, sbb, 8, 1, 15, Rotation.NONE); + placeSarcophagus(world, sbb, 13, 1, 15, Rotation.NONE); + placeSarcophagus(world, sbb, 18, 1, 15, Rotation.NONE); - placeSarcophagus(world, sbb, 8, 1, 15, 0); - placeSarcophagus(world, sbb, 13, 1, 15, 0); - placeSarcophagus(world, sbb, 18, 1, 15, 0); - // doorway this.fillWithAir(world, sbb, 12, 1, 1, 14, 4, 2); - this.fillWithBlocks(world, sbb, 12, 1, 3, 14, 4, 3, Blocks.iron_bars, Blocks.iron_bars, false); - - int var8 = this.getXWithOffset(0, 0); - int var9 = this.getYWithOffset(0); - int var10 = this.getZWithOffset(0, 0); - - //System.out.println("Drawing stronghold boss room at " + var8 + ", " + var9 + ", " + var10); + this.fillWithBlocks(world, sbb, 12, 1, 3, 14, 4, 3, Blocks.IRON_BARS.getDefaultState(), Blocks.IRON_BARS.getDefaultState(), false); - //spawner - placeBlockAtCurrentPosition(world, TFBlocks.bossSpawner, 4, 13, 2, 13, sbb); + setBlockState(world, TFBlocks.boss_spawner.getDefaultState().withProperty(BlockTFBossSpawner.VARIANT, BossVariant.KNIGHT_PHANTOM), 13, 2, 13, sbb); - - // out of order - //this.placeSignAtCurrentPosition(world, 13, 1, 5, "Boss Room", "Out of Order", sbb); - - // doors placeDoors(world, rand, sbb); - + return true; } + private void placeSarcophagus(World world, StructureBoundingBox sbb, int x, int y, int z, Rotation rotation) { + + this.setBlockStateRotated(world, deco.pillarState, x - 1, y, z + 0, rotation, sbb); + this.setBlockStateRotated(world, deco.pillarState, x + 1, y, z + 3, rotation, sbb); + this.setBlockStateRotated(world, deco.pillarState, x + 1, y, z + 0, rotation, sbb); + this.setBlockStateRotated(world, deco.pillarState, x - 1, y, z + 3, rotation, sbb); - private void placeSarcophagus(World world, StructureBoundingBox sbb, int x, int y, int z, int rotation) { - - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x + 1, y, z + 0, rotation, sbb); - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x - 1, y, z + 0, rotation, sbb); - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x + 1, y, z + 3, rotation, sbb); - this.placeBlockRotated(world, deco.pillarID, deco.pillarMeta, x - 1, y, z + 3, rotation, sbb); - // make either torches or fence posts - - if (world.rand.nextInt(7) == 0) - { - this.placeBlockRotated(world, Blocks.torch, 0, x + 1, y + 1, z + 0, rotation, sbb); - } - else - { - this.placeBlockRotated(world, deco.fenceID, deco.fenceMeta, x + 1, y + 1, z + 0, rotation, sbb); - } - if (world.rand.nextInt(7) == 0) - { - this.placeBlockRotated(world, Blocks.torch, 0, x - 1, y + 1, z + 0, rotation, sbb); - } - else - { - this.placeBlockRotated(world, deco.fenceID, deco.fenceMeta, x - 1, y + 1, z + 0, rotation, sbb); - } - if (world.rand.nextInt(7) == 0) - { - this.placeBlockRotated(world, Blocks.torch, 0, x + 1, y + 1, z + 3, rotation, sbb); + + if (world.rand.nextInt(7) == 0) { + this.setBlockStateRotated(world, Blocks.TORCH.getDefaultState(), x + 1, y + 1, z + 0, rotation, sbb); + } else { + this.setBlockStateRotated(world, deco.fenceState, x + 1, y + 1, z + 0, rotation, sbb); } - else - { - this.placeBlockRotated(world, deco.fenceID, deco.fenceMeta, x + 1, y + 1, z + 3, rotation, sbb); + if (world.rand.nextInt(7) == 0) { + this.setBlockStateRotated(world, Blocks.TORCH.getDefaultState(), x - 1, y + 1, z + 0, rotation, sbb); + } else { + this.setBlockStateRotated(world, deco.fenceState, x - 1, y + 1, z + 0, rotation, sbb); } - if (world.rand.nextInt(7) == 0) - { - this.placeBlockRotated(world, Blocks.torch, 0, x - 1, y + 1, z + 3, rotation, sbb); + if (world.rand.nextInt(7) == 0) { + this.setBlockStateRotated(world, Blocks.TORCH.getDefaultState(), x + 1, y + 1, z + 3, rotation, sbb); + } else { + this.setBlockStateRotated(world, deco.fenceState, x + 1, y + 1, z + 3, rotation, sbb); } - else - { - this.placeBlockRotated(world, deco.fenceID, deco.fenceMeta, x - 1, y + 1, z + 3, rotation, sbb); + if (world.rand.nextInt(7) == 0) { + this.setBlockStateRotated(world, Blocks.TORCH.getDefaultState(), x - 1, y + 1, z + 3, rotation, sbb); + } else { + this.setBlockStateRotated(world, deco.fenceState, x - 1, y + 1, z + 3, rotation, sbb); } - - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation), x + 0, y, z + 0, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), x + 0, y, z + 3, rotation, sbb); - - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), x + 1, y, z + 1, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), x + 1, y, z + 2, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), x - 1, y, z + 1, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), x - 1, y, z + 2, rotation, sbb); - - this.placeBlockRotated(world, Blocks.stone_slab, 0, x + 0, y + 1, z + 1, rotation, sbb); - this.placeBlockRotated(world, Blocks.stone_slab, 0, x + 0, y + 1, z + 2, rotation, sbb); + + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), x + 0, y, z + 0, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), x + 0, y, z + 3, rotation, sbb); + + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), x + 1, y, z + 1, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), x + 1, y, z + 2, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, false), x - 1, y, z + 1, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.NONE.rotate(EnumFacing.WEST), rotation, false), x - 1, y, z + 2, rotation, sbb); + + this.setBlockStateRotated(world, Blocks.STONE_SLAB.getDefaultState(), x + 0, y + 1, z + 1, rotation, sbb); + this.setBlockStateRotated(world, Blocks.STONE_SLAB.getDefaultState(), x + 0, y + 1, z + 2, rotation, sbb); } - protected void placePillarDecorations(World world, StructureBoundingBox sbb, int rotation) { - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 4, 1, 8, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), 8, 1, 4, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 4, 5, 8, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation) + 4, 8, 5, 4, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 5, 1, 6, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), 6, 1, 6, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), 6, 1, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 5, 5, 6, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation) + 4, 6, 5, 6, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation) + 4, 6, 5, 5, rotation, sbb); + protected void placePillarDecorations(World world, StructureBoundingBox sbb, Rotation rotation) { + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), 4, 1, 8, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), 8, 1, 4, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 4, 5, 8, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 8, 5, 4, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, false), 5, 1, 6, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), 6, 1, 6, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, false), 6, 1, 5, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 5, 5, 6, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 6, 5, 6, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 6, 5, 5, rotation, sbb); } - - /** - * Make a doorway - this is the iron fence door - */ + + @Override protected void placeDoorwayAt(World world, Random rand, int x, int y, int z, StructureBoundingBox sbb) { - if (x == 0 || x == getXSize()) - { - this.fillWithMetadataBlocks(world, sbb, x, y, z - 1, x, y + 3, z + 1, Blocks.iron_bars, 0, Blocks.air, 0, false); - } - else - { - this.fillWithMetadataBlocks(world, sbb, x - 1, y, z, x + 1, y + 3, z, Blocks.iron_bars, 0, Blocks.air, 0, false); + if (x == 0 || x == getXSize()) { + this.fillWithBlocks(world, sbb, x, y, z - 1, x, y + 3, z + 1, Blocks.IRON_BARS.getDefaultState(), Blocks.AIR.getDefaultState(), false); + } else { + this.fillWithBlocks(world, sbb, x - 1, y, z, x + 1, y + 3, z, Blocks.IRON_BARS.getDefaultState(), Blocks.AIR.getDefaultState(), false); } } - - /** - * Is the specified point a valid spot to break in? - */ + + @Override protected boolean isValidBreakInPoint(int wx, int wy, int wz) { return false; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdCrossing.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdCrossing.java index 4a66e6b920..9baac5f269 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdCrossing.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdCrossing.java @@ -1,91 +1,86 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockStairs; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdCrossing extends StructureTFStrongholdComponent { public ComponentTFStrongholdCrossing() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdCrossing(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdCrossing(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -13, -1, 0, 18, 7, 18, facing); } - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + this.addDoor(13, 1, 0); - addNewComponent(parent, list, random, 0, 4, 1, 18); - addNewComponent(parent, list, random, 1, -1, 1, 13); - addNewComponent(parent, list, random, 3, 18, 1, 4); + addNewComponent(parent, list, random, Rotation.NONE, 4, 1, 18); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 1, 13); + addNewComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 18, 1, 4); } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 17, 6, 17, rand, deco.randomBlocks); - + // statues placeCornerStatue(world, 2, 1, 2, 0, sbb); placeCornerStatue(world, 15, 1, 15, 3, sbb); - + // center pillar - this.fillBlocksRotated(world, sbb, 8, 1, 8, 9, 5, 9, deco.pillarID, deco.pillarMeta, 0); - + this.fillBlocksRotated(world, sbb, 8, 1, 8, 9, 5, 9, deco.pillarState, Rotation.NONE); + // statues - placeWallStatue(world, 8, 1, 7, 0, sbb); - placeWallStatue(world, 7, 1, 9, 3, sbb); - placeWallStatue(world, 9, 1, 10, 2, sbb); - placeWallStatue(world, 10, 1, 8, 1, sbb); + placeWallStatue(world, 8, 1, 7, Rotation.NONE, sbb); + placeWallStatue(world, 7, 1, 9, Rotation.COUNTERCLOCKWISE_90, sbb); + placeWallStatue(world, 9, 1, 10, Rotation.CLOCKWISE_180, sbb); + placeWallStatue(world, 10, 1, 8, Rotation.CLOCKWISE_90, sbb); + - // tables - placeTableAndChairs(world, sbb, 0); - placeTableAndChairs(world, sbb, 1); - placeTableAndChairs(world, sbb, 2); - placeTableAndChairs(world, sbb, 3); + placeTableAndChairs(world, sbb, Rotation.NONE); + placeTableAndChairs(world, sbb, Rotation.CLOCKWISE_90); + placeTableAndChairs(world, sbb, Rotation.CLOCKWISE_180); + placeTableAndChairs(world, sbb, Rotation.COUNTERCLOCKWISE_90); // doors placeDoors(world, rand, sbb); - + return true; } - private void placeTableAndChairs(World world, StructureBoundingBox sbb, int rotation) { + private void placeTableAndChairs(World world, StructureBoundingBox sbb, Rotation rotation) { // table - this.placeBlockRotated(world, Blocks.oak_stairs, this.getStairMeta(0 + rotation) + 4, 5, 1, 3, rotation, sbb); - this.placeBlockRotated(world, Blocks.oak_stairs, this.getStairMeta(3 + rotation) + 4, 5, 1, 4, rotation, sbb); - this.placeBlockRotated(world, Blocks.oak_stairs, this.getStairMeta(1 + rotation) + 4, 6, 1, 3, rotation, sbb); - this.placeBlockRotated(world, Blocks.oak_stairs, this.getStairMeta(2 + rotation) + 4, 6, 1, 4, rotation, sbb); + IBlockState oakStairs = Blocks.OAK_STAIRS.getDefaultState(); + ; + this.setBlockStateRotated(world, getStairState(oakStairs, Rotation.NONE.rotate(EnumFacing.WEST), rotation, true), 5, 1, 3, rotation, sbb); + this.setBlockStateRotated(world, getStairState(oakStairs, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 5, 1, 4, rotation, sbb); + this.setBlockStateRotated(world, getStairState(oakStairs, Rotation.CLOCKWISE_90.rotate(EnumFacing.WEST), rotation, true), 6, 1, 3, rotation, sbb); + this.setBlockStateRotated(world, getStairState(oakStairs, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST), rotation, true), 6, 1, 4, rotation, sbb); // chairs - this.placeBlockRotated(world, Blocks.spruce_stairs, this.getStairMeta(3 + rotation), 5, 1, 2, rotation, sbb); - this.placeBlockRotated(world, Blocks.spruce_stairs, this.getStairMeta(0 + rotation), 7, 1, 3, rotation, sbb); - this.placeBlockRotated(world, Blocks.spruce_stairs, this.getStairMeta(1 + rotation), 6, 1, 5, rotation, sbb); - this.placeBlockRotated(world, Blocks.spruce_stairs, this.getStairMeta(2 + rotation), 4, 1, 4, rotation, sbb); + this.setBlockStateRotated(world, Blocks.SPRUCE_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, Rotation.COUNTERCLOCKWISE_90.rotate(EnumFacing.WEST)), 5, 1, 2, rotation, sbb); + this.setBlockStateRotated(world, Blocks.SPRUCE_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, Rotation.NONE.rotate(EnumFacing.WEST)), 7, 1, 3, rotation, sbb); + this.setBlockStateRotated(world, Blocks.SPRUCE_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, Rotation.CLOCKWISE_90.rotate(EnumFacing.WEST)), 6, 1, 5, rotation, sbb); + this.setBlockStateRotated(world, Blocks.SPRUCE_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, Rotation.CLOCKWISE_180.rotate(EnumFacing.WEST)), 4, 1, 4, rotation, sbb); } - } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdDeadEnd.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdDeadEnd.java index 074e09f056..44fec9d0b6 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdDeadEnd.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdDeadEnd.java @@ -1,14 +1,19 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockStairs; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdDeadEnd extends StructureTFStrongholdComponent { @@ -16,88 +21,68 @@ public class ComponentTFStrongholdDeadEnd extends StructureTFStrongholdComponent private boolean chestTrapped; public ComponentTFStrongholdDeadEnd() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdDeadEnd(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdDeadEnd(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); - par1NBTTagCompound.setBoolean("chestTrapped", this.chestTrapped); + tagCompound.setBoolean("chestTrapped", this.chestTrapped); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); - this.chestTrapped = par1NBTTagCompound.getBoolean("chestTrapped"); + this.chestTrapped = tagCompound.getBoolean("chestTrapped"); } - - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 9, 6, 9, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // entrance this.addDoor(4, 1, 0); - + this.chestTrapped = random.nextInt(3) == 0; } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 8, 6, 8, rand, deco.randomBlocks); - + // statues - this.placeWallStatue(world, 1, 1, 4, 1, sbb); - this.placeWallStatue(world, 7, 1, 4, 3, sbb); - this.placeWallStatue(world, 4, 1, 7, 0, sbb); + this.placeWallStatue(world, 1, 1, 4, Rotation.CLOCKWISE_90, sbb); + this.placeWallStatue(world, 7, 1, 4, Rotation.COUNTERCLOCKWISE_90, sbb); + this.placeWallStatue(world, 4, 1, 7, Rotation.NONE, sbb); // doors placeDoors(world, rand, sbb); - + // treasure this.placeTreasureAtCurrentPosition(world, rand, 4, 1, 3, TFTreasure.stronghold_cache, this.chestTrapped, sbb); - if (this.chestTrapped) - { - this.placeBlockAtCurrentPosition(world, Blocks.tnt, 0, 4, 0, 3, sbb); + if (this.chestTrapped) { + this.setBlockState(world, Blocks.TNT.getDefaultState(), 4, 0, 3, sbb); } - - for (int z = 2; z < 5; z++) - { - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(0), 3, 1, z, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2), 5, 1, z, sbb); + + for (int z = 2; z < 5; z++) { + this.setBlockState(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.WEST), 3, 1, z, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.EAST), 5, 1, z, sbb); } - - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1), 4, 1, 2, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(3), 4, 1, 4, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1), 4, 2, 3, sbb); - + + this.setBlockState(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.NORTH), 4, 1, 2, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.SOUTH), 4, 1, 4, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.NORTH), 4, 2, 3, sbb); + return true; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdEntrance.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdEntrance.java index 4025d48600..6b6dda07e8 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdEntrance.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdEntrance.java @@ -1,170 +1,131 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdEntrance extends StructureTFStrongholdComponent { - + public TFStrongholdPieces lowerPieces; public ComponentTFStrongholdEntrance() { - super(); } - public ComponentTFStrongholdEntrance(World world, Random rand, int i, int x, int y, int z) { - super(i, 0, x, y - 10, z); - + public ComponentTFStrongholdEntrance(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, i, EnumFacing.SOUTH, x, y - 10, z); + this.deco = new StructureTFDecoratorStronghold(); - + lowerPieces = new TFStrongholdPieces(); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // make a random component in each direction lowerPieces.prepareStructurePieces(); - addNewComponent(parent, list, random, 0, 4, 1, 18); + addNewComponent(parent, list, random, Rotation.NONE, 4, 1, 18); lowerPieces.prepareStructurePieces(); - if (!listContainsBossRoom(list)) - { - //System.out.println("Did not find boss room from exit 0"); - } - else - { + if (listContainsBossRoom(list)) { lowerPieces.markBossRoomUsed(); } - addNewComponent(parent, list, random, 1, -1, 1, 13); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 1, 13); lowerPieces.prepareStructurePieces(); - if (!listContainsBossRoom(list)) - { - //System.out.println("Did not find boss room from exit 1"); - } - else - { + if (listContainsBossRoom(list)) { lowerPieces.markBossRoomUsed(); } - addNewComponent(parent, list, random, 2, 13, 1, -1); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_180, 13, 1, -1); lowerPieces.prepareStructurePieces(); - if (!listContainsBossRoom(list)) - { - //System.out.println("Did not find boss room from exit 2"); - } - else - { + if (listContainsBossRoom(list)) { lowerPieces.markBossRoomUsed(); } - addNewComponent(parent, list, random, 3, 18, 1, 4); - if (!listContainsBossRoom(list)) - { - System.out.println("Did not find boss room from exit 3 - EPIC FAIL"); + addNewComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 18, 1, 4); + if (!listContainsBossRoom(list)) { + TwilightForestMod.LOGGER.warn("Did not find boss room from exit 3 - EPIC FAIL"); } - List pieceList = (List)list; StructureBoundingBox shieldBox = new StructureBoundingBox(this.boundingBox); - + int tStairs = 0; int tCorridors = 0; int deadEnd = 0; int tRooms = 0; int bossRooms = 0; - + // compute and generate MEGASHIELD - for (StructureTFStrongholdComponent component : pieceList) - { + for (StructureComponent component : list) { shieldBox.expandTo(component.getBoundingBox()); - - - if (component instanceof ComponentTFStrongholdSmallStairs && ((ComponentTFStrongholdSmallStairs)component).hasTreasure) - { + + + if (component instanceof ComponentTFStrongholdSmallStairs && ((ComponentTFStrongholdSmallStairs) component).hasTreasure) { tStairs++; } - if (component instanceof ComponentTFStrongholdTreasureCorridor) - { + if (component instanceof ComponentTFStrongholdTreasureCorridor) { tCorridors++; } - if (component instanceof ComponentTFStrongholdDeadEnd) - { + if (component instanceof ComponentTFStrongholdDeadEnd) { deadEnd++; } - if (component instanceof ComponentTFStrongholdTreasureRoom) - { + if (component instanceof ComponentTFStrongholdTreasureRoom) { tRooms++; } - if (component instanceof ComponentTFStrongholdBossRoom) - { + if (component instanceof ComponentTFStrongholdBossRoom) { bossRooms++; } } - + // System.out.printf("MEGASHIELD computed! %d, %d, %d to %d, %d, %d.\n", shieldBox.minX, shieldBox.minY, shieldBox.minZ, shieldBox.maxX, shieldBox.maxY, shieldBox.maxZ); // System.out.printf("Stronghold at this point contains %d elements.\n", pieceList.size()); // -// System.out.printf("Room count! TStairs = %d, TCorr = %d, Dead End = %d, TRoom = %d, Boss = %d \n", tStairs, tCorridors, deadEnd, tRooms, bossRooms); - // StructureTFStrongholdShield shield = new StructureTFStrongholdShield(shieldBox.minX - 1, shieldBox.minY, shieldBox.minZ - 1, shieldBox.maxX, shieldBox.maxY, shieldBox.maxZ); // list.add(shield); - + // add the upper stronghold - StructureTFStrongholdComponent accessChamber = new ComponentTFStrongholdAccessChamber(2, this.getCoordBaseMode(), boundingBox.minX + 8, boundingBox.minY + 7, boundingBox.minZ + 4); + StructureTFStrongholdComponent accessChamber = new ComponentTFStrongholdAccessChamber(getFeatureType(), 2, this.getCoordBaseMode(), boundingBox.minX + 8, boundingBox.minY + 7, boundingBox.minZ + 4); list.add(accessChamber); accessChamber.buildComponent(this, list, random); - + } - private boolean listContainsBossRoom(List list) { - for (StructureTFStrongholdComponent component : (List)list) - { - if (component instanceof ComponentTFStrongholdBossRoom) - { + private boolean listContainsBossRoom(List list) { + for (StructureComponent component : list) { + if (component instanceof ComponentTFStrongholdBossRoom) { return true; } } - + return false; } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -1, -1, 0, 18, 7, 18, facing); } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 17, 6, 17, rand, deco.randomBlocks); - int var8 = this.getXWithOffset(0, 0); - int var9 = this.getYWithOffset(0); - int var10 = this.getZWithOffset(0, 0); - - //System.out.println("Drawing STRONGHOLD entrance at " + var8 + ", " + var9 + ", " + var10); - // statues placeCornerStatue(world, 5, 1, 5, 0, sbb); placeCornerStatue(world, 5, 1, 12, 1, sbb); placeCornerStatue(world, 12, 1, 5, 2, sbb); placeCornerStatue(world, 12, 1, 12, 3, sbb); - + // statues - this.placeWallStatue(world, 9, 1, 16, 0, sbb); - this.placeWallStatue(world, 1, 1, 9, 1, sbb); - this.placeWallStatue(world, 8, 1, 1, 2, sbb); - this.placeWallStatue(world, 16, 1, 8, 3, sbb); - + this.placeWallStatue(world, 9, 1, 16, Rotation.NONE, sbb); + this.placeWallStatue(world, 1, 1, 9, Rotation.CLOCKWISE_90, sbb); + this.placeWallStatue(world, 8, 1, 1, Rotation.CLOCKWISE_180, sbb); + this.placeWallStatue(world, 16, 1, 8, Rotation.COUNTERCLOCKWISE_90, sbb); + // doors this.placeDoors(world, rand, sbb); diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdFoundry.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdFoundry.java index a2a7b4b82b..3598a1541a 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdFoundry.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdFoundry.java @@ -1,242 +1,193 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdFoundry extends StructureTFStrongholdComponent { - + int entranceLevel; public ComponentTFStrongholdFoundry() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdFoundry(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdFoundry(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("entranceLevel", this.entranceLevel); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("entranceLevel", this.entranceLevel); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.entranceLevel = par1NBTTagCompound.getInteger("entranceLevel"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.entranceLevel = tagCompound.getInteger("entranceLevel"); } @Override - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) { - if (y > 17) - { + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { + if (y > 17) { this.entranceLevel = 3; return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -20, 0, 18, 25, 18, facing); - } - else if (y < 11) - { + } else if (y < 11) { this.entranceLevel = 1; return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -6, 0, 18, 25, 18, facing); - } - else - { + } else { this.entranceLevel = 2; return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -13, 0, 18, 25, 18, facing); } } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - - switch (this.entranceLevel) - { - case 1: - this.addDoor(4, 6, 0); - addNewComponent(parent, list, random, 1, -1, 13, 13); - addNewComponent(parent, list, random, 3, 18, 13, 4); - addNewComponent(parent, list, random, 0, 13, 20, 18); - break; - case 2: - this.addDoor(4, 13, 0); - addNewComponent(parent, list, random, 1, -1, 6, 13); - addNewComponent(parent, list, random, 3, 18, 20, 4); - addNewComponent(parent, list, random, 0, 13, 13, 18); - break; - case 3: - this.addDoor(4, 20, 0); - addNewComponent(parent, list, random, 0, 13, 6, 18); - addNewComponent(parent, list, random, 1, -1, 13, 13); - addNewComponent(parent, list, random, 3, 18, 13, 4); + + switch (this.entranceLevel) { + case 1: + this.addDoor(4, 6, 0); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 13, 13); + addNewComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 18, 13, 4); + addNewComponent(parent, list, random, Rotation.NONE, 13, 20, 18); + break; + case 2: + this.addDoor(4, 13, 0); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 6, 13); + addNewComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 18, 20, 4); + addNewComponent(parent, list, random, Rotation.NONE, 13, 13, 18); + break; + case 3: + this.addDoor(4, 20, 0); + addNewComponent(parent, list, random, Rotation.NONE, 13, 6, 18); + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 13, 13); + addNewComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 18, 13, 4); } - + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 17, 25, 17, rand, deco.randomBlocks); - + // lava bottom - this.fillWithBlocks(world, sbb, 1, 0, 1, 16, 4, 16, Blocks.lava, Blocks.lava, false); - + this.fillWithBlocks(world, sbb, 1, 0, 1, 16, 4, 16, Blocks.LAVA.getDefaultState(), Blocks.LAVA.getDefaultState(), false); + // top ledge this.fillWithRandomizedBlocks(world, sbb, 1, 19, 1, 16, 19, 16, false, rand, deco.randomBlocks); - this.fillWithAir(world, sbb, 2, 19, 2, 15, 19, 15); - + this.fillWithAir(world, sbb, 2, 19, 2, 15, 19, 15); + // middle ledge this.fillWithRandomizedBlocks(world, sbb, 1, 12, 1, 16, 12, 16, false, rand, deco.randomBlocks); - this.fillWithAir(world, sbb, 2, 12, 2, 15, 12, 15); - + this.fillWithAir(world, sbb, 2, 12, 2, 15, 12, 15); + // bottom ledge this.fillWithRandomizedBlocks(world, sbb, 1, 5, 1, 16, 5, 16, false, rand, deco.randomBlocks); this.fillWithAir(world, sbb, 2, 5, 2, 15, 5, 15); - + // corner pillars this.fillWithRandomizedBlocks(world, sbb, 1, 1, 1, 1, 24, 2, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 2, 1, 1, 2, 24, 1, false, rand, deco.randomBlocks); - + this.fillWithRandomizedBlocks(world, sbb, 16, 1, 1, 16, 24, 2, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 15, 1, 1, 15, 24, 1, false, rand, deco.randomBlocks); - + this.fillWithRandomizedBlocks(world, sbb, 1, 1, 15, 1, 24, 16, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 2, 1, 16, 2, 24, 16, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 16, 1, 15, 16, 24, 16, false, rand, deco.randomBlocks); this.fillWithRandomizedBlocks(world, sbb, 15, 1, 16, 15, 24, 16, false, rand, deco.randomBlocks); - + // suspended mass Random massRandom = new Random(rand.nextLong()); - - for (int x = 4; x < 14; x++) - { - for (int z = 4; z < 14; z++) - { - for (int y = 8; y < 23; y++) - { + + for (int x = 4; x < 14; x++) { + for (int z = 4; z < 14; z++) { + for (int y = 8; y < 23; y++) { float c = Math.abs(x - 8.5F) + Math.abs(z - 8.5F) + Math.abs(y - 18F); float r = 5.5F + ((massRandom.nextFloat() - massRandom.nextFloat()) * 3.5F); - - if (c < r) - { - this.placeBlockAtCurrentPosition(world, Blocks.stone, 0, x, y, z, sbb); + + if (c < r) { + this.setBlockState(world, Blocks.STONE.getDefaultState(), x, y, z, sbb); } } } } - + // drips - for (int i = 0; i < 400; i++) - { + for (int i = 0; i < 400; i++) { int dx = massRandom.nextInt(9) + 5; int dz = massRandom.nextInt(9) + 5; int dy = massRandom.nextInt(13) + 10; - if (this.getBlockAtCurrentPosition(world, dx, dy, dz, sbb) != Blocks.air) - { - for (int y = 0; y < 3; y++) - { - this.placeBlockAtCurrentPosition(world, Blocks.stone, 0, dx, dy - y, dz, sbb); + if (this.getBlockStateFromPos(world, dx, dy, dz, sbb).getBlock() != Blocks.AIR) { + for (int y = 0; y < 3; y++) { + this.setBlockState(world, Blocks.STONE.getDefaultState(), dx, dy - y, dz, sbb); } } } - + // add some redstone ore - for (int i = 0; i < 8; i++) - { - Block blockID = Blocks.redstone_ore; - int blockMeta = 0; - - addOreToMass(world, sbb, massRandom, blockID, blockMeta); + for (int i = 0; i < 8; i++) { + addOreToMass(world, sbb, massRandom, Blocks.REDSTONE_ORE.getDefaultState()); } - + // add some iron ore - for (int i = 0; i < 8; i++) - { - Block blockID = Blocks.iron_ore; - int blockMeta = 0; - - addOreToMass(world, sbb, massRandom, blockID, blockMeta); + for (int i = 0; i < 8; i++) { + addOreToMass(world, sbb, massRandom, Blocks.IRON_ORE.getDefaultState()); } - + // add some gold ore - for (int i = 0; i < 6; i++) - { - Block blockID = Blocks.gold_ore; - int blockMeta = 0; - - addOreToMass(world, sbb, massRandom, blockID, blockMeta); + for (int i = 0; i < 6; i++) { + addOreToMass(world, sbb, massRandom, Blocks.GOLD_ORE.getDefaultState()); } - + // add some glowstone - for (int i = 0; i < 2; i++) - { - Block blockID = Blocks.glowstone; - int blockMeta = 0; - - addOreToMass(world, sbb, massRandom, blockID, blockMeta); + for (int i = 0; i < 2; i++) { + addOreToMass(world, sbb, massRandom, Blocks.GLOWSTONE.getDefaultState()); } - - + + // add some emerald ore - for (int i = 0; i < 2; i++) - { - Block blockID = Blocks.emerald_ore; - int blockMeta = 0; - - addOreToMass(world, sbb, massRandom, blockID, blockMeta); + for (int i = 0; i < 2; i++) { + addOreToMass(world, sbb, massRandom, Blocks.EMERALD_ORE.getDefaultState()); } - + // add some diamond ore - for (int i = 0; i < 4; i++) - { - Block blockID = Blocks.diamond_ore; - int blockMeta = 0; - - addOreToMass(world, sbb, massRandom, blockID, blockMeta); + for (int i = 0; i < 4; i++) { + addOreToMass(world, sbb, massRandom, Blocks.DIAMOND_ORE.getDefaultState()); } - + // doors placeDoors(world, rand, sbb); - + return true; } /** * Add a block of ore to the mass */ - private void addOreToMass(World world, StructureBoundingBox sbb, Random massRandom, Block blockID, int blockMeta) { - for (int i = 0; i < 10; i++) - { + private void addOreToMass(World world, StructureBoundingBox sbb, Random massRandom, IBlockState state) { + for (int i = 0; i < 10; i++) { int dx = massRandom.nextInt(9) + 5; int dz = massRandom.nextInt(9) + 5; int dy = massRandom.nextInt(13) + 10; - - if (this.getBlockAtCurrentPosition(world, dx, dy, dz, sbb) != Blocks.air) - { - this.placeBlockAtCurrentPosition(world, blockID, blockMeta, dx, dy, dz, sbb); + + if (this.getBlockStateFromPos(world, dx, dy, dz, sbb).getBlock() != Blocks.AIR) { + this.setBlockState(world, state, dx, dy, dz, sbb); // we have succeeded, stop looping break; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdLeftTurn.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdLeftTurn.java index 8daaba9469..4f298c9059 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdLeftTurn.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdLeftTurn.java @@ -1,69 +1,61 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdLeftTurn extends StructureTFStrongholdComponent { public ComponentTFStrongholdLeftTurn() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdLeftTurn(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdLeftTurn(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 9, 7, 9, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // entrance this.addDoor(4, 1, 0); - + // make a random component to the left - addNewComponent(parent, list, random, 3, 9, 1, 4); - + addNewComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 9, 1, 4); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 8, 6, 8, rand, deco.randomBlocks); // clear inside fillWithAir(world, sbb, 1, 1, 1, 7, 5, 7); - + // // entrance doorway // placeDoorwayAt(world, rand, 2, 4, 1, 0, sbb); // // // left turn doorway // placeDoorwayAt(world, rand, 1, 8, 1, 4, sbb); - + // statue placeCornerStatue(world, 2, 1, 6, 1, sbb); - + // doors placeDoors(world, rand, sbb); - + return true; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdRightTurn.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdRightTurn.java index 2af7a8b8e0..606a21ed61 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdRightTurn.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdRightTurn.java @@ -1,69 +1,61 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdRightTurn extends StructureTFStrongholdComponent { public ComponentTFStrongholdRightTurn() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdRightTurn(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdRightTurn(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 9, 7, 9, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + // entrance this.addDoor(4, 1, 0); // make a random component to the right - addNewComponent(parent, list, random, 1, -1, 1, 4); - + addNewComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 1, 4); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 8, 6, 8, rand, deco.randomBlocks); // clear inside fillWithAir(world, sbb, 1, 1, 1, 7, 5, 7); - + // // entrance doorway // placeDoorwayAt(world, rand, 2, 4, 1, 0, sbb); // // // right turn doorway // placeDoorwayAt(world, rand, 1, 0, 1, 4, sbb); - + // statue placeCornerStatue(world, 6, 1, 6, 3, sbb); - + // doors placeDoors(world, rand, sbb); - + return true; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallHallway.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallHallway.java index c09d9a205e..f05fdb94fa 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallHallway.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallHallway.java @@ -1,62 +1,53 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdSmallHallway extends StructureTFStrongholdComponent { public ComponentTFStrongholdSmallHallway() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdSmallHallway(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdSmallHallway(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 9, 7, 18, facing); } - - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + // entrance this.addDoor(4, 1, 0); // make a random component at the end - addNewComponent(parent, list, random, 0, 4, 1, 18); - + addNewComponent(parent, list, random, Rotation.NONE, 4, 1, 18); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 8, 6, 17, rand, deco.randomBlocks); // statues - this.placeWallStatue(world, 1, 1, 9, 1, sbb); - this.placeWallStatue(world, 7, 1, 9, 3, sbb); - + this.placeWallStatue(world, 1, 1, 9, Rotation.CLOCKWISE_90, sbb); + this.placeWallStatue(world, 7, 1, 9, Rotation.COUNTERCLOCKWISE_90, sbb); + // doors placeDoors(world, rand, sbb); - + return true; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallStairs.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallStairs.java index 1d2b0658f9..fba6fac405 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallStairs.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdSmallStairs.java @@ -1,163 +1,131 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockStairs; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; -public class ComponentTFStrongholdSmallStairs extends - StructureTFStrongholdComponent { +import java.util.List; +import java.util.Random; + +public class ComponentTFStrongholdSmallStairs extends StructureTFStrongholdComponent { private boolean enterBottom; public boolean hasTreasure; public boolean chestTrapped; public ComponentTFStrongholdSmallStairs() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdSmallStairs(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdSmallStairs(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("enterBottom", this.enterBottom); - par1NBTTagCompound.setBoolean("hasTreasure", this.hasTreasure); - par1NBTTagCompound.setBoolean("chestTrapped", this.chestTrapped); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("enterBottom", this.enterBottom); + tagCompound.setBoolean("hasTreasure", this.hasTreasure); + tagCompound.setBoolean("chestTrapped", this.chestTrapped); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.enterBottom = par1NBTTagCompound.getBoolean("enterBottom"); - this.hasTreasure = par1NBTTagCompound.getBoolean("hasTreasure"); - this.chestTrapped = par1NBTTagCompound.getBoolean("chestTrapped"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.enterBottom = tagCompound.getBoolean("enterBottom"); + this.hasTreasure = tagCompound.getBoolean("hasTreasure"); + this.chestTrapped = tagCompound.getBoolean("chestTrapped"); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { - - if (y > 17) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { + + if (y > 17) { this.enterBottom = false; - } - else if (y < 11) - { + } else if (y < 11) { this.enterBottom = true; - } - else - { + } else { this.enterBottom = (z & 1) == 0; } - - if (enterBottom) - { + + if (enterBottom) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 9, 14, 9, facing); - } - else - { + } else { // enter on the top return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -4, -8, 0, 9, 14, 9, facing); } } - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - - if (this.enterBottom) - { + + if (this.enterBottom) { this.addDoor(4, 1, 0); - addNewComponent(parent, list, random, 0, 4, 8, 9); - } - else - { + addNewComponent(parent, list, random, Rotation.NONE, 4, 8, 9); + } else { this.addDoor(4, 8, 0); - addNewComponent(parent, list, random, 0, 4, 1, 9); + addNewComponent(parent, list, random, Rotation.NONE, 4, 1, 9); } - + this.hasTreasure = random.nextBoolean(); this.chestTrapped = random.nextInt(3) == 0; } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 8, 13, 8, rand, deco.randomBlocks); - + // railing - this.fillWithMetadataBlocks(world, sbb, 1, 7, 1, 7, 7, 7, deco.platformID, deco.platformMeta, Blocks.air, 0, false); + this.fillWithBlocks(world, sbb, 1, 7, 1, 7, 7, 7, deco.platformState, Blocks.AIR.getDefaultState(), false); this.fillWithAir(world, sbb, 2, 7, 2, 6, 7, 6); - - int rotation = this.enterBottom ? 0 : 2; - + + Rotation rotation = this.enterBottom ? Rotation.NONE : Rotation.CLOCKWISE_180; + // stairs - for (int y = 1; y < 8; y++) - { - for (int x = 3; x < 6; x++) - { - this.placeBlockRotated(world, Blocks.air, 0, x, y + 1, y, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation),x, y, y, rotation, sbb); - this.placeBlockRotated(world, deco.blockID, deco.blockMeta, x, y - 1, y, rotation, sbb); + for (int y = 1; y < 8; y++) { + for (int x = 3; x < 6; x++) { + this.setBlockStateRotated(world, Blocks.AIR.getDefaultState(), x, y + 1, y, rotation, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.NORTH), x, y, y, rotation, sbb); + this.setBlockStateRotated(world, deco.blockState, x, y - 1, y, rotation, sbb); } } - + // treasure - if (this.hasTreasure) - { + if (this.hasTreasure) { this.placeTreasureRotated(world, 4, 1, 6, rotation, TFTreasure.stronghold_cache, this.chestTrapped, sbb); - - if (this.chestTrapped) - { - this.placeBlockRotated(world, Blocks.tnt, 0, 4, 0, 6, rotation, sbb); + + if (this.chestTrapped) { + this.setBlockStateRotated(world, Blocks.TNT.getDefaultState(), 4, 0, 6, rotation, sbb); } - for (int z = 5; z < 8; z++) - { - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), 3, 1, z, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(2 + rotation), 5, 1, z, rotation, sbb); + for (int z = 5; z < 8; z++) { + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.WEST), 3, 1, z, rotation, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.EAST), 5, 1, z, rotation, sbb); } - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation), 4, 1, 5, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 4, 1, 7, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation), 4, 2, 6, rotation, sbb); - } - - if (enterBottom) - { - this.placeWallStatue(world, 4, 8, 1, 2, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.NORTH), 4, 1, 5, rotation, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.SOUTH), 4, 1, 7, rotation, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.NORTH), 4, 2, 6, rotation, sbb); } - else - { - this.placeWallStatue(world, 4, 8, 7, 0, sbb); + + if (enterBottom) { + this.placeWallStatue(world, 4, 8, 1, Rotation.CLOCKWISE_180, sbb); + } else { + this.placeWallStatue(world, 4, 8, 7, Rotation.NONE, sbb); } - + // doors placeDoors(world, rand, sbb); - + return true; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTrainingRoom.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTrainingRoom.java index 07a5121e14..e1a7d2846c 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTrainingRoom.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTrainingRoom.java @@ -1,91 +1,85 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.BlockPumpkin; import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdTrainingRoom extends StructureTFStrongholdComponent { public ComponentTFStrongholdTrainingRoom() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdTrainingRoom(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdTrainingRoom(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -13, -1, 0, 18, 7, 18, facing); } - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + this.addDoor(13, 1, 0); - addNewComponent(parent, list, random, 0, 4, 1, 18); + addNewComponent(parent, list, random, Rotation.NONE, 4, 1, 18); } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 17, 6, 17, rand, deco.randomBlocks); - + // statues placeCornerStatue(world, 2, 1, 2, 0, sbb); placeCornerStatue(world, 15, 1, 15, 3, sbb); // sand floor - this.randomlyFillWithBlocks(world, sbb, rand, 0.7F, 4, 0, 4, 8, 0, 8, Blocks.sand, Blocks.sand, false); - this.randomlyFillWithBlocks(world, sbb, rand, 0.7F, 9, 0, 4, 13, 0, 8, Blocks.sand, Blocks.sand, false); - this.randomlyFillWithBlocks(world, sbb, rand, 0.7F, 9, 0, 9, 13, 0, 13, Blocks.sand, Blocks.sand, false); - + this.generateMaybeBox(world, sbb, rand, 0.7F, 4, 0, 4, 8, 0, 8, Blocks.SAND.getDefaultState(), Blocks.SAND.getDefaultState(), false, 0); + this.generateMaybeBox(world, sbb, rand, 0.7F, 9, 0, 4, 13, 0, 8, Blocks.SAND.getDefaultState(), Blocks.SAND.getDefaultState(), false, 0); + this.generateMaybeBox(world, sbb, rand, 0.7F, 9, 0, 9, 13, 0, 13, Blocks.SAND.getDefaultState(), Blocks.SAND.getDefaultState(), false, 0); + // training dummies - placeTrainingDummy(world, sbb, 0); - placeTrainingDummy(world, sbb, 1); - placeTrainingDummy(world, sbb, 2); - + placeTrainingDummy(world, sbb, Rotation.NONE); + placeTrainingDummy(world, sbb, Rotation.CLOCKWISE_90); + placeTrainingDummy(world, sbb, Rotation.CLOCKWISE_180); + // anvil pad - this.fillWithBlocks(world, sbb, 5, 0, 10, 7, 0, 12, Blocks.cobblestone, Blocks.cobblestone, false); - - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, 5, 1, 12, sbb); - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, 5, 2, 12, sbb); - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, 6, 1, 12, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2), 6, 2, 12, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2), 7, 1, 12, sbb); - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, 5, 1, 11, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1), 5, 2, 11, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1), 5, 1, 10, sbb); - - this.placeBlockAtCurrentPosition(world, Blocks.anvil, 0, 6, 1, 11, sbb); + this.fillWithBlocks(world, sbb, 5, 0, 10, 7, 0, 12, Blocks.COBBLESTONE.getDefaultState(), Blocks.COBBLESTONE.getDefaultState(), false); + + this.setBlockState(world, deco.pillarState, 5, 1, 12, sbb); + this.setBlockState(world, deco.pillarState, 5, 2, 12, sbb); + this.setBlockState(world, deco.pillarState, 6, 1, 12, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockPumpkin.FACING, EnumFacing.EAST), 6, 2, 12, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockPumpkin.FACING, EnumFacing.EAST), 7, 1, 12, sbb); + this.setBlockState(world, deco.pillarState, 5, 1, 11, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockPumpkin.FACING, EnumFacing.NORTH), 5, 2, 11, sbb); + this.setBlockState(world, deco.stairState.withProperty(BlockPumpkin.FACING, EnumFacing.NORTH), 5, 1, 10, sbb); + + this.setBlockState(world, Blocks.ANVIL.getDefaultState(), 6, 1, 11, sbb); // doors placeDoors(world, rand, sbb); - + return true; } - private void placeTrainingDummy(World world, StructureBoundingBox sbb, int rotation) { - this.fillBlocksRotated(world, sbb, 5, 0, 5, 7, 0, 7, Blocks.sand, 0, rotation); - this.placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 6, 1, 6, rotation, sbb); - this.placeBlockRotated(world, Blocks.planks, 2, 6, 2, 6, rotation, sbb); - this.placeBlockRotated(world, Blocks.fence, 0, 5, 2, 6, rotation, sbb); - this.placeBlockRotated(world, Blocks.fence, 0, 7, 2, 6, rotation, sbb); - this.placeBlockRotated(world, Blocks.pumpkin, this.getStairMeta(0 + rotation), 6, 3, 6, rotation, sbb); + private void placeTrainingDummy(World world, StructureBoundingBox sbb, Rotation rotation) { + this.fillBlocksRotated(world, sbb, 5, 0, 5, 7, 0, 7, Blocks.SAND.getDefaultState(), rotation); + this.setBlockStateRotated(world, deco.fenceState, 6, 1, 6, rotation, sbb); + this.setBlockStateRotated(world, Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, BlockPlanks.EnumType.BIRCH), 6, 2, 6, rotation, sbb); + this.setBlockStateRotated(world, Blocks.OAK_FENCE.getDefaultState(), 5, 2, 6, rotation, sbb); + this.setBlockStateRotated(world, Blocks.OAK_FENCE.getDefaultState(), 7, 2, 6, rotation, sbb); + this.setBlockStateRotated(world, Blocks.PUMPKIN.getDefaultState().withProperty(BlockPumpkin.FACING, getStructureRelativeRotation(rotation)), 6, 3, 6, rotation, sbb); } } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureCorridor.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureCorridor.java index 69a979976a..963bb6bad0 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureCorridor.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureCorridor.java @@ -1,80 +1,73 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockStairs; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdTreasureCorridor extends StructureTFStrongholdComponent { public ComponentTFStrongholdTreasureCorridor() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdTreasureCorridor(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdTreasureCorridor(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureTFStrongholdComponent.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 9, 7, 27, facing); } - - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + // entrance this.addDoor(4, 1, 0); // make a random component at the end - addNewComponent(parent, list, random, 0, 4, 1, 27); - + addNewComponent(parent, list, random, Rotation.NONE, 4, 1, 27); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 8, 6, 26, rand, deco.randomBlocks); // statues - this.placeWallStatue(world, 1, 1, 9, 1, sbb); - this.placeWallStatue(world, 1, 1, 17, 1, sbb); - this.placeWallStatue(world, 7, 1, 9, 3, sbb); - this.placeWallStatue(world, 7, 1, 17, 3, sbb); - - int rotation = (this.boundingBox.minX ^ this.boundingBox.minZ) % 2 == 0 ? 0 : 2; - + this.placeWallStatue(world, 1, 1, 9, Rotation.CLOCKWISE_90, sbb); + this.placeWallStatue(world, 1, 1, 17, Rotation.CLOCKWISE_90, sbb); + this.placeWallStatue(world, 7, 1, 9, Rotation.COUNTERCLOCKWISE_90, sbb); + this.placeWallStatue(world, 7, 1, 17, Rotation.COUNTERCLOCKWISE_90, sbb); + + Rotation rotation = (this.boundingBox.minX ^ this.boundingBox.minZ) % 2 == 0 ? Rotation.NONE : Rotation.CLOCKWISE_180; + // treasure! this.placeTreasureRotated(world, 8, 2, 13, rotation, TFTreasure.stronghold_cache, sbb); - + // niche! - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation) + 4, 8, 3, 12, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation) + 4, 8, 3, 13, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation) + 4, 8, 3, 14, rotation, sbb); - this.placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 8, 2, 12, rotation, sbb); - this.placeBlockRotated(world, deco.fenceID, deco.fenceMeta, 8, 2, 14, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(1 + rotation), 7, 1, 12, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(0 + rotation), 7, 1, 13, rotation, sbb); - this.placeBlockRotated(world, deco.stairID, this.getStairMeta(3 + rotation), 7, 1, 14, rotation, sbb); + + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.SOUTH, rotation, true), 8, 3, 12, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.WEST, rotation, true), 8, 3, 13, rotation, sbb); + this.setBlockStateRotated(world, getStairState(deco.stairState, EnumFacing.NORTH, rotation, true), 8, 3, 14, rotation, sbb); + this.setBlockStateRotated(world, deco.fenceState, 8, 2, 12, rotation, sbb); + this.setBlockStateRotated(world, deco.fenceState, 8, 2, 14, rotation, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.SOUTH), 7, 1, 12, rotation, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.WEST), 7, 1, 13, rotation, sbb); + this.setBlockStateRotated(world, deco.stairState.withProperty(BlockStairs.FACING, EnumFacing.NORTH), 7, 1, 14, rotation, sbb); // doors placeDoors(world, rand, sbb); - + return true; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureRoom.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureRoom.java index 0e159c2347..a75bd2cc0d 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureRoom.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdTreasureRoom.java @@ -1,65 +1,53 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; -import twilightforest.entity.TFCreatures; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.util.TFEntityNames; -public class ComponentTFStrongholdTreasureRoom extends - StructureTFStrongholdComponent { +import java.util.List; +import java.util.Random; + +public class ComponentTFStrongholdTreasureRoom extends StructureTFStrongholdComponent { private boolean enterBottom; public ComponentTFStrongholdTreasureRoom() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdTreasureRoom(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); - // TODO Auto-generated constructor stub + public ComponentTFStrongholdTreasureRoom(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("enterBottom", this.enterBottom); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("enterBottom", this.enterBottom); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.enterBottom = par1NBTTagCompound.getBoolean("enterBottom"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.enterBottom = tagCompound.getBoolean("enterBottom"); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -4, -1, 0, 9, 7, 18, facing); } - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); - + this.addDoor(4, 1, 0); } @@ -69,43 +57,41 @@ public void buildComponent(StructureComponent parent, List list, Random random) @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { placeStrongholdWalls(world, sbb, 0, 0, 0, 8, 6, 17, rand, deco.randomBlocks); - + // statues - this.placeWallStatue(world, 1, 1, 4, 1, sbb); - this.placeWallStatue(world, 1, 1, 13, 1, sbb); - this.placeWallStatue(world, 7, 1, 4, 3, sbb); - this.placeWallStatue(world, 7, 1, 13, 3, sbb); - this.placeWallStatue(world, 4, 1, 16, 0, sbb); - + this.placeWallStatue(world, 1, 1, 4, Rotation.CLOCKWISE_90, sbb); + this.placeWallStatue(world, 1, 1, 13, Rotation.CLOCKWISE_90, sbb); + this.placeWallStatue(world, 7, 1, 4, Rotation.COUNTERCLOCKWISE_90, sbb); + this.placeWallStatue(world, 7, 1, 13, Rotation.COUNTERCLOCKWISE_90, sbb); + this.placeWallStatue(world, 4, 1, 16, Rotation.NONE, sbb); + this.fillWithRandomizedBlocks(world, sbb, 1, 1, 8, 7, 5, 9, false, rand, deco.randomBlocks); - this.fillWithBlocks(world, sbb, 3, 1, 8, 5, 4, 9, Blocks.iron_bars, Blocks.iron_bars, false); - + this.fillWithBlocks(world, sbb, 3, 1, 8, 5, 4, 9, Blocks.IRON_BARS.getDefaultState(), Blocks.IRON_BARS.getDefaultState(), false); + // spawnwers - this.placeSpawnerAtCurrentPosition(world, rand, 4, 1, 4, TFCreatures.getSpawnerNameFor("Helmet Crab"), sbb); - - this.placeSpawnerAtCurrentPosition(world, rand, 4, 4, 15, TFCreatures.getSpawnerNameFor("Helmet Crab"), sbb); - + this.setSpawner(world, 4, 1, 4, sbb, TFEntityNames.HELMET_CRAB); + + this.setSpawner(world, 4, 4, 15, sbb, TFEntityNames.HELMET_CRAB); + // treasure! this.placeTreasureAtCurrentPosition(world, rand, 2, 4, 13, TFTreasure.stronghold_room, sbb); this.placeTreasureAtCurrentPosition(world, rand, 6, 4, 13, TFTreasure.stronghold_room, sbb); - + // doors placeDoors(world, rand, sbb); - + return true; } - + /** * Make a doorway */ + @Override protected void placeDoorwayAt(World world, Random rand, int x, int y, int z, StructureBoundingBox sbb) { - if (x == 0 || x == getXSize()) - { - this.fillWithMetadataBlocks(world, sbb, x, y, z - 1, x, y + 3, z + 1, Blocks.iron_bars, 0, Blocks.air, 0, false); - } - else - { - this.fillWithMetadataBlocks(world, sbb, x - 1, y, z, x + 1, y + 3, z, Blocks.iron_bars, 0, Blocks.air, 0, false); + if (x == 0 || x == getXSize()) { + this.fillWithBlocks(world, sbb, x, y, z - 1, x, y + 3, z + 1, Blocks.IRON_BARS.getDefaultState(), Blocks.AIR.getDefaultState(), false); + } else { + this.fillWithBlocks(world, sbb, x - 1, y, z, x + 1, y + 3, z, Blocks.IRON_BARS.getDefaultState(), Blocks.AIR.getDefaultState(), false); } } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperAscender.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperAscender.java index 22382b4342..ff664ca9d0 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperAscender.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperAscender.java @@ -1,148 +1,120 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.block.BlockStairs; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdUpperAscender extends StructureTFStrongholdComponent { - + boolean exitTop; public ComponentTFStrongholdUpperAscender() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdUpperAscender(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdUpperAscender(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("exitTop", this.exitTop); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("exitTop", this.exitTop); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.exitTop = par1NBTTagCompound.getBoolean("exitTop"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.exitTop = tagCompound.getBoolean("exitTop"); } - - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { - if (y < 36) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { + if (y < 36) { this.exitTop = true; return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -2, -1, 0, 5, 10, 10, facing); - } - else - { + } else { this.exitTop = false; return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -2, -6, 0, 5, 10, 10, facing); } } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // make a random component on the other side - addNewUpperComponent(parent, list, random, 0, 2, exitTop ? 6 : 1, 10); + addNewUpperComponent(parent, list, random, Rotation.NONE, 2, exitTop ? 6 : 1, 10); } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isLiquidInStructureBoundingBox(world, sbb)) - { - return false; - } - else - { - placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 9, 9, rand, deco.randomBlocks); - - // entrance doorway - placeSmallDoorwayAt(world, rand, 2, 2, exitTop ? 1 : 6, 0, sbb); - - // exit doorway - placeSmallDoorwayAt(world, rand, 0, 2, exitTop ? 6 : 1, 9, sbb); - - // steps! - if (exitTop) - { - makeStairsAt(world, 1, 3, 1, sbb); - makeStairsAt(world, 2, 4, 1, sbb); - makeStairsAt(world, 3, 5, 1, sbb); - makeStairsAt(world, 4, 6, 1, sbb); - makeStairsAt(world, 5, 7, 1, sbb); - makePlatformAt(world, 5, 8, sbb); - } - else - { - makeStairsAt(world, 1, 6, 3, sbb); - makeStairsAt(world, 2, 5, 3, sbb); - makeStairsAt(world, 3, 4, 3, sbb); - makeStairsAt(world, 4, 3, 3, sbb); - makeStairsAt(world, 5, 2, 3, sbb); - makePlatformAt(world, 5, 1, sbb); - } - return true; - } + if (this.isLiquidInStructureBoundingBox(world, sbb)) { + return false; + } else { + placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 9, 9, rand, deco.randomBlocks); + + // entrance doorway + placeSmallDoorwayAt(world, rand, 2, 2, exitTop ? 1 : 6, 0, sbb); + + // exit doorway + placeSmallDoorwayAt(world, rand, 0, 2, exitTop ? 6 : 1, 9, sbb); + + // steps! + if (exitTop) { + makeStairsAt(world, 1, 3, EnumFacing.NORTH, sbb); + makeStairsAt(world, 2, 4, EnumFacing.NORTH, sbb); + makeStairsAt(world, 3, 5, EnumFacing.NORTH, sbb); + makeStairsAt(world, 4, 6, EnumFacing.NORTH, sbb); + makeStairsAt(world, 5, 7, EnumFacing.NORTH, sbb); + makePlatformAt(world, 5, 8, sbb); + } else { + makeStairsAt(world, 1, 6, EnumFacing.NORTH, sbb); + makeStairsAt(world, 2, 5, EnumFacing.NORTH, sbb); + makeStairsAt(world, 3, 4, EnumFacing.NORTH, sbb); + makeStairsAt(world, 4, 3, EnumFacing.NORTH, sbb); + makeStairsAt(world, 5, 2, EnumFacing.NORTH, sbb); + makePlatformAt(world, 5, 1, sbb); + } + return true; + } } /** * Check if we can find at least one wall, and if so, generate stairs */ - private void makeStairsAt(World world, int y, int z, int facing, StructureBoundingBox sbb) { + private void makeStairsAt(World world, int y, int z, EnumFacing facing, StructureBoundingBox sbb) { // check walls - if (this.getBlockAtCurrentPosition(world, 0, y, z, sbb) != Blocks.air || this.getBlockAtCurrentPosition(world, 4, y, z, sbb) != Blocks.air) - { - for (int x = 1; x < 4; x++) - { - this.placeBlockAtCurrentPosition(world, Blocks.stone_brick_stairs, this.getStairMeta(facing), x, y, z, sbb); + if (this.getBlockStateFromPos(world, 0, y, z, sbb).getBlock() != Blocks.AIR || this.getBlockStateFromPos(world, 4, y, z, sbb).getBlock() != Blocks.AIR) { + for (int x = 1; x < 4; x++) { + this.setBlockState(world, Blocks.STONE_BRICK_STAIRS.getDefaultState().withProperty(BlockStairs.FACING, facing), x, y, z, sbb); } } } - + /** * Check if we can find at least one wall, and if so, generate blocks */ private void makePlatformAt(World world, int y, int z, StructureBoundingBox sbb) { // check walls - if (this.getBlockAtCurrentPosition(world, 0, y, z, sbb) != Blocks.air || this.getBlockAtCurrentPosition(world, 4, y, z, sbb) != Blocks.air) - { - for (int x = 1; x < 4; x++) - { - this.placeBlockAtCurrentPosition(world, Blocks.stonebrick, 0, x, y, z, sbb); + if (this.getBlockStateFromPos(world, 0, y, z, sbb).getBlock() != Blocks.AIR || this.getBlockStateFromPos(world, 4, y, z, sbb).getBlock() != Blocks.AIR) { + for (int x = 1; x < 4; x++) { + this.setBlockState(world, Blocks.STONEBRICK.getDefaultState(), x, y, z, sbb); } } } - /** - * Does this component fall under block protection when progression is turned on, normally true - */ + @Override public boolean isComponentProtected() { return false; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperCorridor.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperCorridor.java index 16f2a08d72..3e718f98ff 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperCorridor.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperCorridor.java @@ -1,71 +1,57 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdUpperCorridor extends StructureTFStrongholdComponent { public ComponentTFStrongholdUpperCorridor() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdUpperCorridor(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdUpperCorridor(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -2, -1, 0, 5, 5, 9, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // make a random component at the end - addNewUpperComponent(parent, list, random, 0, 2, 1, 9); - + addNewUpperComponent(parent, list, random, Rotation.NONE, 2, 1, 9); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isLiquidInStructureBoundingBox(world, sbb)) - { - return false; - } - else - { - placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 8, rand, deco.randomBlocks); + if (this.isLiquidInStructureBoundingBox(world, sbb)) { + return false; + } else { + placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 8, rand, deco.randomBlocks); - // entrance doorway - placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); + // entrance doorway + placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); - // end - placeSmallDoorwayAt(world, rand, 2, 2, 1, 8, sbb); + // end + placeSmallDoorwayAt(world, rand, 2, 2, 1, 8, sbb); - return true; - } + return true; + } } - - /** - * Does this component fall under block protection when progression is turned on, normally true - */ + @Override public boolean isComponentProtected() { return false; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperLeftTurn.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperLeftTurn.java index c76a63d6fd..851cfb1082 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperLeftTurn.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperLeftTurn.java @@ -1,71 +1,57 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdUpperLeftTurn extends StructureTFStrongholdComponent { public ComponentTFStrongholdUpperLeftTurn() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdUpperLeftTurn(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdUpperLeftTurn(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -2, -1, 0, 5, 5, 5, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // make a random component to the left - addNewUpperComponent(parent, list, random, 3, 5, 1, 2); - + addNewUpperComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 5, 1, 2); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isLiquidInStructureBoundingBox(world, sbb)) - { - return false; - } - else - { - placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 4, rand, deco.randomBlocks); + if (this.isLiquidInStructureBoundingBox(world, sbb)) { + return false; + } else { + placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 4, rand, deco.randomBlocks); - // entrance doorway - placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); + // entrance doorway + placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); - // left turn doorway - placeSmallDoorwayAt(world, rand, 3, 4, 1, 2, sbb); + // left turn doorway + placeSmallDoorwayAt(world, rand, 3, 4, 1, 2, sbb); - return true; - } + return true; + } } - - /** - * Does this component fall under block protection when progression is turned on, normally true - */ + @Override public boolean isComponentProtected() { return false; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperRightTurn.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperRightTurn.java index f5cb533d72..ff930de6ee 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperRightTurn.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperRightTurn.java @@ -1,70 +1,57 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdUpperRightTurn extends StructureTFStrongholdComponent { public ComponentTFStrongholdUpperRightTurn() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdUpperRightTurn(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdUpperRightTurn(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -2, -1, 0, 5, 5, 5, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // make a random component to the right - addNewUpperComponent(parent, list, random, 1, -1, 1, 2); - + addNewUpperComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 1, 2); + } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isLiquidInStructureBoundingBox(world, sbb)) - { - return false; - } - else - { - placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 4, rand, deco.randomBlocks); - - // entrance doorway - placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); - - // right turn doorway - placeSmallDoorwayAt(world, rand, 1, 0, 1, 2, sbb); - - return true; - } + if (this.isLiquidInStructureBoundingBox(world, sbb)) { + return false; + } else { + placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 4, rand, deco.randomBlocks); + + // entrance doorway + placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); + + // right turn doorway + placeSmallDoorwayAt(world, rand, 1, 0, 1, 2, sbb); + + return true; + } } - /** - * Does this component fall under block protection when progression is turned on, normally true - */ + @Override public boolean isComponentProtected() { return false; } diff --git a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperTIntersection.java b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperTIntersection.java index 10b4bf3794..69109d2693 100644 --- a/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperTIntersection.java +++ b/src/main/java/twilightforest/structures/stronghold/ComponentTFStrongholdUpperTIntersection.java @@ -1,76 +1,62 @@ package twilightforest.structures.stronghold; -import java.util.List; -import java.util.Random; - +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; + +import java.util.List; +import java.util.Random; public class ComponentTFStrongholdUpperTIntersection extends StructureTFStrongholdComponent { public ComponentTFStrongholdUpperTIntersection() { - super(); - // TODO Auto-generated constructor stub } - public ComponentTFStrongholdUpperTIntersection(int i, int facing, int x, int y, int z) { - super(i, facing, x, y, z); + public ComponentTFStrongholdUpperTIntersection(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i, facing, x, y, z); } - /** - * Make a bounding box for this room - */ - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) - { + @Override + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return StructureBoundingBox.getComponentToAddBoundingBox(x, y, z, -2, -1, 0, 5, 5, 5, facing); } - - /** - * Initiates construction of the Structure Component picked, at the current Location of StructGen - */ + @Override - public void buildComponent(StructureComponent parent, List list, Random random) { + public void buildComponent(StructureComponent parent, List list, Random random) { super.buildComponent(parent, list, random); // make a random component to the left - addNewUpperComponent(parent, list, random, 3, 5, 1, 2); + addNewUpperComponent(parent, list, random, Rotation.COUNTERCLOCKWISE_90, 5, 1, 2); // make a random component to the right - addNewUpperComponent(parent, list, random, 1, -1, 1, 2); + addNewUpperComponent(parent, list, random, Rotation.CLOCKWISE_90, -1, 1, 2); } - /** - * Generate the blocks that go here - */ @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isLiquidInStructureBoundingBox(world, sbb)) - { - return false; - } - else - { - placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 4, rand, deco.randomBlocks); + if (this.isLiquidInStructureBoundingBox(world, sbb)) { + return false; + } else { + placeUpperStrongholdWalls(world, sbb, 0, 0, 0, 4, 4, 4, rand, deco.randomBlocks); - // entrance doorway - placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); + // entrance doorway + placeSmallDoorwayAt(world, rand, 2, 2, 1, 0, sbb); - // left turn doorway - placeSmallDoorwayAt(world, rand, 3, 4, 1, 2, sbb); + // left turn doorway + placeSmallDoorwayAt(world, rand, 3, 4, 1, 2, sbb); - // right turn doorway - placeSmallDoorwayAt(world, rand, 1, 0, 1, 2, sbb); + // right turn doorway + placeSmallDoorwayAt(world, rand, 1, 0, 1, 2, sbb); - return true; - } + return true; + } } - - /** - * Does this component fall under block protection when progression is turned on, normally true - */ + @Override public boolean isComponentProtected() { return false; } diff --git a/src/main/java/twilightforest/structures/stronghold/StructureTFDecoratorStronghold.java b/src/main/java/twilightforest/structures/stronghold/StructureTFDecoratorStronghold.java index 9c0145edac..ebe62aee87 100644 --- a/src/main/java/twilightforest/structures/stronghold/StructureTFDecoratorStronghold.java +++ b/src/main/java/twilightforest/structures/stronghold/StructureTFDecoratorStronghold.java @@ -1,30 +1,25 @@ package twilightforest.structures.stronghold; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.BlockStoneBrick; +import net.minecraft.block.BlockStoneSlab; import net.minecraft.init.Blocks; +import twilightforest.block.BlockTFUnderBrick; import twilightforest.block.TFBlocks; +import twilightforest.enums.UnderBrickVariant; import twilightforest.structures.StructureTFDecorator; public class StructureTFDecoratorStronghold extends StructureTFDecorator { - - public StructureTFDecoratorStronghold() - { - this.blockID = TFBlocks.underBrick; - this.blockMeta = 0; - - this.accentID = TFBlocks.underBrick; - this.accentMeta = 3; - - this.fenceID = Blocks.cobblestone_wall; - - this.stairID = Blocks.stone_brick_stairs; - - this.pillarID = Blocks.stonebrick; - this.pillarMeta = 1; - - this.platformID = Blocks.stone_slab; - this.platformMeta = 5 + 8; + public StructureTFDecoratorStronghold() { + this.blockState = TFBlocks.underbrick.getDefaultState(); + this.accentState = TFBlocks.underbrick.getDefaultState().withProperty(BlockTFUnderBrick.VARIANT, UnderBrickVariant.CRACKED); + this.fenceState = Blocks.COBBLESTONE_WALL.getDefaultState(); + this.stairState = Blocks.STONE_BRICK_STAIRS.getDefaultState(); + this.pillarState = Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.MOSSY); + this.platformState = Blocks.STONE_SLAB.getDefaultState().withProperty(BlockStoneSlab.VARIANT, BlockStoneSlab.EnumType.SMOOTHBRICK) + .withProperty(BlockStoneSlab.HALF, BlockSlab.EnumBlockHalf.TOP); this.randomBlocks = new StructureTFKnightStones(); } } diff --git a/src/main/java/twilightforest/structures/stronghold/StructureTFKnightStones.java b/src/main/java/twilightforest/structures/stronghold/StructureTFKnightStones.java index 936ae4c6ec..9dbd69e89d 100644 --- a/src/main/java/twilightforest/structures/stronghold/StructureTFKnightStones.java +++ b/src/main/java/twilightforest/structures/stronghold/StructureTFKnightStones.java @@ -1,38 +1,30 @@ package twilightforest.structures.stronghold; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.block.BlockTFUnderBrick; import twilightforest.block.TFBlocks; +import twilightforest.enums.UnderBrickVariant; + +import java.util.Random; public class StructureTFKnightStones extends StructureComponent.BlockSelector { @Override - public void selectBlocks(Random par1Random, int par2, int par3, int par4, boolean par5) { - if (!par5) - { - this.field_151562_a = Blocks.air; - this.selectedBlockMetaData = 0; - } - else - { - this.field_151562_a = TFBlocks.underBrick; - float var6 = par1Random.nextFloat(); + public void selectBlocks(Random random, int x, int y, int z, boolean edge) { + if (!edge) { + this.blockstate = Blocks.AIR.getDefaultState(); + } else { + float f = random.nextFloat(); - if (var6 < 0.2F) - { - this.selectedBlockMetaData = 2; - } - else if (var6 < 0.5F) - { - this.selectedBlockMetaData = 1; - } - else - { - this.selectedBlockMetaData = 0; - } - } + if (f < 0.2F) { + this.blockstate = TFBlocks.underbrick.getDefaultState().withProperty(BlockTFUnderBrick.VARIANT, UnderBrickVariant.CRACKED); + } else if (f < 0.5F) { + this.blockstate = TFBlocks.underbrick.getDefaultState().withProperty(BlockTFUnderBrick.VARIANT, UnderBrickVariant.MOSSY); + } else { + this.blockstate = TFBlocks.underbrick.getDefaultState().withProperty(BlockTFUnderBrick.VARIANT, UnderBrickVariant.NORMAL); + } + } } } diff --git a/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdComponent.java b/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdComponent.java index 8c47720323..c1349c5ad4 100644 --- a/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdComponent.java +++ b/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdComponent.java @@ -1,43 +1,44 @@ package twilightforest.structures.stronghold; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFConfig; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; -public abstract class StructureTFStrongholdComponent extends StructureTFComponent { +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public abstract class StructureTFStrongholdComponent extends StructureTFComponentOld { - public List doors = new ArrayList(); + public List doors = new ArrayList(); public StructureTFStrongholdComponent() { - super(); - // TODO Auto-generated constructor stub } - public StructureTFStrongholdComponent(int i, int facing, int x, int y, int z) { - super(i); + public StructureTFStrongholdComponent(TFFeature feature, int i, EnumFacing facing, int x, int y, int z) { + super(feature, i); this.boundingBox = generateBoundingBox(facing, x, y, z); this.setCoordBaseMode(facing); } - /** - * Save to NBT - */ @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); - par1NBTTagCompound.setIntArray("doorInts", this.getDoorsAsIntArray()); + tagCompound.setIntArray("doorInts", this.getDoorsAsIntArray()); } /** @@ -45,188 +46,164 @@ protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { */ private int[] getDoorsAsIntArray() { IntBuffer ibuffer = IntBuffer.allocate(this.doors.size() * 3); - - for (ChunkCoordinates door : doors) - { - ibuffer.put(door.posX); - ibuffer.put(door.posY); - ibuffer.put(door.posZ); + + for (BlockPos door : doors) { + ibuffer.put(door.getX()); + ibuffer.put(door.getY()); + ibuffer.put(door.getZ()); } - + return ibuffer.array(); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + // init doors - this.readOpeningsFromArray(par1NBTTagCompound.getIntArray("doorInts")); + this.readOpeningsFromArray(tagCompound.getIntArray("doorInts")); } /** * Read in openings from int array */ private void readOpeningsFromArray(int[] intArray) { - for (int i = 0; i < intArray.length; i += 3) - { - ChunkCoordinates door = new ChunkCoordinates(intArray[i], intArray[i + 1], intArray[i + 2]); - + for (int i = 0; i < intArray.length; i += 3) { + BlockPos door = new BlockPos(intArray[i], intArray[i + 1], intArray[i + 2]); + this.doors.add(door); } } - - public abstract StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z); - - /** - * used to project a possible new component Bounding Box - to check if it would cut anything already spawned - */ - public static StructureBoundingBox getComponentToAddBoundingBox(int x, int y, int z, int xOff, int yOff, int zOff, int xSize, int ySize, int zSize, int facing) - { - switch (facing) - { - case 0: - return new StructureBoundingBox(x + xOff, y + yOff, z + zOff, x + xSize - 1 + xOff, y + ySize - 1 + yOff, z + zSize - 1 + zOff); - case 1: - return new StructureBoundingBox(x - zSize + 1 + zOff, y + yOff, z + xOff, x + zOff, y + ySize - 1 + yOff, z + xSize - 1 + xOff); - case 2: - return new StructureBoundingBox(x - xSize + 1 - xOff, y + yOff, z - zSize + 1 + zOff, x - xOff, y + ySize - 1 + yOff, z + zOff); - case 3: - return new StructureBoundingBox(x + zOff, y + yOff, z - xSize + 1 - xOff, x + zSize - 1 + zOff, y + ySize - 1 + yOff, z - xOff); - default: - return new StructureBoundingBox(x + xOff, y + yOff, z + zOff, x + xSize - 1 + xOff, y + ySize - 1 + yOff, z + zSize - 1 + zOff); - } - } - - @SuppressWarnings("rawtypes") - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) - { - if (parent != null && parent instanceof StructureTFComponent) - { - this.deco = ((StructureTFComponent)parent).deco; + + public abstract StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z); + + /** + * used to project a possible new component Bounding Box - to check if it would cut anything already spawned + */ + public static StructureBoundingBox getComponentToAddBoundingBox(int x, int y, int z, int xOff, int yOff, int zOff, int xSize, int ySize, int zSize, EnumFacing facing) { + switch (facing) { + case SOUTH: + return new StructureBoundingBox(x + xOff, y + yOff, z + zOff, x + xSize - 1 + xOff, y + ySize - 1 + yOff, z + zSize - 1 + zOff); + case WEST: + return new StructureBoundingBox(x - zSize + 1 + zOff, y + yOff, z + xOff, x + zOff, y + ySize - 1 + yOff, z + xSize - 1 + xOff); + case NORTH: + return new StructureBoundingBox(x - xSize + 1 - xOff, y + yOff, z - zSize + 1 + zOff, x - xOff, y + ySize - 1 + yOff, z + zOff); + case EAST: + return new StructureBoundingBox(x + zOff, y + yOff, z - xSize + 1 - xOff, x + zSize - 1 + zOff, y + ySize - 1 + yOff, z - xOff); + default: + return new StructureBoundingBox(x + xOff, y + yOff, z + zOff, x + xSize - 1 + xOff, y + ySize - 1 + yOff, z + zSize - 1 + zOff); } } - + @Override + public void buildComponent(StructureComponent parent, List list, Random rand) { + if (parent != null && parent instanceof StructureTFComponentOld) { + this.deco = ((StructureTFComponentOld) parent).deco; + } + } /** * Add a new component in the specified direction */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void addNewComponent(StructureComponent entrance, List list, Random random, int facing, int x, int y, int z) - { + protected void addNewComponent(StructureComponent entrance, List list, Random random, Rotation facing, int x, int y, int z) { int index = this.componentType + 1; - int nFacing = (this.coordBaseMode + facing) % 4; + EnumFacing nFacing = getStructureRelativeRotation(facing); int nx = this.getXWithOffset(x, z); int ny = this.getYWithOffset(y); int nz = this.getZWithOffset(x, z); - + // limit sprawl to a reasonable amount - if (index > 50 || isOutOfRange(entrance, nx, ny, nz, 112)) - { + if (index > 50 || isOutOfRange(entrance, nx, ny, nz, 112)) { return; } - + // are we looking at a point we can possibly break in to? - StructureTFStrongholdComponent breakIn = this.findBreakInComponent(list, nx, ny, nz); - if (breakIn != null && breakIn.attemptToBreakIn(nx, ny, nz)) - { + StructureTFStrongholdComponent breakIn = (StructureTFStrongholdComponent) this.findBreakInComponent(list, nx, ny, nz); + if (breakIn != null && breakIn.attemptToBreakIn(nx, ny, nz)) { // success! this.addDoorwayTo(x, y, z, facing); return; } - - TFStrongholdPieces pieceList = ((ComponentTFStrongholdEntrance)entrance).lowerPieces; - - StructureTFStrongholdComponent nextComponent = pieceList.getNextComponent(entrance, list, random, index, nFacing, nx, ny, nz); - + + TFStrongholdPieces pieceList = ((ComponentTFStrongholdEntrance) entrance).lowerPieces; + + StructureComponent nextComponent = pieceList.getNextComponent(entrance, list, random, getFeatureType(), index, nFacing, nx, ny, nz); + // is it clear? - if (nextComponent != null) - { + if (nextComponent != null) { // if so, add it list.add(nextComponent); nextComponent.buildComponent(entrance, list, random); this.addDoorwayTo(x, y, z, facing); } } - + /** * Check the list for components we can break in to at the specified point */ - protected StructureTFStrongholdComponent findBreakInComponent(List list, int x, int y, int z) - { - for (StructureTFStrongholdComponent component : list) - { - if (component.boundingBox != null && component.boundingBox.isVecInside(x, y, z)) - { + protected StructureComponent findBreakInComponent(List list, int x, int y, int z) { + BlockPos pos = new BlockPos(x, y, z); + for (StructureComponent component : list) { + if (component.getBoundingBox() != null && component.getBoundingBox().isVecInside(pos)) { return component; } } - + return null; } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected void addNewUpperComponent(StructureComponent parent, List list, Random random, int facing, int x, int y, int z) - { + + protected void addNewUpperComponent(StructureComponent parent, List list, Random random, Rotation facing, int x, int y, int z) { StructureTFStrongholdComponent attempted = null; - + int index = this.componentType + 1; - int nFacing = (this.coordBaseMode + facing) % 4; + EnumFacing nFacing = getStructureRelativeRotation(facing); int nx = this.getXWithOffset(x, z); int ny = this.getYWithOffset(y); int nz = this.getZWithOffset(x, z); - + // limit sprawl to a reasonable amount - if (index > 100 || isOutOfRange(parent, nx, ny, nz, 48)) - { + if (index > 100 || isOutOfRange(parent, nx, ny, nz, 48)) { return; } - + // find a new component - switch (random.nextInt(5)) - { - case 0: - default : - attempted = new ComponentTFStrongholdUpperTIntersection(index, nFacing, nx, ny, nz); - break; - case 1: - attempted = new ComponentTFStrongholdUpperLeftTurn(index, nFacing, nx, ny, nz); - break; - case 2: - attempted = new ComponentTFStrongholdUpperRightTurn(index, nFacing, nx, ny, nz); - break; - case 3: - attempted = new ComponentTFStrongholdUpperCorridor(index, nFacing, nx, ny, nz); - break; - case 4: - attempted = new ComponentTFStrongholdUpperAscender(index, nFacing, nx, ny, nz); - break; + switch (random.nextInt(5)) { + case 0: + default: + attempted = new ComponentTFStrongholdUpperTIntersection(getFeatureType(), index, nFacing, nx, ny, nz); + break; + case 1: + attempted = new ComponentTFStrongholdUpperLeftTurn(getFeatureType(), index, nFacing, nx, ny, nz); + break; + case 2: + attempted = new ComponentTFStrongholdUpperRightTurn(getFeatureType(), index, nFacing, nx, ny, nz); + break; + case 3: + attempted = new ComponentTFStrongholdUpperCorridor(getFeatureType(), index, nFacing, nx, ny, nz); + break; + case 4: + attempted = new ComponentTFStrongholdUpperAscender(getFeatureType(), index, nFacing, nx, ny, nz); + break; } - - + + // is it clear? - if (attempted != null && StructureComponent.findIntersecting(list, attempted.getBoundingBox()) == null) - { + if (attempted != null && StructureComponent.findIntersecting(list, attempted.getBoundingBox()) == null) { // if so, add it list.add(attempted); attempted.buildComponent(parent, list, random); - + } - + } - + /** * Have we strayed more than range blocks away from the center? */ private boolean isOutOfRange(StructureComponent parent, int nx, int ny, int nz, int range) { - + return Math.abs(nx - parent.getBoundingBox().minX) > range || Math.abs(nz - parent.getBoundingBox().minZ) > range; } @@ -235,30 +212,26 @@ private boolean isOutOfRange(StructureComponent parent, int nx, int ny, int nz, * Make a doorway */ protected void placeDoorwayAt(World world, Random rand, int x, int y, int z, StructureBoundingBox sbb) { - if (x == 0 || x == this.getXSize()) - { - this.fillWithMetadataBlocks(world, sbb, x, y, z - 2, x, y + 3, z + 2, deco.fenceID, deco.fenceMeta, Blocks.air, 0, false); + if (x == 0 || x == this.getXSize()) { + this.fillWithBlocks(world, sbb, x, y, z - 2, x, y + 3, z + 2, deco.fenceState, Blocks.AIR.getDefaultState(), false); this.fillWithAir(world, sbb, x, y, z - 1, x, y + 3, z + 1); - } - else - { - this.fillWithMetadataBlocks(world, sbb, x - 2, y, z, x + 2, y + 3, z, deco.fenceID, deco.fenceMeta, Blocks.air, 0, false); + } else { + this.fillWithBlocks(world, sbb, x - 2, y, z, x + 2, y + 3, z, deco.fenceState, Blocks.AIR.getDefaultState(), false); this.fillWithAir(world, sbb, x - 1, y, z, x + 1, y + 3, z); } - - //this.placeBlockAtCurrentPosition(world, Blocks.wool, this.coordBaseMode, x, y, z, sbb); + + //this.setBlockState(world, Blocks.WOOL, this.coordBaseMode, x, y, z, sbb); } protected int getXSize() { - switch (this.getCoordBaseMode()) - { - default: - case 0: - case 2: - return this.boundingBox.getXSize() - 1; - case 1: - case 3: - return this.boundingBox.getZSize() - 1; + switch (this.getCoordBaseMode()) { + default: + case SOUTH: + case NORTH: + return this.boundingBox.getXSize() - 1; + case WEST: + case EAST: + return this.boundingBox.getZSize() - 1; } } @@ -266,18 +239,15 @@ protected int getXSize() { * Make a smaller doorway */ protected void placeSmallDoorwayAt(World world, Random rand, int facing, int x, int y, int z, StructureBoundingBox sbb) { - if (facing == 0 || facing == 2) - { - this.fillWithMetadataBlocks(world, sbb, x - 1, y, z, x + 1, y + 1, z, Blocks.cobblestone_wall, 0, Blocks.air, 0, true); + if (facing == 0 || facing == 2) { + this.fillWithBlocks(world, sbb, x - 1, y, z, x + 1, y + 1, z, Blocks.COBBLESTONE_WALL.getDefaultState(), Blocks.AIR.getDefaultState(), true); this.fillWithAir(world, sbb, x, y, z, x, y + 1, z); - } - else - { - this.fillWithMetadataBlocks(world, sbb, x, y, z - 1, x, y + 1, z + 1, Blocks.cobblestone_wall, 0, Blocks.air, 0, true); + } else { + this.fillWithBlocks(world, sbb, x, y, z - 1, x, y + 1, z + 1, Blocks.COBBLESTONE_WALL.getDefaultState(), Blocks.AIR.getDefaultState(), true); this.fillWithAir(world, sbb, x, y, z, x, y + 1, z); } - - //this.placeBlockAtCurrentPosition(world, Blocks.wool, this.coordBaseMode, x, y, z, sbb); + + //this.setBlockState(world, Blocks.WOOL, this.coordBaseMode, x, y, z, sbb); } /** @@ -288,162 +258,145 @@ public void placeCornerStatue(World world, int x, int y, int z, int facing, Stru // set offsets and stair metas int ox = 1; int oz = 1; - int smx = 2; - int smz = 3; - - - switch (facing) - { - case 0: - // already set up - break; - case 1: - oz = -1; - smz = 1; - break; - case 2 : - ox = -1; - smx = 0; - break; - case 3: - ox = -1; - oz = -1; - smx = 0; - smz = 1; - break; + EnumFacing smx = EnumFacing.EAST; + EnumFacing smz = EnumFacing.SOUTH; + + + switch (facing) { + case 0: + // already set up + break; + case 1: + oz = -1; + smz = EnumFacing.SOUTH; + break; + case 2: + ox = -1; + smx = EnumFacing.WEST; + break; + case 3: + ox = -1; + oz = -1; + smx = EnumFacing.WEST; + smz = EnumFacing.NORTH; + break; } // the center is always the same - for (int sy = 0; sy < 5; sy++) - { - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, x, y + sy, z, sbb); + for (int sy = 0; sy < 5; sy++) { + this.setBlockState(world, deco.pillarState, x, y + sy, z, sbb); } // antlers - this.placeBlockAtCurrentPosition(world, Blocks.fence, 0, x + 0, y + 4, z + oz, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.fence, 0, x + ox, y + 4, z + 0, sbb); + this.setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x + 0, y + 4, z + oz, sbb); + this.setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x + ox, y + 4, z + 0, sbb); // arms - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(smz), x + 0, y + 3, z + oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(smx), x + ox, y + 3, z + 0, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(smz) + 4, x + 0, y + 2, z + oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(smx) + 4, x + ox, y + 2, z + 0, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(smx) + 4, x + ox, y + 2, z + oz, sbb); + + this.setBlockState(world, getStairState(deco.stairState, smz, rotation, false), x + 0, y + 3, z + oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, smx, rotation, false), x + ox, y + 3, z + 0, sbb); + this.setBlockState(world, getStairState(deco.stairState, smz, rotation, true), x + 0, y + 2, z + oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, smx, rotation, true), x + ox, y + 2, z + 0, sbb); + this.setBlockState(world, getStairState(deco.stairState, smx, rotation, true), x + ox, y + 2, z + oz, sbb); // sword - this.placeBlockAtCurrentPosition(world, Blocks.cobblestone_wall, 0, x + ox, y + 0, z + oz, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.cobblestone_wall, 0, x + ox, y + 1, z + oz, sbb); + this.setBlockState(world, Blocks.COBBLESTONE_WALL.getDefaultState(), x + ox, y + 0, z + oz, sbb); + this.setBlockState(world, Blocks.COBBLESTONE_WALL.getDefaultState(), x + ox, y + 1, z + oz, sbb); // feet - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(smz), x + 0, y + 0, z + oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(smx), x + ox, y + 0, z + 0, sbb); + this.setBlockState(world, getStairState(deco.stairState, smz, rotation, false), x + 0, y + 0, z + oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, smx, rotation, false), x + ox, y + 0, z + 0, sbb); } - + /** * Make a statue that faces out from a wall */ - public void placeWallStatue(World world, int x, int y, int z, int facing, StructureBoundingBox sbb) { + public void placeWallStatue(World world, int x, int y, int z, Rotation facing, StructureBoundingBox sbb) { int ox = 1; int oz = 1; - + // the center is always the same - for (int sy = 0; sy < 5; sy++) - { - this.placeBlockAtCurrentPosition(world, deco.pillarID, deco.pillarMeta, x, y + sy, z, sbb); + for (int sy = 0; sy < 5; sy++) { + this.setBlockState(world, deco.pillarState, x, y + sy, z, sbb); } - - if (facing == 0 || facing == 2) - { - if (facing == 2) - { + + if (facing == Rotation.NONE || facing == Rotation.CLOCKWISE_180) { + if (facing == Rotation.CLOCKWISE_180) { ox = -ox; oz = -oz; } - + // antlers - this.placeBlockAtCurrentPosition(world, Blocks.fence, 0, x - ox, y + 4, z, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.fence, 0, x + ox, y + 4, z, sbb); - + this.setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x - ox, y + 4, z, sbb); + this.setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x + ox, y + 4, z, sbb); + // arms - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(0 + facing), x - ox, y + 3, z, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2 + facing), x + ox, y + 3, z, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing), x - ox, y + 3, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing), x + ox, y + 3, z - oz, sbb); - - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(0 + facing) + 4, x - ox, y + 2, z, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2 + facing) + 4, x + ox, y + 2, z, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing) + 4, x + 0, y + 2, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing) + 4, x - ox, y + 2, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing) + 4, x + ox, y + 2, z - oz, sbb); - + + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.NONE).rotate(EnumFacing.WEST), rotation, false), x - ox, y + 3, z, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_180).rotate(EnumFacing.WEST), rotation, false), x + ox, y + 3, z, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, false), x - ox, y + 3, z - oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, false), x + ox, y + 3, z - oz, sbb); + + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.NONE).rotate(EnumFacing.WEST), rotation, true), x - ox, y + 2, z, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_180).rotate(EnumFacing.WEST), rotation, true), x + ox, y + 2, z, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, true), x + 0, y + 2, z - oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, true), x - ox, y + 2, z - oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, true), x + ox, y + 2, z - oz, sbb); + // sword - this.placeBlockAtCurrentPosition(world, Blocks.cobblestone_wall, 0, x, y + 0, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.cobblestone_wall, 0, x, y + 1, z - oz, sbb); - + this.setBlockState(world, Blocks.COBBLESTONE_WALL.getDefaultState(), x, y + 0, z - oz, sbb); + this.setBlockState(world, Blocks.COBBLESTONE_WALL.getDefaultState(), x, y + 1, z - oz, sbb); + // feet - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(0 + facing), x - ox, y + 0, z + 0, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2 + facing), x + ox, y + 0, z + 0, sbb); - } - else - { - if (facing == 3) - { + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.NONE).rotate(EnumFacing.WEST), rotation, false), x - ox, y + 0, z + 0, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_180).rotate(EnumFacing.WEST), rotation, false), x + ox, y + 0, z + 0, sbb); + } else { + if (facing == Rotation.COUNTERCLOCKWISE_90) { oz = -oz; ox = -ox; } - + // antlers - this.placeBlockAtCurrentPosition(world, Blocks.fence, 0, x, y + 4, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.fence, 0, x, y + 4, z + oz, sbb); - + this.setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x, y + 4, z - oz, sbb); + this.setBlockState(world, Blocks.OAK_FENCE.getDefaultState(), x, y + 4, z + oz, sbb); + // arms - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(0 + facing), x, y + 3, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2 + facing), x, y + 3, z + oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing), x + ox, y + 3, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing), x + ox, y + 3, z + oz, sbb); - - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(0 + facing) + 4, x, y + 2, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2 + facing) + 4, x, y + 2, z + oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing) + 4, x + oz, y + 2, z + 0, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing) + 4, x + ox, y + 2, z - oz, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(1 + facing) + 4, x + ox, y + 2, z + oz, sbb); - + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.NONE).rotate(EnumFacing.WEST), rotation, false), x, y + 3, z - oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_180).rotate(EnumFacing.WEST), rotation, false), x, y + 3, z + oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, false), x + ox, y + 3, z - oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, false), x + ox, y + 3, z + oz, sbb); + + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.NONE).rotate(EnumFacing.WEST), rotation, true), x, y + 2, z - oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_180).rotate(EnumFacing.WEST), rotation, true), x, y + 2, z + oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, true), x + oz, y + 2, z + 0, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, true), x + ox, y + 2, z - oz, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_90).rotate(EnumFacing.WEST), rotation, true), x + ox, y + 2, z + oz, sbb); + // sword - this.placeBlockAtCurrentPosition(world, Blocks.cobblestone_wall, 0, x + ox, y + 0, z, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.cobblestone_wall, 0, x + ox, y + 1, z, sbb); - + this.setBlockState(world, Blocks.COBBLESTONE_WALL.getDefaultState(), x + ox, y + 0, z, sbb); + this.setBlockState(world, Blocks.COBBLESTONE_WALL.getDefaultState(), x + ox, y + 1, z, sbb); + // feet - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(0 + facing), x, y + 0, z - ox, sbb); - this.placeBlockAtCurrentPosition(world, deco.stairID, this.getStairMeta(2 + facing), x, y + 0, z + ox, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.NONE).rotate(EnumFacing.WEST), rotation, false), x, y + 0, z - ox, sbb); + this.setBlockState(world, getStairState(deco.stairState, facing.add(Rotation.CLOCKWISE_180).rotate(EnumFacing.WEST), rotation, false), x, y + 0, z + ox, sbb); } } - + /** * Called curing construction. If an attempted component collides with this one, try "breaking in". */ - public boolean attemptToBreakIn(int wx, int wy, int wz) - { - if (!isValidBreakInPoint(wx, wy, wz)) - { - //System.out.println("Break in failed because the point is invalid"); - - //System.out.printf("Break point is %d, %d, %d, bounding sides are %d-%d x %d-%d\n", wx, wy, wz, this.boundingBox.minX, this.boundingBox.maxX, this.boundingBox.minZ, this.boundingBox.maxZ); - - + public boolean attemptToBreakIn(int wx, int wy, int wz) { + if (!isValidBreakInPoint(wx, wy, wz)) { return false; - } - else - { + } else { int dx = this.getRelativeX(wx, wz); int dy = this.getRelativeY(wy); int dz = this.getRelativeZ(wx, wz); - + addDoor(dx, dy, dz); - - //System.out.printf("Break in success for component %s, at %d, %d, %d! Facing is %d\n", this, dx, dy, dz, this.getCoordBaseMode()); - + return true; } } @@ -451,184 +404,158 @@ public boolean attemptToBreakIn(int wx, int wy, int wz) /** * Add a door to our list */ - public void addDoorwayTo(int dx, int dy, int dz, int facing) { - switch (facing) - { - case 0: - addDoor(dx, dy, dz - 1); - break; - case 1: - addDoor(dx + 1, dy, dz); - break; - case 2: - addDoor(dx, dy, dz + 1); - break; - case 3: - addDoor(dx - 1, dy, dz); - break; + public void addDoorwayTo(int dx, int dy, int dz, Rotation facing) { + switch (facing) { + case NONE: + addDoor(dx, dy, dz - 1); + break; + case CLOCKWISE_90: + addDoor(dx + 1, dy, dz); + break; + case CLOCKWISE_180: + addDoor(dx, dy, dz + 1); + break; + case COUNTERCLOCKWISE_90: + addDoor(dx - 1, dy, dz); + break; } } - + /** * Add a door to our list */ public void addDoor(int dx, int dy, int dz) { - this.doors.add(new ChunkCoordinates(dx, dy, dz)); + this.doors.add(new BlockPos(dx, dy, dz)); } /** * Is the specified point a valid spot to break in? */ protected boolean isValidBreakInPoint(int wx, int wy, int wz) { - if (wy < this.boundingBox.minY || wy > this.boundingBox.maxY) - { + if (wy < this.boundingBox.minY || wy > this.boundingBox.maxY) { return false; - } - else if (wx == this.boundingBox.minX || wx == this.boundingBox.maxX) - { + } else if (wx == this.boundingBox.minX || wx == this.boundingBox.maxX) { return wz > this.boundingBox.minZ && wz < this.boundingBox.maxZ; - } - else if (wz == this.boundingBox.minZ || wz == this.boundingBox.maxZ) - { + } else if (wz == this.boundingBox.minZ || wz == this.boundingBox.maxZ) { return wx > this.boundingBox.minX && wx < this.boundingBox.maxX; - } - else - { + } else { return false; } } - protected int getRelativeX(int x, int z) - { + protected int getRelativeX(int x, int z) { //this.getXWithOffset(x, z); - switch(getCoordBaseMode()) - { - case 0: - return x - boundingBox.minX; - case 2: - return boundingBox.maxX - x; - case 1: - return z - boundingBox.minZ; - case 3: - return boundingBox.maxZ - z; - } - return x; - } - - protected int getRelativeY(int par1) - { - return par1 - this.boundingBox.minY; - } - - protected int getRelativeZ(int x, int z) - { - switch(getCoordBaseMode()) - { - case 0: - return z - boundingBox.minZ; - case 2: - return boundingBox.maxZ - z; - case 1: - return boundingBox.maxX - x; - case 3: - return x - boundingBox.minX; - } - return z; - } - - /** - * Place any doors on our list - */ - public void placeDoors(World world, Random rand, StructureBoundingBox sbb) - { - if (this.doors != null) - { - for (ChunkCoordinates doorCoords : doors) - { - this.placeDoorwayAt(world, rand, doorCoords.posX, doorCoords.posY, doorCoords.posZ, sbb); - - //this.placeBlockAtCurrentPosition(world, Blocks.wool, doorCoords.posX, doorCoords.posX, doorCoords.posY + 2, doorCoords.posZ, sbb); + switch (getCoordBaseMode()) { + case SOUTH: + return x - boundingBox.minX; + case NORTH: + return boundingBox.maxX - x; + case WEST: + return z - boundingBox.minZ; + case EAST: + return boundingBox.maxZ - z; + default: + return x; + } + } + + protected int getRelativeY(int y) { + return y - this.boundingBox.minY; + } + + protected int getRelativeZ(int x, int z) { + switch (getCoordBaseMode()) { + case SOUTH: + return z - boundingBox.minZ; + case NORTH: + return boundingBox.maxZ - z; + case WEST: + return boundingBox.maxX - x; + case EAST: + return x - boundingBox.minX; + default: + return z; + } + } + + /** + * Place any doors on our list + */ + public void placeDoors(World world, Random rand, StructureBoundingBox sbb) { + if (this.doors != null) { + for (BlockPos doorCoords : doors) { + this.placeDoorwayAt(world, rand, doorCoords.getX(), doorCoords.getY(), doorCoords.getZ(), sbb); + + //this.setBlockState(world, Blocks.WOOL, doorCoords.posX, doorCoords.posX, doorCoords.posY + 2, doorCoords.posZ, sbb); } } - } - - /** - * Place stronghold walls in every position except those filled with dirt. - */ - protected void placeStrongholdWalls(World world, StructureBoundingBox sbb, int sx, int sy, int sz, int dx, int dy, int dz, Random rand, StructureComponent.BlockSelector randomBlocks) { - for (int y = sy; y <= dy; ++y) - { - for (int x = sx; x <= dx; ++x) - { - for (int z = sz; z <= dz; ++z) - { - boolean wall = y == sy || y == dy || x == sx || x == dx || z == sz || z == dz; - Block blockID = this.getBlockAtCurrentPosition(world, x, y, z, sbb); - - if (blockID == Blocks.air) - { - // cobblestone to "fill in holes" - if (wall) - { - this.placeBlockAtCurrentPosition(world, Blocks.cobblestone, 0, x, y, z, sbb); - } - } - else if (y == sy || y == dy) - { + } + + /** + * Place stronghold walls in every position except those filled with dirt. + */ + protected void placeStrongholdWalls(World world, StructureBoundingBox sbb, int sx, int sy, int sz, int dx, int dy, int dz, Random rand, StructureComponent.BlockSelector randomBlocks) { + for (int y = sy; y <= dy; ++y) { + for (int x = sx; x <= dx; ++x) { + for (int z = sz; z <= dz; ++z) { + boolean wall = y == sy || y == dy || x == sx || x == dx || z == sz || z == dz; + Block blockID = this.getBlockStateFromPos(world, x, y, z, sbb).getBlock(); + + if (blockID == Blocks.AIR && !TFConfig.dimension.skylightForest) { + // cobblestone to "fill in holes" + if (wall) { + this.setBlockState(world, Blocks.COBBLESTONE.getDefaultState(), x, y, z, sbb); + } + } else if (y == sy || y == dy) { // do stronghold bricks for floor/ceiling - StructureComponent.BlockSelector strongBlocks = StructureTFComponent.getStrongholdStones(); - strongBlocks.selectBlocks(rand, x, y, z, wall); - this.placeBlockAtCurrentPosition(world, strongBlocks.func_151561_a(), strongBlocks.getSelectedBlockMetaData(), x, y, z, sbb); - - } - else if (!wall || blockID != Blocks.dirt) // leave dirt there - { + StructureComponent.BlockSelector strongBlocks = StructureTFComponentOld.getStrongholdStones(); + strongBlocks.selectBlocks(rand, x, y, z, wall); + this.setBlockState(world, strongBlocks.getBlockState(), x, y, z, sbb); + + } else if (!wall || blockID != Blocks.DIRT) { // leave dirt there // and use decorator (with presumably underbricks) for walls - randomBlocks.selectBlocks(rand, x, y, z, wall); - this.placeBlockAtCurrentPosition(world, randomBlocks.func_151561_a(), randomBlocks.getSelectedBlockMetaData(), x, y, z, sbb); - } - } - } - } - } - - - /** - * Place stronghold walls on dirt/grass/stone - */ - protected void placeUpperStrongholdWalls(World world, StructureBoundingBox sbb, int sx, int sy, int sz, int dx, int dy, int dz, Random rand, StructureComponent.BlockSelector randomBlocks) { - for (int y = sy; y <= dy; ++y) - { - for (int x = sx; x <= dx; ++x) - { - for (int z = sz; z <= dz; ++z) - { - boolean wall = y == sy || y == dy || x == sx || x == dx || z == sz || z == dz; - Block blockID = this.getBlockAtCurrentPosition(world, x, y, z, sbb); - - if ((blockID != Blocks.air && (blockID.getMaterial() == Material.rock || blockID.getMaterial() == Material.grass || blockID.getMaterial() == Material.ground)) - || (blockID == Blocks.air && rand.nextInt(3) == 0) && this.getBlockAtCurrentPosition(world, x, y - 1, z, sbb) == Blocks.stonebrick) - { - if (y == sy || y == dy) - { - // do stronghold bricks for floor/ceiling - StructureComponent.BlockSelector strongBlocks = StructureTFComponent.getStrongholdStones(); - strongBlocks.selectBlocks(rand, x, y, z, wall); - this.placeBlockAtCurrentPosition(world, strongBlocks.func_151561_a(), strongBlocks.getSelectedBlockMetaData(), x, y, z, sbb); - - } - else - { - // and use decorator (with presumably underbricks) for walls - randomBlocks.selectBlocks(rand, x, y, z, wall); - this.placeBlockAtCurrentPosition(world, randomBlocks.func_151561_a(), randomBlocks.getSelectedBlockMetaData(), x, y, z, sbb); - } - } - } - } - } - } + randomBlocks.selectBlocks(rand, x, y, z, wall); + this.setBlockState(world, randomBlocks.getBlockState(), x, y, z, sbb); + } + } + } + } + } + + + /** + * Place stronghold walls on dirt/grass/stone + */ + protected void placeUpperStrongholdWalls(World world, StructureBoundingBox sbb, int sx, int sy, int sz, int dx, int dy, int dz, Random rand, StructureComponent.BlockSelector randomBlocks) { + for (int y = sy; y <= dy; ++y) { + for (int x = sx; x <= dx; ++x) { + for (int z = sz; z <= dz; ++z) { + boolean wall = y == sy || y == dy || x == sx || x == dx || z == sz || z == dz; + IBlockState state = this.getBlockStateFromPos(world, x, y, z, sbb); + Block blockID = state.getBlock(); + + if ((blockID != Blocks.AIR && (state.getMaterial() == Material.ROCK || state.getMaterial() == Material.GRASS || state.getMaterial() == Material.GROUND)) + || (blockID == Blocks.AIR && rand.nextInt(3) == 0) && this.getBlockStateFromPos(world, x, y - 1, z, sbb).getBlock() == Blocks.STONEBRICK) { + if (y == sy || y == dy) { + // do stronghold bricks for floor/ceiling + StructureComponent.BlockSelector strongBlocks = StructureTFComponentOld.getStrongholdStones(); + strongBlocks.selectBlocks(rand, x, y, z, wall); + this.setBlockState(world, strongBlocks.getBlockState(), x, y, z, sbb); + + } else { + // and use decorator (with presumably underbricks) for walls + randomBlocks.selectBlocks(rand, x, y, z, wall); + this.setBlockState(world, randomBlocks.getBlockState(), x, y, z, sbb); + } + } + } + } + } + } + public interface Factory { + T newInstance(TFFeature feature, int i, EnumFacing facing, int x, int y, int z); + } } \ No newline at end of file diff --git a/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdShield.java b/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdShield.java index 5c3ae5912f..82f33a1a97 100644 --- a/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdShield.java +++ b/src/main/java/twilightforest/structures/stronghold/StructureTFStrongholdShield.java @@ -1,52 +1,54 @@ package twilightforest.structures.stronghold; -import java.util.Random; - -import net.minecraft.block.Block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; -public class StructureTFStrongholdShield extends StructureTFStrongholdComponent { - +import java.util.Random; +public class StructureTFStrongholdShield extends StructureTFStrongholdComponent { public StructureTFStrongholdShield() { - super(); - // TODO Auto-generated constructor stub } - public StructureTFStrongholdShield(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - super(0, 0, minX, minY, minZ); + public StructureTFStrongholdShield(TFFeature feature, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + super(feature, 0, EnumFacing.SOUTH, minX, minY, minZ); this.boundingBox = new StructureBoundingBox(minX, minY, minZ, maxX, maxY, maxZ); this.spawnListIndex = -1; } @Override - public StructureBoundingBox generateBoundingBox(int facing, int x, int y, int z) { + public StructureBoundingBox generateBoundingBox(EnumFacing facing, int x, int y, int z) { return null; } @Override public boolean addComponentParts(World world, Random random, StructureBoundingBox sbb) { - Block shieldBlock = TFBlocks.shield; - - //Facing.facings - - // +x - this.fillWithMetadataBlocks(world, sbb, this.boundingBox.getXSize(), 0, 0, this.boundingBox.getXSize(), this.boundingBox.getYSize(), this.boundingBox.getZSize(), shieldBlock, 4, shieldBlock, 4, false); - // -x - this.fillWithMetadataBlocks(world, sbb, 0, 0, 0, 0, this.boundingBox.getYSize(), this.boundingBox.getZSize(), shieldBlock, 5, shieldBlock, 5, false); - // +z - this.fillWithMetadataBlocks(world, sbb, 0, 0, this.boundingBox.getZSize(), this.boundingBox.getXSize(), this.boundingBox.getYSize(), this.boundingBox.getZSize(), shieldBlock, 2, shieldBlock, 2, false); - // -z - this.fillWithMetadataBlocks(world, sbb, 0, 0, 0, this.boundingBox.getXSize(), this.boundingBox.getYSize(), 0, shieldBlock, 3, shieldBlock, 3, false); + IBlockState down = TFBlocks.stronghold_shield.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.DOWN); + IBlockState up = TFBlocks.stronghold_shield.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.UP); + IBlockState north = TFBlocks.stronghold_shield.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.NORTH); + IBlockState south = TFBlocks.stronghold_shield.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.SOUTH); + IBlockState west = TFBlocks.stronghold_shield.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.WEST); + IBlockState east = TFBlocks.stronghold_shield.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.EAST); + + // +x + this.fillWithBlocks(world, sbb, this.boundingBox.getXSize(), 0, 0, this.boundingBox.getXSize(), this.boundingBox.getYSize(), this.boundingBox.getZSize(), west, west, false); + // -x + this.fillWithBlocks(world, sbb, 0, 0, 0, 0, this.boundingBox.getYSize(), this.boundingBox.getZSize(), east, east, false); + // +z + this.fillWithBlocks(world, sbb, 0, 0, this.boundingBox.getZSize(), this.boundingBox.getXSize(), this.boundingBox.getYSize(), this.boundingBox.getZSize(), north, north, false); + // -z + this.fillWithBlocks(world, sbb, 0, 0, 0, this.boundingBox.getXSize(), this.boundingBox.getYSize(), 0, south, south, false); // top - this.fillWithMetadataBlocks(world, sbb, 0, 0, 0, this.boundingBox.getXSize(), 0, this.boundingBox.getZSize(), shieldBlock, 1, shieldBlock, 1, false); - // bottom - this.fillWithMetadataBlocks(world, sbb, 0, this.boundingBox.getYSize(), 0, this.boundingBox.getXSize(), this.boundingBox.getYSize(), this.boundingBox.getZSize(), shieldBlock, 0, shieldBlock, 0, false); - - return true; + this.fillWithBlocks(world, sbb, 0, 0, 0, this.boundingBox.getXSize(), 0, this.boundingBox.getZSize(), up, up, false); + // bottom + this.fillWithBlocks(world, sbb, 0, this.boundingBox.getYSize(), 0, this.boundingBox.getXSize(), this.boundingBox.getYSize(), this.boundingBox.getZSize(), down, down, false); + + return true; } } diff --git a/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieceWeight.java b/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieceWeight.java index badb3a3208..7246545f9a 100644 --- a/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieceWeight.java +++ b/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieceWeight.java @@ -1,40 +1,39 @@ package twilightforest.structures.stronghold; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.stronghold.StructureTFStrongholdComponent.Factory; /** * Based off StructureStrongholdPieceWeight */ public class TFStrongholdPieceWeight { - - public Class pieceClass; - public final int pieceWeight; - public int instancesSpawned; - - /** How many Structure Pieces of this type may spawn in a structure */ - public int instancesLimit; - public int minimumDepth; - - public TFStrongholdPieceWeight(Class par1Class, int weight, int limit) - { - this(par1Class, weight, limit, 0); - } - public TFStrongholdPieceWeight(Class par1Class, int weight, int limit, int minDepth) - { - this.pieceClass = par1Class; - this.pieceWeight = weight; - this.instancesLimit = limit; - this.minimumDepth = minDepth; - } - - public boolean isDeepEnough(int par1) - { - return canSpawnMoreStructures() && par1 >= this.minimumDepth; - } - - public boolean canSpawnMoreStructures() - { - return this.instancesLimit == 0 || this.instancesSpawned < this.instancesLimit; - } + + public final Factory factory; + public final int pieceWeight; + public int instancesSpawned; + + /** + * How many Structure Pieces of this type may spawn in a structure + */ + public int instancesLimit; + public int minimumDepth; + + public TFStrongholdPieceWeight(Factory factory, int weight, int limit) { + this(factory, weight, limit, 0); + } + + public TFStrongholdPieceWeight(Factory factory, int weight, int limit, int minDepth) { + this.factory = factory; + this.pieceWeight = weight; + this.instancesLimit = limit; + this.minimumDepth = minDepth; + } + + public boolean isDeepEnough(int depth) { + return canSpawnMoreStructures() && depth >= this.minimumDepth; + } + + public boolean canSpawnMoreStructures() { + return this.instancesLimit == 0 || this.instancesSpawned < this.instancesLimit; + } } diff --git a/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieces.java b/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieces.java index 741db82c6c..58ee320bed 100644 --- a/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieces.java +++ b/src/main/java/twilightforest/structures/stronghold/TFStrongholdPieces.java @@ -1,188 +1,139 @@ package twilightforest.structures.stronghold; -import java.lang.reflect.InvocationTargetException; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.gen.structure.MapGenStructureIO; +import net.minecraft.world.gen.structure.StructureComponent; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.structures.start.StructureStartKnightStronghold; + import java.util.ArrayList; import java.util.List; import java.util.Random; -import twilightforest.structures.StructureTFComponent; -import net.minecraft.world.gen.structure.MapGenStructureIO; -import net.minecraft.world.gen.structure.StructureComponent; - public class TFStrongholdPieces { - private static final TFStrongholdPieceWeight[] pieceWeightArray = new TFStrongholdPieceWeight[] { - new TFStrongholdPieceWeight(ComponentTFStrongholdSmallHallway.class, 40, 0), - new TFStrongholdPieceWeight(ComponentTFStrongholdLeftTurn.class, 20, 0), - new TFStrongholdPieceWeight(ComponentTFStrongholdCrossing.class, 10, 4), - new TFStrongholdPieceWeight(ComponentTFStrongholdRightTurn.class, 20, 0), - new TFStrongholdPieceWeight(ComponentTFStrongholdDeadEnd.class, 5, 0), - new TFStrongholdPieceWeight(ComponentTFStrongholdBalconyRoom.class, 10, 3, 2), - new TFStrongholdPieceWeight(ComponentTFStrongholdTrainingRoom.class, 10, 2), - new TFStrongholdPieceWeight(ComponentTFStrongholdSmallStairs.class, 10, 0), - new TFStrongholdPieceWeight(ComponentTFStrongholdTreasureCorridor.class, 5, 0), - new TFStrongholdPieceWeight(ComponentTFStrongholdAtrium.class, 5, 2, 3), - new TFStrongholdPieceWeight(ComponentTFStrongholdFoundry.class, 5, 1, 4), - new TFStrongholdPieceWeight(ComponentTFStrongholdTreasureRoom.class, 5, 1, 4), - new TFStrongholdPieceWeight(ComponentTFStrongholdBossRoom.class, 10, 1, 4)}; + private static final TFStrongholdPieceWeight[] pieceWeightArray = new TFStrongholdPieceWeight[]{ + new TFStrongholdPieceWeight(ComponentTFStrongholdSmallHallway::new, 40, 0), + new TFStrongholdPieceWeight(ComponentTFStrongholdLeftTurn::new, 20, 0), + new TFStrongholdPieceWeight(ComponentTFStrongholdCrossing::new, 10, 4), + new TFStrongholdPieceWeight(ComponentTFStrongholdRightTurn::new, 20, 0), + new TFStrongholdPieceWeight(ComponentTFStrongholdDeadEnd::new, 5, 0), + new TFStrongholdPieceWeight(ComponentTFStrongholdBalconyRoom::new, 10, 3, 2), + new TFStrongholdPieceWeight(ComponentTFStrongholdTrainingRoom::new, 10, 2), + new TFStrongholdPieceWeight(ComponentTFStrongholdSmallStairs::new, 10, 0), + new TFStrongholdPieceWeight(ComponentTFStrongholdTreasureCorridor::new, 5, 0), + new TFStrongholdPieceWeight(ComponentTFStrongholdAtrium::new, 5, 2, 3), + new TFStrongholdPieceWeight(ComponentTFStrongholdFoundry::new, 5, 1, 4), + new TFStrongholdPieceWeight(ComponentTFStrongholdTreasureRoom::new, 5, 1, 4), + new TFStrongholdPieceWeight(ComponentTFStrongholdBossRoom::new, 10, 1, 4)}; private List pieceList; static int totalWeight = 0; - private static Class lastPieceMade; - - public static void registerPieces() - { - MapGenStructureIO.func_143031_a(ComponentTFStrongholdSmallHallway.class, "TFSSH"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdLeftTurn.class, "TFSLT"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdCrossing.class, "TFSCr"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdRightTurn.class, "TFSRT"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdDeadEnd.class, "TFSDE"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdBalconyRoom.class, "TFSBR"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdTrainingRoom.class, "TFSTR"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdSmallStairs.class, "TFSSS"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdTreasureCorridor.class, "TFSTC"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdAtrium.class, "TFSAt"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdFoundry.class, "TFSFo"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdTreasureRoom.class, "TFTreaR"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdBossRoom.class, "TFSBR"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdAccessChamber.class, "TFSAC"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdEntrance.class, "TFSEnter"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdUpperAscender.class, "TFSUA"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdUpperLeftTurn.class, "TFSULT"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdUpperRightTurn.class, "TFSURT"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdUpperCorridor.class, "TFSUCo"); - MapGenStructureIO.func_143031_a(ComponentTFStrongholdUpperTIntersection.class, "TFSUTI"); - MapGenStructureIO.func_143031_a(StructureTFStrongholdShield.class, "TFSShield"); - } - - /** - * sets up Arrays with the Structure pieces and their weights - */ - public void prepareStructurePieces() - { - pieceList = new ArrayList(); - - for (TFStrongholdPieceWeight piece : pieceWeightArray) - { - piece.instancesSpawned = 0; - pieceList.add(piece); - } - } - - public void markBossRoomUsed() - { - // let's assume the boss room is the last one on the list - //System.out.println("Removing " + pieceList.get(pieceList.size() - 1).pieceClass); - - pieceList.remove(pieceList.size() - 1); - } - - - private boolean hasMoreLimitedPieces() - { - boolean flag = false; - totalWeight = 0; - - for (TFStrongholdPieceWeight piece : pieceList) - { - totalWeight += piece.pieceWeight; - - if (piece.instancesLimit > 0 && piece.instancesSpawned < piece.instancesLimit) - { - flag = true; - } - } - - return flag; - } - - @SuppressWarnings("rawtypes") - public StructureTFStrongholdComponent getNextComponent(StructureComponent parent, List list, Random random, int index, int facing, int x, int y, int z) - { - if (!hasMoreLimitedPieces()) - { - return null; - } - else - { - // repeat up to 5 times if we're not getting the right thing - for (int i = 0; i < 5; i++) - { - int counter = random.nextInt(totalWeight); - - for (TFStrongholdPieceWeight piece : pieceList) - { - counter -= piece.pieceWeight; - - if (counter < 0) - { - - if (!piece.isDeepEnough(index) || piece.pieceClass == lastPieceMade) - { - break; - } - - // we're here! - StructureTFStrongholdComponent component = instantiateComponent(piece.pieceClass, index, facing, x, y, z); - - if (StructureComponent.findIntersecting(list, component.getBoundingBox()) == null) - { - ++piece.instancesSpawned; - - if (!piece.canSpawnMoreStructures()) - { - pieceList.remove(piece); - } - - lastPieceMade = piece.pieceClass; - - return component; - } - } - } - } - } - - // dead end? - StructureTFStrongholdComponent deadEnd = new ComponentTFStrongholdDeadEnd(index, facing, x, y, z); - - if (StructureComponent.findIntersecting(list, deadEnd.getBoundingBox()) == null) - { - return deadEnd; - } - else - { - return null; - } - } - - private static StructureTFStrongholdComponent instantiateComponent(Class pieceClass, int index, int facing, int x, int y, int z) { - try { - return (StructureTFStrongholdComponent) pieceClass.getConstructor(int.class, int.class, int.class, int.class, int.class).newInstance(index, facing, x, y, z); - } catch (InstantiationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvocationTargetException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (NoSuchMethodException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + private static TFStrongholdPieceWeight lastPieceMade; + + public static void registerPieces() { + MapGenStructureIO.registerStructure(StructureStartKnightStronghold.class, "TFKSt"); + + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdSmallHallway.class, "TFSSH"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdLeftTurn.class, "TFSLT"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdCrossing.class, "TFSCr"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdRightTurn.class, "TFSRT"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdDeadEnd.class, "TFSDE"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdBalconyRoom.class, "TFSBR"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdTrainingRoom.class, "TFSTR"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdSmallStairs.class, "TFSSS"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdTreasureCorridor.class, "TFSTC"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdAtrium.class, "TFSAt"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdFoundry.class, "TFSFo"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdTreasureRoom.class, "TFTreaR"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdBossRoom.class, "TFSBR"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdAccessChamber.class, "TFSAC"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdEntrance.class, "TFSEnter"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdUpperAscender.class, "TFSUA"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdUpperLeftTurn.class, "TFSULT"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdUpperRightTurn.class, "TFSURT"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdUpperCorridor.class, "TFSUCo"); + MapGenStructureIO.registerStructureComponent(ComponentTFStrongholdUpperTIntersection.class, "TFSUTI"); + MapGenStructureIO.registerStructureComponent(StructureTFStrongholdShield.class, "TFSShield"); + } + + /** + * sets up Arrays with the Structure pieces and their weights + */ + public void prepareStructurePieces() { + pieceList = new ArrayList<>(); + + for (TFStrongholdPieceWeight piece : pieceWeightArray) { + piece.instancesSpawned = 0; + pieceList.add(piece); } - - //// attempted = new ComponentTFStrongholdRoom(index, nFacing, nx, ny, nz); + } - return null; + public void markBossRoomUsed() { + // let's assume the boss room is the last one on the list + pieceList.remove(pieceList.size() - 1); } + private boolean hasMoreLimitedPieces() { + boolean flag = false; + totalWeight = 0; + + for (TFStrongholdPieceWeight piece : pieceList) { + totalWeight += piece.pieceWeight; + + if (piece.instancesLimit > 0 && piece.instancesSpawned < piece.instancesLimit) { + flag = true; + } + } + + return flag; + } + + public StructureTFStrongholdComponent getNextComponent(StructureComponent parent, List list, Random random, TFFeature feature, int index, EnumFacing facing, int x, int y, int z) { + if (!hasMoreLimitedPieces()) { + return null; + } else { + // repeat up to 5 times if we're not getting the right thing + for (int i = 0; i < 5; i++) { + int counter = random.nextInt(totalWeight); + + for (TFStrongholdPieceWeight piece : pieceList) { + counter -= piece.pieceWeight; + + if (counter < 0) { + + if (!piece.isDeepEnough(index) || piece == lastPieceMade) { + break; + } + + // we're here! + StructureTFStrongholdComponent component = piece.factory.newInstance(feature, index, facing, x, y, z); + + if (StructureComponent.findIntersecting(list, component.getBoundingBox()) == null) { + ++piece.instancesSpawned; + + if (!piece.canSpawnMoreStructures()) { + pieceList.remove(piece); + } + + lastPieceMade = piece; + + return component; + } + } + } + } + } + + // dead end? + StructureTFStrongholdComponent deadEnd = new ComponentTFStrongholdDeadEnd(parent instanceof StructureTFComponentOld ? ((StructureTFComponentOld)parent).getFeatureType() : TFFeature.NOTHING, index, facing, x, y, z); + + if (StructureComponent.findIntersecting(list, deadEnd.getBoundingBox()) == null) { + return deadEnd; + } else { + return null; + } + } } diff --git a/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudCastle.java b/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudCastle.java index ed140dd984..0d44a3ee7d 100644 --- a/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudCastle.java +++ b/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudCastle.java @@ -1,66 +1,61 @@ package twilightforest.structures.trollcave; -import java.util.List; -import java.util.Random; - import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; import twilightforest.entity.EntityTFArmoredGiant; import twilightforest.entity.EntityTFGiantMiner; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.StructureTFComponentOld; -public class ComponentTFCloudCastle extends StructureTFComponent { +import java.util.List; +import java.util.Random; + +public class ComponentTFCloudCastle extends StructureTFComponentOld { private boolean minerPlaced = false; private boolean warriorPlaced = false; - public ComponentTFCloudCastle() { } - - public ComponentTFCloudCastle(int index, int x, int y, int z) { - super(index); - this.setCoordBaseMode(0); - - - // adjust x, y, z - x = (x >> 2) << 2; - y = (y >> 2) << 2; - z = (z >> 2) << 2; - + public ComponentTFCloudCastle() { + } + + public ComponentTFCloudCastle(TFFeature feature, int index, int x, int y, int z) { + super(feature, index); + this.setCoordBaseMode(EnumFacing.SOUTH); + + // round to nearest mult of 4 + x &= ~0b11; + y &= ~0b11; + z &= ~0b11; + // spawn list! this.spawnListIndex = 1; - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -8, 0, -8, 16, 16, 16, 0); + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -8, 0, -8, 16, 16, 16, EnumFacing.SOUTH); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setBoolean("minerPlaced", this.minerPlaced); - par1NBTTagCompound.setBoolean("warriorPlaced", this.warriorPlaced); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setBoolean("minerPlaced", this.minerPlaced); + tagCompound.setBoolean("warriorPlaced", this.warriorPlaced); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.minerPlaced = par1NBTTagCompound.getBoolean("minerPlaced"); - this.warriorPlaced = par1NBTTagCompound.getBoolean("warriorPlaced"); - + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.minerPlaced = tagCompound.getBoolean("minerPlaced"); + this.warriorPlaced = tagCompound.getBoolean("warriorPlaced"); } - - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { + public void buildComponent(StructureComponent parent, List list, Random rand) { // up to two trees // tree in x direction boolean plus = rand.nextBoolean(); @@ -77,54 +72,58 @@ public void buildComponent(StructureComponent parent, List list, Random rand) { treeZ.buildComponent(this, list, rand); } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make haus - this.fillWithMetadataBlocks(world, sbb, 0, -4, 0, 15, -1, 15, TFBlocks.fluffyCloud, 0,TFBlocks.fluffyCloud, 0, false); - this.fillWithMetadataBlocks(world, sbb, 0, 0, 0, 15, 11, 15, TFBlocks.giantCobble, 0, TFBlocks.giantCobble, 0, false); - this.fillWithMetadataBlocks(world, sbb, 0, 12, 0, 15, 15, 15, TFBlocks.giantLog, 0, TFBlocks.giantLog, 0, false); - - + this.fillWithBlocks(world, sbb, 0, -4, 0, 15, -1, 15, TFBlocks.fluffy_cloud.getDefaultState(), TFBlocks.fluffy_cloud.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 0, 0, 0, 15, 11, 15, TFBlocks.giant_cobblestone.getDefaultState(), TFBlocks.giant_cobblestone.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 0, 12, 0, 15, 15, 15, TFBlocks.giant_log.getDefaultState(), TFBlocks.giant_log.getDefaultState(), false); + + // clear inside this.fillWithAir(world, sbb, 4, 0, 4, 11, 11, 11); // clear door this.fillWithAir(world, sbb, 0, 0, 4, 4, 7, 7); - - + + // add giants if (!this.minerPlaced) { int bx = this.getXWithOffset(6, 6); int by = this.getYWithOffset(0); int bz = this.getZWithOffset(6, 6); - - if (sbb.isVecInside(bx, by, bz)) { + BlockPos pos = new BlockPos(bx, by, bz); + + if (sbb.isVecInside(pos)) { this.minerPlaced = true; - + EntityTFGiantMiner miner = new EntityTFGiantMiner(world); miner.setPosition(bx, by, bz); - miner.makeNonDespawning(); - - world.spawnEntityInWorld(miner); + miner.enablePersistence(); + miner.onInitialSpawn(world.getDifficultyForLocation(pos), null); + + world.spawnEntity(miner); } } if (!this.warriorPlaced) { int bx = this.getXWithOffset(9, 9); int by = this.getYWithOffset(0); int bz = this.getZWithOffset(9, 9); - - if (sbb.isVecInside(bx, by, bz)) { + BlockPos pos = new BlockPos(bx, by, bz); + + if (sbb.isVecInside(pos)) { this.warriorPlaced = true; - + EntityTFArmoredGiant warrior = new EntityTFArmoredGiant(world); warrior.setPosition(bx, by, bz); - warrior.makeNonDespawning(); - - world.spawnEntityInWorld(warrior); + warrior.enablePersistence(); + warrior.onInitialSpawn(world.getDifficultyForLocation(pos), null); + + world.spawnEntity(warrior); } } - + return true; } diff --git a/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudTree.java b/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudTree.java index 79a158d564..930c19f1df 100644 --- a/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudTree.java +++ b/src/main/java/twilightforest/structures/trollcave/ComponentTFCloudTree.java @@ -1,27 +1,28 @@ package twilightforest.structures.trollcave; -import java.util.Random; - +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.StructureTFComponentOld; +import java.util.Random; -public class ComponentTFCloudTree extends StructureTFComponent { - - public ComponentTFCloudTree() {} +public class ComponentTFCloudTree extends StructureTFComponentOld { + + public ComponentTFCloudTree() { + } public ComponentTFCloudTree(int index, int x, int y, int z) { - this.setCoordBaseMode(0); - + this.setCoordBaseMode(EnumFacing.SOUTH); + // adjust x, y, z - x = (x >> 2) << 2; - y = (y >> 2) << 2; - z = (z >> 2) << 2; - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -8, 0, -8, 20, 28, 20, 0); + x = (x >> 2) << 2; + y = (y >> 2) << 2; + z = (z >> 2) << 2; + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -8, 0, -8, 20, 28, 20, EnumFacing.SOUTH); // spawn list! this.spawnListIndex = 1; @@ -29,18 +30,18 @@ public ComponentTFCloudTree(int index, int x, int y, int z) { @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - + // leaves - this.fillWithMetadataBlocks(world, sbb, 0, 12, 0, 19, 19, 19, TFBlocks.giantLeaves, 0,TFBlocks.giantLeaves, 0, false); - this.fillWithMetadataBlocks(world, sbb, 4, 20, 4, 15, 23, 15, TFBlocks.giantLeaves, 0,TFBlocks.giantLeaves, 0, false); - this.fillWithMetadataBlocks(world, sbb, 8, 24, 4, 11, 27, 15, TFBlocks.giantLeaves, 0,TFBlocks.giantLeaves, 0, false); - this.fillWithMetadataBlocks(world, sbb, 4, 24, 8, 15, 27, 11, TFBlocks.giantLeaves, 0,TFBlocks.giantLeaves, 0, false); - + this.fillWithBlocks(world, sbb, 0, 12, 0, 19, 19, 19, TFBlocks.giant_leaves.getDefaultState(), TFBlocks.giant_leaves.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 4, 20, 4, 15, 23, 15, TFBlocks.giant_leaves.getDefaultState(), TFBlocks.giant_leaves.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 8, 24, 4, 11, 27, 15, TFBlocks.giant_leaves.getDefaultState(), TFBlocks.giant_leaves.getDefaultState(), false); + this.fillWithBlocks(world, sbb, 4, 24, 8, 15, 27, 11, TFBlocks.giant_leaves.getDefaultState(), TFBlocks.giant_leaves.getDefaultState(), false); + // trunk - this.fillWithMetadataBlocks(world, sbb, 8, 0, 8, 11, 23, 11, TFBlocks.giantLog, 0,TFBlocks.giantLog, 0, false); - + this.fillWithBlocks(world, sbb, 8, 0, 8, 11, 23, 11, TFBlocks.giant_log.getDefaultState(), TFBlocks.giant_log.getDefaultState(), false); + // cloud base - this.fillWithMetadataBlocks(world, sbb, 8, -4, 8, 11, -1, 11, TFBlocks.fluffyCloud, 0,TFBlocks.fluffyCloud, 0, false); + this.fillWithBlocks(world, sbb, 8, -4, 8, 11, -1, 11, TFBlocks.fluffy_cloud.getDefaultState(), TFBlocks.fluffy_cloud.getDefaultState(), false); return true; } diff --git a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveConnect.java b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveConnect.java index 937a012b3b..57500dac25 100644 --- a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveConnect.java +++ b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveConnect.java @@ -1,149 +1,143 @@ package twilightforest.structures.trollcave; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; +import java.util.List; +import java.util.Random; public class ComponentTFTrollCaveConnect extends ComponentTFTrollCaveMain { - - protected boolean [] openingTowards = new boolean[] {false, false, true, false}; - public ComponentTFTrollCaveConnect() { } + protected boolean[] openingTowards = {false, false, true, false}; + + public ComponentTFTrollCaveConnect() {} - public ComponentTFTrollCaveConnect(int index, int x, int y, int z, int caveSize, int caveHeight, int direction) { - super(index); + public ComponentTFTrollCaveConnect(TFFeature feature, int index, int x, int y, int z, int caveSize, int caveHeight, EnumFacing direction) { + super(feature, index); this.size = caveSize; this.height = caveHeight; this.setCoordBaseMode(direction); - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, size - 1, direction); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, size - 1, direction); } - - /** - * Save to NBT - */ - @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - par1NBTTagCompound.setBoolean("openingTowards0", this.openingTowards[0]); - par1NBTTagCompound.setBoolean("openingTowards1", this.openingTowards[1]); - par1NBTTagCompound.setBoolean("openingTowards2", this.openingTowards[2]); - par1NBTTagCompound.setBoolean("openingTowards3", this.openingTowards[3]); + @Override + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + tagCompound.setBoolean("openingTowards0", this.openingTowards[0]); + tagCompound.setBoolean("openingTowards1", this.openingTowards[1]); + tagCompound.setBoolean("openingTowards2", this.openingTowards[2]); + tagCompound.setBoolean("openingTowards3", this.openingTowards[3]); } - - /** - * Load from NBT - */ + @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - - // too lazy to do this as a loop - this.openingTowards[0] = par1NBTTagCompound.getBoolean("openingTowards0"); - this.openingTowards[1] = par1NBTTagCompound.getBoolean("openingTowards1"); - this.openingTowards[2] = par1NBTTagCompound.getBoolean("openingTowards2"); - this.openingTowards[3] = par1NBTTagCompound.getBoolean("openingTowards3"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + + // too lazy to do this as a loop + this.openingTowards[0] = tagCompound.getBoolean("openingTowards0"); + this.openingTowards[1] = tagCompound.getBoolean("openingTowards1"); + this.openingTowards[2] = tagCompound.getBoolean("openingTowards2"); + this.openingTowards[3] = tagCompound.getBoolean("openingTowards3"); } - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { + public void buildComponent(StructureComponent parent, List list, Random rand) { // make 4 caves if (this.getComponentType() < 3) { + for (final Rotation rotation : RotationUtil.ROTATIONS) { + BlockPos dest = getValidOpening(rand, 2, rotation); - for (int i = 0; i < 4; i++) { - ChunkCoordinates dest = getValidOpening(rand, 2, i); - - if (rand.nextBoolean() || !makeGardenCave(list, rand, this.getComponentType() + 1, dest.posX, dest.posY, dest.posZ, 30, 15, i)) { - makeSmallerCave(list, rand, this.getComponentType() + 1, dest.posX, dest.posY, dest.posZ, 20, 15, i); + if (rand.nextBoolean() || !makeGardenCave(list, rand, this.getComponentType() + 1, dest.getX(), dest.getY(), dest.getZ(), 30, 15, rotation)) { + makeSmallerCave(list, rand, this.getComponentType() + 1, dest.getX(), dest.getY(), dest.getZ(), 20, 15, rotation); } - } } } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isBoundingBoxOutOfHighlands(world, sbb)) { - return false; - } else { - // clear inside - hollowCaveMiddle(world, sbb, rand, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1); - - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - // wall decorations - for (int i = 0; i < 4; i++) { - if (!this.openingTowards[i]) { - decorateWall(world, sbb, decoRNG, i); - } - } - - decoRNG.setSeed(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - // stone stalactites! - for (int i = 0; i < 32; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generateBlockStalactite(world, decoRNG, Blocks.stone, 0.5F, true, dest.posX, 3, dest.posZ, sbb); - } - // stone stalagmites! - for (int i = 0; i < 8; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generateBlockStalactite(world, decoRNG, Blocks.stone, 0.5F, false, dest.posX, 3, dest.posZ, sbb); - } - - // possible treasure - decoRNG.setSeed(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - if (this.countExits() == 1 && decoRNG.nextInt(3) == 0) { - // treasure! - makeTreasureCrate(world, decoRNG, sbb); - } else if (decoRNG.nextInt(3) == 0) { - // or a monolith! - makeMonolith(world, decoRNG, sbb); - } - - return true; - } + + if (this.isBoundingBoxOutsideBiomes(world, sbb, highlands)) { + return false; + } + + // clear inside + hollowCaveMiddle(world, sbb, rand, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1); + + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + // wall decorations + for (Rotation rotation : RotationUtil.ROTATIONS) { + if (!this.openingTowards[rotation.ordinal()]) { + decorateWall(world, sbb, decoRNG, rotation); + } + } + + decoRNG.setSeed(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + // stone stalactites! + for (int i = 0; i < 32; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generateBlockStalactite(world, decoRNG, Blocks.STONE, 0.5F, true, dest.getX(), 3, dest.getZ(), sbb); + } + // stone stalagmites! + for (int i = 0; i < 8; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generateBlockStalactite(world, decoRNG, Blocks.STONE, 0.5F, false, dest.getX(), 3, dest.getZ(), sbb); + } + + // possible treasure + decoRNG.setSeed(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + if (this.countExits() == 1 && decoRNG.nextInt(3) == 0) { + // treasure! + makeTreasureCrate(world, decoRNG, sbb); + } else if (decoRNG.nextInt(3) == 0) { + // or a monolith! + makeMonolith(world, decoRNG, sbb); + } + + return true; } protected void makeMonolith(World world, Random rand, StructureBoundingBox sbb) { // monolith int mid = this.size / 2; int height = 7 + rand.nextInt(8); - int rotation = rand.nextInt(4); - - this.fillBlocksRotated(world, sbb, mid - 1, 0, mid - 1, mid - 1, height, mid - 1, Blocks.obsidian, 0, rotation); - this.fillBlocksRotated(world, sbb, mid + 0, 0, mid - 1, mid + 0, height - 2, mid - 1, Blocks.obsidian, 0, rotation); - this.fillBlocksRotated(world, sbb, mid - 1, 0, mid + 0, mid - 1, height - 2, mid + 0, Blocks.obsidian, 0, rotation); - this.fillBlocksRotated(world, sbb, mid + 0, 0, mid + 0, mid + 0, height - 4, mid + 0, Blocks.obsidian, 0, rotation); + Rotation rotation = RotationUtil.ROTATIONS[rand.nextInt(4)]; + + this.fillBlocksRotated(world, sbb, mid - 1, 0, mid - 1, mid - 1, height, mid - 1, Blocks.OBSIDIAN.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, mid + 0, 0, mid - 1, mid + 0, height - 2, mid - 1, Blocks.OBSIDIAN.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, mid - 1, 0, mid + 0, mid - 1, height - 2, mid + 0, Blocks.OBSIDIAN.getDefaultState(), rotation); + this.fillBlocksRotated(world, sbb, mid + 0, 0, mid + 0, mid + 0, height - 4, mid + 0, Blocks.OBSIDIAN.getDefaultState(), rotation); } private int countExits() { int count = 0; for (int i = 0; i < this.openingTowards.length; i++) { - if (this.openingTowards[i] == true) { + if (this.openingTowards[i]) { count++; } } return count; } - private void decorateWall(World world, StructureBoundingBox sbb, Random decoRNG, int rotation) { - + private void decorateWall(World world, StructureBoundingBox sbb, Random decoRNG, Rotation rotation) { if (decoRNG.nextBoolean()) { + //FIXME: AtomicBlom: Don't do this, bring rotation all the way through. decorateBracketMushrooms(world, sbb, decoRNG, rotation); } else if (decoRNG.nextBoolean()) { decorateStoneFormation(world, sbb, decoRNG, rotation); @@ -151,15 +145,14 @@ private void decorateWall(World world, StructureBoundingBox sbb, Random decoRNG, } else { decorateStoneProjection(world, sbb, decoRNG, rotation); } - } - private void decorateStoneFormation(World world, StructureBoundingBox sbb, Random decoRNG, int rotation) { + private void decorateStoneFormation(World world, StructureBoundingBox sbb, Random decoRNG, Rotation rotation) { int z = 5 + decoRNG.nextInt(7); int startY = 1 + decoRNG.nextInt(2); - + for (int y = startY; y < this.height; y += 2) { - + int width = 1; int depth = 1 + (decoRNG.nextInt(3) == 0 ? 1 : 0); makeSingleStoneFormation(world, sbb, decoRNG, rotation, z, y, width, depth); @@ -172,45 +165,45 @@ private void decorateStoneFormation(World world, StructureBoundingBox sbb, Rando } } - private void makeSingleStoneFormation(World world, StructureBoundingBox sbb, Random decoRNG, int rotation, int z, int y, int width, int depth) { + private void makeSingleStoneFormation(World world, StructureBoundingBox sbb, Random decoRNG, Rotation rotation, int z, int y, int width, int depth) { if (decoRNG.nextInt(8) == 0) { - this.fillBlocksRotated(world, sbb, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, Blocks.obsidian, 0, rotation); + this.fillBlocksRotated(world, sbb, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, Blocks.OBSIDIAN.getDefaultState(), rotation); } else if (decoRNG.nextInt(4) == 0) { - this.fillBlocksRotated(world, sbb, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, TFBlocks.trollSteinn, 0, rotation); + this.fillBlocksRotated(world, sbb, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, TFBlocks.trollsteinn.getDefaultState(), rotation); } else { // normal stone - this.fillBlocksRotated(world, sbb, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, Blocks.stone, 0, rotation); + this.fillBlocksRotated(world, sbb, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, Blocks.STONE.getDefaultState(), rotation); } - //this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.5F, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, TFBlocks.trollSteinn, 0, Blocks.stone, 0, rotation); + //this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.5F, size - (depth + 1), y - width, z - width, size - 1, y + width, z + width, TFBlocks.trollsteinn, 0, Blocks.STONE, 0, rotation); } - private void decorateStoneProjection(World world, StructureBoundingBox sbb, Random decoRNG, int rotation) { + private void decorateStoneProjection(World world, StructureBoundingBox sbb, Random decoRNG, Rotation rotation) { int z = 7 + decoRNG.nextInt(3) - decoRNG.nextInt(3); int y = 7 + decoRNG.nextInt(3) - decoRNG.nextInt(3); - - this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.25F, size - 9, y, z, size - 2, y + 3, z + 3, TFBlocks.trollSteinn, 0, Blocks.stone, 0, rotation); + + this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.25F, size - 9, y, z, size - 2, y + 3, z + 3, TFBlocks.trollsteinn.getDefaultState(), Blocks.STONE.getDefaultState(), rotation); if (decoRNG.nextBoolean()) { // down - this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.25F, size - 9, 1, z, size - 6, y - 1, z + 3, TFBlocks.trollSteinn, 0, Blocks.stone, 0, rotation); + this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.25F, size - 9, 1, z, size - 6, y - 1, z + 3, TFBlocks.trollsteinn.getDefaultState(), Blocks.STONE.getDefaultState(), rotation); } else { // up - this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.25F, size - 9, y + 4, z, size - 6, height - 2, z + 3, TFBlocks.trollSteinn, 0, Blocks.stone, 0, rotation); + this.randomlyFillBlocksRotated(world, sbb, decoRNG, 0.25F, size - 9, y + 4, z, size - 6, height - 2, z + 3, TFBlocks.trollsteinn.getDefaultState(), Blocks.STONE.getDefaultState(), rotation); } } /** * Decorate with a patch of bracket fungi */ - private void decorateBracketMushrooms(World world, StructureBoundingBox sbb, Random decoRNG, int rotation) { + private void decorateBracketMushrooms(World world, StructureBoundingBox sbb, Random decoRNG, Rotation rotation) { int z = 5 + decoRNG.nextInt(7); int startY = 1 + decoRNG.nextInt(4); - + for (int y = startY; y < this.height; y += 2) { - + int width = 1 + decoRNG.nextInt(2) + decoRNG.nextInt(2); int depth = 1 + decoRNG.nextInt(2) + decoRNG.nextInt(2); - Block mushBlock = ((decoRNG.nextInt(3) == 0) ? TFBlocks.hugeGloomBlock : (decoRNG.nextBoolean() ? Blocks.brown_mushroom_block : Blocks.red_mushroom_block)); - makeSingleBracketMushroom(world, sbb, rotation, z, y, width, depth, mushBlock); + Block mushBlock = ((decoRNG.nextInt(3) == 0) ? TFBlocks.huge_mushgloom : (decoRNG.nextBoolean() ? Blocks.BROWN_MUSHROOM_BLOCK : Blocks.RED_MUSHROOM_BLOCK)); + makeSingleBracketMushroom(world, sbb, rotation, z, y, width, depth, mushBlock.getDefaultState()); // wiggle a little z += decoRNG.nextInt(4) - decoRNG.nextInt(4); @@ -223,79 +216,39 @@ private void decorateBracketMushrooms(World world, StructureBoundingBox sbb, Ran /** * Make one mushroom with the specified parameters */ - private void makeSingleBracketMushroom(World world, StructureBoundingBox sbb, int rotation, int z, int y, int width, int depth, Block mushBlock) { - - this.fillBlocksRotated(world, sbb, size - depth, y, z - (width - 1), size - 2, y, z + (width - 1), mushBlock, 5, rotation); + private void makeSingleBracketMushroom(World world, StructureBoundingBox sbb, Rotation rotation, int z, int y, int width, int depth, IBlockState mushBlock) { + + this.fillBlocksRotated(world, sbb, size - depth, y, z - (width - 1), size - 2, y, z + (width - 1), mushBlock.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER), rotation); + + this.fillBlocksRotated(world, sbb, size - (depth + 1), y, z - (width - 1), size - (depth + 1), y, z + (width - 1), getMushroomState(mushBlock, BlockHugeMushroom.EnumType.EAST), rotation); - this.fillBlocksRotated(world, sbb, size - (depth + 1), y, z - (width - 1), size - (depth + 1), y, z + (width - 1), mushBlock, getMushroomMetaFor(4, rotation), rotation); - + final IBlockState northMushroom = getMushroomState(mushBlock, BlockHugeMushroom.EnumType.SOUTH); for (int d = 0; d < (depth - 1); d++) { - this.placeBlockRotated(world, mushBlock, getMushroomMetaFor(2, rotation), size - (2 + d), y, z - width, rotation, sbb); + this.setBlockStateRotated(world, northMushroom, size - (2 + d), y, z - width, rotation, sbb); } - this.placeBlockRotated(world, mushBlock, getMushroomMetaFor(1, rotation), size - (depth + 1), y, z - width, rotation, sbb); + final IBlockState northWestMushroom = getMushroomState(mushBlock, BlockHugeMushroom.EnumType.SOUTH_EAST); + this.setBlockStateRotated(world, northWestMushroom, size - (depth + 1), y, z - width, rotation, sbb); + final IBlockState southMushroom = getMushroomState(mushBlock, BlockHugeMushroom.EnumType.NORTH); for (int d = 0; d < (depth - 1); d++) { - this.placeBlockRotated(world, mushBlock, getMushroomMetaFor(8, rotation), size - (2 + d), y, z + width, rotation, sbb); + this.setBlockStateRotated(world, southMushroom, size - (2 + d), y, z + width, rotation, sbb); } - this.placeBlockRotated(world, mushBlock, getMushroomMetaFor(7, rotation), size - (depth + 1), y, z + width, rotation, sbb); - - + final IBlockState southWestMushroom = getMushroomState(mushBlock, BlockHugeMushroom.EnumType.NORTH_EAST); + this.setBlockStateRotated(world, southWestMushroom, size - (depth + 1), y, z + width, rotation, sbb); } - - /** - * Hacky, incomplete method to generate mushroom block metadata - */ - private int getMushroomMetaFor(int meta, int rotation) { - if (meta > 0 && meta < 10) { - - int totalRot = (coordBaseMode + rotation) % 4; - - switch (totalRot) { - case 0: - return meta; - case 1: - switch (meta) { - case 1: - return 3; - case 2: - return 6; - case 4: - return 2; - case 7: - return 1; - case 8: - return 4; - } - case 2: - return 10 - (meta % 10); - case 3: - switch (meta) { - case 1: - return 7; - case 2: - return 4; - case 4: - return 8; - case 7: - return 9; - case 8: - return 6; - } - default: - return 15; - } - } else { - return meta; + private IBlockState getMushroomState(IBlockState mushroomBlockState, BlockHugeMushroom.EnumType defaultRotation) { + if (mushroomBlockState.getPropertyKeys().contains(BlockHugeMushroom.VARIANT)) { + return mushroomBlockState.withProperty(BlockHugeMushroom.VARIANT, defaultRotation); } - + return mushroomBlockState; } - protected boolean makeGardenCave(List list, Random rand, int index, int x, int y, int z, int caveSize, int caveHeight, int rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; - ChunkCoordinates dest = offsetTowerCCoords(x, y, z, caveSize, direction); - - ComponentTFTrollCaveMain cave = new ComponentTFTrollCaveGarden(index, dest.posX, dest.posY, dest.posZ, caveSize, caveHeight, direction); + protected boolean makeGardenCave(List list, Random rand, int index, int x, int y, int z, int caveSize, int caveHeight, Rotation rotation) { + EnumFacing direction = getStructureRelativeRotation(rotation); + BlockPos dest = offsetTowerCCoords(x, y, z, caveSize, direction); + + ComponentTFTrollCaveMain cave = new ComponentTFTrollCaveGarden(getFeatureType(), index, dest.getX(), dest.getY(), dest.getZ(), caveSize, caveHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, cave.getBoundingBox()); StructureComponent otherGarden = findNearbyGarden(list, cave.getBoundingBox()); @@ -303,19 +256,16 @@ protected boolean makeGardenCave(List list, Random rand, int list.add(cave); cave.buildComponent(list.get(0), list, rand); //addOpening(x, y, z, rotation); - - this.openingTowards[rotation] = true; + + this.openingTowards[rotation.ordinal()] = true; return true; } - else - { - return false; - } + return false; } private StructureComponent findNearbyGarden(List list, StructureBoundingBox boundingBox) { - + StructureBoundingBox largeBox = new StructureBoundingBox(boundingBox); largeBox.minX -= 30; largeBox.minY -= 30; @@ -323,23 +273,22 @@ private StructureComponent findNearbyGarden(List list, Struc largeBox.maxX += 30; largeBox.maxY += 30; largeBox.maxZ += 30; - + for (StructureComponent component : list) { if (component instanceof ComponentTFTrollCaveGarden && component.getBoundingBox().intersectsWith(largeBox)) { - //System.out.println("found intersecting garden"); return component; } } - + return null; } - - protected boolean makeSmallerCave(List list, Random rand, int index, int x, int y, int z, int caveSize, int caveHeight, int rotation) { + + @Override + protected boolean makeSmallerCave(List list, Random rand, int index, int x, int y, int z, int caveSize, int caveHeight, Rotation rotation) { if (super.makeSmallerCave(list, rand, index, x, y, z, caveSize, caveHeight, rotation)) { - this.openingTowards[rotation] = true; + this.openingTowards[rotation.ordinal()] = true; return true; - } else { - return false; } + return false; } } diff --git a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveGarden.java b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveGarden.java index 0d552f011a..89e3d0fcd1 100644 --- a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveGarden.java +++ b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveGarden.java @@ -1,120 +1,110 @@ package twilightforest.structures.trollcave; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenBigMushroom; import net.minecraft.world.gen.feature.WorldGenerator; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.structures.StructureTFComponent; -import twilightforest.world.TFGenBigMushgloom; -import twilightforest.world.TFGenMyceliumBlob; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.world.feature.TFGenBigMushgloom; +import twilightforest.world.feature.TFGenMyceliumBlob; + +import java.util.List; +import java.util.Random; public class ComponentTFTrollCaveGarden extends ComponentTFTrollCaveMain { - - TFGenMyceliumBlob myceliumBlobGen = new TFGenMyceliumBlob(5); - TFGenMyceliumBlob dirtGen = new TFGenMyceliumBlob(Blocks.dirt, 5); - WorldGenBigMushroom bigMushroomGen = new WorldGenBigMushroom(); - TFGenBigMushgloom bigMushgloomGen = new TFGenBigMushgloom(); - - public ComponentTFTrollCaveGarden() { } + private TFGenMyceliumBlob myceliumBlobGen = new TFGenMyceliumBlob(5); + private TFGenMyceliumBlob dirtGen = new TFGenMyceliumBlob(Blocks.DIRT, 5); + private WorldGenBigMushroom bigMushroomGen = new WorldGenBigMushroom(); + private TFGenBigMushgloom bigMushgloomGen = new TFGenBigMushgloom(); - public ComponentTFTrollCaveGarden(int index, int x, int y, int z, int caveSize, int caveHeight, int direction) { - super(index); + public ComponentTFTrollCaveGarden() {} + + public ComponentTFTrollCaveGarden(TFFeature feature, int index, int x, int y, int z, int caveSize, int caveHeight, EnumFacing direction) { + super(feature, index); this.size = caveSize; this.height = caveHeight; this.setCoordBaseMode(direction); - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, size - 1, direction); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, 0, 0, 0, size - 1, height - 1, size - 1, direction); } - @SuppressWarnings({ "rawtypes" }) @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { + public void buildComponent(StructureComponent parent, List list, Random rand) { // add a cloud // ComponentTFTrollCloud cloud = new ComponentTFTrollCloud(1, boundingBox.minX + ((boundingBox.maxX - boundingBox.minX) / 2), rand.nextInt(64) + 160, boundingBox.minZ + ((boundingBox.maxZ - boundingBox.minZ) / 2)); // list.add(cloud); // cloud.buildComponent(this, list, rand); } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { - if (this.isBoundingBoxOutOfHighlands(world, sbb)) { - return false; - } else { - // clear inside - hollowCaveMiddle(world, sbb, rand, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1); - Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - - // treasure! - makeTreasureCrate(world, rand, sbb); - - // dirt! - for (int i = 0; i < 24; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generate(world, dirtGen, decoRNG, dest.posX, 1, dest.posZ, sbb); - } - - // mycelium! - for (int i = 0; i < 16; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generate(world, myceliumBlobGen, decoRNG, dest.posX, 1, dest.posZ, sbb); - } - - // uberous! - for (int i = 0; i < 16; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generate(world, uberousGen, decoRNG, dest.posX, 1, dest.posZ, sbb); - - generateAtSurface(world, uberousGen, decoRNG, dest.posX, 60, dest.posZ, sbb); - } - - // mushglooms first - for (int i = 0; i < 32; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generate(world, bigMushgloomGen, decoRNG, dest.posX, 1, dest.posZ, sbb); - } - - // mushrooms! - for (int i = 0; i < 64; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generate(world, bigMushroomGen, decoRNG, dest.posX, 1, dest.posZ, sbb); - } - - // stone stalactites! - for (int i = 0; i < 128; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generateBlockStalactite(world, decoRNG, Blocks.stone, 0.7F, true, dest.posX, 3, dest.posZ, sbb); - } - - - return true; - } + + if (this.isBoundingBoxOutsideBiomes(world, sbb, highlands)) { + return false; + } + + // clear inside + hollowCaveMiddle(world, sbb, rand, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1); + Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); + + // treasure! + makeTreasureCrate(world, rand, sbb); + + // dirt! + for (int i = 0; i < 24; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generate(world, dirtGen, decoRNG, dest.getX(), 1, dest.getZ(), sbb); + } + + // mycelium! + for (int i = 0; i < 16; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generate(world, myceliumBlobGen, decoRNG, dest.getX(), 1, dest.getZ(), sbb); + } + + // uberous! + for (int i = 0; i < 16; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generate(world, uberousGen, decoRNG, dest.getX(), 1, dest.getZ(), sbb); + + generateAtSurface(world, uberousGen, decoRNG, dest.getX(), 60, dest.getZ(), sbb); + } + + // mushglooms first + for (int i = 0; i < 32; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generate(world, bigMushgloomGen, decoRNG, dest.getX(), 1, dest.getZ(), sbb); + } + + // mushrooms! + for (int i = 0; i < 64; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generate(world, bigMushroomGen, decoRNG, dest.getX(), 1, dest.getZ(), sbb); + } + + // stone stalactites! + for (int i = 0; i < 128; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generateBlockStalactite(world, decoRNG, Blocks.STONE, 0.7F, true, dest.getX(), 3, dest.getZ(), sbb); + } + + return true; } - /** - * Use the generator at the specified coords - */ protected void generate(World world, WorldGenerator generator, Random rand, int x, int y, int z, StructureBoundingBox sbb) { // are the coordinates in our bounding box? - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz)) { - generator.generate(world, rand, dx, dy, dz); - } - } - - + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos)) { + generator.generate(world, rand, pos); + } + } } diff --git a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveMain.java b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveMain.java index 6c2e6af811..33c6febfce 100644 --- a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveMain.java +++ b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCaveMain.java @@ -1,102 +1,97 @@ package twilightforest.structures.trollcave; -import java.util.List; -import java.util.Random; - import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.feature.WorldGenerator; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; -import twilightforest.biomes.TFBiomeBase; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; +import twilightforest.biomes.TFBiomes; import twilightforest.block.TFBlocks; -import twilightforest.structures.StructureTFComponent; -import twilightforest.world.TFGenCaveStalactite; -import twilightforest.world.TFGenMyceliumBlob; +import twilightforest.structures.StructureTFComponentOld; +import twilightforest.util.RotationUtil; +import twilightforest.world.feature.TFGenCaveStalactite; +import twilightforest.world.feature.TFGenMyceliumBlob; + +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; + +public class ComponentTFTrollCaveMain extends StructureTFComponentOld { -public class ComponentTFTrollCaveMain extends StructureTFComponent { - protected int size; protected int height; - - public static final TFGenMyceliumBlob uberousGen = new TFGenMyceliumBlob(TFBlocks.uberousSoil, 4); - + public static final TFGenMyceliumBlob uberousGen = new TFGenMyceliumBlob(TFBlocks.uberous_soil, 4); - public ComponentTFTrollCaveMain() { } + public ComponentTFTrollCaveMain() {} - public ComponentTFTrollCaveMain(int index) { - super(index); + public ComponentTFTrollCaveMain(TFFeature feature, int index) { + super(feature, index); } + public ComponentTFTrollCaveMain(TFFeature feature, World world, Random rand, int i, int x, int y, int z) { + super(feature, i); + this.setCoordBaseMode(EnumFacing.SOUTH); - public ComponentTFTrollCaveMain(World world, Random rand, int i, int x, int y, int z) { - this.setCoordBaseMode(0); - // adjust y y += 10; - + this.size = 30; this.height = 20; - - int radius = this.size / 2; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -radius, -this.height, -radius, this.size, this.height, this.size, 0); + int radius = this.size / 2; + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -radius, -this.height, -radius, this.size, this.height, this.size, EnumFacing.SOUTH); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("size", this.size); - par1NBTTagCompound.setInteger("height", this.height); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("size", this.size); + tagCompound.setInteger("height", this.height); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.size = par1NBTTagCompound.getInteger("size"); - this.height = par1NBTTagCompound.getInteger("height"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + + this.size = tagCompound.getInteger("size"); + this.height = tagCompound.getInteger("height"); } - - @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { + public void buildComponent(StructureComponent parent, List list, Random rand) { // make 4 caves - for (int i = 0; i < 4; i++) { - ChunkCoordinates dest = getValidOpening(rand, 5, i); - - makeSmallerCave(list, rand, this.getComponentType() + 1, dest.posX, dest.posY, dest.posZ, 18, 15, i); - + for (final Rotation caveRotation : RotationUtil.ROTATIONS) { + BlockPos dest = getValidOpening(rand, 5, caveRotation); + makeSmallerCave(list, rand, this.getComponentType() + 1, dest.getX(), dest.getY(), dest.getZ(), 18, 15, caveRotation); } - + // add cloud castle - ComponentTFCloudCastle castle = new ComponentTFCloudCastle(this.getComponentType() + 1, boundingBox.minX + ((boundingBox.maxX - boundingBox.minX) / 2), 168, boundingBox.minZ + ((boundingBox.maxZ - boundingBox.minZ) / 2)); + ComponentTFCloudCastle castle = new ComponentTFCloudCastle(getFeatureType(), this.getComponentType() + 1, boundingBox.minX + ((boundingBox.maxX - boundingBox.minX) / 2), 168, boundingBox.minZ + ((boundingBox.maxZ - boundingBox.minZ) / 2)); list.add(castle); castle.buildComponent(this, list, rand); - + // add vault - ComponentTFTrollVault vault = new ComponentTFTrollVault(this.getComponentType() + 1, boundingBox.minX + ((boundingBox.maxX - boundingBox.minX) / 2), boundingBox.minY, boundingBox.minZ + ((boundingBox.maxZ - boundingBox.minZ) / 2)); + ComponentTFTrollVault vault = new ComponentTFTrollVault(getFeatureType(), this.getComponentType() + 1, boundingBox.minX + ((boundingBox.maxX - boundingBox.minX) / 2), boundingBox.minY, boundingBox.minZ + ((boundingBox.maxZ - boundingBox.minZ) / 2)); list.add(vault); vault.buildComponent(this, list, rand); } + protected boolean makeSmallerCave(List list, Random rand, int index, int x, int y, int z, int caveSize, int caveHeight, Rotation rotation) { + EnumFacing direction = getStructureRelativeRotation(rotation); + BlockPos dest = offsetTowerCCoords(x, y, z, caveSize, direction); - protected boolean makeSmallerCave(List list, Random rand, int index, int x, int y, int z, int caveSize, int caveHeight, int rotation) { - int direction = (getCoordBaseMode() + rotation) % 4; - ChunkCoordinates dest = offsetTowerCCoords(x, y, z, caveSize, direction); - - ComponentTFTrollCaveConnect cave = new ComponentTFTrollCaveConnect(index, dest.posX, dest.posY, dest.posZ, caveSize, caveHeight, direction); + ComponentTFTrollCaveConnect cave = new ComponentTFTrollCaveConnect(getFeatureType(), index, dest.getX(), dest.getY(), dest.getZ(), caveSize, caveHeight, direction); // check to see if it intersects something already there StructureComponent intersect = StructureComponent.findIntersecting(list, cave.getBoundingBox()); if (intersect == null || intersect == this) { @@ -105,167 +100,131 @@ protected boolean makeSmallerCave(List list, Random rand, in //addOpening(x, y, z, rotation); return true; } - else - { - return false; - } + return false; } - @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { Random decoRNG = new Random(world.getSeed() + (this.boundingBox.minX * 321534781) ^ (this.boundingBox.minZ * 756839)); - + // clear inside hollowCaveMiddle(world, sbb, rand, 0, 0, 0, this.size - 1, this.height - 1, this.size - 1); - + // stone stalactites! - for (int i = 0; i < 128; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generateBlockStalactite(world, decoRNG, Blocks.stone, 0.7F, true, dest.posX, 3, dest.posZ, sbb); + for (int i = 0; i < 128; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generateBlockStalactite(world, decoRNG, Blocks.STONE, 0.7F, true, dest.getX(), 3, dest.getZ(), sbb); } // stone stalagmites! - for (int i = 0; i < 32; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - generateBlockStalactite(world, decoRNG, Blocks.stone, 0.5F, false, dest.posX, 3, dest.posZ, sbb); + for (int i = 0; i < 32; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generateBlockStalactite(world, decoRNG, Blocks.STONE, 0.5F, false, dest.getX(), 3, dest.getZ(), sbb); } - - + // uberous! - for (int i = 0; i < 32; i++) - { - ChunkCoordinates dest = getCoordsInCave(decoRNG); - - generateAtSurface(world, uberousGen, decoRNG, dest.posX, 60, dest.posZ, sbb); + for (int i = 0; i < 32; i++) { + BlockPos dest = getCoordsInCave(decoRNG); + generateAtSurface(world, uberousGen, decoRNG, dest.getX(), 60, dest.getZ(), sbb); } - + return true; } - - protected ChunkCoordinates getCoordsInCave(Random rand) { - return new ChunkCoordinates(rand.nextInt(this.size - 1), rand.nextInt(this.height - 1), rand.nextInt(this.size - 1)); + protected BlockPos getCoordsInCave(Random rand) { + return new BlockPos(rand.nextInt(this.size - 1), rand.nextInt(this.height - 1), rand.nextInt(this.size - 1)); } - /** - * arguments: (World worldObj, StructureBoundingBox structBB, int minX, int minY, int minZ, int maxX, int maxY, int - * maxZ) - * @param rand - */ - protected void hollowCaveMiddle(World par1World, StructureBoundingBox par2StructureBoundingBox, Random rand, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) - { - int threshold = this.size / 5; - - for (int y = minY; y <= maxY; ++y) - { - for (int x = minX; x <= maxX; ++x) - { - for (int z = minZ; z <= maxZ; ++z) - { - int ex = Math.min(x - minX, maxX - x); - int ey = Math.min((y - minY) * 2, maxY - y); - int ez = Math.min(z - minZ, maxZ - z); - - double dist = Math.sqrt(ex * ey * ez); - + protected void hollowCaveMiddle(World world, StructureBoundingBox boundingBox, Random rand, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + int threshold = this.size / 5; + + for (int y = minY; y <= maxY; ++y) { + for (int x = minX; x <= maxX; ++x) { + for (int z = minZ; z <= maxZ; ++z) { + + int ex = Math.min(x - minX, maxX - x); + int ey = Math.min((y - minY) * 2, maxY - y); + int ez = Math.min(z - minZ, maxZ - z); + + double dist = Math.sqrt(ex * ey * ez); + if (dist > threshold) { - this.placeBlockAtCurrentPosition(par1World, Blocks.air, 0, x, y, z, par2StructureBoundingBox); - } else if (dist == threshold && rand.nextInt(4) == 0 && this.getBlockAtCurrentPosition(par1World, x, y, z, par2StructureBoundingBox) == Blocks.stone) { - this.placeBlockAtCurrentPosition(par1World, TFBlocks.trollSteinn, 0, x, y, z, par2StructureBoundingBox); - } - } - } - } - } - - + this.setBlockState(world, Blocks.AIR.getDefaultState(), x, y, z, boundingBox); + } else if (dist == threshold && rand.nextInt(4) == 0 && this.getBlockStateFromPos(world, x, y, z, boundingBox).getBlock() == Blocks.STONE) { + this.setBlockState(world, TFBlocks.trollsteinn.getDefaultState(), x, y, z, boundingBox); + } + } + } + } + } + /** * Gets a random position in the specified direction that connects to stairs currently in the tower. */ - public ChunkCoordinates getValidOpening(Random rand, int caveHeight, int direction) { + public BlockPos getValidOpening(Random rand, int caveHeight, Rotation direction) { // variables! int offset = this.size / 4; // wall thickness int wLength = size - (offset * 2); // wall length // for directions 0 or 2, the wall lies along the z axis - if (direction == 0 || direction == 2) { - int rx = direction == 0 ? size - 1 : 0; + if (direction == Rotation.NONE || direction == Rotation.CLOCKWISE_180) { + int rx = direction == Rotation.NONE ? size - 1 : 0; int rz = offset + rand.nextInt(wLength); int ry = (rand.nextInt(offset) - rand.nextInt(offset)); - - return new ChunkCoordinates(rx, ry, rz); + + return new BlockPos(rx, ry, rz); } - + // for directions 1 or 3, the wall lies along the x axis - if (direction == 1 || direction == 3) { + if (direction == Rotation.CLOCKWISE_90 || direction == Rotation.COUNTERCLOCKWISE_90) { int rx = offset + rand.nextInt(wLength); - int rz = direction == 1 ? size - 1 : 0; + int rz = direction == Rotation.CLOCKWISE_90 ? size - 1 : 0; int ry = (rand.nextInt(offset) - rand.nextInt(offset)); - - return new ChunkCoordinates(rx, ry, rz); + + return new BlockPos(rx, ry, rz); } - - + return null; } - - + /** * Provides coordinates to make a tower such that it will open into the parent tower at the provided coordinates. */ - protected ChunkCoordinates offsetTowerCCoords(int x, int y, int z, int towerSize, int direction) { - + @Override + protected BlockPos offsetTowerCCoords(int x, int y, int z, int towerSize, EnumFacing direction) { + int dx = getXWithOffset(x, z); int dy = getYWithOffset(y); int dz = getZWithOffset(x, z); - - if (direction == 0) { - return new ChunkCoordinates(dx - 1, dy - 1, dz - towerSize / 2); - } else if (direction == 1) { - return new ChunkCoordinates(dx + towerSize / 2, dy - 1, dz - 1); - } else if (direction == 2) { - return new ChunkCoordinates(dx + 1, dy - 1, dz + towerSize / 2); - } else if (direction == 3) { - return new ChunkCoordinates(dx - towerSize / 2, dy - 1, dz + 1); + + if (direction == EnumFacing.SOUTH) { + return new BlockPos(dx - 1, dy - 1, dz - towerSize / 2); + } else if (direction == EnumFacing.WEST) { + return new BlockPos(dx + towerSize / 2, dy - 1, dz - 1); + } else if (direction == EnumFacing.NORTH) { + return new BlockPos(dx + 1, dy - 1, dz + towerSize / 2); + } else if (direction == EnumFacing.EAST) { + return new BlockPos(dx - towerSize / 2, dy - 1, dz + 1); } - - + // ugh? - return new ChunkCoordinates(x, y, z); - } - - - public boolean isBoundingBoxOutOfHighlands(World world, StructureBoundingBox sbb) { - int minX = this.boundingBox.minX - 1; - int minZ = this.boundingBox.minZ - 1; - int maxX = this.boundingBox.maxX + 1; - int maxZ = this.boundingBox.maxZ + 1; - - for (int x = minX; x <= maxX; x++) { - for (int z = minZ; z <= maxZ; z++) { - if (world.getBiomeGenForCoords(x, z) != TFBiomeBase.highlands) { - return true; - } - } - } - - return false; + return new BlockPos(x, y, z); } - + protected static final Predicate highlands = biome -> biome == TFBiomes.highlands; + /** * Make a random stone stalactite */ protected void generateBlockStalactite(World world, Random rand, Block blockToGenerate, float length, boolean up, int x, int y, int z, StructureBoundingBox sbb) { // are the coordinates in our bounding box? - int dx = getXWithOffset(x, z); - int dy = getYWithOffset(y); - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz)) { - (new TFGenCaveStalactite(blockToGenerate, length, up)).generate(world, rand, dx, dy, dz); - } + int dx = getXWithOffset(x, z); + int dy = getYWithOffset(y); + int dz = getZWithOffset(x, z); + + BlockPos pos = new BlockPos(dx, dy, dz); + if (sbb.isVecInside(pos)) { + new TFGenCaveStalactite(blockToGenerate, length, up).generate(world, rand, pos); + } } /** @@ -273,29 +232,30 @@ protected void generateBlockStalactite(World world, Random rand, Block blockToGe */ protected void generateAtSurface(World world, WorldGenerator generator, Random rand, int x, int y, int z, StructureBoundingBox sbb) { // are the coordinates in our bounding box? - int dx = getXWithOffset(x, z); - int dy = y; - int dz = getZWithOffset(x, z); - if(sbb.isVecInside(dx, dy, dz)) { - // find surface above the listed coords - for (dy = y; dy < y + 32; dy++) { - if (world.isAirBlock( dx, dy, dz)) { - //System.out.println("Found surface for generator. It's " + dy); - - break; - } - } - - generator.generate(world, rand, dx, dy, dz); - } + int dx = getXWithOffset(x, z); + int dy = y; + int dz = getZWithOffset(x, z); + + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(dx, dy, dz); + + if (sbb.isVecInside(pos)) { + // find surface above the listed coords + for (dy = y; dy < y + 32; dy++) { + pos.setY(dy); + if (world.isAirBlock(pos)) { + break; + } + } + + generator.generate(world, rand, pos.toImmutable()); + } } protected void makeTreasureCrate(World world, Random rand, StructureBoundingBox sbb) { // treasure! int mid = this.size / 2; - this.fillWithBlocks(world, sbb, mid - 2, 0, mid - 2, mid + 1, 3, mid + 1, Blocks.obsidian, Blocks.obsidian, false); + this.fillWithBlocks(world, sbb, mid - 2, 0, mid - 2, mid + 1, 3, mid + 1, Blocks.OBSIDIAN.getDefaultState(), Blocks.OBSIDIAN.getDefaultState(), false); this.fillWithAir(world, sbb, mid - 1, 1, mid - 1, mid + 0, 2, mid + 0); this.placeTreasureAtCurrentPosition(world, rand, mid, 1, mid, TFTreasure.troll_garden, false, sbb); } - } diff --git a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCloud.java b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCloud.java index 6ed4e8c8bf..4a336e13cd 100644 --- a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCloud.java +++ b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollCloud.java @@ -1,50 +1,48 @@ package twilightforest.structures.trollcave; -import java.util.Random; - import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import twilightforest.structures.StructureTFComponent; +import net.minecraft.world.gen.structure.template.TemplateManager; +import twilightforest.TFFeature; +import twilightforest.structures.StructureTFComponentOld; -public class ComponentTFTrollCloud extends StructureTFComponent { +import java.util.Random; + +public class ComponentTFTrollCloud extends StructureTFComponentOld { private int size; private int height; - public ComponentTFTrollCloud() { } - - public ComponentTFTrollCloud(int index, int x, int y, int z) { - super(index); - this.setCoordBaseMode(0); + public ComponentTFTrollCloud() { + } + + public ComponentTFTrollCloud(TFFeature feature, int index, int x, int y, int z) { + super(feature, index); + this.setCoordBaseMode(EnumFacing.SOUTH); this.size = 40; this.height = 20; - + int radius = this.size / 2; - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -radius, -this.height, -radius, this.size, this.height, this.size, 0); + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -radius, -this.height, -radius, this.size, this.height, this.size, EnumFacing.SOUTH); } - - /** - * Save to NBT - */ + @Override - protected void func_143012_a(NBTTagCompound par1NBTTagCompound) { - super.func_143012_a(par1NBTTagCompound); - - par1NBTTagCompound.setInteger("size", this.size); - par1NBTTagCompound.setInteger("height", this.height); + protected void writeStructureToNBT(NBTTagCompound tagCompound) { + super.writeStructureToNBT(tagCompound); + + tagCompound.setInteger("size", this.size); + tagCompound.setInteger("height", this.height); } - /** - * Load from NBT - */ @Override - protected void func_143011_b(NBTTagCompound par1NBTTagCompound) { - super.func_143011_b(par1NBTTagCompound); - this.size = par1NBTTagCompound.getInteger("size"); - this.height = par1NBTTagCompound.getInteger("height"); + protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templateManager) { + super.readStructureFromNBT(tagCompound, templateManager); + this.size = tagCompound.getInteger("size"); + this.height = tagCompound.getInteger("height"); } @Override @@ -54,10 +52,10 @@ public boolean addComponentParts(World world, Random rand, StructureBoundingBox return true; } - protected void placeCloud(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - this.fillWithMetadataBlocks(world, sbb, minX, minY, minZ, maxX, maxY, maxZ, Blocks.stained_glass, 0, Blocks.stained_glass, 0, false); - this.fillWithMetadataBlocks(world, sbb, minX + 2, minY + 2, minZ + 2, maxX - 2, maxY - 1, maxZ - 2, Blocks.quartz_block, 0, Blocks.quartz_block, 0, false); - + protected void placeCloud(World world, StructureBoundingBox sbb, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + this.fillWithBlocks(world, sbb, minX, minY, minZ, maxX, maxY, maxZ, Blocks.STAINED_GLASS.getDefaultState(), Blocks.STAINED_GLASS.getDefaultState(), false); + this.fillWithBlocks(world, sbb, minX + 2, minY + 2, minZ + 2, maxX - 2, maxY - 1, maxZ - 2, Blocks.QUARTZ_BLOCK.getDefaultState(), Blocks.QUARTZ_BLOCK.getDefaultState(), false); + } } diff --git a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollVault.java b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollVault.java index 27dcbac0ef..9ac26f73f0 100644 --- a/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollVault.java +++ b/src/main/java/twilightforest/structures/trollcave/ComponentTFTrollVault.java @@ -1,63 +1,54 @@ package twilightforest.structures.trollcave; -import java.util.List; -import java.util.Random; - import net.minecraft.init.Blocks; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraft.world.gen.structure.StructureComponent; -import twilightforest.TFTreasure; +import twilightforest.TFFeature; +import twilightforest.loot.TFTreasure; import twilightforest.block.TFBlocks; -import twilightforest.entity.EntityTFArmoredGiant; -import twilightforest.entity.EntityTFGiantMiner; -import twilightforest.structures.StructureTFComponent; +import twilightforest.structures.StructureTFComponentOld; + +import java.util.Random; -public class ComponentTFTrollVault extends StructureTFComponent { +public class ComponentTFTrollVault extends StructureTFComponentOld { + + public ComponentTFTrollVault() { + } + + public ComponentTFTrollVault(TFFeature feature, int index, int x, int y, int z) { + super(feature, index); + this.setCoordBaseMode(EnumFacing.SOUTH); - public ComponentTFTrollVault() { } - - public ComponentTFTrollVault(int index, int x, int y, int z) { - super(index); - this.setCoordBaseMode(0); - // adjust x, y, z - x = (x >> 2) << 2; - y = (y / 4) * 4; - z = (z >> 2) << 2; - + x = (x >> 2) << 2; + y = (y / 4) * 4; + z = (z >> 2) << 2; + // spawn list! this.spawnListIndex = -1; - - this.boundingBox = StructureTFComponent.getComponentToAddBoundingBox(x, y, z, -8, 0, -8, 12, 12, 12, 0); - } - - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public void buildComponent(StructureComponent parent, List list, Random rand) { - ; + + this.boundingBox = StructureTFComponentOld.getComponentToAddBoundingBox(x, y, z, -8, 0, -8, 12, 12, 12, EnumFacing.SOUTH); } - + @Override public boolean addComponentParts(World world, Random rand, StructureBoundingBox sbb) { // make walls - this.fillWithMetadataBlocks(world, sbb, 0, 0, 0, 11, 11, 11, TFBlocks.giantObsidian, 0, TFBlocks.giantObsidian, 0, false); - + this.fillWithBlocks(world, sbb, 0, 0, 0, 11, 11, 11, TFBlocks.giant_obsidian.getDefaultState(), TFBlocks.giant_obsidian.getDefaultState(), false); + // clear inside this.fillWithAir(world, sbb, 4, 4, 4, 7, 7, 7); - + // cobblestone platform - this.fillWithMetadataBlocks(world, sbb, 5, 5, 5, 6, 5, 6, Blocks.cobblestone, 0, Blocks.cobblestone, 0, false); - + this.fillWithBlocks(world, sbb, 5, 5, 5, 6, 5, 6, Blocks.COBBLESTONE.getDefaultState(), Blocks.COBBLESTONE.getDefaultState(), false); + // chests - this.placeBlockAtCurrentPosition(world, Blocks.chest, 0, 5, 6, 5, sbb); + this.setBlockState(world, Blocks.CHEST.getDefaultState(), 5, 6, 5, sbb); this.placeTreasureAtCurrentPosition(world, rand, 5, 6, 6, TFTreasure.troll_vault, false, sbb); - + this.placeTreasureAtCurrentPosition(world, rand, 6, 6, 5, TFTreasure.troll_garden, true, sbb); - this.placeBlockAtCurrentPosition(world, Blocks.trapped_chest, 0, 6, 6, 6, sbb); + this.setBlockState(world, Blocks.TRAPPED_CHEST.getDefaultState(), 6, 6, 6, sbb); return true; } diff --git a/src/main/java/twilightforest/structures/trollcave/TFTrollCavePieces.java b/src/main/java/twilightforest/structures/trollcave/TFTrollCavePieces.java index 1421209e8a..354abef9b6 100644 --- a/src/main/java/twilightforest/structures/trollcave/TFTrollCavePieces.java +++ b/src/main/java/twilightforest/structures/trollcave/TFTrollCavePieces.java @@ -1,17 +1,19 @@ package twilightforest.structures.trollcave; import net.minecraft.world.gen.structure.MapGenStructureIO; +import twilightforest.structures.start.StructureStartTrollCave; public class TFTrollCavePieces { - public static void registerPieces() - { - MapGenStructureIO.func_143031_a(ComponentTFTrollCaveMain.class, "TFTCMai"); - MapGenStructureIO.func_143031_a(ComponentTFTrollCaveConnect.class, "TFTCCon"); - MapGenStructureIO.func_143031_a(ComponentTFTrollCaveGarden.class, "TFTCGard"); - MapGenStructureIO.func_143031_a(ComponentTFTrollCloud.class, "TFTCloud"); - MapGenStructureIO.func_143031_a(ComponentTFCloudCastle.class, "TFClCa"); - MapGenStructureIO.func_143031_a(ComponentTFCloudTree.class, "TFClTr"); - MapGenStructureIO.func_143031_a(ComponentTFTrollVault.class, "TFTCVa"); - } + public static void registerPieces() { + MapGenStructureIO.registerStructure(StructureStartTrollCave.class, "TFTC"); + + MapGenStructureIO.registerStructureComponent(ComponentTFTrollCaveMain.class, "TFTCMai"); + MapGenStructureIO.registerStructureComponent(ComponentTFTrollCaveConnect.class, "TFTCCon"); + MapGenStructureIO.registerStructureComponent(ComponentTFTrollCaveGarden.class, "TFTCGard"); + MapGenStructureIO.registerStructureComponent(ComponentTFTrollCloud.class, "TFTCloud"); + MapGenStructureIO.registerStructureComponent(ComponentTFCloudCastle.class, "TFClCa"); + MapGenStructureIO.registerStructureComponent(ComponentTFCloudTree.class, "TFClTr"); + MapGenStructureIO.registerStructureComponent(ComponentTFTrollVault.class, "TFTCVa"); + } } \ No newline at end of file diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFAntibuilder.java b/src/main/java/twilightforest/tileentity/TileEntityTFAntibuilder.java new file mode 100644 index 0000000000..3128f3d2fe --- /dev/null +++ b/src/main/java/twilightforest/tileentity/TileEntityTFAntibuilder.java @@ -0,0 +1,298 @@ +package twilightforest.tileentity; + +import com.google.common.collect.ImmutableSet; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ITickable; +import net.minecraft.util.math.BlockPos; +import twilightforest.TFConfig; +import twilightforest.block.BlockTFTowerTranslucent; +import twilightforest.block.TFBlocks; +import twilightforest.enums.TowerTranslucentVariant; + +import java.util.Random; + +public class TileEntityTFAntibuilder extends TileEntity implements ITickable { + + private static final int REVERT_CHANCE = 10; + + private final int radius = 4; + private final int diameter = 2 * radius + 1; + private final double requiredPlayerRange = 16.0; + + private final Random rand = new Random(); + + private int tickCount; + private boolean slowScan; + private int ticksSinceChange; + + private IBlockState[] blockData; + + @Override + public void update() { + if (this.anyPlayerInRange()) { + this.tickCount++; + + if (this.world.isRemote) { + double x = this.pos.getX() + this.world.rand.nextFloat(); + double y = this.pos.getY() + this.world.rand.nextFloat(); + double z = this.pos.getZ() + this.world.rand.nextFloat(); +// this.world.spawnParticle("smoke", x, y, z, 0.0D, 0.0D, 0.0D); + this.world.spawnParticle(EnumParticleTypes.REDSTONE, x, y, z, 0.0D, 0.0D, 0.0D); + + // occasionally make a little red dust line to outline our radius + if (this.rand.nextInt(10) == 0) { + makeRandomOutline(); + makeRandomOutline(); + makeRandomOutline(); + } + } else { + + // new plan, take a snapshot of the world when we are first activated, and then rapidly revert changes + if (blockData == null && world.isAreaLoaded(this.pos, this.radius)) { + captureBlockData(); + this.slowScan = true; + } + + if (blockData != null && (!this.slowScan || this.tickCount % 20 == 0)) { + if (scanAndRevertChanges()) { + this.slowScan = false; + this.ticksSinceChange = 0; + } else { + ticksSinceChange++; + + if (ticksSinceChange > 20) { + this.slowScan = true; + } + } + } + } + } else { + // remove data + this.blockData = null; + this.tickCount = 0; + } + } + + + /** + * Display a random one of the 12 possible outlines + */ + private void makeRandomOutline() { + makeOutline(this.rand.nextInt(12)); + } + + /** + * Display a specific outline + */ + private void makeOutline(int outline) { + // src + double sx = this.pos.getX(); + double sy = this.pos.getY(); + double sz = this.pos.getZ(); + // dest + double dx = this.pos.getX(); + double dy = this.pos.getY(); + double dz = this.pos.getZ(); + + switch (outline) { + case 0: + case 8: + sx -= radius; + dx += radius + 1; + sz -= radius; + dz -= radius; + break; + case 1: + case 9: + sx -= radius; + dx -= radius; + sz -= radius; + dz += radius + 1; + break; + case 2: + case 10: + sx -= radius; + dx += radius + 1; + sz += radius + 1; + dz += radius + 1; + break; + case 3: + case 11: + sx += radius + 1; + dx += radius + 1; + sz -= radius; + dz += radius + 1; + break; + case 4: + sx -= radius; + dx -= radius; + sz -= radius; + dz -= radius; + break; + case 5: + sx += radius + 1; + dx += radius + 1; + sz -= radius; + dz -= radius; + break; + case 6: + sx += radius + 1; + dx += radius + 1; + sz += radius + 1; + dz += radius + 1; + break; + case 7: + sx -= radius; + dx -= radius; + sz += radius + 1; + dz += radius + 1; + break; + } + + switch (outline) { + case 0: + case 1: + case 2: + case 3: + sy += radius + 1; + dy += radius + 1; + break; + case 4: + case 5: + case 6: + case 7: + sy -= radius; + dy += radius + 1; + break; + case 8: + case 9: + case 10: + case 11: + sy -= radius; + dy -= radius; + break; + } + + if (rand.nextBoolean()) { + drawParticleLine(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, dx, dy, dz); + } else { + drawParticleLine(sx, sy, sz, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); + } + drawParticleLine(sx, sy, sz, dx, dy, dz); + } + + private void drawParticleLine(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { + // make particle trail + int particles = 16; + for (int i = 0; i < particles; i++) { + double trailFactor = i / (particles - 1.0D); + + double tx = srcX + (destX - srcX) * trailFactor + rand.nextFloat() * 0.005; + double ty = srcY + (destY - srcY) * trailFactor + rand.nextFloat() * 0.005; + double tz = srcZ + (destZ - srcZ) * trailFactor + rand.nextFloat() * 0.005; + world.spawnParticle(EnumParticleTypes.REDSTONE, tx, ty, tz, 0, 0, 0); + } + } + + private boolean scanAndRevertChanges() { + int index = 0; + boolean reverted = false; + + for (int x = -radius; x <= radius; x++) { + for (int y = -radius; y <= radius; y++) { + for (int z = -radius; z <= radius; z++) { + IBlockState stateThere = world.getBlockState(pos.add(x, y, z)); + + if (blockData[index].getBlock() != stateThere.getBlock()) { + if (revertBlock(pos.add(x, y, z), stateThere, blockData[index])) { + reverted = true; + } else { + blockData[index] = stateThere; + } + } + + index++; + } + } + } + + return reverted; + } + + private boolean revertBlock(BlockPos pos, IBlockState stateThere, IBlockState replaceWith) { + if (stateThere.getBlock() == Blocks.AIR && !replaceWith.getMaterial().blocksMovement()) { + return false; + } + if (stateThere.getBlockHardness(world, pos) < 0 || isUnrevertable(stateThere, replaceWith)) { + return false; + } else if (this.rand.nextInt(REVERT_CHANCE) == 0) { + // don't revert everything instantly + if (replaceWith.getBlock() != Blocks.AIR) { + replaceWith = TFBlocks.tower_translucent.getDefaultState().withProperty(BlockTFTowerTranslucent.VARIANT, TowerTranslucentVariant.REVERTER_REPLACEMENT); + } + + world.setBlockState(pos, replaceWith, 2); + + // play a little animation + if (stateThere.getBlock() == Blocks.AIR) { + world.playEvent(2001, pos, Block.getStateId(replaceWith)); + } else if (replaceWith.getBlock() == Blocks.AIR) { + world.playEvent(2001, pos, Block.getStateId(stateThere)); + stateThere.getBlock().dropBlockAsItem(world, pos, stateThere, 0); + } + } + + return true; + } + + private boolean isUnrevertable(IBlockState stateThere, IBlockState replaceWith) { + if (stateThere.getBlock() == TFBlocks.tower_device || replaceWith.getBlock() == TFBlocks.tower_device) { + return true; + } + if ((stateThere.getBlock() == TFBlocks.tower_translucent && stateThere.getValue(BlockTFTowerTranslucent.VARIANT) != TowerTranslucentVariant.REVERTER_REPLACEMENT) + || (replaceWith.getBlock() == TFBlocks.tower_translucent && replaceWith.getValue(BlockTFTowerTranslucent.VARIANT) != TowerTranslucentVariant.REVERTER_REPLACEMENT)) { + return true; + } + if (stateThere.getBlock() == Blocks.REDSTONE_LAMP && replaceWith.getBlock() == Blocks.LIT_REDSTONE_LAMP) { + return true; + } + if (stateThere.getBlock() == Blocks.LIT_REDSTONE_LAMP && replaceWith.getBlock() == Blocks.REDSTONE_LAMP) { + return true; + } + if (stateThere.getBlock() == Blocks.WATER || replaceWith.getBlock() == Blocks.FLOWING_WATER) { + return true; + } + if (stateThere.getBlock() == Blocks.FLOWING_WATER || replaceWith.getBlock() == Blocks.WATER) { + return true; + } + if (replaceWith.getBlock() == Blocks.TNT) { + return true; + } + + ImmutableSet blacklist = TFConfig.getDisallowedBlocks(); + return blacklist.contains(stateThere) || blacklist.contains(replaceWith); + } + + private void captureBlockData() { + blockData = new IBlockState[diameter * diameter * diameter]; + + int index = 0; + + for (int x = -radius; x <= radius; x++) { + for (int y = -radius; y <= radius; y++) { + for (int z = -radius; z <= radius; z++) { + blockData[index] = world.getBlockState(pos.add(x, y, z)); + index++; + } + } + } + } + + private boolean anyPlayerInRange() { + return this.world.isAnyPlayerWithinRangeAt(this.pos.getX() + 0.5D, this.pos.getY() + 0.5D, this.pos.getZ() + 0.5D, this.requiredPlayerRange); + } +} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFBossSpawner.java b/src/main/java/twilightforest/tileentity/TileEntityTFBossSpawner.java deleted file mode 100644 index 6a9233f439..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFBossSpawner.java +++ /dev/null @@ -1,135 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityCreature; -import net.minecraft.entity.EntityList; -import net.minecraft.entity.EntityLiving; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.EnumDifficulty; - - -public abstract class TileEntityTFBossSpawner extends TileEntity { - - protected String mobID = "Pig"; - protected int counter; - - protected Entity displayCreature = null; - - - public TileEntityTFBossSpawner() { - ; - } - - /** - * Is there a player in our detection range? - */ - public boolean anyPlayerInRange() - { - return worldObj.getClosestPlayer(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, getRange()) != null; - } - - /** - * Determines if this TileEntity requires update calls. - * @return True if you want updateEntity() to be called, false if not - */ - @Override - public boolean canUpdate() { - return true; - } - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - this.counter++; - - if(anyPlayerInRange()) - { - if (worldObj.isRemote) - { - // particles - double rx = xCoord + worldObj.rand.nextFloat(); - double ry = yCoord + worldObj.rand.nextFloat(); - double rz = zCoord + worldObj.rand.nextFloat(); - worldObj.spawnParticle("smoke", rx, ry, rz, 0.0D, 0.0D, 0.0D); - worldObj.spawnParticle("flame", rx, ry, rz, 0.0D, 0.0D, 0.0D); - } - else - { - //System.out.println("Thinking about boss!"); - - - if (worldObj.difficultySetting != EnumDifficulty.PEACEFUL) - { - spawnMyBoss(); - - // destroy block - worldObj.setBlock(xCoord, yCoord, zCoord, Blocks.air, 0, 2); - - //System.out.println("Spawning boss!"); - } - } - } - - } - - /** - * Spawn the boss - */ - protected void spawnMyBoss() { - // spawn creature - EntityLiving myCreature = makeMyCreature(); - - double rx = xCoord + 0.5D; - double ry = yCoord + 0.5D; - double rz = zCoord + 0.5D; - myCreature.setLocationAndAngles(rx, ry, rz, worldObj.rand.nextFloat() * 360F, 0.0F); - - // set creature's home to this - initializeCreature(myCreature); - - // spawn it - worldObj.spawnEntityInWorld(myCreature); - } - - /** - * Get a temporary copy of the creature we're going to summon for display purposes - */ - public Entity getDisplayEntity() - { - if (this.displayCreature == null) - { - this.displayCreature = makeMyCreature(); - } - - return this.displayCreature; - } - - /** - * Any post-creation initialization goes here - */ - protected void initializeCreature(EntityLiving myCreature) { - if (myCreature instanceof EntityCreature) - { - ((EntityCreature) myCreature).setHomeArea(xCoord, yCoord, zCoord, 46); - } - } - - /** - * Range? - */ - protected int getRange() { - return 50; - } - - /** - * Create a copy of what we spawn - */ - protected EntityLiving makeMyCreature() { - return (EntityLiving)EntityList.createEntityByName(mobID, worldObj); - } -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFCReactorActive.java b/src/main/java/twilightforest/tileentity/TileEntityTFCReactorActive.java index 1571a9ec53..63f5d4be7e 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFCReactorActive.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFCReactorActive.java @@ -1,273 +1,233 @@ package twilightforest.tileentity; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.init.SoundEvents; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ITickable; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; import twilightforest.block.BlockTFTowerTranslucent; import twilightforest.block.TFBlocks; +import twilightforest.enums.TowerTranslucentVariant; import twilightforest.entity.EntityTFMiniGhast; -public class TileEntityTFCReactorActive extends TileEntity { - - int counter = 0; - - int secX, secY, secZ; - int terX, terY, terZ; - - - public TileEntityTFCReactorActive() { - Random rand = new Random(); - - // determine the two smaller bursts - this.secX = 3 * (rand.nextBoolean() ? 1 : -1); - this.secY = 3 * (rand.nextBoolean() ? 1 : -1); - this.secZ = 3 * (rand.nextBoolean() ? 1 : -1); - - this.terX = 3 * (rand.nextBoolean() ? 1 : -1); - this.terY = 3 * (rand.nextBoolean() ? 1 : -1); - this.terZ = 3 * (rand.nextBoolean() ? 1 : -1); - - if (secX == terX && secY == terY && secZ == terZ) - { - terX = -terX; - terY = -terY; - terZ = -terZ; - } +import java.util.Random; + +public class TileEntityTFCReactorActive extends TileEntity implements ITickable { + + private int counter = 0; + + private int secX, secY, secZ; + private int terX, terY, terZ; + + + public TileEntityTFCReactorActive() { + Random rand = new Random(); + + // determine the two smaller bursts + this.secX = 3 * (rand.nextBoolean() ? 1 : -1); + this.secY = 3 * (rand.nextBoolean() ? 1 : -1); + this.secZ = 3 * (rand.nextBoolean() ? 1 : -1); + + this.terX = 3 * (rand.nextBoolean() ? 1 : -1); + this.terY = 3 * (rand.nextBoolean() ? 1 : -1); + this.terZ = 3 * (rand.nextBoolean() ? 1 : -1); + + if (secX == terX && secY == terY && secZ == terZ) { + terX = -terX; + terY = -terY; + terZ = -terZ; + } } + @Override + public void update() { + counter++; + + if (!world.isRemote) { - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - counter++; - - if (!worldObj.isRemote) - { - - // every 2 seconds for 10 seconds, destroy a new radius + // every 2 seconds for 10 seconds, destroy a new radius int offset = 10; - - if (counter % 5 == 0) - { - if (counter == 5) - { - // transformation! - worldObj.setBlock(this.xCoord + 1, this.yCoord + 1, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord + 1, this.yCoord + 1, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord + 1, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord + 1, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - - worldObj.setBlock(this.xCoord + 0, this.yCoord + 1, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord + 0, this.yCoord + 1, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord + 1, this.yCoord + 1, this.zCoord + 0, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord + 1, this.zCoord + 0, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - - - worldObj.setBlock(this.xCoord + 1, this.yCoord + 0, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord + 1, this.yCoord + 0, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord + 0, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord + 0, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - - worldObj.setBlock(this.xCoord + 0, this.yCoord + 0, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord + 0, this.yCoord + 0, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord + 1, this.yCoord + 0, this.zCoord + 0, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord + 0, this.zCoord + 0, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - - - worldObj.setBlock(this.xCoord + 1, this.yCoord - 1, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord + 1, this.yCoord - 1, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord - 1, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord - 1, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_DIAMOND, 2); - - worldObj.setBlock(this.xCoord + 0, this.yCoord - 1, this.zCoord + 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord + 0, this.yCoord - 1, this.zCoord - 1, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord + 1, this.yCoord - 1, this.zCoord + 0, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - worldObj.setBlock(this.xCoord - 1, this.yCoord - 1, this.zCoord + 0, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_FAKE_GOLD, 2); - - } - - - // primary burst - int primary = counter - 80; - - if (primary >= offset && primary <= 249) - { - drawBlob(this.xCoord, this.yCoord, this.zCoord, (primary - offset) / 40, Blocks.air, 0, primary - offset, false); - } - if (primary <= 200) - { - drawBlob(this.xCoord, this.yCoord, this.zCoord, primary / 40, TFBlocks.towerTranslucent, BlockTFTowerTranslucent.META_REACTOR_DEBRIS, counter, false); - } - - // secondary burst - int secondary = counter - 120; - - if (secondary >= offset && secondary <= 129) - { - drawBlob(this.xCoord + secX, this.yCoord + secY, this.zCoord + secZ, (secondary - offset) / 40, Blocks.air, 0, secondary - offset, false); - } - if (secondary >= 0 && secondary <= 160) - { - drawBlob(this.xCoord + secX, this.yCoord + secY, this.zCoord + secZ, secondary / 40, Blocks.air, 0, secondary, true); - } - - // tertiary burst - int tertiary = counter - 160; - - if (tertiary >= offset && tertiary <= 129) - { - drawBlob(this.xCoord + terX, this.yCoord + terY, this.zCoord + terZ, (tertiary - offset) / 40, Blocks.air, 0, tertiary - offset, false); - } - if (tertiary >= 0 && tertiary <= 160) - { - drawBlob(this.xCoord + terX, this.yCoord + terY, this.zCoord + terZ, tertiary / 40, Blocks.air, 0, tertiary, true); - } - - } - - - - - if (counter >= 350) - { + + if (counter % 5 == 0) { + if (counter == 5) { + IBlockState fakeGold = TFBlocks.tower_translucent.getDefaultState().withProperty(BlockTFTowerTranslucent.VARIANT, TowerTranslucentVariant.FAKE_GOLD); + IBlockState fakeDiamond = TFBlocks.tower_translucent.getDefaultState().withProperty(BlockTFTowerTranslucent.VARIANT, TowerTranslucentVariant.FAKE_DIAMOND); + + // transformation! + world.setBlockState(pos.add(1, 1, 1), fakeDiamond, 2); + world.setBlockState(pos.add(1, 1, -1), fakeDiamond, 2); + world.setBlockState(pos.add(-1, 1, 1), fakeDiamond, 2); + world.setBlockState(pos.add(-1, 1, -1), fakeDiamond, 2); + + world.setBlockState(pos.add(0, 1, 1), fakeGold, 2); + world.setBlockState(pos.add(0, 1, -1), fakeGold, 2); + world.setBlockState(pos.add(1, 1, 0), fakeGold, 2); + world.setBlockState(pos.add(-1, 1, 0), fakeGold, 2); + + + world.setBlockState(pos.add(1, 0, 1), fakeGold, 2); + world.setBlockState(pos.add(1, 0, -1), fakeGold, 2); + world.setBlockState(pos.add(-1, 0, 1), fakeGold, 2); + world.setBlockState(pos.add(-1, 0, -1), fakeGold, 2); + + world.setBlockState(pos.add(0, 0, 1), fakeDiamond, 2); + world.setBlockState(pos.add(0, 0, -1), fakeDiamond, 2); + world.setBlockState(pos.add(1, 0, 0), fakeDiamond, 2); + world.setBlockState(pos.add(-1, 0, 0), fakeDiamond, 2); + + + world.setBlockState(pos.add(1, -1, 1), fakeDiamond, 2); + world.setBlockState(pos.add(1, -1, -1), fakeDiamond, 2); + world.setBlockState(pos.add(-1, -1, 1), fakeDiamond, 2); + world.setBlockState(pos.add(-1, -1, -1), fakeDiamond, 2); + + world.setBlockState(pos.add(0, -1, 1), fakeGold, 2); + world.setBlockState(pos.add(0, -1, -1), fakeGold, 2); + world.setBlockState(pos.add(1, -1, 0), fakeGold, 2); + world.setBlockState(pos.add(-1, -1, 0), fakeGold, 2); + + } + + + // primary burst + int primary = counter - 80; + + if (primary >= offset && primary <= 249) { + drawBlob(this.pos, (primary - offset) / 40, Blocks.AIR.getDefaultState(), primary - offset, false); + } + if (primary <= 200) { + drawBlob(this.pos, primary / 40, TFBlocks.tower_translucent.getDefaultState().withProperty(BlockTFTowerTranslucent.VARIANT, TowerTranslucentVariant.REACTOR_DEBRIS), counter, false); + } + + // secondary burst + int secondary = counter - 120; + + if (secondary >= offset && secondary <= 129) { + drawBlob(this.pos.add(secX, secY, secZ), (secondary - offset) / 40, Blocks.AIR.getDefaultState(), secondary - offset, false); + } + if (secondary >= 0 && secondary <= 160) { + drawBlob(this.pos.add(secX, secY, secZ), secondary / 40, Blocks.AIR.getDefaultState(), secondary, true); + } + + // tertiary burst + int tertiary = counter - 160; + + if (tertiary >= offset && tertiary <= 129) { + drawBlob(this.pos.add(terX, terY, terZ), (tertiary - offset) / 40, Blocks.AIR.getDefaultState(), tertiary - offset, false); + } + if (tertiary >= 0 && tertiary <= 160) { + drawBlob(this.pos.add(terX, terY, terZ), tertiary / 40, Blocks.AIR.getDefaultState(), tertiary, true); + } + + } + + + if (counter >= 350) { // spawn mini ghasts near the secondary & tertiary points - for (int i = 0; i < 3; i++) - { - spawnGhastNear(this.xCoord + secX, this.yCoord + secY, this.zCoord + secZ); - spawnGhastNear(this.xCoord + terX, this.yCoord + terY, this.zCoord + terZ); + for (int i = 0; i < 3; i++) { + spawnGhastNear(this.pos.getX() + secX, this.pos.getY() + secY, this.pos.getZ() + secZ); + spawnGhastNear(this.pos.getX() + terX, this.pos.getY() + terY, this.pos.getZ() + terZ); } - + // deactivate & explode - worldObj.createExplosion(null, this.xCoord, this.yCoord, this.zCoord, 2.0F, true); - - worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, Blocks.air, 0, 3); + world.createExplosion(null, this.pos.getX(), this.pos.getY(), this.pos.getZ(), 2.0F, true); + world.setBlockToAir(pos); } - - } - else - { - if (counter % 5 == 0 && counter <= 250) - { - // sound - worldObj.playSound(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D, "portal.portal", counter / 100F, counter / 100F, false); + + } else { + if (counter % 5 == 0 && counter <= 250) { + world.playSound(this.pos.getX() + 0.5D, this.pos.getY() + 0.5D, this.pos.getZ() + 0.5D, SoundEvents.BLOCK_PORTAL_AMBIENT, SoundCategory.BLOCKS, counter / 100F, counter / 100F, false); } } - } + } + - private void spawnGhastNear(int x, int y, int z) { - EntityTFMiniGhast ghast = new EntityTFMiniGhast(worldObj); - ghast.setLocationAndAngles(x - 1.5 + worldObj.rand.nextFloat() * 3.0, y - 1.5 + worldObj.rand.nextFloat() * 3.0, z - 1.5 + worldObj.rand.nextFloat() * 3.0, worldObj.rand.nextFloat() * 360F, 0.0F); - worldObj.spawnEntityInWorld(ghast); + EntityTFMiniGhast ghast = new EntityTFMiniGhast(world); + ghast.setLocationAndAngles(x - 1.5 + world.rand.nextFloat() * 3.0, y - 1.5 + world.rand.nextFloat() * 3.0, z - 1.5 + world.rand.nextFloat() * 3.0, world.rand.nextFloat() * 360F, 0.0F); + world.spawnEntity(ghast); } - - /** - * Draw a giant blob of whatevs (okay, it's going to be leaves). - */ - public void drawBlob(int sx, int sy, int sz, int rad, Block blockValue, int metaValue, int fuzz, boolean netherTransform) { + private void drawBlob(BlockPos pos, int rad, IBlockState state, int fuzz, boolean netherTransform) { // then trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { + for (byte dx = 0; dx <= rad; dx++) { // transform fuzz int fuzzX = (fuzz + dx) % 8; - for (byte dy = 0; dy <= rad; dy++) - { + for (byte dy = 0; dy <= rad; dy++) { int fuzzY = (fuzz + dy) % 8; - - for (byte dz = 0; dz <= rad; dz++) - { + + for (byte dz = 0; dz <= rad; dz++) { // determine how far we are from the center. byte dist = 0; - if (dx >= dy && dx >= dz) - { - dist = (byte) (dx + (byte)((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); - } - else if (dy >= dx && dy >= dz) - { - dist = (byte) (dy + (byte)((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); - } - else - { - dist = (byte) (dz + (byte)((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); + if (dx >= dy && dx >= dz) { + dist = (byte) (dx + (byte) ((Math.max(dy, dz) * 0.5) + (Math.min(dy, dz) * 0.25))); + } else if (dy >= dx && dy >= dz) { + dist = (byte) (dy + (byte) ((Math.max(dx, dz) * 0.5) + (Math.min(dx, dz) * 0.25))); + } else { + dist = (byte) (dz + (byte) ((Math.max(dx, dy) * 0.5) + (Math.min(dx, dy) * 0.25))); } - + // if we're inside the blob, fill it if (dist == rad && !(dx == 0 && dy == 0 && dz == 0)) { // do eight at a time for easiness! - switch (fuzzX) - { - case 0: - transformBlock(sx + dx, sy + dy, sz + dz, blockValue, metaValue, fuzzY, netherTransform); - break; - case 1: - transformBlock(sx + dx, sy + dy, sz - dz, blockValue, metaValue, fuzzY, netherTransform); - break; - case 2: - transformBlock(sx - dx, sy + dy, sz + dz, blockValue, metaValue, fuzzY, netherTransform); - break; - case 3: - transformBlock(sx - dx, sy + dy, sz - dz, blockValue, metaValue, fuzzY, netherTransform); - break; - case 4: - transformBlock(sx + dx, sy - dy, sz + dz, blockValue, metaValue, fuzzY, netherTransform); - break; - case 5: - transformBlock(sx + dx, sy - dy, sz - dz, blockValue, metaValue, fuzzY, netherTransform); - break; - case 6: - transformBlock(sx - dx, sy - dy, sz + dz, blockValue, metaValue, fuzzY, netherTransform); - break; - case 7: - transformBlock(sx - dx, sy - dy, sz - dz, blockValue, metaValue, fuzzY, netherTransform); - break; + switch (fuzzX) { + case 0: + transformBlock(pos.add(dx, dy, dz), state, fuzzY, netherTransform); + break; + case 1: + transformBlock(pos.add(dx, dy, -dz), state, fuzzY, netherTransform); + break; + case 2: + transformBlock(pos.add(-dx, dy, dz), state, fuzzY, netherTransform); + break; + case 3: + transformBlock(pos.add(-dx, dy, -dz), state, fuzzY, netherTransform); + break; + case 4: + transformBlock(pos.add(dx, -dy, dz), state, fuzzY, netherTransform); + break; + case 5: + transformBlock(pos.add(dx, -dy, -dz), state, fuzzY, netherTransform); + break; + case 6: + transformBlock(pos.add(-dx, -dy, dz), state, fuzzY, netherTransform); + break; + case 7: + transformBlock(pos.add(-dx, -dy, -dz), state, fuzzY, netherTransform); + break; } } } } } } - - /** - * - */ - protected void transformBlock(int x, int y, int z, Block blockValue, int metaValue, int fuzz, boolean netherTransform) - { - Block whatsThere = worldObj.getBlock(x, y, z); - int whatsMeta = worldObj.getBlockMetadata(x, y, z); - - if (whatsThere != Blocks.air && whatsThere.getBlockHardness(worldObj, x, y, z) == -1) - { + + private void transformBlock(BlockPos pos, IBlockState state, int fuzz, boolean netherTransform) { + IBlockState stateThere = world.getBlockState(pos); + + if (stateThere.getBlock() != Blocks.AIR && stateThere.getBlockHardness(world, pos) == -1) { // don't destroy unbreakable stuff return; } - - if (fuzz == 0 && whatsThere != Blocks.air) - { + + if (fuzz == 0 && stateThere.getBlock() != Blocks.AIR) { // make pop thing for original block - worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(whatsThere) + (whatsMeta << 12)); + world.playEvent(2001, pos, Block.getStateId(stateThere)); } - - if (netherTransform && whatsThere != Blocks.air) - { - worldObj.setBlock(x, y, z, Blocks.netherrack, 0, 3); + + if (netherTransform && stateThere.getBlock() != Blocks.AIR) { + world.setBlockState(pos, Blocks.NETHERRACK.getDefaultState(), 3); // fire on top? - if (worldObj.getBlock(x, y + 1, z) == Blocks.air && fuzz % 3 == 0) - { - worldObj.setBlock(x, y + 1, z, Blocks.fire, 0, 3); + if (world.isAirBlock(pos.up()) && fuzz % 3 == 0) { + world.setBlockState(pos.up(), Blocks.FIRE.getDefaultState(), 3); } - } - else - { - worldObj.setBlock(x, y, z, blockValue, metaValue, 3); + } else { + world.setBlockState(pos, state, 3); } } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFCicada.java b/src/main/java/twilightforest/tileentity/TileEntityTFCicada.java deleted file mode 100644 index 413708b67b..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFCicada.java +++ /dev/null @@ -1,113 +0,0 @@ -package twilightforest.tileentity; - -import twilightforest.TwilightForestMod; - - -public class TileEntityTFCicada extends TileEntityTFCritter { - - - public int yawDelay; - public int currentYaw; - public int desiredYaw; - - public int singDuration; - public boolean singing; - public int singDelay; - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - super.updateEntity(); - -// if (worldObj.getBlockMetadata(xCoord, yCoord, zCoord) != 1) { -// //System.out.println("Cicada tile entity block has invalid metadata, fixing"); -// worldObj.setBlockMetadata(xCoord, yCoord, zCoord, 1); -// } - - if(yawDelay > 0) - { - yawDelay--; - } else { - if (currentYaw == 0 && desiredYaw == 0) - { - // make it rotate! - yawDelay = 200 + worldObj.rand.nextInt(200); - desiredYaw = worldObj.rand.nextInt(15) - worldObj.rand.nextInt(15); - } - - if (currentYaw < desiredYaw) - { - currentYaw++; - } - if (currentYaw > desiredYaw) - { - currentYaw--; - } - if (currentYaw == desiredYaw) - { - desiredYaw = 0; - } - } - - if (singDelay > 0) - { - singDelay--; - } else { - if (singing && singDuration == 0) { - playSong(); - } - if (singing && singDuration >= 100) - { - singing = false; - singDuration = 0; - } - if (singing && singDuration < 100) - { - singDuration++; - doSingAnimation(); - } - if (!singing && singDuration <= 0) - { - singing = true; - singDelay = 100 + worldObj.rand.nextInt(100); - } - } - } - -// /** -// * There seems to be a bug in the chunk placing routines which sets the tileentity metadta to 0 even if the tile shifts metadatas when placed. -// * Thus, if the metadata is 0, re-check it -// */ -// @Override -// public int getBlockMetadata() { -// if (super.getBlockMetadata() == 0) -// { -// this.blockMetadata = -1; -// } -// return super.getBlockMetadata(); -// } - - - public void doSingAnimation() - { - if (worldObj.rand.nextInt(5) == 0) - { - double rx = xCoord + worldObj.rand.nextFloat(); - double ry = yCoord + worldObj.rand.nextFloat(); - double rz = zCoord + worldObj.rand.nextFloat(); - worldObj.spawnParticle("note", rx, ry, rz, 0.0D, 0.0D, 0.0D); - } - } - - public void playSong() - { - if (!TwilightForestMod.silentCicadas) - { - worldObj.playSoundEffect(xCoord, yCoord, zCoord, TwilightForestMod.ID + ":mob.cicada", 1.0f, (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.2F + 1.0F); - } - } -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFCinderFurnace.java b/src/main/java/twilightforest/tileentity/TileEntityTFCinderFurnace.java index 26eacda821..28210027cb 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFCinderFurnace.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFCinderFurnace.java @@ -1,621 +1,253 @@ package twilightforest.tileentity; -import java.util.Random; - -import twilightforest.block.BlockTFCinderFurnace; -import twilightforest.block.TFBlocks; -import cpw.mods.fml.common.registry.GameRegistry; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; -import net.minecraft.block.BlockFurnace; -import net.minecraft.block.material.Material; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.block.BlockLog; import net.minecraft.init.Blocks; import net.minecraft.init.Items; -import net.minecraft.inventory.ISidedInventory; +import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemSword; -import net.minecraft.item.ItemTool; import net.minecraft.item.crafting.FurnaceRecipes; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraftforge.oredict.OreDictionary; +import twilightforest.block.BlockTFCinderFurnace; +import twilightforest.block.BlockTFCinderLog; +import twilightforest.block.TFBlocks; -public class TileEntityTFCinderFurnace extends TileEntity implements ISidedInventory { - - private static final int SMELT_LOG_FACTOR = 10; - private static final int SLOT_INPUT = 0; - private static final int SLOT_FUEL = 1; - private static final int SLOT_OUTPUT = 2; - - private static final int[] slotsTop = new int[] {SLOT_INPUT}; - private static final int[] slotsBottom = new int[] {SLOT_OUTPUT, SLOT_FUEL}; - private static final int[] slotsSides = new int[] {SLOT_FUEL}; - - /** The ItemStacks that hold the items currently being used in the furnace */ - private ItemStack[] furnaceItemStacks = new ItemStack[3]; - /** The number of ticks that the furnace will keep burning */ - public int furnaceBurnTime; - /** The number of ticks that a fresh copy of the currently-burning item would keep the furnace burning for */ - public int currentItemBurnTime; - /** The number of ticks that the current item has been cooking for */ - public int furnaceCookTime; - private String customName; +import java.util.Random; - @Override - public int getSizeInventory() { - return this.furnaceItemStacks.length; - } +public class TileEntityTFCinderFurnace extends TileEntityFurnace { + private static final int SMELT_LOG_FACTOR = 10; + // [VanillaCopy] of superclass, edits noted @Override - public ItemStack getStackInSlot(int slot) { - return this.furnaceItemStacks[slot]; + public void update() { + boolean flag = this.isBurning(); + boolean flag1 = false; + + if (this.isBurning()) { + --this.furnaceBurnTime; + } + + if (!this.world.isRemote) { + ItemStack itemstack = (ItemStack) this.furnaceItemStacks.get(1); + + if (this.isBurning() || !itemstack.isEmpty() && !((ItemStack) this.furnaceItemStacks.get(0)).isEmpty()) { + if (!this.isBurning() && this.canSmelt()) { + this.furnaceBurnTime = getItemBurnTime(itemstack); + this.currentItemBurnTime = this.furnaceBurnTime; + + if (this.isBurning()) { + flag1 = true; + + if (!itemstack.isEmpty()) { + Item item = itemstack.getItem(); + itemstack.shrink(1); + + if (itemstack.isEmpty()) { + ItemStack item1 = item.getContainerItem(itemstack); + this.furnaceItemStacks.set(1, item1); + } + } + } + } + + if (this.isBurning() && this.canSmelt()) { + // TF - cook faster + this.cookTime += this.getCurrentSpeedMultiplier(); + + if (this.cookTime >= this.totalCookTime) // TF - change to geq since we can increment by >1 + { + this.cookTime = 0; + this.totalCookTime = this.getCookTime((ItemStack) this.furnaceItemStacks.get(0)); + this.smeltItem(); + flag1 = true; + } + } else { + this.cookTime = 0; + } + } else if (!this.isBurning() && this.cookTime > 0) { + this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.totalCookTime); + } + + if (flag != this.isBurning()) { + flag1 = true; + BlockTFCinderFurnace.setState(this.isBurning(), this.world, this.pos); // TF - use our furnace + } + + // TF - occasionally cinderize nearby logs + if (this.isBurning() && this.furnaceBurnTime % 5 == 0) { + this.cinderizeNearbyLog(); + } + } + + if (flag1) { + this.markDirty(); + } } - /** - * Removes from an inventory slot (first arg) up to a specified number (second arg) of items and returns them in a - * new stack. - */ - public ItemStack decrStackSize(int slot, int amount) - { - if (this.furnaceItemStacks[slot] != null) - { - ItemStack itemstack; - - if (this.furnaceItemStacks[slot].stackSize <= amount) - { - itemstack = this.furnaceItemStacks[slot]; - this.furnaceItemStacks[slot] = null; - return itemstack; - } - else - { - itemstack = this.furnaceItemStacks[slot].splitStack(amount); - - if (this.furnaceItemStacks[slot].stackSize == 0) - { - this.furnaceItemStacks[slot] = null; - } - - return itemstack; - } - } - else - { - return null; - } - } - - /** - * When some containers are closed they call this on each slot, then drop whatever it returns as an EntityItem - - * like when you close a workbench GUI. - */ - public ItemStack getStackInSlotOnClosing(int slot) - { - if (this.furnaceItemStacks[slot] != null) - { - ItemStack itemstack = this.furnaceItemStacks[slot]; - this.furnaceItemStacks[slot] = null; - return itemstack; - } - else - { - return null; - } - } - - /** - * Sets the given item stack to the specified slot in the inventory (can be crafting or armor sections). - */ - public void setInventorySlotContents(int slot, ItemStack itemStack) - { - this.furnaceItemStacks[slot] = itemStack; - - if (itemStack != null && itemStack.stackSize > this.getInventoryStackLimit()) - { - itemStack.stackSize = this.getInventoryStackLimit(); - } - } - - /** - * Returns the name of the inventory - */ - public String getInventoryName() - { - return this.hasCustomInventoryName() ? this.customName : "twilightforest.container.furnace"; - } - - /** - * Returns if the inventory is named - */ - public boolean hasCustomInventoryName() - { - return this.customName != null && this.customName.length() > 0; - } - - - public void readFromNBT(NBTTagCompound nbtTags) - { - super.readFromNBT(nbtTags); - NBTTagList nbttaglist = nbtTags.getTagList("Items", 10); - this.furnaceItemStacks = new ItemStack[this.getSizeInventory()]; - - for (int i = 0; i < nbttaglist.tagCount(); ++i) - { - NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); - byte slot = nbttagcompound1.getByte("Slot"); - - if (slot >= 0 && slot < this.furnaceItemStacks.length) - { - this.furnaceItemStacks[slot] = ItemStack.loadItemStackFromNBT(nbttagcompound1); - } - } - - this.furnaceBurnTime = nbtTags.getShort("BurnTime"); - this.furnaceCookTime = nbtTags.getShort("CookTime"); - this.currentItemBurnTime = getItemBurnTime(this.furnaceItemStacks[1]); - - if (nbtTags.hasKey("CustomName", 8)) - { - this.customName = nbtTags.getString("CustomName"); - } - } - - public void writeToNBT(NBTTagCompound nbtTags) - { - super.writeToNBT(nbtTags); - nbtTags.setShort("BurnTime", (short)this.furnaceBurnTime); - nbtTags.setShort("CookTime", (short)this.furnaceCookTime); - NBTTagList nbttaglist = new NBTTagList(); - - for (int i = 0; i < this.furnaceItemStacks.length; ++i) - { - if (this.furnaceItemStacks[i] != null) - { - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - nbttagcompound1.setByte("Slot", (byte)i); - this.furnaceItemStacks[i].writeToNBT(nbttagcompound1); - nbttaglist.appendTag(nbttagcompound1); - } - } - - nbtTags.setTag("Items", nbttaglist); - - if (this.hasCustomInventoryName()) - { - nbtTags.setString("CustomName", this.customName); - } - } - - /** - * Returns an integer between 0 and the passed value representing how close the current item is to being completely - * cooked - */ - @SideOnly(Side.CLIENT) - public int getCookProgressScaled(int p_145953_1_) - { - return this.furnaceCookTime * p_145953_1_ / 200; - } - - /** - * Returns an integer between 0 and the passed value representing how much burn time is left on the current fuel - * item, where 0 means that the item is exhausted and the passed value means that the item is fresh - */ - @SideOnly(Side.CLIENT) - public int getBurnTimeRemainingScaled(int p_145955_1_) - { - if (this.currentItemBurnTime == 0) - { - this.currentItemBurnTime = 200; - } - - return this.furnaceBurnTime * p_145955_1_ / this.currentItemBurnTime; - } - - /** - * Furnace isBurning - */ - public boolean isBurning() - { - return this.furnaceBurnTime > 0; - } - - public void updateEntity() - { - boolean flag = this.furnaceBurnTime > 0; - boolean flag1 = false; - - - if (this.furnaceBurnTime > 0) - { - --this.furnaceBurnTime; - } - - if (!this.worldObj.isRemote) - { - if (this.furnaceBurnTime != 0 || this.furnaceItemStacks[1] != null && this.furnaceItemStacks[0] != null) - { - if (this.furnaceBurnTime == 0 && this.canSmelt()) - { - this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]); - - if (this.furnaceBurnTime > 0) - { - flag1 = true; - - if (this.furnaceItemStacks[1] != null) - { - --this.furnaceItemStacks[1].stackSize; - - if (this.furnaceItemStacks[1].stackSize == 0) - { - this.furnaceItemStacks[1] = furnaceItemStacks[1].getItem().getContainerItem(furnaceItemStacks[1]); - } - } - } - } - - if (this.isBurning() && this.canSmelt()) - { - int speedMultiplier = this.getCurrentSpeedMultiplier(); - - //System.out.println("cooking with cinder furnace, speed multiplier = " + speedMultiplier); - - this.furnaceCookTime += speedMultiplier; - - if (this.furnaceCookTime >= 200) - { - this.furnaceCookTime = 0; - this.smeltItem(); - flag1 = true; - } - } - else - { - this.furnaceCookTime = 0; - } - } - - // update block if needed - if (flag != this.furnaceBurnTime > 0) - { - flag1 = true; - BlockTFCinderFurnace.updateFurnaceBlockState(this.furnaceBurnTime > 0, this.worldObj, this.xCoord, this.yCoord, this.zCoord); - } - - // occasionally cinderize nearby logs - if (this.isBurning() && this.furnaceBurnTime % 5 == 0) { - this.cinderizeNearbyLog(); - } - } - - if (flag1) - { - this.markDirty(); - } - } - - /** - * Turn a nearby log into a cinder log - */ - private void cinderizeNearbyLog() { - Random rand = this.getWorldObj().rand; - + private void cinderizeNearbyLog() { + Random rand = this.getWorld().rand; + int dx = rand.nextInt(2) - rand.nextInt(2); int dy = rand.nextInt(2) - rand.nextInt(2); int dz = rand.nextInt(2) - rand.nextInt(2); + BlockPos pos = getPos().add(dx, dy, dz); - if (this.worldObj.blockExists(this.xCoord + dx, this.yCoord + dy, this.zCoord + dz)) { - Block nearbyBlock = this.getWorldObj().getBlock(this.xCoord + dx, this.yCoord + dy, this.zCoord + dz); + if (this.world.isBlockLoaded(pos)) { + Block nearbyBlock = this.getWorld().getBlockState(pos).getBlock(); - if (nearbyBlock != TFBlocks.cinderLog && this.isLog(nearbyBlock)) { - this.getWorldObj().setBlock(this.xCoord + dx, this.yCoord + dy, this.zCoord + dz, TFBlocks.cinderLog, getCinderMetaFor(dx, dy, dz), 2); - // special effect? - this.getWorldObj().playAuxSFX(2004, this.xCoord + dx, this.yCoord + dy, this.zCoord + dz, 0); - this.getWorldObj().playAuxSFX(2004, this.xCoord + dx, this.yCoord + dy, this.zCoord + dz, 0); - this.getWorldObj().playSoundEffect(this.xCoord + dx + 0.5F, this.yCoord + dy + 0.5F, this.zCoord + dz + 0.5F, "fire.fire", 1.0F, 1.0F); + if (nearbyBlock != TFBlocks.cinder_log && this.isLog(nearbyBlock)) { + this.getWorld().setBlockState(pos, TFBlocks.cinder_log.getDefaultState().withProperty(BlockTFCinderLog.LOG_AXIS, getCinderFacing(dx, dy, dz)), 2); + this.getWorld().playEvent(2004, pos, 0); + this.getWorld().playEvent(2004, pos, 0); + this.getWorld().playSound(null, pos, SoundEvents.BLOCK_FIRE_AMBIENT, SoundCategory.BLOCKS, 1.0F, 1.0F); } } } - /** - * What meta should we set the log block with the specified offset to? - */ - private int getCinderMetaFor(int dx, int dy, int dz) { + /** + * What meta should we set the log block with the specified offset to? + */ + private BlockLog.EnumAxis getCinderFacing(int dx, int dy, int dz) { if (dz == 0 && dx != 0) { - return dy == 0 ? 4 : 8; + return dy == 0 ? BlockLog.EnumAxis.X : BlockLog.EnumAxis.Z; } else if (dx == 0 && dz != 0) { - return dy == 0 ? 8 : 4; + return dy == 0 ? BlockLog.EnumAxis.Z : BlockLog.EnumAxis.X; } else if (dx == 0 && dz == 0) { - return 0; + return BlockLog.EnumAxis.Y; } else { - return dy == 0 ? 0 : 12; + return dy == 0 ? BlockLog.EnumAxis.Y : BlockLog.EnumAxis.NONE; } - + } - /** - * Check the ore dictionary to see if a nearby block is a wood log block - */ private boolean isLog(Block nearbyBlock) { - int[] oreIDs = OreDictionary.getOreIDs(new ItemStack(nearbyBlock)); - for (int id : oreIDs) { - if (id == OreDictionary.getOreID("logWood")) { - return true; - } - } - - return false; + int[] oreIDs = OreDictionary.getOreIDs(new ItemStack(nearbyBlock)); + for (int id : oreIDs) { + if (id == OreDictionary.getOreID("logWood")) { + return true; + } + } + + return false; } /** - * What is the current speed multiplier, as an int. - */ - private int getCurrentSpeedMultiplier() { + * What is the current speed multiplier, as an int. + */ + private int getCurrentSpeedMultiplier() { return getCurrentMultiplier(2); } - /** - * Returns a number that is based on the number of nearby logs divided by the factor given. - */ + /** + * Returns a number that is based on the number of nearby logs divided by the factor given. + */ private int getCurrentMultiplier(int factor) { int logs = this.countNearbyLogs(); - + if (logs < factor) { return 1; } else { - return (logs / factor) + (this.worldObj.rand.nextInt(factor) >= (logs % factor) ? 0 : 1); + return (logs / factor) + (this.world.rand.nextInt(factor) >= (logs % factor) ? 0 : 1); } } - /** - * Search around the block and return how many (out of a possible 26) of the blocks nearby are cinder log blocks - */ - private int countNearbyLogs() { - int count = 0; - + private int countNearbyLogs() { + int count = 0; + for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { for (int dz = -1; dz <= 1; dz++) { - if (this.worldObj.blockExists(this.xCoord + dx, this.yCoord + dy, this.zCoord + dz) && this.getWorldObj().getBlock(this.xCoord + dx, this.yCoord + dy, this.zCoord + dz) == TFBlocks.cinderLog) { + BlockPos pos = getPos().add(dx, dy, dz); + if (this.world.isBlockLoaded(pos) && this.getWorld().getBlockState(pos).getBlock() == TFBlocks.cinder_log) { count++; } } } } - - //System.out.println("cooking with cinder furnace, log factor = " + count); - return count; } - /** - * Returns true if the furnace can smelt an item, i.e. has a source item, destination stack isn't full, etc. - */ - private boolean canSmelt() - { - if (this.furnaceItemStacks[SLOT_INPUT] == null) - { - return false; - } - else - { - ItemStack outputStack = FurnaceRecipes.smelting().getSmeltingResult(this.furnaceItemStacks[SLOT_INPUT]); - if (outputStack == null) { - return false; - } - if (this.furnaceItemStacks[SLOT_OUTPUT] == null) { - return true; - } - if (!this.furnaceItemStacks[SLOT_OUTPUT].isItemEqual(outputStack)) { - return false; - } - - int resultStackSize = furnaceItemStacks[SLOT_OUTPUT].stackSize + this.getMaxOutputStacks(this.furnaceItemStacks[SLOT_INPUT], outputStack); - - return resultStackSize <= getInventoryStackLimit() && resultStackSize <= this.furnaceItemStacks[2].getMaxStackSize(); - } - } - - /** - * Return the max number of items in the output stack, given our current multiplier - */ - public int getMaxOutputStacks(ItemStack input, ItemStack output) { - if (this.canMultiply(input, output)) { - return output.stackSize * this.getCurrentMaxSmeltMultiplier(); - } else { - return output.stackSize; - } - } - - /** - * Turn one item from the furnace source stack into the appropriate smelted item in the furnace result stack - */ - public void smeltItem() - { - if (this.canSmelt()) - { - ItemStack outputStack = FurnaceRecipes.smelting().getSmeltingResult(this.furnaceItemStacks[SLOT_INPUT]); - - if (this.canMultiply(this.furnaceItemStacks[SLOT_INPUT], outputStack)) { - - // multiply number of results by our current smelt factor - int smeltMultiplier = this.getCurrentSmeltMultiplier(); - - if (smeltMultiplier > 1) { - // copy output stack - outputStack = outputStack.copy(); - - // we shouldn't run into max stack size problems, since we've already checked in canSmelt() - outputStack.stackSize *= smeltMultiplier; - } - - - } - - if (this.furnaceItemStacks[SLOT_OUTPUT] == null) - { - this.furnaceItemStacks[SLOT_OUTPUT] = outputStack.copy(); - } - else if (this.furnaceItemStacks[SLOT_OUTPUT].getItem() == outputStack.getItem()) - { - this.furnaceItemStacks[SLOT_OUTPUT].stackSize += outputStack.stackSize; // Forge BugFix: Results may have multiple items - } - - --this.furnaceItemStacks[SLOT_INPUT].stackSize; - - if (this.furnaceItemStacks[SLOT_INPUT].stackSize <= 0) - { - this.furnaceItemStacks[SLOT_INPUT] = null; - } - } - } - - - /** - * Can we multiply the output? We currently multiply logs->charcoal, ore->ingots, and food - */ - public boolean canMultiply(ItemStack input, ItemStack output) { - - // check the input ore ID for ores - int[] oreIDs = OreDictionary.getOreIDs(input); - for (int id : oreIDs) { - // does the input have an oredictionary result that starts with "ore"? - if (OreDictionary.getOreName(id).startsWith("ore")) { - //System.out.println("cinder furnace cook result, ore found, name is " + OreDictionary.getOreName(id)); - - return true; - } else if (id == OreDictionary.getOreID("logWood")) { - //System.out.println("cinder furnace cook result, log found"); - return true; - } - } - - // does the in - - return false; - } - - /** - * What is the current speed multiplier, as an int. - */ - private int getCurrentSmeltMultiplier() { - return getCurrentMultiplier(SMELT_LOG_FACTOR); + // [VanillaCopy] of superclass ver, changes noted + private boolean canSmelt() { + if (((ItemStack) this.furnaceItemStacks.get(0)).isEmpty()) { + return false; + } else { + ItemStack itemstack = FurnaceRecipes.instance().getSmeltingResult((ItemStack) this.furnaceItemStacks.get(0)); + + if (itemstack.isEmpty()) { + return false; + } else { + ItemStack itemstack1 = (ItemStack) this.furnaceItemStacks.get(2); + if (itemstack1.isEmpty()) return true; + if (!itemstack1.isItemEqual(itemstack)) return false; + int result = itemstack1.getCount() + getMaxOutputStacks(furnaceItemStacks.get(0), itemstack); // TF - account for multiplying + return result <= getInventoryStackLimit() && result <= itemstack1.getMaxStackSize(); // Forge fix: make furnace respect stack sizes in furnace recipes + } + } } /** - * What is the current speed multiplier, as an int. - */ - private int getCurrentMaxSmeltMultiplier() { - return (int)Math.ceil((float)this.countNearbyLogs() / (float)SMELT_LOG_FACTOR); + * Return the max number of items in the output stack, given our current multiplier + */ + public int getMaxOutputStacks(ItemStack input, ItemStack output) { + if (this.canMultiply(input, output)) { + return output.getCount() * this.getCurrentMaxSmeltMultiplier(); + } else { + return output.getCount(); + } } - - /** - * Returns the number of ticks that the supplied fuel item will keep the furnace burning, or 0 if the item isn't - * fuel - */ - public static int getItemBurnTime(ItemStack p_145952_0_) - { - if (p_145952_0_ == null) - { - return 0; - } - else - { - Item item = p_145952_0_.getItem(); - - if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.air) - { - Block block = Block.getBlockFromItem(item); - - if (block == Blocks.wooden_slab) - { - return 150; - } - - if (block.getMaterial() == Material.wood) - { - return 300; - } - - if (block == Blocks.coal_block) - { - return 16000; - } - } - - if (item instanceof ItemTool && ((ItemTool)item).getToolMaterialName().equals("WOOD")) return 200; - if (item instanceof ItemSword && ((ItemSword)item).getToolMaterialName().equals("WOOD")) return 200; - if (item instanceof ItemHoe && ((ItemHoe)item).getToolMaterialName().equals("WOOD")) return 200; - if (item == Items.stick) return 100; - if (item == Items.coal) return 1600; - if (item == Items.lava_bucket) return 20000; - if (item == Item.getItemFromBlock(Blocks.sapling)) return 100; - if (item == Items.blaze_rod) return 2400; - return GameRegistry.getFuelValue(p_145952_0_); - } - } - - public static boolean isItemFuel(ItemStack p_145954_0_) - { - /** - * Returns the number of ticks that the supplied fuel item will keep the furnace burning, or 0 if the item isn't - * fuel - */ - return getItemBurnTime(p_145954_0_) > 0; - } - + // [VanillaCopy] superclass, using our own canSmelt and multiplying output @Override - public int getInventoryStackLimit() { - return 64; - } + public void smeltItem() { + if (this.canSmelt()) { + ItemStack itemstack = (ItemStack) this.furnaceItemStacks.get(0); + ItemStack itemstack1 = FurnaceRecipes.instance().getSmeltingResult(itemstack); + itemstack1.setCount(itemstack1.getCount() * getCurrentSmeltMultiplier()); + ItemStack itemstack2 = (ItemStack) this.furnaceItemStacks.get(2); + + if (itemstack2.isEmpty()) { + this.furnaceItemStacks.set(2, itemstack1.copy()); + } else if (itemstack2.getItem() == itemstack1.getItem()) { + itemstack2.grow(itemstack1.getCount()); + } - @Override - public boolean isUseableByPlayer(EntityPlayer player) { - return this.worldObj.getTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : player.getDistanceSq((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D) <= 64.0D; + if (itemstack.getItem() == Item.getItemFromBlock(Blocks.SPONGE) && itemstack.getMetadata() == 1 && !((ItemStack) this.furnaceItemStacks.get(1)).isEmpty() && ((ItemStack) this.furnaceItemStacks.get(1)).getItem() == Items.BUCKET) { + this.furnaceItemStacks.set(1, new ItemStack(Items.WATER_BUCKET)); + } + itemstack.shrink(1); + } } - @Override - public void openInventory() {;} - - @Override - public void closeInventory() {;} + private boolean canMultiply(ItemStack input, ItemStack output) { + int[] oreIDs = OreDictionary.getOreIDs(input); + for (int id : oreIDs) { + if (OreDictionary.getOreName(id).startsWith("ore") || id == OreDictionary.getOreID("logWood")) { + return true; + } + } - @Override - public boolean isItemValidForSlot(int slot, ItemStack itemStack) { - return slot == SLOT_OUTPUT ? false : (slot == SLOT_FUEL ? TileEntityFurnace.isItemFuel(itemStack) : true); + return false; } - @Override - public int[] getAccessibleSlotsFromSide(int p_94128_1_) { - return p_94128_1_ == 0 ? slotsBottom : (p_94128_1_ == 1 ? slotsTop : slotsSides); + /** + * What is the current speed multiplier, as an int. + */ + private int getCurrentSmeltMultiplier() { + return getCurrentMultiplier(SMELT_LOG_FACTOR); } - /** - * Returns true if automation can insert the given item in the given slot from the given side. Args: Slot, item, - * side - */ - public boolean canInsertItem(int slot, ItemStack itemStack, int side) - { - return this.isItemValidForSlot(slot, itemStack); - } - - /** - * Returns true if automation can extract the given item in the given slot from the given side. Args: Slot, item, - * side - */ - public boolean canExtractItem(int slot, ItemStack itemStack, int side) - { - return side != SLOT_INPUT || slot != SLOT_FUEL || itemStack.getItem() == Items.bucket; - } - + /** + * What is the current speed multiplier, as an int. + */ + private int getCurrentMaxSmeltMultiplier() { + return (int) Math.ceil((float) this.countNearbyLogs() / (float) SMELT_LOG_FACTOR); + } } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFCritter.java b/src/main/java/twilightforest/tileentity/TileEntityTFCritter.java deleted file mode 100644 index 648e6c8883..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFCritter.java +++ /dev/null @@ -1,105 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; - -public abstract class TileEntityTFCritter extends TileEntity { - - public TileEntityTFCritter() { - super(); - } - - - /** - * Reads a tile entity from NBT. - */ - @Override - public void readFromNBT(NBTTagCompound par1NBTTagCompound) { - super.readFromNBT(par1NBTTagCompound); - } - - /** - * Writes a tile entity to NBT. - */ - @Override - public void writeToNBT(NBTTagCompound par1NBTTagCompound) { - super.writeToNBT(par1NBTTagCompound); - } - - /** - * Determines if this TileEntity requires update calls. - * @return True if you want updateEntity() to be called, false if not - */ - @Override - public boolean canUpdate() - { - return true; - } - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - - } - - -// /** -// * Fix imported tileentities from version 1.9 -// */ -// private void fixFacing() { -// // we get called here if our facing is -1. Let's see what we can do. -// //System.out.println("Trying to fix critter tile entity facing..."); -// -// // look in all directions for a surface to face -// if (TFBlocks.firefly.canPlaceBlockAt(worldObj, xCoord - 1, yCoord, zCoord)) { -// setFacing(1); -// } -// else if (TFBlocks.firefly.canPlaceBlockAt(worldObj, xCoord + 1, yCoord, zCoord)) { -// setFacing(2); -// } -// else if (TFBlocks.firefly.canPlaceBlockAt(worldObj, xCoord, yCoord, zCoord - 1)) { -// setFacing(3); -// } -// else if (TFBlocks.firefly.canPlaceBlockAt(worldObj, xCoord, yCoord, zCoord + 1)) { -// setFacing(4); -// } -// else if (TFBlocks.firefly.canPlaceBlockAt(worldObj, xCoord, yCoord - 1, zCoord)) { -// setFacing(5); -// } -// else if (TFBlocks.firefly.canPlaceBlockAt(worldObj, xCoord, yCoord + 1, zCoord)) { -// setFacing(6); -// } -// -// } - -// /** -// * Called when you receive a TileEntityData packet for the location this -// * TileEntity is currently in. On the client, the NetworkManager will always -// * be the remote server. On the server, it will be whomever is responsible for -// * sending the packet. -// * -// * @param net The NetworkManager the packet originated from -// * @param pkt The data packet -// */ -// @Override -// public void onDataPacket(NetworkManager net, Packet132TileEntityData pkt) { -//// setFacing(pkt.customParam1); -// } - - - -// /** -// * Overriden in a sign to provide the text -// */ -// public Packet getDescriptionPacket() -// { -// int var1 = getFacing(); -// return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, var1); -// } - - -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFFirefly.java b/src/main/java/twilightforest/tileentity/TileEntityTFFirefly.java deleted file mode 100644 index 122711c6c4..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFFirefly.java +++ /dev/null @@ -1,120 +0,0 @@ -package twilightforest.tileentity; - -import twilightforest.entity.passive.EntityTFTinyFirefly; - - - -public class TileEntityTFFirefly extends TileEntityTFCritter { - - - public int yawDelay; - public int currentYaw; - public int desiredYaw; - - public float glowIntensity; - public boolean glowing; - public int glowDelay; - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - super.updateEntity(); - -// if (worldObj.getBlockMetadata(xCoord, yCoord, zCoord) != 0) { -// //System.out.println("Firefly tile entity block has invalid metadata, fixing"); -// worldObj.setBlockMetadata(xCoord, yCoord, zCoord, 0); -// } - - if (anyPlayerInRange() && worldObj.rand.nextInt(20) == 0) - { - doFireflyFX(); - } - - if(yawDelay > 0) - { - yawDelay--; - } else { - if (currentYaw == 0 && desiredYaw == 0) - { - // make it rotate! - yawDelay = 200 + worldObj.rand.nextInt(200); - desiredYaw = worldObj.rand.nextInt(15) - worldObj.rand.nextInt(15); - } - - if (currentYaw < desiredYaw) - { - currentYaw++; - } - if (currentYaw > desiredYaw) - { - currentYaw--; - } - if (currentYaw == desiredYaw) - { - desiredYaw = 0; - } - } - - if (glowDelay > 0) - { - glowDelay--; - } else { - if (glowing && glowIntensity >= 1.0) - { - glowing = false; - } - if (glowing && glowIntensity < 1.0) - { - glowIntensity += 0.05; - } - if (!glowing && glowIntensity > 0) - { - glowIntensity -= 0.05; - } - if (!glowing && glowIntensity <= 0) - { - glowing = true; - glowDelay = worldObj.rand.nextInt(50); - } - } - } - - public boolean anyPlayerInRange() - { - return worldObj.getClosestPlayer(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, 16D) != null; - } - - -// /** -// * There seems to be a bug in the chunk placing routines which sets the tileentity metadta to 0 even if the tile shifts metadatas when placed. -// * Thus, if the metadata is 0, re-check it -// */ -// @Override -// public int getBlockMetadata() { -// if (super.getBlockMetadata() == 0) -// { -// this.blockMetadata = -1; -// } -// return super.getBlockMetadata(); -// } - - /** - * Makes little fireflies float around - */ - void doFireflyFX() - { - double rx = xCoord + worldObj.rand.nextFloat(); - double ry = yCoord + worldObj.rand.nextFloat(); - double rz = zCoord + worldObj.rand.nextFloat(); -// EntityTFFireflyFX fireflyfx = new EntityTFFireflyFX(worldObj, rx, ry, rz, 0.0F, 0.0F, 0.0F); -// ModLoader.getMinecraftInstance().effectRenderer.addEffect(fireflyfx); - EntityTFTinyFirefly tinyfly = new EntityTFTinyFirefly(worldObj, rx, ry, rz); - worldObj.addWeatherEffect(tinyfly); - } - - -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFFlameJet.java b/src/main/java/twilightforest/tileentity/TileEntityTFFlameJet.java index 1251e7f669..4d7f26b04e 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFFlameJet.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFFlameJet.java @@ -1,114 +1,103 @@ package twilightforest.tileentity; -import java.util.List; - import net.minecraft.entity.Entity; +import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ITickable; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; import twilightforest.TwilightForestMod; import twilightforest.block.BlockTFFireJet; import twilightforest.block.TFBlocks; +import twilightforest.enums.FireJetVariant; +import twilightforest.client.particle.TFParticleType; -public class TileEntityTFFlameJet extends TileEntity { - - int counter = 0; - private int nextMeta; - - public TileEntityTFFlameJet() { - this(BlockTFFireJet.META_JET_IDLE); - } - - public TileEntityTFFlameJet(int parNextMeta) { - this.nextMeta = parNextMeta; +import java.util.List; + +public class TileEntityTFFlameJet extends TileEntity implements ITickable { + + private int counter = 0; + private FireJetVariant nextVariant; + + public TileEntityTFFlameJet(FireJetVariant variant) { + this.nextVariant = variant; } - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - if (++counter > 60) - { + public TileEntityTFFlameJet() {} + + @Override + public void update() { + + double x = this.pos.getX(); + double y = this.pos.getY(); + double z = this.pos.getZ(); + + if (++counter > 60) { counter = 0; - // idle again - if (!worldObj.isRemote && worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord) == TFBlocks.fireJet) - { - worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, TFBlocks.fireJet, this.nextMeta, 3); + // idle again + if (!world.isRemote && world.getBlockState(pos).getBlock() == TFBlocks.fire_jet) { + world.setBlockState(pos, TFBlocks.fire_jet.getDefaultState().withProperty(BlockTFFireJet.VARIANT, this.nextVariant)); } - this.invalidate(); } - else if (counter % 2 == 0) - { - worldObj.spawnParticle("largesmoke", this.xCoord + 0.5, this.yCoord + 1.0, this.zCoord + 0.5, 0.0D, 0.0D, 0.0D); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "largeflame", this.xCoord + 0.5, this.yCoord + 1.0, this.zCoord + 0.5, 0.0D, 0.5D, 0.0D); -// TwilightForestMod.proxy.spawnParticle("largeflame", this.xCoord + 0.5, this.yCoord + 1.0, this.zCoord + 0.5, + + if (world.isRemote) { + if (counter % 2 == 0) { + world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, x + 0.5, y + 1.0, z + 0.5, 0.0D, 0.0D, 0.0D); + TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 0.5, y + 1.0, z + 0.5, 0.0D, 0.5D, 0.0D); +// TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 0.5, y + 1.0, z + 0.5, // Math.cos(counter / 4.0) * 0.2, 0.35D, Math.sin(counter / 4.0) * 0.2); -// TwilightForestMod.proxy.spawnParticle("largeflame", this.xCoord + 0.5, this.yCoord + 1.0, this.zCoord + 0.5, +// TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 0.5, y + 1.0, this.pos.getZ() + 0.5, // Math.cos(counter / 4.0 + Math.PI) * 0.2, 0.35D, Math.sin(counter / 4.0 + Math.PI) * 0.2); -// TwilightForestMod.proxy.spawnParticle("largeflame", this.xCoord + 0.5 + Math.cos(counter / 4.0), this.yCoord + 1.0, this.zCoord + 0.5 + Math.sin(counter / 4.0), +// TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 0.5 + Math.cos(counter / 4.0), y + 1.0, z + 0.5 + Math.sin(counter / 4.0), // Math.sin(counter / 4.0) * 0.05, 0.35D, Math.cos(counter / 4.0) * 0.05); -// TwilightForestMod.proxy.spawnParticle("largeflame", this.xCoord + 0.5 + Math.cos(counter / 4.0 + Math.PI), this.yCoord + 1.0, this.zCoord + 0.5 + Math.sin(counter / 4.0 + Math.PI), +// TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 0.5 + Math.cos(counter / 4.0 + Math.PI), y + 1.0, z + 0.5 + Math.sin(counter / 4.0 + Math.PI), // Math.sin(counter / 4.0 + Math.PI) * 0.05, 0.35D, Math.cos(counter / 4.0 + Math.PI) * 0.05); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "largeflame", this.xCoord - 0.5, this.yCoord + 1.0, this.zCoord + 0.5, 0.05D, 0.5D, 0.0D); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "largeflame", this.xCoord + 0.5, this.yCoord + 1.0, this.zCoord - 0.5, 0.0D, 0.5D, 0.05D); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "largeflame", this.xCoord + 1.5, this.yCoord + 1.0, this.zCoord + 0.5, -0.05D, 0.5D, 0.0D); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "largeflame", this.xCoord + 0.5, this.yCoord + 1.0, this.zCoord + 1.5, 0.0D, 0.5D, -0.05D); + TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x - 0.5, y + 1.0, z + 0.5, 0.05D, 0.5D, 0.0D); + TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 0.5, y + 1.0, z - 0.5, 0.0D, 0.5D, 0.05D); + TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 1.5, y + 1.0, z + 0.5, -0.05D, 0.5D, 0.0D); + TwilightForestMod.proxy.spawnParticle(TFParticleType.LARGE_FLAME, x + 0.5, y + 1.0, z + 1.5, 0.0D, 0.5D, -0.05D); + } - } - - // sounds - if (counter % 4 == 0) - { - worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, "mob.ghast.fireball", 1.0F + worldObj.rand.nextFloat(), worldObj.rand.nextFloat() * 0.7F + 0.3F); + // sounds + if (counter % 4 == 0) { + world.playSound(x + 0.5, y + 0.5, z + 0.5, SoundEvents.ENTITY_GHAST_SHOOT, SoundCategory.BLOCKS, 1.0F + world.rand.nextFloat(), world.rand.nextFloat() * 0.7F + 0.3F, false); + } else if (counter == 1) { + world.playSound(x + 0.5, y + 0.5, z + 0.5, SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F + world.rand.nextFloat(), world.rand.nextFloat() * 0.7F + 0.3F, false); + } } - else if (counter == 1) - { - worldObj.playSoundEffect(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, "fire.ignite", 1.0F + worldObj.rand.nextFloat(), worldObj.rand.nextFloat() * 0.7F + 0.3F); - } - + // actual fire effects - if (!worldObj.isRemote) - { - if (counter % 5 == 0) - { + if (!world.isRemote) { + if (counter % 5 == 0) { // find entities in the area of effect - List entitiesInRange = worldObj.getEntitiesWithinAABB(Entity.class, - AxisAlignedBB.getBoundingBox(this.xCoord - 2, this.yCoord, this.zCoord - 2, - this.xCoord + 2, this.yCoord + 4, this.zCoord + 2)); + List entitiesInRange = world.getEntitiesWithinAABB(Entity.class, + new AxisAlignedBB(pos.add(-2, 0, -2), pos.add(2, 4, 2))); // fire! - for (Entity entity : entitiesInRange) - { - if (!entity.isImmuneToFire()) - { - entity.attackEntityFrom(DamageSource.inFire, 2); + for (Entity entity : entitiesInRange) { + if (!entity.isImmuneToFire()) { + entity.attackEntityFrom(DamageSource.IN_FIRE, 2); entity.setFire(15); - } + } } } } - } - - /** - * Reads a tile entity from NBT. - */ - public void readFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readFromNBT(par1NBTTagCompound); - this.nextMeta = par1NBTTagCompound.getInteger("NextMeta"); - } - - /** - * Writes a tile entity to NBT. - */ - public void writeToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeToNBT(par1NBTTagCompound); - par1NBTTagCompound.setInteger("NextMeta", this.nextMeta); - } + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + super.readFromNBT(compound); + this.nextVariant = FireJetVariant.values()[compound.getInteger("NextMeta")]; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + super.writeToNBT(compound); + compound.setInteger("NextMeta", this.nextVariant.ordinal()); + return compound; + } } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapActive.java b/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapActive.java index 4939811cba..31642a258b 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapActive.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapActive.java @@ -1,129 +1,108 @@ package twilightforest.tileentity; -import java.util.List; -import java.util.Random; - import net.minecraft.entity.monster.EntityGhast; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; +import net.minecraft.util.ITickable; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; +import twilightforest.TFSounds; import twilightforest.TwilightForestMod; import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.TFBlocks; +import twilightforest.enums.TowerDeviceVariant; +import twilightforest.client.particle.TFParticleType; import twilightforest.entity.EntityTFTowerGhast; import twilightforest.entity.boss.EntityTFUrGhast; -public class TileEntityTFGhastTrapActive extends TileEntity { - - public int counter = 0; - - public Random rand = new Random(); +import java.util.List; +import java.util.Random; + +public class TileEntityTFGhastTrapActive extends TileEntity implements ITickable { + + private int counter = 0; + + private final Random rand = new Random(); - - public boolean canUpdate() - { - return true; - } - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ @Override - public void updateEntity() - { + public void update() { ++counter; - if (worldObj.isRemote) - { + if (world.isRemote) { // smoke when done if (counter > 100 && counter % 4 == 0) { - TwilightForestMod.proxy.spawnParticle(this.worldObj, "hugesmoke", this.xCoord + 0.5, this.yCoord + 0.95, this.zCoord + 0.5, Math.cos(counter / 10.0) * 0.05, 0.25D, Math.sin(counter / 10.0) * 0.05); - } - else if (counter < 100) - { + TwilightForestMod.proxy.spawnParticle(TFParticleType.HUGE_SMOKE, this.pos.getX() + 0.5, this.pos.getY() + 0.95, this.pos.getZ() + 0.5, Math.cos(counter / 10.0) * 0.05, 0.25D, Math.sin(counter / 10.0) * 0.05); + + } else if (counter < 100) { + + double x = this.pos.getX() + 0.5D; + double y = this.pos.getY() + 1.0D; + double z = this.pos.getZ() + 0.5D; + double dx = Math.cos(counter / 10.0) * 2.5; double dy = 20D; double dz = Math.sin(counter / 10.0) * 2.5; - - TwilightForestMod.proxy.spawnParticle(this.worldObj, "ghasttrap", this.xCoord + 0.5D, this.yCoord + 1.0D, this.zCoord + 0.5D, dx, dy, dz); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "ghasttrap", this.xCoord + 0.5D, this.yCoord + 1.0D, this.zCoord + 0.5D, -dx, dy, -dz); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "ghasttrap", this.xCoord + 0.5D, this.yCoord + 1.0D, this.zCoord + 0.5D, -dx, dy / 2, dz); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "ghasttrap", this.xCoord + 0.5D, this.yCoord + 1.0D, this.zCoord + 0.5D, dx, dy / 2, -dz); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "ghasttrap", this.xCoord + 0.5D, this.yCoord + 1.0D, this.zCoord + 0.5D, dx / 2, dy / 4, dz / 2); - TwilightForestMod.proxy.spawnParticle(this.worldObj, "ghasttrap", this.xCoord + 0.5D, this.yCoord + 1.0D, this.zCoord + 0.5D, -dx / 2, dy / 4, -dz / 2); + TwilightForestMod.proxy.spawnParticle(TFParticleType.GHAST_TRAP, x, y, z, dx, dy, dz); + TwilightForestMod.proxy.spawnParticle(TFParticleType.GHAST_TRAP, x, y, z, -dx, dy, -dz); + TwilightForestMod.proxy.spawnParticle(TFParticleType.GHAST_TRAP, x, y, z, -dx, dy / 2, dz); + TwilightForestMod.proxy.spawnParticle(TFParticleType.GHAST_TRAP, x, y, z, dx, dy / 2, -dz); + TwilightForestMod.proxy.spawnParticle(TFParticleType.GHAST_TRAP, x, y, z, dx / 2, dy / 4, dz / 2); + TwilightForestMod.proxy.spawnParticle(TFParticleType.GHAST_TRAP, x, y, z, -dx / 2, dy / 4, -dz / 2); } // appropriate sound - if (counter < 30) - { - worldObj.playSound(this.xCoord + 0.5D, this.yCoord + 1.5D, this.zCoord + 0.5D, TwilightForestMod.ID + ":mob.urghast.trapwarmup", 1.0F, 4.0F, false); - } - else if (counter < 80) - { - worldObj.playSound(this.xCoord + 0.5D, this.yCoord + 1.5D, this.zCoord + 0.5D, TwilightForestMod.ID + ":mob.urghast.trapon", 1.0F, 4.0F, false); - } - else - { - worldObj.playSound(this.xCoord + 0.5D, this.yCoord + 1.5D, this.zCoord + 0.5D, TwilightForestMod.ID + ":mob.urghast.trapspindown", 1.0F, 4.0F, false); + if (counter < 30) { + world.playSound(pos.getX() + 0.5D, pos.getY() + 1.5D, pos.getZ() + 0.5D, TFSounds.URGHAST_TRAP_WARMUP, SoundCategory.BLOCKS, 1.0F, 4.0F, false); + } else if (counter < 80) { + world.playSound(pos.getX() + 0.5D, pos.getY() + 1.5D, pos.getZ() + 0.5D, TFSounds.URGHAST_TRAP_ON, SoundCategory.BLOCKS, 1.0F, 4.0F, false); + } else { + world.playSound(pos.getX() + 0.5D, pos.getY() + 1.5D, pos.getZ() + 0.5D, TFSounds.URGHAST_TRAP_SPINDOWN, SoundCategory.BLOCKS, 1.0F, 4.0F, false); } } - if (!worldObj.isRemote) - { + if (!world.isRemote) { // trap nearby ghasts - AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox((double)this.xCoord, (double)this.yCoord + 16, (double)this.zCoord, (double)(this.xCoord + 1), (double)(this.yCoord + 16 + 1), (double)(this.zCoord + 1)).expand(6D, 16D, 6D); + AxisAlignedBB aabb = new AxisAlignedBB(pos.up(16), pos.up(16).add(1, 1, 1)).grow(6D, 16D, 6D); - List nearbyGhasts = worldObj.getEntitiesWithinAABB(EntityGhast.class, aabb); + List nearbyGhasts = world.getEntitiesWithinAABB(EntityGhast.class, aabb); - for (EntityGhast ghast : nearbyGhasts) - { + for (EntityGhast ghast : nearbyGhasts) { //stop boss tantrum - if (ghast instanceof EntityTFUrGhast) - { - ((EntityTFUrGhast)ghast).stopTantrum(); + if (ghast instanceof EntityTFUrGhast) { + ((EntityTFUrGhast) ghast).setInTantrum(false); + ((EntityTFUrGhast) ghast).noClip = true; // turn this on so we can pull it in close // move boss to this point - ghast.motionX = (ghast.posX - this.xCoord - 0.5) * -0.1; - ghast.motionY = (ghast.posY - this.yCoord - 2.5) * -0.1; - ghast.motionZ = (ghast.posZ - this.zCoord - 0.5) * -0.1; + ghast.motionX = (ghast.posX - this.pos.getX() - 0.5) * -0.1; + ghast.motionY = (ghast.posY - this.pos.getY() - 2.5) * -0.1; + ghast.motionZ = (ghast.posZ - this.pos.getZ() - 0.5) * -0.1; - if (rand.nextInt(10) == 0) - { - ghast.attackEntityFrom(DamageSource.generic, 3); + if (rand.nextInt(10) == 0) { + ghast.attackEntityFrom(DamageSource.GENERIC, 7); + ((EntityTFUrGhast) ghast).resetDamageUntilNextPhase(); } - } - else - { + } else { // move ghasts to this point - ghast.motionX = (ghast.posX - this.xCoord - 0.5) * -0.1; - ghast.motionY = (ghast.posY - this.yCoord - 1.5) * -0.1; - ghast.motionZ = (ghast.posZ - this.zCoord - 0.5) * -0.1; + ghast.motionX = (ghast.posX - this.pos.getX() - 0.5) * -0.1; + ghast.motionY = (ghast.posY - this.pos.getY() - 1.5) * -0.1; + ghast.motionZ = (ghast.posZ - this.pos.getZ() - 0.5) * -0.1; - if (rand.nextInt(10) == 0) - { - ghast.attackEntityFrom(DamageSource.generic, 10); + if (rand.nextInt(10) == 0) { + ghast.attackEntityFrom(DamageSource.GENERIC, 10); } } - - if (ghast instanceof EntityTFTowerGhast) - { - ((EntityTFTowerGhast)ghast).setInTrap(); + + if (ghast instanceof EntityTFTowerGhast) { + ((EntityTFTowerGhast) ghast).setInTrap(); } } - - - - if (counter >= 120) - { - // deactivate - worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, TFBlocks.towerDevice, BlockTFTowerDevice.META_GHASTTRAP_INACTIVE, 3); - //worldObj.scheduleBlockUpdate(this.xCoord, this.yCoord, this.zCoord, TFBlocks.towerDevice, 4); + if (counter >= 120) { + world.setBlockState(pos, TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.GHASTTRAP_INACTIVE), 3); } } } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapInactive.java b/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapInactive.java index b7a23a9bd8..784a4009f1 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapInactive.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFGhastTrapInactive.java @@ -1,53 +1,39 @@ package twilightforest.tileentity; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - import net.minecraft.entity.Entity; +import net.minecraft.init.SoundEvents; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ITickable; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; import twilightforest.TwilightForestMod; -import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.TFBlocks; +import twilightforest.client.particle.TFParticleType; import twilightforest.entity.EntityTFMiniGhast; -public class TileEntityTFGhastTrapInactive extends TileEntity { - - int counter; - Random rand = new Random(); - - ArrayList dyingGhasts = new ArrayList(); - - /** - * Determines if this TileEntity requires update calls. - * @return True if you want updateEntity() to be called, false if not - */ - @Override - public boolean canUpdate() { - return true; - } +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class TileEntityTFGhastTrapInactive extends TileEntity implements ITickable { + + private int counter; + private final Random rand = new Random(); + private final List dyingGhasts = new ArrayList(); - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ @Override - public void updateEntity() - { + public void update() { // check to see if there are any dying mini ghasts within our scan range - AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox((double)this.xCoord, (double)this.yCoord, (double)this.zCoord, (double)(this.xCoord + 1), (double)(this.yCoord + 1), (double)(this.zCoord + 1)).expand(10D, 16D, 10D); + AxisAlignedBB aabb = new AxisAlignedBB(pos).grow(10D, 16D, 10D); - List nearbyGhasts = worldObj.getEntitiesWithinAABB(EntityTFMiniGhast.class, aabb); + List nearbyGhasts = world.getEntitiesWithinAABB(EntityTFMiniGhast.class, aabb); - for (EntityTFMiniGhast ghast : nearbyGhasts) - { - if (ghast.deathTime > 0) - { + for (EntityTFMiniGhast ghast : nearbyGhasts) { + if (ghast.deathTime > 0) { this.makeParticlesTo(ghast); - if (!dyingGhasts.contains(ghast)) - { + if (!dyingGhasts.contains(ghast)) { dyingGhasts.add(ghast); } } @@ -58,60 +44,49 @@ public void updateEntity() counter++; - if (this.worldObj.isRemote) - { + if (this.world.isRemote) { // occasionally make a redstone line to a mini ghast - if (this.counter % 20 == 0 && nearbyGhasts.size() > 0) - { + if (this.counter % 20 == 0 && nearbyGhasts.size() > 0) { EntityTFMiniGhast highlight = nearbyGhasts.get(rand.nextInt(nearbyGhasts.size())); - this.makeParticlesTo(highlight); } - if (chargeLevel >= 1 && counter % 10 == 0) - { - ((BlockTFTowerDevice)TFBlocks.towerDevice).sparkle(worldObj, this.xCoord, this.yCoord, this.zCoord, worldObj.rand); - - worldObj.playSound(this.xCoord + 0.5D, this.yCoord + 1.5D, this.zCoord + 0.5D, "note.harp", 1.0F, 1.0F, false); + if (chargeLevel >= 1 && counter % 10 == 0) { + TFBlocks.tower_device.sparkle(world, this.pos); + world.playSound(this.pos.getX() + 0.5D, this.pos.getY() + 1.5D, this.pos.getZ() + 0.5D, SoundEvents.BLOCK_NOTE_HARP, SoundCategory.BLOCKS, 1.0F, 1.0F, false); } - if (chargeLevel >= 2) - { - worldObj.spawnParticle("smoke", this.xCoord + 0.1 + rand.nextFloat() * 0.8, this.yCoord + 1.05, this.zCoord + 0.1 + rand.nextFloat() * 0.8, (rand.nextFloat() - rand.nextFloat()) * 0.05, 0.00, (rand.nextFloat() - rand.nextFloat()) * 0.05); - if (counter % 10 == 0) - { - worldObj.playSound(this.xCoord + 0.5D, this.yCoord + 1.5D, this.zCoord + 0.5D, "note.harp", 1.2F, 0.8F, false); + if (chargeLevel >= 2) { + world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, pos.getX() + 0.1 + rand.nextFloat() * 0.8, pos.getY() + 1.05, pos.getZ() + 0.1 + rand.nextFloat() * 0.8, (rand.nextFloat() - rand.nextFloat()) * 0.05, 0.00, (rand.nextFloat() - rand.nextFloat()) * 0.05); + if (counter % 10 == 0) { + world.playSound(this.pos.getX() + 0.5D, this.pos.getY() + 1.5D, this.pos.getZ() + 0.5D, SoundEvents.BLOCK_NOTE_HARP, SoundCategory.BLOCKS, 1.2F, 0.8F, false); } } - if (chargeLevel >= 3) - { - worldObj.spawnParticle("largesmoke", this.xCoord + 0.1 + rand.nextFloat() * 0.8, this.yCoord + 1.05, this.zCoord + 0.1 + rand.nextFloat() * 0.8, (rand.nextFloat() - rand.nextFloat()) * 0.05, 0.05, (rand.nextFloat() - rand.nextFloat()) * 0.05); - ((BlockTFTowerDevice)TFBlocks.towerDevice).sparkle(worldObj, this.xCoord, this.yCoord, this.zCoord, worldObj.rand); - if (counter % 5 == 0) - { - worldObj.playSound(this.xCoord + 0.5D, this.yCoord + 1.5D, this.zCoord + 0.5D, "note.harp", 1.5F, 2F, false); + if (chargeLevel >= 3) { + world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.pos.getX() + 0.1 + rand.nextFloat() * 0.8, this.pos.getY() + 1.05, this.pos.getZ() + 0.1 + rand.nextFloat() * 0.8, (rand.nextFloat() - rand.nextFloat()) * 0.05, 0.05, (rand.nextFloat() - rand.nextFloat()) * 0.05); + TFBlocks.tower_device.sparkle(world, this.pos); + if (counter % 5 == 0) { + world.playSound(this.pos.getX() + 0.5D, this.pos.getY() + 1.5D, this.pos.getZ() + 0.5D, SoundEvents.BLOCK_NOTE_HARP, SoundCategory.BLOCKS, 1.5F, 2F, false); } } } } - + private void makeParticlesTo(Entity highlight) { - double sx = this.xCoord + 0.5D; - double sy = this.yCoord + 1.0D; - double sz = this.zCoord + 0.5D; - + + double sx = this.pos.getX() + 0.5D; + double sy = this.pos.getY() + 1.0D; + double sz = this.pos.getZ() + 0.5D; + double dx = sx - highlight.posX; double dy = sy - highlight.posY - highlight.getEyeHeight(); double dz = sz - highlight.posZ; - - for (int i = 0; i < 5; i++) - { - TwilightForestMod.proxy.spawnParticle(this.worldObj, "ghasttrap", sx, sy, sz, -dx, -dy, -dz); - } + for (int i = 0; i < 5; i++) { + TwilightForestMod.proxy.spawnParticle(TFParticleType.GHAST_TRAP, sx, sy, sz, -dx, -dy, -dz); + } } - public boolean isCharged() - { + public boolean isCharged() { return dyingGhasts.size() >= 3; } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFHydraSpawner.java b/src/main/java/twilightforest/tileentity/TileEntityTFHydraSpawner.java deleted file mode 100644 index e26fd45263..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFHydraSpawner.java +++ /dev/null @@ -1,26 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList; -import twilightforest.entity.TFCreatures; - - -public class TileEntityTFHydraSpawner extends TileEntityTFBossSpawner { - - public TileEntityTFHydraSpawner() { - this.mobID = TFCreatures.getSpawnerNameFor("Hydra"); - } - - /** - * Get a temporary copy of the creature we're going to summon for display purposes - */ - public Entity getDisplayEntity() - { - if (this.displayCreature == null) - { - this.displayCreature = EntityList.createEntityByName("HydraHead", worldObj); - } - - return this.displayCreature; - } -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFKnightPhantomsSpawner.java b/src/main/java/twilightforest/tileentity/TileEntityTFKnightPhantomsSpawner.java deleted file mode 100644 index 06bc55a66e..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFKnightPhantomsSpawner.java +++ /dev/null @@ -1,62 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.player.EntityPlayer; -import twilightforest.entity.TFCreatures; -import twilightforest.entity.boss.EntityTFKnightPhantom; - -public class TileEntityTFKnightPhantomsSpawner extends TileEntityTFBossSpawner { - - public TileEntityTFKnightPhantomsSpawner() { - this.mobID = TFCreatures.getSpawnerNameFor("Knight Phantom"); - } - - @Override - public boolean anyPlayerInRange() - { - EntityPlayer closestPlayer = worldObj.getClosestPlayer(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, 9D); - - return closestPlayer != null && closestPlayer.posY > yCoord - 2; - } - - /** - * Spawn the boss - */ - protected void spawnMyBoss() { - - for (int i = 0; i < 6; i++) - { - - // spawn creature - EntityLiving myCreature = makeMyCreature(); - - float angle = 60F * i; - float distance = 4F; - - double rx = xCoord + 0.5D + Math.cos((angle) * Math.PI / 180.0D) * distance; - double ry = yCoord + 0.5D; - double rz = zCoord + 0.5D + Math.sin((angle) * Math.PI / 180.0D) * distance; - - myCreature.setLocationAndAngles(rx, ry, rz, worldObj.rand.nextFloat() * 360F, 0.0F); - - // set creature's home to this - initializeCreature(myCreature); - - ((EntityTFKnightPhantom)myCreature).setNumber(i); - - // spawn it - worldObj.spawnEntityInWorld(myCreature); - } - } - - /** - * Any post-creation initialization goes here - */ - protected void initializeCreature(EntityLiving myCreature) { - if (myCreature instanceof EntityTFKnightPhantom) - { - ((EntityTFKnightPhantom) myCreature).setHomeArea(xCoord, yCoord, zCoord, 46); - } - } - -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFLichSpawner.java b/src/main/java/twilightforest/tileentity/TileEntityTFLichSpawner.java deleted file mode 100644 index bcd3d4160b..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFLichSpawner.java +++ /dev/null @@ -1,20 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.entity.player.EntityPlayer; -import twilightforest.entity.TFCreatures; - -public class TileEntityTFLichSpawner extends TileEntityTFBossSpawner { - - public TileEntityTFLichSpawner() { - this.mobID = TFCreatures.getSpawnerNameFor("Twilight Lich"); - } - - @Override - public boolean anyPlayerInRange() - { - EntityPlayer closestPlayer = worldObj.getClosestPlayer(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, 9D); - - return closestPlayer != null && closestPlayer.posY > yCoord - 4; - } - -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFMoonworm.java b/src/main/java/twilightforest/tileentity/TileEntityTFMoonworm.java deleted file mode 100644 index c1d175aaa5..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFMoonworm.java +++ /dev/null @@ -1,61 +0,0 @@ -package twilightforest.tileentity; - - - -public class TileEntityTFMoonworm extends TileEntityTFCritter { - - - public int yawDelay; - public int currentYaw; - public int desiredYaw; - - public TileEntityTFMoonworm() { - super(); - - currentYaw = -1; - yawDelay = 0; - desiredYaw = 0; - } - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - super.updateEntity(); - - if (currentYaw == -1) - { - currentYaw = worldObj.rand.nextInt(4) * 90; - } - - if(yawDelay > 0) - { - yawDelay--; - } - else - { - if (desiredYaw == 0) - { - // make it rotate! - yawDelay = 200 + worldObj.rand.nextInt(200); - desiredYaw = worldObj.rand.nextInt(4) * 90; - } - - currentYaw++; - - if (currentYaw > 360) - { - currentYaw = 0; - } - - if (currentYaw == desiredYaw) - { - desiredYaw = 0; - } - } - } - -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFNagaSpawner.java b/src/main/java/twilightforest/tileentity/TileEntityTFNagaSpawner.java deleted file mode 100644 index 1893becf46..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFNagaSpawner.java +++ /dev/null @@ -1,35 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.entity.EntityCreature; -import net.minecraft.entity.EntityLiving; -import twilightforest.entity.TFCreatures; - -public class TileEntityTFNagaSpawner extends TileEntityTFBossSpawner { - - public TileEntityTFNagaSpawner() { - this.mobID = TFCreatures.getSpawnerNameFor("Naga"); - } - - public boolean anyPlayerInRange() - { - return worldObj.getClosestPlayer(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, 50D) != null; - } - - /** - * Any post-creation initialization goes here - */ - protected void initializeCreature(EntityLiving myCreature) { - - if (myCreature instanceof EntityCreature) - { - ((EntityCreature) myCreature).setHomeArea(xCoord, yCoord, zCoord, 46); - } - } - - /** - * Range? - */ - protected int getRange() { - return 50; - } -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFPoppingJet.java b/src/main/java/twilightforest/tileentity/TileEntityTFPoppingJet.java index f623f717fd..2c8db577f6 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFPoppingJet.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFPoppingJet.java @@ -1,66 +1,57 @@ package twilightforest.tileentity; +import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ITickable; +import net.minecraft.util.SoundCategory; import twilightforest.block.BlockTFFireJet; import twilightforest.block.TFBlocks; +import twilightforest.enums.FireJetVariant; -public class TileEntityTFPoppingJet extends TileEntity { +public class TileEntityTFPoppingJet extends TileEntity implements ITickable { - int counter = 0; - int nextMeta; - - public TileEntityTFPoppingJet() { - this(BlockTFFireJet.META_JET_FLAME); - } + private int counter = 0; + private FireJetVariant nextVariant; - public TileEntityTFPoppingJet(int parNextMeta) { - this.nextMeta = parNextMeta; + public TileEntityTFPoppingJet(FireJetVariant variant) { + this.nextVariant = variant; } - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - if (++counter >= 80) - { + public TileEntityTFPoppingJet() {} + + @Override + public void update() { + if (++counter >= 80) { counter = 0; - // turn to flame - if (!worldObj.isRemote && worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord) == TFBlocks.fireJet) - { - worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, TFBlocks.fireJet, this.nextMeta, 3); + // turn to flame + if (!world.isRemote && world.getBlockState(pos).getBlock() == TFBlocks.fire_jet) { + world.setBlockState(pos, TFBlocks.fire_jet.getDefaultState().withProperty(BlockTFFireJet.VARIANT, nextVariant), 3); } - this.invalidate(); - } - else - { + } else { if (counter % 20 == 0) { - worldObj.spawnParticle("lava", this.xCoord + 0.5, this.yCoord + 1.5, this.zCoord + 0.5, 0.0D, 0.0D, 0.0D); - worldObj.playSoundEffect(this.xCoord, this.yCoord, this.zCoord, "liquid.lavapop", 0.2F + worldObj.rand.nextFloat() * 0.2F, 0.9F + worldObj.rand.nextFloat() * 0.15F); + for (int i = 0; i < 8; i++) + { + world.spawnParticle(EnumParticleTypes.LAVA, this.pos.getX() + 0.5, this.pos.getY() + 1.5, this.pos.getZ() + 0.5, 0.0D, 0.0D, 0.0D); + } + world.playSound(null, pos, SoundEvents.BLOCK_LAVA_POP, SoundCategory.BLOCKS, 0.2F + world.rand.nextFloat() * 0.2F, 0.9F + world.rand.nextFloat() * 0.15F); } } - } - - /** - * Reads a tile entity from NBT. - */ - public void readFromNBT(NBTTagCompound par1NBTTagCompound) - { - super.readFromNBT(par1NBTTagCompound); - this.nextMeta = par1NBTTagCompound.getInteger("NextMeta"); - } + } - /** - * Writes a tile entity to NBT. - */ - public void writeToNBT(NBTTagCompound par1NBTTagCompound) - { - super.writeToNBT(par1NBTTagCompound); - par1NBTTagCompound.setInteger("NextMeta", this.nextMeta); - } + @Override + public void readFromNBT(NBTTagCompound compound) { + super.readFromNBT(compound); + this.nextVariant = FireJetVariant.values()[compound.getInteger("NextMeta")]; + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + NBTTagCompound ret = super.writeToNBT(compound); + ret.setInteger("NextMeta", nextVariant.ordinal()); + return ret; + } } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFReverter.java b/src/main/java/twilightforest/tileentity/TileEntityTFReverter.java deleted file mode 100644 index 72d36e08f8..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFReverter.java +++ /dev/null @@ -1,380 +0,0 @@ -package twilightforest.tileentity; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntity; -import twilightforest.block.BlockTFTowerTranslucent; -import twilightforest.block.TFBlocks; - -public class TileEntityTFReverter extends TileEntity -{ - private static final int REVERT_CHANCE = 10; - - public int radius = 4; - public int diameter = 2 * radius + 1; - public double requiredPlayerRange = 16; - public Random rand = new Random(); - private int tickCount; - - private boolean slowScan; - private int ticksSinceChange; - - private Block[] blockData; - private byte[] metaData; - - /** - * Determines if this TileEntity requires update calls. - * @return True if you want updateEntity() to be called, false if not - */ - @Override - public boolean canUpdate() { - return true; - } - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - if (this.anyPlayerInRange()) - { - this.tickCount++; - - if (this.worldObj.isRemote) - { - double var1 = (double)((float)this.xCoord + this.worldObj.rand.nextFloat()); - double var3 = (double)((float)this.yCoord + this.worldObj.rand.nextFloat()); - double var5 = (double)((float)this.zCoord + this.worldObj.rand.nextFloat()); -// this.worldObj.spawnParticle("smoke", var1, var3, var5, 0.0D, 0.0D, 0.0D); - this.worldObj.spawnParticle("reddust", var1, var3, var5, 0.0D, 0.0D, 0.0D); - - - // occasionally make a little red dust line to outline our radius - if (this.rand.nextInt(10) == 0) - { - makeRandomOutline(); - makeRandomOutline(); - makeRandomOutline(); - } - } - else - { - - // new plan, take a snapshot of the world when we are first activated, and then rapidly revert changes - if (blockData == null || metaData == null) - { - captureBlockData(); - this.slowScan = true; - } - - if (!this.slowScan || this.tickCount % 20 == 0) - { - if (scanAndRevertChanges()) - { - this.slowScan = false; - this.ticksSinceChange = 0; - } - else - { - ticksSinceChange++; - - if (ticksSinceChange > 20) - { - this.slowScan = true; - } - } - } - } - } - else - { - // remove data - this.blockData = null; - this.metaData = null; - - this.tickCount = 0; - } - } - - - /** - * Display a random one of the 12 possible outlines - */ - private void makeRandomOutline() - { - makeOutline(this.rand.nextInt(12)); - } - - /** - * Display a specific outline - */ - private void makeOutline(int outline) - { - // src - double sx = this.xCoord; - double sy = this.yCoord; - double sz = this.zCoord; - // dest - double dx = this.xCoord; - double dy = this.yCoord; - double dz = this.zCoord; - - switch (outline) - { - case 0: - case 8: - sx -= radius; - dx += radius + 1; - sz -= radius; - dz -= radius; - break; - case 1: - case 9: - sx -= radius; - dx -= radius; - sz -= radius; - dz += radius + 1; - break; - case 2: - case 10: - sx -= radius; - dx += radius + 1; - sz += radius + 1; - dz += radius + 1; - break; - case 3: - case 11: - sx += radius + 1; - dx += radius + 1; - sz -= radius; - dz += radius + 1; - break; - case 4: - sx -= radius; - dx -= radius; - sz -= radius; - dz -= radius; - break; - case 5: - sx += radius + 1; - dx += radius + 1; - sz -= radius; - dz -= radius; - break; - case 6: - sx += radius + 1; - dx += radius + 1; - sz += radius + 1; - dz += radius + 1; - break; - case 7: - sx -= radius; - dx -= radius; - sz += radius + 1; - dz += radius + 1; - break; - } - - switch (outline) - { - case 0: - case 1: - case 2: - case 3: - sy += radius + 1; - dy += radius + 1; - break; - case 4: - case 5: - case 6: - case 7: - sy -= radius; - dy += radius + 1; - break; - case 8: - case 9: - case 10: - case 11: - sy -= radius; - dy -= radius; - break; - } - - if(rand.nextBoolean()) - { - drawParticleLine(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, dx, dy, dz); - } - else - { - drawParticleLine(sx, sy, sz, this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5); - } - drawParticleLine(sx, sy, sz, dx, dy, dz); - } - - /** - * Make a trail of particles from one point to another - */ - protected void drawParticleLine(double srcX, double srcY, double srcZ, double destX, double destY, double destZ) { - // make particle trail - int particles = 16; - for (int i = 0; i < particles; i++) - { - double trailFactor = i / (particles - 1.0D); - - double tx = srcX + (destX - srcX) * trailFactor + rand.nextFloat() * 0.005; - double ty = srcY + (destY - srcY) * trailFactor + rand.nextFloat() * 0.005; - double tz = srcZ + (destZ - srcZ) * trailFactor + rand.nextFloat() * 0.005; - worldObj.spawnParticle("reddust", tx, ty, tz, 0, 0, 0); - } - } - - private boolean scanAndRevertChanges() { - int index = 0; - boolean reverted = false; - - for (int x = - radius; x <= radius; x++) - { - for (int y = - radius; y <= radius; y++) - { - for (int z = - radius; z <= radius; z++) - { - Block blockID = worldObj.getBlock(this.xCoord + x, this.yCoord + y, this.zCoord + z); - byte meta = (byte) worldObj.getBlockMetadata(this.xCoord + x, this.yCoord + y, this.zCoord + z); - - if (blockData[index] != blockID) - { - if (revertBlock(this.xCoord + x, this.yCoord + y, this.zCoord + z, blockID, meta, blockData[index], metaData[index])) - { - reverted = true; - } - else - { - blockData[index] = blockID; - metaData[index] = meta; - } - } - - index++; - } - } - } - - return reverted; - } - - private boolean revertBlock(int x, int y, int z, Block thereBlockID, byte thereMeta, Block replaceBlockID, byte replaceMeta) - { - if (thereBlockID == Blocks.air && !replaceBlockID.getMaterial().blocksMovement()) - { - // do not revert - - System.out.println("Not replacing block " + replaceBlockID + " because it doesn't block movement"); - - return false; - } - if (isUnrevertable(thereBlockID, thereMeta, replaceBlockID, replaceMeta)) - { - // do not revert - return false; - } - else if (this.rand.nextInt(REVERT_CHANCE) == 0) - { - // don't revert everything instantly - if (replaceBlockID != Blocks.air) - { - replaceBlockID = TFBlocks.towerTranslucent; - replaceMeta = BlockTFTowerTranslucent.META_REVERTER_REPLACEMENT; - } - - worldObj.setBlock(x, y, z, replaceBlockID, replaceMeta, 2); - - // play a little animation - if (thereBlockID == Blocks.air) - { - worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(replaceBlockID) + (replaceMeta << 12)); - } - else if (replaceBlockID == Blocks.air) - { - worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(thereBlockID) + (thereMeta << 12)); - thereBlockID.dropBlockAsItem(worldObj, x, y, z, thereMeta, 0); - - } - } - - return true; - } - - private boolean isUnrevertable(Block thereBlockID, byte thereMeta, Block replaceBlockID, byte replaceMeta) - { - if (thereBlockID == TFBlocks.towerDevice || replaceBlockID == TFBlocks.towerDevice) - { - return true; - } - if ((thereBlockID == TFBlocks.towerTranslucent && thereMeta != BlockTFTowerTranslucent.META_REVERTER_REPLACEMENT) - || (replaceBlockID == TFBlocks.towerTranslucent && replaceMeta != BlockTFTowerTranslucent.META_REVERTER_REPLACEMENT)) - { - return true; - } - if (thereBlockID == Blocks.redstone_lamp && replaceBlockID == Blocks.lit_redstone_lamp) - { - return true; - } - if (thereBlockID == Blocks.lit_redstone_lamp && replaceBlockID == Blocks.redstone_lamp) - { - return true; - } - if (thereBlockID == Blocks.water || replaceBlockID == Blocks.flowing_water) - { - return true; - } - if (thereBlockID == Blocks.flowing_water || replaceBlockID == Blocks.water) - { - return true; - } - if (replaceBlockID == Blocks.tnt) - { - return true; - } - - return false; - } - - private void captureBlockData() - { - blockData = new Block[diameter * diameter * diameter]; - metaData = new byte[diameter * diameter * diameter]; - - int index = 0; - - for (int x = - radius; x <= radius; x++) - { - for (int y = - radius; y <= radius; y++) - { - for (int z = - radius; z <= radius; z++) - { - Block blockID = worldObj.getBlock(this.xCoord + x, this.yCoord + y, this.zCoord + z); - int meta = worldObj.getBlockMetadata(this.xCoord + x, this.yCoord + y, this.zCoord + z); - - blockData[index] = blockID; - metaData[index] = (byte) meta; - - index++; - } - } - } - - //System.out.println("Captured data for " + index + " blocks"); - } - - /** - * Returns true if there is a player in range (using World.getClosestPlayer) - */ - public boolean anyPlayerInRange() - { - return this.worldObj.getClosestPlayer((double)this.xCoord + 0.5D, (double)this.yCoord + 0.5D, (double)this.zCoord + 0.5D, (double)this.requiredPlayerRange ) != null; - } -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFSmoker.java b/src/main/java/twilightforest/tileentity/TileEntityTFSmoker.java index f06ecb5421..a53a83f1f9 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFSmoker.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFSmoker.java @@ -1,22 +1,20 @@ package twilightforest.tileentity; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ITickable; import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; -public class TileEntityTFSmoker extends TileEntity { - - public long counter = 0; +public class TileEntityTFSmoker extends TileEntity implements ITickable { - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ - @Override - public void updateEntity() - { - if (++counter % 4 == 0) { - TwilightForestMod.proxy.spawnParticle(this.worldObj, "hugesmoke", this.xCoord + 0.5, this.yCoord + 0.95, this.zCoord + 0.5, - Math.cos(counter / 10.0) * 0.05, 0.25D, Math.sin(counter / 10.0) * 0.05); - } - } + private long counter = 0; + + @Override + public void update() { + if (world.isRemote && ++counter % 4 == 0) { + TwilightForestMod.proxy.spawnParticle(TFParticleType.HUGE_SMOKE, pos.getX() + 0.5, pos.getY() + 0.95, pos.getZ() + 0.5, + Math.cos(counter / 10.0) * 0.05, 0.25D, Math.sin(counter / 10.0) * 0.05 + ); + } + } } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFSnowQueenSpawner.java b/src/main/java/twilightforest/tileentity/TileEntityTFSnowQueenSpawner.java deleted file mode 100644 index d05fe04505..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFSnowQueenSpawner.java +++ /dev/null @@ -1,37 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.player.EntityPlayer; -import twilightforest.entity.TFCreatures; - -public class TileEntityTFSnowQueenSpawner extends TileEntityTFBossSpawner { - - public TileEntityTFSnowQueenSpawner() { - this.mobID = TFCreatures.getSpawnerNameFor("Snow Queen"); - } - - @Override - public boolean anyPlayerInRange() - { - EntityPlayer closestPlayer = worldObj.getClosestPlayer(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, 9D); - - return closestPlayer != null && closestPlayer.posY > yCoord - 4; - } - - protected void spawnMyBoss() { - // spawn creature - EntityLiving myCreature = makeMyCreature(); - - double rx = xCoord + 0.5D; - double ry = yCoord + 0.5D; - double rz = zCoord + 0.5D; - myCreature.setLocationAndAngles(rx, ry, rz, worldObj.rand.nextFloat() * 360F, 0.0F); - - // set creature's home to this - initializeCreature(myCreature); - - // spawn it - worldObj.spawnEntityInWorld(myCreature); - } - -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFTowerBossSpawner.java b/src/main/java/twilightforest/tileentity/TileEntityTFTowerBossSpawner.java deleted file mode 100644 index 79aad70480..0000000000 --- a/src/main/java/twilightforest/tileentity/TileEntityTFTowerBossSpawner.java +++ /dev/null @@ -1,37 +0,0 @@ -package twilightforest.tileentity; - -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.player.EntityPlayer; -import twilightforest.entity.TFCreatures; - -public class TileEntityTFTowerBossSpawner extends TileEntityTFBossSpawner { - - public TileEntityTFTowerBossSpawner() { - this.mobID = TFCreatures.getSpawnerNameFor("Tower Boss"); - } - - @Override - public boolean anyPlayerInRange() - { - EntityPlayer closestPlayer = worldObj.getClosestPlayer(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D, 9D); - - return closestPlayer != null && closestPlayer.posY > yCoord - 4; - } - - protected void spawnMyBoss() { - // spawn creature - EntityLiving myCreature = makeMyCreature(); - - double rx = xCoord + 0.5D; - double ry = yCoord + 0.5D; - double rz = zCoord + 0.5D; - myCreature.setLocationAndAngles(rx, ry, rz, worldObj.rand.nextFloat() * 360F, 0.0F); - - // set creature's home to this - initializeCreature(myCreature); - - // spawn it - worldObj.spawnEntityInWorld(myCreature); - } - -} diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFTowerBuilder.java b/src/main/java/twilightforest/tileentity/TileEntityTFTowerBuilder.java index 51e99362ff..71a22bc3b6 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFTowerBuilder.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFTowerBuilder.java @@ -1,39 +1,35 @@ package twilightforest.tileentity; -import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.Facing; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ITickable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import twilightforest.block.BlockTFTowerDevice; import twilightforest.block.BlockTFTowerTranslucent; import twilightforest.block.TFBlocks; +import twilightforest.enums.TowerDeviceVariant; +import twilightforest.enums.TowerTranslucentVariant; -public class TileEntityTFTowerBuilder extends TileEntity -{ +public class TileEntityTFTowerBuilder extends TileEntity implements ITickable { private static final int RANGE = 16; - int ticksRunning = 0; - int blockedCounter = 0; - int ticksStopped = 0; - + private int ticksRunning = 0; + private int blockedCounter = 0; + private int ticksStopped = 0; + public boolean makingBlocks = false; - - int blocksMade = 0; - - protected ChunkCoordinates lastBlockCoords; - protected int nextFacing; - - protected EntityPlayer trackedPlayer; - - protected Block blockBuiltID = TFBlocks.towerTranslucent; - protected int blockBuiltMeta = BlockTFTowerTranslucent.META_BUILT_INACTIVE; - - public TileEntityTFTowerBuilder() - { - //System.out.println("I made a builder!"); - } + + private int blocksMade = 0; + + private BlockPos lastBlockCoords; + private EnumFacing nextFacing; + + private EntityPlayer trackedPlayer; + + private IBlockState blockBuiltState = TFBlocks.tower_translucent.getDefaultState().withProperty(BlockTFTowerTranslucent.VARIANT, TowerTranslucentVariant.BUILT_INACTIVE); /** * Start building stuffs @@ -41,141 +37,80 @@ public TileEntityTFTowerBuilder() public void startBuilding() { this.makingBlocks = true; this.blocksMade = 0; - this.lastBlockCoords = new ChunkCoordinates(this.xCoord, this.yCoord, this.zCoord); - } - - /** - * Determines if this TileEntity requires update calls. - * @return True if you want updateEntity() to be called, false if not - */ - @Override - public boolean canUpdate() { - return true; + this.lastBlockCoords = getPos(); } - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ @Override - public void updateEntity() - { - if (!worldObj.isRemote && this.makingBlocks) - { + public void update() { + if (!world.isRemote && this.makingBlocks) { // if we are not tracking the nearest player, start tracking them - if (trackedPlayer == null) - { + if (trackedPlayer == null) { this.trackedPlayer = findClosestValidPlayer(); } - + // find player facing this.nextFacing = findNextFacing(); - + ++this.ticksRunning; - + // if we are at the half second marker, make a block and advance the block cursor - if (this.ticksRunning % 10 == 0 && lastBlockCoords != null && nextFacing != -1) - { - int nextX = lastBlockCoords.posX + Facing.offsetsXForSide[nextFacing]; - int nextY = lastBlockCoords.posY + Facing.offsetsYForSide[nextFacing]; - int nextZ = lastBlockCoords.posZ + Facing.offsetsZForSide[nextFacing]; - + if (this.ticksRunning % 10 == 0 && lastBlockCoords != null && nextFacing != null) { + BlockPos nextPos = lastBlockCoords.offset(nextFacing); + // make a block - if (blocksMade <= RANGE && worldObj.isAirBlock(nextX, nextY, nextZ)) - { - worldObj.setBlock(nextX, nextY, nextZ,blockBuiltID, blockBuiltMeta, 3); - - worldObj.playAuxSFX(1001, nextX, nextY, nextZ, 0); - - this.lastBlockCoords.posX = nextX; - this.lastBlockCoords.posY = nextY; - this.lastBlockCoords.posZ = nextZ; - + if (blocksMade <= RANGE && world.isAirBlock(nextPos)) { + world.setBlockState(nextPos, blockBuiltState, 3); + + world.playEvent(1001, nextPos, 0); + + this.lastBlockCoords = nextPos; + blockedCounter = 0; blocksMade++; - } - else - { + } else { blockedCounter++; } } - + // if we're blocked for more than a second, shut down block making - if (blockedCounter > 0) - { + if (blockedCounter > 0) { this.makingBlocks = false; this.trackedPlayer = null; ticksStopped = 0; } - } - else if (!worldObj.isRemote && !this.makingBlocks) - { + } else if (!world.isRemote && !this.makingBlocks) { this.trackedPlayer = null; - if (++ticksStopped == 60) - { + if (++ticksStopped == 60) { // force the builder back into an inactive state - worldObj.setBlock(this.xCoord, this.yCoord, this.zCoord, TFBlocks.towerDevice, BlockTFTowerDevice.META_BUILDER_TIMEOUT, 3); - worldObj.scheduleBlockUpdate(this.xCoord, this.yCoord, this.zCoord, TFBlocks.towerDevice, 4); + world.setBlockState(getPos(), TFBlocks.tower_device.getDefaultState().withProperty(BlockTFTowerDevice.VARIANT, TowerDeviceVariant.BUILDER_TIMEOUT), 3); + world.scheduleUpdate(getPos(), TFBlocks.tower_device, 4); } } } - /** - * Are the specified destination coordinates within our build range? - */ - private boolean isInBounds(int nextX, int nextY, int nextZ) - { - return nextX > this.xCoord - RANGE && nextX < this.xCoord + RANGE - && nextY > this.yCoord - RANGE && nextY < this.yCoord + RANGE - && nextZ > this.zCoord - RANGE && nextZ < this.zCoord + RANGE; - } - - /** - * Which direction is the player facing, in terms of directions in java.util.Facing - */ - private int findNextFacing() - { - if (this.trackedPlayer != null) - { + private EnumFacing findNextFacing() { + if (this.trackedPlayer != null) { // check up and down - int pitch = MathHelper.floor_double((double)(trackedPlayer.rotationPitch * 4.0F / 360.0F) + 1.5D) & 3; - - if (pitch == 0) - { - return 1; - } - else if (pitch == 2) - { - return 0; - } - else - { - int direction = MathHelper.floor_double((double)(trackedPlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; - - switch (direction) - { - case 0: // south - return 3; - case 1: // west - return 4; - case 2: // north - return 2; - case 3: // east - return 5; - } + int pitch = MathHelper.floor((double) (trackedPlayer.rotationPitch * 4.0F / 360.0F) + 1.5D) & 3; + + if (pitch == 0) { + return EnumFacing.UP; // todo 1.9 recheck this and down + } else if (pitch == 2) { + return EnumFacing.DOWN; + } else { + return trackedPlayer.getHorizontalFacing(); } } - return -1; + return null; } /** * Who is the closest player? Used to find which player we should track when building */ - private EntityPlayer findClosestValidPlayer() - { - return worldObj.getClosestPlayer(this.xCoord + 0.5, this.yCoord + 0.5, this.zCoord + 0.5, 16); + private EntityPlayer findClosestValidPlayer() { + return world.getClosestPlayer(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 16, false); } - - + + } diff --git a/src/main/java/twilightforest/tileentity/TileEntityTFTrophy.java b/src/main/java/twilightforest/tileentity/TileEntityTFTrophy.java index 7f8aee7ef9..6d6541a39b 100644 --- a/src/main/java/twilightforest/tileentity/TileEntityTFTrophy.java +++ b/src/main/java/twilightforest/tileentity/TileEntityTFTrophy.java @@ -1,21 +1,22 @@ package twilightforest.tileentity; +import net.minecraft.block.state.IBlockState; import net.minecraft.tileentity.TileEntitySkull; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class TileEntityTFTrophy extends TileEntitySkull { -public class TileEntityTFTrophy extends TileEntitySkull -{ - public int ticksExisted; - - /** - * Allows the entity to update its state. Overridden in most subclasses, e.g. the mob spawner uses this to count - * ticks and creates a new spawn inside its implementation. - */ + @Override - public void updateEntity() - { - super.updateEntity(); + public void update() { + super.update(); this.ticksExisted++; } + @Override + public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { + return oldState.getBlock() != newState.getBlock(); + } } diff --git a/src/main/java/twilightforest/tileentity/critters/TileEntityTFCicada.java b/src/main/java/twilightforest/tileentity/critters/TileEntityTFCicada.java new file mode 100644 index 0000000000..24a45a6f2d --- /dev/null +++ b/src/main/java/twilightforest/tileentity/critters/TileEntityTFCicada.java @@ -0,0 +1,6 @@ +package twilightforest.tileentity.critters; + +import net.minecraft.tileentity.TileEntity; + +public class TileEntityTFCicada extends TileEntity { +} diff --git a/src/main/java/twilightforest/tileentity/critters/TileEntityTFCicadaTicking.java b/src/main/java/twilightforest/tileentity/critters/TileEntityTFCicadaTicking.java new file mode 100644 index 0000000000..fdac172024 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/critters/TileEntityTFCicadaTicking.java @@ -0,0 +1,78 @@ +package twilightforest.tileentity.critters; + +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ITickable; +import net.minecraft.util.SoundCategory; +import twilightforest.TFConfig; +import twilightforest.TFSounds; + + +public class TileEntityTFCicadaTicking extends TileEntityTFCicada implements ITickable { + private int yawDelay; + public int currentYaw; + private int desiredYaw; + + private int singDuration; + private boolean singing; + private int singDelay; + + @Override + public void update() { + if (world.isRemote) { + if (yawDelay > 0) { + yawDelay--; + } else { + if (currentYaw == 0 && desiredYaw == 0) { + // make it rotate! + yawDelay = 200 + world.rand.nextInt(200); + desiredYaw = world.rand.nextInt(15) - world.rand.nextInt(15); + } + + if (currentYaw < desiredYaw) { + currentYaw++; + } + if (currentYaw > desiredYaw) { + currentYaw--; + } + if (currentYaw == desiredYaw) { + desiredYaw = 0; + } + } + + if (singDelay > 0) { + singDelay--; + } else { + if (singing && singDuration == 0) { + playSong(); + } + if (singing && singDuration >= 100) { + singing = false; + singDuration = 0; + } + if (singing && singDuration < 100) { + singDuration++; + doSingAnimation(); + } + if (!singing && singDuration <= 0) { + singing = true; + singDelay = 100 + world.rand.nextInt(100); + } + } + } + } + + private void doSingAnimation() { + if (world.rand.nextInt(5) == 0) { + double rx = pos.getX() + world.rand.nextFloat(); + double ry = pos.getY() + world.rand.nextFloat(); + double rz = pos.getZ() + world.rand.nextFloat(); + world.spawnParticle(EnumParticleTypes.NOTE, rx, ry, rz, 0.0D, 0.0D, 0.0D); + } + } + + private void playSong() { + if (!TFConfig.silentCicadas) { + world.playSound(pos.getX(), pos.getY(), pos.getZ(), TFSounds.CICADA, SoundCategory.NEUTRAL, 1.0f, (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F + 1.0F, false); + } + } +} diff --git a/src/main/java/twilightforest/tileentity/critters/TileEntityTFFirefly.java b/src/main/java/twilightforest/tileentity/critters/TileEntityTFFirefly.java new file mode 100644 index 0000000000..15ea1ea818 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/critters/TileEntityTFFirefly.java @@ -0,0 +1,6 @@ +package twilightforest.tileentity.critters; + +import net.minecraft.tileentity.TileEntity; + +public class TileEntityTFFirefly extends TileEntity { +} diff --git a/src/main/java/twilightforest/tileentity/critters/TileEntityTFFireflyTicking.java b/src/main/java/twilightforest/tileentity/critters/TileEntityTFFireflyTicking.java new file mode 100644 index 0000000000..69fcf46dad --- /dev/null +++ b/src/main/java/twilightforest/tileentity/critters/TileEntityTFFireflyTicking.java @@ -0,0 +1,76 @@ +package twilightforest.tileentity.critters; + +import net.minecraft.util.ITickable; +import twilightforest.TwilightForestMod; +import twilightforest.client.particle.TFParticleType; + +public class TileEntityTFFireflyTicking extends TileEntityTFFirefly implements ITickable { + + private int yawDelay; + public int currentYaw; + private int desiredYaw; + + public float glowIntensity; + private boolean glowing; + private int glowDelay; + + @Override + public void update() { + if (world.isRemote) { + if (anyPlayerInRange() && world.rand.nextInt(20) == 0) { + spawnParticles(); + } + + if (yawDelay > 0) { + yawDelay--; + } else { + if (currentYaw == 0 && desiredYaw == 0) { + // make it rotate! + yawDelay = 200 + world.rand.nextInt(200); + desiredYaw = world.rand.nextInt(15) - world.rand.nextInt(15); + } + + if (currentYaw < desiredYaw) { + currentYaw++; + } + if (currentYaw > desiredYaw) { + currentYaw--; + } + if (currentYaw == desiredYaw) { + desiredYaw = 0; + } + } + + if (glowDelay > 0) { + glowDelay--; + } else { + if (glowing && glowIntensity >= 1.0) { + glowing = false; + } + if (glowing && glowIntensity < 1.0) { + glowIntensity += 0.05; + } + if (!glowing && glowIntensity > 0) { + glowIntensity -= 0.05; + } + if (!glowing && glowIntensity <= 0) { + glowing = true; + glowDelay = world.rand.nextInt(50); + } + } + } + } + + private boolean anyPlayerInRange() { + return world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, 16D, false) != null; + } + + private void spawnParticles() { + double rx = pos.getX() + world.rand.nextFloat(); + double ry = pos.getY() + world.rand.nextFloat(); + double rz = pos.getZ() + world.rand.nextFloat(); +// ModLoader.getMinecraftInstance().effectRenderer.addEffect(fireflyfx); + // ^ keeping here only for pure lolz + TwilightForestMod.proxy.spawnParticle(TFParticleType.FIREFLY, rx, ry, rz, 0, 0, 0); + } +} diff --git a/src/main/java/twilightforest/tileentity/critters/TileEntityTFMoonworm.java b/src/main/java/twilightforest/tileentity/critters/TileEntityTFMoonworm.java new file mode 100644 index 0000000000..98e9479a98 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/critters/TileEntityTFMoonworm.java @@ -0,0 +1,9 @@ +package twilightforest.tileentity.critters; + +import net.minecraft.tileentity.TileEntity; + +/** + * Created by Drullkus on 1/19/18. + */ +public class TileEntityTFMoonworm extends TileEntity { +} diff --git a/src/main/java/twilightforest/tileentity/critters/TileEntityTFMoonwormTicking.java b/src/main/java/twilightforest/tileentity/critters/TileEntityTFMoonwormTicking.java new file mode 100644 index 0000000000..9fcca57839 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/critters/TileEntityTFMoonwormTicking.java @@ -0,0 +1,46 @@ +package twilightforest.tileentity.critters; + + +import net.minecraft.util.ITickable; + +public class TileEntityTFMoonwormTicking extends TileEntityTFMoonworm implements ITickable { + public int yawDelay; + public int currentYaw; + public int desiredYaw; + + public TileEntityTFMoonwormTicking() { + currentYaw = -1; + yawDelay = 0; + desiredYaw = 0; + } + + @Override + public void update() { + if (world.isRemote) { + if (currentYaw == -1) { + currentYaw = world.rand.nextInt(4) * 90; + } + + if (yawDelay > 0) { + yawDelay--; + } else { + if (desiredYaw == 0) { + // make it rotate! + yawDelay = 200 + world.rand.nextInt(200); + desiredYaw = world.rand.nextInt(4) * 90; + } + + currentYaw++; + + if (currentYaw > 360) { + currentYaw = 0; + } + + if (currentYaw == desiredYaw) { + desiredYaw = 0; + } + } + } + } + +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFAlphaYetiSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFAlphaYetiSpawner.java new file mode 100644 index 0000000000..ec8cf625ff --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFAlphaYetiSpawner.java @@ -0,0 +1,18 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; +import twilightforest.entity.boss.EntityTFYetiAlpha; + +public class TileEntityTFAlphaYetiSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFAlphaYetiSpawner() { + super(EntityList.getKey(EntityTFYetiAlpha.class)); + } + + @Override + public boolean anyPlayerInRange() { + EntityPlayer closestPlayer = world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, getRange(), false); + return closestPlayer != null && closestPlayer.posY > pos.getY() - 4; + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFBossSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFBossSpawner.java new file mode 100644 index 0000000000..45686a0118 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFBossSpawner.java @@ -0,0 +1,94 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ITickable; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.EnumDifficulty; + +public abstract class TileEntityTFBossSpawner extends TileEntity implements ITickable { + + protected static final int SHORT_RANGE = 9, LONG_RANGE = 50; + + protected final ResourceLocation mobID; + protected Entity displayCreature = null; + protected boolean spawnedBoss = false; + + protected TileEntityTFBossSpawner(ResourceLocation mobID) { + this.mobID = mobID; + } + + public boolean anyPlayerInRange() { + return world.isAnyPlayerWithinRangeAt(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, getRange()); + } + + @Override + public void update() { + if (spawnedBoss || !anyPlayerInRange()) { + return; + } + if (world.isRemote) { + // particles + double rx = pos.getX() + world.rand.nextFloat(); + double ry = pos.getY() + world.rand.nextFloat(); + double rz = pos.getZ() + world.rand.nextFloat(); + world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, rx, ry, rz, 0.0D, 0.0D, 0.0D); + world.spawnParticle(EnumParticleTypes.FLAME, rx, ry, rz, 0.0D, 0.0D, 0.0D); + } else { + if (world.getDifficulty() != EnumDifficulty.PEACEFUL) { + if (spawnMyBoss()) { + world.destroyBlock(pos, false); + spawnedBoss = true; + } + } + } + } + + /** + * Spawn the boss + */ + protected boolean spawnMyBoss() { + // create creature + EntityLiving myCreature = makeMyCreature(); + + myCreature.moveToBlockPosAndAngles(pos, world.rand.nextFloat() * 360F, 0.0F); + myCreature.onInitialSpawn(world.getDifficultyForLocation(pos), null); + + // set creature's home to this + initializeCreature(myCreature); + + // spawn it + return world.spawnEntity(myCreature); + } + + /** + * Get a temporary copy of the creature we're going to summon for display purposes + */ + public Entity getDisplayEntity() { + if (this.displayCreature == null) { + this.displayCreature = makeMyCreature(); + } + return this.displayCreature; + } + + /** + * Any post-creation initialization goes here + */ + protected void initializeCreature(EntityLiving myCreature) { + if (myCreature instanceof EntityCreature) { + ((EntityCreature) myCreature).setHomePosAndDistance(pos, 46); + } + } + + protected int getRange() { + return SHORT_RANGE; + } + + protected EntityLiving makeMyCreature() { + return (EntityLiving) EntityList.createEntityByIDFromName(mobID, world); + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFFinalBossSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFFinalBossSpawner.java new file mode 100644 index 0000000000..8976aa724c --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFFinalBossSpawner.java @@ -0,0 +1,23 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.player.EntityPlayer; +import twilightforest.entity.EntityTFKobold; +import twilightforest.entity.boss.EntityTFYetiAlpha; + +public class TileEntityTFFinalBossSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFFinalBossSpawner() { + super(EntityList.getKey(EntityTFKobold.class)); + } + + @Override + protected void initializeCreature(EntityLiving myCreature) { + super.initializeCreature(myCreature); + myCreature.setCustomNameTag("Final Boss"); + myCreature.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(1024); + myCreature.setHealth(myCreature.getMaxHealth()); + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFHydraSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFHydraSpawner.java new file mode 100644 index 0000000000..ba2f3f9901 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFHydraSpawner.java @@ -0,0 +1,26 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import twilightforest.entity.boss.EntityTFHydra; +import twilightforest.entity.boss.EntityTFHydraHead; + +public class TileEntityTFHydraSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFHydraSpawner() { + super(EntityList.getKey(EntityTFHydra.class)); + } + + @Override + protected int getRange() { + return LONG_RANGE; + } + + @Override + public Entity getDisplayEntity() { + if (this.displayCreature == null) { + this.displayCreature = EntityList.createEntityByIDFromName(EntityList.getKey(EntityTFHydraHead.class), world); + } + return this.displayCreature; + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFKnightPhantomsSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFKnightPhantomsSpawner.java new file mode 100644 index 0000000000..77518189b0 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFKnightPhantomsSpawner.java @@ -0,0 +1,68 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.EnumDifficulty; +import twilightforest.entity.boss.EntityTFKnightPhantom; +import twilightforest.item.TFItems; + +public class TileEntityTFKnightPhantomsSpawner extends TileEntityTFBossSpawner { + + private static final int COUNT = 6; + + private int spawned = 0; + + public TileEntityTFKnightPhantomsSpawner() { + super(EntityList.getKey(EntityTFKnightPhantom.class)); + } + + @Override + public boolean anyPlayerInRange() { + EntityPlayer closestPlayer = world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, getRange(), false); + return closestPlayer != null && closestPlayer.posY > pos.getY() - 2; + } + + @Override + protected boolean spawnMyBoss() { + for (int i = spawned; i < COUNT; i++) { + // create creature + EntityLiving myCreature = makeMyCreature(); + + float angle = (360F / COUNT) * i; + final float distance = 4F; + + double rx = pos.getX() + 0.5D + Math.cos(angle * Math.PI / 180.0D) * distance; + double ry = pos.getY(); + double rz = pos.getZ() + 0.5D + Math.sin(angle * Math.PI / 180.0D) * distance; + + myCreature.setLocationAndAngles(rx, ry, rz, world.rand.nextFloat() * 360F, 0.0F); + myCreature.onInitialSpawn(world.getDifficultyForLocation(new BlockPos(myCreature)), null); + + if(i == 5 && world.getDifficulty() == EnumDifficulty.HARD){ + myCreature.setItemStackToSlot(EntityEquipmentSlot.OFFHAND,new ItemStack(TFItems.knightmetal_shield)); + } + + // set creature's home to this + initializeCreature(myCreature); + + ((EntityTFKnightPhantom) myCreature).setNumber(i); + + // spawn it + if (world.spawnEntity(myCreature)) { + spawned++; + } + } + return spawned == COUNT; + } + + @Override + protected void initializeCreature(EntityLiving myCreature) { + if (myCreature instanceof EntityTFKnightPhantom) { + ((EntityTFKnightPhantom) myCreature).setHomePosAndDistance(pos, 46); + } + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFLichSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFLichSpawner.java new file mode 100644 index 0000000000..014f41b3cd --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFLichSpawner.java @@ -0,0 +1,18 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; +import twilightforest.entity.boss.EntityTFLich; + +public class TileEntityTFLichSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFLichSpawner() { + super(EntityList.getKey(EntityTFLich.class)); + } + + @Override + public boolean anyPlayerInRange() { + EntityPlayer closestPlayer = world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, getRange(), false); + return closestPlayer != null && closestPlayer.posY > pos.getY() - 4; + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFMinoshroomSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFMinoshroomSpawner.java new file mode 100644 index 0000000000..2d4129c5d1 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFMinoshroomSpawner.java @@ -0,0 +1,18 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; +import twilightforest.entity.boss.EntityTFMinoshroom; + +public class TileEntityTFMinoshroomSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFMinoshroomSpawner() { + super(EntityList.getKey(EntityTFMinoshroom.class)); + } + + @Override + public boolean anyPlayerInRange() { + EntityPlayer closestPlayer = world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, getRange(), false); + return closestPlayer != null && closestPlayer.posY > pos.getY() - 4; + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFNagaSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFNagaSpawner.java new file mode 100644 index 0000000000..37b95b3d21 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFNagaSpawner.java @@ -0,0 +1,16 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import twilightforest.entity.boss.EntityTFNaga; + +public class TileEntityTFNagaSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFNagaSpawner() { + super(EntityList.getKey(EntityTFNaga.class)); + } + + @Override + protected int getRange() { + return LONG_RANGE; + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFSnowQueenSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFSnowQueenSpawner.java new file mode 100644 index 0000000000..62b35506de --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFSnowQueenSpawner.java @@ -0,0 +1,18 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; +import twilightforest.entity.boss.EntityTFSnowQueen; + +public class TileEntityTFSnowQueenSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFSnowQueenSpawner() { + super(EntityList.getKey(EntityTFSnowQueen.class)); + } + + @Override + public boolean anyPlayerInRange() { + EntityPlayer closestPlayer = world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, getRange(), false); + return closestPlayer != null && closestPlayer.posY > pos.getY() - 4; + } +} diff --git a/src/main/java/twilightforest/tileentity/spawner/TileEntityTFTowerBossSpawner.java b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFTowerBossSpawner.java new file mode 100644 index 0000000000..4b6439bbc0 --- /dev/null +++ b/src/main/java/twilightforest/tileentity/spawner/TileEntityTFTowerBossSpawner.java @@ -0,0 +1,18 @@ +package twilightforest.tileentity.spawner; + +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; +import twilightforest.entity.boss.EntityTFUrGhast; + +public class TileEntityTFTowerBossSpawner extends TileEntityTFBossSpawner { + + public TileEntityTFTowerBossSpawner() { + super(EntityList.getKey(EntityTFUrGhast.class)); + } + + @Override + public boolean anyPlayerInRange() { + EntityPlayer closestPlayer = world.getClosestPlayer(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, getRange(), false); + return closestPlayer != null && closestPlayer.posY > pos.getY() - 4; + } +} diff --git a/src/main/java/twilightforest/util/EntityUtil.java b/src/main/java/twilightforest/util/EntityUtil.java new file mode 100644 index 0000000000..9d52c0fb1b --- /dev/null +++ b/src/main/java/twilightforest/util/EntityUtil.java @@ -0,0 +1,52 @@ +package twilightforest.util; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; + +import javax.annotation.Nullable; +import java.util.function.DoubleUnaryOperator; + +public class EntityUtil { + + public static boolean canDestroyBlock(World world, BlockPos pos, Entity entity) { + return canDestroyBlock(world, pos, world.getBlockState(pos), entity); + } + + public static boolean canDestroyBlock(World world, BlockPos pos, IBlockState state, Entity entity) { + float hardness = state.getBlockHardness(world, pos); + return hardness >= 0f && hardness < 50f && !state.getBlock().isAir(state, world, pos) + && state.getBlock().canEntityDestroy(state, world, pos, entity) + && (/* rude type limit */!(entity instanceof EntityLivingBase) + || ForgeEventFactory.onEntityDestroyBlock((EntityLivingBase) entity, pos, state)); + } + + /** + * [VanillaCopy] Exact copy of Entity.rayTrace + * TODO: update it? + */ + @Nullable + public static RayTraceResult rayTrace(Entity entity, double range) { + Vec3d position = entity.getPositionEyes(1.0F); + Vec3d look = entity.getLook(1.0F); + Vec3d dest = position.add(look.x * range, look.y * range, look.z * range); + return entity.world.rayTraceBlocks(position, dest); + } + + @Nullable + public static RayTraceResult rayTrace(EntityPlayer player) { + return rayTrace(player, null); + } + + @Nullable + public static RayTraceResult rayTrace(EntityPlayer player, @Nullable DoubleUnaryOperator modifier) { + double range = player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(); + return rayTrace(player, modifier == null ? range : modifier.applyAsDouble(range)); + } +} diff --git a/src/main/java/twilightforest/util/IMapColorSupplier.java b/src/main/java/twilightforest/util/IMapColorSupplier.java new file mode 100644 index 0000000000..e90e79fabf --- /dev/null +++ b/src/main/java/twilightforest/util/IMapColorSupplier.java @@ -0,0 +1,12 @@ +package twilightforest.util; + +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.material.MapColor; + +public interface IMapColorSupplier { + default MapColor supplyMapColor() { + return supplyPlankColor().getMapColor(); + } + + BlockPlanks.EnumType supplyPlankColor(); +} diff --git a/src/main/java/twilightforest/util/IntPair.java b/src/main/java/twilightforest/util/IntPair.java new file mode 100644 index 0000000000..aa157213f3 --- /dev/null +++ b/src/main/java/twilightforest/util/IntPair.java @@ -0,0 +1,13 @@ +package twilightforest.util; + +public final class IntPair { + + public int x, z; + + public IntPair() {} + + public IntPair(int x, int z) { + this.x = x; + this.z = z; + } +} diff --git a/src/main/java/twilightforest/util/MirrorUtil.java b/src/main/java/twilightforest/util/MirrorUtil.java new file mode 100644 index 0000000000..dff4f0f122 --- /dev/null +++ b/src/main/java/twilightforest/util/MirrorUtil.java @@ -0,0 +1,13 @@ +package twilightforest.util; + +import net.minecraft.util.Mirror; + +import java.util.Random; + +public class MirrorUtil { + private static final Mirror[] MIRRORS = { Mirror.NONE, Mirror.LEFT_RIGHT, Mirror.FRONT_BACK }; + + public static Mirror getRandomMirror(Random random) { + return MIRRORS[random.nextInt(MIRRORS.length)]; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/util/ParticleHelper.java b/src/main/java/twilightforest/util/ParticleHelper.java new file mode 100644 index 0000000000..6dad8455f1 --- /dev/null +++ b/src/main/java/twilightforest/util/ParticleHelper.java @@ -0,0 +1,35 @@ +package twilightforest.util; + +import net.minecraft.entity.Entity; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.fml.common.network.NetworkRegistry; +import twilightforest.client.particle.TFParticleType; +import twilightforest.network.PacketSpawnEntityParticles; +import twilightforest.network.TFPacketHandler; + +public class ParticleHelper { + + public static void spawnParticles(World world, BlockPos pos, EnumParticleTypes type, int count, double speed, int... particleArgs) { + if (world instanceof WorldServer) { + ((WorldServer) world).spawnParticle(type, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, count, 0.5, 0.5, 0.5, speed, particleArgs); + } + } + + public static void spawnParticles(Entity entity, EnumParticleTypes type, int count, double speed, int... particleArgs) { + if (entity.world instanceof WorldServer) { + ((WorldServer) entity.world).spawnParticle(type, entity.posX, entity.posY + entity.height * 0.5, entity.posZ, count, entity.width * 0.5, entity.height * 0.5, entity.width * 0.5, speed, particleArgs); + } + } + + public static void spawnParticles(Entity entity, TFParticleType type, int count) { + if (!entity.world.isRemote) { + TFPacketHandler.CHANNEL.sendToAllAround( + new PacketSpawnEntityParticles(type, entity, count), + new NetworkRegistry.TargetPoint(entity.world.provider.getDimension(), entity.posX, entity.posY, entity.posZ, 32.0) + ); + } + } +} diff --git a/src/main/java/twilightforest/util/PlayerHelper.java b/src/main/java/twilightforest/util/PlayerHelper.java new file mode 100644 index 0000000000..a31b268d54 --- /dev/null +++ b/src/main/java/twilightforest/util/PlayerHelper.java @@ -0,0 +1,42 @@ +package twilightforest.util; + +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.PlayerAdvancements; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +public class PlayerHelper { + /** + * Fulfills all remaining criteria of the given advancement + */ + @Deprecated + public static void grantAdvancement(EntityPlayerMP player, ResourceLocation id) { + PlayerAdvancements advancements = player.getAdvancements(); + Advancement advancement = player.getServerWorld().getAdvancementManager().getAdvancement(id); + if (advancement != null) { + for (String criterion : advancements.getProgress(advancement).getRemaningCriteria()) { + advancements.grantCriterion(advancement, criterion); + } + } + } + + @Deprecated + public static void grantCriterion(EntityPlayerMP player, ResourceLocation id, String criterion) { + PlayerAdvancements advancements = player.getAdvancements(); + Advancement advancement = player.getServerWorld().getAdvancementManager().getAdvancement(id); + if (advancement != null) { + advancements.grantCriterion(advancement, criterion); + } + } + + public static boolean doesPlayerHaveRequiredAdvancements(EntityPlayer player, ResourceLocation... requiredAdvancements) { + for (ResourceLocation advancementLocation : requiredAdvancements) { + if (!TwilightForestMod.proxy.doesPlayerHaveAdvancement(player, advancementLocation)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/twilightforest/util/RotationUtil.java b/src/main/java/twilightforest/util/RotationUtil.java new file mode 100644 index 0000000000..7173014732 --- /dev/null +++ b/src/main/java/twilightforest/util/RotationUtil.java @@ -0,0 +1,131 @@ +package twilightforest.util; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Rotation; + +import java.util.Random; + +import static net.minecraft.util.Rotation.CLOCKWISE_180; +import static net.minecraft.util.Rotation.CLOCKWISE_90; +import static net.minecraft.util.Rotation.COUNTERCLOCKWISE_90; +import static net.minecraft.util.Rotation.NONE; + +public final class RotationUtil { + public static final Rotation[] ROTATIONS = Rotation.values(); + public static final EnumFacing[] CARDINALS = { EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST }; + + private RotationUtil() { + } + + public static Rotation getRandomRotation(Random random) { + return ROTATIONS[random.nextInt(ROTATIONS.length)]; + } + + public static Rotation add(Rotation original, int rotations) { + return original.add(ROTATIONS[(rotations + 4) & 3]); + } + + public static Rotation subtract(Rotation original, Rotation rotation) { + switch (rotation) { + case CLOCKWISE_180: + + switch (original) { + case NONE: + return CLOCKWISE_180; + case CLOCKWISE_90: + return COUNTERCLOCKWISE_90; + case CLOCKWISE_180: + return NONE; + case COUNTERCLOCKWISE_90: + return CLOCKWISE_90; + } + + case COUNTERCLOCKWISE_90: + + switch (original) { + case NONE: + return CLOCKWISE_90; + case CLOCKWISE_90: + return CLOCKWISE_180; + case CLOCKWISE_180: + return COUNTERCLOCKWISE_90; + case COUNTERCLOCKWISE_90: + return NONE; + } + + case CLOCKWISE_90: + + switch (original) { + case NONE: + return COUNTERCLOCKWISE_90; + case CLOCKWISE_90: + return NONE; + case CLOCKWISE_180: + return CLOCKWISE_90; + case COUNTERCLOCKWISE_90: + return CLOCKWISE_180; + } + + default: + return original; + } + } + + public static Rotation getRelativeRotation(EnumFacing original, EnumFacing destination) { + switch (original) { + case NORTH: + default: + switch (destination) { + case NORTH: + default: + return Rotation.NONE; + case SOUTH: + return Rotation.CLOCKWISE_180; + case EAST: + return Rotation.CLOCKWISE_90; + case WEST: + return Rotation.COUNTERCLOCKWISE_90; + } + case SOUTH: + switch (destination) { + case SOUTH: + default: + return Rotation.NONE; + case NORTH: + return Rotation.CLOCKWISE_180; + case WEST: + return Rotation.CLOCKWISE_90; + case EAST: + return Rotation.COUNTERCLOCKWISE_90; + } + case EAST: + switch (destination) { + case EAST: + default: + return Rotation.NONE; + case WEST: + return Rotation.CLOCKWISE_180; + case SOUTH: + return Rotation.CLOCKWISE_90; + case NORTH: + return Rotation.COUNTERCLOCKWISE_90; + } + case WEST: + switch (destination) { + case WEST: + default: + return Rotation.NONE; + case EAST: + return Rotation.CLOCKWISE_180; + case NORTH: + return Rotation.CLOCKWISE_90; + case SOUTH: + return Rotation.COUNTERCLOCKWISE_90; + } + } + } + + public static EnumFacing getRandomFacing(Random random) { + return CARDINALS[random.nextInt(CARDINALS.length)]; + } +} diff --git a/src/main/java/twilightforest/util/StructureBoundingBoxUtils.java b/src/main/java/twilightforest/util/StructureBoundingBoxUtils.java new file mode 100644 index 0000000000..3a5949d69c --- /dev/null +++ b/src/main/java/twilightforest/util/StructureBoundingBoxUtils.java @@ -0,0 +1,33 @@ +package twilightforest.util; + +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.gen.structure.StructureBoundingBox; + +import javax.annotation.Nullable; + +public class StructureBoundingBoxUtils { + public static Vec3i getCenter(StructureBoundingBox sbb) { + return new BlockPos(sbb.minX + (sbb.maxX - sbb.minX + 1) / 2, sbb.minY + (sbb.maxY - sbb.minY + 1) / 2, sbb.minZ + (sbb.maxZ - sbb.minZ + 1) / 2); + } + + @SuppressWarnings("unused") + @Nullable + public static StructureBoundingBox getUnionOfSBBs(StructureBoundingBox sbbIn, StructureBoundingBox sbbMask) { + if (!sbbIn.intersectsWith(sbbMask)) + return null; + + return new StructureBoundingBox( + sbbIn.minX > sbbMask.minX ? sbbIn.minX : sbbMask.minX, + sbbIn.minY > sbbMask.minY ? sbbIn.minY : sbbMask.minY, + sbbIn.minZ > sbbMask.minZ ? sbbIn.minZ : sbbMask.minZ, + sbbIn.maxX < sbbMask.maxX ? sbbIn.maxX : sbbMask.maxX, + sbbIn.maxY < sbbMask.maxY ? sbbIn.maxY : sbbMask.maxY, + sbbIn.maxZ < sbbMask.maxZ ? sbbIn.maxZ : sbbMask.maxZ); + } + + public static AxisAlignedBB toAABB(StructureBoundingBox sbb) { + return new AxisAlignedBB(sbb.minX, sbb.minY, sbb.minZ, sbb.maxX + 1, sbb.maxY + 1, sbb.maxZ + 1); + } +} diff --git a/src/main/java/twilightforest/util/TFEntityNames.java b/src/main/java/twilightforest/util/TFEntityNames.java new file mode 100644 index 0000000000..5a28407815 --- /dev/null +++ b/src/main/java/twilightforest/util/TFEntityNames.java @@ -0,0 +1,123 @@ +package twilightforest.util; + +import net.minecraft.util.ResourceLocation; +import twilightforest.TwilightForestMod; + +public class TFEntityNames { + // Passive Animals + public static final ResourceLocation WILD_BOAR = prefix("wild_boar"); + public static final ResourceLocation BIGHORN_SHEEP = prefix("bighorn_sheep"); + public static final ResourceLocation DEER = prefix("deer"); + public static final ResourceLocation PENGUIN = prefix("penguin"); + public static final ResourceLocation TINY_BIRD = prefix("tiny_bird"); + public static final ResourceLocation SQUIRREL = prefix("squirrel"); + public static final ResourceLocation BUNNY = prefix("bunny"); + public static final ResourceLocation RAVEN = prefix("raven"); + public static final ResourceLocation FIREFLY = prefix("firefly"); + + public static final ResourceLocation QUEST_RAM = prefix("quest_ram"); + + // Common Enemies + public static final ResourceLocation SKELETON_DRUID = prefix("skeleton_druid"); + public static final ResourceLocation WRAITH = prefix("wraith"); + public static final ResourceLocation KOBOLD = prefix("kobold"); + public static final ResourceLocation HOSTILE_WOLF = prefix("hostile_wolf"); + + public static final ResourceLocation REDCAP = prefix("redcap"); + public static final ResourceLocation REDCAP_SAPPER = prefix("redcap_sapper"); + + public static final ResourceLocation SWARM_SPIDER = prefix("swarm_spider"); + public static final ResourceLocation HEDGE_SPIDER = prefix("hedge_spider"); + + public static final ResourceLocation FIRE_BEETLE = prefix("fire_beetle"); + public static final ResourceLocation SLIME_BEETLE = prefix("slime_beetle"); + public static final ResourceLocation PINCH_BEETLE = prefix("pinch_beetle"); + + public static final ResourceLocation BOGGARD = prefix("boggard"); // <- ?? + + // Graveyard + public static final ResourceLocation RISING_ZOMBIE = prefix("rising_zombie"); + + // Courtyard + public static final ResourceLocation NAGA = prefix("naga"); + + // Lich Tower + public static final ResourceLocation LICH = prefix("lich"); + public static final ResourceLocation LICH_MINION = prefix("lich_minion"); + public static final ResourceLocation LOYAL_ZOMBIE = prefix("loyal_zombie"); + public static final ResourceLocation DEATH_TOME = prefix("death_tome"); + + // Swamp + public static final ResourceLocation MOSQUITO_SWARM = prefix("mosquito_swarm"); + public static final ResourceLocation HYDRA = prefix("hydra"); + + public static final ResourceLocation MINOTAUR = prefix("minotaur"); + public static final ResourceLocation MINOSHROOM = prefix("minoshroom"); + public static final ResourceLocation MAZE_SLIME = prefix("maze_slime"); + + // Dark Forest + public static final ResourceLocation MIST_WOLF = prefix("mist_wolf"); + public static final ResourceLocation KING_SPIDER = prefix("king_spider"); + + public static final ResourceLocation MINI_GHAST = prefix("mini_ghast"); + public static final ResourceLocation TOWER_GHAST = prefix("tower_ghast"); + public static final ResourceLocation TOWER_GOLEM = prefix("tower_golem"); + public static final ResourceLocation TOWER_TERMITE = prefix("tower_termite"); + public static final ResourceLocation TOWER_BROODLING = prefix("tower_broodling"); + public static final ResourceLocation UR_GHAST = prefix("ur_ghast"); + + public static final ResourceLocation BLOCKCHAIN_GOBLIN = prefix("blockchain_goblin"); + public static final ResourceLocation GOBLIN_KNIGHT_UPPER = prefix("goblin_knight_upper"); + public static final ResourceLocation GOBLIN_KNIGHT_LOWER = prefix("goblin_knight_lower"); + public static final ResourceLocation HELMET_CRAB = prefix("helmet_crab"); + public static final ResourceLocation KNIGHT_PHANTOM = prefix("knight_phantom"); + + // Snow Region + public static final ResourceLocation YETI = prefix("yeti"); + public static final ResourceLocation YETI_ALPHA = prefix("yeti_alpha"); + public static final ResourceLocation WINTER_WOLF = prefix("winter_wolf"); + + public static final ResourceLocation SNOW_GUARDIAN = prefix("snow_guardian"); + public static final ResourceLocation STABLE_ICE_CORE = prefix("stable_ice_core"); + public static final ResourceLocation UNSTABLE_ICE_CORE = prefix("unstable_ice_core"); + public static final ResourceLocation SNOW_QUEEN = prefix("snow_queen"); + public static final ResourceLocation ICE_CRYSTAL = prefix("ice_crystal"); + + // Highlands + public static final ResourceLocation TROLL = prefix("troll"); + + public static final ResourceLocation GIANT_MINER = prefix("giant_miner"); + public static final ResourceLocation ARMORED_GIANT = prefix("armored_giant"); + + public static final ResourceLocation HARBINGER_CUBE = prefix("harbinger_cube"); + public static final ResourceLocation ADHERENT = prefix("adherent"); + public static final ResourceLocation ROVING_CUBE = prefix("roving_cube"); + public static final ResourceLocation SLIDER = prefix("slider"); + public static final ResourceLocation CASTLE_GUARDIAN = prefix("castle_guardian"); + + // Technical + public static final ResourceLocation HYDRA_HEAD = prefix("hydra_head"); + public static final ResourceLocation CHARM_EFFECT = prefix("charm_effect"); + public static final ResourceLocation FALLING_ICE = prefix("falling_ice"); + public static final ResourceLocation CHAIN_BLOCK = prefix("chain_block"); + public static final ResourceLocation CUBE_OF_ANNIHILATION = prefix("cube_of_annihilation"); + + // Projectiles + public static final ResourceLocation NATURE_BOLT = prefix("nature_bolt"); + public static final ResourceLocation LICH_BOLT = prefix("lich_bolt"); + public static final ResourceLocation WAND_BOLT = prefix("wand_bolt"); + public static final ResourceLocation TOME_BOLT = prefix("tome_bolt"); + public static final ResourceLocation HYDRA_MORTAR = prefix("hydra_mortar"); + public static final ResourceLocation LICH_BOMB = prefix("lich_bomb"); + public static final ResourceLocation MOONWORM_SHOT = prefix("moonworm_shot"); + public static final ResourceLocation SLIME_BLOB = prefix("slime_blob"); + public static final ResourceLocation THROWN_WEP = prefix("thrown_wep"); + public static final ResourceLocation THROWN_ICE = prefix("thrown_ice"); + public static final ResourceLocation SEEKER_ARROW = prefix("seeker_arrow"); + public static final ResourceLocation ICE_ARROW = prefix("ice_arrow"); + public static final ResourceLocation ICE_SNOWBALL = prefix("ice_snowball"); + + private static ResourceLocation prefix(String path) { + return new ResourceLocation(TwilightForestMod.ID, path); + } +} diff --git a/src/main/java/twilightforest/util/TFItemStackUtils.java b/src/main/java/twilightforest/util/TFItemStackUtils.java new file mode 100644 index 0000000000..85597adf45 --- /dev/null +++ b/src/main/java/twilightforest/util/TFItemStackUtils.java @@ -0,0 +1,80 @@ +package twilightforest.util; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.*; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.NonNullList; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import twilightforest.compat.Baubles; +import twilightforest.compat.TFCompat; + +import java.util.function.Predicate; + +public class TFItemStackUtils { + + public static boolean consumeInventoryItem(EntityLivingBase living, Predicate matcher, int count) { + + IItemHandler inv = living.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); + if (inv == null) return false; + + boolean consumedSome = false; + + for (int i = 0; i < inv.getSlots() && count > 0; i++) { + ItemStack stack = inv.getStackInSlot(i); + if (matcher.test(stack)) { + ItemStack consumed = inv.extractItem(i, count, false); + count -= consumed.getCount(); + consumedSome = true; + } + } + + if (TFCompat.BAUBLES.isActivated() && living instanceof EntityPlayer) { + consumedSome |= Baubles.consumeInventoryItem((EntityPlayer) living, matcher, count); + } + + return consumedSome; + } + + public static NonNullList splitToSize(ItemStack stack) { + + NonNullList result = NonNullList.create(); + + int size = stack.getMaxStackSize(); + + while (!stack.isEmpty()) { + result.add(stack.splitStack(size)); + } + + return result; + } + + public static boolean hasToolMaterial(ItemStack stack, Item.ToolMaterial material) { + + Item item = stack.getItem(); + + // see TileEntityFurnace.getItemBurnTime + if (item instanceof ItemTool && material.toString().equals(((ItemTool)item).getToolMaterialName())) { + return true; + } + if (item instanceof ItemSword && material.toString().equals(((ItemSword)item).getToolMaterialName())) { + return true; + } + if (item instanceof ItemHoe && material.toString().equals(((ItemHoe)item).getMaterialName())) { + return true; + } + + return false; + } + + public static void clearInfoTag(ItemStack stack, String key) { + NBTTagCompound nbt = stack.getTagCompound(); + if (nbt != null) { + nbt.removeTag(key); + if (nbt.isEmpty()) { + stack.setTagCompound(null); + } + } + } +} diff --git a/src/main/java/twilightforest/util/VanillaEntityNames.java b/src/main/java/twilightforest/util/VanillaEntityNames.java new file mode 100644 index 0000000000..0d76c59e89 --- /dev/null +++ b/src/main/java/twilightforest/util/VanillaEntityNames.java @@ -0,0 +1,30 @@ +package twilightforest.util; + +import net.minecraft.util.ResourceLocation; + +public class VanillaEntityNames { + + public static final ResourceLocation PIG = prefix("pig"); + public static final ResourceLocation SHEEP = prefix("sheep"); + public static final ResourceLocation COW = prefix("cow"); + public static final ResourceLocation CHICKEN = prefix("chicken"); + public static final ResourceLocation RABBIT = prefix("rabbit"); + public static final ResourceLocation PARROT = prefix("parrot"); + public static final ResourceLocation WOLF = prefix("wolf"); + + public static final ResourceLocation VILLAGER = prefix("villager"); + + public static final ResourceLocation BAT = prefix("bat"); + + public static final ResourceLocation CAVE_SPIDER = prefix("cave_spider"); + public static final ResourceLocation SPIDER = prefix("spider"); + public static final ResourceLocation ZOMBIE = prefix("zombie"); + public static final ResourceLocation SKELETON = prefix("skeleton"); + public static final ResourceLocation BLAZE = prefix("blaze"); + public static final ResourceLocation ZOMBIE_PIGMAN = prefix("zombie_pigman"); + public static final ResourceLocation WITCH = prefix("witch"); + + private static ResourceLocation prefix(String path) { + return new ResourceLocation("minecraft", path); + } +} diff --git a/src/main/java/twilightforest/util/WorldUtil.java b/src/main/java/twilightforest/util/WorldUtil.java new file mode 100644 index 0000000000..2fe580f3fb --- /dev/null +++ b/src/main/java/twilightforest/util/WorldUtil.java @@ -0,0 +1,37 @@ +package twilightforest.util; + +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; + +import java.util.Random; + +public final class WorldUtil { + + private WorldUtil() {} + + /** + * Inclusive of edges + */ + public static Iterable getAllAround(BlockPos center, int range) { + return BlockPos.getAllInBox(center.add(-range, -range, -range), center.add(range, range, range)); + } + + /** + * Floors both corners of the bounding box to integers + * Inclusive of edges + */ + public static Iterable getAllInBB(AxisAlignedBB bb) { + return BlockPos.getAllInBox(new BlockPos(bb.minX, bb.minY, bb.minZ), new BlockPos(bb.maxX, bb.maxY, bb.maxZ)); + } + + public static BlockPos randomOffset(Random random, BlockPos pos, int range) { + return randomOffset(random, pos, range, range, range); + } + + public static BlockPos randomOffset(Random random, BlockPos pos, int rx, int ry, int rz) { + int dx = random.nextInt(rx * 2 + 1) - rx; + int dy = random.nextInt(ry * 2 + 1) - ry; + int dz = random.nextInt(rz * 2 + 1) - rz; + return pos.add(dx, dy, dz); + } +} diff --git a/src/main/java/twilightforest/world/ChunkBitArray.java b/src/main/java/twilightforest/world/ChunkBitArray.java new file mode 100644 index 0000000000..5c520b29e6 --- /dev/null +++ b/src/main/java/twilightforest/world/ChunkBitArray.java @@ -0,0 +1,28 @@ +package twilightforest.world; + +public class ChunkBitArray { + private static final int CHUNK_SIZE = (16 * 256 * 16); + private static final int BITS_PER_WORD = 6; + + private final long[] words = new long[CHUNK_SIZE >> 3]; + + public void set(int index) { + this.words[index >> BITS_PER_WORD] |= (1L << index); + } + + public void set(int index, boolean value) { + if (value) { + this.set(index); + } else { + this.clear(index); + } + } + + public void clear(int index) { + this.words[index >> BITS_PER_WORD] &= ~(1L << index); + } + + public boolean get(int index) { + return (this.words[index >> BITS_PER_WORD] & (1L << index)) != 0; + } +} diff --git a/src/main/java/twilightforest/world/ChunkGeneratorTFBase.java b/src/main/java/twilightforest/world/ChunkGeneratorTFBase.java new file mode 100644 index 0000000000..2d4ac2736b --- /dev/null +++ b/src/main/java/twilightforest/world/ChunkGeneratorTFBase.java @@ -0,0 +1,789 @@ +package twilightforest.world; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.init.Blocks; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.WorldType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biome.SpawnListEntry; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; +import net.minecraft.world.gen.IChunkGenerator; +import net.minecraft.world.gen.NoiseGeneratorOctaves; +import net.minecraft.world.gen.NoiseGeneratorPerlin; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraftforge.event.ForgeEventFactory; +import twilightforest.TFFeature; +import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomeDecorator; +import twilightforest.block.TFBlocks; +import twilightforest.util.IntPair; + +import javax.annotation.Nullable; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +// TODO: doc out all the vanilla copying +public abstract class ChunkGeneratorTFBase implements IChunkGenerator { + + protected final Random rand; + + private final NoiseGeneratorOctaves minLimitPerlinNoise; + private final NoiseGeneratorOctaves maxLimitPerlinNoise; + private final NoiseGeneratorOctaves mainPerlinNoise; + private final NoiseGeneratorPerlin surfaceNoise; + private final NoiseGeneratorOctaves depthNoise; + + protected final World world; + protected final WorldType terrainType; + + private double[] mainNoiseRegion; + private double[] minLimitRegion; + private double[] maxLimitRegion; + private double[] depthRegion; + + protected double[] depthBuffer = new double[256]; + protected Biome[] biomesForGeneration; + + private final double[] heightMap; + private final float[] biomeWeights; + + protected final MapGenTFHollowTree hollowTreeGenerator = new MapGenTFHollowTree(); + protected final Map featureGenerators = new EnumMap<>(TFFeature.class); + protected final MapGenTFMajorFeature nothingGenerator = new MapGenTFMajorFeature(); + + private final boolean shouldGenerateBedrock; + + protected static long getSeed(int x, int z) { + return x * 0x4f9939f508L + z * 0x1ef1565bd5L; + } + + // same as ChunkPrimer + protected static int getIndex(int x, int y, int z) { + return x << 12 | z << 8 | y; + } + + public ChunkGeneratorTFBase(World world, long seed, boolean enableFeatures, boolean shouldGenerateBedrock) { + + this.world = world; + this.terrainType = world.getWorldInfo().getTerrainType(); + this.rand = new Random(seed); + this.shouldGenerateBedrock = shouldGenerateBedrock; + + this.minLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16); + this.maxLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16); + this.mainPerlinNoise = new NoiseGeneratorOctaves(this.rand, 8); + this.surfaceNoise = new NoiseGeneratorPerlin(this.rand, 4); + this.depthNoise = new NoiseGeneratorOctaves(rand, 16); + + this.heightMap = new double[825]; + this.biomeWeights = new float[25]; + + for (int j = -2; j <= 2; ++j) { + for (int k = -2; k <= 2; ++k) { + float f = 10.0F / MathHelper.sqrt((float) (j * j + k * k) + 0.2F); + this.biomeWeights[j + 2 + (k + 2) * 5] = f; + } + } + + for (TFFeature feature : TFFeature.values()) { + MapGenTFMajorFeature generator = feature.createFeatureGenerator(); + if (generator != null) { + featureGenerators.put(feature, generator); + } + } + } + + protected final void generateFeatures(int x, int z, ChunkPrimer primer) { + for (MapGenTFMajorFeature generator : featureGenerators.values()) { + generator.generate(world, x, z, primer); + } + } + + protected final Chunk makeChunk(int x, int z, ChunkPrimer primer) { + + Chunk chunk = new Chunk(world, x, z); + + fillChunk(chunk, primer); + + // load in biomes, to prevent striping?! + byte[] chunkBiomes = chunk.getBiomeArray(); + for (int i = 0; i < chunkBiomes.length; ++i) { + chunkBiomes[i] = (byte) Biome.getIdForBiome(this.biomesForGeneration[i]); + } + + chunk.generateSkylightMap(); + + return chunk; + } + + // [VanillaCopy] Extended Chunk constructor, material check replaced with block check + private void fillChunk(Chunk chunk, ChunkPrimer primer) { + + int i = 256; + boolean flag = world.provider.hasSkyLight(); + ExtendedBlockStorage[] storageArrays = chunk.getBlockStorageArray(); + + for (int j = 0; j < 16; ++j) { + for (int k = 0; k < 16; ++k) { + for (int l = 0; l < 256; ++l) { + + IBlockState iblockstate = primer.getBlockState(j, l, k); + + if (iblockstate.getBlock() != Blocks.AIR) { + + int i1 = l >> 4; + + if (storageArrays[i1] == Chunk.NULL_BLOCK_STORAGE) { + storageArrays[i1] = new ExtendedBlockStorage(i1 << 4, flag); + } + + storageArrays[i1].set(j, l & 15, k, iblockstate); + } + } + } + } + } + + // note: ChunkPrimer changed to a BitSet marking 'solid' blocks + // this allows for some post-processing before populating the primer + protected final void setBlocksInChunk(int x, int z, ChunkBitArray data) { + + byte seaLevel = 63; + this.biomesForGeneration = this.world.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 4 - 2, z * 4 - 2, 10, 10); + this.generateHeightmap(x * 4, 0, z * 4); + + for (int k = 0; k < 4; ++k) { + int l = k * 5; + int i1 = (k + 1) * 5; + + for (int j1 = 0; j1 < 4; ++j1) { + int k1 = (l + j1) * 33; + int l1 = (l + j1 + 1) * 33; + int i2 = (i1 + j1) * 33; + int j2 = (i1 + j1 + 1) * 33; + + for (int k2 = 0; k2 < 32; ++k2) { + double d0 = 0.125D; + double d1 = this.heightMap[k1 + k2]; + double d2 = this.heightMap[l1 + k2]; + double d3 = this.heightMap[i2 + k2]; + double d4 = this.heightMap[j2 + k2]; + double d5 = (this.heightMap[k1 + k2 + 1] - d1) * d0; + double d6 = (this.heightMap[l1 + k2 + 1] - d2) * d0; + double d7 = (this.heightMap[i2 + k2 + 1] - d3) * d0; + double d8 = (this.heightMap[j2 + k2 + 1] - d4) * d0; + + for (int l2 = 0; l2 < 8; ++l2) { + double d9 = 0.25D; + double d10 = d1; + double d11 = d2; + double d12 = (d3 - d1) * d9; + double d13 = (d4 - d2) * d9; + + for (int i3 = 0; i3 < 4; ++i3) { + double d14 = 0.25D; + double d16 = (d11 - d10) * d14; + double d15 = d10 - d16; + + for (int k3 = 0; k3 < 4; ++k3) { + if ((d15 += d16) > 0.0D) { + // stone here + data.set(getIndex(k * 4 + i3, k2 * 8 + l2, j1 * 4 + k3)); + } /* else if (k2 * 8 + l2 < seaLevel) */ { + // water below sea level left until later + } + } + + d10 += d12; + d11 += d13; + } + + d1 += d5; + d2 += d6; + d3 += d7; + d4 += d8; + } + } + } + } + } + + private void generateHeightmap(int x, int zero, int z) { + + this.depthRegion = this.depthNoise.generateNoiseOctaves(this.depthRegion, x, z, 5, 5, 200.0D, 200.0D, 0.5D); + this.mainNoiseRegion = this.mainPerlinNoise.generateNoiseOctaves(this.mainNoiseRegion, x, zero, z, 5, 33, 5, 8.555150000000001D, 4.277575000000001D, 8.555150000000001D); + this.minLimitRegion = this.minLimitPerlinNoise.generateNoiseOctaves(this.minLimitRegion, x, zero, z, 5, 33, 5, 684.412D, 684.412D, 684.412D); + this.maxLimitRegion = this.maxLimitPerlinNoise.generateNoiseOctaves(this.maxLimitRegion, x, zero, z, 5, 33, 5, 684.412D, 684.412D, 684.412D); + int terrainIndex = 0; + int noiseIndex = 0; + + for (int ax = 0; ax < 5; ++ax) { + for (int az = 0; az < 5; ++az) { + float totalVariation = 0.0F; + float totalHeight = 0.0F; + float totalFactor = 0.0F; + byte two = 2; + Biome biome = this.biomesForGeneration[ax + 2 + (az + 2) * 10]; + + for (int ox = -two; ox <= two; ++ox) { + for (int oz = -two; oz <= two; ++oz) { + Biome biome1 = this.biomesForGeneration[ax + ox + 2 + (az + oz + 2) * 10]; + float rootHeight = biome1.getBaseHeight(); + float heightVariation = biome1.getHeightVariation(); + + if (this.terrainType == WorldType.AMPLIFIED && rootHeight > 0.0F) { + rootHeight = 1.0F + rootHeight * 2.0F; + heightVariation = 1.0F + heightVariation * 4.0F; + } + + float heightFactor = this.biomeWeights[ox + 2 + (oz + 2) * 5] / (rootHeight + 2.0F); + + if (biome1.getBaseHeight() > biome.getBaseHeight()) { + heightFactor /= 2.0F; + } + + totalVariation += heightVariation * heightFactor; + totalHeight += rootHeight * heightFactor; + totalFactor += heightFactor; + } + } + + totalVariation /= totalFactor; + totalHeight /= totalFactor; + totalVariation = totalVariation * 0.9F + 0.1F; + totalHeight = (totalHeight * 4.0F - 1.0F) / 8.0F; + double terrainNoise = this.depthRegion[noiseIndex] / 8000.0D; + + if (terrainNoise < 0.0D) { + terrainNoise = -terrainNoise * 0.3D; + } + + terrainNoise = terrainNoise * 3.0D - 2.0D; + + if (terrainNoise < 0.0D) { + terrainNoise /= 2.0D; + + if (terrainNoise < -1.0D) { + terrainNoise = -1.0D; + } + + terrainNoise /= 1.4D; + terrainNoise /= 2.0D; + } else { + if (terrainNoise > 1.0D) { + terrainNoise = 1.0D; + } + + terrainNoise /= 8.0D; + } + + ++noiseIndex; + double heightCalc = (double) totalHeight; + double variationCalc = (double) totalVariation; + heightCalc += terrainNoise * 0.2D; + heightCalc = heightCalc * 8.5D / 8.0D; + double d5 = 8.5D + heightCalc * 4.0D; + + for (int ay = 0; ay < 33; ++ay) { + double d6 = ((double) ay - d5) * 12.0D * 128.0D / 256.0D / variationCalc; + + if (d6 < 0.0D) { + d6 *= 4.0D; + } + + double d7 = this.minLimitRegion[terrainIndex] / 512.0D; + double d8 = this.maxLimitRegion[terrainIndex] / 512.0D; + double d9 = (this.mainNoiseRegion[terrainIndex] / 10.0D + 1.0D) / 2.0D; + double terrainCalc = MathHelper.clampedLerp(d7, d8, d9) - d6; + + if (ay > 29) { + double d11 = (double) ((float) (ay - 29) / 3.0F); + terrainCalc = terrainCalc * (1.0D - d11) + -10.0D * d11; + } + + this.heightMap[terrainIndex] = terrainCalc; + ++terrainIndex; + } + } + } + } + + /** + * Crush the terrain to half the height + */ + protected final void squishTerrain(ChunkBitArray data) { + int squishHeight = TFWorld.MAXHEIGHT / 2; + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < squishHeight; y++) { + data.set(getIndex(x, y, z), data.get(getIndex(x, y * 2 + 1, z))); + } + for (int y = squishHeight; y < TFWorld.CHUNKHEIGHT; y++) { + data.clear(getIndex(x, y, z)); + } + } + } + } + + protected abstract void initPrimer(ChunkPrimer primer, ChunkBitArray data); + + // [VanillaCopy] Exact, ChunkGeneratorOverworld.replaceBiomeBlocks + public void replaceBiomeBlocks(int x, int z, ChunkPrimer primer, Biome[] biomesIn) { + + if (!ForgeEventFactory.onReplaceBiomeBlocks(this, x, z, primer, this.world)) return; + double d0 = 0.03125D; + this.depthBuffer = this.surfaceNoise.getRegion(this.depthBuffer, (double)(x * 16), (double)(z * 16), 16, 16, 0.0625D, 0.0625D, 1.0D); + + for (int i = 0; i < 16; ++i) { + for (int j = 0; j < 16; ++j) { + Biome biome = biomesIn[j + i * 16]; + biome.genTerrainBlocks(this.world, this.rand, primer, x * 16 + i, z * 16 + j, this.depthBuffer[j + i * 16]); + } + } + } + + protected final void deformTerrainForFeature(int cx, int cz, ChunkPrimer primer) { + + IntPair nearCenter = new IntPair(); + TFFeature nearFeature = TFFeature.getNearestFeature(cx, cz, world, nearCenter); + + if (!nearFeature.isTerrainAltered) { + return; + } + + int hx = nearCenter.x; + int hz = nearCenter.z; + + if (nearFeature == TFFeature.TROLL_CAVE) { + // troll cloud, more like + deformTerrainForTrollCloud2(primer, nearFeature, cx, cz, hx, hz); + } + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + + int dx = x - hx; + int dz = z - hz; + + if (nearFeature == TFFeature.SMALL_HILL || nearFeature == TFFeature.MEDIUM_HILL || nearFeature == TFFeature.LARGE_HILL || nearFeature == TFFeature.HYDRA_LAIR) { + // hollow hills + int hdiam = ((nearFeature.size * 2 + 1) * 16); + int dist = (int) Math.sqrt(dx * dx + dz * dz); + int hheight = (int) (Math.cos((float) dist / (float) hdiam * Math.PI) * ((float) hdiam / 3F)); + + raiseHills(primer, nearFeature, hdiam, x, z, dx, dz, hheight); + + } else if (nearFeature == TFFeature.HEDGE_MAZE || nearFeature == TFFeature.NAGA_COURTYARD || nearFeature == TFFeature.QUEST_GROVE) { + // hedge mazes, naga arena + flattenTerrainForFeature(primer, nearFeature, x, z, dx, dz); + + } else if (nearFeature == TFFeature.YETI_CAVE) { + // yeti lairs are square + deformTerrainForYetiLair(primer, nearFeature, x, z, dx, dz); + + } else if (nearFeature == TFFeature.TROLL_CAVE) { + deformTerrainForTrollCaves(primer, nearFeature, x, z, dx, dz); + } + //else if (nearFeature != TFFeature.NOTHING) { + // // hedge mazes, naga arena + // flattenTerrainForFeature(primer, nearFeature, x, z, dx, dz); + //} + } + } + + // done! + } + + /** + * Raises up and hollows out the hollow hills. + */ + private void raiseHills(ChunkPrimer primer, TFFeature nearFeature, int hdiam, int x, int z, int dx, int dz, int hillHeight) { + + int oldGround = -1; + int newGround = -1; + boolean foundGroundLevel = false; + + // raise the hill + for (int y = TFWorld.SEALEVEL; y < TFWorld.CHUNKHEIGHT; y++) { + Block currentTerrain = primer.getBlockState(x, y, z).getBlock(); + if (currentTerrain != Blocks.STONE) { + // we found the top of the stone layer + oldGround = y; + newGround = y + hillHeight; + foundGroundLevel = true; + break; + } + } + + if (foundGroundLevel) { + for (int y = oldGround; y <= newGround; y++) { + primer.setBlockState(x, y, z, Blocks.STONE.getDefaultState()); + } + } + + // add the hollow part. Also turn water into stone below that + int hollow = hillHeight - 4 - nearFeature.size; + + // hydra lair has a piece missing + if (nearFeature == TFFeature.HYDRA_LAIR) { + int mx = dx + 16; + int mz = dz + 16; + int mdist = (int) Math.sqrt(mx * mx + mz * mz); + int mheight = (int) (Math.cos(mdist / (hdiam / 1.5) * Math.PI) * (hdiam / 1.5)); + + hollow = Math.max(mheight - 4, hollow); + } + + if (hollow < 0) { + hollow = 0; + } + + // hollow out the hollow parts + int hollowFloor = TFWorld.SEALEVEL - 3 - (hollow / 8); + if (nearFeature == TFFeature.HYDRA_LAIR) { + // different floor + hollowFloor = TFWorld.SEALEVEL; + } + + if (hillHeight > 0) { + // put a base on hills that go over open space or water + for (int y = 0; y < TFWorld.SEALEVEL; y++) { + if (primer.getBlockState(x, y, z).getBlock() != Blocks.STONE) { + primer.setBlockState(x, y, z, Blocks.STONE.getDefaultState()); + } + } + } + + for (int y = hollowFloor + 1; y < hollowFloor + hollow; y++) { + primer.setBlockState(x, y, z, Blocks.AIR.getDefaultState()); + } + } + + private void flattenTerrainForFeature(ChunkPrimer primer, TFFeature nearFeature, int x, int z, int dx, int dz) { + + float squishFactor = 0f; + int mazeHeight = TFWorld.SEALEVEL + 1; + final int FEATURE_BOUNDARY = (nearFeature.size * 2 + 1) * 8 - 8; + + if (dx <= -FEATURE_BOUNDARY) { + squishFactor = (-dx - FEATURE_BOUNDARY) / 8.0f; + } else if (dx >= FEATURE_BOUNDARY) { + squishFactor = (dx - FEATURE_BOUNDARY) / 8.0f; + } + + if (dz <= -FEATURE_BOUNDARY) { + squishFactor = Math.max(squishFactor, (-dz - FEATURE_BOUNDARY) / 8.0f); + } else if (dz >= FEATURE_BOUNDARY) { + squishFactor = Math.max(squishFactor, (dz - FEATURE_BOUNDARY) / 8.0f); + } + + if (squishFactor > 0f) { + // blend the old terrain height to arena height + for (int y = 0; y <= 127; y++) { + Block currentTerrain = primer.getBlockState(x, y, z).getBlock(); + // we're still in ground + if (currentTerrain != Blocks.STONE) { + // we found the lowest chunk of earth + mazeHeight += ((y - mazeHeight) * squishFactor); + break; + } + } + } + + // sets the ground level to the maze height + for (int y = 0; y < mazeHeight; y++) { + Block b = primer.getBlockState(x, y, z).getBlock(); + if (b == Blocks.AIR || b == Blocks.WATER) { + primer.setBlockState(x, y, z, Blocks.STONE.getDefaultState()); + } + } + for (int y = mazeHeight; y <= 127; y++) { + Block b = primer.getBlockState(x, y, z).getBlock(); + if (b != Blocks.AIR && b != Blocks.WATER) { + primer.setBlockState(x, y, z, Blocks.AIR.getDefaultState()); + } + } + } + + private void deformTerrainForYetiLair(ChunkPrimer primer, TFFeature nearFeature, int x, int z, int dx, int dz) { + + float squishFactor = 0f; + int topHeight = TFWorld.SEALEVEL + 24; + int outerBoundary = (nearFeature.size * 2 + 1) * 8 - 8; + + // outer boundary + if (dx <= -outerBoundary) { + squishFactor = (-dx - outerBoundary) / 8.0f; + } else if (dx >= outerBoundary) { + squishFactor = (dx - outerBoundary) / 8.0f; + } + + if (dz <= -outerBoundary) { + squishFactor = Math.max(squishFactor, (-dz - outerBoundary) / 8.0f); + } else if (dz >= outerBoundary) { + squishFactor = Math.max(squishFactor, (dz - outerBoundary) / 8.0f); + } + + // inner boundary + int caveBoundary = (nearFeature.size * 2) * 8 - 8; + int hollowCeiling = TFWorld.SEALEVEL + 16; + + int offset = Math.min(Math.abs(dx), Math.abs(dz)); + hollowCeiling = (TFWorld.SEALEVEL + 40) - (offset * 4); + + // center square cave + if (dx >= -caveBoundary && dz >= -caveBoundary && dx <= caveBoundary && dz <= caveBoundary) { + hollowCeiling = TFWorld.SEALEVEL + 16; + } + + // slope ceiling slightly + hollowCeiling -= (offset / 6); + + // max out ceiling 8 blocks from roof + hollowCeiling = Math.min(hollowCeiling, TFWorld.SEALEVEL + 16); + + // floor, also with slight slope + int hollowFloor = TFWorld.SEALEVEL - 1 + (offset / 6); + + if (squishFactor > 0f) { + // blend the old terrain height to arena height + for (int y = 0; y <= 127; y++) { + Block currentTerrain = primer.getBlockState(x, y, z).getBlock(); + if (currentTerrain != Blocks.STONE) { + // we found the lowest chunk of earth + topHeight += ((y - topHeight) * squishFactor); + hollowFloor += ((y - hollowFloor) * squishFactor); + break; + } + } + } + + // carve the cave into the stone + + // add stone + for (int y = 0; y < topHeight; y++) { + Block b = primer.getBlockState(x, y, z).getBlock(); + if (b == Blocks.AIR || b == Blocks.WATER) { + primer.setBlockState(x, y, z, Blocks.STONE.getDefaultState()); + } + } + + // hollow out inside + for (int y = hollowFloor + 1; y < hollowCeiling; ++y) { + primer.setBlockState(x, y, z, Blocks.AIR.getDefaultState()); + } + + // ice floor + if (hollowFloor < hollowCeiling && hollowFloor < TFWorld.SEALEVEL + 3) { + primer.setBlockState(x, hollowFloor, z, Blocks.PACKED_ICE.getDefaultState()); + } + } + + protected void deformTerrainForTrollCaves(ChunkPrimer primer, TFFeature nearFeature, int x, int z, int dx, int dz) {} + + private void deformTerrainForTrollCloud2(ChunkPrimer primer, TFFeature nearFeature, int cx, int cz, int hx, int hz) { + for (int bx = 0; bx < 4; bx++) { + for (int bz = 0; bz < 4; bz++) { + int dx = (bx * 4) - hx - 2; + int dz = (bz * 4) - hz - 2; + + // generate several centers for other clouds + int regionX = (cx + 8) >> 4; + int regionZ = (cz + 8) >> 4; + + long seed = (long) (regionX * 3129871) ^ (long) regionZ * 116129781L; + seed = seed * seed * 42317861L + seed * 7L; + + int num0 = (int) (seed >> 12 & 3L); + int num1 = (int) (seed >> 15 & 3L); + int num2 = (int) (seed >> 18 & 3L); + int num3 = (int) (seed >> 21 & 3L); + int num4 = (int) (seed >> 9 & 3L); + int num5 = (int) (seed >> 6 & 3L); + int num6 = (int) (seed >> 3 & 3L); + int num7 = (int) (seed >> 0 & 3L); + + int dx2 = dx + (num0 * 5) - (num1 * 4); + int dz2 = dz + (num2 * 4) - (num3 * 5); + int dx3 = dx + (num4 * 5) - (num5 * 4); + int dz3 = dz + (num6 * 4) - (num7 * 5); + + // take the minimum distance to any center + double dist0 = Math.sqrt(dx * dx + dz * dz) / 4.0; + double dist2 = Math.sqrt(dx2 * dx2 + dz2 * dz2) / 3.5; + double dist3 = Math.sqrt(dx3 * dx3 + dz3 * dz3) / 4.5; + + double dist = Math.min(dist0, Math.min(dist2, dist3)); + + float pr = world.rand.nextFloat(); + double cv = (dist - 7F) - (pr * 3.0F); + + // randomize depth and height + int y = 166; + int depth = 4; + + if (pr < 0.1F) { + y++; + } + if (pr > 0.6F) { + depth++; + } + if (pr > 0.9F) { + depth++; + } + + // generate cloud + for (int sx = 0; sx < 4; sx++) { + for (int sz = 0; sz < 4; sz++) { + int lx = bx * 4 + sx; + int lz = bz * 4 + sz; + + if (dist < 7 || cv < 0.05F) { + + primer.setBlockState(lx, y, lz, TFBlocks.wispy_cloud.getDefaultState()); + for (int d = 1; d < depth; d++) { + primer.setBlockState(lx, y - d, lz, TFBlocks.fluffy_cloud.getDefaultState()); + } + primer.setBlockState(lx, y - depth, lz, TFBlocks.wispy_cloud.getDefaultState()); + } else if (dist < 8 || cv < 1F) { + for (int d = 1; d < depth; d++) { + primer.setBlockState(lx, y - d, lz, TFBlocks.fluffy_cloud.getDefaultState()); + } + } + } + } + } + } + } + + protected final boolean allowSurfaceLakes(Biome biome) { + if (biome.decorator instanceof TFBiomeDecorator) { + return !((TFBiomeDecorator) biome.decorator).hasCanopy; + } + return true; + } + + public final boolean shouldGenerateBedrock() { + return shouldGenerateBedrock; + } + + @Override + public boolean generateStructures(Chunk chunk, int x, int z) { + return false; + } + + /** + * Returns a list of creatures of the specified type that can spawn at the + * given location. + *

+ * Twilight Forest variant! First check features, then only if we're not in + * a feature, check the biome. + */ + @Override + public List getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos) { + // are the specified coordinates precisely in a feature? + TFFeature nearestFeature = TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world); + + List featureList = getFeatureGenerator(nearestFeature).getPossibleCreatures(creatureType, pos); + if (featureList != null) { + return featureList; + } + + Biome biome = world.getBiome(pos); + + if (pos.getY() < TFWorld.SEALEVEL && biome instanceof TFBiomeBase) { + // cave monsters! + return ((TFBiomeBase) biome).getUndergroundSpawnableList(creatureType); + } else { + return biome.getSpawnableList(creatureType); + } + } + + @Nullable + @Override + public BlockPos getNearestStructurePos(World world, String structureName, BlockPos position, boolean findUnexplored) { + if (structureName.equalsIgnoreCase(hollowTreeGenerator.getStructureName())) { + return hollowTreeGenerator.getNearestStructurePos(world, position, findUnexplored); + } + TFFeature feature = TFFeature.getFeatureByName(new ResourceLocation(structureName)); + if (feature != TFFeature.NOTHING) { + return TFFeature.findNearestFeaturePosBySpacing(world, feature, position, 20, 11, 10387313, true, 100, findUnexplored); + } + return null; + } + + protected final MapGenTFMajorFeature getFeatureGenerator(TFFeature feature) { + return featureGenerators.getOrDefault(feature, nothingGenerator); + } + + public void setStructureConquered(BlockPos pos, boolean flag) { + getFeatureGenerator(TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world)).setStructureConquered(pos, flag); + } + + public boolean isStructureLocked(BlockPos pos, int lockIndex) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world)).isStructureLocked(pos, lockIndex); + } + + public boolean isBlockInStructureBB(BlockPos pos) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world)).isInsideStructure(pos); + } + + @Nullable + public StructureBoundingBox getSBBAt(BlockPos pos) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world)).getSBBAt(pos); + } + + public boolean isBlockProtected(BlockPos pos) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world)).isBlockProtectedAt(pos); + } + + public boolean isStructureConquered(BlockPos pos) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world)).isStructureConquered(pos); + } + + public boolean isBlockInFullStructure(int x, int z) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(x, z, world)).isBlockInFullStructure(x, z); + } + + public boolean isBlockNearFullStructure(int x, int z, int range) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(x, z, world)).isBlockNearFullStructure(x, z, range); + } + + //public StructureBoundingBox getFullSBBAt(int mapX, int mapZ) { + // getFeatureGenerator(TFFeature.getFeatureAt(mapX, mapZ, world)).getFullSBBAt(mapX, mapZ); + //} + + @Nullable + public StructureBoundingBox getFullSBBNear(int mapX, int mapZ, int range) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(mapX, mapZ, world)).getFullSBBNear(mapX, mapZ, range); + } + + public TFFeature getFeatureAt(BlockPos pos) { + return getFeatureGenerator(TFFeature.getFeatureForRegionPos(pos.getX(), pos.getZ(), world)).getFeatureAt(pos); + } + + @Override + public void recreateStructures(Chunk chunk, int x, int z) { + for (MapGenTFMajorFeature generator : featureGenerators.values()) { + generator.generate(world, x, z, null); + } + } + + @Override + public boolean isInsideStructure(World world, String structureName, BlockPos pos) { + if (structureName.equalsIgnoreCase(hollowTreeGenerator.getStructureName())) { + return hollowTreeGenerator.isInsideStructure(pos); + } + TFFeature feature = TFFeature.getFeatureByName(new ResourceLocation(structureName)); + return feature != TFFeature.NOTHING && getFeatureGenerator(feature).isInsideStructure(pos); + } +} diff --git a/src/main/java/twilightforest/world/ChunkGeneratorTwilightForest.java b/src/main/java/twilightforest/world/ChunkGeneratorTwilightForest.java new file mode 100644 index 0000000000..0f5f7e334e --- /dev/null +++ b/src/main/java/twilightforest/world/ChunkGeneratorTwilightForest.java @@ -0,0 +1,326 @@ +package twilightforest.world; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockFalling; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldEntitySpawner; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.gen.NoiseGeneratorOctaves; +import net.minecraft.world.gen.feature.WorldGenDungeons; +import net.minecraft.world.gen.feature.WorldGenLakes; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.terraingen.PopulateChunkEvent; +import net.minecraftforge.event.terraingen.TerrainGen; +import twilightforest.TFConfig; +import twilightforest.TFFeature; +import twilightforest.biomes.TFBiomes; +import twilightforest.block.TFBlocks; +import twilightforest.util.IntPair; + +// TODO: doc out all the vanilla copying +public class ChunkGeneratorTwilightForest extends ChunkGeneratorTFBase { + + private final NoiseGeneratorOctaves noiseGen4; + //private final NoiseGeneratorOctaves scaleNoise; + //private final NoiseGeneratorOctaves forestNoise; + + private final TFGenCaves caveGenerator = new TFGenCaves(); + private final TFGenRavine ravineGenerator = new TFGenRavine(); + + public ChunkGeneratorTwilightForest(World world, long seed, boolean enableFeatures) { + super(world, seed, enableFeatures, true); + this.noiseGen4 = new NoiseGeneratorOctaves(rand, 4); + //this.scaleNoise = new NoiseGeneratorOctaves(rand, 10); + //this.forestNoise = new NoiseGeneratorOctaves(rand, 8); + } + + @Override + public Chunk generateChunk(int x, int z) { + rand.setSeed(getSeed(x, z)); + + ChunkBitArray data = new ChunkBitArray(); + setBlocksInChunk(x, z, data); + squishTerrain(data); + + ChunkPrimer primer = new DirectChunkPrimer(); + initPrimer(primer, data); + + // Dark Forest canopy uses the different scaled biomesForGeneration value already set in setBlocksInChunk + addDarkForestCanopy2(x, z, primer); + + // now we reload the biome array so that it's scaled 1:1 with blocks on the ground + this.biomesForGeneration = world.getBiomeProvider().getBiomes(biomesForGeneration, x * 16, z * 16, 16, 16); + + addGlaciers(x, z, primer, biomesForGeneration); + deformTerrainForFeature(x, z, primer); + replaceBiomeBlocks(x, z, primer, biomesForGeneration); + + caveGenerator.generate(world, x, z, primer); + ravineGenerator.generate(world, x, z, primer); + generateFeatures(x, z, primer); + hollowTreeGenerator.generate(world, x, z, primer); + + return makeChunk(x, z, primer); + } + + @Override + protected void initPrimer(ChunkPrimer primer, ChunkBitArray data) { + + IBlockState water = Blocks.WATER.getDefaultState(); + IBlockState stone = Blocks.STONE.getDefaultState(); + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < 256; y++) { + boolean solid = data.get(getIndex(x, y, z)); + if (y < TFWorld.SEALEVEL && !solid) { + primer.setBlockState(x, y, z, water); + } else if (solid) { + primer.setBlockState(x, y, z, stone); + } + } + } + } + } + + private void addGlaciers(int chunkX, int chunkZ, ChunkPrimer primer, Biome[] biomes) { + + IBlockState glacierBase = Blocks.GRAVEL.getDefaultState(); + IBlockState glacierMain = TFConfig.performance.glacierPackedIce ? Blocks.PACKED_ICE.getDefaultState() : Blocks.ICE.getDefaultState(); + IBlockState glacierTop = Blocks.ICE.getDefaultState(); + + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + + Biome biome = biomes[x & 15 | (z & 15) << 4]; + if (biome != TFBiomes.glacier) continue; + + // find the (current) top block + int gBase = -1; + for (int y = 127; y >= 0; y--) { + Block currentBlock = primer.getBlockState(x, y, z).getBlock(); + if (currentBlock == Blocks.STONE) { + gBase = y + 1; + primer.setBlockState(x, y, z, glacierBase); + break; + } + } + + // raise the glacier from that top block + int gHeight = 32; + int gTop = Math.min(gBase + gHeight, 127); + + for (int y = gBase; y < gTop; y++) { + primer.setBlockState(x, y, z, glacierMain); + } + primer.setBlockState(x, gTop, z, glacierTop); + } + } + } + + /** + * Adds dark forest canopy. This version uses the "unzoomed" array of biomes used in land generation to determine how many of the nearby blocks are dark forest + */ + private void addDarkForestCanopy2(int chunkX, int chunkZ, ChunkPrimer primer) { + + int[] thicks = new int[5 * 5]; + boolean biomeFound = false; + + for (int z = 0; z < 5; z++) { + for (int x = 0; x < 5; x++) { + + for (int bx = -1; bx <= 1; bx++) { + for (int bz = -1; bz <= 1; bz++) { + Biome biome = biomesForGeneration[x + bx + 2 + (z + bz + 2) * (10)]; + + if (biome == TFBiomes.darkForest || biome == TFBiomes.darkForestCenter) { + thicks[x + z * 5]++; + biomeFound = true; + } + } + } + } + } + + if (!biomeFound) return; + + IntPair nearCenter = new IntPair(); + TFFeature nearFeature = TFFeature.getNearestFeature(chunkX, chunkZ, world, nearCenter); + + double d = 0.03125D; + depthBuffer = noiseGen4.generateNoiseOctaves(depthBuffer, chunkX * 16, chunkZ * 16, 0, 16, 16, 1, d * 2D, d * 2D, d * 2D); + + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + + int qx = x / 4; + int qz = z / 4; + + float xweight = (x % 4) * 0.25F + 0.125F; + float zweight = (z % 4) * 0.25F + 0.125F; + + float thickness = 0; + + thickness += thicks[qx + (qz) * 5] * (1F - xweight) * (1F - zweight); + thickness += thicks[qx + 1 + (qz) * 5] * (xweight) * (1F - zweight); + thickness += thicks[qx + (qz + 1) * 5] * (1F - xweight) * (zweight); + thickness += thicks[qx + 1 + (qz + 1) * 5] * (xweight) * (zweight); + + thickness -= 4; + + //int thickness = thicks[qz + (qz) * 5]; + + // make sure we're not too close to the tower + if (nearFeature == TFFeature.DARK_TOWER) { + + int hx = nearCenter.x; + int hz = nearCenter.z; + + int dx = x - hx; + int dz = z - hz; + int dist = (int) Math.sqrt(dx * dx + dz * dz); + + if (dist < 24) { + thickness -= (24 - dist); + } + } + + if (thickness > 1) { + // find the (current) top block + int topLevel = -1; + for (int y = 127; y >= 0; y--) { + Block currentBlock = primer.getBlockState(x, y, z).getBlock(); + if (currentBlock == Blocks.WATER) { + // don't generate over water + break; + } + if (currentBlock == Blocks.STONE) { + topLevel = y; + break; + } + } + + if (topLevel != -1) { + // just use the same noise generator as the terrain uses for stones + int noise = Math.min(3, (int) (depthBuffer[z & 15 | (x & 15) << 4] / 1.25f)); + + // manipulate top and bottom + int treeBottom = topLevel + 12 - (int) (thickness * 0.5F); + int treeTop = treeBottom + (int) (thickness * 1.5F); + + treeBottom -= noise; + + IBlockState darkLeaves = TFBlocks.dark_leaves.getDefaultState(); + for (int y = treeBottom; y < treeTop; y++) { + primer.setBlockState(x, y, z, darkLeaves); + } + } + } + } + } + } + + @Override + public void populate(int x, int z) { + + BlockFalling.fallInstantly = true; + + int i = x * 16; + int j = z * 16; + BlockPos blockpos = new BlockPos(i, 0, j); + Biome biome = this.world.getBiome(blockpos.add(16, 0, 16)); + this.rand.setSeed(this.world.getSeed()); + long k = this.rand.nextLong() / 2L * 2L + 1L; + long l = this.rand.nextLong() / 2L * 2L + 1L; + this.rand.setSeed((long)x * k + (long)z * l ^ this.world.getSeed()); + boolean flag = false; + ChunkPos chunkpos = new ChunkPos(x, z); + + ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, flag); + + boolean disableFeatures = false; + + for (MapGenTFMajorFeature generator : featureGenerators.values()) { + if (generator.generateStructure(world, rand, chunkpos)) { + disableFeatures = true; + } + } + + disableFeatures = disableFeatures || !TFFeature.getNearestFeature(x, z, world).areChunkDecorationsEnabled; + + hollowTreeGenerator.generateStructure(world, rand, chunkpos); + + if (!disableFeatures && rand.nextInt(4) == 0) { + if (TerrainGen.populate(this, this.world, this.rand, x, x, flag, PopulateChunkEvent.Populate.EventType.LAKE)) { + int i1 = blockpos.getX() + rand.nextInt(16) + 8; + int i2 = rand.nextInt(TFWorld.CHUNKHEIGHT); + int i3 = blockpos.getZ() + rand.nextInt(16) + 8; + if (i2 < TFWorld.SEALEVEL || allowSurfaceLakes(biome)) { + (new WorldGenLakes(Blocks.WATER)).generate(world, rand, new BlockPos(i1, i2, i3)); + } + } + } + + if (!disableFeatures && rand.nextInt(32) == 0) { // reduced from 8 + if (TerrainGen.populate(this, this.world, this.rand, x, z, flag, PopulateChunkEvent.Populate.EventType.LAVA)) { + int j1 = blockpos.getX() + rand.nextInt(16) + 8; + int j2 = rand.nextInt(rand.nextInt(TFWorld.CHUNKHEIGHT - 8) + 8); + int j3 = blockpos.getZ() + rand.nextInt(16) + 8; + if (j2 < TFWorld.SEALEVEL || allowSurfaceLakes(biome) && rand.nextInt(10) == 0) { + (new WorldGenLakes(Blocks.LAVA)).generate(world, rand, new BlockPos(j1, j2, j3)); + } + } + } + + if (TerrainGen.populate(this, this.world, this.rand, x, z, flag, PopulateChunkEvent.Populate.EventType.DUNGEON)) { + for (int k1 = 0; k1 < 8; k1++) { + int k2 = blockpos.getX() + rand.nextInt(16) + 8; + int k3 = rand.nextInt(TFWorld.CHUNKHEIGHT); + int l3 = blockpos.getZ() + rand.nextInt(16) + 8; + (new WorldGenDungeons()).generate(world, rand, new BlockPos(k2, k3, l3)); + } + } + + biome.decorate(this.world, this.rand, new BlockPos(i, 0, j)); + + if (TerrainGen.populate(this, this.world, this.rand, x, z, flag, PopulateChunkEvent.Populate.EventType.ANIMALS)) { + WorldEntitySpawner.performWorldGenSpawning(this.world, biome, i + 8, j + 8, 16, 16, this.rand); + } + + blockpos = blockpos.add(8, 0, 8); + + if (TerrainGen.populate(this, this.world, this.rand, x, z, flag, PopulateChunkEvent.Populate.EventType.ICE)) { + for (int k2 = 0; k2 < 16; ++k2) { + for (int j3 = 0; j3 < 16; ++j3) { + + BlockPos blockpos1 = this.world.getPrecipitationHeight(blockpos.add(k2, 0, j3)); + BlockPos blockpos2 = blockpos1.down(); + + if (this.world.canBlockFreezeWater(blockpos2)) { + this.world.setBlockState(blockpos2, Blocks.ICE.getDefaultState(), 16 | 2); + } + + if (this.world.canSnowAt(blockpos1, true)) { + this.world.setBlockState(blockpos1, Blocks.SNOW_LAYER.getDefaultState(), 16 | 2); + } + } + } + }//Forge: End ICE + + ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, flag); + + BlockFalling.fallInstantly = false; + } + + @Override + public void recreateStructures(Chunk chunk, int x, int z) { + super.recreateStructures(chunk, x, z); + hollowTreeGenerator.generate(world, x, z, null); + } +} diff --git a/src/main/java/twilightforest/world/ChunkGeneratorTwilightVoid.java b/src/main/java/twilightforest/world/ChunkGeneratorTwilightVoid.java new file mode 100644 index 0000000000..b8c189e4bf --- /dev/null +++ b/src/main/java/twilightforest/world/ChunkGeneratorTwilightVoid.java @@ -0,0 +1,146 @@ +package twilightforest.world; + +import net.minecraft.block.BlockFalling; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.terraingen.PopulateChunkEvent; +import net.minecraftforge.event.terraingen.TerrainGen; +import twilightforest.TFConfig; +import twilightforest.TFFeature; +import twilightforest.biomes.TFBiomes; + +public class ChunkGeneratorTwilightVoid extends ChunkGeneratorTFBase { + + private final boolean generateHollowTrees = TFConfig.dimension.skylightOaks; + + public ChunkGeneratorTwilightVoid(World world, long seed, boolean enableFeatures) { + super(world, seed, enableFeatures, false); + } + + @Override + public Chunk generateChunk(int x, int z) { + rand.setSeed(getSeed(x, z)); + + ChunkBitArray data = new ChunkBitArray(); + setBlocksInChunk(x, z, data); + squishTerrain(data); + + // now we reload the biome array so that it's scaled 1:1 with blocks on the ground + this.biomesForGeneration = world.getBiomeProvider().getBiomes(biomesForGeneration, x * 16, z * 16, 16, 16); + + ChunkPrimer primer = new DirectChunkPrimer(); + initPrimer(primer, data); + + deformTerrainForFeature(x, z, primer); + replaceBiomeBlocks(x, z, primer, biomesForGeneration); + + generateFeatures(x, z, primer); + if (generateHollowTrees) { + hollowTreeGenerator.generate(world, x, z, primer); + } + + return makeChunk(x, z, primer); + } + + @Override + protected void initPrimer(ChunkPrimer primer, ChunkBitArray data) { + + IBlockState stone = Blocks.STONE.getDefaultState(); + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + + Biome biome = biomesForGeneration[x & 15 | (z & 15) << 4]; + if (biome != TFBiomes.highlandsCenter) continue; + + for (int y = 0; y < 256; y++) { + if (data.get(getIndex(x, y, z))) { + primer.setBlockState(x, y, z, stone); + } + } + } + } + } + + @Override + public void populate(int x, int z) { + + BlockFalling.fallInstantly = true; + + int i = x * 16; + int j = z * 16; + BlockPos blockpos = new BlockPos(i, 0, j); + this.rand.setSeed(this.world.getSeed()); + long k = this.rand.nextLong() / 2L * 2L + 1L; + long l = this.rand.nextLong() / 2L * 2L + 1L; + this.rand.setSeed((long)x * k + (long)z * l ^ this.world.getSeed()); + boolean flag = false; + ChunkPos chunkpos = new ChunkPos(x, z); + + ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, flag); + + for (MapGenTFMajorFeature generator : featureGenerators.values()) { + generator.generateStructure(world, rand, chunkpos); + } + + if (generateHollowTrees) { + hollowTreeGenerator.generateStructure(world, rand, chunkpos); + } + + blockpos = blockpos.add(8, 0, 8); + + if (TerrainGen.populate(this, this.world, this.rand, x, z, flag, PopulateChunkEvent.Populate.EventType.ICE)) { + for (int k2 = 0; k2 < 16; ++k2) { + for (int j3 = 0; j3 < 16; ++j3) { + + BlockPos blockpos1 = this.world.getPrecipitationHeight(blockpos.add(k2, 0, j3)); + BlockPos blockpos2 = blockpos1.down(); + + if (this.world.canBlockFreezeWater(blockpos2)) { + this.world.setBlockState(blockpos2, Blocks.ICE.getDefaultState(), 16 | 2); + } + + if (this.world.canSnowAt(blockpos1, true)) { + this.world.setBlockState(blockpos1, Blocks.SNOW_LAYER.getDefaultState(), 16 | 2); + } + } + } + }//Forge: End ICE + + ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, flag); + + BlockFalling.fallInstantly = false; + } + + @Override + protected void deformTerrainForTrollCaves(ChunkPrimer primer, TFFeature nearFeature, int x, int z, int dx, int dz) { + + int radius = (nearFeature.size * 2 + 1) * 8; + int dist = (int) Math.sqrt(dx * dx + dz * dz); + if (dist > radius) return; + + Biome biome = biomesForGeneration[x & 15 | (z & 15) << 4]; + if (biome != TFBiomes.highlands) return; + + for (int y = 0; y < 60; y++) { + if (primer.getBlockState(x, y, z).getBlock() != Blocks.STONE) { + primer.setBlockState(x, y, z, Blocks.STONE.getDefaultState()); + } + } + } + + @Override + public void recreateStructures(Chunk chunk, int x, int z) { + super.recreateStructures(chunk, x, z); + if (generateHollowTrees) { + hollowTreeGenerator.generate(world, x, z, null); + } + } +} diff --git a/src/main/java/twilightforest/world/ChunkProviderTwilightForest.java b/src/main/java/twilightforest/world/ChunkProviderTwilightForest.java deleted file mode 100644 index f66673bf17..0000000000 --- a/src/main/java/twilightforest/world/ChunkProviderTwilightForest.java +++ /dev/null @@ -1,1137 +0,0 @@ -// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. -// Jad home page: http://www.kpdus.com/jad.html -// Decompiler options: packimports(3) braces deadcode - -package twilightforest.world; - -import java.util.List; -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.BlockFalling; -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.init.Blocks; -import net.minecraft.util.IProgressUpdate; -import net.minecraft.util.MathHelper; -import net.minecraft.world.ChunkPosition; -import net.minecraft.world.SpawnerAnimals; -import net.minecraft.world.World; -import net.minecraft.world.WorldType; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.biome.BiomeGenBase.SpawnListEntry; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.IChunkProvider; -import net.minecraft.world.gen.NoiseGeneratorOctaves; -import net.minecraft.world.gen.NoiseGeneratorPerlin; -import net.minecraft.world.gen.feature.WorldGenDungeons; -import net.minecraft.world.gen.feature.WorldGenLakes; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.terraingen.ChunkProviderEvent; -import twilightforest.TFFeature; -import twilightforest.biomes.TFBiomeBase; -import twilightforest.block.TFBlocks; -import cpw.mods.fml.common.eventhandler.Event.Result; - -// Referenced classes of package net.minecraft.src: -// IChunkProvider, MapGenCaves, MapGenStronghold, MapGenVillage, -// MapGenMineshaft, MapGenRavine, NoiseGeneratorOctaves, World, -// WorldChunkManager, Block, BiomeGenBase, Chunk, -// MapGenBase, MathHelper, BlockSand, WorldGenLakes, -// WorldGenDungeons, SpawnerAnimals, IProgressUpdate - -public class ChunkProviderTwilightForest implements IChunkProvider { - private Random rand; - //private NoiseGeneratorOctaves noiseGen1; - //private NoiseGeneratorOctaves noiseGen2; - //private NoiseGeneratorOctaves noiseGen3; - private NoiseGeneratorOctaves noiseGen4; - public NoiseGeneratorOctaves noiseGen5; - public NoiseGeneratorOctaves noiseGen6; - public NoiseGeneratorOctaves mobSpawnerNoise; - private World worldObj; - private double stoneNoise[]; - private TFGenCaves caveGenerator; - private TFGenRavine ravineGenerator; - private BiomeGenBase biomesForGeneration[]; - double noise3[]; - double noise1[]; - double noise2[]; - double noise5[]; - double noise6[]; - float squareTable[]; - int unusedIntArray32x32[][]; - - - private WorldType field_147435_p; - - private NoiseGeneratorOctaves field_147431_j; - private NoiseGeneratorOctaves field_147432_k; - private NoiseGeneratorOctaves field_147429_l; - private NoiseGeneratorPerlin field_147430_m; - - private final double[] terrainCalcs; - private final float[] parabolicField; - - double[] field_147427_d; - double[] field_147428_e; - double[] field_147425_f; - double[] field_147426_g; - int[][] field_73219_j = new int[32][32]; - - private MapGenTFMajorFeature majorFeatureGenerator; - private MapGenTFHollowTree hollowTreeGenerator; - - public ChunkProviderTwilightForest(World world, long l, boolean flag) { - stoneNoise = new double[256]; - caveGenerator = new TFGenCaves(); - - majorFeatureGenerator = new MapGenTFMajorFeature(); - hollowTreeGenerator = new MapGenTFHollowTree(); - - ravineGenerator = new TFGenRavine(); - unusedIntArray32x32 = new int[32][32]; - worldObj = world; - rand = new Random(l); - //noiseGen1 = new NoiseGeneratorOctaves(rand, 16); - //noiseGen2 = new NoiseGeneratorOctaves(rand, 16); - //noiseGen3 = new NoiseGeneratorOctaves(rand, 8); - noiseGen4 = new NoiseGeneratorOctaves(rand, 4); - noiseGen5 = new NoiseGeneratorOctaves(rand, 10); - noiseGen6 = new NoiseGeneratorOctaves(rand, 16); - mobSpawnerNoise = new NoiseGeneratorOctaves(rand, 8); - - - this.field_147435_p = world.getWorldInfo().getTerrainType(); - this.field_147431_j = new NoiseGeneratorOctaves(this.rand, 16); - this.field_147432_k = new NoiseGeneratorOctaves(this.rand, 16); - this.field_147429_l = new NoiseGeneratorOctaves(this.rand, 8); - this.field_147430_m = new NoiseGeneratorPerlin(this.rand, 4); - - this.terrainCalcs = new double[825]; - this.parabolicField = new float[25]; - - for (int j = -2; j <= 2; ++j) - { - for (int k = -2; k <= 2; ++k) - { - float f = 10.0F / MathHelper.sqrt_float((float)(j * j + k * k) + 0.2F); - this.parabolicField[j + 2 + (k + 2) * 5] = f; - } - } - } - - @Override - public Chunk provideChunk(int cx, int cz) { - rand.setSeed(cx * 0x4f9939f508L + cz * 0x1ef1565bd5L); - Block blockStorage[] = new Block[16 * 16 * TFWorld.CHUNKHEIGHT]; - byte metaStorage[] = new byte[16 * 16 * TFWorld.CHUNKHEIGHT]; - generateTerrain2(cx, cz, blockStorage); - - squishTerrain(blockStorage); - - addDarkForestCanopy2(cx, cz, blockStorage, metaStorage); - biomesForGeneration = worldObj.getWorldChunkManager().loadBlockGeneratorData(biomesForGeneration, cx * 16, cz * 16, 16, 16); - addGlaciers(cx, cz, blockStorage, metaStorage, biomesForGeneration); - deformTerrainForFeature(cx, cz, blockStorage, metaStorage); - replaceBlocksForBiome(cx, cz, blockStorage, metaStorage, biomesForGeneration); - caveGenerator.func_151539_a(this, worldObj, cx, cz, blockStorage); - ravineGenerator.func_151539_a(this, worldObj, cx, cz, blockStorage); - // fake byte array - Block[] fake = new Block[0]; - - majorFeatureGenerator.func_151539_a(this, worldObj, cx, cz, fake); - hollowTreeGenerator.func_151539_a(this, worldObj, cx, cz, fake); - - Chunk chunk = new Chunk(worldObj, blockStorage, metaStorage, cx, cz); - - // load in biomes, to prevent striping?! - byte[] chunkBiomes = chunk.getBiomeArray(); - for (int i = 0; i < chunkBiomes.length; ++i) { - chunkBiomes[i] = (byte) this.biomesForGeneration[i].biomeID; - } - - chunk.generateSkylightMap(); - - return chunk; - } - - public void generateTerrain2(int chunkX, int chunkZ, Block[] blockStorage) - { - byte seaLevel = 63; - this.biomesForGeneration = this.worldObj.getWorldChunkManager().getBiomesForGeneration(this.biomesForGeneration, chunkX * 4 - 2, chunkZ * 4 - 2, 10, 10); - this.makeLandPerBiome2(chunkX * 4, 0, chunkZ * 4); - - for (int k = 0; k < 4; ++k) - { - int l = k * 5; - int i1 = (k + 1) * 5; - - for (int j1 = 0; j1 < 4; ++j1) - { - int k1 = (l + j1) * 33; - int l1 = (l + j1 + 1) * 33; - int i2 = (i1 + j1) * 33; - int j2 = (i1 + j1 + 1) * 33; - - for (int k2 = 0; k2 < 32; ++k2) - { - double d0 = 0.125D; - double d1 = this.terrainCalcs[k1 + k2]; - double d2 = this.terrainCalcs[l1 + k2]; - double d3 = this.terrainCalcs[i2 + k2]; - double d4 = this.terrainCalcs[j2 + k2]; - double d5 = (this.terrainCalcs[k1 + k2 + 1] - d1) * d0; - double d6 = (this.terrainCalcs[l1 + k2 + 1] - d2) * d0; - double d7 = (this.terrainCalcs[i2 + k2 + 1] - d3) * d0; - double d8 = (this.terrainCalcs[j2 + k2 + 1] - d4) * d0; - - for (int l2 = 0; l2 < 8; ++l2) - { - double d9 = 0.25D; - double d10 = d1; - double d11 = d2; - double d12 = (d3 - d1) * d9; - double d13 = (d4 - d2) * d9; - - for (int i3 = 0; i3 < 4; ++i3) - { - int j3 = i3 + k * 4 << 12 | 0 + j1 * 4 << 8 | k2 * 8 + l2; - short short1 = 256; - j3 -= short1; - double d14 = 0.25D; - double d16 = (d11 - d10) * d14; - double d15 = d10 - d16; - - for (int k3 = 0; k3 < 4; ++k3) - { - if ((d15 += d16) > 0.0D) - { - blockStorage[j3 += short1] = Blocks.stone; - } - else if (k2 * 8 + l2 < seaLevel) - { - blockStorage[j3 += short1] = Blocks.water; - } - else - { - blockStorage[j3 += short1] = null; - } - } - - d10 += d12; - d11 += d13; - } - - d1 += d5; - d2 += d6; - d3 += d7; - d4 += d8; - } - } - } - } - } - - private void makeLandPerBiome2(int x, int zero, int z) - { - - this.field_147426_g = this.noiseGen6.generateNoiseOctaves(this.field_147426_g, x, z, 5, 5, 200.0D, 200.0D, 0.5D); - this.field_147427_d = this.field_147429_l.generateNoiseOctaves(this.field_147427_d, x, zero, z, 5, 33, 5, 8.555150000000001D, 4.277575000000001D, 8.555150000000001D); - this.field_147428_e = this.field_147431_j.generateNoiseOctaves(this.field_147428_e, x, zero, z, 5, 33, 5, 684.412D, 684.412D, 684.412D); - this.field_147425_f = this.field_147432_k.generateNoiseOctaves(this.field_147425_f, x, zero, z, 5, 33, 5, 684.412D, 684.412D, 684.412D); - int terrainIndex = 0; - int noiseIndex = 0; - - for (int ax = 0; ax < 5; ++ax) - { - for (int az = 0; az < 5; ++az) - { - float totalVariation = 0.0F; - float totalHeight = 0.0F; - float totalFactor = 0.0F; - byte two = 2; - BiomeGenBase biomegenbase = this.biomesForGeneration[ax + 2 + (az + 2) * 10]; - - for (int ox = -two; ox <= two; ++ox) - { - for (int oz = -two; oz <= two; ++oz) - { - BiomeGenBase biomegenbase1 = this.biomesForGeneration[ax + ox + 2 + (az + oz + 2) * 10]; - float rootHeight = biomegenbase1.rootHeight; - float heightVariation = biomegenbase1.heightVariation; - - if (this.field_147435_p == WorldType.AMPLIFIED && rootHeight > 0.0F) - { - rootHeight = 1.0F + rootHeight * 2.0F; - heightVariation = 1.0F + heightVariation * 4.0F; - } - - float heightFactor = this.parabolicField[ox + 2 + (oz + 2) * 5] / (rootHeight + 2.0F); - - if (biomegenbase1.rootHeight > biomegenbase.rootHeight) - { - heightFactor /= 2.0F; - } - - totalVariation += heightVariation * heightFactor; - totalHeight += rootHeight * heightFactor; - totalFactor += heightFactor; - } - } - - totalVariation /= totalFactor; - totalHeight /= totalFactor; - totalVariation = totalVariation * 0.9F + 0.1F; - totalHeight = (totalHeight * 4.0F - 1.0F) / 8.0F; - double terrainNoise = this.field_147426_g[noiseIndex] / 8000.0D; - - if (terrainNoise < 0.0D) - { - terrainNoise = -terrainNoise * 0.3D; - } - - terrainNoise = terrainNoise * 3.0D - 2.0D; - - if (terrainNoise < 0.0D) - { - terrainNoise /= 2.0D; - - if (terrainNoise < -1.0D) - { - terrainNoise = -1.0D; - } - - terrainNoise /= 1.4D; - terrainNoise /= 2.0D; - } - else - { - if (terrainNoise > 1.0D) - { - terrainNoise = 1.0D; - } - - terrainNoise /= 8.0D; - } - - ++noiseIndex; - double heightCalc = (double)totalHeight; - double variationCalc = (double)totalVariation; - heightCalc += terrainNoise * 0.2D; - heightCalc = heightCalc * 8.5D / 8.0D; - double d5 = 8.5D + heightCalc * 4.0D; - - for (int ay = 0; ay < 33; ++ay) - { - double d6 = ((double)ay - d5) * 12.0D * 128.0D / 256.0D / variationCalc; - - if (d6 < 0.0D) - { - d6 *= 4.0D; - } - - double d7 = this.field_147428_e[terrainIndex] / 512.0D; - double d8 = this.field_147425_f[terrainIndex] / 512.0D; - double d9 = (this.field_147427_d[terrainIndex] / 10.0D + 1.0D) / 2.0D; - double terrainCalc = MathHelper.denormalizeClamp(d7, d8, d9) - d6; - - if (ay > 29) - { - double d11 = (double)((float)(ay - 29) / 3.0F); - terrainCalc = terrainCalc * (1.0D - d11) + -10.0D * d11; - } - - this.terrainCalcs[terrainIndex] = terrainCalc; - ++terrainIndex; - } - } - } - } - - - - /** - * Crush the terrain to half the height - */ - private void squishTerrain(Block[] blockStorage) { - int squishHeight = TFWorld.MAXHEIGHT / 2; - - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - for (int y = 0; y < TFWorld.CHUNKHEIGHT; y++) { - int index = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | y; - - if (y < squishHeight) { - int twiceIndex = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | (y * 2 + 1); - blockStorage[index] = blockStorage[twiceIndex]; - } else { - blockStorage[index] = Blocks.air; - } - } - } - } - } - - /** - * Replaces the stone that was placed in with blocks that match the biome - */ - public void replaceBlocksForBiome(int chunkX, int chunkZ, Block[] blockStorage, byte[] metaStorage, BiomeGenBase[] biomes) - { - ChunkProviderEvent.ReplaceBiomeBlocks event = new ChunkProviderEvent.ReplaceBiomeBlocks(this, chunkX, chunkZ, blockStorage, biomes); - MinecraftForge.EVENT_BUS.post(event); - if (event.getResult() == Result.DENY) return; - - double d0 = 0.03125D; - this.stoneNoise = this.field_147430_m.func_151599_a(this.stoneNoise, (double)(chunkX * 16), (double)(chunkZ * 16), 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D); - - for (int z = 0; z < 16; ++z) - { - for (int x = 0; x < 16; ++x) - { - BiomeGenBase biomegenbase = biomes[x + z * 16]; - biomegenbase.genTerrainBlocks(this.worldObj, this.rand, blockStorage, metaStorage, chunkX * 16 + z, chunkZ * 16 + x, this.stoneNoise[x + z * 16]); - } - } - } - - @Override - public Chunk loadChunk(int i, int j) { - return provideChunk(i, j); - } - - /** - * Raises up and hollows out the hollow hills. - * - * @param cx - * @param cz - * @param blockStorage - * @param metaStorage - */ - public void deformTerrainForFeature(int cx, int cz, Block[] blockStorage, byte[] metaStorage) { - // what feature are we near? - TFFeature nearFeature = TFFeature.getNearestFeature(cx, cz, worldObj); - if (!nearFeature.isTerrainAltered) { - // well that was easy. - return; - } - - int[] nearCenter = TFFeature.getNearestCenter(cx, cz, worldObj); - - int hx = nearCenter[0]; - int hz = nearCenter[1]; - - if (nearFeature == TFFeature.trollCave) { - // troll cloud, more like - deformTerrainForTrollCloud2(blockStorage, metaStorage, nearFeature, cx, cz, hx, hz); - } - - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - int dx = x - hx; - int dz = z - hz; - - if (nearFeature == TFFeature.hill1 || nearFeature == TFFeature.hill2 || nearFeature == TFFeature.hill3 || nearFeature == TFFeature.hydraLair) { - // hollow hills - int hdiam = ((nearFeature.size * 2 + 1) * 16); - int dist = (int) Math.sqrt(dx * dx + dz * dz); - int hheight = (int) (Math.cos((float)dist / (float)hdiam * Math.PI) * ((float)hdiam / 3F)); - - raiseHills(blockStorage, nearFeature, hdiam, x, z, dx, dz, hheight); - } else if (nearFeature == TFFeature.hedgeMaze || nearFeature == TFFeature.nagaCourtyard || nearFeature == TFFeature.questGrove) { - // hedge mazes, naga arena - flattenTerrainForFeature(blockStorage, nearFeature, x, z, dx, dz); - } else if (nearFeature == TFFeature.yetiCave) { - // yeti lairs are square - deformTerrainForYetiLair(blockStorage, nearFeature, x, z, dx, dz); - } else if (nearFeature == TFFeature.trollCave) { - // troll cloud, more like - //deformTerrainForTrollCloud(blockStorage, metaStorage, nearFeature, x, z, dx, dz); - } - } - } - - // done! - } - - private void raiseHills(Block[] storage, TFFeature nearFeature, int hdiam, int x, int z, int dx, int dz, int hillHeight) { - int newGround = -1; - boolean foundGroundLevel = false; - - // raise the hill - for (int y = 0; y < TFWorld.CHUNKHEIGHT; y++) { - int index = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | y; - Block currentTerrain = storage[index]; - if (currentTerrain != Blocks.stone && !foundGroundLevel) { - // we found the top of the stone layer - newGround = y + hillHeight; - - foundGroundLevel = true; - } - if (foundGroundLevel && y <= newGround) { - storage[index] = Blocks.stone; - } - } - // add the hollow part. Also turn water into stone below that - int hollow = hillHeight - 4 - nearFeature.size; - - // hydra lair has a piece missing - if (nearFeature == TFFeature.hydraLair) { - int mx = dx + 16; - int mz = dz + 16; - int mdist = (int) Math.sqrt(mx * mx + mz * mz); - int mheight = (int) (Math.cos(mdist / (hdiam / 1.5) * Math.PI) * (hdiam / 1.5)); - - hollow = Math.max(mheight - 4, hollow); - } - - if (hollow < 0) { - hollow = 0; - } - - for (int y = 0; y < TFWorld.CHUNKHEIGHT; y++) { - int index = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | y; - // put a base on hills that go over open space or water - if (hillHeight > 0 && y < TFWorld.SEALEVEL && storage[index] != Blocks.stone) { - storage[index] = Blocks.stone; - } - // hollow out the hollow parts - int hollowFloor = TFWorld.SEALEVEL - 3 - (hollow / 8); - if (nearFeature == TFFeature.hydraLair) { - // different floor - hollowFloor = TFWorld.SEALEVEL; - } - if (y > hollowFloor && y < hollowFloor + hollow) { - storage[index] = Blocks.air; - } - } - } - - private void flattenTerrainForFeature(Block[] storage, TFFeature nearFeature, int x, int z, int dx, int dz) { - int oldGround; - int newGround; - float squishfactor = 0; - int mazeheight = TFWorld.SEALEVEL + 1; - int FEATUREBOUNDRY = (nearFeature.size * 2 + 1) * 8 - 8; - - if (dx <= -FEATUREBOUNDRY) { - squishfactor = (-dx - FEATUREBOUNDRY) / 8.0f; - } - - if (dx >= FEATUREBOUNDRY) { - squishfactor = (dx - FEATUREBOUNDRY) / 8.0f; - } - if (dz <= -FEATUREBOUNDRY) { - squishfactor = Math.max(squishfactor, (-dz - FEATUREBOUNDRY) / 8.0f); - } - - if (dz >= FEATUREBOUNDRY) { - squishfactor = Math.max(squishfactor, (dz - FEATUREBOUNDRY) / 8.0f); - } - - if (squishfactor > 0) { - // blend the old terrain height to arena height - newGround = -1; - - for (int y = 0; y <= 127; y++) { - int index = (x * 16 + z) * TFWorld.CHUNKHEIGHT + y; - Block currentTerrain = storage[index]; - if (currentTerrain == Blocks.stone) { - // we're still in ground - continue; - } else { - if (newGround == -1) { - // we found the lowest chunk of earth - oldGround = y; - mazeheight += ((oldGround - mazeheight) * squishfactor); - - newGround = oldGround; - } - } - } - } - - // sets the groundlevel to the mazeheight - for (int y = 0; y <= 127; y++) { - int index = (x * 16 + z) * TFWorld.CHUNKHEIGHT + y; - if (y < mazeheight && (storage[index] == Blocks.air || storage[index] == Blocks.water)) { - storage[index] = Blocks.stone; - } - if (y >= mazeheight && storage[index] != Blocks.water) { - storage[index] = Blocks.air; - } - } - } - - private void deformTerrainForYetiLair(Block[] storage, TFFeature nearFeature, int x, int z, int dx, int dz) { - int oldGround; - int newGround; - float squishfactor = 0; - int topHeight = TFWorld.SEALEVEL + 24; - int outerBoundry = (nearFeature.size * 2 + 1) * 8 - 8; - - // outer boundry - if (dx <= -outerBoundry) { - squishfactor = (-dx - outerBoundry) / 8.0f; - } - - if (dx >= outerBoundry) { - squishfactor = (dx - outerBoundry) / 8.0f; - } - if (dz <= -outerBoundry) { - squishfactor = Math.max(squishfactor, (-dz - outerBoundry) / 8.0f); - } - - if (dz >= outerBoundry) { - squishfactor = Math.max(squishfactor, (dz - outerBoundry) / 8.0f); - } - - // inner boundry - int caveBoundry = (nearFeature.size * 2) * 8 - 8; - int hollowCeiling = TFWorld.SEALEVEL + 16; - - int offset = Math.min(Math.abs(dx), Math.abs(dz)); - hollowCeiling = (TFWorld.SEALEVEL + 40) - (offset * 4); - - // center square cave - if (dx >= -caveBoundry && dz >= -caveBoundry && dx <= caveBoundry && dz <= caveBoundry) { - hollowCeiling = TFWorld.SEALEVEL + 16; - } - - // slope ceiling slightly - hollowCeiling -= (offset / 6); - - // max out ceiling 8 blocks from roof - hollowCeiling = Math.min(hollowCeiling, TFWorld.SEALEVEL + 16); - - // floor, also with slight slope - int hollowFloor = TFWorld.SEALEVEL - 1 + (offset / 6); - - if (squishfactor > 0) { - // blend the old terrain height to arena height - newGround = -1; - - for (int y = 0; y <= 127; y++) { - int index = (x * 16 + z) * TFWorld.CHUNKHEIGHT + y; - Block currentTerrain = storage[index]; - if (currentTerrain == Blocks.stone) { - // we're still in ground - continue; - } else { - if (newGround == -1) { - // we found the lowest chunk of earth - oldGround = y; - topHeight += ((oldGround - topHeight) * squishfactor); - - hollowFloor += ((oldGround - hollowFloor) * squishfactor); - - newGround = oldGround; - } - } - } - } - - // carve the cave into the stone - for (int y = 0; y <= 127; y++) { - int index = (x * 16 + z) * TFWorld.CHUNKHEIGHT + y; - - // add stone - if (y < topHeight && (storage[index] == null || storage[index] == Blocks.air || storage[index] == Blocks.water)) { - storage[index] = Blocks.stone; - } - - // hollow out inside - if (y > hollowFloor && y < hollowCeiling) { - storage[index] = Blocks.air; - } - - // ice floor - if (y == hollowFloor && y < hollowCeiling && y < TFWorld.SEALEVEL + 3) { - storage[index] = Blocks.packed_ice; - } - } - } - - private void deformTerrainForTrollCloud(Block[] storage, byte[] metaStorage, TFFeature nearFeature, int x, int z, int dx, int dz) { - int y = 164; - - int index = (x * 16 + z) * TFWorld.CHUNKHEIGHT + y; - - - // make 4x4 blocks of cloud - - int bx = dx >> 2; - int bz = dz >> 2; - - - double dist = Math.sqrt(bx * bx + bz * bz); - - float pr = pseudoRand(x >> 2, z >> 2); - - //System.out.println("pr = " + pr + ", /18 = " + (dist / 18F)); - System.out.println("pr = " + pr + ", dist = " + dist + "dx = " + dx + " dz = " + dz); - - double cv = (dist - 9F) - (pr * 4F); - - if (dist < 9 || cv < 0.05F) { - storage[index] = Blocks.stained_glass; - storage[index - 1] = Blocks.quartz_block; - storage[index - 2] = Blocks.quartz_block; - storage[index - 3] = Blocks.quartz_block; - storage[index - 4] = Blocks.stained_glass; - } else if (dist < 10 || cv < 1F) { - storage[index - 1] = Blocks.stained_glass; - storage[index - 2] = Blocks.stained_glass; - storage[index - 3] = Blocks.stained_glass; - } - - } - - - private void deformTerrainForTrollCloud2(Block[] storage, byte[] metaStorage, TFFeature nearFeature, int cx, int cz, int hx, int hz) { - for (int bx = 0; bx < 4; bx++) { - for (int bz = 0; bz < 4; bz++) { - int dx = (bx * 4) - hx - 2; - int dz = (bz * 4) - hz - 2; - - // generate several centers for other clouds - int regionX = (cx + 8) >> 4; - int regionZ = (cx + 8) >> 4; - - long seed = (long)(regionX * 3129871) ^ (long)regionZ * 116129781L; - seed = seed * seed * 42317861L + seed * 7L; - - int num0 = (int) (seed >> 12 & 3L); - int num1 = (int) (seed >> 15 & 3L); - int num2 = (int) (seed >> 18 & 3L); - int num3 = (int) (seed >> 21 & 3L); - int num4 = (int) (seed >> 9 & 3L); - int num5 = (int) (seed >> 6 & 3L); - int num6 = (int) (seed >> 3 & 3L); - int num7 = (int) (seed >> 0 & 3L); - - int dx2 = dx + (num0 * 5) - (num1 * 4); - int dz2 = dz + (num2 * 4) - (num3 * 5); - int dx3 = dx + (num4 * 5) - (num5 * 4); - int dz3 = dz + (num6 * 4) - (num7 * 5); - - // take the minimum distance to any center - double dist0 = Math.sqrt(dx * dx + dz * dz) / 4.0; - double dist2 = Math.sqrt(dx2 * dx2 + dz2 * dz2) / 3.5; - double dist3 = Math.sqrt(dx3 * dx3 + dz3 * dz3) / 4.5; - - double dist = Math.min(dist0, Math.min(dist2, dist3)); - - // make a random float - float pr = worldObj.rand.nextFloat(); - double cv = (dist - 7F) - (pr * 3.0F); - - //System.out.println("pr = " + pr + ", dist = " + dist + ", dx = " + dx + ", dz = " + dz); - - // randomize depth and height - int y = 166; - int depth = 4; - - if (pr < 0.1F) { - y++; - } - if (pr > 0.6F) { - depth++; - } - if (pr > 0.9F) { - depth++; - } - - // generate cloud - for (int sx = 0; sx < 4; sx++) { - for (int sz = 0; sz < 4; sz++) { - int index = ((bx * 4 + sx) * 16 + (bz * 4 + sz)) * TFWorld.CHUNKHEIGHT + y; - - if (dist < 7 || cv < 0.05F) { - storage[index] = TFBlocks.wispyCloud; - for (int d = 1; d < depth; d++) { - storage[index - d] = TFBlocks.fluffyCloud; - } - storage[index - depth] = TFBlocks.wispyCloud; - } else if (dist < 8 || cv < 1F) { - for (int d = 1; d < depth; d++) { - storage[index - d] = TFBlocks.wispyCloud; - } - } - } - } - } - } - } - - private float pseudoRand(int bx, int bz) { - Random rand = new Random(this.worldObj.getSeed() + (bx * 321534781) ^ (bz * 756839)); - rand.setSeed(rand.nextLong()); - return rand.nextFloat(); - } - - /** - * Adds glaciers onto the map - * - * @param chunkX - * @param chunkZ - * @param blocks - */ - public void addGlaciers(int chunkX, int chunkZ, Block blocks[], byte meta[], BiomeGenBase biomes[]) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - BiomeGenBase biome = biomes[x & 15 | (z & 15) << 4]; - if (biome == TFBiomeBase.glacier) { - // find the (current) top block - int topLevel = -1; - for (int y = 127; y >= 0; y--) { - // look at where we are - int index = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | y; - Block currentBlock = blocks[index]; - if (currentBlock == Blocks.stone) { - topLevel = y; - // make that block gravel - blocks[index] = Blocks.gravel; - break; - } - } - - // raise the glacier from that top block - int gHeight = 32; - int gTop = topLevel + gHeight + 1; - - for (int y = topLevel + 1; y <= gTop && y < 128; y++) { - int index = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | y; - blocks[index] = Blocks.ice; - } - } - } - } - } - - /** - * Adds dark forest canopy. This version uses the "unzoomed" array of biomes used in land generation to determine how many of the nearby blocks are dark forest - */ - public void addDarkForestCanopy2(int chunkX, int chunkZ, Block blocks[], byte meta[]) { - - - int[] thicks = new int[5 * 5]; - - for (int z = 0; z < 5; z++) { - for (int x = 0; x < 5; x++) { - - for (int bx = -1 ; bx <= 1; bx++) { - for (int bz = -1; bz <= 1; bz++) { - BiomeGenBase biome = biomesForGeneration[x + bx + 2 + (z + bz + 2) * (10)]; - - if (biome == TFBiomeBase.darkForest || biome == TFBiomeBase.darkForestCenter) { - thicks[x + z * 5]++; - } - } - } - } - } - - - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - - int qx = x / 4; - int qz = z / 4; - - float xweight = (x % 4) * 0.25F + 0.125F; - float zweight = (z % 4) * 0.25F + 0.125F; - - float thickness = 0; - - thickness += thicks[qx + (qz) * 5] * (1F - xweight) * (1F - zweight); - thickness += thicks[qx + 1 + (qz) * 5] * (xweight) * (1F - zweight); - thickness += thicks[qx + (qz + 1) * 5] * (1F - xweight) * (zweight); - thickness += thicks[qx + 1 + (qz + 1) * 5] * (xweight) * (zweight); - - thickness -= 4; - - //int thickness = thicks[qz + (qz) * 5]; - - - - - - // make sure we're not too close to the tower - TFFeature nearFeature = TFFeature.getNearestFeature(chunkX, chunkZ, worldObj); - if (nearFeature == TFFeature.darkTower) { - // check for closeness - int[] nearCenter = TFFeature.getNearestCenter(chunkX, chunkZ, worldObj); - int hx = nearCenter[0]; - int hz = nearCenter[1]; - - int dx = x - hx; - int dz = z - hz; - int dist = (int) Math.sqrt(dx * dx + dz * dz); - - if (dist < 24) { - - thickness -= (24 - dist); - } - } - - boolean generateForest = thickness > 1; - - - if (generateForest) { - double d = 0.03125D; - stoneNoise = noiseGen4.generateNoiseOctaves(stoneNoise, chunkX * 16, chunkZ * 16, 0, 16, 16, 1, d * 2D, d * 2D, d * 2D); - - // find the (current) top block - int topLevel = -1; - for (int y = 127; y >= 0; y--) { - // look at where we are - int index = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | y; - // int index = (x * 16 + z) * 128 + y; - Block currentBlock = blocks[index]; - if (currentBlock == Blocks.water) { - // don't generate over water - break; - } - if (currentBlock == Blocks.stone) { - topLevel = y; - break; - } - } - - if (topLevel != -1) { - // just use the same noise generator as the terrain uses - // for stones - int noise = Math.min(3, (int) (stoneNoise[z & 15 | (x & 15) << 4] / 1.25f)); - - // manipulate top and bottom - int treeBottom = topLevel + 12 - (int)(thickness * 0.5F); - int treeTop = treeBottom + (int)(thickness * 1.5F); - - treeBottom -= noise; - - for (int y = treeBottom; y < treeTop; y++) { - int index = x * TFWorld.CHUNKHEIGHT * 16 | z * TFWorld.CHUNKHEIGHT | y; - blocks[index] = TFBlocks.darkleaves; - meta[index] = (byte) 0; - } - } - } - } - } - } - - @Override - public boolean chunkExists(int i, int j) { - return true; - } - - // int chunksGenerated = 0; - // long totalTime = 0; - - @Override - public void populate(IChunkProvider ichunkprovider, int chunkX, int chunkZ) { - //long startTime = System.nanoTime(); - - BlockFalling.fallInstantly = true; - int mapX = chunkX * 16; - int mapY = chunkZ * 16; - - BiomeGenBase biomeGen = worldObj.getBiomeGenForCoords(mapX + 16, mapY + 16); - - rand.setSeed(worldObj.getSeed()); - long l1 = (rand.nextLong() / 2L) * 2L + 1L; - long l2 = (rand.nextLong() / 2L) * 2L + 1L; - rand.setSeed(chunkX * l1 + chunkZ * l2 ^ worldObj.getSeed()); - - boolean disableFeatures = false; - - disableFeatures |= this.majorFeatureGenerator.generateStructuresInChunk(worldObj, rand, chunkX, chunkZ); - disableFeatures |= !TFFeature.getNearestFeature(chunkX, chunkZ, worldObj).areChunkDecorationsEnabled; - - hollowTreeGenerator.generateStructuresInChunk(worldObj, rand, chunkX, chunkZ); - - if (!disableFeatures && rand.nextInt(4) == 0 && biomeGen.theBiomeDecorator.generateLakes) { - int i1 = mapX + rand.nextInt(16) + 8; - int i2 = rand.nextInt(TFWorld.CHUNKHEIGHT); - int i3 = mapY + rand.nextInt(16) + 8; - (new WorldGenLakes(Blocks.water)).generate(worldObj, rand, i1, i2, i3); - } - - if (!disableFeatures && rand.nextInt(32) == 0) // reduced from 8 - { - int j1 = mapX + rand.nextInt(16) + 8; - int j2 = rand.nextInt(rand.nextInt(TFWorld.CHUNKHEIGHT - 8) + 8); - int j3 = mapY + rand.nextInt(16) + 8; - if (j2 < TFWorld.SEALEVEL || rand.nextInt(10) == 0) { - (new WorldGenLakes(Blocks.lava)).generate(worldObj, rand, j1, j2, j3); - } - } - for (int k1 = 0; k1 < 8; k1++) { - int k2 = mapX + rand.nextInt(16) + 8; - int k3 = rand.nextInt(TFWorld.CHUNKHEIGHT); - int l3 = mapY + rand.nextInt(16) + 8; - (new WorldGenDungeons()).generate(worldObj, rand, k2, k3, l3); - } - - biomeGen.decorate(worldObj, rand, mapX, mapY); - SpawnerAnimals.performWorldGenSpawning(worldObj, biomeGen, mapX + 8, mapY + 8, 16, 16, rand); - mapX += 8; - mapY += 8; - for (int i2 = 0; i2 < 16; i2++) { - for (int j3 = 0; j3 < 16; j3++) { - int j4 = worldObj.getPrecipitationHeight(mapX + i2, mapY + j3); - if (worldObj.isBlockFreezable(i2 + mapX, j4 - 1, j3 + mapY)) { - worldObj.setBlock(i2 + mapX, j4 - 1, j3 + mapY, Blocks.ice, 0, 2); - } - if (worldObj.func_147478_e(i2 + mapX, j4, j3 + mapY, true)) { - worldObj.setBlock(i2 + mapX, j4, j3 + mapY, Blocks.snow_layer, 0, 2); - } - } - } - - BlockFalling.fallInstantly = false; - - // long endTime = System.nanoTime(); - // long chunkTime = (endTime - startTime); - // - // System.out.println("Generated a chunk in " + chunkTime + - // " nanoseconds."); - // - // this.totalTime += chunkTime; - // this.chunksGenerated++; - // - // System.out.println("Generated " + chunksGenerated + - // " chunks in avg. " + (totalTime / chunksGenerated) + " nanos or " + - // ((int)( (totalTime / chunksGenerated / 1000000))) + " millis."); - } - - @Override - public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) { - return true; - } - - @Override - public boolean canSave() { - return true; - } - - @Override - public String makeString() { - return "TwilightLevelSource"; - } - - /** - * Returns a list of creatures of the specified type that can spawn at the - * given location. - * - * Twilight Forest varient! First check features, then only if we're not in - * a feature, check the biome. - */ - @SuppressWarnings("unchecked") - @Override - public List getPossibleCreatures(EnumCreatureType creatureType, int mapX, int mapY, int mapZ) { - // are the specified coordinates precicely in a feature? - TFFeature nearestFeature = TFFeature.getFeatureForRegion(mapX >> 4, mapZ >> 4, worldObj); - - if (nearestFeature != TFFeature.nothing) { - // if the feature is already conquered, no spawns - if (this.isStructureConquered(mapX, mapY, mapZ)) { - return null; - } - - // check the precise coords. - int spawnListIndex = this.majorFeatureGenerator.getSpawnListIndexAt(mapX, mapY, mapZ); - if (spawnListIndex >= 0) { - return nearestFeature.getSpawnableList(creatureType, spawnListIndex); - } - } - - BiomeGenBase biome = worldObj.getBiomeGenForCoords(mapX, mapZ); - - if (biome == null) { - return null; - } else if (mapY < TFWorld.SEALEVEL && creatureType == EnumCreatureType.monster && biome instanceof TFBiomeBase) { - // cave monsters! - return ((TFBiomeBase)biome).getUndergroundSpawnableList(); - } else { - return biome.getSpawnableList(creatureType); - } - } - - /** - * Is the block specified part of a structure bounding box? - */ - public boolean isBlockInStructureBB(int mapX, int mapY, int mapZ) { - return this.majorFeatureGenerator.hasStructureAt(mapX, mapY, mapZ); - } - - /** - * Find the structure at x, y, z, and set the "isConquered" flag - */ - public void setStructureConquered(int mapX, int mapY, int mapZ, boolean flag) { - this.majorFeatureGenerator.setStructureConquered(mapX, mapY, mapZ, flag); - } - - public StructureBoundingBox getSBBAt(int mapX, int mapY, int mapZ) { - return this.majorFeatureGenerator.getSBBAt(mapX, mapY, mapZ); - } - - public boolean isBlockProtected(int x, int y, int z) { - return this.majorFeatureGenerator.isBlockProtectedAt(x, y, z); - } - - public boolean isStructureConquered(int mapX, int mapY, int mapZ) { - return this.majorFeatureGenerator.isStructureConquered(mapX, mapY, mapZ); - } - - public boolean isStructureLocked(int mapX, int mapY, int mapZ, int lockIndex) { - return this.majorFeatureGenerator.isStructureLocked(mapX, mapY, mapZ, lockIndex); - } - - - public boolean isBlockInFullStructure(int x, int z) { - return this.majorFeatureGenerator.isBlockInFullStructure(x, z); - } - - public boolean isBlockNearFullStructure(int x, int z, int range) { - return this.majorFeatureGenerator.isBlockNearFullStructure(x, z, range); - } - - public StructureBoundingBox getFullSBBAt(int mapX, int mapZ) { - return this.majorFeatureGenerator.getFullSBBAt(mapX, mapZ); - } - - - public StructureBoundingBox getFullSBBNear(int mapX, int mapZ, int range) { - return this.majorFeatureGenerator.getFullSBBNear(mapX, mapZ, range); - - } - - @Override - public int getLoadedChunkCount() { - return 0; - } - - @Override - public void recreateStructures(int var1, int var2) { - majorFeatureGenerator.func_151539_a(this, worldObj, var1, var2, (Block[]) null); - hollowTreeGenerator.func_151539_a(this, worldObj, var1, var2, (Block[]) null); - } - - @Override - public boolean unloadQueuedChunks() { - return false; - } - - @Override - public void saveExtraData() { - } - - @Override - public ChunkPosition func_147416_a(World var1, String var2, int var3, - int var4, int var5) { - return null; - } - -} diff --git a/src/main/java/twilightforest/world/DirectChunkPrimer.java b/src/main/java/twilightforest/world/DirectChunkPrimer.java new file mode 100644 index 0000000000..2ed29c7886 --- /dev/null +++ b/src/main/java/twilightforest/world/DirectChunkPrimer.java @@ -0,0 +1,30 @@ +package twilightforest.world; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.world.chunk.ChunkPrimer; + +/** + * ChunkPrimer that stores states directly. + */ +public class DirectChunkPrimer extends ChunkPrimer { + + private static final IBlockState DEFAULT_STATE = Blocks.AIR.getDefaultState(); + + private final IBlockState[] states = new IBlockState[65536]; + + @Override + public IBlockState getBlockState(int x, int y, int z) { + IBlockState state = states[getBlockIndex(x, y, z)]; + return state == null ? DEFAULT_STATE : state; + } + + @Override + public void setBlockState(int x, int y, int z, IBlockState state) { + states[getBlockIndex(x, y, z)] = state; + } + + private static int getBlockIndex(int x, int y, int z) { + return x << 12 | z << 8 | y; + } +} diff --git a/src/main/java/twilightforest/world/MapGenTFHollowTree.java b/src/main/java/twilightforest/world/MapGenTFHollowTree.java index 9da8a94a8d..f4b8fbcc0d 100644 --- a/src/main/java/twilightforest/world/MapGenTFHollowTree.java +++ b/src/main/java/twilightforest/world/MapGenTFHollowTree.java @@ -1,118 +1,69 @@ package twilightforest.world; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.Callable; - -import net.minecraft.block.Block; -import net.minecraft.crash.CrashReport; -import net.minecraft.crash.CrashReportCategory; -import net.minecraft.util.ReportedException; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.ChunkPosition; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.gen.MapGenBase; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.structure.MapGenStructure; -import net.minecraft.world.gen.structure.StructureBoundingBox; -import net.minecraft.world.gen.structure.StructureComponent; import net.minecraft.world.gen.structure.StructureStart; +import twilightforest.TFConfig; import twilightforest.TFFeature; -import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; import twilightforest.structures.hollowtree.StructureTFHollowTreeStart; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; -public class MapGenTFHollowTree extends MapGenBase { - - //public static final int SPAWN_CHANCE = 48; - /** - * Used to store a list of all structures that have been recursively generated. Used so that during recursive - * generation, the structure generator can avoid generating structures that intersect ones that have already been - * placed. - */ - protected Map structureMap = new HashMap(); - - /** - * Generate recursively - */ - protected void func_151538_a(World world, final int chunkX, final int chunkZ, int centerX, int centerZ, Block[] blockData) { - if (!this.structureMap.containsKey(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(chunkX, chunkZ)))){ - this.rand.nextInt(); - - try { - if (this.canSpawnStructureAtCoords(chunkX, chunkZ)){ - StructureStart structurestart = this.getStructureStart(chunkX, chunkZ); - this.structureMap.put(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(chunkX, chunkZ)), structurestart); - } - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception preparing hollow tree"); - CrashReportCategory crashreportcategory = crashreport.makeCategory("Feature being prepared"); - crashreportcategory.addCrashSectionCallable("Is feature chunk", new Callable() { - private static final String __OBFID = "CL_00000506"; - public String call() { - return MapGenTFHollowTree.this.canSpawnStructureAtCoords(chunkX, chunkZ) ? "True" : "False"; - } - }); - crashreportcategory.addCrashSection("Chunk location", String.format("%d,%d", new Object[] {Integer.valueOf(chunkX), Integer.valueOf(chunkZ)})); - crashreportcategory.addCrashSectionCallable("Chunk pos hash", new Callable() { - private static final String __OBFID = "CL_00000507"; - public String call() { - return String.valueOf(ChunkCoordIntPair.chunkXZ2Int(chunkX, chunkZ)); - } - }); - crashreportcategory.addCrashSectionCallable("Structure type", new Callable() { - private static final String __OBFID = "CL_00000508"; - public String call() { - return MapGenTFHollowTree.this.getClass().getCanonicalName(); - } - }); - throw new ReportedException(crashreport); - } - } - - - - } - - - public boolean generateStructuresInChunk(World world, Random rand, int chunkX, int chunkZ) { - int mapX = (chunkX << 4) + 8; - int mapZ = (chunkZ << 4) + 8; - boolean flag = false; - - Iterator iterator = this.structureMap.values().iterator(); +public class MapGenTFHollowTree extends MapGenStructure { - while (iterator.hasNext()) - { - StructureStart structurestart = iterator.next(); + //public static final int SPAWN_CHANCE = 48; - if (structurestart.isSizeableStructure() && structurestart.getBoundingBox().intersectsWith(mapX, mapZ, mapX + 15, mapZ + 15)) - { - structurestart.generateStructure(world, rand, new StructureBoundingBox(mapX, mapZ, mapX + 15, mapZ + 15)); - flag = true; - } - } + private static final List> oakSpawnBiomes = Arrays.asList( + () -> TFBiomes.twilightForest, + () -> TFBiomes.denseTwilightForest, + () -> TFBiomes.mushrooms, + () -> TFBiomes.tfSwamp, + () -> TFBiomes.clearing, + () -> TFBiomes.oakSavanna, + () -> TFBiomes.fireflyForest, + () -> TFBiomes.deepMushrooms, + () -> TFBiomes.enchantedForest, + () -> TFBiomes.fireSwamp + ); - return flag; + @Override + public String getStructureName() { + return "TFHollowTree"; } - /** A list of all the biomes twilight oaks can spawn in. */ - public static List oakSpawnBiomes = Arrays.asList(new BiomeGenBase[] {TFBiomeBase.twilightForest, TFBiomeBase.twilightForest2, - TFBiomeBase.mushrooms, TFBiomeBase.tfSwamp, TFBiomeBase.clearing, TFBiomeBase.oakSavanna, - TFBiomeBase.fireflyForest, TFBiomeBase.deepMushrooms, TFBiomeBase.enchantedForest, TFBiomeBase.fireSwamp}); + @Nullable + @Override + public BlockPos getNearestStructurePos(World worldIn, BlockPos pos, boolean findUnexplored) { + this.world = worldIn; + return findNearestStructurePosBySpacing(worldIn, this, pos, 20, 11, 10387313, true, 100, findUnexplored); + } + @Override protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) { - return rand.nextInt(TwilightForestMod.twilightOakChance) == 0 && TFFeature.getNearestFeature(chunkX, chunkZ, worldObj).areChunkDecorationsEnabled - && this.worldObj.getWorldChunkManager().areBiomesViable(chunkX * 16 + 8, chunkZ * 16 + 8, 0, oakSpawnBiomes); + return rand.nextInt(TFConfig.performance.twilightOakChance) == 0 + && TFFeature.getNearestFeature(chunkX, chunkZ, world).areChunkDecorationsEnabled + && this.world.getBiomeProvider().areBiomesViable(chunkX * 16 + 8, chunkZ * 16 + 8, 0, getCurrentSpawnBiomes()); } + @Nonnull + @Override protected StructureStart getStructureStart(int chunkX, int chunkZ) { - return new StructureTFHollowTreeStart(worldObj, rand, chunkX, chunkZ); + return new StructureTFHollowTreeStart(world, rand, chunkX, chunkZ); + } + + private static List getCurrentSpawnBiomes() { + List biomes = new ArrayList<>(oakSpawnBiomes.size()); + for (Supplier biomeSupplier : oakSpawnBiomes) { + biomes.add(biomeSupplier.get()); + } + return biomes; } - } diff --git a/src/main/java/twilightforest/world/MapGenTFMajorFeature.java b/src/main/java/twilightforest/world/MapGenTFMajorFeature.java index b08cc8371b..15e5526914 100644 --- a/src/main/java/twilightforest/world/MapGenTFMajorFeature.java +++ b/src/main/java/twilightforest/world/MapGenTFMajorFeature.java @@ -1,87 +1,102 @@ package twilightforest.world; -import java.util.Collection; -import java.util.Iterator; - +import com.google.common.base.Predicates; +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.EntitySelectors; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.structure.MapGenStructure; -import net.minecraft.world.gen.structure.MapGenStructureData; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; import net.minecraft.world.gen.structure.StructureStart; import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.advancements.TFAdvancements; import twilightforest.structures.StructureTFComponent; -import twilightforest.structures.StructureTFMajorFeatureStart; -import cpw.mods.fml.common.ObfuscationReflectionHelper; +import twilightforest.structures.start.StructureStartTFFeatureAbstract; +import twilightforest.util.StructureBoundingBoxUtils; + +import javax.annotation.Nullable; + +import java.util.Collections; +import java.util.List; +import static twilightforest.TFFeature.NOTHING; public class MapGenTFMajorFeature extends MapGenStructure { - - public MapGenTFMajorFeature() {} - - @Override - protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) { - return TFFeature.getFeatureDirectlyAt(chunkX, chunkZ, worldObj).isStructureEnabled; - } - - @Override - protected StructureStart getStructureStart(int chunkX, int chunkZ) { - // fix rand - this.rand.setSeed(worldObj.getSeed()); + + private final TFFeature FEATURE; + + public MapGenTFMajorFeature() { + this.FEATURE = NOTHING; + } + + public MapGenTFMajorFeature(TFFeature feature) { + this.FEATURE = feature; + } + + @SuppressWarnings("ConstantConditions") + public TFFeature getFeature() { + return FEATURE != null ? FEATURE : NOTHING; + } + + @Override + public String getStructureName() { + return this.getFeature().name.toLowerCase(); + } + + @Nullable + @Override + public BlockPos getNearestStructurePos(World worldIn, BlockPos pos, boolean findUnexplored) { + this.world = worldIn; + return findNearestStructurePosBySpacing(worldIn, this, pos, 20, 11, 10387313, true, 100, findUnexplored); + } + + @Override + protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) { + return FEATURE.isStructureEnabled && TFFeature.getFeatureDirectlyAt(chunkX, chunkZ, world) == FEATURE; + } + + @Override + protected StructureStart getStructureStart(int chunkX, int chunkZ) { + // fix rand + this.rand.setSeed(world.getSeed()); long rand1 = this.rand.nextLong(); long rand2 = this.rand.nextLong(); - long chunkXr1 = (long)(chunkX) * rand1; - long chunkZr2 = (long)(chunkZ) * rand2; - this.rand.setSeed(chunkXr1 ^ chunkZr2 ^ worldObj.getSeed()); + long chunkXr1 = (long) (chunkX) * rand1; + long chunkZr2 = (long) (chunkZ) * rand2; + this.rand.setSeed(chunkXr1 ^ chunkZr2 ^ world.getSeed()); this.rand.nextInt(); - - return new StructureTFMajorFeatureStart(worldObj, rand, chunkX, chunkZ); - } - - - public String func_143025_a() - { - return "TFFeature"; + + //TFFeature feature = TFFeature.getFeatureDirectlyAt(chunkX, chunkZ, world); + + TwilightForestMod.LOGGER.debug("{} @ chunk [{}, {}]", this.FEATURE, chunkX, chunkZ); + + return this.getFeature().provideStructureStart(world, rand, chunkX, chunkZ); } - + /** * Returns true if the structure generator has generated a structure located at the given position tuple. */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public int getSpawnListIndexAt(int par1, int par2, int par3) - { - int highestFoundIndex = -1; - - Iterator startIterator = this.structureMap.values().iterator(); - - while (startIterator.hasNext()) - { - StructureStart start = (StructureStart)startIterator.next(); - - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(par1, par3, par1, par3)) - { - Iterator componentIterator = start.getComponents().iterator(); - - while (componentIterator.hasNext()) - { - StructureComponent component = (StructureComponent)componentIterator.next(); - - if (component != null && component.getBoundingBox() != null && component.getBoundingBox().isVecInside(par1, par2, par3)) - { - if (component instanceof StructureTFComponent) - { - StructureTFComponent tfComponent = (StructureTFComponent)component; - - //System.out.println("found a tfComponent at the specified coordinates. It's a " + tfComponent + ", index = " + tfComponent.spawnListIndex); - - if (tfComponent.spawnListIndex > highestFoundIndex) - { - highestFoundIndex = tfComponent.spawnListIndex; - } - } - else - { - return 0; - } + public int getSpawnListIndexAt(BlockPos pos) { + int highestFoundIndex = -1; + + for (StructureStart start : this.structureMap.values()) { + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(pos.getX(), pos.getZ(), pos.getX(), pos.getZ())) { + + for (StructureComponent component : start.getComponents()) { + if (component.getBoundingBox().isVecInside(pos)) { + if (component instanceof StructureTFComponent) { + StructureTFComponent tfComponent = (StructureTFComponent) component; + + if (tfComponent.spawnListIndex > highestFoundIndex) { + highestFoundIndex = tfComponent.spawnListIndex; + } + } else { + return 0; + } } } } @@ -90,194 +105,179 @@ public int getSpawnListIndexAt(int par1, int par2, int par3) return highestFoundIndex; } - /** - * Get the structure bounding box, if any, at the specified position - */ - @SuppressWarnings("unchecked") - public StructureBoundingBox getSBBAt(int mapX, int mapY, int mapZ) { - StructureBoundingBox boxFound = null; + // TODO: look at combining duplicate logic here + @Nullable + public List getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos) { - Iterator startIterator = this.structureMap.values().iterator(); + // if the feature is already conquered, no hostile spawns + if (creatureType == EnumCreatureType.MONSTER && isStructureConquered(pos)) { + return Collections.emptyList(); + } - while (startIterator.hasNext()) - { - StructureStart start = (StructureStart)startIterator.next(); + // check the precise coords. + int spawnListIndex = getSpawnListIndexAt(pos); + if (spawnListIndex >= 0) { + return getFeature().getSpawnableList(creatureType, spawnListIndex); + } - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(mapX, mapZ, mapX, mapZ)) - { - Iterator componentIterator = start.getComponents().iterator(); + return null; + } - while (componentIterator.hasNext()) - { - StructureComponent component = (StructureComponent)componentIterator.next(); + /** + * Get the structure bounding box, if any, at the specified position + */ + @Nullable + public StructureBoundingBox getSBBAt(BlockPos pos) { + StructureBoundingBox boxFound = null; - if (component.getBoundingBox().isVecInside(mapX, mapY, mapZ)) - { - boxFound = component.getBoundingBox(); + for (StructureStart start : this.structureMap.values()) { + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(pos.getX(), pos.getZ(), pos.getX(), pos.getZ())) { + + for (StructureComponent component : start.getComponents()) { + if (component.getBoundingBox().isVecInside(pos)) { + boxFound = component.getBoundingBox(); } } } } return boxFound; - } - - /** - * Is the block at the coordinates given a protected one? - */ - @SuppressWarnings("unchecked") - public boolean isBlockProtectedAt(int mapX, int mapY, int mapZ) { - boolean blockProtected = false; + } - Iterator startIterator = this.structureMap.values().iterator(); + public TFFeature getFeatureAt(BlockPos pos) { + for (StructureStart start : this.structureMap.values()) + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(pos.getX(), pos.getZ(), pos.getX(), pos.getZ())) + for (StructureComponent component : start.getComponents()) + if (component.getBoundingBox().isVecInside(pos)) + if (component instanceof StructureTFComponent) + return ((StructureTFComponent) component).getFeatureType(); + return NOTHING; + } - while (startIterator.hasNext()) { - StructureStart start = (StructureStart)startIterator.next(); + /** + * Is the block at the coordinates given a protected one? + */ + public boolean isBlockProtectedAt(BlockPos pos) { + boolean blockProtected = false; - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(mapX, mapZ, mapX, mapZ)) { - Iterator componentIterator = start.getComponents().iterator(); - - while (componentIterator.hasNext()) { - StructureComponent component = (StructureComponent)componentIterator.next(); - - if (component.getBoundingBox().isVecInside(mapX, mapY, mapZ)) { - - if (component instanceof StructureTFComponent) { - StructureTFComponent tfComp = (StructureTFComponent)component; - - blockProtected = tfComp.isComponentProtected(); - - } else { - blockProtected = true; - } - - // check if it's a twilight forest component, then check if it's protected + for (StructureStart start : this.structureMap.values()) { + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(pos.getX(), pos.getZ(), pos.getX(), pos.getZ())) { + + for (StructureComponent component : start.getComponents()) { + if (component.getBoundingBox().isVecInside(pos)) { + + if (component instanceof StructureTFComponent) { + StructureTFComponent tfComp = (StructureTFComponent) component; + + blockProtected = tfComp.isComponentProtected(); + + } else { + blockProtected = true; + } + + // check if it's a twilight forest component, then check if it's protected } } } } return blockProtected; + } + + public void setStructureConquered(BlockPos pos, boolean flag) { + for (StructureStart start : this.structureMap.values()) { + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(pos.getX(), pos.getZ(), pos.getX(), pos.getZ())) { + if (start instanceof StructureStartTFFeatureAbstract) { + StructureStartTFFeatureAbstract featureStart = (StructureStartTFFeatureAbstract) start; + featureStart.isConquered = flag; + this.structureData.writeInstance(featureStart.writeStructureComponentsToNBT(start.getChunkPosX(), start.getChunkPosZ()), start.getChunkPosX(), start.getChunkPosZ()); + this.structureData.setDirty(true); + if (flag) { + for (EntityPlayerMP player : getPlayersInsideStructure(start)) { + TFAdvancements.STRUCTURE_CLEARED.trigger(player, FEATURE.name); + } + } + } + } + } + } + + private List getPlayersInsideStructure(StructureStart start) { + return world.getPlayers(EntityPlayerMP.class, Predicates.and(EntitySelectors.IS_ALIVE, + p -> p.getEntityBoundingBox().intersects(StructureBoundingBoxUtils.toAABB(start.getBoundingBox())))); + } + + public boolean isStructureConquered(BlockPos pos) { + boolean conquered = false; + + for (StructureStart start : this.structureMap.values()) + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(pos.getX(), pos.getZ(), pos.getX(), pos.getZ())) + if (start instanceof StructureStartTFFeatureAbstract) + conquered = ((StructureStartTFFeatureAbstract) start).isConquered; + + return conquered; + } + + /** + * Check the lock at the specified lockIndex for the structure at the specified coords + */ + public boolean isStructureLocked(BlockPos pos, int lockIndex) { + boolean locked = false; + + for (StructureStart start : this.structureMap.values()) + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(pos.getX(), pos.getZ(), pos.getX(), pos.getZ())) + if (start instanceof StructureStartTFFeatureAbstract) + locked = ((StructureStartTFFeatureAbstract) start).isLocked(lockIndex); - } - - /** - * Mark the structure at the specified position as defeated - * @return - */ - @SuppressWarnings("unchecked") - public void setStructureConquered(int mapX, int mapY, int mapZ, boolean flag) { - - for (StructureStart start : (Collection)this.structureMap.values()) { - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(mapX, mapZ, mapX, mapZ)) { - if (start instanceof StructureTFMajorFeatureStart) { - - StructureTFMajorFeatureStart featureStart =(StructureTFMajorFeatureStart)start; - - //System.out.println("The data says that the conquered flag is " + featureStart.isConquered); - - - featureStart.isConquered = flag; - - MapGenStructureData data = ObfuscationReflectionHelper.getPrivateValue(MapGenStructure.class, this, "field_143029_e"); - - data.func_143043_a(featureStart.func_143021_a(start.func_143019_e(), start.func_143018_f()), start.func_143019_e(), start.func_143018_f()); - //System.out.println("Writing data"); - - data.setDirty(true); - - //System.out.println("Set the data as dirty"); - } - } - } - } - - @SuppressWarnings("unchecked") - public boolean isStructureConquered(int mapX, int mapY, int mapZ) { - - boolean conquered = false; - - for (StructureStart start : (Collection)this.structureMap.values()) { - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(mapX, mapZ, mapX, mapZ)) { - if (start instanceof StructureTFMajorFeatureStart) { - - conquered = ((StructureTFMajorFeatureStart)start).isConquered; - } - } - } - - return conquered; - } - - /** - * Check the lock at the specified lockIndex for the structure at the specified coords - */ - @SuppressWarnings("unchecked") - public boolean isStructureLocked(int mapX, int mapY, int mapZ, int lockIndex) { - - boolean locked = false; - - for (StructureStart start : (Collection)this.structureMap.values()) { - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(mapX, mapZ, mapX, mapZ)) { - if (start instanceof StructureTFMajorFeatureStart) { - - locked = ((StructureTFMajorFeatureStart)start).isLocked(lockIndex); - } - } - } - - return locked; - } - - /** - * Do the specified x & z coordinates intersect the full structure? - */ - @SuppressWarnings("unchecked") - public boolean isBlockInFullStructure(int mapX, int mapZ) { - for (StructureStart start : (Collection)this.structureMap.values()) { + return locked; + } + + /** + * Do the specified x & z coordinates intersect the full structure? + */ + public boolean isBlockInFullStructure(int mapX, int mapZ) { + for (StructureStart start : this.structureMap.values()) { if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(mapX, mapZ, mapX, mapZ)) { - return true; + return true; } - } - return false; - } - - /** - * Are the specified x & z coordinates close to a full structure? - */ - @SuppressWarnings("unchecked") - public boolean isBlockNearFullStructure(int mapX, int mapZ, int range) { + } + return false; + } + + /** + * Are the specified x & z coordinates close to a full structure? + */ + public boolean isBlockNearFullStructure(int mapX, int mapZ, int range) { StructureBoundingBox rangeBB = new StructureBoundingBox(mapX - range, mapZ - range, mapX + range, mapZ + range); - for (StructureStart start : (Collection)this.structureMap.values()) { - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(rangeBB)) { - return true; + for (StructureStart start : this.structureMap.values()) { + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(rangeBB)) { + return true; } - } - return false; - } - - /** - * Get full structure bounding box at the specified x, z coordinates. - */ - @SuppressWarnings("unchecked") - public StructureBoundingBox getFullSBBAt(int mapX, int mapZ) { - for (StructureStart start : (Collection)this.structureMap.values()) { + } + return false; + } + + /** + * Get full structure bounding box at the specified x, z coordinates. + */ + @Nullable + public StructureBoundingBox getFullSBBAt(int mapX, int mapZ) { + for (StructureStart start : this.structureMap.values()) { if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(mapX, mapZ, mapX, mapZ)) { - return start.getBoundingBox(); + return start.getBoundingBox(); } - } - return null; - } + } + return null; + } - @SuppressWarnings("unchecked") - public StructureBoundingBox getFullSBBNear(int mapX, int mapZ, int range) { + @Nullable + public StructureBoundingBox getFullSBBNear(int mapX, int mapZ, int range) { StructureBoundingBox rangeBB = new StructureBoundingBox(mapX - range, mapZ - range, mapX + range, mapZ + range); - for (StructureStart start : (Collection)this.structureMap.values()) { - if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(rangeBB)) { - return start.getBoundingBox(); + for (StructureStart start : this.structureMap.values()) { + if (start.isSizeableStructure() && start.getBoundingBox().intersectsWith(rangeBB)) { + return start.getBoundingBox(); } - } - return null; - - } + } + return null; + } } diff --git a/src/main/java/twilightforest/world/TFBiomeCache.java b/src/main/java/twilightforest/world/TFBiomeCache.java new file mode 100644 index 0000000000..af167759e7 --- /dev/null +++ b/src/main/java/twilightforest/world/TFBiomeCache.java @@ -0,0 +1,111 @@ +package twilightforest.world; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.biome.Biome; + +import java.util.ArrayList; +import java.util.List; + +/** + * Based on {@link net.minecraft.world.biome.BiomeCache}. + * This version allows specifying the grid size, and uses the alternate biome + * layer used in world generation. Used for magic maps, and supports a centred + * grid for this purpose. + */ +public class TFBiomeCache { + + private final Long2ObjectMap entryMap = new Long2ObjectOpenHashMap<>(); + private final List entries = new ArrayList<>(); + private final TFBiomeProvider provider; + private final int gridSize; + private final boolean offset; + private long lastCleanupTime; + + public TFBiomeCache(TFBiomeProvider provider, int gridSize, boolean offset) { + this.provider = provider; + this.gridSize = gridSize; + this.offset = offset; + } + + private final class Entry { + + final Biome[] biomes = new Biome[gridSize * gridSize]; + final int x, z; + long lastAccessTime; + + Entry(int x, int z) { + this.x = x; + this.z = z; + provider.getBiomesForGeneration(biomes, fromGrid(x), fromGrid(z), gridSize, gridSize, false); + } + } + + private Entry getEntry(int x, int z) { + + x = toGrid(x); + z = toGrid(z); + + long key = getKey(x, z); + Entry entry = this.entryMap.get(key); + + if (entry == null) { + + entry = new Entry(x, z); + this.entryMap.put(key, entry); + this.entries.add(entry); + } + + entry.lastAccessTime = MinecraftServer.getCurrentTimeMillis(); + return entry; + } + + public Biome[] getBiomes(int x, int z) { + return getEntry(x, z).biomes; + } + + public void cleanup() { + + long currentTime = MinecraftServer.getCurrentTimeMillis(); + long timeSinceCleanup = currentTime - this.lastCleanupTime; + + if (timeSinceCleanup > 7500L || timeSinceCleanup < 0L) { + + this.lastCleanupTime = currentTime; + + for (int i = 0; i < this.entries.size(); ++i) { + + Entry entry = this.entries.get(i); + long timeSinceAccess = currentTime - entry.lastAccessTime; + + if (timeSinceAccess > 30000L || timeSinceAccess < 0L) { + + this.entries.remove(i--); + long key = getKey(entry.x, entry.z); + this.entryMap.remove(key); + } + } + } + } + + public boolean isGridAligned(int x, int z, int width, int height) { + return width == gridSize && height == gridSize && gridOffset(x) == 0 && gridOffset(z) == 0; + } + + private int gridOffset(int n) { + return (n + (offset ? gridSize / 2 : 0)) % gridSize; + } + + private int toGrid(int n) { + return (n + (offset ? gridSize / 2 : 0)) / gridSize; + } + + private int fromGrid(int n) { + return n * gridSize - (offset ? gridSize / 2 : 0); + } + + private static long getKey(int x, int z) { + return Integer.toUnsignedLong(x) | Integer.toUnsignedLong(z) << 32; + } +} diff --git a/src/main/java/twilightforest/world/TFBiomeProvider.java b/src/main/java/twilightforest/world/TFBiomeProvider.java new file mode 100644 index 0000000000..95725d191f --- /dev/null +++ b/src/main/java/twilightforest/world/TFBiomeProvider.java @@ -0,0 +1,87 @@ +package twilightforest.world; + +import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeProvider; +import net.minecraft.world.gen.layer.GenLayer; +import net.minecraft.world.gen.layer.GenLayerSmooth; +import net.minecraft.world.gen.layer.GenLayerVoronoiZoom; +import net.minecraft.world.gen.layer.GenLayerZoom; +import twilightforest.biomes.TFBiomes; +import twilightforest.world.layer.GenLayerTFBiomeStabilize; +import twilightforest.world.layer.GenLayerTFBiomes; +import twilightforest.world.layer.GenLayerTFCompanionBiomes; +import twilightforest.world.layer.GenLayerTFKeyBiomes; +import twilightforest.world.layer.GenLayerTFRiverMix; +import twilightforest.world.layer.GenLayerTFStream; +import twilightforest.world.layer.GenLayerTFThornBorder; + +import java.util.Arrays; + +public class TFBiomeProvider extends BiomeProvider { + + private final TFBiomeCache mapCache; + + public TFBiomeProvider(World world) { + getBiomesToSpawnIn().clear(); + getBiomesToSpawnIn().add(TFBiomes.twilightForest); + getBiomesToSpawnIn().add(TFBiomes.denseTwilightForest); + getBiomesToSpawnIn().add(TFBiomes.clearing); + getBiomesToSpawnIn().add(TFBiomes.tfSwamp); + getBiomesToSpawnIn().add(TFBiomes.mushrooms); + + makeLayers(world.getSeed()); + mapCache = new TFBiomeCache(this, 512, true); + } + + private void makeLayers(long seed) { + GenLayer biomes = new GenLayerTFBiomes(1L); + biomes = new GenLayerTFKeyBiomes(1000L, biomes); + biomes = new GenLayerTFCompanionBiomes(1000L, biomes); + + biomes = new GenLayerZoom(1000L, biomes); + biomes = new GenLayerZoom(1001, biomes); + + biomes = new GenLayerTFBiomeStabilize(700L, biomes); + + biomes = new GenLayerTFThornBorder(500L, biomes); + + biomes = new GenLayerZoom(1002, biomes); + biomes = new GenLayerZoom(1003, biomes); + biomes = new GenLayerZoom(1004, biomes); + biomes = new GenLayerZoom(1005, biomes); + + GenLayer riverLayer = new GenLayerTFStream(1L, biomes); + riverLayer = new GenLayerSmooth(7000L, riverLayer); + biomes = new GenLayerTFRiverMix(100L, biomes, riverLayer); + + // do "voronoi" zoom + GenLayer genlayervoronoizoom = new GenLayerVoronoiZoom(10L, biomes); + + biomes.initWorldGenSeed(seed); + genlayervoronoizoom.initWorldGenSeed(seed); + + genBiomes = biomes; + biomeIndexLayer = genlayervoronoizoom; + } + + @Override + public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height) { + return getBiomesForGeneration(biomes, x, z, width, height, true); + } + + public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height, boolean useCache) { + // for grid-centred magic maps, get from map cache + if (useCache && mapCache.isGridAligned(x, z, width, height)) { + Biome[] cached = mapCache.getBiomes(x, z); + return Arrays.copyOf(cached, cached.length); + } + return super.getBiomesForGeneration(biomes, x, z, width, height); + } + + @Override + public void cleanupCache() { + mapCache.cleanup(); + super.cleanupCache(); + } +} diff --git a/src/main/java/twilightforest/world/TFGenBigMushgloom.java b/src/main/java/twilightforest/world/TFGenBigMushgloom.java deleted file mode 100644 index b67a3010e8..0000000000 --- a/src/main/java/twilightforest/world/TFGenBigMushgloom.java +++ /dev/null @@ -1,50 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import twilightforest.block.TFBlocks; -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - -public class TFGenBigMushgloom extends TFGenerator { - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - int height = 3 + rand.nextInt(2) + rand.nextInt(2); - - if (!this.isAreaSuitable(world, rand, x - 1, y, z - 1, 3, height, 3)) { - return false; - } - - Block blockUnder = world.getBlock(x, y - 1, z); - if (blockUnder != Blocks.dirt && blockUnder != Blocks.grass && blockUnder != Blocks.mycelium) { - return false; - } - - // generate! - for (int dy = 0; dy < height - 2; dy++) { - this.setBlockAndNotifyAdequately(world, x, y + dy, z, TFBlocks.hugeGloomBlock, 10); - } - - makeMushroomCap(world, x, z, y + (height - 2)); - if (rand.nextBoolean()) { - makeMushroomCap(world, x, z, y + (height - 1)); - } - - return true; - } - - private void makeMushroomCap(World world, int x, int z, int dy) { - this.setBlockAndNotifyAdequately(world, x - 1, dy, z - 1, TFBlocks.hugeGloomBlock, 1); - this.setBlockAndNotifyAdequately(world, x + 0, dy, z - 1, TFBlocks.hugeGloomBlock, 2); - this.setBlockAndNotifyAdequately(world, x + 1, dy, z - 1, TFBlocks.hugeGloomBlock, 3); - this.setBlockAndNotifyAdequately(world, x - 1, dy, z + 0, TFBlocks.hugeGloomBlock, 4); - this.setBlockAndNotifyAdequately(world, x + 0, dy, z + 0, TFBlocks.hugeGloomBlock, 5); - this.setBlockAndNotifyAdequately(world, x + 1, dy, z + 0, TFBlocks.hugeGloomBlock, 6); - this.setBlockAndNotifyAdequately(world, x - 1, dy, z + 1, TFBlocks.hugeGloomBlock, 7); - this.setBlockAndNotifyAdequately(world, x + 0, dy, z + 1, TFBlocks.hugeGloomBlock, 8); - this.setBlockAndNotifyAdequately(world, x + 1, dy, z + 1, TFBlocks.hugeGloomBlock, 9); - } - -} diff --git a/src/main/java/twilightforest/world/TFGenCanopyMushroom.java b/src/main/java/twilightforest/world/TFGenCanopyMushroom.java deleted file mode 100644 index 8123f9b7f2..0000000000 --- a/src/main/java/twilightforest/world/TFGenCanopyMushroom.java +++ /dev/null @@ -1,216 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.World; -import twilightforest.block.TFBlocks; - - -/** - * Makes large mushrooms with flat mushroom tops that provide a canopy for the forest - * - * @author Ben - * - */ -public class TFGenCanopyMushroom extends TFTreeGenerator { - - public TFGenCanopyMushroom() - { - this(false); - } - - public TFGenCanopyMushroom(boolean par1) - { - super(par1); - treeBlock = Blocks.red_mushroom_block; - treeMeta = 10; - branchMeta = 15; - leafBlock = Blocks.red_mushroom_block; - leafMeta = 5; - } - - @Override - public boolean generate(World world, Random random, int x, int y, int z) - { - // determine a height - int treeHeight = 12; - if (random.nextInt(3) == 0) { - treeHeight += random.nextInt(5); - - if (random.nextInt(8) == 0) { - treeHeight += random.nextInt(5); - } - } - - // check if we're on dirt or grass - Block blockUnder = world.getBlock(x, y - 1, z); - if(blockUnder != Blocks.grass && blockUnder != Blocks.dirt && blockUnder != Blocks.mycelium || y >= 256 - treeHeight - 1) - { - return false; - } - - - this.treeBlock = random.nextInt(3) == 0 ? Blocks.red_mushroom_block : Blocks.brown_mushroom_block; - this.leafBlock = treeBlock; - - //okay build a tree! Go up to the height - buildBranch(world, x, y, z, 0, treeHeight, 0, 0, true, random); - - // make 3-4 branches - int numBranches = 3 + random.nextInt(2); - double offset = random.nextDouble(); - for (int b = 0; b < numBranches; b++) - { - buildBranch(world, x, y, z, treeHeight - 5 + b, 9, 0.3 * b + offset, 0.2, false, random); - } - - return true; - } - - /** - * Build a branch with a flat blob of leaves at the end. - * - * @param height - * @param length - * @param angle - * @param tilt - */ - void buildBranch(World world, int x, int y, int z, int height, double length, double angle, double tilt, boolean trunk, Random treeRNG) - { - ChunkCoordinates src = new ChunkCoordinates(x, y + height, z); - ChunkCoordinates dest = translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); - - // constrain branch spread - if ((dest.posX - x) < -4) - { - dest.posX = x - 4; - } - if ((dest.posX - x) > 4) - { - dest.posX = x + 4; - } - if ((dest.posZ - z) < -4) - { - dest.posZ = z - 4; - } - if ((dest.posZ - z) > 4) - { - dest.posZ = z + 4; - } - - if (src.posX != dest.posX || src.posZ != dest.posZ) { - // branch - drawBresehnam(world, src.posX, src.posY, src.posZ, dest.posX, src.posY, dest.posZ, treeBlock, branchMeta); - drawBresehnam(world, dest.posX, src.posY + 1, dest.posZ, dest.posX, dest.posY - 1, dest.posZ, treeBlock, treeMeta); - } - else { - // trunk - drawBresehnam(world, src.posX, src.posY, src.posZ, dest.posX, dest.posY - 1, dest.posZ, treeBlock, treeMeta); - } - - // do this here until that bug with the lighting is fixed - if (trunk) { - // add a firefly (torch) to the trunk - addFirefly(world, x, y, z, 3 + treeRNG.nextInt(7), treeRNG.nextDouble()); - } - - drawMushroomCircle(world, dest.posX, dest.posY, dest.posZ, 4, leafBlock); - } - - /** - * Draw a flat blob (a circle?) of whatevs (I'm guessing... leaves). - * @param sx - * @param sy - * @param sz - * @param rad radius - * @param blockValue - * @param metaValue - * @param priority do we overwrite what's there? - */ - public void drawMushroomCircle(World world, int sx, int sy, int sz, int rad, Block blockValue) - { - // trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dz = 0; dz <= rad; dz++) - { - int dist = (int)(Math.max(dx, dz) + (Math.min(dx, dz) * 0.5)); - - //hack! I keep getting failing leaves at a certain position. - if (dx == 3 && dz == 3) { - dist = 6; - } - - // if we're inside the blob, fill it - if (dx == 0) { - // two! - if (dz < rad) { - setBlockAndMetadata(world, sx + 0, sy, sz + dz, blockValue, 5); - setBlockAndMetadata(world, sx + 0, sy, sz - dz, blockValue, 5); - } - else { - setBlockAndMetadata(world, sx + 0, sy, sz + dz, blockValue, 8); - setBlockAndMetadata(world, sx + 0, sy, sz - dz, blockValue, 2); - } - } - else if (dz == 0) { - // two! - if (dx < rad) { - setBlockAndMetadata(world, sx + dx, sy, sz + 0, blockValue, 5); - setBlockAndMetadata(world, sx - dx, sy, sz + 0, blockValue, 5); - } - else { - setBlockAndMetadata(world, sx + dx, sy, sz + 0, blockValue, 6); - setBlockAndMetadata(world, sx - dx, sy, sz + 0, blockValue, 4); - } - } - else if (dist < rad) { - // do four at a time for easiness! - setBlockAndMetadata(world, sx + dx, sy, sz + dz, blockValue, 5); - setBlockAndMetadata(world, sx + dx, sy, sz - dz, blockValue, 5); - setBlockAndMetadata(world, sx - dx, sy, sz + dz, blockValue, 5); - setBlockAndMetadata(world, sx - dx, sy, sz - dz, blockValue, 5); - } - else if (dist == rad) { - // do four at a time for easiness! - setBlockAndMetadata(world, sx + dx, sy, sz + dz, blockValue, 9); - setBlockAndMetadata(world, sx + dx, sy, sz - dz, blockValue, 3); - setBlockAndMetadata(world, sx - dx, sy, sz + dz, blockValue, 7); - setBlockAndMetadata(world, sx - dx, sy, sz - dz, blockValue, 1); - } - } - } - } - - - /** - * Add a firefly at the specified height and angle. - * - * @param height how far up the tree - * @param angle from 0 - 1 rotation around the tree - */ - private void addFirefly(World world, int x, int y, int z, int height, double angle) - { - int iAngle = (int)(angle * 4.0); - if (iAngle == 0) - { - setBlockAndMetadata(world, x + 1, y + height, z, TFBlocks.firefly, 0); - } - else if (iAngle == 1) - { - setBlockAndMetadata(world, x - 1, y + height, z, TFBlocks.firefly, 0); - } - else if (iAngle == 2) - { - setBlockAndMetadata(world, x, y + height, z + 1, TFBlocks.firefly, 0); - } - else if (iAngle == 3) - { - setBlockAndMetadata(world, x, y + height, z - 1, TFBlocks.firefly, 0); - } - } - -} diff --git a/src/main/java/twilightforest/world/TFGenCanopyOak.java b/src/main/java/twilightforest/world/TFGenCanopyOak.java deleted file mode 100644 index 65cfb9ddc1..0000000000 --- a/src/main/java/twilightforest/world/TFGenCanopyOak.java +++ /dev/null @@ -1,164 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.material.Material; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.World; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - -public class TFGenCanopyOak extends TFGenCanopyTree { - - public TFGenCanopyOak() - { - this(false); - } - - public TFGenCanopyOak(boolean par1) - { - super(par1); - this.treeBlock = TFBlocks.log; - this.treeMeta = 0; - this.branchMeta = 12; - this.leafBlock = TFBlocks.leaves; - this.leafMeta = 0; - this.rootBlock = TFBlocks.root; - this.rootMeta = BlockTFRoots.ROOT_META; - - } - - @Override - public boolean generate(World world, Random random, int x, int y, int z) - { - int treeHeight; - - // check if we're on dirt or grass - Material materialUnder = world.getBlock(x, y - 1, z).getMaterial(); - if ((materialUnder != Material.grass && materialUnder != Material.ground) || y >= TFWorld.MAXHEIGHT - 12) - { - return false; - } - - - // determine a height - treeHeight = minHeight; - if (random.nextInt(chanceAddFirstFive) == 0) { - treeHeight += random.nextInt(5); - - if (random.nextInt(chanceAddSecondFive) == 0) { - treeHeight += random.nextInt(5); - } - } - - //okay build a tree! Go up to the height - buildTrunk(world, x, y, z, treeHeight); - - // make 12 - 20 branches - int numBranches = 12 + random.nextInt(9); - float bangle = random.nextFloat(); - for (int b = 0; b < numBranches; b++) { - float btilt = 0.15F + (random.nextFloat() * 0.35F); - buildBranch(world, x, y, z, treeHeight - 10 + (b / 2), 5, bangle, btilt, false, random); - - bangle += (random.nextFloat() * 0.4F); - if (bangle > 1.0F) { - bangle -= 1.0F; - } - } - - makeRoots(world, random, x + 0, y, z + 0); - makeRoots(world, random, x + 1, y, z + 0); - makeRoots(world, random, x + 0, y, z + 1); - makeRoots(world, random, x + 1, y, z + 1); - - - return true; - } - - private void makeRoots(World world, Random random, int x, int y, int z) { - // root bulb - if (hasAirAround(world, x, y - 1, z)) { - this.setBlockAndMetadata(world, x, y - 1, z, treeBlock, treeMeta); - } - else { - this.setBlockAndMetadata(world, x, y - 1, z, rootBlock, rootMeta); - } - - // roots! - int numRoots = 1 + random.nextInt(2); - float offset = random.nextFloat(); - for (int b = 0; b < numRoots; b++) - { - buildRoot(world, x, y, z, offset, b); - } - } - - private void buildTrunk(World world, int sx, int sy, int sz, int treeHeight) { - for (int dy = 0; dy < treeHeight; dy++) { - this.setBlockAndMetadata(world, sx + 0, sy + dy, sz + 0, this.treeBlock, this.treeMeta); - this.setBlockAndMetadata(world, sx + 1, sy + dy, sz + 0, this.treeBlock, this.treeMeta); - this.setBlockAndMetadata(world, sx + 0, sy + dy, sz + 1, this.treeBlock, this.treeMeta); - this.setBlockAndMetadata(world, sx + 1, sy + dy, sz + 1, this.treeBlock, this.treeMeta); - } - - drawLeafBlob(world, sx + 0, sy + treeHeight, sz + 0, 3, leafBlock, leafMeta); - - } - - /** - * Build a branch with a flat blob of leaves at the end. - * - * @param height - * @param length - * @param angle - * @param tilt - */ - void buildBranch(World world, int x, int y, int z, int height, double length, double angle, double tilt, boolean trunk, Random treeRNG) - { - ChunkCoordinates src = new ChunkCoordinates(x, y + height, z); - ChunkCoordinates dest = translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); - - // constrain branch spread - int limit = 5; - if ((dest.posX - x) < -limit) - { - dest.posX = x - limit; - } - if ((dest.posX - x) > limit) - { - dest.posX = x + limit; - } - if ((dest.posZ - z) < -limit) - { - dest.posZ = z - limit; - } - if ((dest.posZ - z) > limit) - { - dest.posZ = z + limit; - } - - drawBresehnam(world, src.posX, src.posY, src.posZ, dest.posX, dest.posY, dest.posZ, treeBlock, trunk ? treeMeta : branchMeta); - - // do this here until that bug with the lighting is fixed - if (trunk) - { - // add a firefly (torch) to the trunk - addFirefly(world, x, y, z, 3 + treeRNG.nextInt(7), treeRNG.nextDouble()); - } - - int blobSize = 2;// + treeRNG.nextInt(2); - - drawLeafBlob(world, dest.posX, dest.posY, dest.posZ, blobSize, leafBlock, leafMeta); - -// makeLeafCircle(world, dest.posX, dest.posY - 1, dest.posZ, 3, leafBlock, leafMeta, true); -// makeLeafCircle(world, dest.posX, dest.posY, dest.posZ, 4, leafBlock, leafMeta, true); -// makeLeafCircle(world, dest.posX, dest.posY + 1, dest.posZ, 2, leafBlock, leafMeta, true); - - setBlockAndMetadata(world, dest.posX + 1, dest.posY, dest.posZ, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX - 1, dest.posY, dest.posZ, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX, dest.posY, dest.posZ + 1, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX, dest.posY, dest.posZ - 1, treeBlock, branchMeta); - - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/world/TFGenCanopyTree.java b/src/main/java/twilightforest/world/TFGenCanopyTree.java deleted file mode 100644 index 0e3b87db1f..0000000000 --- a/src/main/java/twilightforest/world/TFGenCanopyTree.java +++ /dev/null @@ -1,180 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.material.Material; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.World; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - - - - -/** - * Makes large trees with flat leaf ovals that provide a canopy for the forest - * - * @author Ben - * - */ -public class TFGenCanopyTree extends TFTreeGenerator { - - protected int minHeight = 20; - protected int chanceAddFirstFive = 3; - protected int chanceAddSecondFive = 8; - - - public TFGenCanopyTree() - { - this(false); - } - - public TFGenCanopyTree(boolean par1) - { - super(par1); - treeBlock = TFBlocks.log; - treeMeta = 1; - branchMeta = 13; - leafBlock = TFBlocks.leaves; - leafMeta = 1; - rootBlock = TFBlocks.root; - rootMeta = BlockTFRoots.ROOT_META; - - } - - @Override - public boolean generate(World world, Random random, int x, int y, int z) - { - int treeHeight; - - // check if we're on dirt or grass - Material materialUnder = world.getBlock(x, y - 1, z).getMaterial(); - if ((materialUnder != Material.grass && materialUnder != Material.ground) || y >= TFWorld.MAXHEIGHT - 12) - { - return false; - } - - - // determine a height - treeHeight = minHeight; - if (random.nextInt(chanceAddFirstFive) == 0) { - treeHeight += random.nextInt(5); - - if (random.nextInt(chanceAddSecondFive) == 0) { - treeHeight += random.nextInt(5); - } - } - - //okay build a tree! Go up to the height - buildBranch(world, x, y, z, 0, treeHeight, 0, 0, true, random); - - // make 3-4 branches - int numBranches = 3 + random.nextInt(2); - float offset = random.nextFloat(); - for (int b = 0; b < numBranches; b++) - { - buildBranch(world, x, y, z, treeHeight - 10 + b, 9, 0.3 * b + offset, 0.2, false, random); - } - - // root bulb - if (hasAirAround(world, x, y - 1, z)) { - this.setBlockAndMetadata(world, x, y - 1, z, treeBlock, treeMeta); - } - else { - this.setBlockAndMetadata(world, x, y - 1, z, rootBlock, rootMeta); - } - - // roots! - int numRoots = 3 + random.nextInt(2); - offset = random.nextFloat(); - for (int b = 0; b < numRoots; b++) - { - buildRoot(world, x, y, z, offset, b); - } - - - return true; - } - - /** - * Build a branch with a flat blob of leaves at the end. - * - * @param height - * @param length - * @param angle - * @param tilt - */ - void buildBranch(World world, int x, int y, int z, int height, double length, double angle, double tilt, boolean trunk, Random treeRNG) - { - ChunkCoordinates src = new ChunkCoordinates(x, y + height, z); - ChunkCoordinates dest = translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); - - // constrain branch spread - if ((dest.posX - x) < -4) - { - dest.posX = x - 4; - } - if ((dest.posX - x) > 4) - { - dest.posX = x + 4; - } - if ((dest.posZ - z) < -4) - { - dest.posZ = z - 4; - } - if ((dest.posZ - z) > 4) - { - dest.posZ = z + 4; - } - - drawBresehnam(world, src.posX, src.posY, src.posZ, dest.posX, dest.posY, dest.posZ, treeBlock, trunk ? treeMeta : branchMeta); - - // do this here until that bug with the lighting is fixed - if (trunk) - { - // add a firefly (torch) to the trunk - addFirefly(world, x, y, z, 3 + treeRNG.nextInt(7), treeRNG.nextDouble()); - } - - makeLeafCircle(world, dest.posX, dest.posY - 1, dest.posZ, 3, leafBlock, leafMeta, true); - makeLeafCircle(world, dest.posX, dest.posY, dest.posZ, 4, leafBlock, leafMeta, true); - makeLeafCircle(world, dest.posX, dest.posY + 1, dest.posZ, 2, leafBlock, leafMeta, true); - - setBlockAndMetadata(world, dest.posX + 1, dest.posY, dest.posZ, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX - 1, dest.posY, dest.posZ, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX, dest.posY, dest.posZ + 1, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX, dest.posY, dest.posZ - 1, treeBlock, branchMeta); - - } - - /** - * Add a firefly at the specified height and angle. - * - * @param height how far up the tree - * @param angle from 0 - 1 rotation around the tree - */ - protected void addFirefly(World world, int x, int y, int z, int height, double angle) - { - int iAngle = (int)(angle * 4.0); - if (iAngle == 0) - { - setBlockAndMetadata(world, x + 1, y + height, z, TFBlocks.firefly, 0); - } - else if (iAngle == 1) - { - setBlockAndMetadata(world, x - 1, y + height, z, TFBlocks.firefly, 0); - } - else if (iAngle == 2) - { - setBlockAndMetadata(world, x, y + height, z + 1, TFBlocks.firefly, 0); - } - else if (iAngle == 3) - { - setBlockAndMetadata(world, x, y + height, z - 1, TFBlocks.firefly, 0); - } - } - - - - -} diff --git a/src/main/java/twilightforest/world/TFGenCaveStalactite.java b/src/main/java/twilightforest/world/TFGenCaveStalactite.java deleted file mode 100644 index a57e88e196..0000000000 --- a/src/main/java/twilightforest/world/TFGenCaveStalactite.java +++ /dev/null @@ -1,230 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - - - -public class TFGenCaveStalactite extends TFGenerator { - - - public static TFGenCaveStalactite diamond = new TFGenCaveStalactite(Blocks.diamond_ore, 0.5F, 4, 16); - public static TFGenCaveStalactite lapis = new TFGenCaveStalactite(Blocks.lapis_ore, 0.8F, 8, 1); - public static TFGenCaveStalactite emerald = new TFGenCaveStalactite(Blocks.emerald_ore, 0.5F, 3, 12); - public static TFGenCaveStalactite gold = new TFGenCaveStalactite(Blocks.gold_ore, 0.6F, 6, 1); - public static TFGenCaveStalactite redstone = new TFGenCaveStalactite(Blocks.redstone_ore, 0.8F, 8, 1); - public static TFGenCaveStalactite iron = new TFGenCaveStalactite(Blocks.iron_ore, 0.7F, 8, 1); - public static TFGenCaveStalactite coal = new TFGenCaveStalactite(Blocks.coal_ore, 0.8F, 12, 1); - public static TFGenCaveStalactite glowstone = new TFGenCaveStalactite(Blocks.glowstone, 0.5F, 8, 1); - - - public Block blockID; - public boolean hang; - public float sizeFactor; - public int maxLength; - public int minHeight; - - /** - * Initializes a stalactite builder. Actually also makes stalagmites - * - * @param size - * @param stone - */ - public TFGenCaveStalactite(Block blockType, float size, boolean down) - { - this.blockID = blockType; - this.sizeFactor = size; - this.maxLength = -1; - this.minHeight = -1; - this.hang = down; - } - - /** - * Initializes a stalactite builder - */ - public TFGenCaveStalactite(Block blockType, float size, int maxLength, int minHeight) - { - this.blockID = blockType; - this.sizeFactor = size; - this.maxLength = maxLength; - this.minHeight = minHeight; - this.hang = true; - } - - /** - * Makes a random stalactite appropriate to the cave size - * - * All include iron, coal and glowstone. - * - * Gold and redstone appears in size 2 and larger caves. - * - * Diamonds and lapis only appear in size 3 and larger caves. - */ - public static TFGenCaveStalactite makeRandomOreStalactite(Random rand, int hillSize) - { - if (hillSize >= 3 || (hillSize >= 2 && rand.nextInt(5) == 0)) - { - int s3 = rand.nextInt(13); - if (s3 == 0 || s3 == 1) - { - return diamond; - } - else if (s3 == 2 || s3 == 3) - { - return lapis; - } - else if (s3 == 4) - { - return emerald; - } - } - if (hillSize >= 2 || (hillSize >= 1 && rand.nextInt(5) == 0)) - { - int s2 = rand.nextInt(6); - if (s2 == 0) - { - return gold; - } - else if (s2 == 1 || s2 == 2) - { - return redstone; - } - } - - // fall through to size 1 - int s1 = rand.nextInt(5); - if (s1 == 0 || s1 == 1) - { - return iron; - } - else if (s1 == 2 || s1 == 3) - { - return coal; - } - else - { - return glowstone; - } - } - - /** - * Generates a stalactite at the specified location. - * The coordinates should be inside a cave. - * This will return false if it can't find a valid ceiling and floor, or if there are other errors. - */ - public boolean generate(World world, Random random, int x, int y, int z) - { - int ceiling = Integer.MAX_VALUE; - int floor = -1; - - // find a ceiling - for (int ty = y; ty < TFWorld.CHUNKHEIGHT; ty++) - { - Material m = world.getBlock(x, ty, z).getMaterial(); - // if we're in air, continue - if (m == Material.air) - { - continue; - } - // if we get something that's not cave material, fail! - if (m != Material.ground && m != Material.rock) - { - return false; - } - // okay, we found a valid ceiling. - ceiling = ty; - break; - } - // if we didn't find a ceiling, fail. - if (ceiling == Integer.MAX_VALUE) - { - return false; - } - - // find a floor - for (int ty = y; ty > 4; ty--) - { - Material m = world.getBlock(x, ty, z).getMaterial(); - // if we're in air, continue - if (m == Material.air) - { - continue; - } - // if we get something that's not cave material, fail! - // actually stalactites can hang above water or lava - if (m != Material.ground && m != Material.rock && (!hang && m != Material.water) && (!hang && m != Material.lava) ) - { - return false; - } - // okay, we found a valid floor. - floor = ty; - break; - } - - int length = (int)((ceiling - floor) * this.sizeFactor * random.nextFloat()); - - // check max length - if (this.maxLength > -1 && length > this.maxLength) - { - length = this.maxLength; - } - - // check minimum height - if (this.minHeight > -1 && ceiling - floor - length < this.minHeight) - { - return false; - } - - return makeSpike(world, random, x, hang ? ceiling : floor, z, length); - } - - - public boolean makeSpike(World world, Random random, int x, int y, int z, int maxLength) - { - - int diameter = (int)(maxLength / 4.5); // diameter of the base - - // let's see... - for (int dx = -diameter; dx <= diameter; dx++) - { - for (int dz = -diameter; dz <= diameter; dz++) - { - // determine how long this spike will be. - int absx = Math.abs(dx); - int absz = Math.abs(dz); - int dist = (int)(Math.max(absx, absz) + (Math.min(absx, absz) * 0.5)); - int spikeLength = 0; - - if (dist == 0) - { - spikeLength = maxLength; - } - - if (dist > 0) - { - spikeLength = random.nextInt((int)(maxLength / (dist + 0.25))); - } - - int dir = hang ? -1 : 1; - - // check if we're generating over anything - if (!world.getBlock(x + dx, y - dir, z + dz).getMaterial().isSolid()) - { - spikeLength = 0; - } - - for (int dy = 0; dy != (spikeLength * dir); dy += dir) - { - setBlock(world, x + dx, y + dy, z + dz, blockID); - } - } - } - - return true; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenCaves.java b/src/main/java/twilightforest/world/TFGenCaves.java index 58a9d7ab1c..54c9887cbc 100644 --- a/src/main/java/twilightforest/world/TFGenCaves.java +++ b/src/main/java/twilightforest/world/TFGenCaves.java @@ -1,282 +1,250 @@ package twilightforest.world; -import java.util.Random; - -import twilightforest.biomes.TFBiomeHighlands; -import twilightforest.block.TFBlocks; import net.minecraft.block.Block; import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; -import net.minecraft.world.gen.MapGenBase; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.gen.MapGenCaves; +import twilightforest.biomes.TFBiomeHighlands; +import twilightforest.block.TFBlocks; +import java.util.Random; -public class TFGenCaves extends MapGenCaves -{ - /** - * Generates a larger initial cave node than usual. Called 25% of the time. - * @param isHighlands - */ - protected void generateLargeCaveNode(long caveSeed, int centerX, int centerZ, Block[] blockStorage, double randX, double randY, double randZ, boolean isHighlands) - { - this.generateCaveNode(caveSeed, centerX, centerZ, blockStorage, randX, randY, randZ, 1.0F + this.rand.nextFloat() * 6.0F, 0.0F, 0.0F, -1, -1, 0.5D, isHighlands); - } - - /** - * Generates a node in the current cave system recursion tree. - * @param isHighlands - */ - protected void generateCaveNode(long caveSeed, int centerX, int centerZ, Block[] blockStorage, double randX, double randY, double randZ, float caveSize, float randPI, float angleToGenerate, int loopOne, int loopEnd, double yScale, boolean isHighlands) - { - double offsetCenterX = (double)(centerX * 16 + 8); - double offsetCenterZ = (double)(centerZ * 16 + 8); - float var23 = 0.0F; - float var24 = 0.0F; - Random caveRNG = new Random(caveSeed); - Random mossRNG = new Random(caveSeed); - -// if (isHighlands) { -// //System.out.println("Saying highlands and it's not"); -// isHighlands = false; -// } - - if (isHighlands && caveSize < 6F) { - caveSize *= 2.5F; - } - - if (loopEnd <= 0) - { - int rangeInBlocks = this.range * 16 - 16; - loopEnd = rangeInBlocks - caveRNG.nextInt(rangeInBlocks / 4); - } - - boolean shouldStop = false; - - if (loopOne == -1) - { - loopOne = loopEnd / 2; - shouldStop = true; - } - - int var27 = caveRNG.nextInt(loopEnd / 2) + loopEnd / 4; - - for (boolean var28 = caveRNG.nextInt(6) == 0; loopOne < loopEnd; ++loopOne) - { - double sizeVar = 1.5D + (double)(MathHelper.sin((float)loopOne * (float)Math.PI / (float)loopEnd) * caveSize * 1.0F); - double scaledSize = sizeVar * yScale; - float cosAngle = MathHelper.cos(angleToGenerate); - float sinAngle = MathHelper.sin(angleToGenerate); - randX += (double)(MathHelper.cos(randPI) * cosAngle); - randY += (double)sinAngle; - randZ += (double)(MathHelper.sin(randPI) * cosAngle); - - if (var28) - { - angleToGenerate *= 0.92F; - } - else - { - angleToGenerate *= 0.7F; - } - - angleToGenerate += var24 * 0.1F; - randPI += var23 * 0.1F; - var24 *= 0.9F; - var23 *= 0.75F; - var24 += (caveRNG.nextFloat() - caveRNG.nextFloat()) * caveRNG.nextFloat() * 2.0F; - var23 += (caveRNG.nextFloat() - caveRNG.nextFloat()) * caveRNG.nextFloat() * 4.0F; - - if (!shouldStop && loopOne == var27 && caveSize > 1.0F && loopEnd > 0) - { - this.generateCaveNode(caveRNG.nextLong(), centerX, centerZ, blockStorage, randX, randY, randZ, caveRNG.nextFloat() * 0.5F + 0.5F, randPI - ((float)Math.PI / 2F), angleToGenerate / 3.0F, loopOne, loopEnd, 1.0D, isHighlands); - this.generateCaveNode(caveRNG.nextLong(), centerX, centerZ, blockStorage, randX, randY, randZ, caveRNG.nextFloat() * 0.5F + 0.5F, randPI + ((float)Math.PI / 2F), angleToGenerate / 3.0F, loopOne, loopEnd, 1.0D, isHighlands); - return; - } - - if (shouldStop || caveRNG.nextInt(4) != 0) - { - double distX = randX - offsetCenterX; - double distZ = randZ - offsetCenterZ; - double var39 = (double)(loopEnd - loopOne); - double sizeSixteen = (double)(caveSize + 2.0F + 16.0F); - - if (distX * distX + distZ * distZ - var39 * var39 > sizeSixteen * sizeSixteen) - { - return; - } - - if (randX >= offsetCenterX - 16.0D - sizeVar * 2.0D && randZ >= offsetCenterZ - 16.0D - sizeVar * 2.0D && randX <= offsetCenterX + 16.0D + sizeVar * 2.0D && randZ <= offsetCenterZ + 16.0D + sizeVar * 2.0D) - { - int minX = MathHelper.floor_double(randX - sizeVar) - centerX * 16 - 1; - int maxX = MathHelper.floor_double(randX + sizeVar) - centerX * 16 + 1; - int maxY = MathHelper.floor_double(randY - scaledSize) - 1; - int minY = MathHelper.floor_double(randY + scaledSize) + 1; - int minZ = MathHelper.floor_double(randZ - sizeVar) - centerZ * 16 - 1; - int maxZ = MathHelper.floor_double(randZ + sizeVar) - centerZ * 16 + 1; - - if (minX < 0) - { - minX = 0; - } - - if (maxX > 16) - { - maxX = 16; - } - - if (maxY < 1) - { - maxY = 1; - } - - if (minY > 120) - { - minY = 120; - } - - if (minZ < 0) - { - minZ = 0; - } - - if (maxZ > 16) - { - maxZ = 16; - } - - boolean hasHitWater = false; - int genX; - int genZ; - - for (genX = minX; !hasHitWater && genX < maxX; ++genX) - { - for (genZ = minZ; !hasHitWater && genZ < maxZ; ++genZ) - { - for (int genY = minY + 1; !hasHitWater && genY >= maxY - 1; --genY) - { - int waterIndex = (genX * 16 + genZ) * 128 + genY; - - if (genY >= 0 && genY < 128) - { - if (isOceanBlock(blockStorage, waterIndex, genX, genY, genZ, centerX, centerZ)) - { - hasHitWater = true; - } - - if (genY != maxY - 1 && genX != minX && genX != maxX - 1 && genZ != minZ && genZ != maxZ - 1) - { - genY = maxY; - } - } - } - } - } - - if (!hasHitWater) - { - for (genX = minX; genX < maxX; ++genX) - { - double var59 = ((double)(genX + centerX * 16) + 0.5D - randX) / sizeVar; - - for (genZ = minZ; genZ < maxZ; ++genZ) - { - double var46 = ((double)(genZ + centerZ * 16) + 0.5D - randZ) / sizeVar; - int caveIndex = (genX * 16 + genZ) * TFWorld.CHUNKHEIGHT + minY; - boolean hitGrass = false; - - if (var59 * var59 + var46 * var46 < 1.0D) - { - for (int caveY = minY - 1; caveY >= maxY; --caveY) - { - double var51 = ((double)caveY + 0.5D - randY) / scaledSize; - - if (var51 > -0.7D && var59 * var59 + var51 * var51 + var46 * var46 < 20.0D) - { - Block blockAt = blockStorage[caveIndex]; - - if (blockAt == Blocks.grass) - { - hitGrass = true; - } - - if (blockAt != null && (blockAt == Blocks.stone || blockAt == TFBlocks.trollSteinn || blockAt.getMaterial() == Material.ground || blockAt.getMaterial() == Material.grass)) - { - if (var59 * var59 + var51 * var51 + var46 * var46 < 0.85D) { - blockStorage[caveIndex] = caveY < 10 ? Blocks.water : Blocks.air; - } - else { - Block localBlock = isHighlands ? (mossRNG.nextInt(6) == 0 ? TFBlocks.trollSteinn : Blocks.stone) : Blocks.dirt; - blockStorage[caveIndex] = hitGrass ? Blocks.grass : localBlock; - hitGrass = false; - } - - if (hitGrass && blockStorage[caveIndex - 1] == Blocks.dirt) - { - blockStorage[caveIndex - 1] = this.worldObj.getBiomeGenForCoords(genX + centerX * 16, genZ + centerZ * 16).topBlock; - } - } - } - - --caveIndex; - } - } - } - } - - if (shouldStop) - { - break; - } - } - } - } - } - } - - /** - * Recursively called by generate() (generate) and optionally by itself. - */ - protected void func_151538_a(World par1World, int genX, int genZ, int centerX, int centerZ, Block[] blockStorage) { - int numberOfCaves = this.rand.nextInt(this.rand.nextInt(this.rand.nextInt(40) + 1) + 1); - boolean isHighlands = par1World.getBiomeGenForCoords(genX * 16, genZ * 16) instanceof TFBiomeHighlands; - - if (this.rand.nextInt(15) != 0) - { - numberOfCaves = 0; - } - - for (int i = 0; i < numberOfCaves; ++i) - { - double randX = (double)(genX * 16 + this.rand.nextInt(16)); - double randY = (double)this.rand.nextInt(this.rand.nextInt(120) + 8); - double randZ = (double)(genZ * 16 + this.rand.nextInt(16)); - int numberOfNormalNodes = 1; - - if (this.rand.nextInt(4) == 0) - { - this.generateLargeCaveNode(this.rand.nextLong(), centerX, centerZ, blockStorage, randX, randY, randZ, isHighlands); - numberOfNormalNodes += this.rand.nextInt(4); - } - - for (int j = 0; j < numberOfNormalNodes; ++j) - { - float randPi = this.rand.nextFloat() * (float)Math.PI * 2.0F; - float randEight = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; - float caveSize = this.rand.nextFloat() * 2.0F + this.rand.nextFloat(); - - if (this.rand.nextInt(10) == 0){ - caveSize *= this.rand.nextFloat() * this.rand.nextFloat() * 3.0F + 1.0F; - } - - this.generateCaveNode(this.rand.nextLong(), centerX, centerZ, blockStorage, randX, randY, randZ, caveSize, randPi, randEight, 0, 0, 1.0D, isHighlands); - } - } - } - - protected boolean isOceanBlock(Block[] data, int index, int x, int y, int z, int chunkX, int chunkZ) - { - return data[index] == Blocks.flowing_water || data[index] == Blocks.water; - } +public class TFGenCaves extends MapGenCaves { + + private Biome[] biomes; + + /** + * Generates a larger initial cave node than usual. Called 25% of the time. + */ + protected void generateLargeCaveNode(long caveSeed, int centerX, int centerZ, ChunkPrimer blockStorage, double randX, double randY, double randZ, boolean isHighlands) { + this.generateCaveNode(caveSeed, centerX, centerZ, blockStorage, randX, randY, randZ, 1.0F + this.rand.nextFloat() * 6.0F, 0.0F, 0.0F, -1, -1, 0.5D, isHighlands); + } + + /** + * Generates a node in the current cave system recursion tree. + */ + protected void generateCaveNode(long caveSeed, int centerX, int centerZ, ChunkPrimer blockStorage, double randX, double randY, double randZ, float caveSize, float randPI, float angleToGenerate, int loopOne, int loopEnd, double yScale, boolean isHighlands) { + + double offsetCenterX = (double) (centerX * 16 + 8); + double offsetCenterZ = (double) (centerZ * 16 + 8); + float var23 = 0.0F; + float var24 = 0.0F; + Random caveRNG = new Random(caveSeed); + Random mossRNG = new Random(caveSeed); + + if (isHighlands && caveSize < 6F) { + caveSize *= 2.5F; + } + + if (loopEnd <= 0) { + int rangeInBlocks = this.range * 16 - 16; + loopEnd = rangeInBlocks - caveRNG.nextInt(rangeInBlocks / 4); + } + + boolean shouldStop = false; + + if (loopOne == -1) { + loopOne = loopEnd / 2; + shouldStop = true; + } + + int var27 = caveRNG.nextInt(loopEnd / 2) + loopEnd / 4; + + for (boolean var28 = caveRNG.nextInt(6) == 0; loopOne < loopEnd; ++loopOne) { + double sizeVar = 1.5D + (double) (MathHelper.sin((float) loopOne * (float) Math.PI / (float) loopEnd) * caveSize * 1.0F); + double scaledSize = sizeVar * yScale; + float cosAngle = MathHelper.cos(angleToGenerate); + float sinAngle = MathHelper.sin(angleToGenerate); + randX += (double) (MathHelper.cos(randPI) * cosAngle); + randY += (double) sinAngle; + randZ += (double) (MathHelper.sin(randPI) * cosAngle); + + if (var28) { + angleToGenerate *= 0.92F; + } else { + angleToGenerate *= 0.7F; + } + + angleToGenerate += var24 * 0.1F; + randPI += var23 * 0.1F; + var24 *= 0.9F; + var23 *= 0.75F; + var24 += (caveRNG.nextFloat() - caveRNG.nextFloat()) * caveRNG.nextFloat() * 2.0F; + var23 += (caveRNG.nextFloat() - caveRNG.nextFloat()) * caveRNG.nextFloat() * 4.0F; + + if (!shouldStop && loopOne == var27 && caveSize > 1.0F && loopEnd > 0) { + this.generateCaveNode(caveRNG.nextLong(), centerX, centerZ, blockStorage, randX, randY, randZ, caveRNG.nextFloat() * 0.5F + 0.5F, randPI - ((float) Math.PI / 2F), angleToGenerate / 3.0F, loopOne, loopEnd, 1.0D, isHighlands); + this.generateCaveNode(caveRNG.nextLong(), centerX, centerZ, blockStorage, randX, randY, randZ, caveRNG.nextFloat() * 0.5F + 0.5F, randPI + ((float) Math.PI / 2F), angleToGenerate / 3.0F, loopOne, loopEnd, 1.0D, isHighlands); + return; + } + + if (shouldStop || caveRNG.nextInt(4) != 0) { + double distX = randX - offsetCenterX; + double distZ = randZ - offsetCenterZ; + double var39 = (double) (loopEnd - loopOne); + double sizeSixteen = (double) (caveSize + 2.0F + 16.0F); + + if (distX * distX + distZ * distZ - var39 * var39 > sizeSixteen * sizeSixteen) { + return; + } + + if (randX >= offsetCenterX - 16.0D - sizeVar * 2.0D && randZ >= offsetCenterZ - 16.0D - sizeVar * 2.0D && randX <= offsetCenterX + 16.0D + sizeVar * 2.0D && randZ <= offsetCenterZ + 16.0D + sizeVar * 2.0D) { + int minX = MathHelper.floor(randX - sizeVar) - centerX * 16 - 1; + int maxX = MathHelper.floor(randX + sizeVar) - centerX * 16 + 1; + int maxY = MathHelper.floor(randY - scaledSize) - 1; + int minY = MathHelper.floor(randY + scaledSize) + 1; + int minZ = MathHelper.floor(randZ - sizeVar) - centerZ * 16 - 1; + int maxZ = MathHelper.floor(randZ + sizeVar) - centerZ * 16 + 1; + + if (minX < 0) { + minX = 0; + } + + if (maxX > 16) { + maxX = 16; + } + + if (maxY < 1) { + maxY = 1; + } + + if (minY > 120) { + minY = 120; + } + + if (minZ < 0) { + minZ = 0; + } + + if (maxZ > 16) { + maxZ = 16; + } + + boolean hasHitWater = false; + + for (int genX = minX; !hasHitWater && genX < maxX; ++genX) { + for (int genZ = minZ; !hasHitWater && genZ < maxZ; ++genZ) { + for (int genY = minY + 1; !hasHitWater && genY >= maxY - 1; --genY) { + + if (genY >= 0 && genY < 128) { + if (isOceanBlock(blockStorage, genX, genY, genZ)) { + hasHitWater = true; + } + + if (genY != maxY - 1 && genX != minX && genX != maxX - 1 && genZ != minZ && genZ != maxZ - 1) { + genY = maxY; + } + } + } + } + } + + if (!hasHitWater) { + for (int genX = minX; genX < maxX; ++genX) { + double dx = ((double) (genX + centerX * 16) + 0.5D - randX) / sizeVar; + + for (int genZ = minZ; genZ < maxZ; ++genZ) { + double dz = ((double) (genZ + centerZ * 16) + 0.5D - randZ) / sizeVar; + //int caveIndex = (genX * 16 + genZ) * TFWorld.CHUNKHEIGHT + minY; + boolean hitGrass = false; + + if (dx * dx + dz * dz < 1.0D) { + for (int caveY = minY - 1; caveY >= maxY; --caveY) { + double dy = ((double) caveY + 0.5D - randY) / scaledSize; + + if (dy > -0.7D && dx * dx + dy * dy + dz * dz < 20.0D) { + final IBlockState blockStateAt = blockStorage.getBlockState(genX, caveY, genZ); + Block blockAt = blockStateAt.getBlock(); + + if (blockAt == Blocks.GRASS) { + hitGrass = true; + } + + if (blockAt == Blocks.STONE || blockAt == TFBlocks.trollsteinn || canReplace(blockStateAt.getMaterial())) { + if (dx * dx + dy * dy + dz * dz < 0.85D) { + final IBlockState state = (caveY < 10 ? Blocks.WATER : Blocks.AIR).getDefaultState(); + blockStorage.setBlockState(genX, caveY, genZ, state); + } else { + Block localBlock = mossRNG.nextInt(6) == 0 ? TFBlocks.trollsteinn : Blocks.STONE; + localBlock = isHighlands ? localBlock : Blocks.DIRT; + localBlock = hitGrass ? Blocks.GRASS : localBlock; + blockStorage.setBlockState(genX, caveY, genZ, localBlock.getDefaultState()); + hitGrass = false; + } + + if (hitGrass && blockStorage.getBlockState(genX, caveY - 1, genZ).getBlock() == Blocks.DIRT) { + IBlockState blockState = getBiome(genX, genZ).topBlock; + blockStorage.setBlockState(genX, caveY - 1, genZ, blockState); + } + } + } + } + } + } + } + + if (shouldStop) { + break; + } + } + } + } + } + } + + private boolean canReplace(Material material) { + return material == Material.GROUND || material == Material.GRASS; + } + + @Override + protected void recursiveGenerate(World world, int genX, int genZ, int centerX, int centerZ, ChunkPrimer primer) { + + int numberOfCaves = this.rand.nextInt(this.rand.nextInt(this.rand.nextInt(40) + 1) + 1); + + if (this.rand.nextInt(15) != 0) { + return; // TF - just return here + } + + this.biomes = world.getBiomeProvider().getBiomes(this.biomes, genX << 4, genZ << 4, 16, 16); + + boolean isHighlands = getBiome(0, 0) instanceof TFBiomeHighlands; + + for (int i = 0; i < numberOfCaves; ++i) { + double randX = (double) (genX * 16 + this.rand.nextInt(16)); + double randY = (double) this.rand.nextInt(this.rand.nextInt(120) + 8); + double randZ = (double) (genZ * 16 + this.rand.nextInt(16)); + int numberOfNormalNodes = 1; + + if (this.rand.nextInt(4) == 0) { + this.generateLargeCaveNode(this.rand.nextLong(), centerX, centerZ, primer, randX, randY, randZ, isHighlands); + numberOfNormalNodes += this.rand.nextInt(4); + } + + for (int j = 0; j < numberOfNormalNodes; ++j) { + float randPi = this.rand.nextFloat() * (float) Math.PI * 2.0F; + float randEight = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; + float caveSize = this.rand.nextFloat() * 2.0F + this.rand.nextFloat(); + + if (this.rand.nextInt(10) == 0) { + caveSize *= this.rand.nextFloat() * this.rand.nextFloat() * 3.0F + 1.0F; + } + + this.generateCaveNode(this.rand.nextLong(), centerX, centerZ, primer, randX, randY, randZ, caveSize, randPi, randEight, 0, 0, 1.0D, isHighlands); + } + } + } + + private boolean isOceanBlock(ChunkPrimer data, int x, int y, int z) { + Block block = data.getBlockState(x, y, z).getBlock(); + return block == Blocks.FLOWING_WATER || block == Blocks.WATER; + } + + private Biome getBiome(int x, int z) { + return this.biomes[x & 15 | (z & 15) << 4]; + } } diff --git a/src/main/java/twilightforest/world/TFGenDarkCanopyTree.java b/src/main/java/twilightforest/world/TFGenDarkCanopyTree.java deleted file mode 100644 index cdc410537b..0000000000 --- a/src/main/java/twilightforest/world/TFGenDarkCanopyTree.java +++ /dev/null @@ -1,165 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.material.Material; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.World; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - - - - -/** - * Makes large trees with flat leaf ovals that provide a canopy for the forest - * - * @author Ben - * - */ -public class TFGenDarkCanopyTree extends TFTreeGenerator { - - - public TFGenDarkCanopyTree() - { - this(false); - } - - public TFGenDarkCanopyTree(boolean par1) - { - super(par1); - treeBlock = TFBlocks.log; - treeMeta = 3; - branchMeta = 15; - leafBlock = TFBlocks.darkleaves; - leafMeta = 0; - rootBlock = TFBlocks.root; - rootMeta = BlockTFRoots.ROOT_META; - } - - @Override - public boolean generate(World world, Random random, int x, int y, int z) - { - // if we are given leaves as a starting position, seek dirt or grass underneath - boolean foundDirt = false; - Material materialUnder; - for (int dy = y; dy >= TFWorld.SEALEVEL; dy--) { - materialUnder = world.getBlock(x, dy - 1, z).getMaterial(); - if (materialUnder == Material.grass || materialUnder == Material.ground) - { - // yes! - foundDirt = true; - y = dy; - break; - } - else if (materialUnder == Material.rock || materialUnder == Material.sand) { - // nope - break; - } - } - - if (!foundDirt) { - return false; - } - - // do not grow next to another tree - if (world.getBlock(x + 1, y, z + 0).getMaterial() == Material.wood || world.getBlock(x - 1, y, z + 0).getMaterial() == Material.wood - || world.getBlock(x + 0, y, z + 1).getMaterial() == Material.wood || world.getBlock(x + 0, y, z - 1).getMaterial() == Material.wood) { - return false; - } - - // determine a height - int treeHeight = 6 + random.nextInt(5); - - //okay build a tree! trunk here - drawBresehnam(world, x, y, z, x, y + treeHeight, z, treeBlock, treeMeta); - leafAround(world, x, y + treeHeight, z); - - // make 4 branches - int numBranches = 4; - double offset = random.nextFloat(); - for (int b = 0; b < numBranches; b++) - { - buildBranch(world, x, y, z, treeHeight - 3 - numBranches + (b / 2), 10 + random.nextInt(4), 0.23 * b + offset, 0.23, random); - } - - // root bulb - if (hasAirAround(world, x, y - 1, z)) { - this.setBlockAndMetadata(world, x, y - 1, z, treeBlock, treeMeta); - } - else { - this.setBlockAndMetadata(world, x, y - 1, z, rootBlock, rootMeta); - } - - // roots! - int numRoots = 3 + random.nextInt(2); - offset = random.nextDouble(); - for (int b = 0; b < numRoots; b++) - { - buildRoot(world, x, y, z, offset, b); - } - - - return true; - } - - - /** - * Build a branch with a flat blob of leaves at the end. - * - * @param height - * @param length - * @param angle - * @param tilt - */ - void buildBranch(World world, int x, int y, int z, int height, double length, double angle, double tilt, Random random) - { - ChunkCoordinates src = new ChunkCoordinates(x, y + height, z); - ChunkCoordinates dest = translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); - - // constrain branch spread - if ((dest.posX - x) < -4) - { - dest.posX = x - 4; - } - if ((dest.posX - x) > 4) - { - dest.posX = x + 4; - } - if ((dest.posZ - z) < -4) - { - dest.posZ = z - 4; - } - if ((dest.posZ - z) > 4) - { - dest.posZ = z + 4; - } - - drawBresehnam(world, src.posX, src.posY, src.posZ, dest.posX, dest.posY, dest.posZ, treeBlock, branchMeta); - - if (Math.abs(x - dest.posX) + 2 > 7 || Math.abs(z - dest.posZ) + 2 > 7 ) - { - System.out.println("getting branch too far. x = " + (x - dest.posX + 2) + ", z = " + (z - dest.posZ + 2)); - } - - leafAround(world, dest.posX, dest.posY, dest.posZ); - - } - - /** - * Make our leaf pattern - */ - private void leafAround(World world, int dx, int dy, int dz) { - int leafSize = 4; - - // only leaf if there are no leaves by where we are thinking of leafing - if (hasAirAround(world, dx, dy, dz)) - { - makeLeafCircle(world, dx, dy - 1, dz, leafSize, leafBlock, leafMeta); - makeLeafCircle(world, dx, dy, dz, leafSize + 1, leafBlock, leafMeta); - makeLeafCircle(world, dx, dy + 1, dz, leafSize, leafBlock, leafMeta); - makeLeafCircle(world, dx, dy + 2, dz, leafSize - 2, leafBlock, leafMeta); - } - } - -} diff --git a/src/main/java/twilightforest/world/TFGenFallenHollowLog.java b/src/main/java/twilightforest/world/TFGenFallenHollowLog.java deleted file mode 100644 index 2fc55d3865..0000000000 --- a/src/main/java/twilightforest/world/TFGenFallenHollowLog.java +++ /dev/null @@ -1,244 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.block.BlockTFPlant; -import twilightforest.block.TFBlocks; - - - -public class TFGenFallenHollowLog extends TFGenerator { - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - - return rand.nextBoolean() ? makeLog4Z(world, rand, x, y, z) : makeLog4X(world, rand, x, y, z); - } - - private boolean makeLog4Z(World world, Random rand, int x, int y, int z) { - // +Z 4x4 log - if (!isAreaSuitable(world, rand, x, y, z, 9, 3, 4)) - { - return false; - } - - // jaggy parts - makeNegativeZJaggy(world, x, y, z, rand.nextInt(3), 0, 0); - makeNegativeZJaggy(world, x, y, z, rand.nextInt(3), 3, 0); - makeNegativeZJaggy(world, x, y, z, rand.nextInt(3), 0, 1); - makeNegativeZJaggy(world, x, y, z, rand.nextInt(3), 3, 1); - makeNegativeZJaggy(world, x, y, z, rand.nextInt(3), 1, 2); - makeNegativeZJaggy(world, x, y, z, rand.nextInt(3), 2, 2); - - makePositiveZJaggy(world, x, y, z, rand.nextInt(3), 0, 0); - makePositiveZJaggy(world, x, y, z, rand.nextInt(3), 3, 0); - makePositiveZJaggy(world, x, y, z, rand.nextInt(3), 0, 1); - makePositiveZJaggy(world, x, y, z, rand.nextInt(3), 3, 1); - makePositiveZJaggy(world, x, y, z, rand.nextInt(3), 1, 2); - makePositiveZJaggy(world, x, y, z, rand.nextInt(3), 2, 2); - - // center - for (int dz = 0; dz < 4; dz++) - { - // floor - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + 1, y - 1, z + dz + 3, TFBlocks.log, 8); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + 1, y + 0, z + dz + 3, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - else - { - this.setBlockAndMetadata(world, x + 1, y - 1, z + dz + 3, Blocks.dirt, 0); - this.setBlockAndMetadata(world, x + 1, y + 0, z + dz + 3, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + 2, y - 1, z + dz + 3, TFBlocks.log, 8); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + 2, y + 0, z + dz + 3, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - else - { - this.setBlockAndMetadata(world, x + 2, y - 1, z + dz + 3, Blocks.dirt, 0); - this.setBlockAndMetadata(world, x + 2, y + 0, z + dz + 3, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - - // log part - this.setBlockAndMetadata(world, x + 0, y + 0, z + dz + 3, TFBlocks.log, 8); - this.setBlockAndMetadata(world, x + 3, y + 0, z + dz + 3, TFBlocks.log, 8); - this.setBlockAndMetadata(world, x + 0, y + 1, z + dz + 3, TFBlocks.log, 8); - this.setBlockAndMetadata(world, x + 3, y + 1, z + dz + 3, TFBlocks.log, 8); - this.setBlockAndMetadata(world, x + 1, y + 2, z + dz + 3, TFBlocks.log, 8); - this.setBlockAndMetadata(world, x + 2, y + 2, z + dz + 3, TFBlocks.log, 8); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + 1, y + 3, z + dz + 3, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + 2, y + 3, z + dz + 3, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - - // a few leaves? - int offZ = rand.nextInt(3) + 2; - boolean plusX = rand.nextBoolean(); - for (int dz = 0; dz < 3; dz++) - { - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + (plusX ? 3 : 0), y + 2, z + dz + offZ, TFBlocks.leaves, 0); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + (plusX ? 3 : 0), y + 3, z + dz + offZ, TFBlocks.leaves, 0); - } - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + (plusX ? 4 : -1), y + 2, z + dz + offZ, TFBlocks.leaves, 0); - } - } - } - - - // firefly - this.setBlockAndMetadata(world, x + (plusX ? 0 : 3), y + 2, z + rand.nextInt(4) + 3, TFBlocks.firefly, 0); - - - return true; - } - - private void makeNegativeZJaggy(World world, int x, int y, int z, int length, int dx, int dy) { - for (int dz = -length; dz < 0; dz++) - { - this.setBlockAndMetadata(world, x + dx, y + dy, z + dz + 3, TFBlocks.log, 8); - } - } - - private void makePositiveZJaggy(World world, int x, int y, int z, int length, int dx, int dy) { - for (int dz = 0; dz < length; dz++) - { - this.setBlockAndMetadata(world, x + dx, y + dy, z + dz + 7, TFBlocks.log, 8); - } - } - - /** - * Make a 4x4 log in the +X direction - */ - private boolean makeLog4X(World world, Random rand, int x, int y, int z) { - // +Z 4x4 log - if (!isAreaSuitable(world, rand, x, y, z, 4, 3, 9)) - { - return false; - } - - // jaggy parts - makeNegativeXJaggy(world, x, y, z, rand.nextInt(3), 0, 0); - makeNegativeXJaggy(world, x, y, z, rand.nextInt(3), 3, 0); - makeNegativeXJaggy(world, x, y, z, rand.nextInt(3), 0, 1); - makeNegativeXJaggy(world, x, y, z, rand.nextInt(3), 3, 1); - makeNegativeXJaggy(world, x, y, z, rand.nextInt(3), 1, 2); - makeNegativeXJaggy(world, x, y, z, rand.nextInt(3), 2, 2); - - makePositiveXJaggy(world, x, y, z, rand.nextInt(3), 0, 0); - makePositiveXJaggy(world, x, y, z, rand.nextInt(3), 3, 0); - makePositiveXJaggy(world, x, y, z, rand.nextInt(3), 0, 1); - makePositiveXJaggy(world, x, y, z, rand.nextInt(3), 3, 1); - makePositiveXJaggy(world, x, y, z, rand.nextInt(3), 1, 2); - makePositiveXJaggy(world, x, y, z, rand.nextInt(3), 2, 2); - - // center - for (int dx = 0; dx < 4; dx++) - { - // floor - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + 3, y - 1, z + 1, TFBlocks.log, 4); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + 3, y, z + 1, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - else - { - this.setBlockAndMetadata(world, x + dx + 3, y - 1, z + 1, Blocks.dirt, 0); - this.setBlockAndMetadata(world, x + dx + 3, y, z + 1, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + 3, y - 1, z + 2, TFBlocks.log, 4); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + 3, y, z + 2, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - else - { - this.setBlockAndMetadata(world, x + dx + 3, y - 1, z + 2, Blocks.dirt, 0); - this.setBlockAndMetadata(world, x + dx + 3, y, z + 2, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - - // log part - this.setBlockAndMetadata(world, x + dx + 3, y + 0, z + 0, TFBlocks.log, 4); - this.setBlockAndMetadata(world, x + dx + 3, y + 0, z + 3, TFBlocks.log, 4); - this.setBlockAndMetadata(world, x + dx + 3, y + 1, z + 0, TFBlocks.log, 4); - this.setBlockAndMetadata(world, x + dx + 3, y + 1, z + 3, TFBlocks.log, 4); - this.setBlockAndMetadata(world, x + dx + 3, y + 2, z + 1, TFBlocks.log, 4); - this.setBlockAndMetadata(world, x + dx + 3, y + 2, z + 2, TFBlocks.log, 4); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + 3, y + 3, z + 1, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + 3, y + 3, z + 2, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - - } - - // a few leaves? - int offX = rand.nextInt(3) + 2; - boolean plusZ = rand.nextBoolean(); - for (int dx = 0; dx < 3; dx++) - { - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + offX, y + 2, z + (plusZ ? 3 : 0), TFBlocks.leaves, 0); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + offX, y + 3, z + (plusZ ? 3 : 0), TFBlocks.leaves, 0); - } - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + dx + offX, y + 2, z + (plusZ ? 4 : -1), TFBlocks.leaves, 0); - } - } - } - - - // firefly - this.setBlockAndMetadata(world, x + rand.nextInt(4) + 3, y + 2, z + (plusZ ? 0 : 3), TFBlocks.firefly, 0); - - return true; - } - - private void makeNegativeXJaggy(World world, int x, int y, int z, int length, int dz, int dy) { - for (int dx = -length; dx < 0; dx++) - { - this.setBlockAndMetadata(world, x + 3 + dx, y + dy, z + dz, TFBlocks.log, 4); - } - } - - private void makePositiveXJaggy(World world, int x, int y, int z, int length, int dz, int dy) { - for (int dx = 0; dx < length; dx++) - { - this.setBlockAndMetadata(world, x + dx + 7, y + dy, z + dz, TFBlocks.log, 4); - } - } -} diff --git a/src/main/java/twilightforest/world/TFGenFallenSmallLog.java b/src/main/java/twilightforest/world/TFGenFallenSmallLog.java deleted file mode 100644 index 60de90504b..0000000000 --- a/src/main/java/twilightforest/world/TFGenFallenSmallLog.java +++ /dev/null @@ -1,133 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.block.BlockTFPlant; -import twilightforest.block.TFBlocks; - -public class TFGenFallenSmallLog extends TFGenerator { - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - - // determine direction - boolean goingX = rand.nextBoolean(); - - // length - int length = rand.nextInt(4) + 3; - - // check area clear - if (goingX) - { - if (!isAreaSuitable(world, rand, x, y, z, length, 3, 2)) - { - return false; - } - } - else - { - if (!isAreaSuitable(world, rand, x, y, z, 3, length, 2)) - { - return false; - } - } - - // determine wood type - Block logID; - int logMeta; - int logMetaBranch; - - switch (rand.nextInt(7)) - { - case 0: - default: - logID = TFBlocks.log; - logMeta = 0; - case 1: - logID = TFBlocks.log; - logMeta = 1; - case 2: - logID = TFBlocks.log; - logMeta = 2; - case 3: - logID = Blocks.log; - logMeta = 0; - case 4: - logID = Blocks.log; - logMeta = 1; - case 5: - logID = Blocks.log; - logMeta = 2; - case 6: - logID = Blocks.log; - logMeta = 3; - } - logMetaBranch = logMeta; - - // check biome - - - // make log - if (goingX) - { - logMeta |= 4; - logMetaBranch |= 8; - - for (int lx = 0; lx < length; lx++) - { - this.setBlockAndMetadata(world, x + lx, y + 0, z + 1, logID, logMeta); - if (rand.nextInt(3) > 0) - { - this.setBlockAndMetadata(world, x + lx, y + 1, z + 1, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - } - else - { - logMeta |= 8; - logMetaBranch |= 4; - - for (int lz = 0; lz < length; lz++) - { - this.setBlockAndMetadata(world, x + 1, y + 0, z + lz, logID, logMeta); - if (rand.nextInt(3) > 0) - { - this.setBlockAndMetadata(world, x + 1, y + 1, z + lz, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - } - - // possibly make branch - if (rand.nextInt(3) > 0) - { - if (goingX) - { - int bx = rand.nextInt(length); - int bz = rand.nextBoolean() ? 2 : 0; - - this.setBlockAndMetadata(world, x + bx, y + 0, z + bz, logID, logMetaBranch); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + bx, y + 1, z + bz, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - else - { - int bx = rand.nextBoolean() ? 2 : 0; - int bz = rand.nextInt(length); - - this.setBlockAndMetadata(world, x + bx, y + 0, z + bz, logID, logMetaBranch); - if (rand.nextBoolean()) - { - this.setBlockAndMetadata(world, x + bx, y + 1, z + bz, TFBlocks.plant, BlockTFPlant.META_MOSSPATCH); - } - } - } - - return true; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenFireJet.java b/src/main/java/twilightforest/world/TFGenFireJet.java deleted file mode 100644 index 6e96885ae6..0000000000 --- a/src/main/java/twilightforest/world/TFGenFireJet.java +++ /dev/null @@ -1,60 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - -public class TFGenFireJet extends TFGenerator -{ - private Block plantBlockId; - private int plantBlockMeta; - - public TFGenFireJet(Block fireJet, int meta) - { - this.plantBlockId = fireJet; - this.plantBlockMeta = meta; - } - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - for (int var6 = 0; var6 < 4; ++var6) - { - int dx = x + rand.nextInt(8) - rand.nextInt(8); - int dy = y + rand.nextInt(4) - rand.nextInt(4); - int dz = z + rand.nextInt(8) - rand.nextInt(8); - - if (world.isAirBlock(dx, dy, dz) && world.canBlockSeeTheSky(dx, dy, dz) && world.getBlock(dx, dy - 1, dz).getMaterial() == Material.grass - && world.getBlock(dx + 1, dy - 1, dz).getMaterial() == Material.grass && world.getBlock(dx - 1, dy - 1, dz).getMaterial() == Material.grass - && world.getBlock(dx, dy - 1, dz + 1).getMaterial() == Material.grass && world.getBlock(dx, dy - 1, dz - 1).getMaterial() == Material.grass) - { - // jet - world.setBlock(dx, dy - 1, dz, this.plantBlockId, this.plantBlockMeta, 0); - - // create reservoir with stone walls - for (int rx = -2; rx <= 2; rx++) - { - for (int rz = -2; rz <= 2; rz++) - { - if ((rx == 1 || rx == 0 || rx == -1) && (rz == 1 || rz == 0 || rz == -1)) - { - // lava reservoir - world.setBlock(dx + rx, dy - 2, dz + rz, Blocks.flowing_lava, 0, 0); - } - else if (world.getBlock(dx + rx, dy - 2, dz + rz).getMaterial() != Material.lava) - { - // only stone where there is no lava - world.setBlock(dx + rx, dy - 2, dz + rz, Blocks.stone, 0, 0); - } - world.setBlock(dx + rx, dy - 3, dz + rz, Blocks.stone, 0, 0); - } - } - } - } - - return true; - - } -} diff --git a/src/main/java/twilightforest/world/TFGenFoundation.java b/src/main/java/twilightforest/world/TFGenFoundation.java deleted file mode 100644 index 1c9d2dd1ea..0000000000 --- a/src/main/java/twilightforest/world/TFGenFoundation.java +++ /dev/null @@ -1,74 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.TFTreasure; - - - -public class TFGenFoundation extends TFGenerator { - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - int sx = 5 + rand.nextInt(5); - int sz = 5 + rand.nextInt(5); - - - if (!isAreaSuitable(world, rand, x, y, z, sx, 4, sz)) - { - return false; - } - - //okay! - for (int cx = 0; cx <= sx; cx++) - { - for (int cz = 0; cz <= sz; cz++) - { - if (cx == 0 || cx == sx || cz == 0 || cz == sz) - { - // stone on the edges - int ht = rand.nextInt(4) + 1; - - for (int cy = 0; cy <= ht; cy++) - { - setBlock(world, x + cx, y + cy - 1, z + cz, randStone(rand, cy + 1)); - } - } - else - { - // destroyed wooden plank floor - if (rand.nextInt(3) != 0) { - setBlock(world, x + cx, y - 1, z + cz, Blocks.planks); - } - } - } - } - - //TODO: chimney? - - // 50% basement chance! - if (rand.nextInt(2) == 0) { - // clear basement - for (int cx = 1; cx < sx; cx++) - { - for (int cz = 1; cz < sz; cz++) - { - setBlock(world, x + cx, y - 3, z + cz, Blocks.air); - setBlock(world, x + cx, y - 4, z + cz, Blocks.air); - } - } - - // make chest - int cx = rand.nextInt(sx - 1) + 1; - int cz = rand.nextInt(sz - 1) + 1; - TFTreasure.basement.generate(world, rand, x + cx, y - 4, z + cz); - - } - - - - return true; - } -} diff --git a/src/main/java/twilightforest/world/TFGenGroveRuins.java b/src/main/java/twilightforest/world/TFGenGroveRuins.java deleted file mode 100644 index cd4007bbe3..0000000000 --- a/src/main/java/twilightforest/world/TFGenGroveRuins.java +++ /dev/null @@ -1,123 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - - -/** - * Several ruin types that look like the quest grove - * - * @author Ben - * - */ -public class TFGenGroveRuins extends TFGenerator { - - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - - if (rand.nextBoolean()) - { - return generateLargeArch(world, rand, x, y, z); - } - else - { - return generateSmallArch(world, rand, x, y, z); - } - } - - /** - * Generate a ruin with the larger arch - */ - private boolean generateLargeArch(World world, Random rand, int x, int y, int z) { - if (!isAreaSuitable(world, rand, x, y, z, 2, 7, 6)) - { - return false; - } - - // pillar - for (int dy = -2; dy <= 7; dy++) { - this.setBlockAndMetadata(world, x + 0, y + dy, z + 1, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y + dy, z + 1, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y + dy, z + 2, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y + dy, z + 2, Blocks.stonebrick, 1); - } - - // broken floor part - this.setBlockAndMetadata(world, x + 0, y - 1, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y - 1, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y - 2, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y - 2, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y - 1, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y - 1, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y - 2, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y - 2, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y - 1, z + 5, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y - 2, z + 5, Blocks.stonebrick, 1); - - // broken top part - this.setBlockAndMetadata(world, x + 0, y + 6, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y + 6, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y + 7, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y + 7, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y + 6, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y + 6, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y + 7, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y + 7, z + 4, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 1, y + 7, z + 5, Blocks.stonebrick, 1); - - // small piece of chiseled stone brick - this.setBlockAndMetadata(world, x + 0, y + 5, z + 0, Blocks.stonebrick, 3); - - return true; - } - - /** - * Generate a ruin with the smaller arch - */ - private boolean generateSmallArch(World world, Random rand, int x, int y, int z) { - if (!isAreaSuitable(world, rand, x, y, z, 7, 5, 9)) - { - return false; - } - - // corner - this.setBlockAndMetadata(world, x + 0, y + 4, z + 0, Blocks.stonebrick, 3); - this.setBlockAndMetadata(world, x + 0, y + 3, z + 0, Blocks.stonebrick, 3); - this.setBlockAndMetadata(world, x + 1, y + 4, z + 0, Blocks.stonebrick, 3); - this.setBlockAndMetadata(world, x + 2, y + 4, z + 0, Blocks.stonebrick, 3); - this.setBlockAndMetadata(world, x + 0, y + 4, z + 1, Blocks.stonebrick, 3); - this.setBlockAndMetadata(world, x + 0, y + 4, z + 2, Blocks.stonebrick, 3); - - // broken arch in x direction - for (int dy = -1; dy <= 5; dy++) { - this.setBlockAndMetadata(world, x + 3, y + dy, z + 0, Blocks.stonebrick, 1); - } - this.setBlockAndMetadata(world, x + 4, y - 1, z + 0, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 5, y - 1, z + 0, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 6, y - 1, z + 0, Blocks.stonebrick, 1); - - this.setBlockAndMetadata(world, x + 4, y + 5, z + 0, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 5, y + 5, z + 0, Blocks.stonebrick, 1); - - // full arch in z direction - for (int dy = -1; dy <= 5; dy++) { - this.setBlockAndMetadata(world, x + 0, y + dy, z + 3, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y + dy, z + 7, Blocks.stonebrick, 1); - } - for (int dz = 4; dz < 7; dz++) { - this.setBlockAndMetadata(world, x + 0, y - 1, z + dz, Blocks.stonebrick, 1); - this.setBlockAndMetadata(world, x + 0, y + 5, z + dz, Blocks.stonebrick, 1); - } - - // small piece of chiseled stone brick - this.setBlockAndMetadata(world, x + 0, y + 4, z + 8, Blocks.stonebrick, 3); - - - return true; - } - -} - diff --git a/src/main/java/twilightforest/world/TFGenHangingLamps.java b/src/main/java/twilightforest/world/TFGenHangingLamps.java deleted file mode 100644 index 2c534b4e8b..0000000000 --- a/src/main/java/twilightforest/world/TFGenHangingLamps.java +++ /dev/null @@ -1,63 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import twilightforest.block.TFBlocks; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - - - -public class TFGenHangingLamps extends TFGenerator -{ - private static final int MAX_HANG = 8; - - public boolean generate(World par1World, Random par2Random, int x, int y, int z) - { - // this must be an air block, surrounded by air - if (par1World.isAirBlock(x, y, z) && TFGenerator.surroundedByAir(par1World, x, y, z)) { - // there should be leaves or wood within 12 blocks above - if (areLeavesAbove(par1World, x, y, z)) { - // we need to be at least 4 above ground - if (isClearBelow(par1World, x, y, z)) { - // generate lamp - par1World.setBlock(x, y, z, TFBlocks.fireflyJar); - - for (int cy = 1; cy < MAX_HANG; cy++) { - Material above = par1World.getBlock(x, y + cy, z).getMaterial(); - if (above.isSolid() || above == Material.leaves) { - break; - } else { - par1World.setBlock(x, y + cy, z, Blocks.fence); - } - } - } - } - - } - - return false; - } - - private boolean areLeavesAbove(World par1World, int x, int y, int z) { - boolean areLeavesAbove = false; - for (int cy = 1; cy < MAX_HANG; cy++) { - Material above = par1World.getBlock(x, y + cy, z).getMaterial(); - if (above.isSolid() || above == Material.leaves) { - areLeavesAbove = true; - } - } - return areLeavesAbove; - } - - private boolean isClearBelow(World par1World, int x, int y, int z) { - boolean isClearBelow = true; - for (int cy = 1; cy < 4; cy++) { - if (World.doesBlockHaveSolidTopSurface(par1World, x, y - cy, z)) { - isClearBelow = false; - } - } - return isClearBelow; - } -} diff --git a/src/main/java/twilightforest/world/TFGenHollowStump.java b/src/main/java/twilightforest/world/TFGenHollowStump.java deleted file mode 100644 index 57288e3789..0000000000 --- a/src/main/java/twilightforest/world/TFGenHollowStump.java +++ /dev/null @@ -1,97 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.world.World; - - -/** - * A stump from a hollow tree - * - * @author Ben - * - */ -public class TFGenHollowStump extends TFGenHollowTree { - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - - int radius = rand.nextInt(2) + 2; - - if (!isAreaSuitable(world, rand, x - radius, y, z - radius, 2 * radius, 6, 2 * radius)) - { - return false; - } - - buildTrunk(world, rand, x, y, z, radius, 6); - - // 3-5 roots at the bottom - buildBranchRing(world, rand, x, y, z, radius, 3, 2, 6, 0, 0.75D, 0, 3, 5, 3, false); - - - // several more taproots - buildBranchRing(world, rand, x, y, z, radius, 1, 2, 8, 0, 0.9D, 0, 3, 5, 3, false); - - - return true; - } - - /** - * This function builds the hollow trunk of the tree - */ - protected void buildTrunk(World world, Random random, int x, int y, int z, int diameter, int maxHeight) { - - int hollow = diameter / 2; - - - // go down 4 squares and fill in extra trunk as needed, in case we're on uneven terrain - for (int dx = -diameter; dx <= diameter; dx++) - { - for (int dz = -diameter; dz <= diameter; dz++) - { - for (int dy = -4; dy < 0; dy++) - { - // determine how far we are from the center. - int ax = Math.abs(dx); - int az = Math.abs(dz); - int dist = (int)(Math.max(ax, az) + (Math.min(ax, az) * 0.5)); - - if (dist <= diameter) { - if (hasAirAround(world, dx + x, dy + y, dz + z)) { - this.setBlockAndMetadata(world, dx + x, dy + y, dz + z, treeBlock, dist > hollow ? treeMeta : branchMeta); - } - else { - this.setBlockAndMetadata(world, dx + x, dy + y, dz + z, rootBlock, rootMeta); - } - } - } - } - } - - // build the trunk upwards - for (int dx = -diameter; dx <= diameter; dx++) - { - for (int dz = -diameter; dz <= diameter; dz++) - { - int height = 2 + random.nextInt(3) + random.nextInt(2); - - for (int dy = 0; dy <= height; dy++) - { - // determine how far we are from the center. - int ax = Math.abs(dx); - int az = Math.abs(dz); - int dist = (int)(Math.max(ax, az) + (Math.min(ax, az) * 0.5)); - - // make a trunk! - if (dist <= diameter && dist > hollow) { - setBlockAndMetadata(world, dx + x, dy + y, dz + z, treeBlock, treeMeta); - } - } - } - } - - } - - -} - diff --git a/src/main/java/twilightforest/world/TFGenHollowTree.java b/src/main/java/twilightforest/world/TFGenHollowTree.java deleted file mode 100644 index 07cd4cbc6f..0000000000 --- a/src/main/java/twilightforest/world/TFGenHollowTree.java +++ /dev/null @@ -1,568 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntityMobSpawner; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.util.Direction; -import net.minecraft.world.World; -import twilightforest.TFTreasure; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; -import twilightforest.entity.TFCreatures; - - - -public class TFGenHollowTree extends TFGenerator -{ - - private static final int LEAF_DUNGEON_CHANCE = 8; - - protected Block treeBlock = TFBlocks.log; - protected int treeMeta = 0; - protected int branchMeta = 12; - protected Block leafBlock = TFBlocks.leaves; - protected int leafMeta = 0; - protected Block rootBlock = TFBlocks.root; - protected int rootMeta = BlockTFRoots.ROOT_META; - - public TFGenHollowTree() - { - this(false); - } - - public TFGenHollowTree(boolean par1) - { - super(par1); - } - - public boolean generate(World world, Random random, int x, int y, int z) { - - int height = random.nextInt(64) + 32; - int diameter = random.nextInt(4) + 1; - - - // do we have enough height? - if(y < 1 || y + height + diameter > TFWorld.MAXHEIGHT) - { -// System.out.println("Failed with hollow tree of height " + height); - return false; - } -// System.out.println("Succeeded with hollow tree of height " + height); - -// // are we going to hit something? -// for (int dx = -diameter; dx <= diameter; dx++) -// { -// for (int dz = -diameter; dz <= diameter; dz++) -// { -// for (int dy = 1; dy <= height; dy++) -// { -// int whatsThere = world.getBlock(dx + x, dy + y, dz + z); -// if(whatsThere != 0 && whatsThere != Blocks.leaves) -// { -// System.out.println("Failed tree due to things at the base at height " + dy); -// return false; -// } -// } -// } -// } - // check the top too - int crownRadius = diameter * 4 + 8; - for (int dx = -crownRadius; dx <= crownRadius; dx++) - { - for (int dz = -crownRadius; dz <= crownRadius; dz++) - { - for (int dy = height - crownRadius; dy <= height + crownRadius; dy++) - { - Block whatsThere = world.getBlock(dx + x, dy + y, dz + z); - if(whatsThere != Blocks.air && whatsThere != Blocks.leaves) - { -// System.out.println("Failed tree due to things at the top"); - return false; - } - } - } - } - - - // make a tree! - - // check if we're on dirt or grass - Block j1 = world.getBlock(x, y - 1, z); - if(j1 != Blocks.grass && j1 != Blocks.dirt) - { - return false; - } - - // build the trunk - buildTrunk(world, random, x, y, z, diameter, height); - - // fireflies - int numFireflies = random.nextInt(3 * diameter) + 5; - for (int i = 0; i <= numFireflies; i++) { - int fHeight = (int)(height * random.nextDouble() * 0.9) + (height / 10); - double fAngle = random.nextDouble(); - addFirefly(world, x, y, z, diameter, fHeight, fAngle); - } - - // cicadas - numFireflies = random.nextInt(3 * diameter) + 5; - for (int i = 0; i <= numFireflies; i++) { - int fHeight = (int)(height * random.nextDouble() * 0.9) + (height / 10); - double fAngle = random.nextDouble(); - addCicada(world, x, y, z, diameter, fHeight, fAngle); - } - - // build the crown - buildFullCrown(world, random, x, y, z, diameter, height); - - - // 3-5 couple branches on the way up... - int numBranches = random.nextInt(3) + 3; - for (int i = 0; i <= numBranches; i++) { - int branchHeight = (int)(height * random.nextDouble() * 0.9) + (height / 10); - double branchRotation = random.nextDouble(); - makeSmallBranch(world, random, x, y, z, diameter, branchHeight, 4, branchRotation, 0.35D, true); - } - - // 3-5 roots at the bottom - buildBranchRing(world, random, x, y, z, diameter, 3, 2, 6, 0, 0.75D, 0, 3, 5, 3, false); - - - // several more taproots - buildBranchRing(world, random, x, y, z, diameter, 1, 2, 8, 0, 0.9D, 0, 3, 5, 3, false); - - return true; - } - - /** - * Build the crown of the tree - * @param diameter - * @param height - */ - protected void buildFullCrown(World world, Random random, int x, int y, int z, int diameter, int height) { - int crownRadius = diameter * 4 + 4; - int bvar = diameter + 2; - - // okay, let's do 3-5 main branches starting at the bottom of the crown - buildBranchRing(world, random, x, y, z, diameter, height - crownRadius, 0, crownRadius, 0, 0.35D, 0, bvar, bvar + 2, 2, true); - - // then, let's do 3-5 medium branches at the crown middle - buildBranchRing(world, random, x, y, z, diameter, height - (crownRadius / 2), 0, crownRadius, 0, 0.28D, 0, bvar, bvar + 2, 1, true); - - // finally, let's do 2-4 main branches at the crown top - buildBranchRing(world, random, x, y, z, diameter, height, 0, crownRadius, 0, 0.15D, 0, 2, 4, 2, true); - - // and extra finally, let's do 3-6 medium branches going straight up - buildBranchRing(world, random, x, y, z, diameter, height, 0, (crownRadius / 2), 0, 0.05D, 0, bvar, bvar + 2, 1, true); - - // this glass sphere approximates where we want our crown - //drawBlob(x, y + height, z, (byte)crownRadius, (byte)Blocks.glass, false); - - } - - /** - * Build the crown of the tree. This builds a smaller crown, since the large ones were causing some performance issues - * @param height - */ - protected void buildWeakCrown(World world, Random random, int x, int y, int z, int diameter, int height) { - int crownRadius = 8; - int bvar = 2; - - // 3-5 medium branches starting at the bottom of the crown - buildBranchRing(world, random, x, y, z, diameter, height - crownRadius, 0, crownRadius, 0, 0.35D, 0, bvar, bvar + 2, 1, true); - - // 3-5 medium branches at the crown middle - buildBranchRing(world, random, x, y, z, diameter, height - (crownRadius / 2), 0, crownRadius, 0, 0.28D, 0, bvar, bvar + 2, 1, true); - - // 2-4 medium branches at the crown top - buildBranchRing(world, random, x, y, z, diameter, height, 0, crownRadius, 0, 0.15D, 0, 2, 4, 1, true); - - // 3-6 medium branches going straight up - buildBranchRing(world, random, x, y, z, diameter, height, 0, (crownRadius / 2), 0, 0.05D, 0, bvar, bvar + 2, 1, true); - } - - /** - * Build a ring of branches around the tree - * size 0 = small, 1 = med, 2 = large, 3 = root - */ - protected void buildBranchRing(World world, Random random, int x, int y, int z, int diameter, int branchHeight, int heightVar, int length, int lengthVar, double tilt, double tiltVar, int minBranches, int maxBranches, int size, boolean leafy) { - //let's do this! - int numBranches = random.nextInt(maxBranches - minBranches) + minBranches; - ; - double branchRotation = 1.0 / (numBranches + 1); - double branchOffset = random.nextDouble(); - - for (int i = 0; i <= numBranches; i++) { - int dHeight; - if (heightVar > 0) { - dHeight = branchHeight - heightVar + random.nextInt(2 * heightVar); - } else { - dHeight = branchHeight; - } - - if (size == 2) { - makeLargeBranch(world, random, x, y, z, diameter, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); - } else if (size == 1) { - makeMedBranch(world, random, x, y, z, diameter, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); - } else if (size == 3) { - makeRoot(world, random, x, y, z, diameter, dHeight, length, i * branchRotation + branchOffset, tilt); - } else { - makeSmallBranch(world, random, x, y, z, diameter, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); - } - } - } - - - /** - * This function builds the hollow trunk of the tree - */ - protected void buildTrunk(World world, Random random, int x, int y, int z, int diameter, int height) { - - int hollow = diameter / 2; - - - // go down 4 squares and fill in extra trunk as needed, in case we're on uneven terrain - for (int dx = -diameter; dx <= diameter; dx++) - { - for (int dz = -diameter; dz <= diameter; dz++) - { - for (int dy = -4; dy < 0; dy++) - { - // determine how far we are from the center. - int ax = Math.abs(dx); - int az = Math.abs(dz); - int dist = (int)(Math.max(ax, az) + (Math.min(ax, az) * 0.5)); - - if (dist <= diameter) { - if (hasAirAround(world, dx + x, dy + y, dz + z)) { - this.setBlockAndMetadata(world, dx + x, dy + y, dz + z, treeBlock, dist > hollow ? treeMeta : branchMeta); - } - else { - this.setBlockAndMetadata(world, dx + x, dy + y, dz + z, rootBlock, rootMeta); - } - } - - } - } - } - - // build the trunk upwards - for (int dx = -diameter; dx <= diameter; dx++) - { - for (int dz = -diameter; dz <= diameter; dz++) - { - for (int dy = 0; dy <= height; dy++) - { - // determine how far we are from the center. - int ax = Math.abs(dx); - int az = Math.abs(dz); - int dist = (int)(Math.max(ax, az) + (Math.min(ax, az) * 0.5)); - - // make a trunk! - if (dist <= diameter && dist > hollow) { - setBlockAndMetadata(world, dx + x, dy + y, dz + z, treeBlock, treeMeta); - } - - - // fill it with lava! - if (dist <= hollow) { - // just kidding! - //world.setBlock(dx + x, dy + y, dz + z, Blocks.lava); - } - - // how about a ladder? is that okay? - if (dist == hollow && dx == hollow) { -// putBlockAndMetadata(dx + x, dy + y, dz + z, Blocks.ladder, 4, true); - setBlockAndMetadata(world, dx + x, dy + y, dz + z, Blocks.vine, 8); - } - } - } - } - - } - - /** - * Make a branch! - */ - protected void makeMedBranch(World world, Random random, int x, int y, int z, int diameter, int branchHeight, double length, double angle, double tilt, boolean leafy) { - int sx = x, sy = y + branchHeight, sz = z; - int[] src = translate(sx, sy, sz, diameter, angle, 0.5); - - makeMedBranch(world, random, src[0], src[1], src[2], length, angle, tilt, leafy); - - } - - /** - * Make a branch! - */ - protected void makeMedBranch(World world, Random random, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { - int[] src = {sx, sy, sz}; - int[] dest = translate(src[0], src[1], src[2], length, angle, tilt); - - //System.out.println("making a branch at angle " + angle); - - drawBresehnam(world, src[0], src[1], src[2], dest[0], dest[1], dest[2], treeBlock, branchMeta); - - // with leaves! - - if (leafy) { - /* - int numLeafBalls = random.nextInt(2) + 1; - for(int i = 0; i <= numLeafBalls; i++) { - - double slength = random.nextDouble() * 0.6 + 0.2; - int[] bdst = translate(src[0], src[1], src[2], slength, angle, tilt); - - - drawBlob(bdst[0], bdst[1], bdst[2], 2, leafBlock, false); - } - */ - - // and a blob at the end - drawLeafBlob(world, dest[0], dest[1], dest[2], (byte)2, leafBlock, leafMeta); - } - - - // and several small branches - - int numShoots = random.nextInt(2) + 1; - double angleInc, angleVar, outVar, tiltVar; - - angleInc = 0.8 / numShoots; - - for(int i = 0; i <= numShoots; i++) { - - angleVar = (angleInc * i) - 0.4; - outVar = (random.nextDouble() * 0.8) + 0.2; - tiltVar = (random.nextDouble() * 0.75) + 0.15; - - int[] bsrc = translate(src[0], src[1], src[2], length * outVar, angle, tilt); - double slength = length * 0.4; - - makeSmallBranch(world, random, bsrc[0], bsrc[1], bsrc[2], slength, angle + angleVar, tilt * tiltVar, leafy); - } - } - - /** - * Make a small branch with a leaf blob at the end - */ - protected void makeSmallBranch(World world, Random random, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { - int[] src = {sx, sy, sz}; - int[] dest = translate(src[0], src[1], src[2], length, angle, tilt); - - drawBresehnam(world, src[0], src[1], src[2], dest[0], dest[1], dest[2], treeBlock, branchMeta); - - //System.out.println("making a branch at angle " + angle); - if (leafy) { - byte leafRad = (byte) (random.nextInt(2) + 1); - drawLeafBlob(world, dest[0], dest[1] , dest[2], leafRad, leafBlock, leafMeta); - } - } - - /** - * Make a small branch at a certain height - */ - protected void makeSmallBranch(World world, Random random, int x, int y, int z, int diameter, int branchHeight, double length, double angle, double tilt, boolean leafy) { - int sx = x, sy = y + branchHeight, sz = z; - int[] src = translate(sx, sy, sz, diameter, angle, 0.5); - - makeSmallBranch(world, random, src[0], src[1], src[2], length, angle, tilt, leafy); - } - - - /** - * Make a root - */ - protected void makeRoot(World world, Random random, int x, int y, int z, int diameter, int branchHeight, double length, double angle, double tilt) { - ChunkCoordinates src = translateCoords(x, y + branchHeight, z, diameter, angle, 0.5); - ChunkCoordinates dest = translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); - - ChunkCoordinates[] lineArray = getBresehnamArrayCoords(src, dest); - boolean stillAboveGround = true; - for (ChunkCoordinates coord : lineArray) - { - if (stillAboveGround && hasAirAround(world, coord.posX, coord.posY, coord.posZ)) { - this.setBlockAndMetadata(world, coord.posX, coord.posY, coord.posZ, treeBlock, branchMeta); - this.setBlockAndMetadata(world, coord.posX, coord.posY - 1, coord.posZ, treeBlock, branchMeta); - } - else { - this.setBlockAndMetadata(world, coord.posX, coord.posY, coord.posZ, rootBlock, rootMeta); - this.setBlockAndMetadata(world, coord.posX, coord.posY - 1, coord.posZ, rootBlock, rootMeta); - stillAboveGround = false; - } - } - } - - /** - * Make a large, branching "base" branch in a specific location. - * - * The large branch will have 1-4 medium branches and several small branches too - */ - protected void makeLargeBranch(World world, Random random, int sx, int sy, int sz, double length, double angle, double tilt, boolean leafy) { - int[] src = {sx, sy, sz}; - int[] dest = translate(src[0], src[1], src[2], length, angle, tilt); - - // draw the main branch - drawBresehnam(world, src[0], src[1], src[2], dest[0], dest[1], dest[2], treeBlock, branchMeta); - - // reinforce it - //drawBresehnam(src[0], src[1] + 1, src[2], dest[0], dest[1], dest[2], treeBlock, true); - int reinforcements = random.nextInt(3); - for(int i = 0; i <= reinforcements; i++) { - int vx = (i & 2) == 0 ? 1 : 0; - int vy = (i & 1) == 0 ? 1 : -1; - int vz = (i & 2) == 0 ? 0 : 1; - drawBresehnam(world, src[0] + vx, src[1] + vy, src[2] + vz, dest[0], dest[1], dest[2], treeBlock, branchMeta); - } - - if (leafy) { - // add a leaf blob at the end - drawLeafBlob(world, dest[0], dest[1] + 1, dest[2], (byte)3, leafBlock, leafMeta); - } - - // go about halfway out and make a few medium branches. - // the number of medium branches we can support depends on the length of the big branch - // every other branch switches sides - int numMedBranches = random.nextInt((int)(length / 6)) + random.nextInt(2) + 1; - - for (int i = 0; i <= numMedBranches; i++) { - - double outVar = (random.nextDouble() * 0.3) + 0.3; - double angleVar = random.nextDouble() * 0.225 * ((i & 1) == 0 ? 1.0 : -1.0); - int[] bsrc = translate(src[0], src[1], src[2], length * outVar, angle, tilt); - - makeMedBranch(world, random, bsrc[0], bsrc[1], bsrc[2], length * 0.6, angle + angleVar, tilt, leafy); - } - - // make 1-2 small ones near the base - int numSmallBranches = random.nextInt(2) + 1; - for(int i = 0; i <= numSmallBranches; i++) { - - double outVar = (random.nextDouble() * 0.25) + 0.25; - double angleVar = random.nextDouble() * 0.25 * ((i & 1) == 0 ? 1.0 : -1.0); - int[] bsrc = translate(src[0], src[1], src[2], length * outVar, angle, tilt); - - makeSmallBranch(world, random, bsrc[0], bsrc[1], bsrc[2], Math.max(length * 0.3, 2), angle + angleVar, tilt, leafy); - } - - if (random.nextInt(LEAF_DUNGEON_CHANCE) == 0) - { - makeLeafDungeon(world, random , dest[0], dest[1] + 1, dest[2]); - } - - } - - - private void makeLeafDungeon(World world, Random random, int x, int y, int z) { - // make leaves - drawLeafBlob(world, x, y, z, 4, leafBlock, leafMeta); - // wood support - drawBlob(world, x, y, z, 3, treeBlock, branchMeta); - // air - drawBlob(world, x, y, z, 2, Blocks.air, 0); - - - // spawner - world.setBlock(x + 0, y + 1, z + 0, Blocks.mob_spawner, 0, 2); - TileEntityMobSpawner ms = (TileEntityMobSpawner)world.getTileEntity(x + 0, y + 1, z + 0); - if (ms != null) { - ms.func_145881_a().setEntityName(TFCreatures.getSpawnerNameFor("Swarm Spider")); - } - - // treasure chests? - makeLeafDungeonChest(world, random, x, y, z); - } - - private void makeLeafDungeonChest(World world, Random random, int x, int y, int z) { - // which direction is this chest in? - int dir = random.nextInt(4); - - x += Direction.offsetX[dir]; - x += Direction.offsetX[dir]; - z += Direction.offsetZ[dir]; - z += Direction.offsetZ[dir]; - - TFTreasure.tree_cache.generate(world, random, x, y - 1, z); - } - - /** - * Make a large, branching "base" branch off of the tree - */ - protected void makeLargeBranch(World world, Random random, int x, int y, int z, int diameter, int branchHeight, double length, double angle, double tilt, boolean leafy) { - int sx = x, sy = y + branchHeight, sz = z; - int[] src = translate(sx, sy, sz, diameter, angle, 0.5); - - makeLargeBranch(world, random, src[0], src[1], src[2], length, angle, tilt, leafy); - } - - /** - * Add a firefly at the specified height and angle. - * - * @param depth how far up the tree - * @param angle from 0 - 1 rotation around the tree - */ - protected void addFirefly(World world, int x, int y, int z, int diameter, int fHeight, double fAngle) - { - int[] src = translate(x, y + fHeight, z, diameter + 1, fAngle, 0.5); - - fAngle = fAngle % 1.0; - int tmeta = 0; - - if (fAngle > 0.875 || fAngle <= 0.125) - { - tmeta = 3; - } - else if (fAngle > 0.125 && fAngle <= 0.375) - { - tmeta = 1; - } - else if (fAngle > 0.375 && fAngle <= 0.625) - { - tmeta = 4; - } - else if (fAngle > 0.625 && fAngle <= 0.875) - { - tmeta = 2; - } - - if (TFBlocks.firefly.canPlaceBlockAt(world, src[0], src[1], src[2])) - { - setBlockAndMetadata(world, src[0], src[1], src[2], TFBlocks.firefly, tmeta); - } - } - - protected void addCicada(World world, int x, int y, int z, int diameter, int fHeight, double fAngle) - { - int[] src = translate(x, y + fHeight, z, diameter + 1, fAngle, 0.5); - - fAngle = fAngle % 1.0; - int tmeta = 1; - - if (fAngle > 0.875 || fAngle <= 0.125) - { - tmeta = 3; - } - else if (fAngle > 0.125 && fAngle <= 0.375) - { - tmeta = 1; - } - else if (fAngle > 0.375 && fAngle <= 0.625) - { - tmeta = 4; - } - else if (fAngle > 0.625 && fAngle <= 0.875) - { - tmeta = 2; - } - - if (TFBlocks.cicada.canPlaceBlockAt(world, src[0], src[1], src[2])) - { - setBlockAndMetadata(world, src[0], src[1], src[2], TFBlocks.cicada, tmeta); - } - } - - -} \ No newline at end of file diff --git a/src/main/java/twilightforest/world/TFGenHugeLilyPad.java b/src/main/java/twilightforest/world/TFGenHugeLilyPad.java deleted file mode 100644 index e27f885994..0000000000 --- a/src/main/java/twilightforest/world/TFGenHugeLilyPad.java +++ /dev/null @@ -1,58 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import twilightforest.block.TFBlocks; -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenerator; - - -/** - * Generate huge lily pads - * - * @author Ben - * - */ -public class TFGenHugeLilyPad extends WorldGenerator -{ - - private Random rand = new Random(); - - - public boolean generate(World world, Random random, int x, int y, int z) - { - for (int i = 0; i < 10; i++) { - int dx = x + random.nextInt(8) - random.nextInt(8); - int dy = y + random.nextInt(4) - random.nextInt(4); - int dz = z + random.nextInt(8) - random.nextInt(8); - - dx = (dx >> 1) << 1; - dz = (dz >> 1) << 1; - - if (shouldPlacePadAt(world, dx, dy, dz)) { - // this seems like a difficult way to generate 2 pseudorandom bits - rand .setSeed(8890919293L); - rand.setSeed((dx * rand.nextLong()) ^ (dz * rand.nextLong()) ^ 8890919293L); - int orient = rand.nextInt(4) << 2; - - world.setBlock(dx, dy, dz, TFBlocks.hugeLilyPad, 0 | orient, 2); - world.setBlock(dx + 1, dy, dz, TFBlocks.hugeLilyPad, 1 | orient, 2); - world.setBlock(dx + 1, dy, dz + 1, TFBlocks.hugeLilyPad, 2 | orient, 2); - world.setBlock(dx, dy, dz + 1, TFBlocks.hugeLilyPad, 3 | orient, 2); - } - } - - return true; - } - - - private boolean shouldPlacePadAt(World world, int dx, int dy, int dz) { - return world.isAirBlock(dx, dy, dz) && world.getBlock(dx, dy - 1, dz).getMaterial() == Material.water - && world.isAirBlock(dx + 1, dy, dz) && world.getBlock(dx + 1, dy - 1, dz).getMaterial() == Material.water - && world.isAirBlock(dx, dy, dz + 1) && world.getBlock(dx, dy - 1, dz + 1).getMaterial() == Material.water - && world.isAirBlock(dx + 1, dy, dz + 1) && world.getBlock(dx + 1, dy - 1, dz + 1).getMaterial() == Material.water; - } -} diff --git a/src/main/java/twilightforest/world/TFGenLampposts.java b/src/main/java/twilightforest/world/TFGenLampposts.java deleted file mode 100644 index 956ffba182..0000000000 --- a/src/main/java/twilightforest/world/TFGenLampposts.java +++ /dev/null @@ -1,42 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import twilightforest.block.TFBlocks; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - - - -public class TFGenLampposts extends TFGenerator { - private static final int MAX_HANG = 8; - - public boolean generate(World world, Random rand, int x, int y, int z) { - // we should start on a grass block - if (world.getBlock(x, y - 1, z) == Blocks.grass) { - // generate a height - int height = 1 + rand.nextInt(4); - boolean clear = true; - - // is it air or replaceable above our grass block - for (int dy = 0; dy < height; dy++) { - if (!world.isAirBlock(x, y + dy, z) && !world.getBlock(x, y + dy, z).isReplaceable(world, x, y + dy, z)) { - clear = false; - } - } - - // generate lamp - if (clear) { - for (int dy = 0; dy < height; dy++) { - world.setBlock(x, y + dy, z, Blocks.fence); - world.setBlock(x, y + height, z, TFBlocks.fireflyJar); - } - } - return clear; - } else { - return false; - } - } - -} diff --git a/src/main/java/twilightforest/world/TFGenLargeRainboak.java b/src/main/java/twilightforest/world/TFGenLargeRainboak.java deleted file mode 100644 index 3e87de971b..0000000000 --- a/src/main/java/twilightforest/world/TFGenLargeRainboak.java +++ /dev/null @@ -1,523 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; -import net.minecraft.world.World; -import twilightforest.block.TFBlocks; - -/** - * This is a lame copy of WorldGenLargeTree, since I'm too lazy to make my own tree and all the methods in WorldGenLargeTree are package-only - * - */ -public class TFGenLargeRainboak extends TFTreeGenerator -{ - /** - * Contains three sets of two values that provide complimentary indices for a given 'major' index - 1 and 2 for 0, 0 - * and 2 for 1, and 0 and 1 for 2. - */ - static final byte[] otherCoordPairs = new byte[] {(byte)2, (byte)0, (byte)0, (byte)1, (byte)2, (byte)1}; - - /** random seed for GenBigTree */ - Random rand = new Random(); - - /** Reference to the World object. */ - World worldObj; - int[] basePos = new int[] {0, 0, 0}; - int heightLimit = 0; - int height; - double heightAttenuation = 0.618D; - double branchDensity = 1.0D; - double branchSlope = 0.381D; - double scaleWidth = 1.0D; - double leafDensity = 1.0D; - - /** - * Currently always 1, can be set to 2 in the class constructor to generate a double-sized tree trunk for big trees. - */ - int trunkSize = 1; - - /** - * Sets the limit of the random value used to initialize the height limit. - */ - int heightLimitLimit = 12; - - /** - * Sets the distance limit for how far away the generator will populate leaves from the base leaf node. - */ - int leafDistanceLimit = 4; - - /** Contains a list of a points at which to generate groups of leaves. */ - int[][] leafNodes; - - public TFGenLargeRainboak(boolean par1) - { - super(par1); - } - - public TFGenLargeRainboak() { - this(false); - } - - /** - * Generates a list of leaf nodes for the tree, to be populated by generateLeaves. - */ - void generateLeafNodeList() - { - this.height = (int)((double)this.heightLimit * this.heightAttenuation); - - if (this.height >= this.heightLimit) - { - this.height = this.heightLimit - 1; - } - - int var1 = (int)(1.382D + Math.pow(this.leafDensity * (double)this.heightLimit / 13.0D, 2.0D)); - - if (var1 < 1) - { - var1 = 1; - } - - int[][] var2 = new int[var1 * this.heightLimit][4]; - int var3 = this.basePos[1] + this.heightLimit - this.leafDistanceLimit; - int var4 = 1; - int var5 = this.basePos[1] + this.height; - int var6 = var3 - this.basePos[1]; - var2[0][0] = this.basePos[0]; - var2[0][1] = var3; - var2[0][2] = this.basePos[2]; - var2[0][3] = var5; - --var3; - - while (var6 >= 0) - { - int var7 = 0; - float var8 = this.layerSize(var6); - - if (var8 < 0.0F) - { - --var3; - --var6; - } - else - { - for (double var9 = 0.5D; var7 < var1; ++var7) - { - double var11 = this.scaleWidth * (double)var8 * ((double)this.rand.nextFloat() + 0.328D); - double var13 = (double)this.rand.nextFloat() * 2.0D * Math.PI; - int var15 = MathHelper.floor_double(var11 * Math.sin(var13) + (double)this.basePos[0] + var9); - int var16 = MathHelper.floor_double(var11 * Math.cos(var13) + (double)this.basePos[2] + var9); - int[] var17 = new int[] {var15, var3, var16}; - int[] var18 = new int[] {var15, var3 + this.leafDistanceLimit, var16}; - - if (this.checkBlockLine(var17, var18) == -1) - { - int[] var19 = new int[] {this.basePos[0], this.basePos[1], this.basePos[2]}; - double var20 = Math.sqrt(Math.pow((double)Math.abs(this.basePos[0] - var17[0]), 2.0D) + Math.pow((double)Math.abs(this.basePos[2] - var17[2]), 2.0D)); - double var22 = var20 * this.branchSlope; - - if ((double)var17[1] - var22 > (double)var5) - { - var19[1] = var5; - } - else - { - var19[1] = (int)((double)var17[1] - var22); - } - - if (this.checkBlockLine(var19, var17) == -1) - { - var2[var4][0] = var15; - var2[var4][1] = var3; - var2[var4][2] = var16; - var2[var4][3] = var19[1]; - ++var4; - } - } - } - - --var3; - --var6; - } - } - - this.leafNodes = new int[var4][4]; - System.arraycopy(var2, 0, this.leafNodes, 0, var4); - } - - void genTreeLayer(int par1, int par2, int par3, float par4, byte par5, Block leaves, int meta) - { - int var7 = (int)((double)par4 + 0.618D); - byte var8 = otherCoordPairs[par5]; - byte var9 = otherCoordPairs[par5 + 3]; - int[] var10 = new int[] {par1, par2, par3}; - int[] var11 = new int[] {0, 0, 0}; - int var12 = -var7; - int var13 = -var7; - - for (var11[par5] = var10[par5]; var12 <= var7; ++var12) - { - var11[var8] = var10[var8] + var12; - var13 = -var7; - - while (var13 <= var7) - { - double var15 = Math.pow((double)Math.abs(var12) + 0.5D, 2.0D) + Math.pow((double)Math.abs(var13) + 0.5D, 2.0D); - - if (var15 > (double)(par4 * par4)) - { - ++var13; - } - else - { - var11[var9] = var10[var9] + var13; - Block var14 = this.worldObj.getBlock(var11[0], var11[1], var11[2]); - - if (var14 != Blocks.air && !var14.canBeReplacedByLeaves(this.worldObj, var11[0], var11[1], var11[2])) - { - ++var13; - } - else - { - this.setBlockAndMetadata(this.worldObj, var11[0], var11[1], var11[2], leaves, meta); - ++var13; - } - } - } - } - } - - /** - * Gets the rough size of a layer of the tree. - */ - float layerSize(int par1) - { - if ((double)par1 < (double)((float)this.heightLimit) * 0.3D) - { - return -1.618F; - } - else - { - float var2 = (float)this.heightLimit / 2.0F; - float var3 = (float)this.heightLimit / 2.0F - (float)par1; - float var4; - - if (var3 == 0.0F) - { - var4 = var2; - } - else if (Math.abs(var3) >= var2) - { - var4 = 0.0F; - } - else - { - var4 = (float)Math.sqrt(Math.pow((double)Math.abs(var2), 2.0D) - Math.pow((double)Math.abs(var3), 2.0D)); - } - - var4 *= 0.5F; - return var4; - } - } - - float leafSize(int par1) - { - return par1 >= 0 && par1 < this.leafDistanceLimit ? (par1 != 0 && par1 != this.leafDistanceLimit - 1 ? 3.0F : 2.0F) : -1.0F; - } - - /** - * Generates the leaves surrounding an individual entry in the leafNodes list. - */ - void generateLeafNode(int par1, int par2, int par3) - { - int var4 = par2; - - for (int var5 = par2 + this.leafDistanceLimit; var4 < var5; ++var4) - { - float var6 = this.leafSize(var4 - par2); - this.genTreeLayer(par1, var4, par3, var6, (byte)1, TFBlocks.leaves, 3); - } - } - - /** - * Places a line of the specified block ID into the world from the first coordinate triplet to the second. - */ - void placeBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger, Block log) - { - int[] var4 = new int[] {0, 0, 0}; - byte var5 = 0; - byte var6; - - for (var6 = 0; var5 < 3; ++var5) - { - var4[var5] = par2ArrayOfInteger[var5] - par1ArrayOfInteger[var5]; - - if (Math.abs(var4[var5]) > Math.abs(var4[var6])) - { - var6 = var5; - } - } - - if (var4[var6] != 0) - { - byte var7 = otherCoordPairs[var6]; - byte var8 = otherCoordPairs[var6 + 3]; - byte var9; - - if (var4[var6] > 0) - { - var9 = 1; - } - else - { - var9 = -1; - } - - double var10 = (double)var4[var7] / (double)var4[var6]; - double var12 = (double)var4[var8] / (double)var4[var6]; - int[] var14 = new int[] {0, 0, 0}; - int var15 = 0; - - for (int var16 = var4[var6] + var9; var15 != var16; var15 += var9) - { - var14[var6] = MathHelper.floor_double((double)(par1ArrayOfInteger[var6] + var15) + 0.5D); - var14[var7] = MathHelper.floor_double((double)par1ArrayOfInteger[var7] + (double)var15 * var10 + 0.5D); - var14[var8] = MathHelper.floor_double((double)par1ArrayOfInteger[var8] + (double)var15 * var12 + 0.5D); - byte var17 = 0; - int var18 = Math.abs(var14[0] - par1ArrayOfInteger[0]); - int var19 = Math.abs(var14[2] - par1ArrayOfInteger[2]); - int var20 = Math.max(var18, var19); - - if (var20 > 0) - { - if (var18 == var20) - { - var17 = 4; - } - else if (var19 == var20) - { - var17 = 8; - } - } - - this.setBlockAndMetadata(this.worldObj, var14[0], var14[1], var14[2], log, var17); - } - } - } - - /** - * Generates the leaf portion of the tree as specified by the leafNodes list. - */ - void generateLeaves() - { - int var1 = 0; - - for (int var2 = this.leafNodes.length; var1 < var2; ++var1) - { - int var3 = this.leafNodes[var1][0]; - int var4 = this.leafNodes[var1][1]; - int var5 = this.leafNodes[var1][2]; - this.generateLeafNode(var3, var4, var5); - } - } - - /** - * Indicates whether or not a leaf node requires additional wood to be added to preserve integrity. - */ - boolean leafNodeNeedsBase(int par1) - { - return (double)par1 >= (double)this.heightLimit * 0.2D; - } - - /** - * Places the trunk for the big tree that is being generated. Able to generate double-sized trunks by changing a - * field that is always 1 to 2. - */ - void generateTrunk() - { - int var1 = this.basePos[0]; - int var2 = this.basePos[1]; - int var3 = this.basePos[1] + this.height; - int var4 = this.basePos[2]; - int[] var5 = new int[] {var1, var2, var4}; - int[] var6 = new int[] {var1, var3, var4}; - this.placeBlockLine(var5, var6, TFBlocks.log); - - if (this.trunkSize == 2) - { - ++var5[0]; - ++var6[0]; - this.placeBlockLine(var5, var6, TFBlocks.log); - ++var5[2]; - ++var6[2]; - this.placeBlockLine(var5, var6, TFBlocks.log); - var5[0] += -1; - var6[0] += -1; - this.placeBlockLine(var5, var6, TFBlocks.log); - } - } - - /** - * Generates additional wood blocks to fill out the bases of different leaf nodes that would otherwise degrade. - */ - void generateLeafNodeBases() - { - int var1 = 0; - int var2 = this.leafNodes.length; - - for (int[] var3 = new int[] {this.basePos[0], this.basePos[1], this.basePos[2]}; var1 < var2; ++var1) - { - int[] var4 = this.leafNodes[var1]; - int[] var5 = new int[] {var4[0], var4[1], var4[2]}; - var3[1] = var4[3]; - int var6 = var3[1] - this.basePos[1]; - - if (this.leafNodeNeedsBase(var6)) - { - this.placeBlockLine(var3, var5, TFBlocks.log); - } - } - } - - /** - * Checks a line of blocks in the world from the first coordinate to triplet to the second, returning the distance - * (in blocks) before a non-air, non-leaf block is encountered and/or the end is encountered. - */ - int checkBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger) - { - int[] var3 = new int[] {0, 0, 0}; - byte var4 = 0; - byte var5; - - for (var5 = 0; var4 < 3; ++var4) - { - var3[var4] = par2ArrayOfInteger[var4] - par1ArrayOfInteger[var4]; - - if (Math.abs(var3[var4]) > Math.abs(var3[var5])) - { - var5 = var4; - } - } - - if (var3[var5] == 0) - { - return -1; - } - else - { - byte var6 = otherCoordPairs[var5]; - byte var7 = otherCoordPairs[var5 + 3]; - byte var8; - - if (var3[var5] > 0) - { - var8 = 1; - } - else - { - var8 = -1; - } - - double var9 = (double)var3[var6] / (double)var3[var5]; - double var11 = (double)var3[var7] / (double)var3[var5]; - int[] var13 = new int[] {0, 0, 0}; - int var14 = 0; - int var15; - - for (var15 = var3[var5] + var8; var14 != var15; var14 += var8) - { - var13[var5] = par1ArrayOfInteger[var5] + var14; - var13[var6] = MathHelper.floor_double((double)par1ArrayOfInteger[var6] + (double)var14 * var9); - var13[var7] = MathHelper.floor_double((double)par1ArrayOfInteger[var7] + (double)var14 * var11); - Block var16 = this.worldObj.getBlock(var13[0], var13[1], var13[2]); - - if (var16 != Blocks.air && var16 != Blocks.leaves) - { - break; - } - } - - return var14 == var15 ? -1 : Math.abs(var14); - } - } - - /** - * Returns a boolean indicating whether or not the current location for the tree, spanning basePos to to the height - * limit, is valid. - */ - boolean validTreeLocation() - { - int[] var1 = new int[] {this.basePos[0], this.basePos[1], this.basePos[2]}; - int[] var2 = new int[] {this.basePos[0], this.basePos[1] + this.heightLimit - 1, this.basePos[2]}; - Block var3 = this.worldObj.getBlock(this.basePos[0], this.basePos[1] - 1, this.basePos[2]); - - if (var3 != Blocks.dirt && var3 != Blocks.grass) - { - return false; - } - else - { - int var4 = this.checkBlockLine(var1, var2); - - if (var4 == -1) - { - return true; - } - else if (var4 < 6) - { - return false; - } - else - { - this.heightLimit = var4; - return true; - } - } - } - - /** - * Rescales the generator settings, only used in WorldGenBigTree - */ - public void setScale(double par1, double par3, double par5) - { - this.heightLimitLimit = (int)(par1 * 12.0D); - - if (par1 > 0.5D) - { - this.leafDistanceLimit = 5; - } - - this.scaleWidth = par3; - this.leafDensity = par5; - } - - public boolean generate(World par1World, Random par2Random, int par3, int par4, int par5) - { - this.worldObj = par1World; - long var6 = par2Random.nextLong(); - this.rand.setSeed(var6); - this.basePos[0] = par3; - this.basePos[1] = par4; - this.basePos[2] = par5; - - if (this.heightLimit == 0) - { - this.heightLimit = 5 + this.rand.nextInt(this.heightLimitLimit); - } - - if (!this.validTreeLocation()) - { - return false; - } - else - { - this.generateLeafNodeList(); - this.generateLeaves(); - this.generateTrunk(); - this.generateLeafNodeBases(); - return true; - } - } -} diff --git a/src/main/java/twilightforest/world/TFGenLargeWinter.java b/src/main/java/twilightforest/world/TFGenLargeWinter.java deleted file mode 100644 index e7a826e18e..0000000000 --- a/src/main/java/twilightforest/world/TFGenLargeWinter.java +++ /dev/null @@ -1,129 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - -public class TFGenLargeWinter extends TFTreeGenerator { - - public TFGenLargeWinter() - { - this(false); - } - - public TFGenLargeWinter(boolean par1) - { - super(par1); - treeBlock = Blocks.log; - treeMeta = 1; - branchMeta = 13; - leafBlock = Blocks.leaves; - leafMeta = 1; - rootBlock = TFBlocks.root; - rootMeta = BlockTFRoots.ROOT_META; - - } - - @Override - public boolean generate(World world, Random random, int x, int y, int z) { - // determine a height - int treeHeight = 35; - if (random.nextInt(3) == 0) { - treeHeight += random.nextInt(10); - - if (random.nextInt(8) == 0) { - treeHeight += random.nextInt(10); - } - } - - // check if we're on dirt or grass - Block blockUnder = world.getBlock(x, y - 1, z); - if(blockUnder != Blocks.grass && blockUnder != Blocks.dirt || y >= TFWorld.MAXHEIGHT - treeHeight) - { - return false; - } - - - //okay build a tree! Go up to the height - buildTrunk(world, x, y, z, treeHeight); - - // make leaves - makeLeaves(world, x, y, z, treeHeight); - - // roots! - int numRoots = 4 + random.nextInt(3); - float offset = random.nextFloat(); - for (int b = 0; b < numRoots; b++) - { - buildRoot(world, x, y, z, offset, b); - } - - return true; - } - - private void makeLeaves(World world, int x, int y, int z, int treeHeight) { - int offGround = 3; - int leafType = 1; - - for (int dy = 0; dy < treeHeight; dy++) { - - int radius = leafRadius(treeHeight, dy, leafType); - - this.makeLeafCircle2(world, x, y + offGround + treeHeight - dy, z, radius, leafBlock, leafMeta, false); - this.makePineBranches(world, x, y + offGround + treeHeight - dy, z, radius); - } - } - - private void makePineBranches(World world, int x, int y, int z, int radius) { - int branchLength = radius > 4 ? radius - 1 : radius - 2; - - switch (y % 2) - { - case 0: - // branches - for (int i = 1; i <= branchLength; i++) - { - this.setBlockAndMetadata(world, x + 0 - i, y, z + 0, treeBlock, branchMeta & 3 | 4); - this.setBlockAndMetadata(world, x + 0, y, z + 1 + i, treeBlock, branchMeta & 3 | 8); - this.setBlockAndMetadata(world, x + 1 + i, y, z + 1, treeBlock, branchMeta & 3 | 4); - this.setBlockAndMetadata(world, x + 1, y, z - 0 - i, treeBlock, branchMeta & 3 | 8); - } - break; - case 1: - for (int i = 1; i <= branchLength; i++) - { - this.setBlockAndMetadata(world, x + 0 - i, y, z + 1, treeBlock, branchMeta & 3 | 4); - this.setBlockAndMetadata(world, x + 1, y, z + 1 + i, treeBlock, branchMeta & 3 | 8); - this.setBlockAndMetadata(world, x + 1 + i, y, z + 0, treeBlock, branchMeta & 3 | 4); - this.setBlockAndMetadata(world, x + 0, y, z - 0 - i, treeBlock, branchMeta & 3 | 8); - } - break; - } - } - - private int leafRadius(int treeHeight, int dy, int functionType) { - switch (functionType) { - case 0: - default: - return (dy - 1) % 4; - case 1: - return (int)(4F * (float)dy / (float)treeHeight + (0.75F * dy % 3)); - case 99: - return (treeHeight - (dy / 2) - 1) % 4; // bad - } - } - - private void buildTrunk(World world, int x, int y, int z, int treeHeight) { - for (int dy = 0; dy < treeHeight; dy++) { - this.setBlockAndMetadata(world, x + 0, y + dy, z + 0, treeBlock, treeMeta); - this.setBlockAndMetadata(world, x + 1, y + dy, z + 0, treeBlock, treeMeta); - this.setBlockAndMetadata(world, x + 0, y + dy, z + 1, treeBlock, treeMeta); - this.setBlockAndMetadata(world, x + 1, y + dy, z + 1, treeBlock, treeMeta); - } - } - -} diff --git a/src/main/java/twilightforest/world/TFGenMangroveTree.java b/src/main/java/twilightforest/world/TFGenMangroveTree.java deleted file mode 100644 index a0ef8cbc99..0000000000 --- a/src/main/java/twilightforest/world/TFGenMangroveTree.java +++ /dev/null @@ -1,180 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.World; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - - -public class TFGenMangroveTree extends TFTreeGenerator { - - boolean checkForWater; - - - public TFGenMangroveTree() - { - this(false); - } - - public TFGenMangroveTree(boolean par1) - { - super(par1); - - this.checkForWater = !par1; - - treeBlock = TFBlocks.log; - treeMeta = 2; - branchMeta = 14; - leafBlock = TFBlocks.leaves; - leafMeta = 2; - rootBlock = TFBlocks.root; - rootMeta = BlockTFRoots.ROOT_META; - } - - @Override - public boolean generate(World world, Random random, int x, int y, int z) - { - // we only start over water - if ((this.checkForWater && world.getBlock(x, y - 1, z) != Blocks.water) || y >= 128 - 18 - 1) - { - return false; - } - - //okay build a trunk! Start 5 squares off the ground and go up maybe 6-9 squares - buildBranch(world, random, x, y, z, 5, 6 + random.nextInt(3), 0, 0, true); - - // make 0-3 branches - int numBranches = random.nextInt(3); - double offset = random.nextDouble(); - for (int b = 0; b < numBranches; b++) - { - buildBranch(world, random, x, y, z, 7 + b, 6 + random.nextInt(2), 0.3 * b + offset, 0.25, false); - } - - // make 3-5 roots - int numRoots = 3 + random.nextInt(2); - offset = random.nextDouble(); - for (int i = 0; i < numRoots; i++) - { - double rTilt = 0.75 + (random.nextDouble() * 0.1); - buildRoot(world, x, y, z, 5, 12, 0.4 * i + offset, rTilt); - } - - // add a firefly (torch) to the trunk - addFirefly(world, x, y, z, 5 + random.nextInt(5), random.nextDouble()); - - - return true; - } - - /** - * Build a branch with a flat blob of leaves at the end. - * - * @param height - * @param length - * @param angle - * @param tilt - */ - void buildBranch(World world, Random random, int x, int y, int z, int height, double length, double angle, double tilt, boolean trunk) - { - ChunkCoordinates src = new ChunkCoordinates(x, y + height, z); - ChunkCoordinates dest = translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); - - - // constrain branch spread - if ((dest.posX - x) < -4) - { - dest.posX = x - 4; - } - if ((dest.posX - x) > 4) - { - dest.posX = x + 4; - } - if ((dest.posZ - z) < -4) - { - dest.posZ = z - 4; - } - if ((dest.posZ - z) > 4) - { - dest.posZ = z + 4; - } - - drawBresehnam(world, src.posX, src.posY, src.posZ, dest.posX, dest.posY, dest.posZ, treeBlock, trunk ? treeMeta : branchMeta); - - - // variable size leaves - int bSize = 2 + random.nextInt(3); - - // we only need these side blocks if the size is > 2 - if (bSize > 2) { - setBlockAndMetadata(world, dest.posX + 1, dest.posY, dest.posZ, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX - 1, dest.posY, dest.posZ, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX, dest.posY, dest.posZ + 1, treeBlock, branchMeta); - setBlockAndMetadata(world, dest.posX, dest.posY, dest.posZ - 1, treeBlock, branchMeta); - } - // leaves! - makeLeafCircle(world, dest.posX, dest.posY - 1, dest.posZ, (byte)(bSize - 1), leafBlock, leafMeta); - makeLeafCircle(world, dest.posX, dest.posY, dest.posZ, (byte)(bSize), leafBlock, leafMeta); - makeLeafCircle(world, dest.posX, dest.posY + 1, dest.posZ, (byte)(bSize - 2), leafBlock, leafMeta); - } - - /** - * Build a root. (Which is really like a branch without the leaves) - * - * @param height - * @param length - * @param angle - * @param tilt - */ - void buildRoot(World world, int x, int y, int z, int height, double length, double angle, double tilt) - { - ChunkCoordinates src = new ChunkCoordinates(x, y + height, z); - ChunkCoordinates dest = translateCoords(src.posX, src.posY, src.posZ, length, angle, tilt); - - ChunkCoordinates[] lineArray = getBresehnamArrayCoords(src, dest); - boolean stillAboveGround = true; - for (ChunkCoordinates coord : lineArray) - { - if (stillAboveGround && hasAirAround(world, coord.posX, coord.posY, coord.posZ)) { - this.setBlockAndMetadata(world, coord.posX, coord.posY, coord.posZ, treeBlock, branchMeta); - this.setBlockAndMetadata(world, coord.posX, coord.posY - 1, coord.posZ, treeBlock, branchMeta); - } - else { - this.placeRootBlock(world, coord.posX, coord.posY, coord.posZ, rootBlock, rootMeta); - this.placeRootBlock(world, coord.posX, coord.posY - 1, coord.posZ, rootBlock, rootMeta); - stillAboveGround = false; - } - } - - } - - /** - * Add a firefly at the specified height and angle. - * - * @param height how far up the tree - * @param angle from 0 - 1 rotation around the tree - */ - private void addFirefly(World world, int x, int y, int z, int height, double angle) - { - int iAngle = (int)(angle * 4.0); - if (iAngle == 0) - { - setBlockAndMetadata(world, x + 1, y + height, z, TFBlocks.firefly, 0); - } - else if (iAngle == 1) - { - setBlockAndMetadata(world, x - 1, y + height, z, TFBlocks.firefly, 0); - } - else if (iAngle == 2) - { - setBlockAndMetadata(world, x, y + height, z + 1, TFBlocks.firefly, 0); - } - else if (iAngle == 3) - { - setBlockAndMetadata(world, x, y + height, z - 1, TFBlocks.firefly, 0); - } - } -} diff --git a/src/main/java/twilightforest/world/TFGenMinersTree.java b/src/main/java/twilightforest/world/TFGenMinersTree.java deleted file mode 100644 index d5881edba6..0000000000 --- a/src/main/java/twilightforest/world/TFGenMinersTree.java +++ /dev/null @@ -1,109 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.material.Material; -import net.minecraft.world.World; -import twilightforest.block.BlockTFMagicLogSpecial; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - - -public class TFGenMinersTree extends TFTreeGenerator -{ - - public TFGenMinersTree() - { - this(false); - } - - - public TFGenMinersTree(boolean notify) - { - super(notify); - this.treeBlock = TFBlocks.magicLog; - this.treeMeta = 2; - this.branchMeta = treeMeta | 12; - this.leafBlock = TFBlocks.magicLeaves; - this.leafMeta = 2; - this.rootBlock = TFBlocks.root; - this.rootMeta = BlockTFRoots.ROOT_META; - } - - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) - { - - // check soil - Material materialUnder = world.getBlock(x, y - 1, z).getMaterial(); - if ((materialUnder != Material.grass && materialUnder != Material.ground) || y >= TFWorld.MAXHEIGHT - 12) - { - return false; - } - - // 9 block high trunk - for (int dy = 0; dy < 10; dy++) - { - setBlockAndMetadata(world, x, y + dy, z, treeBlock, branchMeta); - } - - // branches with leaf blocks - putBranchWithLeaves(world, x, y + 9, z + 1, true); - putBranchWithLeaves(world, x, y + 9, z + 2, false); - putBranchWithLeaves(world, x, y + 8, z + 3, false); - putBranchWithLeaves(world, x, y + 7, z + 4, false); - putBranchWithLeaves(world, x, y + 6, z + 5, false); - - putBranchWithLeaves(world, x, y + 9, z - 1, true); - putBranchWithLeaves(world, x, y + 9, z - 2, false); - putBranchWithLeaves(world, x, y + 8, z - 3, false); - putBranchWithLeaves(world, x, y + 7, z - 4, false); - putBranchWithLeaves(world, x, y + 6, z - 5, false); - - // place minewood core - setBlockAndMetadata(world, x, y + 1, z, TFBlocks.magicLogSpecial, BlockTFMagicLogSpecial.META_MINE); - world.scheduleBlockUpdate(x, y + 1, z, TFBlocks.magicLogSpecial, TFBlocks.magicLogSpecial.tickRate(world)); - - - // root bulb - if (hasAirAround(world, x, y - 1, z)) { - this.setBlockAndMetadata(world, x, y - 1, z, treeBlock, treeMeta); - } - else { - this.setBlockAndMetadata(world, x, y - 1, z, rootBlock, rootMeta); - } - - // roots! - int numRoots = 3 + rand.nextInt(2); - double offset = rand.nextDouble(); - for (int b = 0; b < numRoots; b++) - { - buildRoot(world, x, y, z, offset, b); - } - - return true; - } - - - protected void putBranchWithLeaves(World world, int bx, int by, int bz, boolean bushy) { - setBlockAndMetadata(world, bx, by, bz, treeBlock, branchMeta); - - for (int lx = -1; lx <= 1; lx++) - { - for (int ly = -1; ly <= 1; ly++) - { - for (int lz = -1; lz <= 1; lz++) - { - if (!bushy && Math.abs(ly) > 0 && Math.abs(lx) > 0) - { - continue; - } - putLeafBlock(world, bx + lx, by + ly, bz + lz, leafBlock, leafMeta); - } - } - } - } - - -} diff --git a/src/main/java/twilightforest/world/TFGenMonolith.java b/src/main/java/twilightforest/world/TFGenMonolith.java deleted file mode 100644 index 10bbaaca95..0000000000 --- a/src/main/java/twilightforest/world/TFGenMonolith.java +++ /dev/null @@ -1,95 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.entity.passive.EntityTFRaven; - - -/** - * A 2x2 monolith of obsidian - * - * @author Ben - * - */ -public class TFGenMonolith extends TFGenerator { - - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - int ht = rand.nextInt(10) + 10; - int dir = rand.nextInt(4); - int h0, h1, h2, h3; - - if (!isAreaSuitable(world, rand, x, y, z, 2, ht, 2)) - { - return false; - } - - - switch (dir) - { - case 0: - h0 = ht; - h1 = (int)(ht * .75); - h2 = (int)(ht * .75); - h3 = (int)(ht * .5); - break; - case 1: - h0 = (int)(ht * .5); - h1 = ht; - h2 = (int)(ht * .75); - h3 = (int)(ht * .75); - break; - case 2: - h0 = (int)(ht * .75); - h1 = (int)(ht * .5); - h2 = ht; - h3 = (int)(ht * .75); - break; - case 3: - default: - h0 = (int)(ht * .75); - h1 = (int)(ht * .75); - h2 = (int)(ht * .5); - h3 = ht; - break; - } - - - for (int cy = 0; cy <= h0; cy++) - { - setBlock(world, x + 0, y + cy - 1, z + 0, cy == ht ? Blocks.lapis_block : Blocks.obsidian); - } - for (int cy = 0; cy <= h1; cy++) - { - setBlock(world, x + 1, y + cy - 1, z + 0, cy == ht ? Blocks.lapis_block : Blocks.obsidian); - } - for (int cy = 0; cy <= h2; cy++) - { - setBlock(world, x + 0, y + cy - 1, z + 1, cy == ht ? Blocks.lapis_block : Blocks.obsidian); - } - for (int cy = 0; cy <= h3; cy++) - { - setBlock(world, x + 1, y + cy - 1, z + 1, cy == ht ? Blocks.lapis_block : Blocks.obsidian); - } - - // spawn a few ravens nearby - for (int i = 0; i < 2; i++) - { - int dx = (x + rand.nextInt(8)) - rand.nextInt(8); - int dz = (z + rand.nextInt(8)) - rand.nextInt(8); - int dy = world.getTopSolidOrLiquidBlock(dx, dz); - - EntityTFRaven raven = new EntityTFRaven(world); - raven.setLocationAndAngles(dx, dy, dz, rand.nextFloat() * 360.0F, 0.0F); - - world.spawnEntityInWorld(raven); - - } - - return true; - } -} - diff --git a/src/main/java/twilightforest/world/TFGenMyceliumBlob.java b/src/main/java/twilightforest/world/TFGenMyceliumBlob.java deleted file mode 100644 index fd8c4fad3e..0000000000 --- a/src/main/java/twilightforest/world/TFGenMyceliumBlob.java +++ /dev/null @@ -1,65 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenerator; - - -/** - * This is a copypasta of the sand/gravel/clay generator that produces mycelium blobs for mushroom biomes - * - * @author Ben - * - */ -public class TFGenMyceliumBlob extends WorldGenerator -{ - private Block myceliumBlockId; - private int numberOfBlocks; - - public TFGenMyceliumBlob(int i) - { - myceliumBlockId = Blocks.mycelium; - numberOfBlocks = i; - } - - public TFGenMyceliumBlob(Block block, int i) - { - myceliumBlockId = block; - numberOfBlocks = i; - } - - public boolean generate(World world, Random random, int x, int y, int z) - { -// if (world.getBlock(i, j, k).getMaterial() != Material.water) -// { -// return false; -// } - int range = random.nextInt(numberOfBlocks - 2) + 2; - int yRange = 1; - for (int dx = x - range; dx <= x + range; dx++) - { - for (int dz = z - range; dz <= z + range; dz++) - { - int l1 = dx - x; - int i2 = dz - z; - if (l1 * l1 + i2 * i2 > range * range) - { - continue; - } - for (int dy = y - yRange; dy <= y + yRange; dy++) - { - Block blockThere = world.getBlock(dx, dy, dz); - if (blockThere == Blocks.dirt || blockThere == Blocks.grass || blockThere == Blocks.stone) - { - world.setBlock(dx, dy, dz, myceliumBlockId, 0, 2); - } - } - } - } - - return true; - } -} diff --git a/src/main/java/twilightforest/world/TFGenNoTree.java b/src/main/java/twilightforest/world/TFGenNoTree.java deleted file mode 100644 index b7c531b730..0000000000 --- a/src/main/java/twilightforest/world/TFGenNoTree.java +++ /dev/null @@ -1,24 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.world.World; - -/** - * Used to generate no particular tree - */ -public class TFGenNoTree extends TFTreeGenerator { - - public TFGenNoTree() { - } - - public TFGenNoTree(boolean par1) { - super(par1); - } - - @Override - public boolean generate(World world, Random random, int i, int j, int k) { - return false; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenOutsideStalagmite.java b/src/main/java/twilightforest/world/TFGenOutsideStalagmite.java deleted file mode 100644 index 9585a47e6a..0000000000 --- a/src/main/java/twilightforest/world/TFGenOutsideStalagmite.java +++ /dev/null @@ -1,34 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - - -/** - * Makes a Stalagmite suitable for outside appearances. - * - * @author Ben - * - */ -public class TFGenOutsideStalagmite extends TFGenCaveStalactite { - - public TFGenOutsideStalagmite() { - super(Blocks.stone, 1.0F, false); - } - - public boolean generate(World world, Random rand, int x, int y, int z) - { - int length = rand.nextInt(10) + 5; - - if (!isAreaSuitable(world, rand, x, y, z, 1, length, 1)) - { - return false; - } - - // I think we already have code for this! :D - return makeSpike(world, rand, x, y - 1, z, length); - } - -} diff --git a/src/main/java/twilightforest/world/TFGenPenguins.java b/src/main/java/twilightforest/world/TFGenPenguins.java deleted file mode 100644 index a27dc459d6..0000000000 --- a/src/main/java/twilightforest/world/TFGenPenguins.java +++ /dev/null @@ -1,32 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.world.World; -import twilightforest.entity.passive.EntityTFPenguin; - - - -public class TFGenPenguins extends TFGenerator { - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - - for (int i = 0; i < 10; i++) - { - int dx = (x + rand.nextInt(8)) - rand.nextInt(8); - int dz = (z + rand.nextInt(8)) - rand.nextInt(8); - int dy = world.getTopSolidOrLiquidBlock(dx, dz); - - EntityTFPenguin penguin = new EntityTFPenguin(world); - penguin.setLocationAndAngles(dx, dy, dz, rand.nextFloat() * 360.0F, 0.0F); - - world.spawnEntityInWorld(penguin); - - } - - return true; - - } - -} diff --git a/src/main/java/twilightforest/world/TFGenPlantRoots.java b/src/main/java/twilightforest/world/TFGenPlantRoots.java deleted file mode 100644 index a23e64a3e9..0000000000 --- a/src/main/java/twilightforest/world/TFGenPlantRoots.java +++ /dev/null @@ -1,33 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.world.World; -import twilightforest.block.BlockTFPlant; -import twilightforest.block.TFBlocks; - - - -public class TFGenPlantRoots extends TFGenerator -{ - public boolean generate(World par1World, Random par2Random, int x, int y, int z) - { - int copyX = x; - int copyZ = z; - - for (; y > 5; --y) - { - if (par1World.isAirBlock(x, y, z) && BlockTFPlant.canPlaceRootBelow(par1World, x, y + 1, z) && par2Random.nextInt(6) > 0) - { - par1World.setBlock(x, y, z, TFBlocks.plant, BlockTFPlant.META_ROOT_STRAND, 2); - } - else - { - x = copyX + par2Random.nextInt(4) - par2Random.nextInt(4); - z = copyZ + par2Random.nextInt(4) - par2Random.nextInt(4); - } - } - - return true; - } -} diff --git a/src/main/java/twilightforest/world/TFGenRavine.java b/src/main/java/twilightforest/world/TFGenRavine.java index 611a7b3411..5c1db47dc8 100644 --- a/src/main/java/twilightforest/world/TFGenRavine.java +++ b/src/main/java/twilightforest/world/TFGenRavine.java @@ -1,218 +1,237 @@ package twilightforest.world; -import java.util.Random; - import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; -import net.minecraft.util.MathHelper; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.ChunkPrimer; import net.minecraft.world.gen.MapGenBase; import twilightforest.TFFeature; import twilightforest.block.TFBlocks; +import java.util.Random; + +//FIXME: AtomicBlom - Deobfuscate this crap +public class TFGenRavine extends MapGenBase { + + protected static final IBlockState AIR = Blocks.AIR.getDefaultState(); + private final float[] rs = new float[1024]; + + private Biome[] biomes; + + //[VanillaCopy] Based on MapGenRavine.addTunnel, modified for the lowered chunk height of TF. + protected void addTunnel(long p_180707_1_, int p_180707_3_, int p_180707_4_, ChunkPrimer p_180707_5_, double p_180707_6_, + double p_180707_8_, double p_180707_10_, float p_180707_12_, float p_180707_13_, float p_180707_14_, + int p_180707_15_, int p_180707_16_, double p_180707_17_) { + + Random random = new Random(p_180707_1_); + double d0 = (double) (p_180707_3_ * 16 + 8); + double d1 = (double) (p_180707_4_ * 16 + 8); + float f = 0.0F; + float f1 = 0.0F; + + if (p_180707_16_ <= 0) { + int i = this.range * 16 - 16; + p_180707_16_ = i - random.nextInt(i / 4); + } + + boolean flag1 = false; + + if (p_180707_15_ == -1) { + p_180707_15_ = p_180707_16_ / 2; + flag1 = true; + } + + float f2 = 1.0F; + + for (int j = 0; j < TFWorld.CHUNKHEIGHT; ++j) { + if (j == 0 || random.nextInt(3) == 0) { + f2 = 1.0F + random.nextFloat() * random.nextFloat(); + } + + this.rs[j] = f2 * f2; + } + + for (; p_180707_15_ < p_180707_16_; ++p_180707_15_) { + double d9 = 1.5D + (double) (MathHelper.sin((float) p_180707_15_ * (float) Math.PI / (float) p_180707_16_) * p_180707_12_); + double d2 = d9 * p_180707_17_; + d9 = d9 * ((double) random.nextFloat() * 0.25D + 0.75D); + d2 = d2 * ((double) random.nextFloat() * 0.25D + 0.75D); + float f3 = MathHelper.cos(p_180707_14_); + float f4 = MathHelper.sin(p_180707_14_); + p_180707_6_ += (double) (MathHelper.cos(p_180707_13_) * f3); + p_180707_8_ += (double) f4; + p_180707_10_ += (double) (MathHelper.sin(p_180707_13_) * f3); + p_180707_14_ = p_180707_14_ * 0.7F; + p_180707_14_ = p_180707_14_ + f1 * 0.05F; + p_180707_13_ += f * 0.05F; + f1 = f1 * 0.8F; + f = f * 0.5F; + f1 = f1 + (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F; + f = f + (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0F; + + if (flag1 || random.nextInt(4) != 0) { + double d3 = p_180707_6_ - d0; + double d4 = p_180707_10_ - d1; + double d5 = (double) (p_180707_16_ - p_180707_15_); + double d6 = (double) (p_180707_12_ + 2.0F + 16.0F); + + if (d3 * d3 + d4 * d4 - d5 * d5 > d6 * d6) { + return; + } + + if (p_180707_6_ >= d0 - 16.0D - d9 * 2.0D && p_180707_10_ >= d1 - 16.0D - d9 * 2.0D && p_180707_6_ <= d0 + 16.0D + d9 * 2.0D && p_180707_10_ <= d1 + 16.0D + d9 * 2.0D) { + int k2 = MathHelper.floor(p_180707_6_ - d9) - p_180707_3_ * 16 - 1; + int k = MathHelper.floor(p_180707_6_ + d9) - p_180707_3_ * 16 + 1; + int l2 = MathHelper.floor(p_180707_8_ - d2) - 1; + int l = MathHelper.floor(p_180707_8_ + d2) + 1; + int i3 = MathHelper.floor(p_180707_10_ - d9) - p_180707_4_ * 16 - 1; + int i1 = MathHelper.floor(p_180707_10_ + d9) - p_180707_4_ * 16 + 1; + + if (k2 < 0) { + k2 = 0; + } + + if (k > 16) { + k = 16; + } + + if (l2 < 1) { + l2 = 1; + } + + if (l > TFWorld.CHUNKHEIGHT - 8) { + l = TFWorld.CHUNKHEIGHT - 8; + } + + if (i3 < 0) { + i3 = 0; + } + + if (i1 > 16) { + i1 = 16; + } + + boolean flag2 = false; + + for (int j1 = k2; !flag2 && j1 < k; ++j1) { + for (int k1 = i3; !flag2 && k1 < i1; ++k1) { + for (int l1 = l + 1; !flag2 && l1 >= l2 - 1; --l1) { + if (l1 >= 0 && l1 < TFWorld.CHUNKHEIGHT) { + if (isOceanBlock(p_180707_5_, j1, l1, k1, p_180707_3_, p_180707_4_)) { + flag2 = true; + } + + if (l1 != l2 - 1 && j1 != k2 && j1 != k - 1 && k1 != i3 && k1 != i1 - 1) { + l1 = l2; + } + } + } + } + } + + if (!flag2) { + for (int j3 = k2; j3 < k; ++j3) { + double d10 = ((double) (j3 + p_180707_3_ * 16) + 0.5D - p_180707_6_) / d9; + + for (int i2 = i3; i2 < i1; ++i2) { + double d7 = ((double) (i2 + p_180707_4_ * 16) + 0.5D - p_180707_10_) / d9; + boolean flag = false; + + if (d10 * d10 + d7 * d7 < 1.0D) { + for (int j2 = l; j2 > l2; --j2) { + double d8 = ((double) (j2 - 1) + 0.5D - p_180707_8_) / d2; + + if ((d10 * d10 + d7 * d7) * (double) this.rs[j2 - 1] + d8 * d8 / 6.0D < 1.0D) { + if (isTopBlock(p_180707_5_, j3, j2, i2, p_180707_3_, p_180707_4_)) { + flag = true; + } + + digBlock(p_180707_5_, j3, j2, i2, p_180707_3_, p_180707_4_, flag); + } + } + } + } + } + + if (flag1) { + break; + } + } + } + } + } + } + + //[VanillaCopy] Based on MapGenRavine.recursiveGenerate, modified for TF chunk decorations. + @Override + @SuppressWarnings("unused") + protected void recursiveGenerate(World world, int chunkX, int chunkZ, int p_180701_4_, int p_180701_5_, ChunkPrimer primer) { + if (this.rand.nextInt(127) == 0) { + if (!TFFeature.getNearestFeature(p_180701_4_, p_180701_5_, world).areChunkDecorationsEnabled) { + return; + } + + this.biomes = world.getBiomeProvider().getBiomes(this.biomes, chunkX << 4, chunkZ << 4, 16, 16); + + double d0 = (double) (chunkX * 16 + this.rand.nextInt(16)); + double d1 = (double) (this.rand.nextInt(this.rand.nextInt(40) + 8) + 20); + double d2 = (double) (chunkZ * 16 + this.rand.nextInt(16)); + int i = 1; + + for (int j = 0; j < 1; ++j) { + float f = this.rand.nextFloat() * ((float) Math.PI * 2F); + float f1 = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; + float f2 = (this.rand.nextFloat() * 2.0F + this.rand.nextFloat()) * 2.0F; + this.addTunnel(this.rand.nextLong(), p_180701_4_, p_180701_5_, primer, d0, d1, d2, f2, f, f1, 0, 0, 3.0D); + } + } + } + + //[VanillaCopy] MapGenRavine.isOceanBlock + protected boolean isOceanBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) { + Block block = data.getBlockState(x, y, z).getBlock(); + return block == Blocks.FLOWING_WATER || block == Blocks.WATER; + } + + //Determine if the block at the specified location is the top block for the biome, we take into account + //Vanilla bugs to make sure that we generate the map the same way vanilla does. + private boolean isTopBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ) { + IBlockState state = data.getBlockState(x, y, z); + return state.getBlock() == Blocks.GRASS; + } + + /** + * Digs out the current block, default implementation removes stone, filler, and top block + * Sets the block to lava if y is less then 10, and air other wise. + * If setting to air, it also checks to see if we've broken the surface and if so + * tries to make the floor the biome's top block + * + * @param data Block data array + * @param x local X position + * @param y local Y position + * @param z local Z position + * @param chunkX Chunk X position + * @param chunkZ Chunk Y position + * @param foundTop True if we've encountered the biome's top block. Ideally if we've broken the surface. + */ + protected void digBlock(ChunkPrimer data, int x, int y, int z, int chunkX, int chunkZ, boolean foundTop) { + + IBlockState state = data.getBlockState(x, y, z); + Block block = state.getBlock(); + + if (block == Blocks.STONE || block == TFBlocks.trollsteinn || block == Blocks.DIRT || block == Blocks.GRASS) { + data.setBlockState(x, y, z, AIR); + if (foundTop && data.getBlockState(x, y - 1, z).getBlock() == Blocks.DIRT) { + data.setBlockState(x, y - 1, z, getBiome(x, z).topBlock); + } + } + } -public class TFGenRavine extends MapGenBase -{ - private float field_35627_a[]; - - public TFGenRavine() - { - field_35627_a = new float[1024]; - } - - protected void generateRavine(long l, int i, int j, Block blockStorage[], double d, - double d1, double d2, float f, float f1, float f2, - int k, int i1, double d3) - { - Random random = new Random(l); - double d4 = i * 16 + 8; - double d5 = j * 16 + 8; - float f3 = 0.0F; - float f4 = 0.0F; - if (i1 <= 0) - { - int j1 = range * 16 - 16; - i1 = j1 - random.nextInt(j1 / 4); - } - boolean flag = false; - if (k == -1) - { - k = i1 / 2; - flag = true; - } - float f5 = 1.0F; - for (int k1 = 0; k1 < TFWorld.CHUNKHEIGHT; k1++) - { - if (k1 == 0 || random.nextInt(3) == 0) - { - f5 = 1.0F + random.nextFloat() * random.nextFloat() * 1.0F; - } - field_35627_a[k1] = f5 * f5; - } - - for (; k < i1; k++) - { - double d6 = 1.5D + (double)(MathHelper.sin(((float)k * 3.141593F) / (float)i1) * f * 1.0F); - double d7 = d6 * d3; - d6 *= (double)random.nextFloat() * 0.25D + 0.75D; - d7 *= (double)random.nextFloat() * 0.25D + 0.75D; - float f6 = MathHelper.cos(f2); - float f7 = MathHelper.sin(f2); - d += MathHelper.cos(f1) * f6; - d1 += f7; - d2 += MathHelper.sin(f1) * f6; - f2 *= 0.7F; - f2 += f4 * 0.05F; - f1 += f3 * 0.05F; - f4 *= 0.8F; - f3 *= 0.5F; - f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F; - f3 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4F; - if (!flag && random.nextInt(4) == 0) - { - continue; - } - double d8a = d - d4; - double d9a = d2 - d5; - double d10a = i1 - k; - double d11 = f + 2.0F + 16F; - if ((d8a * d8a + d9a * d9a) - d10a * d10a > d11 * d11) - { - return; - } - if (d < d4 - 16D - d6 * 2D || d2 < d5 - 16D - d6 * 2D || d > d4 + 16D + d6 * 2D || d2 > d5 + 16D + d6 * 2D) - { - continue; - } - int d8 = MathHelper.floor_double(d - d6) - i * 16 - 1; - int l1 = (MathHelper.floor_double(d + d6) - i * 16) + 1; - int d9 = MathHelper.floor_double(d1 - d7) - 1; - int i2 = MathHelper.floor_double(d1 + d7) + 1; - int d10 = MathHelper.floor_double(d2 - d6) - j * 16 - 1; - int j2 = (MathHelper.floor_double(d2 + d6) - j * 16) + 1; - if (d8 < 0) - { - d8 = 0; - } - if (l1 > 16) - { - l1 = 16; - } - if (d9 < 1) - { - d9 = 1; - } - if (i2 > TFWorld.CHUNKHEIGHT - 8) - { - i2 = TFWorld.CHUNKHEIGHT - 8; - } - if (d10 < 0) - { - d10 = 0; - } - if (j2 > 16) - { - j2 = 16; - } - boolean flag1 = false; - for (int k2 = d8; !flag1 && k2 < l1; k2++) - { - for (int i3 = d10; !flag1 && i3 < j2; i3++) - { - for (int j3 = i2 + 1; !flag1 && j3 >= d9 - 1; j3--) - { - int k3 = (k2 * 16 + i3) * TFWorld.CHUNKHEIGHT + j3; - if (j3 < 0 || j3 >= TFWorld.CHUNKHEIGHT) - { - continue; - } - if (blockStorage[k3] == Blocks.water || blockStorage[k3] == Blocks.water) - { - flag1 = true; - } - if (j3 != d9 - 1 && k2 != d8 && k2 != l1 - 1 && i3 != d10 && i3 != j2 - 1) - { - j3 = d9; - } - } - } - } - - if (flag1) - { - continue; - } - for (int l2 = d8; l2 < l1; l2++) - { - double d12 = (((double)(l2 + i * 16) + 0.5D) - d) / d6; - label0: - for (int l3 = d10; l3 < j2; l3++) - { - double d13 = (((double)(l3 + j * 16) + 0.5D) - d2) / d6; - int i4 = (l2 * 16 + l3) * TFWorld.CHUNKHEIGHT + i2; - boolean flag2 = false; - if (d12 * d12 + d13 * d13 >= 1.0D) - { - continue; - } - int j4 = i2 - 1; - do - { - if (j4 < d9) - { - continue label0; - } - double d14 = (((double)j4 + 0.5D) - d1) / d7; - if ((d12 * d12 + d13 * d13) * (double)field_35627_a[j4] + (d14 * d14) / 6D < 1.0D) - { - Block curentBlock = blockStorage[i4]; - if (curentBlock == Blocks.grass) - { - flag2 = true; - } - if (curentBlock == Blocks.stone || curentBlock == TFBlocks.trollSteinn || curentBlock == Blocks.dirt || curentBlock == Blocks.grass) - { - blockStorage[i4] = Blocks.air; - if (flag2 && blockStorage[i4 - 1] == Blocks.dirt) - { - blockStorage[i4 - 1] = this.worldObj.getBiomeGenForCoords(l2 + i * 16, l3 + j * 16).topBlock; - } - } - } - i4--; - j4--; - } - while (true); - } - } - - if (flag) - { - break; - } - } - } - - protected void func_151538_a(World world, int centerChunkX, int centerChunkZ, int currentChunkX, int currentChunkZ, Block shortStorage[]) - { - if (rand.nextInt(127) != 0) - { - return; - } - if (!TFFeature.getNearestFeature(currentChunkX, currentChunkZ, world).areChunkDecorationsEnabled) { - return; - } - double d = centerChunkX * 16 + rand.nextInt(16); - double d1 = rand.nextInt(rand.nextInt(40) + 8) + 20; - double d2 = centerChunkZ * 16 + rand.nextInt(16); - int i1 = 1; - for (int j1 = 0; j1 < i1; j1++) - { - float f = rand.nextFloat() * 3.141593F * 2.0F; - float f1 = ((rand.nextFloat() - 0.5F) * 2.0F) / 8F; - float f2 = (rand.nextFloat() * 2.0F + rand.nextFloat()) * 2.0F; - generateRavine(rand.nextLong(), currentChunkX, currentChunkZ, shortStorage, d, d1, d2, f2, f, f1, 0, 0, 3D); - } - } -} + private Biome getBiome(int x, int z) { + return this.biomes[x & 15 | (z & 15) << 4]; + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/world/TFGenSmallRainboak.java b/src/main/java/twilightforest/world/TFGenSmallRainboak.java deleted file mode 100644 index e3711f63dd..0000000000 --- a/src/main/java/twilightforest/world/TFGenSmallRainboak.java +++ /dev/null @@ -1,19 +0,0 @@ -package twilightforest.world; - - -public class TFGenSmallRainboak extends TFGenSmallTwilightOak -{ - - public TFGenSmallRainboak() - { - this(false); - } - - - public TFGenSmallRainboak(boolean notify) - { - super(notify); - this.leafMeta = 3; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenSmallTwilightOak.java b/src/main/java/twilightforest/world/TFGenSmallTwilightOak.java deleted file mode 100644 index 274ed33c10..0000000000 --- a/src/main/java/twilightforest/world/TFGenSmallTwilightOak.java +++ /dev/null @@ -1,154 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - -public class TFGenSmallTwilightOak extends TFTreeGenerator -{ - /** The minimum height of a generated tree. */ - protected final int minTreeHeight; - - public TFGenSmallTwilightOak(boolean par1) - { - this(par1, 4); - } - - public TFGenSmallTwilightOak(boolean par1, int par2) - { - super(par1); - this.minTreeHeight = par2; - - treeBlock = TFBlocks.log; - treeMeta = 0; - branchMeta = treeMeta | 12; - leafBlock = TFBlocks.leaves; - leafMeta = 0; - rootBlock = TFBlocks.root; - rootMeta = BlockTFRoots.ROOT_META; - } - - public boolean generate(World par1World, Random par2Random, int x, int y, int z) - { - int height = par2Random.nextInt(3) + this.minTreeHeight; - boolean allClear = true; - - if (y >= 1 && y + height + 1 <= 256) - { - int cy; - byte width; - int cz; - Block blockID; - - for (cy = y; cy <= y + 1 + height; ++cy) - { - width = 1; - - if (cy == y) - { - width = 0; - } - - if (cy >= y + 1 + height - 2) - { - width = 2; - } - - for (int cx = x - width; cx <= x + width && allClear; ++cx) - { - for (cz = z - width; cz <= z + width && allClear; ++cz) - { - if (cy >= 0 && cy < 256) - { - blockID = par1World.getBlock(cx, cy, cz); - - Block block = blockID; - - if (blockID != Blocks.air && - !block.isLeaves(par1World, cx, cy, cz) && - blockID != Blocks.grass && - blockID != Blocks.dirt && - !block.isWood(par1World, cx, cy, cz)) - { - allClear = false; - } - } - else - { - allClear = false; - } - } - } - } - - if (!allClear) - { - return false; - } - else - { - Block blockUsing = par1World.getBlock(x, y - 1, z); - - if ((blockUsing == Blocks.grass || blockUsing == Blocks.dirt) && y < 256 - height - 1) - { - this.setBlock(par1World, x, y - 1, z, Blocks.dirt); - width = 3; - byte var18 = 0; - int treeWidth; - int tx; - int var15; - - for (cz = y - width + height; cz <= y + height; ++cz) - { - int number = cz - (y + height); - treeWidth = var18 + 1 - number / 2; - - for (tx = x - treeWidth; tx <= x + treeWidth; ++tx) - { - var15 = tx - x; - - for (int tz = z - treeWidth; tz <= z + treeWidth; ++tz) - { - int var17 = tz - z; - - Block block = par1World.getBlock(tx, cz, tz); - - if ((Math.abs(var15) != treeWidth || Math.abs(var17) != treeWidth || par2Random.nextInt(2) != 0 && number != 0) && - (block == null || block.canBeReplacedByLeaves(par1World, tx, cz, tz))) - { - this.setBlockAndMetadata(par1World, tx, cz, tz, this.leafBlock, this.leafMeta); - } - } - } - } - - for (cz = 0; cz < height; ++cz) - { - blockID = par1World.getBlock(x, y + cz, z); - - Block block = blockID; - - if (blockID == Blocks.air || block == null || block.isLeaves(par1World, x, y + cz, z)) - { - this.setBlockAndMetadata(par1World, x, y + cz, z, this.treeBlock, this.treeMeta); - } - } - - return true; - } - else - { - return false; - } - } - } - else - { - return false; - } - } -} diff --git a/src/main/java/twilightforest/world/TFGenSortingTree.java b/src/main/java/twilightforest/world/TFGenSortingTree.java deleted file mode 100644 index cc48bd95ea..0000000000 --- a/src/main/java/twilightforest/world/TFGenSortingTree.java +++ /dev/null @@ -1,79 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.world.World; -import twilightforest.block.BlockTFMagicLog; -import twilightforest.block.BlockTFMagicLogSpecial; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - - -public class TFGenSortingTree extends TFGenerator -{ - protected Block treeBlock = TFBlocks.magicLog; - protected int treeMeta = BlockTFMagicLog.META_SORT; - protected int branchMeta = treeMeta | 12; - protected Block leafBlock = TFBlocks.magicLeaves; - protected int leafMeta = 3; - protected Block rootBlock = TFBlocks.root; - protected int rootMeta = BlockTFRoots.ROOT_META; - - public TFGenSortingTree() - { - this(false); - } - - - public TFGenSortingTree(boolean notify) - { - super(notify); - } - - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - // check soil - Material materialUnder = world.getBlock(x, y - 1, z).getMaterial(); - if ((materialUnder != Material.grass && materialUnder != Material.ground) || y >= TFWorld.MAXHEIGHT - 12) - { - return false; - } - - // 3 block high trunk - for (int dy = 0; dy < 4; dy++) - { - setBlockAndMetadata(world, x, y + dy, z, treeBlock, treeMeta); - } - - // leaves - putLeaves(world, x, y + 2, z, false); - putLeaves(world, x, y + 3, z, false); - - // sorting engine - setBlockAndMetadata(world, x, y + 1, z, TFBlocks.magicLogSpecial, BlockTFMagicLogSpecial.META_SORT); - - return true; - } - - - protected void putLeaves(World world, int bx, int by, int bz, boolean bushy) { - for (int lx = -1; lx <= 1; lx++) - { - for (int ly = -1; ly <= 1; ly++) - { - for (int lz = -1; lz <= 1; lz++) - { - if (!bushy && Math.abs(ly) > 0 && (Math.abs(lx) + Math.abs(lz)) > 1) - { - continue; - } - putLeafBlock(world, bx + lx, by + ly, bz + lz, leafBlock, leafMeta); - } - } - } - } - -} diff --git a/src/main/java/twilightforest/world/TFGenStoneCircle.java b/src/main/java/twilightforest/world/TFGenStoneCircle.java deleted file mode 100644 index 66d91fc6cc..0000000000 --- a/src/main/java/twilightforest/world/TFGenStoneCircle.java +++ /dev/null @@ -1,38 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.world.World; - - -public class TFGenStoneCircle extends TFGenerator { - - - /** - * We make a stone circle, generally 3 squares in diameter - */ - public boolean generate(World world, Random rand, int x, int y, int z) { - if (!isAreaSuitable(world, rand, x - 3, y, z - 3, 6, 4, 6)) - { - return false; - } - - // okay! circle! - for (int cy = 0; cy <= 2; cy++) - { - setBlock(world, x - 3, y + cy, z, Blocks.mossy_cobblestone); - setBlock(world, x + 3, y + cy, z, Blocks.mossy_cobblestone); - setBlock(world, x, y + cy, z - 3, Blocks.mossy_cobblestone); - setBlock(world, x, y + cy, z + 3, Blocks.mossy_cobblestone); - setBlock(world, x - 2, y + cy, z - 2, Blocks.mossy_cobblestone); - setBlock(world, x + 2, y + cy, z - 2, Blocks.mossy_cobblestone); - setBlock(world, x - 2, y + cy, z + 2, Blocks.mossy_cobblestone); - setBlock(world, x + 2, y + cy, z + 2, Blocks.mossy_cobblestone); - } - - - return true; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenTallGrass.java b/src/main/java/twilightforest/world/TFGenTallGrass.java deleted file mode 100644 index 0c58741eb6..0000000000 --- a/src/main/java/twilightforest/world/TFGenTallGrass.java +++ /dev/null @@ -1,50 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenerator; - -public class TFGenTallGrass extends WorldGenerator { - - private Block tallGrassID; - private int tallGrassMetadata; - private int amount; - - public TFGenTallGrass(Block blockID, int meta, int amount) { - this.amount = amount; - this.tallGrassID = blockID; - this.tallGrassMetadata = meta; - } - - public boolean generate(World par1World, Random par2Random, int x, int y, int z) - { - Block block = null; - do - { - block = par1World.getBlock(x, y, z); - if (block != null && !block.isLeaves(par1World, x, y, z)) - { - break; - } - y--; - } while (y > 0); - - - for (int i = 0; i < amount; ++i) - { - int dx = x + par2Random.nextInt(8) - par2Random.nextInt(8); - int dy = y + par2Random.nextInt(4) - par2Random.nextInt(4); - int dz = z + par2Random.nextInt(8) - par2Random.nextInt(8); - - if (par1World.isAirBlock(dx, dy, dz) && this.tallGrassID.canBlockStay(par1World, dx, dy, dz)) - { - par1World.setBlock(dx, dy, dz, this.tallGrassID, this.tallGrassMetadata, 2); - } - } - - return true; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenThorns.java b/src/main/java/twilightforest/world/TFGenThorns.java deleted file mode 100644 index 5bc78bc5f9..0000000000 --- a/src/main/java/twilightforest/world/TFGenThorns.java +++ /dev/null @@ -1,126 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import twilightforest.block.TFBlocks; - -public class TFGenThorns extends TFGenerator { - - private static final int MAX_SPREAD = 7; - private static final int CHANCE_OF_BRANCH = 3; - private static final int CHANCE_OF_LEAF = 3; - private static final int CHANCE_LEAF_IS_ROSE = 50; - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - - // make a 3-5 long stack going up - int nextLength = 2 + rand.nextInt(4); - int maxLength = 2 + rand.nextInt(4) + rand.nextInt(4) + rand.nextInt(4); - - placeThorns(world, rand, x, y, z, nextLength, ForgeDirection.UP, maxLength, x, y, z); - - - return true; - } - - private void placeThorns(World world, Random rand, int x, int y, int z, int length, ForgeDirection dir, int maxLength, int ox, int oy, int oz) { - boolean complete = false; - for (int i = 0; i < length; i++) { - int dx = x + (dir.offsetX * i); - int dy = y + (dir.offsetY * i); - int dz = z + (dir.offsetZ * i); - - if (Math.abs(dx - ox) < MAX_SPREAD && Math.abs(dz - oz) < MAX_SPREAD && canPlaceThorns(world, dx, dy, dz)) { - this.setBlockAndMetadata(world, dx, dy, dz, TFBlocks.thorns, getMetaFor(dir)); - - // did we make it to the end? - if (i == length - 1) { - complete = true; - // maybe a leaf? or a rose? - if (rand.nextInt(CHANCE_OF_LEAF) == 0 && world.isAirBlock(dx + dir.offsetX, dy + dir.offsetY, dz + dir.offsetZ)) { - if (rand.nextInt(CHANCE_LEAF_IS_ROSE) > 0) { - // leaf - this.setBlockAndMetadata(world, dx + dir.offsetX, dy + dir.offsetY, dz + dir.offsetZ, TFBlocks.leaves3, 0); - } else { - // rose - this.setBlock(world, dx + dir.offsetX, dy + dir.offsetY, dz + dir.offsetZ, TFBlocks.thornRose); - } - } - } - } else { - break; - } - } - - // add another off the end - if (complete && maxLength > 1) { - - ForgeDirection nextDir = ForgeDirection.VALID_DIRECTIONS[rand.nextInt(ForgeDirection.VALID_DIRECTIONS.length)]; - - int nextX = x + (dir.offsetX * (length - 1)) + nextDir.offsetX; - int nextY = y + (dir.offsetY * (length - 1)) + nextDir.offsetY; - int nextZ = z + (dir.offsetZ * (length - 1)) + nextDir.offsetZ; - - int nextLength = 1 + rand.nextInt(maxLength); - - this.placeThorns(world, rand, nextX, nextY, nextZ, nextLength, nextDir, maxLength - 1, ox, oy, oz); - } - - // maybe another branch off the middle - if (complete && length > 3 && rand.nextInt(CHANCE_OF_BRANCH) == 0) { - - int middle = rand.nextInt(length); - - ForgeDirection nextDir = ForgeDirection.VALID_DIRECTIONS[rand.nextInt(ForgeDirection.VALID_DIRECTIONS.length)]; - - int nextX = x + (dir.offsetX * middle) + nextDir.offsetX; - int nextY = y + (dir.offsetY * middle) + nextDir.offsetY; - int nextZ = z + (dir.offsetZ * middle) + nextDir.offsetZ; - - int nextLength = 1 + rand.nextInt(maxLength); - - this.placeThorns(world, rand, nextX, nextY, nextZ, nextLength, nextDir, maxLength - 1, ox, oy, oz); - } - - // maybe a leaf - if (complete && length > 3 && rand.nextInt(CHANCE_OF_LEAF) == 0) { - - int middle = rand.nextInt(length); - - ForgeDirection nextDir = ForgeDirection.VALID_DIRECTIONS[rand.nextInt(ForgeDirection.VALID_DIRECTIONS.length)]; - - int nextX = x + (dir.offsetX * middle) + nextDir.offsetX; - int nextY = y + (dir.offsetY * middle) + nextDir.offsetY; - int nextZ = z + (dir.offsetZ * middle) + nextDir.offsetZ; - - if (world.isAirBlock(nextX, nextY, nextZ)) { - this.setBlockAndMetadata(world, nextX, nextY, nextZ, TFBlocks.leaves3, 0); - } - } - - } - - private boolean canPlaceThorns(World world, int dx, int dy, int dz) { - return world.isAirBlock(dx, dy, dz) || world.getBlock(dx, dy, dz).isLeaves(world, dx, dy, dz); - } - - private int getMetaFor(ForgeDirection dir) { - switch (dir) { - case UNKNOWN: - default: - case UP: - case DOWN: - return 0; - case EAST: - case WEST: - return 4; - case NORTH: - case SOUTH: - return 8; - } - } - -} diff --git a/src/main/java/twilightforest/world/TFGenTorchBerries.java b/src/main/java/twilightforest/world/TFGenTorchBerries.java deleted file mode 100644 index 9f0af6a74d..0000000000 --- a/src/main/java/twilightforest/world/TFGenTorchBerries.java +++ /dev/null @@ -1,34 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.world.World; -import twilightforest.block.BlockTFPlant; -import twilightforest.block.TFBlocks; - - - -public class TFGenTorchBerries extends TFGenerator -{ - public boolean generate(World par1World, Random par2Random, int x, int y, int z) - { - int copyX = x; - int copyZ = z; - - for (; y > 5; --y) - { - if (par1World.isAirBlock(x, y, z) && BlockTFPlant.canPlaceRootBelow(par1World, x, y + 1, z) && par2Random.nextInt(6) > 0) - { - par1World.setBlock(x, y, z, TFBlocks.plant, 13, 2); - break; - } - else - { - x = copyX + par2Random.nextInt(4) - par2Random.nextInt(4); - z = copyZ + par2Random.nextInt(4) - par2Random.nextInt(4); - } - } - - return true; - } -} diff --git a/src/main/java/twilightforest/world/TFGenTreeOfTime.java b/src/main/java/twilightforest/world/TFGenTreeOfTime.java deleted file mode 100644 index 153e6b3c15..0000000000 --- a/src/main/java/twilightforest/world/TFGenTreeOfTime.java +++ /dev/null @@ -1,80 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.block.TFBlocks; - -public class TFGenTreeOfTime extends TFGenHollowTree { - - public TFGenTreeOfTime(boolean par1) { - super(par1); - - this.treeBlock = TFBlocks.magicLog; - this.treeMeta = 0; - this.branchMeta = treeMeta | 12; - this.leafBlock = TFBlocks.magicLeaves; - this.leafMeta = 0; - } - - public boolean generate(World world, Random random, int x, int y, int z) { - - int height = 8; - int diameter = 1; - - // do we have enough height? - if (y < 1 || y + height + diameter > TFWorld.MAXHEIGHT) { - // System.out.println("Failed with hollow tree of height " + - // height); - return false; - } - // make a tree! - - // check if we're on dirt or grass - Block j1 = world.getBlock(x, y - 1, z); - if (j1 != Blocks.grass && j1 != Blocks.dirt) { - return false; - } - - // build the trunk - buildTrunk(world, random, x, y, z, diameter, height); - - // build the crown - buildTinyCrown(world, random, x, y, z, diameter, height); - - // 3-5 roots at the bottom - buildBranchRing(world, random, x, y, z, diameter, 1, 0, 12, 0, 0.75D, 0, 3, 5, 3, false); - - // several more taproots - buildBranchRing(world, random, x, y, z, diameter, 1, 2, 18, 0, 0.9D, 0, 3, 5, 3, false); - - // add clock block - this.setBlockAndMetadata(world, x - 1, y + 2, z, TFBlocks.magicLogSpecial, 0); - - return true; - } - - /** - * Build the crown of the tree. This builds a smaller crown, since the large - * ones were causing some performance issues - */ - protected void buildTinyCrown(World world, Random random, int x, int y, int z, int diameter, int height) { - int crownRadius = 4; - int bvar = 1; - - // 3-5 medium branches starting at the bottom of the crown - buildBranchRing(world, random, x, y, z, diameter, height - crownRadius, 0, crownRadius, 0, 0.35D, 0, bvar, bvar + 2, 1, true); - - // 3-5 medium branches at the crown middle - buildBranchRing(world, random, x, y, z, diameter, height - (crownRadius / 2), 0, crownRadius, 0, 0.28D, 0, bvar, bvar + 2, 1, true); - - // 2-4 medium branches at the crown top - buildBranchRing(world, random, x, y, z, diameter, height, 0, crownRadius, 0, 0.15D, 0, 2, 4, 0, true); - - // 3-6 medium branches going straight up - buildBranchRing(world, random, x, y, z, diameter, height, 0, (crownRadius / 2), 0, 0.05D, 0, bvar, bvar + 2, 0, true); - } - -} diff --git a/src/main/java/twilightforest/world/TFGenTreeOfTransformation.java b/src/main/java/twilightforest/world/TFGenTreeOfTransformation.java deleted file mode 100644 index 028f8428fb..0000000000 --- a/src/main/java/twilightforest/world/TFGenTreeOfTransformation.java +++ /dev/null @@ -1,50 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.world.World; -import twilightforest.block.BlockTFMagicLogSpecial; -import twilightforest.block.TFBlocks; - - -public class TFGenTreeOfTransformation extends TFGenCanopyTree -{ - - public TFGenTreeOfTransformation() - { - this(false); - } - - - public TFGenTreeOfTransformation(boolean notify) - { - super(notify); - - this.treeBlock = TFBlocks.magicLog; - this.treeMeta = 1; - this.branchMeta = treeMeta | 12; - this.leafBlock = TFBlocks.magicLeaves; - this.leafMeta = 1; - - this.minHeight = 11; - this.chanceAddFirstFive = Integer.MAX_VALUE; - this.chanceAddSecondFive = Integer.MAX_VALUE; - } - - - @Override - public boolean generate(World world, Random random, int x, int y, int z) { - if(super.generate(world, random, x, y, z)) - { - // heart of transformation - setBlockAndMetadata(world, x, y + 3, z, TFBlocks.magicLogSpecial, BlockTFMagicLogSpecial.META_TRANS); - return true; - } - else - { - return false; - } - } - - -} diff --git a/src/main/java/twilightforest/world/TFGenTrollRoots.java b/src/main/java/twilightforest/world/TFGenTrollRoots.java deleted file mode 100644 index 8480aac327..0000000000 --- a/src/main/java/twilightforest/world/TFGenTrollRoots.java +++ /dev/null @@ -1,39 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.material.Material; -import net.minecraft.world.World; -import twilightforest.block.BlockTFPlant; -import twilightforest.block.BlockTFTrollRoot; -import twilightforest.block.TFBlocks; - - - -public class TFGenTrollRoots extends TFGenerator -{ - public boolean generate(World par1World, Random par2Random, int x, int y, int z) - { - int copyX = x; - int copyZ = z; - - for (; y > 5; --y) - { - if (par1World.isAirBlock(x, y, z) && BlockTFTrollRoot.canPlaceRootBelow(par1World, x, y + 1, z) && par2Random.nextInt(6) > 0) - { - if (par2Random.nextInt(10) == 0) { - par1World.setBlock(x, y, z, TFBlocks.unripeTrollBer); - } else { - par1World.setBlock(x, y, z, TFBlocks.trollVidr); - } - } - else - { - x = copyX + par2Random.nextInt(4) - par2Random.nextInt(4); - z = copyZ + par2Random.nextInt(4) - par2Random.nextInt(4); - } - } - - return true; - } -} diff --git a/src/main/java/twilightforest/world/TFGenWell.java b/src/main/java/twilightforest/world/TFGenWell.java deleted file mode 100644 index 271f7440cd..0000000000 --- a/src/main/java/twilightforest/world/TFGenWell.java +++ /dev/null @@ -1,201 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.world.World; -import twilightforest.TFTreasure; - - - -public class TFGenWell extends TFGenerator { - - - - public boolean generate(World world, Random rand, int x, int y, int z) - { - if (rand.nextInt(4) == 0) - { - return generate4x4Well(world, rand, x, y, z); - } - else - { - return generate3x3Well(world, rand, x, y, z); - } - } - - - /** - * make a cute little well - */ - public boolean generate3x3Well(World world, Random rand, int x, int y, int z) - { - if (!isAreaSuitable(world, rand, x, y, z, 3, 4, 3)) - { - return false; - } - - - // make a cute well! - setBlock(world, x + 0, y, z + 0, Blocks.mossy_cobblestone); - setBlock(world, x + 1, y, z + 0, Blocks.mossy_cobblestone); - setBlock(world, x + 2, y, z + 0, Blocks.mossy_cobblestone); - setBlock(world, x + 0, y, z + 2, Blocks.mossy_cobblestone); - setBlock(world, x + 1, y, z + 2, Blocks.mossy_cobblestone); - setBlock(world, x + 2, y, z + 2, Blocks.mossy_cobblestone); - setBlock(world, x + 0, y, z + 1, Blocks.mossy_cobblestone); - setBlock(world, x + 2, y, z + 1, Blocks.mossy_cobblestone); - - setBlock(world, x + 1, y, z + 1, Blocks.water); - - setBlock(world, x + 0, y + 1, z + 0, Blocks.fence); - setBlock(world, x + 2, y + 1, z + 0, Blocks.fence); - setBlock(world, x + 0, y + 1, z + 2, Blocks.fence); - setBlock(world, x + 2, y + 1, z + 2, Blocks.fence); - - setBlock(world, x + 0, y + 2, z + 0, Blocks.fence); - setBlock(world, x + 2, y + 2, z + 0, Blocks.fence); - setBlock(world, x + 0, y + 2, z + 2, Blocks.fence); - setBlock(world, x + 2, y + 2, z + 2, Blocks.fence); - - setBlockAndMetadata(world, x + 0, y + 3, z + 0, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 1, y + 3, z + 0, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 2, y + 3, z + 0, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 0, y + 3, z + 2, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 1, y + 3, z + 2, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 2, y + 3, z + 2, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 0, y + 3, z + 1, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 2, y + 3, z + 1, Blocks.wooden_slab, 0); - - setBlock(world, x + 1, y + 3, z + 1, Blocks.planks); - - - boolean madeTreasure = false; - // now drill each the well square down 20 squares, or until we hit something - for (int dy = -1; dy >= -20; dy--) - { - Block dblock = world.getBlock(x + 1, y + dy, z + 1); - // we only drill through dirt, grass, gravel and stone - if (dblock != Blocks.dirt && dblock != Blocks.grass && dblock != Blocks.gravel && dblock != Blocks.stone) - { - break; - } - // we also need a solid block under where we're digging - if (!world.getBlock(x + 1, y + dy - 1, z + 1).getMaterial().isSolid()) - { - break; - } - - // okay, we're good to dig. - setBlock(world, x + 1, y + dy, z + 1, Blocks.water); - - // if we're below 15 squares, there's a small chance of treasure - if (dy < -15 && madeTreasure == false && rand.nextInt(8) == 0) { - //TODO: more directions - setBlock(world, x + 2, y + dy, z + 1, Blocks.water); - setBlock(world, x + 3, y + dy + 1, z + 1, Blocks.air); - setBlock(world, x + 3, y + dy, z + 1, Blocks.air); - - //TODO: unique treasure table that is themed for underwater well exploration - TFTreasure.basement.generate(world, rand, x + 3, y + dy, z + 1); - - // set flag so we only get one chest - madeTreasure = true; - } - } - - return true; - } - - - - - /** - * Make a larger well - */ - public boolean generate4x4Well(World world, Random rand, int x, int y, int z) { - if (!isAreaSuitable(world, rand, x, y, z, 4, 4, 4)) - { - return false; - } - - // make a cute well! - setBlock(world, x + 0, y, z + 0, Blocks.mossy_cobblestone); - setBlock(world, x + 1, y, z + 0, Blocks.mossy_cobblestone); - setBlock(world, x + 2, y, z + 0, Blocks.mossy_cobblestone); - setBlock(world, x + 3, y, z + 0, Blocks.mossy_cobblestone); - setBlock(world, x + 0, y, z + 3, Blocks.mossy_cobblestone); - setBlock(world, x + 1, y, z + 3, Blocks.mossy_cobblestone); - setBlock(world, x + 2, y, z + 3, Blocks.mossy_cobblestone); - setBlock(world, x + 3, y, z + 3, Blocks.mossy_cobblestone); - setBlock(world, x + 0, y, z + 1, Blocks.mossy_cobblestone); - setBlock(world, x + 0, y, z + 2, Blocks.mossy_cobblestone); - setBlock(world, x + 3, y, z + 1, Blocks.mossy_cobblestone); - setBlock(world, x + 3, y, z + 2, Blocks.mossy_cobblestone); - - setBlock(world, x + 1, y, z + 1, Blocks.water); - setBlock(world, x + 2, y, z + 1, Blocks.water); - setBlock(world, x + 1, y, z + 2, Blocks.water); - setBlock(world, x + 2, y, z + 2, Blocks.water); - - setBlock(world, x + 0, y + 1, z + 0, Blocks.fence); - setBlock(world, x + 3, y + 1, z + 0, Blocks.fence); - setBlock(world, x + 0, y + 1, z + 3, Blocks.fence); - setBlock(world, x + 3, y + 1, z + 3, Blocks.fence); - - setBlock(world, x + 0, y + 2, z + 0, Blocks.fence); - setBlock(world, x + 3, y + 2, z + 0, Blocks.fence); - setBlock(world, x + 0, y + 2, z + 3, Blocks.fence); - setBlock(world, x + 3, y + 2, z + 3, Blocks.fence); - - setBlockAndMetadata(world, x + 0, y + 3, z + 0, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 1, y + 3, z + 0, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 2, y + 3, z + 0, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 3, y + 3, z + 0, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 0, y + 3, z + 3, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 1, y + 3, z + 3, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 2, y + 3, z + 3, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 3, y + 3, z + 3, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 0, y + 3, z + 1, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 0, y + 3, z + 2, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 3, y + 3, z + 1, Blocks.wooden_slab, 0); - setBlockAndMetadata(world, x + 3, y + 3, z + 2, Blocks.wooden_slab, 0); - - setBlock(world, x + 1, y + 3, z + 1, Blocks.planks); - setBlock(world, x + 2, y + 3, z + 1, Blocks.planks); - setBlock(world, x + 1, y + 3, z + 2, Blocks.planks); - setBlock(world, x + 2, y + 3, z + 2, Blocks.planks); - - - // now drill each of the 4 well squares down 20 squares, or until we hit something - for (int dx = 1; dx <= 2; dx++) - { - for (int dz = 1; dz <= 2; dz++) - { - for (int dy = -1; dy >= -20; dy--) - { - Block dblock = world.getBlock(x + dx, y + dy, z + dz); - // we only drill through dirt, grass, gravel and stone - if (dblock != Blocks.dirt && dblock != Blocks.grass && dblock != Blocks.gravel && dblock != Blocks.stone) - { - break; - } - // we also need a solid block under where we're digging - if (!world.getBlock(x + dx, y + dy - 1, z + dz).getMaterial().isSolid()) - { - break; - } - - // okay, we're good to dig. - setBlock(world, x + dx, y + dy, z + dz, Blocks.water); - } - - } - - } - - return true; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenWitchHut.java b/src/main/java/twilightforest/world/TFGenWitchHut.java deleted file mode 100644 index 8cab2e003e..0000000000 --- a/src/main/java/twilightforest/world/TFGenWitchHut.java +++ /dev/null @@ -1,191 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.MobSpawnerBaseLogic; -import net.minecraft.tileentity.TileEntityMobSpawner; -import net.minecraft.world.World; -import twilightforest.entity.TFCreatures; - - -public class TFGenWitchHut extends TFGenerator { - - /** - * Make a cute witch's hut - */ - public boolean generate(World world, Random rand, int x, int y, int z) - { - return generateTinyHut(world, rand, x, y, z); - } - - /** - * Make the smallest size hut - */ - public boolean generateTinyHut(World world, Random rand, int x, int y, int z) - { - if (!isAreaSuitable(world, rand, x, y, z, 5, 7, 6)) - { - return false; - } - - // walls! - - setBlock(world, x + 1, y + 0, z + 1, randStone(rand, 1)); - setBlock(world, x + 2, y + 0, z + 1, randStone(rand, 1)); - setBlock(world, x + 3, y + 0, z + 1, randStone(rand, 1)); - setBlock(world, x + 5, y + 0, z + 1, randStone(rand, 1)); - setBlock(world, x + 0, y + 0, z + 2, Blocks.brick_block); - setBlock(world, x + 1, y + 0, z + 2, Blocks.brick_block); - setBlock(world, x + 5, y + 0, z + 2, randStone(rand, 1)); - setBlock(world, x + 0, y + 0, z + 3, Blocks.brick_block); - setBlock(world, x + 5, y + 0, z + 3, randStone(rand, 1)); - setBlock(world, x + 0, y + 0, z + 4, Blocks.brick_block); - setBlock(world, x + 1, y + 0, z + 4, Blocks.brick_block); - setBlock(world, x + 5, y + 0, z + 4, randStone(rand, 1)); - setBlock(world, x + 1, y + 0, z + 5, randStone(rand, 1)); - setBlock(world, x + 2, y + 0, z + 5, randStone(rand, 1)); - setBlock(world, x + 3, y + 0, z + 5, randStone(rand, 1)); - setBlock(world, x + 5, y + 0, z + 5, randStone(rand, 1)); - - setBlock(world, x + 1, y + 1, z + 1, randStone(rand, 2)); - setBlock(world, x + 3, y + 1, z + 1, randStone(rand, 2)); - setBlock(world, x + 5, y + 1, z + 1, randStone(rand, 2)); - setBlock(world, x + 0, y + 1, z + 2, Blocks.brick_block); - setBlock(world, x + 1, y + 1, z + 2, Blocks.brick_block); - setBlock(world, x + 5, y + 1, z + 2, randStone(rand, 2)); - setBlock(world, x + 0, y + 1, z + 3, Blocks.brick_block); - setBlock(world, x + 0, y + 1, z + 4, Blocks.brick_block); - setBlock(world, x + 1, y + 1, z + 4, Blocks.brick_block); - setBlock(world, x + 5, y + 1, z + 4, randStone(rand, 2)); - setBlock(world, x + 1, y + 1, z + 5, randStone(rand, 2)); - setBlock(world, x + 3, y + 1, z + 5, randStone(rand, 2)); - setBlock(world, x + 5, y + 1, z + 5, randStone(rand, 2)); - - setBlock(world, x + 1, y + 2, z + 1, randStone(rand, 3)); - setBlock(world, x + 2, y + 2, z + 1, randStone(rand, 3)); - setBlock(world, x + 3, y + 2, z + 1, randStone(rand, 3)); - setBlock(world, x + 4, y + 2, z + 1, randStone(rand, 3)); - setBlock(world, x + 5, y + 2, z + 1, randStone(rand, 3)); - setBlock(world, x + 0, y + 2, z + 2, Blocks.brick_block); - setBlock(world, x + 1, y + 2, z + 2, Blocks.brick_block); - setBlock(world, x + 5, y + 2, z + 2, randStone(rand, 3)); - setBlock(world, x + 0, y + 2, z + 3, Blocks.brick_block); - setBlock(world, x + 5, y + 2, z + 3, randStone(rand, 3)); - setBlock(world, x + 0, y + 2, z + 4, Blocks.brick_block); - setBlock(world, x + 1, y + 2, z + 4, Blocks.brick_block); - setBlock(world, x + 5, y + 2, z + 4, randStone(rand, 1)); - setBlock(world, x + 1, y + 2, z + 5, randStone(rand, 3)); - setBlock(world, x + 2, y + 2, z + 5, randStone(rand, 3)); - setBlock(world, x + 3, y + 2, z + 5, randStone(rand, 3)); - setBlock(world, x + 4, y + 2, z + 5, randStone(rand, 3)); - setBlock(world, x + 5, y + 2, z + 5, randStone(rand, 3)); - - setBlock(world, x + 0, y + 3, z + 2, Blocks.brick_block); - setBlock(world, x + 0, y + 3, z + 3, Blocks.brick_block); - setBlock(world, x + 0, y + 3, z + 4, Blocks.brick_block); - setBlock(world, x + 2, y + 3, z + 1, randStone(rand, 4)); - setBlock(world, x + 3, y + 3, z + 1, randStone(rand, 4)); - setBlock(world, x + 4, y + 3, z + 1, randStone(rand, 4)); - setBlock(world, x + 2, y + 3, z + 5, randStone(rand, 4)); - setBlock(world, x + 3, y + 3, z + 5, randStone(rand, 4)); - setBlock(world, x + 4, y + 3, z + 5, randStone(rand, 4)); - - setBlock(world, x + 0, y + 4, z + 3, Blocks.brick_block); - setBlock(world, x + 3, y + 4, z + 1, randStone(rand, 5)); - setBlock(world, x + 3, y + 4, z + 5, randStone(rand, 5)); - - setBlock(world, x + 0, y + 5, z + 3, Blocks.brick_block); - - setBlock(world, x + 0, y + 6, z + 3, Blocks.brick_block); - - // roof! - setBlockAndMetadata(world, x + 0, y + 2, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 0, y + 2, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 0, y + 2, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 0, y + 2, z + 6, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 6, y + 2, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 6, y + 2, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 6, y + 2, z + 2, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 6, y + 2, z + 3, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 6, y + 2, z + 4, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 6, y + 2, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 6, y + 2, z + 6, Blocks.double_stone_slab, 2); - - setBlockAndMetadata(world, x + 1, y + 3, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 1, y + 3, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 1, y + 3, z + 2, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 1, y + 3, z + 4, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 1, y + 3, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 1, y + 3, z + 6, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 3, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 3, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 3, z + 2, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 3, z + 3, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 3, z + 4, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 3, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 3, z + 6, Blocks.double_stone_slab, 2); - - setBlockAndMetadata(world, x + 1, y + 4, z + 0, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 4, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 4, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 4, z + 2, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 4, z + 3, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 4, z + 4, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 4, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 4, z + 6, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 1, y + 4, z + 6, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 4, z + 0, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 4, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 4, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 4, z + 2, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 4, z + 3, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 4, z + 4, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 4, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 4, z + 6, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 5, y + 4, z + 6, Blocks.stone_slab, 2); - - setBlockAndMetadata(world, x + 2, y + 5, z + 0, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 5, z + 1, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 5, z + 0, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 5, z + 1, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 5, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 5, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 5, z + 2, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 5, z + 3, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 5, z + 4, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 5, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 5, z + 6, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 5, z + 5, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 2, y + 5, z + 6, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 5, z + 5, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 4, y + 5, z + 6, Blocks.stone_slab, 2); - - setBlockAndMetadata(world, x + 3, y + 6, z + 0, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 6, z + 1, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 6, z + 2, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 6, z + 4, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 6, z + 5, Blocks.double_stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 6, z + 6, Blocks.double_stone_slab, 2); - - setBlockAndMetadata(world, x + 3, y + 7, z + 0, Blocks.stone_slab, 2); - setBlockAndMetadata(world, x + 3, y + 7, z + 6, Blocks.stone_slab, 2); - - // fire in chimney! - setBlock(world, x + 1, y - 1, z + 3, Blocks.netherrack); - setBlock(world, x + 1, y + 0, z + 3, Blocks.fire); // oh god the roof! - - // skeleton spawner! - world.setBlock(x + 3, y + 1, z + 3, Blocks.mob_spawner, 0, 2); - TileEntityMobSpawner ms = (TileEntityMobSpawner)world.getTileEntity(x + 3, y + 1, z + 3); - MobSpawnerBaseLogic spawnerLogic = ms.func_145881_a(); - if (spawnerLogic != null) { - spawnerLogic.setEntityName(TFCreatures.getSpawnerNameFor("Skeleton Druid")); - } - - - - return true; - } - -} diff --git a/src/main/java/twilightforest/world/TFGenWoodRoots.java b/src/main/java/twilightforest/world/TFGenWoodRoots.java deleted file mode 100644 index 7d2f6dd2ce..0000000000 --- a/src/main/java/twilightforest/world/TFGenWoodRoots.java +++ /dev/null @@ -1,122 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.World; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - - -public class TFGenWoodRoots extends TFGenerator { - - private Block rootBlock = TFBlocks.root; - private int rootMeta = BlockTFRoots.ROOT_META; - private Block oreBlock = TFBlocks.root; - private int oreMeta = BlockTFRoots.OREROOT_META; - - @Override - public boolean generate(World world, Random rand, int x, int y, int z) { - // start must be in stone - if (world.getBlock(x, y, z) != Blocks.stone) { - return false; - } - - float length = rand.nextFloat() * 6.0F + rand.nextFloat() * 6.0F + 4.0F; - if (length > y) { - length = y; - } - - // tilt between 0.6 and 0.9 - float tilt = 0.6F + rand.nextFloat() * 0.3F; - - return drawRoot(world, rand, x, y, z, length, rand.nextFloat(), tilt); - } - - private boolean drawRoot(World world, Random rand, int x, int y, int z, float length, float angle, float tilt) { - // put origin at where we start - return this.drawRoot(world, rand, x, y, z, x, y, z, length, angle, tilt); - } - - - private boolean drawRoot(World world, Random rand, int ox, int oy, int oz, int x, int y, int z, float length, float angle, float tilt) { - // generate a direction and a length - int[] dest = translate(x, y, z, length, angle, tilt); - - // restrict x and z to within 7 - int limit = 6; - if (ox + limit < dest[0]) - { - dest[0] = ox + limit; - } - if (ox - limit > dest[0]) - { - dest[0] = ox - limit; - } - if (oz + limit < dest[2]) - { - dest[2] = oz + limit; - } - if (oz - limit > dest[2]) - { - dest[2] = oz - limit; - } - - // end must be in stone - if (world.getBlock(dest[0], dest[1], dest[2]) != Blocks.stone) { - return false; - } - - // if both the start and the end are in stone, put a root there - ChunkCoordinates[] lineArray = getBresehnamArrayCoords(x, y, z, dest[0], dest[1], dest[2]); - for (ChunkCoordinates coord : lineArray) { - this.placeRootBlock(world, coord.posX, coord.posY, coord.posZ, rootBlock, rootMeta); - } - - - // if we are long enough, make either another root or an oreball - if (length > 8) { - if (rand.nextInt(3) > 0) { - // length > 8, usually split off into another root half as long - int[] nextSrc = translate(x, y, z, length / 2, angle, tilt); - float nextAngle = (angle + 0.25F + (rand.nextFloat() * 0.5F)) % 1.0F; - float nextTilt = 0.6F + rand.nextFloat() * 0.3F; - drawRoot(world, rand, ox, oy, oz, nextSrc[0], nextSrc[1], nextSrc[2], length / 2.0F, nextAngle, nextTilt); - - - } - } - - if (length > 6) { - if (rand.nextInt(4) == 0) { - // length > 6, potentially make oreball - int[] ballSrc = translate(x, y, z, length / 2, angle, tilt); - int[] ballDest = translate(ballSrc[0], ballSrc[1], ballSrc[2], 1.5, (angle + 0.5F) % 1.0F, 0.75); - - this.placeRootBlock(world, ballSrc[0], ballSrc[1], ballSrc[2], oreBlock, oreMeta); - this.placeRootBlock(world, ballSrc[0], ballSrc[1], ballDest[2], oreBlock, oreMeta); - this.placeRootBlock(world, ballDest[0], ballSrc[1], ballSrc[2], oreBlock, oreMeta); - this.placeRootBlock(world, ballDest[0], ballSrc[1], ballDest[2], oreBlock, oreMeta); - this.placeRootBlock(world, ballSrc[0], ballDest[1], ballSrc[2], oreBlock, oreMeta); - this.placeRootBlock(world, ballSrc[0], ballDest[1], ballDest[2], oreBlock, oreMeta); - this.placeRootBlock(world, ballDest[0], ballDest[1], ballSrc[2], oreBlock, oreMeta); - this.placeRootBlock(world, ballDest[0], ballDest[1], ballDest[2], oreBlock, oreMeta); - } - } - - return true; - } - - /** - * Function used to actually place root blocks if they're not going to break anything important - */ - protected void placeRootBlock(World world, int x, int y, int z, Block rootBlock2, int meta) { - if (TFTreeGenerator.canRootGrowIn(world, x, y, z)) - { - this.setBlockAndMetadata(world, x, y, z, rootBlock2, meta); - } - } - -} diff --git a/src/main/java/twilightforest/world/TFGenerator.java b/src/main/java/twilightforest/world/TFGenerator.java deleted file mode 100644 index c4ada13f12..0000000000 --- a/src/main/java/twilightforest/world/TFGenerator.java +++ /dev/null @@ -1,461 +0,0 @@ -package twilightforest.world; - -import java.util.Random; - -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenerator; - - -public abstract class TFGenerator extends WorldGenerator { - - //protected World worldObj; - - public TFGenerator() { - this(false); - } - - public TFGenerator(boolean par1) { - super(par1); - } - - /** - * Moves distance along the vector. - * - * This goofy function takes a float between 0 and 1 for the angle, where 0 is 0 degrees, .5 is 180 degrees and 1 and 360 degrees. - * For the tilt, it takes a float between 0 and 1 where 0 is straight up, 0.5 is straight out and 1 is straight down. - */ - public static int[] translate(int sx, int sy, int sz, double distance, double angle, double tilt) { - int[] dest = {sx, sy, sz}; - - double rangle = angle * 2.0D * Math.PI; - double rtilt = tilt * Math.PI; - - - dest[0] += Math.round(Math.sin(rangle) * Math.sin(rtilt) * distance); - dest[1] += Math.round(Math.cos(rtilt) * distance); - dest[2] += Math.round(Math.cos(rangle) * Math.sin(rtilt) * distance); - - return dest; - } - - /** - * Moves distance along the vector. - * - * This goofy function takes a float between 0 and 1 for the angle, where 0 is 0 degrees, .5 is 180 degrees and 1 and 360 degrees. - * For the tilt, it takes a float between 0 and 1 where 0 is straight up, 0.5 is straight out and 1 is straight down. - */ - public static ChunkCoordinates translateCoords(int sx, int sy, int sz, double distance, double angle, double tilt) { - ChunkCoordinates dest = new ChunkCoordinates(sx, sy, sz); - - double rangle = angle * 2.0D * Math.PI; - double rtilt = tilt * Math.PI; - - - dest.posX += Math.round(Math.sin(rangle) * Math.sin(rtilt) * distance); - dest.posY += Math.round(Math.cos(rtilt) * distance); - dest.posZ += Math.round(Math.cos(rangle) * Math.sin(rtilt) * distance); - - return dest; - } - - /** - * Draws a line from {x1, y1, z1} to {x2, y2, z2} - */ - protected void drawBresehnam(World world, int x1, int y1, int z1, int x2, int y2, int z2, Block blockValue, int metaValue) - { - ChunkCoordinates[] lineArray = getBresehnamArrayCoords(x1, y1, z1, x2, y2, z2); - for (ChunkCoordinates pixel : lineArray) - { - setBlockAndMetadata(world, pixel.posX, pixel.posY, pixel.posZ, blockValue, metaValue); - } - } - - /** - * Get an array of values that represent a line from point A to point B - */ - public static ChunkCoordinates[] getBresehnamArrayCoords(ChunkCoordinates src, ChunkCoordinates dest) { - return getBresehnamArrayCoords(src.posX, src.posY, src.posZ, dest.posX, dest.posY, dest.posZ); - } - - /** - * Get an array of values that represent a line from point A to point B - */ - public static ChunkCoordinates[] getBresehnamArrayCoords(int x1, int y1, int z1, int x2, int y2, int z2) { - int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2; - - ChunkCoordinates pixel = new ChunkCoordinates(x1, y1, z1); - ChunkCoordinates lineArray[]; - - dx = x2 - x1; - dy = y2 - y1; - dz = z2 - z1; - x_inc = (dx < 0) ? -1 : 1; - l = Math.abs(dx); - y_inc = (dy < 0) ? -1 : 1; - m = Math.abs(dy); - z_inc = (dz < 0) ? -1 : 1; - n = Math.abs(dz); - dx2 = l << 1; - dy2 = m << 1; - dz2 = n << 1; - - if ((l >= m) && (l >= n)) { - err_1 = dy2 - l; - err_2 = dz2 - l; - lineArray = new ChunkCoordinates[l + 1]; - for (i = 0; i < l; i++) { - lineArray[i] = new ChunkCoordinates (pixel); - if (err_1 > 0) { - pixel.posY += y_inc; - err_1 -= dx2; - } - if (err_2 > 0) { - pixel.posZ += z_inc; - err_2 -= dx2; - } - err_1 += dy2; - err_2 += dz2; - pixel.posX += x_inc; - } - } else if ((m >= l) && (m >= n)) { - err_1 = dx2 - m; - err_2 = dz2 - m; - lineArray = new ChunkCoordinates[m + 1]; - for (i = 0; i < m; i++) { - lineArray[i] = new ChunkCoordinates (pixel); - if (err_1 > 0) { - pixel.posX += x_inc; - err_1 -= dy2; - } - if (err_2 > 0) { - pixel.posZ += z_inc; - err_2 -= dy2; - } - err_1 += dx2; - err_2 += dz2; - pixel.posY += y_inc; - } - } else { - err_1 = dy2 - n; - err_2 = dx2 - n; - lineArray = new ChunkCoordinates[n + 1]; - for (i = 0; i < n; i++) { - lineArray[i] = new ChunkCoordinates(pixel); - if (err_1 > 0) { - pixel.posY += y_inc; - err_1 -= dz2; - } - if (err_2 > 0) { - pixel.posX += x_inc; - err_2 -= dz2; - } - err_1 += dy2; - err_2 += dx2; - pixel.posZ += z_inc; - } - } - lineArray[lineArray.length - 1] = new ChunkCoordinates(pixel); - - return lineArray; - } - - /** - * Draw a flat blob (circle) of leaves - */ - public void makeLeafCircle(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue) - { - this.makeLeafCircle(world, sx, sy, sz, rad, blockValue, metaValue, false); - } - - /** - * Draw a flat blob (circle) of leaves - */ - public void makeLeafCircle(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue, boolean useHack) - { - // trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dz = 0; dz <= rad; dz++) - { - int dist = Math.max(dx, dz) + (Math.min(dx, dz) >> 1); - - //hack! I keep getting failing leaves at a certain position. - if (useHack && dx == 3 && dz == 3) { - dist = 6; - } - - // if we're inside the blob, fill it - if (dist <= rad) { - // do four at a time for easiness! - putLeafBlock(world, sx + dx, sy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz - dz, blockValue, metaValue); - } - } - } - } - - /** - * Draw a flat blob (circle) of leaves. This one makes it offset to surround a 2x2 area instead of a 1 block area - */ - public void makeLeafCircle2(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue, boolean useHack) - { - // trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dz = 0; dz <= rad; dz++) - { -// int dist = Math.max(dx, dz) + (int)(Math.min(dx, dz) * 0.6F); -// -// //hack! I keep getting failing leaves at a certain position. -// if (useHack && dx == 3 && dz == 3) { -// dist = 6; -// } - - // if we're inside the blob, fill it - if (dx * dx + dz * dz <= rad * rad) { - // do four at a time for easiness! - putLeafBlock(world, sx + 1 + dx, sy, sz + 1 + dz, blockValue, metaValue); - putLeafBlock(world, sx + 1 + dx, sy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz + 1 + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz - dz, blockValue, metaValue); - } - } - } - } - - /** - * Put a leaf only in spots where leaves can go! - */ - public void putLeafBlock(World world, int x, int y, int z, Block blockValue, int metaValue) { - Block whatsThere = world.getBlock(x, y, z); - Block block = whatsThere; - - if (block == null || block.canBeReplacedByLeaves(world, x, y, z)) - { - this.setBlockAndMetadata(world, x, y, z, blockValue, metaValue); - } - } - - /** - * Gets either cobblestone or mossy cobblestone, randomly. Used for ruins. - * - * @param rand - * @return - */ - protected Block randStone(Random rand, int howMuch) - { - return rand.nextInt(howMuch) >= 1 ? Blocks.cobblestone : Blocks.mossy_cobblestone; - } - - /** - * Checks an area to see if it consists of flat natural ground below and air above - * - */ - protected boolean isAreaSuitable(World world, Random rand, int x, int y, int z, int width, int height, int depth) - { - boolean flag = true; - - - // check if there's anything within the diameter - for (int cx = 0; cx < width; cx++) - { - for (int cz = 0; cz < depth; cz++) - { - // check if the blocks even exist? - if (world.blockExists(x + cx, y, z + cz)) { - // is there grass, dirt or stone below? - Material m = world.getBlock(x + cx, y - 1, z + cz).getMaterial(); - if (m != Material.ground && m != Material.grass && m != Material.rock) - { - flag = false; - } - - for (int cy = 0; cy < height; cy++) - { - // blank space above? - if (!world.isAirBlock(x + cx, y + cy, z + cz)) - { - flag = false; - } - } - } else { - flag = false; - } - } - } - - // Okie dokie - return flag; - - } - - /** - * Draw a giant blob of whatevs. - */ - public void drawBlob(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue) { - // then trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dy = 0; dy <= rad; dy++) - { - for (byte dz = 0; dz <= rad; dz++) - { - // determine how far we are from the center. - int dist = 0; - if (dx >= dy && dx >= dz) { - dist = dx + (Math.max(dy, dz) >> 1) + (Math.min(dy, dz) >> 2); - } else if (dy >= dx && dy >= dz) - { - dist = dy + (Math.max(dx, dz) >> 1) + (Math.min(dx, dz) >> 2); - } else { - dist = dz + (Math.max(dx, dy) >> 1) + (Math.min(dx, dy) >> 2); - } - - - // if we're inside the blob, fill it - if (dist <= rad) { - // do eight at a time for easiness! - setBlockAndMetadata(world, sx + dx, sy + dy, sz + dz, blockValue, metaValue); - setBlockAndMetadata(world, sx + dx, sy + dy, sz - dz, blockValue, metaValue); - setBlockAndMetadata(world, sx - dx, sy + dy, sz + dz, blockValue, metaValue); - setBlockAndMetadata(world, sx - dx, sy + dy, sz - dz, blockValue, metaValue); - setBlockAndMetadata(world, sx + dx, sy - dy, sz + dz, blockValue, metaValue); - setBlockAndMetadata(world, sx + dx, sy - dy, sz - dz, blockValue, metaValue); - setBlockAndMetadata(world, sx - dx, sy - dy, sz + dz, blockValue, metaValue); - setBlockAndMetadata(world, sx - dx, sy - dy, sz - dz, blockValue, metaValue); - } - } - } - } - } - - /** - * Draw a giant blob of leaves. - */ - public void drawLeafBlob(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue) { - // then trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dy = 0; dy <= rad; dy++) - { - for (byte dz = 0; dz <= rad; dz++) - { - // determine how far we are from the center. - int dist = 0; - if (dx >= dy && dx >= dz) { - dist = dx + (Math.max(dy, dz) >> 1) + (Math.min(dy, dz) >> 2); - } else if (dy >= dx && dy >= dz) - { - dist = dy + (Math.max(dx, dz) >> 1) + (Math.min(dx, dz) >> 2); - } else { - dist = dz + (Math.max(dx, dy) >> 1) + (Math.min(dx, dy) >> 2); - } - - - // if we're inside the blob, fill it - if (dist <= rad) { - // do eight at a time for easiness! - putLeafBlock(world, sx + dx, sy + dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy + dy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy + dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy + dy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy - dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy - dy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy - dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy - dy, sz - dz, blockValue, metaValue); - } - } - } - } - } - - /** - * Does the block have only air blocks adjacent - */ - protected static boolean surroundedByAir(IBlockAccess world, int bx, int by, int bz) { - boolean airAround = true; - if (!world.isAirBlock(bx + 1, by, bz)) { - airAround = false; - } - if (!world.isAirBlock(bx - 1, by, bz)) { - airAround = false; - } - if (!world.isAirBlock(bx, by, bz + 1)) { - airAround = false; - } - if (!world.isAirBlock(bx, by, bz - 1)) { - airAround = false; - } - if (!world.isAirBlock(bx, by + 1, bz)) { - airAround = false; - } - if (!world.isAirBlock(bx, by - 1, bz)) { - airAround = false; - } - - return airAround; - } - - /** - * Does the block have at least 1 air block adjacent - */ - protected static boolean hasAirAround(World world, int bx, int by, int bz) { - boolean airAround = false; - if (world.blockExists(bx + 1, by, bz) && world.getBlock(bx + 1, by, bz) == Blocks.air) { - airAround = true; - } - if (world.blockExists(bx - 1, by, bz) && world.getBlock(bx - 1, by, bz) == Blocks.air) { - airAround = true; - } - if (world.blockExists(bx, by, bz + 1) && world.getBlock(bx, by, bz + 1) == Blocks.air) { - airAround = true; - } - if (world.blockExists(bx, by, bz - 1) && world.getBlock(bx, by, bz - 1) == Blocks.air) { - airAround = true; - } - if (world.getBlock(bx, by + 1, bz) == Blocks.air) { - airAround = true; - } - - return airAround; - } - - protected static boolean isNearSolid(World world, int bx, int by, int bz) { - boolean nearSolid = false; - if (world.blockExists(bx + 1, by, bz) && world.getBlock(bx + 1, by, bz).getMaterial().isSolid()) { - nearSolid = true; - } - if (world.blockExists(bx - 1, by, bz) && world.getBlock(bx - 1, by, bz).getMaterial().isSolid()) { - nearSolid = true; - } - if (world.blockExists(bx, by, bz + 1) && world.getBlock(bx, by, bz + 1).getMaterial().isSolid()) { - nearSolid = true; - } - if (world.blockExists(bx, by, bz - 1) && world.getBlock(bx, by, bz - 1).getMaterial().isSolid()) { - nearSolid = true; - } - - return nearSolid; - } - - - /** - * Temporary override - */ - protected void setBlock(World world, int x, int y, int z, Block block) { - this.func_150515_a(world, x, y, z, block); - } - /** - * Temporary override - */ - protected void setBlockAndMetadata(World world, int x, int y, int z, Block block, int meta) { - this.setBlockAndNotifyAdequately(world, x, y, z, block, meta); - } -} diff --git a/src/main/java/twilightforest/world/TFTreeGenerator.java b/src/main/java/twilightforest/world/TFTreeGenerator.java deleted file mode 100644 index 61fbf7b189..0000000000 --- a/src/main/java/twilightforest/world/TFTreeGenerator.java +++ /dev/null @@ -1,256 +0,0 @@ -package twilightforest.world; - -import net.minecraft.block.Block; -import net.minecraft.init.Blocks; -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.World; -import net.minecraft.world.gen.feature.WorldGenAbstractTree; -import twilightforest.block.BlockTFRoots; -import twilightforest.block.TFBlocks; - -public abstract class TFTreeGenerator extends WorldGenAbstractTree { - - protected Block treeBlock = TFBlocks.log; - protected int treeMeta = 3; - protected int branchMeta = 15; - protected Block leafBlock = TFBlocks.hedge; - protected int leafMeta = 1; - protected Block rootBlock = TFBlocks.root; - protected int rootMeta = BlockTFRoots.ROOT_META; - - - public TFTreeGenerator() { - this(false); - } - - public TFTreeGenerator(boolean par1) { - super(par1); - } - - /** - * Build a root, but don't let it stick out too far into thin air because that's weird - */ - protected void buildRoot(World world, int x, int y, int z, double offset, int b) { - ChunkCoordinates dest = translateCoords(x, y - b - 2, z, 5, 0.3 * b + offset, 0.8); - - // go through block by block and stop drawing when we head too far into open air - ChunkCoordinates[] lineArray = getBresehnamArrayCoords(x, y - b - 2, z, dest.posX, dest.posY, dest.posZ); - for (ChunkCoordinates coord : lineArray) - { - this.placeRootBlock(world, coord.posX, coord.posY, coord.posZ, rootBlock, rootMeta); - } - } - - /** - * Function used to actually place root blocks if they're not going to break anything important - */ - protected void placeRootBlock(World world, int x, int y, int z, Block rootBlock2, int meta) { - if (canRootGrowIn(world, x, y, z)) - { - this.setBlockAndMetadata(world, x, y, z, rootBlock2, meta); - } - } - - public static boolean canRootGrowIn(World world, int x, int y, int z) { - Block blockID = world.getBlock(x, y, z); - - if (blockID == Blocks.air) { - // roots can grow through air if they are near a solid block - return isNearSolid(world, x, y, z); - } - else - { - return blockID != Blocks.bedrock && blockID != Blocks.obsidian && blockID != TFBlocks.shield; - } - } - - - /** - * Moves distance along the vector. - * - * This goofy function takes a float between 0 and 1 for the angle, where 0 is 0 degrees, .5 is 180 degrees and 1 and 360 degrees. - * For the tilt, it takes a float between 0 and 1 where 0 is straight up, 0.5 is straight out and 1 is straight down. - */ - public static int[] translate(int sx, int sy, int sz, double distance, double angle, double tilt) { - return TFGenerator.translate(sx, sy, sz, distance, angle, tilt); - } - - protected static ChunkCoordinates translateCoords(int sx, int sy, int sz, double length, double angle, double tilt) { - return TFGenerator.translateCoords(sx, sy, sz, length, angle, tilt); - } - - /** - * Get an array of values that represent a line from point A to point B - */ - public static ChunkCoordinates[] getBresehnamArrayCoords(ChunkCoordinates src, ChunkCoordinates dest) { - return TFGenerator.getBresehnamArrayCoords(src.posX, src.posY, src.posZ, dest.posX, dest.posY, dest.posZ); - } - - /** - * Get an array of values that represent a line from point A to point B - */ - public static ChunkCoordinates[] getBresehnamArrayCoords(int x1, int y1, int z1, int x2, int y2, int z2) { - return TFGenerator.getBresehnamArrayCoords(x1, y1, z1, x2, y2, z2); - } - - - protected static boolean isNearSolid(World world, int bx, int by, int bz) { - return TFGenerator.isNearSolid(world, bx, by, bz); - } - - protected static boolean hasAirAround(World world, int bx, int by, int bz) { - return TFGenerator.hasAirAround(world, bx, by, bz); - } - - /** - * Temporary override - */ - protected void setBlock(World world, int x, int y, int z, Block block) { - this.func_150515_a(world, x, y, z, block); - } - /** - * Temporary override - */ - protected void setBlockAndMetadata(World world, int x, int y, int z, Block block, int meta) { - this.setBlockAndNotifyAdequately(world, x, y, z, block, meta); - } - - - /** - * Draw a flat blob (circle) of leaves - */ - public void makeLeafCircle(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue) - { - this.makeLeafCircle(world, sx, sy, sz, rad, blockValue, metaValue, false); - } - - - /* - * Fully duplicated code from TFGenerator below. Where is my multiple inheritance? - */ - - - /** - * Draws a line from {x1, y1, z1} to {x2, y2, z2} - */ - protected void drawBresehnam(World world, int x1, int y1, int z1, int x2, int y2, int z2, Block blockValue, int metaValue) - { - ChunkCoordinates[] lineArray = getBresehnamArrayCoords(x1, y1, z1, x2, y2, z2); - for (ChunkCoordinates pixel : lineArray) - { - setBlockAndMetadata(world, pixel.posX, pixel.posY, pixel.posZ, blockValue, metaValue); - } - } - - /** - * Draw a flat blob (circle) of leaves - */ - public void makeLeafCircle(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue, boolean useHack) - { - // trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dz = 0; dz <= rad; dz++) - { - int dist = Math.max(dx, dz) + (Math.min(dx, dz) >> 1); - - //hack! I keep getting failing leaves at a certain position. - if (useHack && dx == 3 && dz == 3) { - dist = 6; - } - - // if we're inside the blob, fill it - if (dist <= rad) { - // do four at a time for easiness! - putLeafBlock(world, sx + dx, sy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz - dz, blockValue, metaValue); - } - } - } - } - - /** - * Draw a flat blob (circle) of leaves. This one makes it offset to surround a 2x2 area instead of a 1 block area - */ - public void makeLeafCircle2(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue, boolean useHack) - { - // trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dz = 0; dz <= rad; dz++) - { -// int dist = Math.max(dx, dz) + (int)(Math.min(dx, dz) * 0.6F); -// -// //hack! I keep getting failing leaves at a certain position. -// if (useHack && dx == 3 && dz == 3) { -// dist = 6; -// } - - // if we're inside the blob, fill it - if (dx * dx + dz * dz <= rad * rad) { - // do four at a time for easiness! - putLeafBlock(world, sx + 1 + dx, sy, sz + 1 + dz, blockValue, metaValue); - putLeafBlock(world, sx + 1 + dx, sy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz + 1 + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy, sz - dz, blockValue, metaValue); - } - } - } - } - - /** - * Draw a giant blob of leaves. - */ - public void drawLeafBlob(World world, int sx, int sy, int sz, int rad, Block blockValue, int metaValue) { - // then trace out a quadrant - for (byte dx = 0; dx <= rad; dx++) - { - for (byte dy = 0; dy <= rad; dy++) - { - for (byte dz = 0; dz <= rad; dz++) - { - // determine how far we are from the center. - int dist = 0; - if (dx >= dy && dx >= dz) { - dist = dx + (Math.max(dy, dz) >> 1) + (Math.min(dy, dz) >> 2); - } else if (dy >= dx && dy >= dz) - { - dist = dy + (Math.max(dx, dz) >> 1) + (Math.min(dx, dz) >> 2); - } else { - dist = dz + (Math.max(dx, dy) >> 1) + (Math.min(dx, dy) >> 2); - } - - - // if we're inside the blob, fill it - if (dist <= rad) { - // do eight at a time for easiness! - putLeafBlock(world, sx + dx, sy + dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy + dy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy + dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy + dy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy - dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx + dx, sy - dy, sz - dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy - dy, sz + dz, blockValue, metaValue); - putLeafBlock(world, sx - dx, sy - dy, sz - dz, blockValue, metaValue); - } - } - } - } - } - - /** - * Put a leaf only in spots where leaves can go! - */ - public void putLeafBlock(World world, int x, int y, int z, Block blockValue, int metaValue) { - Block whatsThere = world.getBlock(x, y, z); - Block block = whatsThere; - - if (block == null || block.canBeReplacedByLeaves(world, x, y, z)) - { - this.setBlockAndMetadata(world, x, y, z, blockValue, metaValue); - } - } -} \ No newline at end of file diff --git a/src/main/java/twilightforest/world/TFWorld.java b/src/main/java/twilightforest/world/TFWorld.java index 6d6b4fc6c4..5b5fc4f8ec 100644 --- a/src/main/java/twilightforest/world/TFWorld.java +++ b/src/main/java/twilightforest/world/TFWorld.java @@ -1,16 +1,87 @@ package twilightforest.world; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.IChunkGenerator; +import twilightforest.TFConfig; +import twilightforest.TFFeature; +import twilightforest.TwilightForestMod; +import twilightforest.biomes.TFBiomeBase; +import javax.annotation.Nullable; +import java.util.function.Predicate; - -/** - * Currently this class just stores variables about sea level and such - * - * @author Ben - * - */ public class TFWorld { - public static int SEALEVEL = 31; - public static int CHUNKHEIGHT = 256; // more like world generation height - public static int MAXHEIGHT = 256; // actual max height + + public static final int SEALEVEL = 31; + public static final int CHUNKHEIGHT = 256; // more like world generation height + public static final int MAXHEIGHT = 256; // actual max height + + @Nullable + public static ChunkGeneratorTFBase getChunkGenerator(World world) { + if (world instanceof WorldServer) { + IChunkGenerator chunkGenerator = ((WorldServer) world).getChunkProvider().chunkGenerator; + return chunkGenerator instanceof ChunkGeneratorTFBase ? (ChunkGeneratorTFBase) chunkGenerator : null; + } + return null; + } + + public static boolean isTwilightForest(World world) { + return world.provider instanceof WorldProviderTwilightForest; + } + + public static NBTTagCompound getDimensionData(World world) { + return world.getWorldInfo().getDimensionData(TFConfig.dimension.dimensionID); + } + + public static void setDimensionData(World world, NBTTagCompound data) { + world.getWorldInfo().setDimensionData(TFConfig.dimension.dimensionID, data); + } + + public static boolean isProgressionEnforced(World world) { + return world.getGameRules().getBoolean(TwilightForestMod.ENFORCED_PROGRESSION_RULE); + } + + public static boolean isBiomeSafeFor(Biome biome, Entity entity) { + if (biome instanceof TFBiomeBase && entity instanceof EntityPlayer) { + return ((TFBiomeBase) biome).doesPlayerHaveRequiredAdvancements((EntityPlayer) entity); + } + return true; + } + + public static void markStructureConquered(World world, BlockPos pos, TFFeature feature) { + ChunkGeneratorTFBase generator = getChunkGenerator(world); + if (generator != null && TFFeature.getFeatureAt(pos.getX(), pos.getZ(), world) == feature) { + generator.setStructureConquered(pos, true); + } + } + + public static int getGroundLevel(World world, int x, int z) { + return getGroundLevel(world, x, z, block -> false); + } + + public static int getGroundLevel(World world, int x, int z, Predicate extraBlocks) { + // go from sea level up. If we get grass, return that, otherwise return the last dirt, stone or gravel we got + Chunk chunk = world.getChunk(x >> 4, z >> 4); + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + int lastDirt = SEALEVEL; + for (int y = SEALEVEL; y < CHUNKHEIGHT - 1; y++) { + Block block = chunk.getBlockState(pos.setPos(x, y, z)).getBlock(); + // grass = return immediately + if (block == Blocks.GRASS) { + return y + 1; + } else if (block == Blocks.DIRT || block == Blocks.STONE || block == Blocks.GRAVEL || extraBlocks.test(block)) { + lastDirt = y + 1; + } + } + return lastDirt; + } } diff --git a/src/main/java/twilightforest/world/TFWorldChunkManager.java b/src/main/java/twilightforest/world/TFWorldChunkManager.java deleted file mode 100644 index 259a9423fa..0000000000 --- a/src/main/java/twilightforest/world/TFWorldChunkManager.java +++ /dev/null @@ -1,355 +0,0 @@ -package twilightforest.world; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import net.minecraft.util.ChunkCoordinates; -import net.minecraft.world.ChunkPosition; -import net.minecraft.world.World; -import net.minecraft.world.WorldType; -import net.minecraft.world.biome.BiomeCache; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.biome.WorldChunkManager; -import net.minecraft.world.gen.layer.GenLayer; -import net.minecraft.world.gen.layer.IntCache; -import twilightforest.TFFeature; -import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; -import twilightforest.world.layer.GenLayerTF; - - -public class TFWorldChunkManager extends WorldChunkManager -{ - private GenLayer unzoomedBiomes; - - /** A GenLayer containing the indices into BiomeGenBase.biomeList[] */ - private GenLayer zoomedBiomes; - - /** The BiomeCache object for this world. */ - private BiomeCache myBiomeCache; - - /** A list of biomes that the player can spawn in. */ - private List myBiomesToSpawnIn; - - protected TFWorldChunkManager() - { - myBiomeCache = new BiomeCache(this); - myBiomesToSpawnIn = new ArrayList(); - myBiomesToSpawnIn.add(TFBiomeBase.twilightForest); - myBiomesToSpawnIn.add(TFBiomeBase.twilightForest2); - myBiomesToSpawnIn.add(TFBiomeBase.clearing); - myBiomesToSpawnIn.add(TFBiomeBase.tfSwamp); - myBiomesToSpawnIn.add(TFBiomeBase.mushrooms); - } - - public TFWorldChunkManager(long par1, WorldType par3WorldType) - { - this(); - GenLayer agenlayer[]; - // new world gen! - if (TwilightForestMod.oldMapGen) - { - agenlayer = GenLayerTF.makeTheWorldOldMapGen(par1); - } - else - { - agenlayer = GenLayerTF.makeTheWorld(par1); - } - unzoomedBiomes = agenlayer[0]; - zoomedBiomes = agenlayer[1]; - } - - public TFWorldChunkManager(World par1World) - { - this(par1World.getSeed(), par1World.getWorldInfo().getTerrainType()); - } - - /** - * Gets the list of valid biomes for the player to spawn in. - */ - @SuppressWarnings("rawtypes") - public List getBiomesToSpawnIn() - { - return myBiomesToSpawnIn; - } - - /** - * Returns the BiomeGenBase related to the x, z position on the world. - */ - public BiomeGenBase getBiomeGenAt(int par1, int par2) - { - BiomeGenBase biome = myBiomeCache.getBiomeGenAt(par1, par2); - if (biome == null) - { - //FMLLog.warning("[TwilightForest] Suppressing bad biome data in getBiomeGenAt, %s at %d, %d", biome, par1, par2); - - //throw new IllegalArgumentException(); - return TFBiomeBase.twilightForest; - } - else - { - return biome; - } - } - - /** - * Returns a list of rainfall values for the specified blocks. Args: listToReuse, x, z, width, length. - */ - public float[] getRainfall(float par1ArrayOfFloat[], int par2, int par3, int par4, int par5) - { - IntCache.resetIntCache(); - - if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5) - { - par1ArrayOfFloat = new float[par4 * par5]; - } - - int ai[] = zoomedBiomes.getInts(par2, par3, par4, par5); - - for (int i = 0; i < par4 * par5; i++) - { - // this keeps NPEing, I wonder why - if (ai[i] >= 0 && BiomeGenBase.getBiome(ai[i]) != null) { - float f = (float)BiomeGenBase.getBiome(ai[i]).getIntRainfall() / 65536F; - - if (f > 1.0F) - { - f = 1.0F; - } - - par1ArrayOfFloat[i] = f; - } - else - { - // nothing - } - } - - return par1ArrayOfFloat; - } - - /** - * Return an adjusted version of a given temperature based on the y height - */ - public float getTemperatureAtHeight(float par1, int par2) - { - return par1; - } - - /** - * Returns an array of biomes for the location input. - */ - public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase par1ArrayOfBiomeGenBase[], int x, int z, int length, int width) - { - IntCache.resetIntCache(); - - if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < length * width) - { - par1ArrayOfBiomeGenBase = new BiomeGenBase[length * width]; - } - - int arrayOfInts[] = unzoomedBiomes.getInts(x, z, length, width); - - for (int i = 0; i < length * width; i++) - { - // biome validity check - if (arrayOfInts[i] >= 0) - { - par1ArrayOfBiomeGenBase[i] = BiomeGenBase.getBiome(arrayOfInts[i]); - } - else - { - //System.err.println("Got bad biome data : " + ai[i]); - par1ArrayOfBiomeGenBase[i] = TFBiomeBase.twilightForest; - } - } - - return par1ArrayOfBiomeGenBase; - } - - /** - * Returns biomes to use for the blocks and loads the other data like temperature and humidity onto the - * WorldChunkManager Args: oldBiomeList, x, z, width, depth - */ - public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase par1ArrayOfBiomeGenBase[], int par2, int par3, int par4, int par5) - { - return getBiomeGenAt(par1ArrayOfBiomeGenBase, par2, par3, par4, par5, true); - } - - /** - * Return a list of biomes for the specified blocks. Args: listToReuse, x, y, width, length, cacheFlag (if false, - * don't check biomeCache to avoid infinite loop in BiomeCacheBlock) - */ - public BiomeGenBase[] getBiomeGenAt(BiomeGenBase par1ArrayOfBiomeGenBase[], int x, int y, int width, int length, boolean cacheFlag) - { - IntCache.resetIntCache(); - - if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < width * length) - { - par1ArrayOfBiomeGenBase = new BiomeGenBase[width * length]; - } - - if (cacheFlag && width == 16 && length == 16 && (x & 0xf) == 0 && (y & 0xf) == 0) - { - BiomeGenBase abiomegenbase[] = myBiomeCache.getCachedBiomes(x, y); - System.arraycopy(abiomegenbase, 0, par1ArrayOfBiomeGenBase, 0, width * length); - return par1ArrayOfBiomeGenBase; - } - - int ai[] = zoomedBiomes.getInts(x, y, width, length); - - for (int i = 0; i < width * length; i++) - { - // biome validity check - if (ai[i] >= 0) - { - par1ArrayOfBiomeGenBase[i] = BiomeGenBase.getBiome(ai[i]); - } - else - { - //System.err.println("Got bad biome data : " + ai[i]); - par1ArrayOfBiomeGenBase[i] = TFBiomeBase.twilightForest; - } - } - - return par1ArrayOfBiomeGenBase; - } - - /** - * checks given Chunk's Biomes against List of allowed ones - */ - @SuppressWarnings("rawtypes") - public boolean areBiomesViable(int par1, int par2, int par3, List par4List) - { - int i = par1 - par3 >> 2; - int j = par2 - par3 >> 2; - int k = par1 + par3 >> 2; - int l = par2 + par3 >> 2; - int i1 = (k - i) + 1; - int j1 = (l - j) + 1; - int ai[] = unzoomedBiomes.getInts(i, j, i1, j1); - - for (int k1 = 0; k1 < i1 * j1; k1++) - { - BiomeGenBase biomegenbase = BiomeGenBase.getBiome(ai[k1]); - - if (!par4List.contains(biomegenbase)) - { - return false; - } - } - - return true; - } - - /** - * Finds a valid position within a range, that is once of the listed biomes. - */ - @SuppressWarnings("rawtypes") - public ChunkPosition findBiomePosition(int par1, int par2, int par3, List par4List, Random par5Random) - { - int i = par1 - par3 >> 2; - int j = par2 - par3 >> 2; - int k = par1 + par3 >> 2; - int l = par2 + par3 >> 2; - int i1 = (k - i) + 1; - int j1 = (l - j) + 1; - int ai[] = unzoomedBiomes.getInts(i, j, i1, j1); - ChunkPosition chunkposition = null; - int k1 = 0; - - for (int l1 = 0; l1 < ai.length; l1++) - { - int i2 = i + l1 % i1 << 2; - int j2 = j + l1 / i1 << 2; - BiomeGenBase biomegenbase = BiomeGenBase.getBiome(ai[l1]); - - if (par4List.contains(biomegenbase) && (chunkposition == null || par5Random.nextInt(k1 + 1) == 0)) - { - chunkposition = new ChunkPosition(i2, 0, j2); - k1++; - } - } - - return chunkposition; - } - - /** - * Calls the WorldChunkManager's biomeCache.cleanupCache() - */ - public void cleanupCache() - { - myBiomeCache.cleanupCache(); - } - - /** - * Returns feature ID at the specified location - */ - public int getFeatureID(int mapX, int mapZ, World world) - { - return getFeatureAt(mapX, mapZ, world).featureID; - } - - /** - * Returns feature at the specified location - */ - public TFFeature getFeatureAt(int mapX, int mapZ, World world) - { - return TFFeature.generateFeatureFor1Point7(mapX >> 4, mapZ >> 4, world); - } - - /** - * Checks if the coordinates are in a feature chunk. - * @param world - */ - public boolean isInFeatureChunk(World world, int mapX, int mapZ) { - // legacy support - if (TwilightForestMod.oldMapGen) - { - return isInFeatureChunkOld(world, mapX, mapZ); - } - - int chunkX = mapX >> 4; - int chunkZ = mapZ >> 4; - ChunkCoordinates cc = TFFeature.getNearestCenterXYZ(chunkX, chunkZ, world); - - return chunkX == (cc.posX >> 4) && chunkZ == (cc.posZ >> 4); - -// logic moved to TFFeature.getNearestCenterXYZ : - -// int chunkX = (mapX + 128) >> 4; -// int chunkZ = (mapZ + 128) >> 4; -// -// // generate random number for the whole biome area -// int regionX = chunkX >> 4; -// int regionZ = chunkZ >> 4; -// -// long seed = (long)(regionX * 3129871) ^ (long)regionZ * 116129781L; -// seed = seed * seed * 42317861L + seed * 7L; -// -// int num0 = (int) (seed >> 12 & 3L); -// int num1 = (int) (seed >> 15 & 3L); -// int num2 = (int) (seed >> 18 & 3L); -// int num3 = (int) (seed >> 21 & 3L); -// -// // slightly randomize center of biome (+/- 3) -// int centerX = 8 + num0 - num1; -// int centerZ = 8 + num2 - num3; -// -// return Math.abs(chunkX % 16) == centerX && Math.abs(chunkZ % 16) == centerZ; - - } - - /** - * Checks if the coordinates are in a feature chunk. - * @param world - */ - public boolean isInFeatureChunkOld(World world, int mapX, int mapZ) { - int chunkX = mapX >> 4; - int chunkZ = mapZ >> 4; - - return chunkX % 16 == 0 && chunkZ % 16 == 0; - } - -} diff --git a/src/main/java/twilightforest/world/WorldProviderTwilightForest.java b/src/main/java/twilightforest/world/WorldProviderTwilightForest.java index 90f9cdcbe6..9b84191fe2 100644 --- a/src/main/java/twilightforest/world/WorldProviderTwilightForest.java +++ b/src/main/java/twilightforest/world/WorldProviderTwilightForest.java @@ -1,274 +1,253 @@ -/** - * - */ package twilightforest.world; +import net.minecraft.client.audio.MusicTicker; import net.minecraft.entity.Entity; -import net.minecraft.util.MathHelper; -import net.minecraft.util.Vec3; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.DimensionType; import net.minecraft.world.WorldProviderSurface; -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.IChunkGenerator; import net.minecraftforge.client.IRenderHandler; +import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import twilightforest.TFConfig; import twilightforest.TwilightForestMod; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; +import twilightforest.client.TFClientProxy; import twilightforest.client.renderer.TFSkyRenderer; import twilightforest.client.renderer.TFWeatherRenderer; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import javax.annotation.Nullable; /** * @author Ben - * */ public class WorldProviderTwilightForest extends WorldProviderSurface { + private static final String SEED_KEY = "CustomSeed"; + private static final String SKYLIGHT_KEY = "HasSkylight"; + + private static volatile boolean skylightEnabled = true; + + private long seed; + + public static void syncFromConfig() { + skylightEnabled = TFConfig.performance.enableSkylight; + } + + public static void setSkylightEnabled(boolean enabled) { + skylightEnabled = enabled; + } + + public static boolean isSkylightEnabled(NBTTagCompound data) { + return data.hasKey(SKYLIGHT_KEY, Constants.NBT.TAG_BYTE) ? data.getBoolean(SKYLIGHT_KEY) : skylightEnabled; + } - public final String saveFolder; - public ChunkProviderTwilightForest chunkProvider; - public WorldProviderTwilightForest() { - setDimension(TwilightForestMod.dimensionID); - saveFolder = "DIM" + TwilightForestMod.dimensionID; + setDimension(TFConfig.dimension.dimensionID); } - - /** - * Always return these colors - */ + + /* TODO Breaking change. Uncomment for 1.13. + Reason for adding ID is if we want multiple TF worlds for servers in future. + + @Override + public String getSaveFolder() { + return "twilightforest" + getDimension(); + }*/ + + @Nullable + @Override + @SideOnly(Side.CLIENT) + public MusicTicker.MusicType getMusicType() { + return TFClientProxy.TFMUSICTYPE; + } + @Override public float[] calcSunriseSunsetColors(float celestialAngle, float f1) { - return null;//super.calcSunriseSunsetColors(celestialAngle, f1); + return null; } - - /** - * Fog color - */ + @Override - public Vec3 getFogColor(float f, float f1) - { - float bright = MathHelper.cos(0.25f * 3.141593F * 2.0F) * 2.0F + 0.5F; - if(bright < 0.0F) - { - bright = 0.0F; - } - if(bright > 1.0F) - { - bright = 1.0F; - } - float red = 0.7529412F; - float green = 1.0F; - float blue = 0.8470588F; - red *= bright * 0.94F + 0.06F; - green *= bright * 0.94F + 0.06F; - blue *= bright * 0.91F + 0.09F; - return Vec3.createVectorHelper(red, green, blue); - } - - /** - * Calculates the angle of sun and moon in the sky relative to a specified time (usually worldTime) - */ - public float calculateCelestialAngle(long par1, float par3) - { - //return super.calculateCelestialAngle(par1, par3); - return 0.225f; - } + public Vec3d getFogColor(float f, float f1) { + float bright = MathHelper.cos(0.25f * 3.141593F * 2.0F) * 2.0F + 0.5F; + if (bright < 0.0F) { + bright = 0.0F; + } + if (bright > 1.0F) { + bright = 1.0F; + } + float red = 0.7529412F; // 192 + float green = 1.0F; // 255 + float blue = 0.8470588F; // 216 + red *= bright * 0.94F + 0.06F; + green *= bright * 0.94F + 0.06F; + blue *= bright * 0.91F + 0.09F; + return new Vec3d(red, green, blue); + } + // Pin the celestial angle at night/evening so things that use it see night + @Override + public float calculateCelestialAngle(long worldTime, float partialTicks) { + return 0.225f; + } @Override - public void registerWorldChunkManager() - { - this.worldChunkMgr = new TFWorldChunkManager(worldObj); - this.dimensionId = TwilightForestMod.dimensionID; - } - - - /** - * Returns a new chunk provider which generates chunks for this world - */ - public IChunkProvider createChunkGenerator() - { - // save chunk generator? - if (this.chunkProvider == null) { - this.chunkProvider = new ChunkProviderTwilightForest(worldObj, worldObj.getSeed(), worldObj.getWorldInfo().isMapFeaturesEnabled()); - return this.chunkProvider; - } else { - return new ChunkProviderTwilightForest(worldObj, worldObj.getSeed(), worldObj.getWorldInfo().isMapFeaturesEnabled()); - } - } - - public ChunkProviderTwilightForest getChunkProvider() { - return this.chunkProvider; - } - + public void init() { + NBTTagCompound data = TFWorld.getDimensionData(world); + seed = data.hasKey(SEED_KEY, Constants.NBT.TAG_LONG) ? data.getLong(SEED_KEY) : loadSeed(); + hasSkyLight = isSkylightEnabled(data); + biomeProvider = new TFBiomeProvider(world); + } + + @Override + protected void generateLightBrightnessTable() { + float f = this.hasSkyLight ? 0.0F : 0.1F; + for (int i = 0; i <= 15; ++i) { + float f1 = 1.0F - (float)i / 15.0F; + this.lightBrightnessTable[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * (1.0F - f) + f; + } + } + + @Override + public IChunkGenerator createChunkGenerator() { + return TFConfig.dimension.skylightForest + ? new ChunkGeneratorTwilightVoid(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled()) + : new ChunkGeneratorTwilightForest(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled()); + } + /** * This seems to be a function checking whether we have an ocean. */ + @SideOnly(Side.CLIENT) @Override - public boolean isSkyColored() - { + public boolean isSkyColored() { return false; } - -// -// @Override -// public float getCloudHeight() -// { -// return 64F; -// } - - public int getAverageGroundLevel() - { - return 30; - } - -// @Override -// public boolean canCoordinateBeSpawn(int i, int j) -// { -// int k = worldObj.getFirstUncoveredBlock(i, j); -// if(k == 0) -// { -// return false; -// } else -// { -// return Blocks.blocksList[k].getMaterial().isSolid(); -// } -// } - - - /** - * True if the player can respawn in this dimension (true = overworld, false = nether). - */ @Override - public boolean canRespawnHere() - { - // lie about this until the world is initialized - // otherwise the server will try to generate enough terrain for a spawn point and that's annoying - return worldObj.getWorldInfo().isInitialized(); - } + public int getAverageGroundLevel() { + return 30; + } @Override - public String getSaveFolder() { - return this.saveFolder; + public double getVoidFogYFactor() { + // allow for terrain squashing + return super.getVoidFogYFactor() * 2.0; } @Override - public String getWelcomeMessage() { - return "Entering the Twilight Forest"; + public boolean canRespawnHere() { + // lie about this until the world is initialized + // otherwise the server will try to generate enough terrain for a spawn point and that's annoying + return world.getWorldInfo().isInitialized(); } @Override - public String getDepartMessage() { - return "Leaving the Twilight Forest"; + public DimensionType getDimensionType() { + return TwilightForestMod.dimType; } @Override - public String getDimensionName() { - return "Twilight Forest"; + public boolean isDaytime() { + return false; } - /** - * Sleep anytime! - */ @Override - public boolean isDaytime() { + public boolean shouldMapSpin(String entityName, double x, double z, double rotation) { return false; } @Override @SideOnly(Side.CLIENT) - public Vec3 getSkyColor(Entity cameraEntity, float partialTicks) { - return Vec3.createVectorHelper(43 / 256.0, 46 / 256.0, 99 / 256.0); + public Vec3d getSkyColor(Entity cameraEntity, float partialTicks) { + // TODO Maybe in the future we can get the return of sky color by biome? + return new Vec3d(32 / 256.0, 34 / 256.0, 74 / 256.0); + } + + @Override + public void getLightmapColors(float partialTicks, float sunBrightness, float skyLight, float blockLight, float[] colors) { + final float r = 64f / 255f, g = 85f / 255f, b = 72f / 255f; + if (!hasSkyLight) { + colors[0] = r + blockLight * (1.0f - r); + colors[1] = g + blockLight * (1.0f - g); + colors[2] = b + blockLight * (1.0f - b); + } } @Override @SideOnly(Side.CLIENT) - public float getStarBrightness(float par1) { + public float getStarBrightness(float partialTicks) { return 1.0F; } - @Override public double getHorizon() { - return 32.0D; + return TFWorld.SEALEVEL; } @Override - public BiomeGenBase getBiomeGenForCoords(int x, int z) { - BiomeGenBase biome = super.getBiomeGenForCoords(x, z); - if (biome == null) - { - biome = TFBiomeBase.twilightForest; + public Biome getBiomeForCoords(BlockPos pos) { + Biome biome = super.getBiomeForCoords(pos); + if (biome == null) { + biome = TFBiomes.twilightForest; } return biome; } - + /** * If there is a specific twilight forest seed set, use that. Otherwise use the world seed. */ @Override - public long getSeed() - { - if (TwilightForestMod.twilightForestSeed == null || TwilightForestMod.twilightForestSeed.length() == 0) - { - return super.getSeed(); - } - else - { - return TwilightForestMod.twilightForestSeed.hashCode(); + public long getSeed() { + return seed == 0L ? super.getSeed() : seed; + } + + private long loadSeed() { + String seed = TFConfig.dimension.twilightForestSeed; + if (seed != null && !seed.isEmpty()) { + try { + return Long.parseLong(seed); + } catch (NumberFormatException e) { + return seed.hashCode(); + } } + return 0L; } - - /** - * We're just going to check here for chunks with the relight flag set and KILL THEM! - */ + + @Override + public void onWorldSave() { + NBTTagCompound data = new NBTTagCompound(); + data.setLong(SEED_KEY, seed); + // TODO: decide on persisting this + //data.setBoolean(SKYLIGHT_KEY, hasSkyLight); + TFWorld.setDimensionData(world, data); + } + @Override - public void updateWeather() - { - super.updateWeather(); - -// for (ChunkCoordIntPair coord : (HashSet)this.worldObj.activeChunkSet) -// { -// Chunk chunk = this.worldObj.getChunkFromChunkCoords(coord.chunkXPos, coord.chunkZPos); -// -// if (chunk.queuedLightChecks < 4096) -// { -// //System.out.println("Stopping light checks!"); -// chunk.queuedLightChecks = 4096; -// } -// } - } - - @SideOnly(Side.CLIENT) - public IRenderHandler getSkyRenderer() - { - if (super.getSkyRenderer() == null) - { + public IRenderHandler getSkyRenderer() { + if (super.getSkyRenderer() == null) { this.setSkyRenderer(new TFSkyRenderer()); } - return super.getSkyRenderer(); } - - @SideOnly(Side.CLIENT) - public IRenderHandler getWeatherRenderer() - { - if (super.getWeatherRenderer() == null) - { + + @Override + @SideOnly(Side.CLIENT) + public IRenderHandler getWeatherRenderer() { + if (super.getWeatherRenderer() == null) { this.setWeatherRenderer(new TFWeatherRenderer()); } - return super.getWeatherRenderer(); - } - - /** - * the y level at which clouds are rendered. - */ - //@SideOnly(Side.CLIENT) // need for magic beans, even on server - public float getCloudHeight() - { - return 161.0F; - } + } + + // no sideonly + @Override + public float getCloudHeight() { + return TFConfig.dimension.skylightForest ? -1F : 161F; + } } diff --git a/src/main/java/twilightforest/world/feature/IBlockSettable.java b/src/main/java/twilightforest/world/feature/IBlockSettable.java new file mode 100644 index 0000000000..d8488f9e0b --- /dev/null +++ b/src/main/java/twilightforest/world/feature/IBlockSettable.java @@ -0,0 +1,15 @@ +package twilightforest.world.feature; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +// Shim interface to expose the WorldGenerator's setBlock method +// Mainly so TFGenerator's util methods don't have to be duplicated between the TFGenerator subclasses and the +// tree generators +// todo 1.9 improve this? +public interface IBlockSettable { + // [VanillaCopy] pin to signature of WorldGenerator.setBlockAndNotifyAdequately + // But cannot have exact same name as the subclass methods will get reobf-ed but the interface one won't + void setBlockAndNotify(World world, BlockPos pos, IBlockState state); +} diff --git a/src/main/java/twilightforest/world/feature/TFGenBigMushgloom.java b/src/main/java/twilightforest/world/feature/TFGenBigMushgloom.java new file mode 100644 index 0000000000..2038b4af93 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenBigMushgloom.java @@ -0,0 +1,55 @@ +package twilightforest.world.feature; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFHugeGloomBlock; +import twilightforest.block.TFBlocks; + +import java.util.Random; + +public class TFGenBigMushgloom extends TFGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + int height = 3 + rand.nextInt(2) + rand.nextInt(2); + + if (!isAreaSuitable(world, rand, pos.add(-1, 0, -1), 3, height, 3)) { + return false; + } + + Block blockUnder = world.getBlockState(pos.down()).getBlock(); + if (blockUnder != Blocks.DIRT && blockUnder != Blocks.GRASS && blockUnder != Blocks.MYCELIUM) { + return false; + } + + // generate! + for (int dy = 0; dy < height - 2; dy++) { + this.setBlockAndNotifyAdequately(world, pos.up(dy), TFBlocks.huge_mushgloom.getDefaultState().withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.STEM)); + } + + makeMushroomCap(world, pos.up(height - 2)); + if (rand.nextBoolean()) { + makeMushroomCap(world, pos.up(height - 1)); + } + + return true; + } + + private void makeMushroomCap(World world, BlockPos pos) { + IBlockState defState = TFBlocks.huge_mushgloom.getDefaultState(); + this.setBlockAndNotifyAdequately(world, pos.add(-1, 0, -1), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.NORTH_WEST)); + this.setBlockAndNotifyAdequately(world, pos.add(0, 0, -1), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.NORTH)); + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, -1), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.NORTH_EAST)); + this.setBlockAndNotifyAdequately(world, pos.add(-1, 0, 0), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.WEST)); + this.setBlockAndNotifyAdequately(world, pos, defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.CENTER)); + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, 0), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.EAST)); + this.setBlockAndNotifyAdequately(world, pos.add(-1, 0, 1), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.SOUTH_WEST)); + this.setBlockAndNotifyAdequately(world, pos.add(0, 0, 1), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.SOUTH)); + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, 1), defState.withProperty(BlockTFHugeGloomBlock.VARIANT, BlockHugeMushroom.EnumType.SOUTH_EAST)); + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenCanopyMushroom.java b/src/main/java/twilightforest/world/feature/TFGenCanopyMushroom.java new file mode 100644 index 0000000000..49c38d4aac --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenCanopyMushroom.java @@ -0,0 +1,156 @@ +package twilightforest.world.feature; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockHugeMushroom; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.world.TFWorld; + +import java.util.Random; + +/** + * Makes large mushrooms with flat mushroom tops that provide a canopy for the forest + * + * @author Ben + */ +public class TFGenCanopyMushroom extends TFTreeGenerator { + + public TFGenCanopyMushroom() { + this(false); + } + + public TFGenCanopyMushroom(boolean notify) { + super(notify); + treeState = Blocks.RED_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM); + branchState = Blocks.RED_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_STEM); + leafState = Blocks.RED_MUSHROOM_BLOCK.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER); + source = Blocks.RED_MUSHROOM; + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + // determine a height + int treeHeight = 12; + if (random.nextInt(3) == 0) { + treeHeight += random.nextInt(5); + + if (random.nextInt(8) == 0) { + treeHeight += random.nextInt(5); + } + } + + if (pos.getY() >= TFWorld.MAXHEIGHT - treeHeight - 1) { + return false; + } + + // check if we're on dirt or grass + Block blockUnder = world.getBlockState(pos.down()).getBlock(); + if (blockUnder != Blocks.GRASS && blockUnder != Blocks.DIRT && blockUnder != Blocks.MYCELIUM) { + return false; + } + + IBlockState baseState = (random.nextInt(3) == 0 ? Blocks.RED_MUSHROOM_BLOCK : Blocks.BROWN_MUSHROOM_BLOCK).getDefaultState(); + + this.treeState = baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM); + this.branchState = baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.ALL_STEM); + this.leafState = baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.CENTER); + + //okay build a tree! Go up to the height + buildBranch(world, pos, 0, treeHeight, 0, 0, true, random); + + // make 3-4 branches + int numBranches = 3 + random.nextInt(2); + double offset = random.nextDouble(); + for (int b = 0; b < numBranches; b++) { + buildBranch(world, pos, treeHeight - 5 + b, 9, 0.3 * b + offset, 0.2, false, random); + } + + return true; + } + + /** + * Build a branch with a flat blob of leaves at the end. + * + * @param height + * @param length + * @param angle + * @param tilt + */ + private void buildBranch(World world, BlockPos pos, int height, double length, double angle, double tilt, boolean trunk, Random treeRNG) { + BlockPos src = pos.up(height); + BlockPos dest = TFGenerator.translate(src, length, angle, tilt); + + // only actually draw the branch if it's not going to load new chunks + if (world.isAreaLoaded(dest, 5)) { + if (src.getX() != dest.getX() || src.getZ() != dest.getZ()) { + // branch + TFGenerator.drawBresehnam(this, world, src, new BlockPos(dest.getX(), src.getY(), dest.getZ()), branchState); + TFGenerator.drawBresehnam(this, world, new BlockPos(dest.getX(), src.getY() + 1, dest.getZ()), dest.down(), treeState); + } else { + // trunk + TFGenerator.drawBresehnam(this, world, src, dest.down(), treeState); + } + + if (trunk) { + // add a firefly (torch) to the trunk + addFirefly(world, pos, 3 + treeRNG.nextInt(7), treeRNG.nextDouble()); + } + + drawMushroomCircle(world, dest, 4, leafState); + } + } + + /** + * Draw a flat blob (a circle?) of mushroom pieces + *

+ * This assumes that the baseState you've passed in is the center variant + */ + private void drawMushroomCircle(World world, BlockPos pos, int rad, IBlockState baseState) { + // trace out a quadrant + for (byte dx = 0; dx <= rad; dx++) { + for (byte dz = 0; dz <= rad; dz++) { + int dist = (int) (Math.max(dx, dz) + (Math.min(dx, dz) * 0.5)); + + //hack! I keep getting failing leaves at a certain position. + if (dx == 3 && dz == 3) { + dist = 6; + } + + // if we're inside the blob, fill it + if (dx == 0) { + // two! + if (dz < rad) { + setBlockAndNotifyAdequately(world, pos.add(0, 0, dz), baseState); + setBlockAndNotifyAdequately(world, pos.add(0, 0, -dz), baseState); + } else { + setBlockAndNotifyAdequately(world, pos.add(0, 0, dz), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH)); + setBlockAndNotifyAdequately(world, pos.add(0, 0, -dz), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH)); + } + } else if (dz == 0) { + // two! + if (dx < rad) { + setBlockAndNotifyAdequately(world, pos.add(dx, 0, 0), baseState); + setBlockAndNotifyAdequately(world, pos.add(-dx, 0, 0), baseState); + } else { + setBlockAndNotifyAdequately(world, pos.add(dx, 0, 0), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.EAST)); + setBlockAndNotifyAdequately(world, pos.add(-dx, 0, 0), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.WEST)); + } + } else if (dist < rad) { + // do four at a time for easiness! + setBlockAndNotifyAdequately(world, pos.add(dx, 0, dz), baseState); + setBlockAndNotifyAdequately(world, pos.add(dx, 0, -dz), baseState); + setBlockAndNotifyAdequately(world, pos.add(-dx, 0, dz), baseState); + setBlockAndNotifyAdequately(world, pos.add(-dx, 0, -dz), baseState); + } else if (dist == rad) { + // do four at a time for easiness! + setBlockAndNotifyAdequately(world, pos.add(dx, 0, dz), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_EAST)); + setBlockAndNotifyAdequately(world, pos.add(dx, 0, -dz), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_EAST)); + setBlockAndNotifyAdequately(world, pos.add(-dx, 0, dz), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.SOUTH_WEST)); + setBlockAndNotifyAdequately(world, pos.add(-dx, 0, -dz), baseState.withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.NORTH_WEST)); + } + } + } + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenCanopyOak.java b/src/main/java/twilightforest/world/feature/TFGenCanopyOak.java new file mode 100644 index 0000000000..86655ccc07 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenCanopyOak.java @@ -0,0 +1,152 @@ +package twilightforest.world.feature; + +import com.google.common.collect.Lists; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFLog; +import twilightforest.block.TFBlocks; +import twilightforest.world.TFWorld; + +import java.util.List; +import java.util.Random; + +public class TFGenCanopyOak extends TFGenCanopyTree { + + private List leaves = Lists.newArrayList(); + + public TFGenCanopyOak() { + this(false); + } + + public TFGenCanopyOak(boolean notify) { + super(notify); + this.treeState = TFBlocks.twilight_log.getDefaultState(); + this.branchState = treeState.withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + this.leafState = TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false); + this.rootState = TFBlocks.root.getDefaultState(); + + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + + // determine a height + int treeHeight = minHeight; + if (random.nextInt(chanceAddFirstFive) == 0) { + treeHeight += random.nextInt(5); + + if (random.nextInt(chanceAddSecondFive) == 0) { + treeHeight += random.nextInt(5); + } + } + + if (pos.getY() >= TFWorld.MAXHEIGHT - treeHeight) { + return false; + } + + // check if we're on dirt or grass + IBlockState state = world.getBlockState(pos.down()); + if (!state.getBlock().canSustainPlant(state, world, pos.down(), EnumFacing.UP, source)) { + return false; + } + + this.leaves.clear(); + + //okay build a tree! Go up to the height + buildTrunk(world, pos, treeHeight); + + // make 12 - 20 branches + int numBranches = 12 + random.nextInt(9); + float bangle = random.nextFloat(); + for (int b = 0; b < numBranches; b++) { + float btilt = 0.15F + (random.nextFloat() * 0.35F); + buildBranch(world, pos, treeHeight - 10 + (b / 2), 5, bangle, btilt, false, random); + + bangle += (random.nextFloat() * 0.4F); + if (bangle > 1.0F) { + bangle -= 1.0F; + } + } + + // add the actual leaves + for (BlockPos leafPos : leaves) { + makeLeafBlob(world, leafPos); + } + + makeRoots(world, random, pos); + makeRoots(world, random, pos.east()); + makeRoots(world, random, pos.south()); + makeRoots(world, random, pos.east().south()); + + return true; + } + + private void makeLeafBlob(World world, BlockPos leafPos) + { + TFGenerator.drawLeafBlob(this, world, leafPos, 2, leafState); + } + + private void makeRoots(World world, Random random, BlockPos pos) { + // root bulb + if (TFGenerator.hasAirAround(world, pos.down())) { + this.setBlockAndNotifyAdequately(world, pos.down(), treeState); + } else { + this.setBlockAndNotifyAdequately(world, pos.down(), rootState); + } + + // roots! + int numRoots = 1 + random.nextInt(2); + float offset = random.nextFloat(); + for (int b = 0; b < numRoots; b++) { + buildRoot(world, pos, offset, b); + } + } + + private void buildTrunk(World world, BlockPos pos, int treeHeight) { + for (int dy = 0; dy < treeHeight; dy++) { + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 0), treeState); + this.setBlockAndNotifyAdequately(world, pos.add(1, dy, 0), treeState); + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 1), treeState); + this.setBlockAndNotifyAdequately(world, pos.add(1, dy, 1), treeState); + } + + this.leaves.add(pos.add(0, treeHeight, 0)); + } + + /** + * Build a branch with a flat blob of leaves at the end. + */ + @Override + void buildBranch(World world, BlockPos pos, int height, double length, double angle, double tilt, boolean trunk, Random treeRNG) { + BlockPos src = pos.up(height); + BlockPos dest = TFGenerator.translate(src, length, angle, tilt); + + // constrain branch spread + int limit = 5; + if ((dest.getX() - pos.getX()) < -limit) { + dest = new BlockPos(pos.getX() - limit, dest.getY(), dest.getZ()); + } + if ((dest.getX() - pos.getX()) > limit) { + dest = new BlockPos(pos.getX() + limit, dest.getY(), dest.getZ()); + } + if ((dest.getZ() - pos.getZ()) < -limit) { + dest = new BlockPos(dest.getX(), dest.getY(), pos.getZ() - limit); + } + if ((dest.getZ() - pos.getZ()) > limit) { + dest = new BlockPos(dest.getX(), dest.getY(), pos.getZ() + limit); + } + + TFGenerator.drawBresehnam(this, world, src, dest, trunk ? treeState : branchState); + + setBlockAndNotifyAdequately(world, dest.east(), branchState); + setBlockAndNotifyAdequately(world, dest.west(), branchState); + setBlockAndNotifyAdequately(world, dest.north(), branchState); + setBlockAndNotifyAdequately(world, dest.south(), branchState); + + this.leaves.add(dest); + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/world/feature/TFGenCanopyTree.java b/src/main/java/twilightforest/world/feature/TFGenCanopyTree.java new file mode 100644 index 0000000000..068ca7a433 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenCanopyTree.java @@ -0,0 +1,140 @@ +package twilightforest.world.feature; + +import com.google.common.collect.Lists; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFLeaves; +import twilightforest.block.BlockTFLog; +import twilightforest.block.TFBlocks; +import twilightforest.enums.LeavesVariant; +import twilightforest.enums.WoodVariant; +import twilightforest.world.TFWorld; + +import java.util.List; +import java.util.Random; + +/** + * Makes large trees with flat leaf ovals that provide a canopy for the forest + * + * @author Ben + */ +public class TFGenCanopyTree extends TFTreeGenerator { + + protected int minHeight = 20; + protected int chanceAddFirstFive = 3; + protected int chanceAddSecondFive = 8; + + private List leaves = Lists.newArrayList(); + + public TFGenCanopyTree() { + this(false); + } + + public TFGenCanopyTree(boolean notify) { + super(notify); + treeState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.CANOPY); + branchState = treeState.withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + leafState = TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockTFLeaves.VARIANT, LeavesVariant.CANOPY).withProperty(BlockLeaves.CHECK_DECAY, false); + rootState = TFBlocks.root.getDefaultState(); + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + return generate(world, random, pos, true); + } + + public boolean generate(World world, Random random, BlockPos pos, boolean hasLeaves) { + // determine a height + int treeHeight = minHeight; + if (random.nextInt(chanceAddFirstFive) == 0) { + treeHeight += random.nextInt(5); + + if (random.nextInt(chanceAddSecondFive) == 0) { + treeHeight += random.nextInt(5); + } + } + + if (pos.getY() >= TFWorld.MAXHEIGHT - treeHeight) { + return false; + } + + // check if we're on dirt or grass + IBlockState state = world.getBlockState(pos.down()); + if (!state.getBlock().canSustainPlant(state, world, pos.down(), EnumFacing.UP, source)) { + return false; + } + + leaves.clear(); + + //okay build a tree! Go up to the height + buildBranch(world, pos, 0, treeHeight, 0, 0, true, random); + + // make 3-4 branches + int numBranches = 3 + random.nextInt(2); + float offset = random.nextFloat(); + for (int b = 0; b < numBranches; b++) { + buildBranch(world, pos, treeHeight - 10 + b, 9, 0.3 * b + offset, 0.2, false, random); + } + + // add the actual leaves + if (hasLeaves) + for (BlockPos leafPos : leaves) { + makeLeafBlob(world, leafPos); + } + + // root bulb + if (TFGenerator.hasAirAround(world, pos.down())) { + this.setBlockAndNotifyAdequately(world, pos.down(), treeState); + } else { + this.setBlockAndNotifyAdequately(world, pos.down(), rootState); + } + + // roots! + int numRoots = 3 + random.nextInt(2); + offset = random.nextFloat(); + for (int b = 0; b < numRoots; b++) { + buildRoot(world, pos, offset, b); + } + + + return true; + } + + private void makeLeafBlob(World world, BlockPos leafPos) { + TFGenerator.makeLeafCircle(this, world, leafPos.down(), 3, leafState, true); + TFGenerator.makeLeafCircle(this, world, leafPos, 4, leafState, true); + TFGenerator.makeLeafCircle(this, world, leafPos.up(), 2, leafState, true); + } + + /** + * Build a branch with a flat blob of leaves at the end. + */ + void buildBranch(World world, BlockPos pos, int height, double length, double angle, double tilt, boolean trunk, Random treeRNG) { + BlockPos src = pos.up(height); + BlockPos dest = TFGenerator.translate(src, length, angle, tilt); + + // only actually draw the branch if it's not going to load new chunks + if (world.isAreaLoaded(dest, 5)) { + + TFGenerator.drawBresehnam(this, world, src, dest, trunk ? treeState : branchState); + + // seems to help lighting to place this firefly now + if (trunk) { + // add a firefly (torch) to the trunk + addFirefly(world, pos, 3 + treeRNG.nextInt(7), treeRNG.nextDouble()); + } + + setBlockAndNotifyAdequately(world, dest.east(), branchState); + setBlockAndNotifyAdequately(world, dest.west(), branchState); + setBlockAndNotifyAdequately(world, dest.south(), branchState); + setBlockAndNotifyAdequately(world, dest.north(), branchState); + + // save leaf position for later + this.leaves.add(dest); + } + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenCaveStalactite.java b/src/main/java/twilightforest/world/feature/TFGenCaveStalactite.java new file mode 100644 index 0000000000..6070a8e99a --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenCaveStalactite.java @@ -0,0 +1,254 @@ +package twilightforest.world.feature; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.WeightedRandom; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.IMCHandler; +import twilightforest.TFConfig; +import twilightforest.TwilightForestMod; +import twilightforest.world.TFWorld; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class TFGenCaveStalactite extends TFGenerator { + + private static final List largeHillStalactites = new ArrayList<>(); + private static final List mediumHillStalactites = new ArrayList<>(); + private static final List smallHillStalactites = new ArrayList<>(); + + public IBlockState blockState; + public boolean hang; + public float sizeFactor; + public int maxLength; + public int minHeight; + + /** + * Initializes a stalactite builder. Actually also makes stalagmites + */ + public TFGenCaveStalactite(Block block, float size, boolean down) { + this(block.getDefaultState(), size, down); + } + + public TFGenCaveStalactite(IBlockState blockState, float size, boolean down) { + this.blockState = blockState; + this.sizeFactor = size; + this.maxLength = -1; + this.minHeight = -1; + this.hang = down; + } + + /** + * Initializes a stalactite builder + */ + public TFGenCaveStalactite(IBlockState blockState, float size, int maxLength, int minHeight) { + this.blockState = blockState; + this.sizeFactor = size; + this.maxLength = maxLength; + this.minHeight = minHeight; + this.hang = true; + } + + /** + * Makes a random stalactite appropriate to the cave size + *

+ * All include iron, coal and glowstone. + *

+ * Gold and redstone appears in size 2 and larger caves. + *

+ * Diamonds and lapis only appear in size 3 and larger caves. + */ + public static TFGenCaveStalactite makeRandomOreStalactite(Random rand, int hillSize) { + if (hillSize >= 3 || (hillSize >= 2 && rand.nextInt(5) == 0)) { + return WeightedRandom.getRandomItem(rand, largeHillStalactites).stalactite; + } + if (hillSize >= 2 || (hillSize >= 1 && rand.nextInt(5) == 0)) { + return WeightedRandom.getRandomItem(rand, mediumHillStalactites).stalactite; + } + return WeightedRandom.getRandomItem(rand, smallHillStalactites).stalactite; + } + + /** + * Generates a stalactite at the specified location. + * The coordinates should be inside a cave. + * This will return false if it can't find a valid ceiling and floor, or if there are other errors. + */ + @Override + public boolean generate(World world, Random random, BlockPos pos) { + int ceiling = Integer.MAX_VALUE; + int floor = -1; + + BlockPos.MutableBlockPos iterPos = new BlockPos.MutableBlockPos(pos); + // find a ceiling + for (int ty = pos.getY(); ty < TFWorld.CHUNKHEIGHT; ty++) { + iterPos.setY(ty); + Material m = world.getBlockState(iterPos).getMaterial(); + // if we're in air, continue + if (m == Material.AIR) { + continue; + } + // if we get something that's not cave material, fail! + if (m != Material.GROUND && m != Material.ROCK) { + return false; + } + // okay, we found a valid ceiling. + ceiling = ty; + break; + } + // if we didn't find a ceiling, fail. + if (ceiling == Integer.MAX_VALUE) { + return false; + } + + // find a floor + for (int ty = pos.getY(); ty > 4; ty--) { + iterPos.setY(ty); + Material m = world.getBlockState(iterPos).getMaterial(); + // if we're in air, continue + if (m == Material.AIR) { + continue; + } + // if we get something that's not cave material, fail! + // actually stalactites can hang above water or lava + if (m != Material.GROUND && m != Material.ROCK && (!hang && m != Material.WATER) && (!hang && m != Material.LAVA)) { + return false; + } + // okay, we found a valid floor. + floor = ty; + break; + } + + int length = (int) ((ceiling - floor) * this.sizeFactor * random.nextFloat()); + + // check max length + if (this.maxLength > -1 && length > this.maxLength) { + length = this.maxLength; + } + + // check minimum height + if (this.minHeight > -1 && ceiling - floor - length < this.minHeight) { + return false; + } + + return makeSpike(world, random, new BlockPos(pos.getX(), hang ? ceiling : floor, pos.getZ()), length); + } + + public boolean makeSpike(World world, Random random, BlockPos pos, int maxLength) { + + int diameter = (int) (maxLength / 4.5); // diameter of the base + + // let's see... + for (int dx = -diameter; dx <= diameter; dx++) { + for (int dz = -diameter; dz <= diameter; dz++) { + // determine how long this spike will be. + int absx = Math.abs(dx); + int absz = Math.abs(dz); + int dist = (int) (Math.max(absx, absz) + (Math.min(absx, absz) * 0.5)); + int spikeLength = 0; + + if (dist == 0) { + spikeLength = maxLength; + } + + if (dist > 0) { + spikeLength = random.nextInt((int) (maxLength / (dist + 0.25))); + } + + int dir = hang ? -1 : 1; + + // check if we're generating over anything + if (!world.getBlockState(pos.add(dx, -dir, dz)).getMaterial().isSolid()) { + spikeLength = 0; + } + + for (int dy = 0; dy != (spikeLength * dir); dy += dir) { + setBlockAndNotifyAdequately(world, pos.add(dx, dy, dz), blockState); + } + } + } + + return true; + } + + public static class StalactiteEntry extends WeightedRandom.Item { + + final TFGenCaveStalactite stalactite; + + StalactiteEntry(TFGenCaveStalactite stalactite, int itemWeight) { + super(itemWeight); + this.stalactite = stalactite; + } + + public StalactiteEntry(IBlockState blockState, float size, int maxLength, int minHeight, int itemWeight) { + this(new TFGenCaveStalactite(blockState, size, maxLength, minHeight), itemWeight); + } + } + + public static void addStalactite(int hillSize, IBlockState blockState, float size, int maxLength, int minHeight, int itemWeight) { + if (itemWeight > 0) { + addStalactite(hillSize, new StalactiteEntry(blockState, size, maxLength, minHeight, itemWeight)); + } + } + + private static void addStalactite(int hillSize, StalactiteEntry entry) { + if (hillSize <= 1) + smallHillStalactites.add(entry); + if (hillSize <= 2) + mediumHillStalactites.add(entry); + largeHillStalactites.add(entry); + } + + /* + * Current default weights are as follows: + * + * Large (total 195 = 13*15): + * 2/13 diamond + * 2/13 lapis + * 1/13 emerald + * 8/13 [medium pool] + * + * Medium (total 120 = 6*20): + * 1/6 gold + * 1/6 redstone + * 3/6 [small pool] + * + * Small (total 60 = 5*12): + * 2/5 iron + * 2/5 coal + * 1/5 glowstone + */ + private static void addDefaultStalactites() { + addStalactite(3, Blocks.DIAMOND_ORE.getDefaultState(), 0.5F, 4, 16, 30); + addStalactite(3, Blocks.LAPIS_ORE.getDefaultState(), 0.8F, 8, 1, 30); + addStalactite(3, Blocks.EMERALD_ORE.getDefaultState(), 0.5F, 3, 12, 15); + + addStalactite(2, Blocks.GOLD_ORE.getDefaultState(), 0.6F, 6, 1, 20); + addStalactite(2, Blocks.REDSTONE_ORE.getDefaultState(), 0.8F, 8, 1, 40); + + addStalactite(1, Blocks.IRON_ORE.getDefaultState(), 0.7F, 8, 1, 24); + addStalactite(1, Blocks.COAL_ORE.getDefaultState(), 0.8F, 12, 1, 24); + addStalactite(1, Blocks.GLOWSTONE.getDefaultState(), 0.5F, 8, 1, 12); + } + + public static void loadStalactites() { + smallHillStalactites.clear(); + mediumHillStalactites.clear(); + largeHillStalactites.clear(); + + TFConfig.dimension.hollowHillStalactites.load(); + if (TFConfig.dimension.hollowHillStalactites.useConfigOnly) { + if (smallHillStalactites.isEmpty()) { + TwilightForestMod.LOGGER.info("Not all hollow hills are populated with the config, adding fallback"); + addStalactite(1, Blocks.STONE.getDefaultState(), 0.7F, 8, 1, 1); + } + return; + } + addDefaultStalactites(); + IMCHandler.getStalactites().forEach(TFGenCaveStalactite::addStalactite); + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenDarkCanopyTree.java b/src/main/java/twilightforest/world/feature/TFGenDarkCanopyTree.java new file mode 100644 index 0000000000..60da63c136 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenDarkCanopyTree.java @@ -0,0 +1,124 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLog; +import net.minecraft.block.material.Material; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFLog; +import twilightforest.block.TFBlocks; +import twilightforest.enums.WoodVariant; +import twilightforest.world.TFWorld; + +import java.util.Random; + +/** + * Makes large trees with flat leaf ovals that provide a canopy for the forest + * + * @author Ben + */ +public class TFGenDarkCanopyTree extends TFTreeGenerator { + + + public TFGenDarkCanopyTree() { + this(false); + } + + public TFGenDarkCanopyTree(boolean notify) { + super(notify); + treeState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.DARK); + branchState = treeState.withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + leafState = TFBlocks.dark_leaves.getDefaultState(); + rootState = TFBlocks.root.getDefaultState(); + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + // if we are given leaves as a starting position, seek dirt or grass underneath + boolean foundDirt = false; + Material materialUnder; + for (int dy = pos.getY(); dy >= TFWorld.SEALEVEL; dy--) { + materialUnder = world.getBlockState(new BlockPos(pos.getX(), dy - 1, pos.getZ())).getMaterial(); + if (materialUnder == Material.GRASS || materialUnder == Material.GROUND) { + // yes! + foundDirt = true; + pos = new BlockPos(pos.getX(), dy, pos.getZ()); + break; + } else if (materialUnder == Material.ROCK || materialUnder == Material.SAND) { + // nope + break; + } + } + + if (!foundDirt) { + return false; + } + + // do not grow next to another tree + for (EnumFacing e : EnumFacing.HORIZONTALS) { + if (world.getBlockState(pos.offset(e)).getMaterial() == Material.WOOD) + return false; + } + + // determine a height + int treeHeight = 6 + random.nextInt(5); + + //okay build a tree! trunk here + TFGenerator.drawBresehnam(this, world, pos, pos.up(treeHeight), treeState); + leafAround(world, pos.up(treeHeight)); + + // make 4 branches + int numBranches = 4; + double offset = random.nextFloat(); + for (int b = 0; b < numBranches; b++) { + buildBranch(world, pos, treeHeight - 3 - numBranches + (b / 2), 10 + random.nextInt(4), 0.23 * b + offset, 0.23, random); + } + + // root bulb + if (TFGenerator.hasAirAround(world, pos.down())) { + this.setBlockAndNotifyAdequately(world, pos.down(), treeState); + } else { + this.setBlockAndNotifyAdequately(world, pos.down(), rootState); + } + + // roots! + int numRoots = 3 + random.nextInt(2); + offset = random.nextDouble(); + for (int b = 0; b < numRoots; b++) { + buildRoot(world, pos, offset, b); + } + + + return true; + } + + /** + * Build a branch with a flat blob of leaves at the end. + */ + private void buildBranch(World world, BlockPos pos, int height, double length, double angle, double tilt, Random random) { + BlockPos src = pos.up(height); + BlockPos dest = TFGenerator.translate(src, length, angle, tilt); + + // only actually draw the branch if it's not going to load new chunks + if (world.isAreaLoaded(dest, 6)) { + TFGenerator.drawBresehnam(this, world, src, dest, branchState); + leafAround(world, dest); + } + } + + /** + * Make our leaf pattern + */ + private void leafAround(World world, BlockPos pos) { + int leafSize = 4; + + // only leaf if there are no leaves by where we are thinking of leafing + if (TFGenerator.hasAirAround(world, pos)) { + TFGenerator.makeLeafCircle(this, world, pos.down(), leafSize, leafState, false); + TFGenerator.makeLeafCircle(this, world, pos, leafSize + 1, leafState, false); + TFGenerator.makeLeafCircle(this, world, pos.up(), leafSize, leafState, false); + TFGenerator.makeLeafCircle(this, world, pos.up(2), leafSize - 2, leafState, false); + } + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenFallenHollowLog.java b/src/main/java/twilightforest/world/feature/TFGenFallenHollowLog.java new file mode 100644 index 0000000000..83791c0d55 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenFallenHollowLog.java @@ -0,0 +1,220 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFLog; +import twilightforest.block.BlockTFPlant; +import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; + +import java.util.Random; + +public class TFGenFallenHollowLog extends TFGenerator { + + final IBlockState mossPatch = TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MOSSPATCH); + final IBlockState oakLeaves = TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false); + final IBlockState oakLogWithZAxis = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.Z); + final IBlockState oakLogWithXAxis = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.X); + final IBlockState dirt = Blocks.DIRT.getDefaultState(); + final IBlockState firefly = TFBlocks.firefly.getDefaultState(); + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + return rand.nextBoolean() ? makeLog4Z(world, rand, pos) : makeLog4X(world, rand, pos); + } + + private boolean makeLog4Z(World world, Random rand, BlockPos pos) { + // +Z 4x4 log + if (!isAreaSuitable(world, rand, pos, 9, 3, 4)) { + return false; + } + + // jaggy parts + makeNegativeZJaggy(world, pos, rand.nextInt(3), 0, 0); + makeNegativeZJaggy(world, pos, rand.nextInt(3), 3, 0); + makeNegativeZJaggy(world, pos, rand.nextInt(3), 0, 1); + makeNegativeZJaggy(world, pos, rand.nextInt(3), 3, 1); + makeNegativeZJaggy(world, pos, rand.nextInt(3), 1, 2); + makeNegativeZJaggy(world, pos, rand.nextInt(3), 2, 2); + + makePositiveZJaggy(world, pos, rand.nextInt(3), 0, 0); + makePositiveZJaggy(world, pos, rand.nextInt(3), 3, 0); + makePositiveZJaggy(world, pos, rand.nextInt(3), 0, 1); + makePositiveZJaggy(world, pos, rand.nextInt(3), 3, 1); + makePositiveZJaggy(world, pos, rand.nextInt(3), 1, 2); + makePositiveZJaggy(world, pos, rand.nextInt(3), 2, 2); + + // center + for (int dz = 0; dz < 4; dz++) { + // floor + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(1, -1, dz + 3), oakLogWithZAxis); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, dz + 3), mossPatch); + } + } else { + this.setBlockAndNotifyAdequately(world, pos.add(1, -1, dz + 3), dirt); + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, dz + 3), mossPatch); + } + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(2, -1, dz + 3), oakLogWithZAxis); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(2, 0, dz + 3), mossPatch); + } + } else { + this.setBlockAndNotifyAdequately(world, pos.add(2, -1, dz + 3), dirt); + this.setBlockAndNotifyAdequately(world, pos.add(2, 0, dz + 3), mossPatch); + } + + // log part + this.setBlockAndNotifyAdequately(world, pos.add(0, 0, dz + 3), oakLogWithZAxis); + this.setBlockAndNotifyAdequately(world, pos.add(3, 0, dz + 3), oakLogWithZAxis); + this.setBlockAndNotifyAdequately(world, pos.add(0, 1, dz + 3), oakLogWithZAxis); + this.setBlockAndNotifyAdequately(world, pos.add(3, 1, dz + 3), oakLogWithZAxis); + this.setBlockAndNotifyAdequately(world, pos.add(1, 2, dz + 3), oakLogWithZAxis); + this.setBlockAndNotifyAdequately(world, pos.add(2, 2, dz + 3), oakLogWithZAxis); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(1, 3, dz + 3), mossPatch); + } + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(2, 3, dz + 3), mossPatch); + } + } + + // a few leaves? + int offZ = rand.nextInt(3) + 2; + boolean plusX = rand.nextBoolean(); + for (int dz = 0; dz < 3; dz++) { + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(plusX ? 3 : 0, 2, dz + offZ), oakLeaves); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(plusX ? 3 : 0, 3, dz + offZ), oakLeaves); + } + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(plusX ? 4 : -1, 2, dz + offZ), oakLeaves); + } + } + } + + + // firefly + this.setBlockAndNotifyAdequately(world, pos.add(plusX ? 0 : 3, 2, rand.nextInt(4) + 3), firefly); + + + return true; + } + + private void makeNegativeZJaggy(World world, BlockPos pos, int length, int dx, int dy) { + for (int dz = -length; dz < 0; dz++) { + this.setBlockAndNotifyAdequately(world, pos.add(dx, dy, dz + 3), oakLogWithZAxis); + } + } + + private void makePositiveZJaggy(World world, BlockPos pos, int length, int dx, int dy) { + for (int dz = 0; dz < length; dz++) { + this.setBlockAndNotifyAdequately(world, pos.add(dx, dy, dz + 7), oakLogWithZAxis); + } + } + + /** + * Make a 4x4 log in the +X direction + */ + private boolean makeLog4X(World world, Random rand, BlockPos pos) { + // +Z 4x4 log + if (!isAreaSuitable(world, rand, pos, 4, 3, 9)) { + return false; + } + + // jaggy parts + makeNegativeXJaggy(world, pos, rand.nextInt(3), 0, 0); + makeNegativeXJaggy(world, pos, rand.nextInt(3), 3, 0); + makeNegativeXJaggy(world, pos, rand.nextInt(3), 0, 1); + makeNegativeXJaggy(world, pos, rand.nextInt(3), 3, 1); + makeNegativeXJaggy(world, pos, rand.nextInt(3), 1, 2); + makeNegativeXJaggy(world, pos, rand.nextInt(3), 2, 2); + + makePositiveXJaggy(world, pos, rand.nextInt(3), 0, 0); + makePositiveXJaggy(world, pos, rand.nextInt(3), 3, 0); + makePositiveXJaggy(world, pos, rand.nextInt(3), 0, 1); + makePositiveXJaggy(world, pos, rand.nextInt(3), 3, 1); + makePositiveXJaggy(world, pos, rand.nextInt(3), 1, 2); + makePositiveXJaggy(world, pos, rand.nextInt(3), 2, 2); + + // center + for (int dx = 0; dx < 4; dx++) { + // floor + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, -1, 1), oakLogWithXAxis); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 0, 1), mossPatch); + } + } else { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, -1, 1), dirt); + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 0, 1), mossPatch); + } + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, -1, 2), oakLogWithXAxis); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 0, 2), mossPatch); + } + } else { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, -1, 2), dirt); + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 0, 2), mossPatch); + } + + // log part + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 0, 0), oakLogWithXAxis); + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 0, 3), oakLogWithXAxis); + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 1, 0), oakLogWithXAxis); + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 1, 3), oakLogWithXAxis); + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 2, 1), oakLogWithXAxis); + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 2, 2), oakLogWithXAxis); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 3, 1), mossPatch); + } + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, 3, 2), mossPatch); + } + + } + + // a few leaves? + int offX = rand.nextInt(3) + 2; + boolean plusZ = rand.nextBoolean(); + for (int dx = 0; dx < 3; dx++) { + if (rand.nextBoolean()) { + + this.setBlockAndNotifyAdequately(world, pos.add(dx + offX, 2, plusZ ? 3 : 0), oakLeaves); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + offX, 3, plusZ ? 3 : 0), oakLeaves); + } + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + offX, 2, plusZ ? 4 : -1), oakLeaves); + } + } + } + + + // firefly + this.setBlockAndNotifyAdequately(world, pos.add(rand.nextInt(4) + 3, 2, plusZ ? 0 : 3), firefly); + + return true; + } + + private void makeNegativeXJaggy(World world, BlockPos pos, int length, int dz, int dy) { + for (int dx = -length; dx < 0; dx++) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 3, dy, dz), oakLogWithXAxis); + } + } + + private void makePositiveXJaggy(World world, BlockPos pos, int length, int dz, int dy) { + for (int dx = 0; dx < length; dx++) { + this.setBlockAndNotifyAdequately(world, pos.add(dx + 7, dy, dz), oakLogWithXAxis); + } + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenFallenLeaves.java b/src/main/java/twilightforest/world/feature/TFGenFallenLeaves.java new file mode 100644 index 0000000000..fa97b2c9df --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenFallenLeaves.java @@ -0,0 +1,53 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockBush; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; +import twilightforest.block.BlockTFPlant; +import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class TFGenFallenLeaves extends WorldGenerator { + + private final IBlockState state = TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.FALLEN_LEAVES); + + @Override + public boolean generate(World worldIn, Random rand, BlockPos position) { + do { + IBlockState state = worldIn.getBlockState(position.down()); + if (worldIn.isAirBlock(position) && (state.getMaterial() == Material.GRASS || state.getMaterial() == Material.GROUND)) + break; + position = position.down(); + } while (position.getY() > TFWorld.SEALEVEL); + + for (int x = 0; x < 5; x++) + for (int z = 0; z < 5; z++) { + if (rand.nextInt(3) != 0) + continue; + boolean flag = false; + int y = 2; + do { + IBlockState state = worldIn.getBlockState(position.add(x, y, z).down()); + if (worldIn.isAirBlock(position.add(x, y, z)) && (state.getMaterial() == Material.GRASS || state.getMaterial() == Material.GROUND)) { + flag = true; + break; + } + y--; + } while (y >= -2); + if (!flag) + continue; + BlockPos pos = position.add(x, y, z); + if (((BlockBush) state.getBlock()).canBlockStay(worldIn, pos, state)) + worldIn.setBlockState(pos, state, 16 | 2); + } + + return true; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenFallenSmallLog.java b/src/main/java/twilightforest/world/feature/TFGenFallenSmallLog.java new file mode 100644 index 0000000000..f4218dd695 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenFallenSmallLog.java @@ -0,0 +1,120 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLog; +import net.minecraft.block.BlockOldLog; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFLog; +import twilightforest.block.BlockTFPlant; +import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; +import twilightforest.enums.WoodVariant; + +import java.util.Random; + +public class TFGenFallenSmallLog extends TFGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + // determine direction + boolean goingX = rand.nextBoolean(); + + // length + int length = rand.nextInt(4) + 3; + + // check area clear + if (goingX) { + if (!isAreaSuitable(world, rand, pos, length, 3, 2)) { + return false; + } + } else { + if (!isAreaSuitable(world, rand, pos, 3, length, 2)) { + return false; + } + } + + // determine wood type + IBlockState logState; + IBlockState branchState; + + switch (rand.nextInt(7)) { + case 0: + default: + logState = TFBlocks.twilight_log.getDefaultState(); + break; + case 1: + logState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.CANOPY); + break; + case 2: + logState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.MANGROVE); + break; + case 3: + logState = Blocks.LOG.getDefaultState(); + break; + case 4: + logState = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.SPRUCE); + break; + case 5: + logState = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.BIRCH); + break; + case 6: + logState = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); + break; + } + branchState = logState; + + // check biome + + + // make log + if (goingX) { + logState = logState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X); + branchState = logState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z); + + for (int lx = 0; lx < length; lx++) { + this.setBlockAndNotifyAdequately(world, pos.add(lx, 0, 1), logState); + if (rand.nextInt(3) > 0) { + this.setBlockAndNotifyAdequately(world, pos.add(lx, 1, 1), TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MOSSPATCH)); + } + } + } else { + logState = logState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z); + branchState = logState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X); + + for (int lz = 0; lz < length; lz++) { + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, lz), logState); + if (rand.nextInt(3) > 0) { + this.setBlockAndNotifyAdequately(world, pos.add(1, 1, lz), TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MOSSPATCH)); + } + } + } + + // possibly make branch + if (rand.nextInt(3) > 0) { + if (goingX) { + int bx = rand.nextInt(length); + int bz = rand.nextBoolean() ? 2 : 0; + + this.setBlockAndNotifyAdequately(world, pos.add(bx, 0, bz), branchState); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(bx, 1, bz), TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MOSSPATCH)); + } + } else { + int bx = rand.nextBoolean() ? 2 : 0; + int bz = rand.nextInt(length); + + this.setBlockAndNotifyAdequately(world, pos.add(bx, 0, bz), branchState); + if (rand.nextBoolean()) { + this.setBlockAndNotifyAdequately(world, pos.add(bx, 1, bz), TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.MOSSPATCH)); + } + } + } + + return true; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenFireJet.java b/src/main/java/twilightforest/world/feature/TFGenFireJet.java new file mode 100644 index 0000000000..8dce6d48cf --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenFireJet.java @@ -0,0 +1,55 @@ +package twilightforest.world.feature; + +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFFireJet; +import twilightforest.block.TFBlocks; +import twilightforest.enums.FireJetVariant; + +import java.util.Random; + +public class TFGenFireJet extends TFGenerator { + private final FireJetVariant variant; + + public TFGenFireJet(FireJetVariant variant) { + this.variant = variant; + } + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + for (int i = 0; i < 4; ++i) { + BlockPos dPos = pos.add( + rand.nextInt(8) - rand.nextInt(8), + rand.nextInt(4) - rand.nextInt(4), + rand.nextInt(8) - rand.nextInt(8) + ); + + if (world.isAirBlock(dPos) && world.canSeeSky(dPos) && world.getBlockState(dPos.down()).getMaterial() == Material.GRASS + && world.getBlockState(dPos.east().down()).getMaterial() == Material.GRASS && world.getBlockState(dPos.west().down()).getMaterial() == Material.GRASS + && world.getBlockState(dPos.south().down()).getMaterial() == Material.GRASS && world.getBlockState(dPos.north().down()).getMaterial() == Material.GRASS) { + // jet + world.setBlockState(dPos.down(), TFBlocks.fire_jet.getDefaultState().withProperty(BlockTFFireJet.VARIANT, variant), 0); + + // create reservoir with stone walls + for (int rx = -2; rx <= 2; rx++) { + for (int rz = -2; rz <= 2; rz++) { + BlockPos dPos2 = dPos.add(rx, -2, rz); + if ((rx == 1 || rx == 0 || rx == -1) && (rz == 1 || rz == 0 || rz == -1)) { + // lava reservoir + world.setBlockState(dPos2, Blocks.FLOWING_LAVA.getDefaultState(), 0); + } else if (world.getBlockState(dPos2).getMaterial() != Material.LAVA) { + // only stone where there is no lava + world.setBlockState(dPos2, Blocks.STONE.getDefaultState(), 0); + } + world.setBlockState(dPos2.down(), Blocks.STONE.getDefaultState(), 0); + } + } + } + } + + return true; + + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenFoundation.java b/src/main/java/twilightforest/world/feature/TFGenFoundation.java new file mode 100644 index 0000000000..bce3b32c83 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenFoundation.java @@ -0,0 +1,64 @@ +package twilightforest.world.feature; + +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.loot.TFTreasure; + +import java.util.Random; + + +public class TFGenFoundation extends TFGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + int sx = 5 + rand.nextInt(5); + int sz = 5 + rand.nextInt(5); + + + if (!isAreaSuitable(world, rand, pos, sx, 4, sz)) { + return false; + } + + //okay! + for (int cx = 0; cx <= sx; cx++) { + for (int cz = 0; cz <= sz; cz++) { + if (cx == 0 || cx == sx || cz == 0 || cz == sz) { + // stone on the edges + int ht = rand.nextInt(4) + 1; + + for (int cy = 0; cy <= ht; cy++) { + setBlockAndNotifyAdequately(world, pos.add(cx, cy - 1, cz), randStone(rand, cy + 1)); + } + } else { + // destroyed wooden plank floor + if (rand.nextInt(3) != 0) { + setBlockAndNotifyAdequately(world, pos.add(cx, -1, cz), Blocks.PLANKS.getDefaultState()); + } + } + } + } + + //TODO: chimney? + + // 50% basement chance! + if (rand.nextInt(2) == 0) { + // clear basement + for (int cx = 1; cx < sx; cx++) { + for (int cz = 1; cz < sz; cz++) { + setBlockAndNotifyAdequately(world, pos.add(cx, -3, cz), Blocks.AIR.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(cx, -4, cz), Blocks.AIR.getDefaultState()); + } + } + + // make chest + int cx = rand.nextInt(sx - 1) + 1; + int cz = rand.nextInt(sz - 1) + 1; + TFTreasure.basement.generateChest(world, pos.add(cx, -4, cz), false); + + } + + + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenGroveRuins.java b/src/main/java/twilightforest/world/feature/TFGenGroveRuins.java new file mode 100644 index 0000000000..5dad664e4c --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenGroveRuins.java @@ -0,0 +1,122 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockStoneBrick; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Random; + + +/** + * Several ruin types that look like the quest grove + * + * @author Ben + */ +public class TFGenGroveRuins extends TFGenerator { + + private static final IBlockState MOSSY_STONEBRICK = Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.MOSSY); + private static final IBlockState CHISELED_STONEBRICK = Blocks.STONEBRICK.getDefaultState().withProperty(BlockStoneBrick.VARIANT, BlockStoneBrick.EnumType.CHISELED); + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + if (rand.nextBoolean()) { + return generateLargeArch(world, rand, pos); + } else { + return generateSmallArch(world, rand, pos); + } + } + + /** + * Generate a ruin with the larger arch + */ + private boolean generateLargeArch(World world, Random rand, BlockPos pos) { + if (!isAreaSuitable(world, rand, pos, 2, 7, 6)) { + return false; + } + + // pillar + for (int dy = -2; dy <= 7; dy++) { + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 1), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, dy, 1), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 2), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, dy, 2), MOSSY_STONEBRICK); + } + + // broken floor part + this.setBlockAndNotifyAdequately(world, pos.add(0, -1, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, -1, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, -2, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, -2, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, -1, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, -1, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, -2, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, -2, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, -1, 5), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, -2, 5), MOSSY_STONEBRICK); + + // broken top part + this.setBlockAndNotifyAdequately(world, pos.add(0, 6, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, 6, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, 7, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, 7, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, 6, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, 6, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, 7, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, 7, 4), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, 7, 5), MOSSY_STONEBRICK); + + // small piece of chiseled stone brick + this.setBlockAndNotifyAdequately(world, pos.add(0, 5, 0), CHISELED_STONEBRICK); + + return true; + } + + /** + * Generate a ruin with the smaller arch + */ + private boolean generateSmallArch(World world, Random rand, BlockPos pos) { + if (!isAreaSuitable(world, rand, pos, 7, 5, 9)) { + return false; + } + + // corner + this.setBlockAndNotifyAdequately(world, pos.add(0, 4, 0), CHISELED_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, 3, 0), CHISELED_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(1, 4, 0), CHISELED_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(2, 4, 0), CHISELED_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, 4, 1), CHISELED_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, 4, 2), CHISELED_STONEBRICK); + + // broken arch in x direction + for (int dy = -1; dy <= 5; dy++) { + this.setBlockAndNotifyAdequately(world, pos.add(3, dy, 0), MOSSY_STONEBRICK); + } + this.setBlockAndNotifyAdequately(world, pos.add(4, -1, 0), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(5, -1, 0), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(6, -1, 0), MOSSY_STONEBRICK); + + this.setBlockAndNotifyAdequately(world, pos.add(4, 5, 0), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(5, 5, 0), MOSSY_STONEBRICK); + + // full arch in z direction + for (int dy = -1; dy <= 5; dy++) { + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 3), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 7), MOSSY_STONEBRICK); + } + for (int dz = 4; dz < 7; dz++) { + this.setBlockAndNotifyAdequately(world, pos.add(0, -1, dz), MOSSY_STONEBRICK); + this.setBlockAndNotifyAdequately(world, pos.add(0, 5, dz), MOSSY_STONEBRICK); + } + + // small piece of chiseled stone brick + this.setBlockAndNotifyAdequately(world, pos.add(0, 4, 8), CHISELED_STONEBRICK); + + + return true; + } + +} + diff --git a/src/main/java/twilightforest/world/feature/TFGenHangingLamps.java b/src/main/java/twilightforest/world/feature/TFGenHangingLamps.java new file mode 100644 index 0000000000..085a5ab4e8 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenHangingLamps.java @@ -0,0 +1,61 @@ +package twilightforest.world.feature; + +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.TFBlocks; + +import java.util.Random; + +public class TFGenHangingLamps extends TFGenerator { + + private static final int MAX_HANG = 8; + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + // this must be an air block, surrounded by air + if (!world.isAirBlock(pos) || !TFGenerator.surroundedByAir(world, pos)) { + return false; + } + + // we need to be at least 4 above ground + if (!isClearBelow(world, pos)) { + return false; + } + + // there should be leaves or wood within 12 blocks above + int dist = findLeavesAbove(world, pos); + if (dist < 0) { + return false; + } + + // generate lamp + world.setBlockState(pos, TFBlocks.firefly_jar.getDefaultState(), 16 | 2); + for (int cy = 1; cy < dist; cy++) { + world.setBlockState(pos.up(cy), Blocks.OAK_FENCE.getDefaultState(), 16 | 2); + } + + return true; + } + + private int findLeavesAbove(World world, BlockPos pos) { + for (int cy = 1; cy < MAX_HANG; cy++) { + Material above = world.getBlockState(pos.up(cy)).getMaterial(); + if (above.isSolid() || above == Material.LEAVES) { + return cy; + } + } + return -1; + } + + private boolean isClearBelow(World world, BlockPos pos) { + for (int cy = 1; cy < 4; cy++) { + if (world.getBlockState(pos.down(cy)).isSideSolid(world, pos, EnumFacing.UP)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenHollowStump.java b/src/main/java/twilightforest/world/feature/TFGenHollowStump.java new file mode 100644 index 0000000000..9ba99b211f --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenHollowStump.java @@ -0,0 +1,88 @@ +package twilightforest.world.feature; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Random; + + +/** + * A stump from a hollow tree + * + * @author Ben + */ +public class TFGenHollowStump extends TFGenHollowTree { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + int radius = rand.nextInt(2) + 2; + + if (!isAreaSuitable(world, rand, pos.add(-radius, 0, -radius), 2 * radius, 6, 2 * radius)) { + return false; + } + + buildTrunk(world, rand, pos, radius, 6); + + // 3-5 roots at the bottom + buildBranchRing(world, rand, pos, radius, 3, 2, 6, 0, 0.75D, 0, 3, 5, 3, false); + + + // several more taproots + buildBranchRing(world, rand, pos, radius, 1, 2, 8, 0, 0.9D, 0, 3, 5, 3, false); + + + return true; + } + + @Override + protected void buildTrunk(World world, Random random, BlockPos pos, int diameter, int maxHeight) { + + int hollow = diameter / 2; + + + // go down 4 squares and fill in extra trunk as needed, in case we're on uneven terrain + for (int dx = -diameter; dx <= diameter; dx++) { + for (int dz = -diameter; dz <= diameter; dz++) { + for (int dy = -4; dy < 0; dy++) { + // determine how far we are from the center. + int ax = Math.abs(dx); + int az = Math.abs(dz); + int dist = (int) (Math.max(ax, az) + (Math.min(ax, az) * 0.5)); + + if (dist <= diameter) { + BlockPos dPos = pos.add(dx, dy, dz); + if (hasAirAround(world, dPos)) { + this.setBlockAndNotifyAdequately(world, dPos, dist > hollow ? treeState : branchState); + } else { + this.setBlockAndNotifyAdequately(world, dPos, rootState); + } + } + } + } + } + + // build the trunk upwards + for (int dx = -diameter; dx <= diameter; dx++) { + for (int dz = -diameter; dz <= diameter; dz++) { + int height = 2 + random.nextInt(3) + random.nextInt(2); + + for (int dy = 0; dy <= height; dy++) { + // determine how far we are from the center. + int ax = Math.abs(dx); + int az = Math.abs(dz); + int dist = (int) (Math.max(ax, az) + (Math.min(ax, az) * 0.5)); + + // make a trunk! + if (dist <= diameter && dist > hollow) { + setBlockAndNotifyAdequately(world, pos.add(dx, dy, dz), treeState); + } + } + } + } + + } + + +} + diff --git a/src/main/java/twilightforest/world/feature/TFGenHollowTree.java b/src/main/java/twilightforest/world/feature/TFGenHollowTree.java new file mode 100644 index 0000000000..f911d6b287 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenHollowTree.java @@ -0,0 +1,519 @@ +package twilightforest.world.feature; + +import net.minecraft.block.*; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityList; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntityMobSpawner; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.IPlantable; +import twilightforest.loot.TFTreasure; +import twilightforest.block.BlockTFLog; +import twilightforest.block.TFBlocks; +import twilightforest.entity.EntityTFSwarmSpider; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class TFGenHollowTree extends TFGenerator { + + private static final int LEAF_DUNGEON_CHANCE = 8; + + protected IBlockState treeState = TFBlocks.twilight_log.getDefaultState(); + protected IBlockState branchState = treeState.withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + protected IBlockState leafState = TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false); + protected IBlockState rootState = TFBlocks.root.getDefaultState(); + + protected IPlantable source = TFBlocks.twilight_sapling; + + public TFGenHollowTree() { + this(false); + } + + public TFGenHollowTree(boolean notify) { + super(notify); + } + + public static boolean canGrowInto(Block blockType) { + Material material = blockType.getDefaultState().getMaterial(); + return material == Material.AIR || material == Material.LEAVES || material == Material.WATER || material == Material.LAVA || blockType instanceof IGrowable || blockType instanceof BlockDirt || blockType instanceof BlockLog || blockType instanceof BlockBush || blockType instanceof BlockVine; + } + + @Override + protected void setBlockAndNotifyAdequately(World worldIn, BlockPos pos, IBlockState state) { + if (canGrowInto(worldIn.getBlockState(pos).getBlock())) + super.setBlockAndNotifyAdequately(worldIn, pos, state); + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + + int height = random.nextInt(64) + 32; + int diameter = random.nextInt(4) + 1; + + + // do we have enough height? + if (pos.getY() < 1 || pos.getY() + height + diameter > TFWorld.MAXHEIGHT) { + return false; + } + +// // are we going to hit something? +// for (int dx = -diameter; dx <= diameter; dx++) +// { +// for (int dz = -diameter; dz <= diameter; dz++) +// { +// for (int dy = 1; dy <= height; dy++) +// { +// int whatsThere = world.getBlock(dx + x, dy + y, dz + z); +// if(whatsThere != 0 && whatsThere != Blocks.LEAVES) +// { +// return false; +// } +// } +// } +// } + // check the top too + int crownRadius = diameter * 4 + 8; + for (int dx = -crownRadius; dx <= crownRadius; dx++) { + for (int dz = -crownRadius; dz <= crownRadius; dz++) { + for (int dy = height - crownRadius; dy <= height + crownRadius; dy++) { + Block whatsThere = world.getBlockState(pos.add(dx, dy, dz)).getBlock(); + if (whatsThere != Blocks.AIR && whatsThere != Blocks.LEAVES) { + return false; + } + } + } + } + + // check if we're on dirt or grass + IBlockState state = world.getBlockState(pos.down()); + if (!state.getBlock().canSustainPlant(state, world, pos.down(), EnumFacing.UP, source)) { + return false; + } + + // make a tree! + + // build the trunk + buildTrunk(world, random, pos, diameter, height); + + // fireflies + int numFireflies = random.nextInt(3 * diameter) + 5; + for (int i = 0; i <= numFireflies; i++) { + int fHeight = (int) (height * random.nextDouble() * 0.9) + (height / 10); + double fAngle = random.nextDouble(); + addFirefly(world, pos, diameter, fHeight, fAngle); + } + + // cicadas + numFireflies = random.nextInt(3 * diameter) + 5; + for (int i = 0; i <= numFireflies; i++) { + int fHeight = (int) (height * random.nextDouble() * 0.9) + (height / 10); + double fAngle = random.nextDouble(); + addCicada(world, pos, diameter, fHeight, fAngle); + } + + // build the crown + buildFullCrown(world, random, pos, diameter, height); + + + // 3-5 couple branches on the way up... + int numBranches = random.nextInt(3) + 3; + for (int i = 0; i <= numBranches; i++) { + int branchHeight = (int) (height * random.nextDouble() * 0.9) + (height / 10); + double branchRotation = random.nextDouble(); + makeSmallBranch(world, random, pos, diameter, branchHeight, 4, branchRotation, 0.35D, true); + } + + // 3-5 roots at the bottom + buildBranchRing(world, random, pos, diameter, 3, 2, 6, 0, 0.75D, 0, 3, 5, 3, false); + + + // several more taproots + buildBranchRing(world, random, pos, diameter, 1, 2, 8, 0, 0.9D, 0, 3, 5, 3, false); + + return true; + } + + /** + * Build the crown of the tree + * + * @param diameter + * @param height + */ + protected void buildFullCrown(World world, Random random, BlockPos pos, int diameter, int height) { + int crownRadius = diameter * 4 + 4; + int bvar = diameter + 2; + + // okay, let's do 3-5 main branches starting at the bottom of the crown + buildBranchRing(world, random, pos, diameter, height - crownRadius, 0, crownRadius, 0, 0.35D, 0, bvar, bvar + 2, 2, true); + + // then, let's do 3-5 medium branches at the crown middle + buildBranchRing(world, random, pos, diameter, height - (crownRadius / 2), 0, crownRadius, 0, 0.28D, 0, bvar, bvar + 2, 1, true); + + // finally, let's do 2-4 main branches at the crown top + buildBranchRing(world, random, pos, diameter, height, 0, crownRadius, 0, 0.15D, 0, 2, 4, 2, true); + + // and extra finally, let's do 3-6 medium branches going straight up + buildBranchRing(world, random, pos, diameter, height, 0, (crownRadius / 2), 0, 0.05D, 0, bvar, bvar + 2, 1, true); + + // this glass sphere approximates where we want our crown + //drawBlob(x, y + height, z, (byte)crownRadius, (byte)Blocks.GLASS, false); + + } + + /** + * Build the crown of the tree. This builds a smaller crown, since the large ones were causing some performance issues + * + * @param height + */ + protected void buildWeakCrown(World world, Random random, BlockPos pos, int diameter, int height) { + int crownRadius = 8; + int bvar = 2; + + // 3-5 medium branches starting at the bottom of the crown + buildBranchRing(world, random, pos, diameter, height - crownRadius, 0, crownRadius, 0, 0.35D, 0, bvar, bvar + 2, 1, true); + + // 3-5 medium branches at the crown middle + buildBranchRing(world, random, pos, diameter, height - (crownRadius / 2), 0, crownRadius, 0, 0.28D, 0, bvar, bvar + 2, 1, true); + + // 2-4 medium branches at the crown top + buildBranchRing(world, random, pos, diameter, height, 0, crownRadius, 0, 0.15D, 0, 2, 4, 1, true); + + // 3-6 medium branches going straight up + buildBranchRing(world, random, pos, diameter, height, 0, (crownRadius / 2), 0, 0.05D, 0, bvar, bvar + 2, 1, true); + } + + /** + * Build a ring of branches around the tree + * size 0 = small, 1 = med, 2 = large, 3 = root + */ + protected void buildBranchRing(World world, Random random, BlockPos pos, int diameter, int branchHeight, int heightVar, int length, int lengthVar, double tilt, double tiltVar, int minBranches, int maxBranches, int size, boolean leafy) { + //let's do this! + int numBranches = random.nextInt(maxBranches - minBranches) + minBranches; + ; + double branchRotation = 1.0 / (numBranches + 1); + double branchOffset = random.nextDouble(); + + for (int i = 0; i <= numBranches; i++) { + int dHeight; + if (heightVar > 0) { + dHeight = branchHeight - heightVar + random.nextInt(2 * heightVar); + } else { + dHeight = branchHeight; + } + + if (size == 2) { + makeLargeBranch(world, random, pos, diameter, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); + } else if (size == 1) { + makeMedBranch(world, random, pos, diameter, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); + } else if (size == 3) { + makeRoot(world, random, pos, diameter, dHeight, length, i * branchRotation + branchOffset, tilt); + } else { + makeSmallBranch(world, random, pos, diameter, dHeight, length, i * branchRotation + branchOffset, tilt, leafy); + } + } + } + + + /** + * This function builds the hollow trunk of the tree + */ + protected void buildTrunk(World world, Random random, BlockPos pos, int diameter, int height) { + + int hollow = diameter / 2; + + + // go down 4 squares and fill in extra trunk as needed, in case we're on uneven terrain + for (int dx = -diameter; dx <= diameter; dx++) { + for (int dz = -diameter; dz <= diameter; dz++) { + for (int dy = -4; dy < 0; dy++) { + // determine how far we are from the center. + int ax = Math.abs(dx); + int az = Math.abs(dz); + int dist = (int) (Math.max(ax, az) + (Math.min(ax, az) * 0.5)); + + if (dist <= diameter) { + BlockPos dPos = pos.add(dx, dy, dz); + if (hasAirAround(world, dPos)) { + this.setBlockAndNotifyAdequately(world, dPos, dist > hollow ? treeState : branchState); + } else { + this.setBlockAndNotifyAdequately(world, dPos, rootState); + } + } + + } + } + } + + // build the trunk upwards + for (int dx = -diameter; dx <= diameter; dx++) { + for (int dz = -diameter; dz <= diameter; dz++) { + for (int dy = 0; dy <= height; dy++) { + BlockPos dPos = pos.add(dx, dy, dz); + // determine how far we are from the center. + int ax = Math.abs(dx); + int az = Math.abs(dz); + int dist = (int) (Math.max(ax, az) + (Math.min(ax, az) * 0.5)); + + // make a trunk! + if (dist <= diameter && dist > hollow) { + setBlockAndNotifyAdequately(world, dPos, treeState); + } + + + // fill it with lava! + if (dist <= hollow) { + // just kidding! + //world.setBlock(dx + x, dy + y, dz + z, Blocks.LAVA); + } + + // how about a ladder? is that okay? + if (dist == hollow && dx == hollow) { +// putBlockAndMetadata(dx + x, dy + y, dz + z, Blocks.LADDER, 4, true); + setBlockAndNotifyAdequately(world, dPos, Blocks.VINE.getDefaultState().withProperty(BlockVine.EAST, true)); + } + } + } + } + + } + + /** + * Make a branch! + */ + protected void makeMedBranch(World world, Random random, BlockPos pos, int diameter, int branchHeight, double length, double angle, double tilt, boolean leafy) { + BlockPos src = translate(pos.up(branchHeight), diameter, angle, 0.5); + makeMedBranch(world, random, src, length, angle, tilt, leafy); + } + + /** + * Make a branch! + */ + protected void makeMedBranch(World world, Random random, BlockPos src, double length, double angle, double tilt, boolean leafy) { + BlockPos dest = translate(src, length, angle, tilt); + + drawBresehnam(this, world, src, dest, branchState); + + // with leaves! + + if (leafy) { + /* + int numLeafBalls = random.nextInt(2) + 1; + for(int i = 0; i <= numLeafBalls; i++) { + + double slength = random.nextDouble() * 0.6 + 0.2; + int[] bdst = translate(src[0], src[1], src[2], slength, angle, tilt); + + + drawBlob(bdst[0], bdst[1], bdst[2], 2, leafBlock, false); + } + */ + + // and a blob at the end + drawLeafBlob(this, world, dest, 2, leafState); + } + + + // and several small branches + + int numShoots = random.nextInt(2) + 1; + double angleInc, angleVar, outVar, tiltVar; + + angleInc = 0.8 / numShoots; + + for (int i = 0; i <= numShoots; i++) { + + angleVar = (angleInc * i) - 0.4; + outVar = (random.nextDouble() * 0.8) + 0.2; + tiltVar = (random.nextDouble() * 0.75) + 0.15; + + BlockPos bsrc = translate(src, length * outVar, angle, tilt); + double slength = length * 0.4; + + makeSmallBranch(world, random, bsrc, slength, angle + angleVar, tilt * tiltVar, leafy); + } + } + + /** + * Make a small branch with a leaf blob at the end + */ + protected void makeSmallBranch(World world, Random random, BlockPos src, double length, double angle, double tilt, boolean leafy) { + BlockPos dest = translate(src, length, angle, tilt); + + drawBresehnam(this, world, src, dest, branchState); + + if (leafy) { + byte leafRad = (byte) (random.nextInt(2) + 1); + drawLeafBlob(this, world, dest, leafRad, leafState); + } + } + + /** + * Make a small branch at a certain height + */ + protected void makeSmallBranch(World world, Random random, BlockPos pos, int diameter, int branchHeight, double length, double angle, double tilt, boolean leafy) { + BlockPos src = translate(pos.up(branchHeight), diameter, angle, 0.5); + makeSmallBranch(world, random, src, length, angle, tilt, leafy); + } + + /** + * Make a root + */ + protected void makeRoot(World world, Random random, BlockPos pos, int diameter, int branchHeight, double length, double angle, double tilt) { + BlockPos src = translate(pos.up(branchHeight), diameter, angle, 0.5); + BlockPos dest = translate(src, length, angle, tilt); + + BlockPos[] lineArray = getBresehnamArrays(src, dest); + boolean stillAboveGround = true; + for (BlockPos coord : lineArray) { + if (stillAboveGround && hasAirAround(world, coord)) { + this.setBlockAndNotifyAdequately(world, coord, branchState); + this.setBlockAndNotifyAdequately(world, coord.down(), branchState); + } else { + this.setBlockAndNotifyAdequately(world, coord, rootState); + this.setBlockAndNotifyAdequately(world, coord.down(), rootState); + stillAboveGround = false; + } + } + } + + /** + * Make a large, branching "base" branch in a specific location. + *

+ * The large branch will have 1-4 medium branches and several small branches too + */ + protected void makeLargeBranch(World world, Random random, BlockPos src, double length, double angle, double tilt, boolean leafy) { + BlockPos dest = translate(src, length, angle, tilt); + + // draw the main branch + drawBresehnam(this, world, src, dest, branchState); + + // reinforce it + //drawBresehnam(src[0], src[1] + 1, src[2], dest[0], dest[1], dest[2], treeBlock, true); + int reinforcements = random.nextInt(3); + for (int i = 0; i <= reinforcements; i++) { + int vx = (i & 2) == 0 ? 1 : 0; + int vy = (i & 1) == 0 ? 1 : -1; + int vz = (i & 2) == 0 ? 0 : 1; + drawBresehnam(this, world, src.add(vx, vy, vz), dest, branchState); + } + + if (leafy) { + // add a leaf blob at the end + drawLeafBlob(this, world, dest.up(), 3, leafState); + } + + // go about halfway out and make a few medium branches. + // the number of medium branches we can support depends on the length of the big branch + // every other branch switches sides + int numMedBranches = random.nextInt((int) (length / 6)) + random.nextInt(2) + 1; + + for (int i = 0; i <= numMedBranches; i++) { + + double outVar = (random.nextDouble() * 0.3) + 0.3; + double angleVar = random.nextDouble() * 0.225 * ((i & 1) == 0 ? 1.0 : -1.0); + BlockPos bsrc = translate(src, length * outVar, angle, tilt); + + makeMedBranch(world, random, bsrc, length * 0.6, angle + angleVar, tilt, leafy); + } + + // make 1-2 small ones near the base + int numSmallBranches = random.nextInt(2) + 1; + for (int i = 0; i <= numSmallBranches; i++) { + + double outVar = (random.nextDouble() * 0.25) + 0.25; + double angleVar = random.nextDouble() * 0.25 * ((i & 1) == 0 ? 1.0 : -1.0); + BlockPos bsrc = translate(src, length * outVar, angle, tilt); + + makeSmallBranch(world, random, bsrc, Math.max(length * 0.3, 2), angle + angleVar, tilt, leafy); + } + + if (random.nextInt(LEAF_DUNGEON_CHANCE) == 0) { + makeLeafDungeon(world, random, dest.up()); + } + + } + + + private void makeLeafDungeon(World world, Random random, BlockPos pos) { + // make leaves + drawLeafBlob(this, world, pos, 4, leafState); + // wood support + drawBlob(this, world, pos, 3, branchState); + // air + drawBlob(this, world, pos, 2, Blocks.AIR.getDefaultState()); + + // spawner + world.setBlockState(pos.up(), Blocks.MOB_SPAWNER.getDefaultState(), 16 | 2); + TileEntityMobSpawner ms = (TileEntityMobSpawner) world.getTileEntity(pos.up()); + if (ms != null) { + ms.getSpawnerBaseLogic().setEntityId(EntityList.getKey(EntityTFSwarmSpider.class)); + } + + // treasure chests? + makeLeafDungeonChest(world, random, pos); + } + + private void makeLeafDungeonChest(World world, Random random, BlockPos pos) { + pos = pos.offset(EnumFacing.HORIZONTALS[random.nextInt(4)]); + TFTreasure.tree_cache.generateChest(world, pos.down(), false); + } + + /** + * Make a large, branching "base" branch off of the tree + */ + protected void makeLargeBranch(World world, Random random, BlockPos pos, int diameter, int branchHeight, double length, double angle, double tilt, boolean leafy) { + BlockPos src = translate(pos.up(branchHeight), diameter, angle, 0.5); + makeLargeBranch(world, random, src, length, angle, tilt, leafy); + } + + /** + * Add a firefly at the specified height and angle. + */ + protected void addFirefly(World world, BlockPos pos, int diameter, int fHeight, double fAngle) { + BlockPos src = translate(pos.up(fHeight), diameter + 1, fAngle, 0.5); + + fAngle = fAngle % 1.0; + EnumFacing facing = EnumFacing.EAST; + + if (fAngle > 0.875 || fAngle <= 0.125) { + facing = EnumFacing.SOUTH; + } else if (fAngle > 0.125 && fAngle <= 0.375) { + facing = EnumFacing.EAST; + } else if (fAngle > 0.375 && fAngle <= 0.625) { + facing = EnumFacing.NORTH; + } else if (fAngle > 0.625 && fAngle <= 0.875) { + facing = EnumFacing.WEST; + } + + if (TFBlocks.firefly.canPlaceBlockAt(world, src)) { + setBlockAndNotifyAdequately(world, src, TFBlocks.firefly.getDefaultState().withProperty(BlockDirectional.FACING, facing)); + } + } + + protected void addCicada(World world, BlockPos pos, int diameter, int fHeight, double fAngle) { + BlockPos src = translate(pos.up(fHeight), diameter + 1, fAngle, 0.5); + + fAngle = fAngle % 1.0; + EnumFacing facing = EnumFacing.EAST; + + if (fAngle > 0.875 || fAngle <= 0.125) { + facing = EnumFacing.SOUTH; + } else if (fAngle > 0.125 && fAngle <= 0.375) { + facing = EnumFacing.EAST; + } else if (fAngle > 0.375 && fAngle <= 0.625) { + facing = EnumFacing.NORTH; + } else if (fAngle > 0.625 && fAngle <= 0.875) { + facing = EnumFacing.WEST; + } + + if (TFBlocks.cicada.canPlaceBlockAt(world, src)) { + setBlockAndNotifyAdequately(world, src, TFBlocks.cicada.getDefaultState().withProperty(BlockDirectional.FACING, facing)); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/twilightforest/world/feature/TFGenHugeLilyPad.java b/src/main/java/twilightforest/world/feature/TFGenHugeLilyPad.java new file mode 100644 index 0000000000..83b7c2067e --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenHugeLilyPad.java @@ -0,0 +1,56 @@ +package twilightforest.world.feature; + +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; +import twilightforest.block.TFBlocks; + +import java.util.Random; + +import static twilightforest.block.BlockTFHugeLilyPad.FACING; +import static twilightforest.block.BlockTFHugeLilyPad.PIECE; +import static twilightforest.enums.HugeLilypadPiece.NE; +import static twilightforest.enums.HugeLilypadPiece.NW; +import static twilightforest.enums.HugeLilypadPiece.SE; +import static twilightforest.enums.HugeLilypadPiece.SW; + +/** + * Generate huge lily pads + * + * @author Ben + */ +public class TFGenHugeLilyPad extends WorldGenerator { + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + for (int i = 0; i < 10; i++) { + BlockPos dPos = pos.add( + random.nextInt(8) - random.nextInt(8), + random.nextInt(4) - random.nextInt(4), + random.nextInt(8) - random.nextInt(8) + ); + + if (shouldPlacePadAt(world, dPos) && world.isAreaLoaded(dPos, 1)) { + final EnumFacing horizontal = EnumFacing.byHorizontalIndex(random.nextInt(4)); + final IBlockState lilypad = TFBlocks.huge_lilypad.getDefaultState().withProperty(FACING, horizontal); + + world.setBlockState(dPos, lilypad.withProperty(PIECE, NW), 16 | 2); + world.setBlockState(dPos.east(), lilypad.withProperty(PIECE, NE), 16 | 2); + world.setBlockState(dPos.east().south(), lilypad.withProperty(PIECE, SE), 16 | 2); + world.setBlockState(dPos.south(), lilypad.withProperty(PIECE, SW), 16 | 2); + } + } + + return true; + } + + private boolean shouldPlacePadAt(World world, BlockPos pos) { + return world.isAirBlock(pos) && world.getBlockState(pos.down()).getMaterial() == Material.WATER + && world.isAirBlock(pos.east()) && world.getBlockState(pos.east().down()).getMaterial() == Material.WATER + && world.isAirBlock(pos.south()) && world.getBlockState(pos.south().down()).getMaterial() == Material.WATER + && world.isAirBlock(pos.east().south()) && world.getBlockState(pos.east().south().down()).getMaterial() == Material.WATER; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenHugeWaterLily.java b/src/main/java/twilightforest/world/feature/TFGenHugeWaterLily.java new file mode 100644 index 0000000000..d622868601 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenHugeWaterLily.java @@ -0,0 +1,38 @@ +package twilightforest.world.feature; + +import net.minecraft.block.material.Material; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; +import twilightforest.block.TFBlocks; + +import java.util.Random; + +/** + * Generate huge lily pads + * + * @author Ben + */ +public class TFGenHugeWaterLily extends WorldGenerator { + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + for (int i = 0; i < 4; i++) { + BlockPos pos_ = pos.add( + random.nextInt(8) - random.nextInt(8), + random.nextInt(4) - random.nextInt(4), + random.nextInt(8) - random.nextInt(8) + ); + + if (shouldPlacePadAt(world, pos_)) { + world.setBlockState(pos_, TFBlocks.huge_waterlily.getDefaultState(), 16 | 2); + } + } + + return true; + } + + private boolean shouldPlacePadAt(World world, BlockPos pos) { + return world.isAirBlock(pos) && world.getBlockState(pos.down()).getMaterial() == Material.WATER; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenLampposts.java b/src/main/java/twilightforest/world/feature/TFGenLampposts.java new file mode 100644 index 0000000000..2d63b2d550 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenLampposts.java @@ -0,0 +1,46 @@ +package twilightforest.world.feature; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Random; + +public class TFGenLampposts extends TFGenerator { + + private static final Rotation[] ROTATIONS = Rotation.values(); + private final IBlockState lamp; + + public TFGenLampposts(IBlockState state) { + lamp = state; + } + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + // we should start on a grass block + if (world.getBlockState(pos.down()).getBlock() != Blocks.GRASS) { + return false; + } + + // generate a height + int height = 1 + rand.nextInt(4); + + // is it air or replaceable above our grass block + for (int dy = 0; dy <= height; dy++) { + IBlockState state = world.getBlockState(pos.up(dy)); + if (!state.getBlock().isAir(state, world, pos.up(dy)) && !state.getBlock().isReplaceable(world, pos.up(dy))) { + return false; + } + } + + // generate lamp + for (int dy = 0; dy < height; dy++) { + world.setBlockState(pos.up(dy), Blocks.OAK_FENCE.getDefaultState(), 16 | 2); + } + world.setBlockState(pos.up(height), lamp.withRotation(ROTATIONS[rand.nextInt(ROTATIONS.length)]), 16 | 2); + return true; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenLargeRainboak.java b/src/main/java/twilightforest/world/feature/TFGenLargeRainboak.java new file mode 100644 index 0000000000..4620bd7f87 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenLargeRainboak.java @@ -0,0 +1,459 @@ +package twilightforest.world.feature; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import twilightforest.block.BlockTFLeaves; +import twilightforest.block.TFBlocks; +import twilightforest.enums.LeavesVariant; + +import java.util.Random; + +/** + * This is a lame copy of WorldGenLargeTree, since I'm too lazy to make my own tree and all the methods in WorldGenLargeTree are package-only + */ +public class TFGenLargeRainboak extends TFTreeGenerator { + /** + * Contains three sets of two values that provide complimentary indices for a given 'major' index - 1 and 2 for 0, 0 + * and 2 for 1, and 0 and 1 for 2. + */ + static final byte[] otherCoordPairs = new byte[]{(byte) 2, (byte) 0, (byte) 0, (byte) 1, (byte) 2, (byte) 1}; + + /** + * random seed for GenBigTree + */ + Random rand = new Random(); + + /** + * Reference to the World object. + */ + World world; + int[] basePos = new int[]{0, 0, 0}; + int heightLimit = 0; + int height; + double heightAttenuation = 0.618D; + double branchDensity = 1.0D; + double branchSlope = 0.381D; + double scaleWidth = 1.0D; + double leafDensity = 1.0D; + + /** + * Currently always 1, can be set to 2 in the class constructor to generate a double-sized tree trunk for big trees. + */ + int trunkSize = 1; + + /** + * Sets the limit of the random value used to initialize the height limit. + */ + int heightLimitLimit = 12; + + /** + * Sets the distance limit for how far away the generator will populate leaves from the base leaf node. + */ + int leafDistanceLimit = 4; + + /** + * Contains a list of a points at which to generate groups of leaves. + */ + int[][] leafNodes; + + public TFGenLargeRainboak(boolean par1) { + super(par1); + } + + public TFGenLargeRainboak() { + this(false); + } + + /** + * Generates a list of leaf nodes for the tree, to be populated by generateLeaves. + */ + void generateLeafNodeList() { + this.height = (int) ((double) this.heightLimit * this.heightAttenuation); + + if (this.height >= this.heightLimit) { + this.height = this.heightLimit - 1; + } + + int var1 = (int) (1.382D + Math.pow(this.leafDensity * (double) this.heightLimit / 13.0D, 2.0D)); + + if (var1 < 1) { + var1 = 1; + } + + int[][] var2 = new int[var1 * this.heightLimit][4]; + int var3 = this.basePos[1] + this.heightLimit - this.leafDistanceLimit; + int var4 = 1; + int var5 = this.basePos[1] + this.height; + int var6 = var3 - this.basePos[1]; + var2[0][0] = this.basePos[0]; + var2[0][1] = var3; + var2[0][2] = this.basePos[2]; + var2[0][3] = var5; + --var3; + + while (var6 >= 0) { + int var7 = 0; + float var8 = this.layerSize(var6); + + if (var8 < 0.0F) { + --var3; + --var6; + } else { + for (double var9 = 0.5D; var7 < var1; ++var7) { + double var11 = this.scaleWidth * (double) var8 * ((double) this.rand.nextFloat() + 0.328D); + double var13 = (double) this.rand.nextFloat() * 2.0D * Math.PI; + int var15 = MathHelper.floor(var11 * Math.sin(var13) + (double) this.basePos[0] + var9); + int var16 = MathHelper.floor(var11 * Math.cos(var13) + (double) this.basePos[2] + var9); + int[] var17 = new int[]{var15, var3, var16}; + int[] var18 = new int[]{var15, var3 + this.leafDistanceLimit, var16}; + + if (this.checkBlockLine(var17, var18) == -1) { + int[] var19 = new int[]{this.basePos[0], this.basePos[1], this.basePos[2]}; + double var20 = Math.sqrt(Math.pow((double) Math.abs(this.basePos[0] - var17[0]), 2.0D) + Math.pow((double) Math.abs(this.basePos[2] - var17[2]), 2.0D)); + double var22 = var20 * this.branchSlope; + + if ((double) var17[1] - var22 > (double) var5) { + var19[1] = var5; + } else { + var19[1] = (int) ((double) var17[1] - var22); + } + + if (this.checkBlockLine(var19, var17) == -1) { + var2[var4][0] = var15; + var2[var4][1] = var3; + var2[var4][2] = var16; + var2[var4][3] = var19[1]; + ++var4; + } + } + } + + --var3; + --var6; + } + } + + this.leafNodes = new int[var4][4]; + System.arraycopy(var2, 0, this.leafNodes, 0, var4); + } + + void genTreeLayer(int par1, int par2, int par3, float par4, byte par5, IBlockState leaves) { + int var7 = (int) ((double) par4 + 0.618D); + byte var8 = otherCoordPairs[par5]; + byte var9 = otherCoordPairs[par5 + 3]; + int[] var10 = new int[]{par1, par2, par3}; + int[] var11 = new int[]{0, 0, 0}; + int var12 = -var7; + int var13 = -var7; + + for (var11[par5] = var10[par5]; var12 <= var7; ++var12) { + var11[var8] = var10[var8] + var12; + var13 = -var7; + + while (var13 <= var7) { + double var15 = Math.pow((double) Math.abs(var12) + 0.5D, 2.0D) + Math.pow((double) Math.abs(var13) + 0.5D, 2.0D); + + if (var15 > (double) (par4 * par4)) { + ++var13; + } else { + var11[var9] = var10[var9] + var13; + final BlockPos pos = new BlockPos(var11[0], var11[1], var11[2]); + IBlockState var14 = this.world.getBlockState(pos); + + final Block block = var14.getBlock(); + if (block != Blocks.AIR && !block.canBeReplacedByLeaves(var14, this.world, pos)) { + ++var13; + } else { + this.setBlockAndNotifyAdequately(this.world, pos, leaves); + ++var13; + } + } + } + } + } + + /** + * Gets the rough size of a layer of the tree. + */ + float layerSize(int par1) { + if ((double) par1 < (double) ((float) this.heightLimit) * 0.3D) { + return -1.618F; + } else { + float var2 = (float) this.heightLimit / 2.0F; + float var3 = (float) this.heightLimit / 2.0F - (float) par1; + float var4; + + if (var3 == 0.0F) { + var4 = var2; + } else if (Math.abs(var3) >= var2) { + var4 = 0.0F; + } else { + var4 = (float) Math.sqrt(Math.pow((double) Math.abs(var2), 2.0D) - Math.pow((double) Math.abs(var3), 2.0D)); + } + + var4 *= 0.5F; + return var4; + } + } + + float leafSize(int par1) { + return par1 >= 0 && par1 < this.leafDistanceLimit ? (par1 != 0 && par1 != this.leafDistanceLimit - 1 ? 3.0F : 2.0F) : -1.0F; + } + + /** + * Generates the leaves surrounding an individual entry in the leafNodes list. + */ + void generateLeafNode(int par1, int par2, int par3) { + int var4 = par2; + + for (int var5 = par2 + this.leafDistanceLimit; var4 < var5; ++var4) { + float var6 = this.leafSize(var4 - par2); + this.genTreeLayer(par1, var4, par3, var6, (byte) 1, TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockTFLeaves.VARIANT, LeavesVariant.RAINBOAK).withProperty(BlockLeaves.CHECK_DECAY, false)); + } + } + + /** + * Places a line of the specified block ID into the world from the first coordinate triplet to the second. + */ + void placeBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger, Block log) { + int[] var4 = new int[]{0, 0, 0}; + byte var5 = 0; + byte var6; + + for (var6 = 0; var5 < 3; ++var5) { + var4[var5] = par2ArrayOfInteger[var5] - par1ArrayOfInteger[var5]; + + if (Math.abs(var4[var5]) > Math.abs(var4[var6])) { + var6 = var5; + } + } + + if (var4[var6] != 0) { + byte var7 = otherCoordPairs[var6]; + byte var8 = otherCoordPairs[var6 + 3]; + byte var9; + + if (var4[var6] > 0) { + var9 = 1; + } else { + var9 = -1; + } + + double var10 = (double) var4[var7] / (double) var4[var6]; + double var12 = (double) var4[var8] / (double) var4[var6]; + int[] var14 = new int[]{0, 0, 0}; + int var15 = 0; + + for (int var16 = var4[var6] + var9; var15 != var16; var15 += var9) { + var14[var6] = MathHelper.floor((double) (par1ArrayOfInteger[var6] + var15) + 0.5D); + var14[var7] = MathHelper.floor((double) par1ArrayOfInteger[var7] + (double) var15 * var10 + 0.5D); + var14[var8] = MathHelper.floor((double) par1ArrayOfInteger[var8] + (double) var15 * var12 + 0.5D); + + IBlockState var17 = log.getDefaultState(); + int var18 = Math.abs(var14[0] - par1ArrayOfInteger[0]); + int var19 = Math.abs(var14[2] - par1ArrayOfInteger[2]); + int var20 = Math.max(var18, var19); + + if (var20 > 0) { + if (var18 == var20) { + var17 = var17.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X); + } else if (var19 == var20) { + var17 = var17.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z); + } + } + + this.setBlockAndNotifyAdequately(this.world, new BlockPos(var14[0], var14[1], var14[2]), var17); + } + } + } + + /** + * Generates the leaf portion of the tree as specified by the leafNodes list. + */ + void generateLeaves() { + int var1 = 0; + + for (int var2 = this.leafNodes.length; var1 < var2; ++var1) { + int var3 = this.leafNodes[var1][0]; + int var4 = this.leafNodes[var1][1]; + int var5 = this.leafNodes[var1][2]; + this.generateLeafNode(var3, var4, var5); + } + } + + /** + * Indicates whether or not a leaf node requires additional wood to be added to preserve integrity. + */ + boolean leafNodeNeedsBase(int par1) { + return (double) par1 >= (double) this.heightLimit * 0.2D; + } + + /** + * Places the trunk for the big tree that is being generated. Able to generate double-sized trunks by changing a + * field that is always 1 to 2. + */ + void generateTrunk() { + int var1 = this.basePos[0]; + int var2 = this.basePos[1]; + int var3 = this.basePos[1] + this.height; + int var4 = this.basePos[2]; + int[] var5 = new int[]{var1, var2, var4}; + int[] var6 = new int[]{var1, var3, var4}; + this.placeBlockLine(var5, var6, TFBlocks.twilight_log); + + if (this.trunkSize == 2) { + ++var5[0]; + ++var6[0]; + this.placeBlockLine(var5, var6, TFBlocks.twilight_log); + ++var5[2]; + ++var6[2]; + this.placeBlockLine(var5, var6, TFBlocks.twilight_log); + var5[0] += -1; + var6[0] += -1; + this.placeBlockLine(var5, var6, TFBlocks.twilight_log); + } + } + + /** + * Generates additional wood blocks to fill out the bases of different leaf nodes that would otherwise degrade. + */ + void generateLeafNodeBases() { + int var1 = 0; + int var2 = this.leafNodes.length; + + for (int[] var3 = new int[]{this.basePos[0], this.basePos[1], this.basePos[2]}; var1 < var2; ++var1) { + int[] var4 = this.leafNodes[var1]; + int[] var5 = new int[]{var4[0], var4[1], var4[2]}; + var3[1] = var4[3]; + int var6 = var3[1] - this.basePos[1]; + + if (this.leafNodeNeedsBase(var6)) { + this.placeBlockLine(var3, var5, TFBlocks.twilight_log); + } + } + } + + /** + * Checks a line of blocks in the world from the first coordinate to triplet to the second, returning the distance + * (in blocks) before a non-air, non-leaf block is encountered and/or the end is encountered. + */ + int checkBlockLine(int[] par1ArrayOfInteger, int[] par2ArrayOfInteger) { + int[] var3 = new int[]{0, 0, 0}; + byte var4 = 0; + byte var5; + + for (var5 = 0; var4 < 3; ++var4) { + var3[var4] = par2ArrayOfInteger[var4] - par1ArrayOfInteger[var4]; + + if (Math.abs(var3[var4]) > Math.abs(var3[var5])) { + var5 = var4; + } + } + + if (var3[var5] == 0) { + return -1; + } else { + byte var6 = otherCoordPairs[var5]; + byte var7 = otherCoordPairs[var5 + 3]; + byte var8; + + if (var3[var5] > 0) { + var8 = 1; + } else { + var8 = -1; + } + + double var9 = (double) var3[var6] / (double) var3[var5]; + double var11 = (double) var3[var7] / (double) var3[var5]; + int[] var13 = new int[]{0, 0, 0}; + int var14 = 0; + int var15; + + for (var15 = var3[var5] + var8; var14 != var15; var14 += var8) { + var13[var5] = par1ArrayOfInteger[var5] + var14; + var13[var6] = MathHelper.floor((double) par1ArrayOfInteger[var6] + (double) var14 * var9); + var13[var7] = MathHelper.floor((double) par1ArrayOfInteger[var7] + (double) var14 * var11); + IBlockState var16 = this.world.getBlockState(new BlockPos(var13[0], var13[1], var13[2])); + final Block block = var16.getBlock(); + + if (block != Blocks.AIR && block != Blocks.LEAVES) { + break; + } + } + + return var14 == var15 ? -1 : Math.abs(var14); + } + } + + /** + * Returns a boolean indicating whether or not the current location for the tree, spanning basePos to to the height + * limit, is valid. + */ + boolean validTreeLocation() { + int[] var1 = new int[]{this.basePos[0], this.basePos[1], this.basePos[2]}; + int[] var2 = new int[]{this.basePos[0], this.basePos[1] + this.heightLimit - 1, this.basePos[2]}; + IBlockState var3 = this.world.getBlockState(new BlockPos(this.basePos[0], this.basePos[1] - 1, this.basePos[2])); + + final Block block = var3.getBlock(); + if (block != Blocks.DIRT && block != Blocks.GRASS) { + return false; + } else { + int var4 = this.checkBlockLine(var1, var2); + + if (var4 == -1) { + return true; + } else if (var4 < 6) { + return false; + } else { + this.heightLimit = var4; + return true; + } + } + } + + /** + * Rescales the generator settings, only used in WorldGenBigTree + */ + public void setScale(double par1, double par3, double par5) { + this.heightLimitLimit = (int) (par1 * 12.0D); + + if (par1 > 0.5D) { + this.leafDistanceLimit = 5; + } + + this.scaleWidth = par3; + this.leafDensity = par5; + } + + @Override + public boolean generate(World par1World, Random par2Random, BlockPos position) { + this.world = par1World; + long var6 = par2Random.nextLong(); + this.rand.setSeed(var6); + this.basePos[0] = position.getX(); + this.basePos[1] = position.getY(); + this.basePos[2] = position.getZ(); + + if (this.heightLimit == 0) { + this.heightLimit = 5 + this.rand.nextInt(this.heightLimitLimit); + } + + if (!this.validTreeLocation()) { + this.world = null; + return false; + } else { + this.generateLeafNodeList(); + this.generateLeaves(); + this.generateTrunk(); + this.generateLeafNodeBases(); + this.world = null; + return true; + } + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenLargeWinter.java b/src/main/java/twilightforest/world/feature/TFGenLargeWinter.java new file mode 100644 index 0000000000..6684bd9a18 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenLargeWinter.java @@ -0,0 +1,130 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.BlockOldLeaf; +import net.minecraft.block.BlockOldLog; +import net.minecraft.block.BlockPlanks; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.IPlantable; +import twilightforest.block.TFBlocks; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class TFGenLargeWinter extends TFTreeGenerator { + + public TFGenLargeWinter() { + this(false); + } + + public TFGenLargeWinter(boolean notify) { + super(notify); + treeState = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.SPRUCE); + branchState = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.SPRUCE).withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + leafState = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.SPRUCE).withProperty(BlockLeaves.CHECK_DECAY, false); + rootState = TFBlocks.root.getDefaultState(); + source = (IPlantable) Blocks.SAPLING; + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + // determine a height + int treeHeight = 35; + if (random.nextInt(3) == 0) { + treeHeight += random.nextInt(10); + + if (random.nextInt(8) == 0) { + treeHeight += random.nextInt(10); + } + } + + if (pos.getY() >= TFWorld.MAXHEIGHT - treeHeight) { + return false; + } + + // check if we're on dirt or grass + IBlockState state = world.getBlockState(pos.down()); + if (!state.getBlock().canSustainPlant(state, world, pos.down(), EnumFacing.UP, source)) { + return false; + } + + //okay build a tree! Go up to the height + buildTrunk(world, pos, treeHeight); + + // make leaves + makeLeaves(world, pos, treeHeight); + + // roots! + int numRoots = 4 + random.nextInt(3); + float offset = random.nextFloat(); + for (int b = 0; b < numRoots; b++) { + buildRoot(world, pos, offset, b); + } + + return true; + } + + private void makeLeaves(World world, BlockPos pos, int treeHeight) { + int offGround = 3; + int leafType = 1; + + for (int dy = 0; dy < treeHeight; dy++) { + + int radius = leafRadius(treeHeight, dy, leafType); + + TFGenerator.makeLeafCircle2(this, world, pos.up(offGround + treeHeight - dy), radius, leafState, false); + this.makePineBranches(world, pos.up(offGround + treeHeight - dy), radius); + } + } + + private void makePineBranches(World world, BlockPos pos, int radius) { + int branchLength = radius > 4 ? radius - 1 : radius - 2; + + switch (pos.getY() % 2) { + case 0: + // branches + for (int i = 1; i <= branchLength; i++) { + this.setBlockAndNotifyAdequately(world, pos.add(-i, 0, 0), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.X)); + this.setBlockAndNotifyAdequately(world, pos.add(0, 0, i + 1), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.Z)); + this.setBlockAndNotifyAdequately(world, pos.add(i + 1, 0, 1), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.X)); + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, -i), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.Z)); + } + break; + case 1: + for (int i = 1; i <= branchLength; i++) { + this.setBlockAndNotifyAdequately(world, pos.add(-1, 0, 1), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.X)); + this.setBlockAndNotifyAdequately(world, pos.add(1, 0, i + 1), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.Z)); + this.setBlockAndNotifyAdequately(world, pos.add(i + 1, 0, 0), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.X)); + this.setBlockAndNotifyAdequately(world, pos.add(0, 0, -i), branchState.withProperty(BlockOldLog.LOG_AXIS, BlockLog.EnumAxis.Z)); + } + break; + } + } + + private int leafRadius(int treeHeight, int dy, int functionType) { + switch (functionType) { + case 0: + default: + return (dy - 1) % 4; + case 1: + return (int) (4F * (float) dy / (float) treeHeight + (0.75F * dy % 3)); + case 99: + return (treeHeight - (dy / 2) - 1) % 4; // bad + } + } + + private void buildTrunk(World world, BlockPos pos, int treeHeight) { + for (int dy = 0; dy < treeHeight; dy++) { + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 0), treeState); + this.setBlockAndNotifyAdequately(world, pos.add(1, dy, 0), treeState); + this.setBlockAndNotifyAdequately(world, pos.add(0, dy, 1), treeState); + this.setBlockAndNotifyAdequately(world, pos.add(1, dy, 1), treeState); + } + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenMangroveTree.java b/src/main/java/twilightforest/world/feature/TFGenMangroveTree.java new file mode 100644 index 0000000000..5bb9b2a809 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenMangroveTree.java @@ -0,0 +1,149 @@ +package twilightforest.world.feature; + +import com.google.common.collect.Lists; +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFLeaves; +import twilightforest.block.BlockTFLog; +import twilightforest.block.TFBlocks; +import twilightforest.enums.LeavesVariant; +import twilightforest.enums.WoodVariant; + +import java.util.List; +import java.util.Random; + +public class TFGenMangroveTree extends TFTreeGenerator { + + private boolean checkForWater; + private List leaves = Lists.newArrayList(); + + public TFGenMangroveTree() { + this(false); + } + + public TFGenMangroveTree(boolean notify) { + super(notify); + + this.checkForWater = !notify; + + treeState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.VARIANT, WoodVariant.MANGROVE); + branchState = treeState.withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + leafState = TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockTFLeaves.VARIANT, LeavesVariant.MANGROVE).withProperty(BlockLeaves.CHECK_DECAY, false); + rootState = TFBlocks.root.getDefaultState(); + } + + @Override + protected void setBlockAndNotifyAdequately(World worldIn, BlockPos pos, IBlockState state) { + if (canGrowInto(worldIn.getBlockState(pos).getBlock())) + super.setBlockAndNotifyAdequately(worldIn, pos, state); + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + // we only start over water + if (pos.getY() >= 128 - 18 - 1 || (this.checkForWater && world.getBlockState(pos.down()).getBlock() != Blocks.WATER)) { + return false; + } + + this.leaves.clear(); + + //okay build a trunk! Start 5 squares off the ground and go up maybe 6-9 squares + buildBranch(world, random, pos, 5, 6 + random.nextInt(3), 0, 0, true); + + // make 0-3 branches + int numBranches = random.nextInt(3); + double offset = random.nextDouble(); + for (int b = 0; b < numBranches; b++) { + buildBranch(world, random, pos, 7 + b, 6 + random.nextInt(2), 0.3 * b + offset, 0.25, false); + } + + // add the actual leaves + for (LeafBlob blob : leaves) { + makeLeafBlob(world, blob.pos, blob.size); + } + + // make 3-5 roots + int numRoots = 3 + random.nextInt(2); + offset = random.nextDouble(); + for (int i = 0; i < numRoots; i++) { + double rTilt = 0.75 + (random.nextDouble() * 0.1); + buildRoot(world, pos, 5, 12, 0.4 * i + offset, rTilt); + } + + // add a firefly (torch) to the trunk + addFirefly(world, pos, 5 + random.nextInt(5), random.nextDouble()); + + + return true; + } + + private void makeLeafBlob(World world, BlockPos pos, int size) { + TFGenerator.makeLeafCircle(this, world, pos.down(), size - 1, leafState, false); + TFGenerator.makeLeafCircle(this, world, pos, size, leafState, false); + TFGenerator.makeLeafCircle(this, world, pos.up(), size - 2, leafState, false); + } + + /** + * Build a branch with a flat blob of leaves at the end. + */ + private void buildBranch(World world, Random random, BlockPos pos, int height, double length, double angle, double tilt, boolean trunk) { + BlockPos src = pos.up(height); + BlockPos dest = TFGenerator.translate(src, length, angle, tilt); + + // variable size leaves + int bSize = 2 + random.nextInt(3); + + // only actually draw the branch if it's not going to load new chunks + if (world.isAreaLoaded(dest, bSize + 1)) { + + TFGenerator.drawBresehnam(this, world, src, dest, trunk ? treeState : branchState); + + // we only need these side blocks if the size is > 2 + if (bSize > 2) { + setBlockAndNotifyAdequately(world, dest.east(), branchState); + setBlockAndNotifyAdequately(world, dest.west(), branchState); + setBlockAndNotifyAdequately(world, dest.south(), branchState); + setBlockAndNotifyAdequately(world, dest.north(), branchState); + } + leaves.add(new LeafBlob(dest, bSize)); + } + } + + /** + * Build a root. (Which is really like a branch without the leaves) + */ + private void buildRoot(World world, BlockPos pos, int height, double length, double angle, double tilt) { + BlockPos src = pos.up(height); + BlockPos dest = TFGenerator.translate(src, length, angle, tilt); + + // only actually draw the root if it's not going to load new chunks + if (world.isAreaLoaded(dest, 1)) { + BlockPos[] lineArray = TFGenerator.getBresehnamArrays(src, dest); + boolean stillAboveGround = true; + for (BlockPos coord : lineArray) { + if (stillAboveGround && TFGenerator.hasAirAround(world, coord)) { + this.setBlockAndNotifyAdequately(world, coord, branchState); + this.setBlockAndNotifyAdequately(world, coord.down(), branchState); + } else { + this.placeRootBlock(world, coord, rootState); + this.placeRootBlock(world, coord.down(), rootState); + stillAboveGround = false; + } + } + } + } + + private class LeafBlob { + BlockPos pos; + int size; + + public LeafBlob(BlockPos pos, int size) { + this.pos = pos; + this.size = size; + } + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenMinersTree.java b/src/main/java/twilightforest/world/feature/TFGenMinersTree.java new file mode 100644 index 0000000000..9e2d88d035 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenMinersTree.java @@ -0,0 +1,100 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFMagicLog; +import twilightforest.block.TFBlocks; +import twilightforest.enums.MagicWoodVariant; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class TFGenMinersTree extends TFTreeGenerator { + + public TFGenMinersTree() { + this(false); + } + + public TFGenMinersTree(boolean notify) { + super(notify); + this.treeState = TFBlocks.magic_log.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.MINE); + this.branchState = treeState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + this.leafState = TFBlocks.magic_leaves.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.MINE).withProperty(BlockLeaves.CHECK_DECAY, false); + this.rootState = TFBlocks.root.getDefaultState(); + } + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + if (pos.getY() >= TFWorld.MAXHEIGHT - 12) { + return false; + } + + // check soil + IBlockState state = world.getBlockState(pos.down()); + if (!state.getBlock().canSustainPlant(state, world, pos.down(), EnumFacing.UP, source)) { + return false; + } + + // 9 block high trunk + for (int dy = 0; dy < 10; dy++) { + setBlockAndNotifyAdequately(world, pos.up(dy), branchState); + } + + // branches with leaf blocks + putBranchWithLeaves(world, pos.add(0, 9, 1), true); + putBranchWithLeaves(world, pos.add(0, 9, 2), false); + putBranchWithLeaves(world, pos.add(0, 8, 3), false); + putBranchWithLeaves(world, pos.add(0, 7, 4), false); + putBranchWithLeaves(world, pos.add(0, 6, 5), false); + + putBranchWithLeaves(world, pos.add(0, 9, -1), true); + putBranchWithLeaves(world, pos.add(0, 9, -2), false); + putBranchWithLeaves(world, pos.add(0, 8, -3), false); + putBranchWithLeaves(world, pos.add(0, 7, -4), false); + putBranchWithLeaves(world, pos.add(0, 6, -5), false); + + // place minewood core + setBlockAndNotifyAdequately(world, pos.up(), TFBlocks.magic_log_core.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.MINE)); + world.scheduleUpdate(pos.up(), TFBlocks.magic_log_core, TFBlocks.magic_log_core.tickRate(world)); + + + // root bulb + if (TFGenerator.hasAirAround(world, pos.down())) { + this.setBlockAndNotifyAdequately(world, pos.down(), treeState); + } else { + this.setBlockAndNotifyAdequately(world, pos.down(), rootState); + } + + // roots! + int numRoots = 3 + rand.nextInt(2); + double offset = rand.nextDouble(); + for (int b = 0; b < numRoots; b++) { + buildRoot(world, pos, offset, b); + } + + return true; + } + + + protected void putBranchWithLeaves(World world, BlockPos pos, boolean bushy) { + setBlockAndNotifyAdequately(world, pos, branchState); + + for (int lx = -1; lx <= 1; lx++) { + for (int ly = -1; ly <= 1; ly++) { + for (int lz = -1; lz <= 1; lz++) { + if (!bushy && Math.abs(ly) > 0 && Math.abs(lx) > 0) { + continue; + } + TFGenerator.putLeafBlock(this, world, pos.add(lx, ly, lz), leafState); + } + } + } + } + + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenMonolith.java b/src/main/java/twilightforest/world/feature/TFGenMonolith.java new file mode 100644 index 0000000000..46e46b520b --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenMonolith.java @@ -0,0 +1,88 @@ +package twilightforest.world.feature; + +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.entity.passive.EntityTFRaven; + +import java.util.Random; + +/** + * A 2x2 monolith of obsidian + * + * @author Ben + */ +public class TFGenMonolith extends TFGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + int ht = rand.nextInt(10) + 10; + int dir = rand.nextInt(4); + int h0, h1, h2, h3; + + if (!isAreaSuitable(world, rand, pos, 2, ht, 2)) { + return false; + } + + switch (dir) { + case 0: + h0 = ht; + h1 = (int) (ht * .75); + h2 = (int) (ht * .75); + h3 = (int) (ht * .5); + break; + case 1: + h0 = (int) (ht * .5); + h1 = ht; + h2 = (int) (ht * .75); + h3 = (int) (ht * .75); + break; + case 2: + h0 = (int) (ht * .75); + h1 = (int) (ht * .5); + h2 = ht; + h3 = (int) (ht * .75); + break; + case 3: + default: + h0 = (int) (ht * .75); + h1 = (int) (ht * .75); + h2 = (int) (ht * .5); + h3 = ht; + break; + } + + for (int cy = 0; cy <= h0; cy++) { + setBlockAndNotifyAdequately(world, pos.add(0, cy - 1, 0), cy == ht ? Blocks.LAPIS_BLOCK.getDefaultState() : Blocks.OBSIDIAN.getDefaultState()); + } + for (int cy = 0; cy <= h1; cy++) { + setBlockAndNotifyAdequately(world, pos.add(1, cy - 1, 0), cy == ht ? Blocks.LAPIS_BLOCK.getDefaultState() : Blocks.OBSIDIAN.getDefaultState()); + } + for (int cy = 0; cy <= h2; cy++) { + setBlockAndNotifyAdequately(world, pos.add(0, cy - 1, 1), cy == ht ? Blocks.LAPIS_BLOCK.getDefaultState() : Blocks.OBSIDIAN.getDefaultState()); + } + for (int cy = 0; cy <= h3; cy++) { + setBlockAndNotifyAdequately(world, pos.add(1, cy - 1, 1), cy == ht ? Blocks.LAPIS_BLOCK.getDefaultState() : Blocks.OBSIDIAN.getDefaultState()); + } + + // spawn a few ravens nearby + for (int i = 0; i < 2; i++) { + BlockPos dPos = pos.add( + rand.nextInt(8) - rand.nextInt(8), + 0, + rand.nextInt(8) - rand.nextInt(8) + ); + dPos = world.getTopSolidOrLiquidBlock(dPos); + + if (dPos.getY() > 0) { + EntityTFRaven raven = new EntityTFRaven(world); + raven.moveToBlockPosAndAngles(dPos, rand.nextFloat() * 360.0F, 0.0F); + + world.spawnEntity(raven); + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenMyceliumBlob.java b/src/main/java/twilightforest/world/feature/TFGenMyceliumBlob.java new file mode 100644 index 0000000000..831c1e3726 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenMyceliumBlob.java @@ -0,0 +1,58 @@ +package twilightforest.world.feature; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import java.util.Random; + +/** + * This is a copypasta of the sand/gravel/clay generator that produces mycelium blobs for mushroom biomes + * + * @author Ben + */ +public class TFGenMyceliumBlob extends WorldGenerator { + + private final IBlockState myceliumState; + private final int numberOfBlocks; + + public TFGenMyceliumBlob(int i) { + this(Blocks.MYCELIUM, i); + } + + public TFGenMyceliumBlob(Block block, int i) { + myceliumState = block.getDefaultState(); + numberOfBlocks = i; + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { +// if (world.getBlock(i, j, k).getMaterial() != Material.WATER) +// { +// return false; +// } + int range = random.nextInt(numberOfBlocks - 2) + 2; + int yRange = 1; + for (int dx = pos.getX() - range; dx <= pos.getX() + range; dx++) { + for (int dz = pos.getZ() - range; dz <= pos.getZ() + range; dz++) { + int l1 = dx - pos.getX(); + int i2 = dz - pos.getZ(); + if (l1 * l1 + i2 * i2 > range * range) { + continue; + } + for (int dy = pos.getY() - yRange; dy <= pos.getY() + yRange; dy++) { + BlockPos dPos = new BlockPos(dx, dy, dz); + Block blockThere = world.getBlockState(dPos).getBlock(); + if (blockThere == Blocks.DIRT || blockThere == Blocks.GRASS || blockThere == Blocks.STONE) { + world.setBlockState(dPos, myceliumState, 16 | 2); + } + } + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenNoTree.java b/src/main/java/twilightforest/world/feature/TFGenNoTree.java new file mode 100644 index 0000000000..a183aa3743 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenNoTree.java @@ -0,0 +1,25 @@ +package twilightforest.world.feature; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Random; + +/** + * Used to generate no particular tree + */ +public class TFGenNoTree extends TFTreeGenerator { + + public TFGenNoTree() { + } + + public TFGenNoTree(boolean notify) { + super(notify); + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + return false; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenOutsideStalagmite.java b/src/main/java/twilightforest/world/feature/TFGenOutsideStalagmite.java new file mode 100644 index 0000000000..1cf959efbd --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenOutsideStalagmite.java @@ -0,0 +1,33 @@ +package twilightforest.world.feature; + +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Random; + + +/** + * Makes a Stalagmite suitable for outside appearances. + * + * @author Ben + */ +public class TFGenOutsideStalagmite extends TFGenCaveStalactite { + + public TFGenOutsideStalagmite() { + super(Blocks.STONE, 1.0F, false); + } + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + int length = rand.nextInt(10) + 5; + + if (!isAreaSuitable(world, rand, pos, 1, length, 1)) { + return false; + } + + // I think we already have code for this! :D + return makeSpike(world, rand, pos.down(), length); + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenPenguins.java b/src/main/java/twilightforest/world/feature/TFGenPenguins.java new file mode 100644 index 0000000000..82e0b055ea --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenPenguins.java @@ -0,0 +1,32 @@ +package twilightforest.world.feature; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.entity.passive.EntityTFPenguin; + +import java.util.Random; + +public class TFGenPenguins extends TFGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + for (int i = 0; i < 10; i++) { + BlockPos dPos = pos.add( + rand.nextInt(8) - rand.nextInt(8), + 0, + rand.nextInt(8) - rand.nextInt(8) + ); + dPos = world.getTopSolidOrLiquidBlock(dPos); + + if (dPos.getY() > 0) { + EntityTFPenguin penguin = new EntityTFPenguin(world); + penguin.moveToBlockPosAndAngles(dPos, rand.nextFloat() * 360.0F, 0.0F); + + world.spawnEntity(penguin); + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenPlantRoots.java b/src/main/java/twilightforest/world/feature/TFGenPlantRoots.java new file mode 100644 index 0000000000..a09f39c9a4 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenPlantRoots.java @@ -0,0 +1,32 @@ +package twilightforest.world.feature; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFPlant; +import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; + +import java.util.Random; + +public class TFGenPlantRoots extends TFGenerator { + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + int copyX = pos.getX(); + int copyZ = pos.getZ(); + + for (; pos.getY() > 5; pos = pos.down()) { + if (world.isAirBlock(pos) && BlockTFPlant.canPlaceRootAt(world, pos) && random.nextInt(6) > 0) { + world.setBlockState(pos, TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.ROOT_STRAND), 16 | 2); + } else { + pos = new BlockPos( + copyX + random.nextInt(4) - random.nextInt(4), + pos.getY(), + copyZ + random.nextInt(4) - random.nextInt(4) + ); + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenSmallRainboak.java b/src/main/java/twilightforest/world/feature/TFGenSmallRainboak.java new file mode 100644 index 0000000000..f642da4a1e --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenSmallRainboak.java @@ -0,0 +1,20 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import twilightforest.block.BlockTFLeaves; +import twilightforest.block.TFBlocks; +import twilightforest.enums.LeavesVariant; + +public class TFGenSmallRainboak extends TFGenSmallTwilightOak { + + public TFGenSmallRainboak() { + this(false); + } + + public TFGenSmallRainboak(boolean notify) { + super(notify, 4, + TFBlocks.twilight_log.getDefaultState(), + TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockTFLeaves.VARIANT, LeavesVariant.RAINBOAK).withProperty(BlockLeaves.CHECK_DECAY, false) + ); + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenSmallTwilightOak.java b/src/main/java/twilightforest/world/feature/TFGenSmallTwilightOak.java new file mode 100644 index 0000000000..f68a38a06b --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenSmallTwilightOak.java @@ -0,0 +1,31 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenTrees; +import twilightforest.block.TFBlocks; + +public class TFGenSmallTwilightOak extends WorldGenTrees implements IBlockSettable { + + public TFGenSmallTwilightOak(boolean notify) { + this(notify, 4); + } + + public TFGenSmallTwilightOak(boolean notify, int minHeight) { + this(notify, minHeight, + TFBlocks.twilight_log.getDefaultState(), + TFBlocks.twilight_leaves.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false) + ); + } + + protected TFGenSmallTwilightOak(boolean notify, int minHeight, IBlockState trunk, IBlockState leaves) { + super(notify, minHeight, trunk, leaves, false); + } + + @Override + public final void setBlockAndNotify(World world, BlockPos pos, IBlockState state) { + setBlockAndNotifyAdequately(world, pos, state); + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenSortingTree.java b/src/main/java/twilightforest/world/feature/TFGenSortingTree.java new file mode 100644 index 0000000000..3790e7ab65 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenSortingTree.java @@ -0,0 +1,67 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFMagicLog; +import twilightforest.block.TFBlocks; +import twilightforest.enums.MagicWoodVariant; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class TFGenSortingTree extends TFGenerator { + + protected IBlockState treeState = TFBlocks.magic_log.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.SORT); + protected IBlockState branchState = treeState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + protected IBlockState leafState = TFBlocks.magic_leaves.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.SORT).withProperty(BlockLeaves.CHECK_DECAY, false); + protected IBlockState rootState = TFBlocks.root.getDefaultState(); + + public TFGenSortingTree() { + this(false); + } + + public TFGenSortingTree(boolean notify) { + super(notify); + } + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + // check soil + Material materialUnder = world.getBlockState(pos.down()).getMaterial(); + if ((materialUnder != Material.GRASS && materialUnder != Material.GROUND) || pos.getY() >= TFWorld.MAXHEIGHT - 12) { + return false; + } + + // 3 block high trunk + for (int dy = 0; dy < 4; dy++) { + setBlockAndNotifyAdequately(world, pos.up(dy), treeState); + } + + // leaves + putLeaves(world, pos.up(2), false); + putLeaves(world, pos.up(3), false); + + // sorting engine + setBlockAndNotifyAdequately(world, pos.up(), TFBlocks.magic_log_core.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.SORT)); + + return true; + } + + private void putLeaves(World world, BlockPos pos, boolean bushy) { + for (int lx = -1; lx <= 1; lx++) { + for (int ly = -1; ly <= 1; ly++) { + for (int lz = -1; lz <= 1; lz++) { + if (!bushy && Math.abs(ly) > 0 && (Math.abs(lx) + Math.abs(lz)) > 1) { + continue; + } + putLeafBlock(this, world, pos.add(lx, ly, lz), leafState); + } + } + } + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenStoneCircle.java b/src/main/java/twilightforest/world/feature/TFGenStoneCircle.java new file mode 100644 index 0000000000..0326a7cc88 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenStoneCircle.java @@ -0,0 +1,37 @@ +package twilightforest.world.feature; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Random; + + +public class TFGenStoneCircle extends TFGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + if (!isAreaSuitable(world, rand, pos.add(-3, 0, -3), 6, 4, 6)) { + return false; + } + + IBlockState mossyCobble = Blocks.MOSSY_COBBLESTONE.getDefaultState(); + + // okay! circle! + for (int cy = 0; cy <= 2; cy++) { + setBlockAndNotifyAdequately(world, pos.add(-3, cy, 0), mossyCobble); + setBlockAndNotifyAdequately(world, pos.add(3, cy, 0), mossyCobble); + setBlockAndNotifyAdequately(world, pos.add(0, cy, -3), mossyCobble); + setBlockAndNotifyAdequately(world, pos.add(0, cy, 3), mossyCobble); + setBlockAndNotifyAdequately(world, pos.add(-2, cy, -2), mossyCobble); + setBlockAndNotifyAdequately(world, pos.add(2, cy, -2), mossyCobble); + setBlockAndNotifyAdequately(world, pos.add(-2, cy, 2), mossyCobble); + setBlockAndNotifyAdequately(world, pos.add(2, cy, 2), mossyCobble); + } + + + return true; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenTallGrass.java b/src/main/java/twilightforest/world/feature/TFGenTallGrass.java new file mode 100644 index 0000000000..0e4622c4d6 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenTallGrass.java @@ -0,0 +1,53 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockBush; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import java.util.Random; + +// [VanillaCopy] of WorldGenTallGrass, relevant changes noted +public class TFGenTallGrass extends WorldGenerator { + + private final IBlockState state; + private final int amount; + + public TFGenTallGrass(IBlockState state) { + this(state, 128); // Default vanilla amount + } + + public TFGenTallGrass(IBlockState state, int amount) { // TF - Allow any blockstate, allow amount to be changed + //WorldGenTallGrass use to use canBlockStay of Block, which was delegated to BlockBush. + //It's sane to make sure that we pass BlockBush in via the constructor. + if (!(state.getBlock() instanceof BlockBush)) { + throw new RuntimeException("attempt to use TFGenTallGrass with a blockstate that isn't a BlockBush"); + } + this.state = state; + this.amount = amount; + } + + @Override + public boolean generate(World worldIn, Random rand, BlockPos position) { + do { + IBlockState state = worldIn.getBlockState(position); + if (!state.getBlock().isAir(state, worldIn, position) && !state.getBlock().isLeaves(state, worldIn, position)) + break; + position = position.down(); + } while (position.getY() > 0); + + // TF - 128 -> amount + for (int i = 0; i < amount; ++i) { + BlockPos blockpos = position.add(rand.nextInt(8) - rand.nextInt(8), rand.nextInt(4) - rand.nextInt(4), rand.nextInt(8) - rand.nextInt(8)); + + // TF - use our own state + if (worldIn.isAirBlock(blockpos) && ((BlockBush) state.getBlock()).canBlockStay(worldIn, blockpos, state)) { + worldIn.setBlockState(blockpos, state, 16 | 2); + } + } + + return true; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenThorns.java b/src/main/java/twilightforest/world/feature/TFGenThorns.java new file mode 100644 index 0000000000..7032eccda7 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenThorns.java @@ -0,0 +1,105 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockRotatedPillar; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.TFBlocks; + +import java.util.Random; + +public class TFGenThorns extends TFGenerator { + + private static final int MAX_SPREAD = 7; + private static final int CHANCE_OF_BRANCH = 3; + private static final int CHANCE_OF_LEAF = 3; + private static final int CHANCE_LEAF_IS_ROSE = 50; + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + + // make a 3-5 long stack going up + int nextLength = 2 + rand.nextInt(4); + int maxLength = 2 + rand.nextInt(4) + rand.nextInt(4) + rand.nextInt(4); + + placeThorns(world, rand, pos, nextLength, EnumFacing.UP, maxLength, pos); + + + return true; + } + + private void placeThorns(World world, Random rand, BlockPos pos, int length, EnumFacing dir, int maxLength, BlockPos oPos) { + boolean complete = false; + for (int i = 0; i < length; i++) { + BlockPos dPos = pos.offset(dir, i); + + if (Math.abs(dPos.getX() - oPos.getX()) < MAX_SPREAD && Math.abs(dPos.getZ() - oPos.getZ()) < MAX_SPREAD && canPlaceThorns(world, dPos)) { + this.setBlockAndNotifyAdequately(world, dPos, TFBlocks.thorns.getDefaultState().withProperty(BlockRotatedPillar.AXIS, dir.getAxis())); + + // did we make it to the end? + if (i == length - 1) { + complete = true; + // maybe a leaf? or a rose? + if (rand.nextInt(CHANCE_OF_LEAF) == 0 && world.isAirBlock(dPos.offset(dir))) { + if (rand.nextInt(CHANCE_LEAF_IS_ROSE) > 0) { + // leaf + this.setBlockAndNotifyAdequately(world, dPos.offset(dir), TFBlocks.twilight_leaves_3.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false)); + } else { + // rose + this.setBlockAndNotifyAdequately(world, dPos.offset(dir), TFBlocks.thorn_rose.getDefaultState()); + } + } + } + } else { + break; + } + } + + // add another off the end + if (complete && maxLength > 1) { + + EnumFacing nextDir = EnumFacing.random(rand); + + BlockPos nextPos = pos.offset(dir, length - 1).offset(nextDir); + int nextLength = 1 + rand.nextInt(maxLength); + + this.placeThorns(world, rand, nextPos, nextLength, nextDir, maxLength - 1, oPos); + } + + // maybe another branch off the middle + if (complete && length > 3 && rand.nextInt(CHANCE_OF_BRANCH) == 0) { + + int middle = rand.nextInt(length); + + EnumFacing nextDir = EnumFacing.random(rand); + + BlockPos nextPos = pos.offset(dir, middle).offset(nextDir); + int nextLength = 1 + rand.nextInt(maxLength); + + this.placeThorns(world, rand, nextPos, nextLength, nextDir, maxLength - 1, oPos); + } + + // maybe a leaf + if (complete && length > 3 && rand.nextInt(CHANCE_OF_LEAF) == 0) { + + int middle = rand.nextInt(length); + + EnumFacing nextDir = EnumFacing.random(rand); + + BlockPos nextPos = pos.offset(dir, middle).offset(nextDir); + + if (world.isAirBlock(nextPos)) { + this.setBlockAndNotifyAdequately(world, nextPos, TFBlocks.twilight_leaves_3.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false)); + } + } + } + + private boolean canPlaceThorns(World world, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + return state.getBlock().isAir(state, world, pos) + || state.getBlock().isLeaves(state, world, pos); + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenTorchBerries.java b/src/main/java/twilightforest/world/feature/TFGenTorchBerries.java new file mode 100644 index 0000000000..196a88d75f --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenTorchBerries.java @@ -0,0 +1,32 @@ +package twilightforest.world.feature; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFPlant; +import twilightforest.block.TFBlocks; +import twilightforest.enums.PlantVariant; + +import java.util.Random; + +public class TFGenTorchBerries extends TFGenerator { + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + int copyX = pos.getX(); + int copyZ = pos.getZ(); + + for (; pos.getY() > 5; pos = pos.down()) { + if (world.isAirBlock(pos) && BlockTFPlant.canPlaceRootAt(world, pos) && random.nextInt(6) > 0) { + world.setBlockState(pos, TFBlocks.twilight_plant.getDefaultState().withProperty(BlockTFPlant.VARIANT, PlantVariant.TORCHBERRY), 16 | 2); + } else { + pos = new BlockPos( + copyX + random.nextInt(4) - random.nextInt(4), + pos.getY(), + copyZ + random.nextInt(4) - random.nextInt(4) + ); + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenTreeOfTime.java b/src/main/java/twilightforest/world/feature/TFGenTreeOfTime.java new file mode 100644 index 0000000000..8ae17ff7d5 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenTreeOfTime.java @@ -0,0 +1,82 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.TFBlocks; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class TFGenTreeOfTime extends TFGenHollowTree { + + public TFGenTreeOfTime(boolean notify) { + super(notify); + + this.treeState = TFBlocks.magic_log.getDefaultState(); + this.branchState = treeState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + this.leafState = TFBlocks.magic_leaves.getDefaultState().withProperty(BlockLeaves.CHECK_DECAY, false); + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + + int height = 8; + int diameter = 1; + + // do we have enough height? + if (pos.getY() < 1 || pos.getY() + height + diameter > TFWorld.MAXHEIGHT) { + return false; + } + + // check if we're on dirt or grass + IBlockState state = world.getBlockState(pos.down()); + if (!state.getBlock().canSustainPlant(state, world, pos.down(), EnumFacing.UP, source)) { + return false; + } + + // make a tree! + + // build the trunk + buildTrunk(world, random, pos, diameter, height); + + // build the crown + buildTinyCrown(world, random, pos, diameter, height); + + // 3-5 roots at the bottom + buildBranchRing(world, random, pos, diameter, 1, 0, 12, 0, 0.75D, 0, 3, 5, 3, false); + + // several more taproots + buildBranchRing(world, random, pos, diameter, 1, 2, 18, 0, 0.9D, 0, 3, 5, 3, false); + + // add clock block + this.setBlockAndNotifyAdequately(world, pos.add(-1, 2, 0), TFBlocks.magic_log_core.getDefaultState()); + + return true; + } + + /** + * Build the crown of the tree. This builds a smaller crown, since the large + * ones were causing some performance issues + */ + protected void buildTinyCrown(World world, Random random, BlockPos pos, int diameter, int height) { + int crownRadius = 4; + int bvar = 1; + + // 3-5 medium branches starting at the bottom of the crown + buildBranchRing(world, random, pos, diameter, height - crownRadius, 0, crownRadius, 0, 0.35D, 0, bvar, bvar + 2, 1, true); + + // 3-5 medium branches at the crown middle + buildBranchRing(world, random, pos, diameter, height - (crownRadius / 2), 0, crownRadius, 0, 0.28D, 0, bvar, bvar + 2, 1, true); + + // 2-4 medium branches at the crown top + buildBranchRing(world, random, pos, diameter, height, 0, crownRadius, 0, 0.15D, 0, 2, 4, 0, true); + + // 3-6 medium branches going straight up + buildBranchRing(world, random, pos, diameter, height, 0, (crownRadius / 2), 0, 0.05D, 0, bvar, bvar + 2, 0, true); + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenTreeOfTransformation.java b/src/main/java/twilightforest/world/feature/TFGenTreeOfTransformation.java new file mode 100644 index 0000000000..0bd8deeb03 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenTreeOfTransformation.java @@ -0,0 +1,43 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockLeaves; +import net.minecraft.block.BlockLog; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFMagicLog; +import twilightforest.block.TFBlocks; +import twilightforest.enums.MagicWoodVariant; + +import java.util.Random; + +public class TFGenTreeOfTransformation extends TFGenCanopyTree { + + public TFGenTreeOfTransformation() { + this(false); + } + + public TFGenTreeOfTransformation(boolean notify) { + super(notify); + + this.treeState = TFBlocks.magic_log.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.TRANS); + this.branchState = treeState.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE); + this.leafState = TFBlocks.magic_leaves.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.TRANS).withProperty(BlockLeaves.CHECK_DECAY, false); + + this.minHeight = 11; + this.chanceAddFirstFive = Integer.MAX_VALUE; + this.chanceAddSecondFive = Integer.MAX_VALUE; + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + if (super.generate(world, random, pos)) { + // heart of transformation + setBlockAndNotifyAdequately(world, pos.up(3), TFBlocks.magic_log_core.getDefaultState().withProperty(BlockTFMagicLog.VARIANT, MagicWoodVariant.TRANS)); + return true; + } else { + return false; + } + } + + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenTrollRoots.java b/src/main/java/twilightforest/world/feature/TFGenTrollRoots.java new file mode 100644 index 0000000000..115ca15d49 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenTrollRoots.java @@ -0,0 +1,35 @@ +package twilightforest.world.feature; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFTrollRoot; +import twilightforest.block.TFBlocks; + +import java.util.Random; + +public class TFGenTrollRoots extends TFGenerator { + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + int copyX = pos.getX(); + int copyZ = pos.getZ(); + + for (; pos.getY() > 5; pos = pos.down()) { + if (world.isAirBlock(pos) && BlockTFTrollRoot.canPlaceRootBelow(world, pos.up()) && random.nextInt(6) > 0) { + if (random.nextInt(10) == 0) { + world.setBlockState(pos, TFBlocks.unripe_trollber.getDefaultState(), 16 | 2); + } else { + world.setBlockState(pos, TFBlocks.trollvidr.getDefaultState(), 16 | 2); + } + } else { + pos = new BlockPos( + copyX + random.nextInt(4) - random.nextInt(4), + pos.getY(), + copyZ + random.nextInt(4) - random.nextInt(4) + ); + } + } + + return true; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenVines.java b/src/main/java/twilightforest/world/feature/TFGenVines.java new file mode 100644 index 0000000000..da2e8c196d --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenVines.java @@ -0,0 +1,68 @@ +package twilightforest.world.feature; + +import net.minecraft.block.BlockVine; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; +import twilightforest.world.TFWorld; + +import java.util.EnumSet; +import java.util.Random; +import java.util.Set; + +/** + * This class fixes the vanilla WorldGenVines, which appears to be nonfunctional in 1.11 + */ +public class TFGenVines extends WorldGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos position) { + + BlockPos original = position; + + for (; position.getY() > TFWorld.SEALEVEL; position = position.down()) { + + if (world.isAirBlock(position)) { + + Set facings = EnumSet.noneOf(EnumFacing.class); + + for (EnumFacing facing : EnumFacing.Plane.HORIZONTAL.facings()) { + if (Blocks.VINE.canPlaceBlockOnSide(world, position, facing.getOpposite())) { + facings.add(facing); + } + } + + if (!facings.isEmpty()) { + + IBlockState vine = Blocks.VINE.getDefaultState(); + for (EnumFacing facing : facings) { + vine = vine.withProperty(BlockVine.getPropertyFor(facing), true); + } + + BlockPos down = position; + do { + world.setBlockState(down, vine, 16 | 2); + down = down.down(); + } while (down.getY() >= 0 && world.isAirBlock(down)); + + return true; + } + + } else { + position = position.add(rand.nextInt(4) - rand.nextInt(4), 0, rand.nextInt(4) - rand.nextInt(4)); + if (isOutsideBounds(7, original, position)) { + break; + } + } + } + + return false; + } + + private static boolean isOutsideBounds(int radius, BlockPos original, BlockPos pos) { + return Math.abs(original.getX() - pos.getX()) > radius || Math.abs(original.getZ() - pos.getZ()) > radius; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenWebs.java b/src/main/java/twilightforest/world/feature/TFGenWebs.java new file mode 100644 index 0000000000..e8f299fe75 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenWebs.java @@ -0,0 +1,35 @@ +package twilightforest.world.feature; + +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.world.TFWorld; + +import java.util.Random; + +public class TFGenWebs extends TFGenerator { + + private static boolean isValidMaterial(Material material) { + return material == Material.LEAVES || material == Material.WOOD; + } + + @Override + public boolean generate(World world, Random random, BlockPos pos) { + while (pos.getY() > TFWorld.SEALEVEL && world.isAirBlock(pos)) + pos = pos.down(); + + if (!isValidMaterial(world.getBlockState(pos).getMaterial())) + return false; + + do { + if (world.isAirBlock(pos.down())) { + world.setBlockState(pos.down(), Blocks.WEB.getDefaultState(), 16 | 2); + return true; + } + pos = pos.down(); + } while (pos.getY() > TFWorld.SEALEVEL && isValidMaterial(world.getBlockState(pos).getMaterial())); + + return false; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFGenWell.java b/src/main/java/twilightforest/world/feature/TFGenWell.java new file mode 100644 index 0000000000..5ae22893a2 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenWell.java @@ -0,0 +1,183 @@ +package twilightforest.world.feature; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.loot.TFTreasure; + +import java.util.Random; + + +public class TFGenWell extends TFGenerator { + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + if (rand.nextInt(4) == 0) { + return generate4x4Well(world, rand, pos); + } else { + return generate3x3Well(world, rand, pos); + } + } + + + /** + * make a cute little well + */ + public boolean generate3x3Well(World world, Random rand, BlockPos pos) { + if (!isAreaSuitable(world, rand, pos, 3, 4, 3)) { + return false; + } + + + // make a cute well! + setBlockAndNotifyAdequately(world, pos, Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 0), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 0), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 2), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 2), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 2), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 1), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 1), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(1, 0, 1), Blocks.WATER.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(0, 1, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 1, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 1, 2), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 1, 2), Blocks.OAK_FENCE.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(0, 2, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 2, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 2), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 2, 2), Blocks.OAK_FENCE.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(0, 3, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 3, 2), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 2), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 2), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 3, 1), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 1), Blocks.WOODEN_SLAB.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(1, 3, 1), Blocks.PLANKS.getDefaultState()); + + + boolean madeTreasure = false; + // now drill each the well square down 20 squares, or until we hit something + for (int dy = -1; dy >= -20; dy--) { + Block dblock = world.getBlockState(pos.add(1, dy, 1)).getBlock(); + // we only drill through dirt, grass, gravel and stone + if (dblock != Blocks.DIRT && dblock != Blocks.GRASS && dblock != Blocks.GRAVEL && dblock != Blocks.STONE) { + break; + } + // we also need a solid block under where we're digging + if (!world.getBlockState(pos.add(1, dy - 1, 1)).getMaterial().isSolid()) { + break; + } + + // okay, we're good to dig. + setBlockAndNotifyAdequately(world, pos.add(1, dy, 1), Blocks.WATER.getDefaultState()); + + // if we're below 15 squares, there's a small chance of treasure + if (dy < -15 && !madeTreasure && rand.nextInt(8) == 0) { + //TODO: more directions + setBlockAndNotifyAdequately(world, pos.add(2, dy, 1), Blocks.WATER.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, dy + 1, 1), Blocks.AIR.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, dy, 1), Blocks.AIR.getDefaultState()); + + //TODO: unique treasure table that is themed for underwater well exploration + TFTreasure.basement.generateChest(world, pos.add(3, dy, 1), false); + + // set flag so we only get one chest + madeTreasure = true; + } + } + + return true; + } + + private boolean generate4x4Well(World world, Random rand, BlockPos pos) { + if (!isAreaSuitable(world, rand, pos, 4, 4, 4)) { + return false; + } + + // make a cute well! + setBlockAndNotifyAdequately(world, pos, Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 0), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 0), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 0, 0), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 3), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 3), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 3), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 0, 3), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 1), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 2), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 0, 1), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 0, 2), Blocks.MOSSY_COBBLESTONE.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(1, 0, 1), Blocks.WATER.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 1), Blocks.WATER.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 2), Blocks.WATER.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 2), Blocks.WATER.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(0, 1, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 1, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 1, 3), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 1, 3), Blocks.OAK_FENCE.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(0, 2, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 2, 0), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 3), Blocks.OAK_FENCE.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 2, 3), Blocks.OAK_FENCE.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(0, 3, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 3, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 3, 3), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 3), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 3), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 3, 3), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 3, 1), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 3, 2), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 3, 1), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 3, 2), Blocks.WOODEN_SLAB.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(1, 3, 1), Blocks.PLANKS.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 1), Blocks.PLANKS.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 2), Blocks.PLANKS.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 2), Blocks.PLANKS.getDefaultState()); + + + // now drill each of the 4 well squares down 20 squares, or until we hit something + for (int dx = 1; dx <= 2; dx++) { + for (int dz = 1; dz <= 2; dz++) { + for (int dy = -1; dy >= -20; dy--) { + BlockPos dPos = pos.add(dx, dy, dz); + IBlockState dState = world.getBlockState(dPos); + Block dblock = dState.getBlock(); + + // we only drill through dirt, grass, gravel and stone + if (dblock != Blocks.DIRT && dblock != Blocks.GRASS && dblock != Blocks.GRAVEL && dblock != Blocks.STONE) { + break; + } + // we also need a solid block under where we're digging + if (!world.getBlockState(dPos.down()).getMaterial().isSolid()) { + break; + } + + // okay, we're good to dig. + setBlockAndNotifyAdequately(world, dPos, Blocks.WATER.getDefaultState()); + } + + } + + } + + return true; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenWitchHut.java b/src/main/java/twilightforest/world/feature/TFGenWitchHut.java new file mode 100644 index 0000000000..3dbf3cfb5a --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenWitchHut.java @@ -0,0 +1,187 @@ +package twilightforest.world.feature; + +import net.minecraft.entity.EntityList; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntityMobSpawner; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.entity.EntityTFSkeletonDruid; + +import java.util.Random; + + +public class TFGenWitchHut extends TFGenerator { + + /** + * Make a cute witch's hut + */ + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + return generateTinyHut(world, rand, pos); + } + + /** + * Make the smallest size hut + */ + public boolean generateTinyHut(World world, Random rand, BlockPos pos) { + if (!isAreaSuitable(world, rand, pos, 5, 7, 6)) { + return false; + } + + // walls! + + setBlockAndNotifyAdequately(world, pos.add(1, 0, 1), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 1), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(3, 0, 1), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(5, 0, 1), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 2), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 2), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 0, 2), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 3), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 0, 3), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(0, 0, 4), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 4), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 0, 4), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 5), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(2, 0, 5), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(3, 0, 5), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(5, 0, 5), randStone(rand, 1)); + + setBlockAndNotifyAdequately(world, pos.add(1, 1, 1), randStone(rand, 2)); + setBlockAndNotifyAdequately(world, pos.add(3, 1, 1), randStone(rand, 2)); + setBlockAndNotifyAdequately(world, pos.add(5, 1, 1), randStone(rand, 2)); + setBlockAndNotifyAdequately(world, pos.add(0, 1, 2), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 1, 2), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 1, 2), randStone(rand, 2)); + setBlockAndNotifyAdequately(world, pos.add(0, 1, 3), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 1, 4), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 1, 4), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 1, 4), randStone(rand, 2)); + setBlockAndNotifyAdequately(world, pos.add(1, 1, 5), randStone(rand, 2)); + setBlockAndNotifyAdequately(world, pos.add(3, 1, 5), randStone(rand, 2)); + setBlockAndNotifyAdequately(world, pos.add(5, 1, 5), randStone(rand, 2)); + + setBlockAndNotifyAdequately(world, pos.add(1, 2, 1), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(2, 2, 1), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(3, 2, 1), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(4, 2, 1), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(5, 2, 1), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 2), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 2, 2), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 2, 2), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 3), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 2, 3), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 4), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 2, 4), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 2, 4), randStone(rand, 1)); + setBlockAndNotifyAdequately(world, pos.add(1, 2, 5), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(2, 2, 5), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(3, 2, 5), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(4, 2, 5), randStone(rand, 3)); + setBlockAndNotifyAdequately(world, pos.add(5, 2, 5), randStone(rand, 3)); + + setBlockAndNotifyAdequately(world, pos.add(0, 3, 2), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 3, 3), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 3, 4), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 1), randStone(rand, 4)); + setBlockAndNotifyAdequately(world, pos.add(3, 3, 1), randStone(rand, 4)); + setBlockAndNotifyAdequately(world, pos.add(4, 3, 1), randStone(rand, 4)); + setBlockAndNotifyAdequately(world, pos.add(2, 3, 5), randStone(rand, 4)); + setBlockAndNotifyAdequately(world, pos.add(3, 3, 5), randStone(rand, 4)); + setBlockAndNotifyAdequately(world, pos.add(4, 3, 5), randStone(rand, 4)); + + setBlockAndNotifyAdequately(world, pos.add(0, 4, 3), Blocks.BRICK_BLOCK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 4, 1), randStone(rand, 5)); + setBlockAndNotifyAdequately(world, pos.add(3, 4, 5), randStone(rand, 5)); + + setBlockAndNotifyAdequately(world, pos.add(0, 5, 3), Blocks.BRICK_BLOCK.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(0, 6, 3), Blocks.BRICK_BLOCK.getDefaultState()); + + // roof! + setBlockAndNotifyAdequately(world, pos.add(0, 2, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(0, 2, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(6, 2, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(6, 2, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(6, 2, 2), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(6, 2, 3), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(6, 2, 4), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(6, 2, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(6, 2, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(1, 3, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 2), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 4), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 3, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 3, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 3, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 3, 2), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 3, 3), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 3, 4), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 3, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 3, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(1, 4, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 4, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 4, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 4, 2), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 4, 3), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 4, 4), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 4, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 4, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 4, 6), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 4, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 4, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 4, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 4, 2), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 4, 3), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 4, 4), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 4, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 4, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(5, 4, 6), Blocks.WOODEN_SLAB.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(2, 5, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 5, 1), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 5, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 5, 1), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 5, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 5, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 5, 2), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 5, 3), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 5, 4), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 5, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 5, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 5, 5), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(2, 5, 6), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 5, 5), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(4, 5, 6), Blocks.WOODEN_SLAB.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(3, 6, 0), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 6, 1), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 6, 2), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 6, 4), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 6, 5), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 6, 6), Blocks.DOUBLE_WOODEN_SLAB.getDefaultState()); + + setBlockAndNotifyAdequately(world, pos.add(3, 7, 0), Blocks.WOODEN_SLAB.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(3, 7, 6), Blocks.WOODEN_SLAB.getDefaultState()); + + // fire in chimney! + setBlockAndNotifyAdequately(world, pos.add(1, -1, 3), Blocks.NETHERRACK.getDefaultState()); + setBlockAndNotifyAdequately(world, pos.add(1, 0, 3), Blocks.FIRE.getDefaultState()); // oh god the roof! + + // skeleton spawner! + world.setBlockState(pos.add(3, 1, 3), Blocks.MOB_SPAWNER.getDefaultState(), 16 | 2); + TileEntityMobSpawner ms = (TileEntityMobSpawner) world.getTileEntity(pos.add(3, 1, 3)); + if (ms != null) { + ms.getSpawnerBaseLogic().setEntityId(EntityList.getKey(EntityTFSkeletonDruid.class)); + } + + return true; + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenWoodRoots.java b/src/main/java/twilightforest/world/feature/TFGenWoodRoots.java new file mode 100644 index 0000000000..2f3b31167e --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenWoodRoots.java @@ -0,0 +1,115 @@ +package twilightforest.world.feature; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import twilightforest.block.BlockTFRoots; +import twilightforest.block.TFBlocks; +import twilightforest.enums.RootVariant; + +import java.util.Random; + +public class TFGenWoodRoots extends TFGenerator { + + private IBlockState rootBlock = TFBlocks.root.getDefaultState(); + private IBlockState oreBlock = TFBlocks.root.getDefaultState().withProperty(BlockTFRoots.VARIANT, RootVariant.LIVEROOT); + + @Override + public boolean generate(World world, Random rand, BlockPos pos) { + // start must be in stone + if (world.getBlockState(pos).getBlock() != Blocks.STONE) { + return false; + } + + float length = rand.nextFloat() * 6.0F + rand.nextFloat() * 6.0F + 4.0F; + if (length > pos.getY()) { + length = pos.getY(); + } + + // tilt between 0.6 and 0.9 + float tilt = 0.6F + rand.nextFloat() * 0.3F; + + return drawRoot(world, rand, pos, length, rand.nextFloat(), tilt); + } + + private boolean drawRoot(World world, Random rand, BlockPos pos, float length, float angle, float tilt) { + // put origin at where we start + return this.drawRoot(world, rand, pos, pos, length, angle, tilt); + } + + + private boolean drawRoot(World world, Random rand, BlockPos oPos, BlockPos pos, float length, float angle, float tilt) { + // generate a direction and a length + BlockPos dest = translate(pos, length, angle, tilt); + + // restrict x and z to within 7 + int limit = 6; + if (oPos.getX() + limit < dest.getX()) { + dest = new BlockPos(oPos.getX() + limit, dest.getY(), dest.getZ()); + } + if (oPos.getX() - limit > dest.getX()) { + dest = new BlockPos(oPos.getX() - limit, dest.getY(), dest.getZ()); + } + if (oPos.getZ() + limit < dest.getZ()) { + dest = new BlockPos(dest.getX(), dest.getY(), oPos.getZ() + limit); + } + if (oPos.getZ() - limit > dest.getZ()) { + dest = new BlockPos(dest.getX(), dest.getY(), oPos.getZ() - limit); + } + + // end must be in stone + if (world.getBlockState(dest).getBlock() != Blocks.STONE) { + return false; + } + + // if both the start and the end are in stone, put a root there + BlockPos[] lineArray = getBresehnamArrays(pos, dest); + for (BlockPos coord : lineArray) { + this.placeRootBlock(world, coord, rootBlock); + } + + + // if we are long enough, make either another root or an oreball + if (length > 8) { + if (rand.nextInt(3) > 0) { + // length > 8, usually split off into another root half as long + BlockPos nextSrc = translate(pos, length / 2, angle, tilt); + float nextAngle = (angle + 0.25F + (rand.nextFloat() * 0.5F)) % 1.0F; + float nextTilt = 0.6F + rand.nextFloat() * 0.3F; + drawRoot(world, rand, oPos, nextSrc, length / 2.0F, nextAngle, nextTilt); + + + } + } + + if (length > 6) { + if (rand.nextInt(4) == 0) { + // length > 6, potentially make oreball + BlockPos ballSrc = translate(pos, length / 2, angle, tilt); + BlockPos ballDest = translate(ballSrc, 1.5, (angle + 0.5F) % 1.0F, 0.75); + + this.placeRootBlock(world, ballSrc, oreBlock); + this.placeRootBlock(world, new BlockPos(ballSrc.getX(), ballSrc.getY(), ballDest.getZ()), oreBlock); + this.placeRootBlock(world, new BlockPos(ballDest.getX(), ballSrc.getY(), ballSrc.getZ()), oreBlock); + this.placeRootBlock(world, new BlockPos(ballSrc.getX(), ballSrc.getY(), ballDest.getZ()), oreBlock); + this.placeRootBlock(world, new BlockPos(ballSrc.getX(), ballDest.getY(), ballSrc.getZ()), oreBlock); + this.placeRootBlock(world, new BlockPos(ballSrc.getX(), ballDest.getY(), ballDest.getZ()), oreBlock); + this.placeRootBlock(world, new BlockPos(ballDest.getX(), ballDest.getY(), ballSrc.getZ()), oreBlock); + this.placeRootBlock(world, ballDest, oreBlock); + } + } + + return true; + } + + /** + * Function used to actually place root blocks if they're not going to break anything important + */ + protected void placeRootBlock(World world, BlockPos pos, IBlockState state) { + if (TFTreeGenerator.canRootGrowIn(world, pos)) { + this.setBlockAndNotifyAdequately(world, pos, state); + } + } + +} diff --git a/src/main/java/twilightforest/world/feature/TFGenerator.java b/src/main/java/twilightforest/world/feature/TFGenerator.java new file mode 100644 index 0000000000..89f7ddfe83 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFGenerator.java @@ -0,0 +1,370 @@ +package twilightforest.world.feature; + +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; + +import java.util.Random; + + +public abstract class TFGenerator extends WorldGenerator implements IBlockSettable { + + public TFGenerator() { + this(false); + } + + public TFGenerator(boolean notify) { + super(notify); + } + + @Override + public final void setBlockAndNotify(World worldIn, BlockPos pos, IBlockState state) { + setBlockAndNotifyAdequately(worldIn, pos, state); + } + + /** + * Moves distance along the vector. + *

+ * This goofy function takes a float between 0 and 1 for the angle, where 0 is 0 degrees, .5 is 180 degrees and 1 and 360 degrees. + * For the tilt, it takes a float between 0 and 1 where 0 is straight up, 0.5 is straight out and 1 is straight down. + */ + public static BlockPos translate(BlockPos pos, double distance, double angle, double tilt) { + double rangle = angle * 2.0D * Math.PI; + double rtilt = tilt * Math.PI; + + return pos.add( + Math.round(Math.sin(rangle) * Math.sin(rtilt) * distance), + Math.round(Math.cos(rtilt) * distance), + Math.round(Math.cos(rangle) * Math.sin(rtilt) * distance) + ); + } + + /** + * Draws a line from {x1, y1, z1} to {x2, y2, z2} + */ + protected static void drawBresehnam(IBlockSettable generator, World world, BlockPos from, BlockPos to, IBlockState state) { + if (from.getX() == to.getX() && from.getZ() == to.getZ()) { + int l = Math.max(from.getY(), to.getY()); + for (int i = Math.min(from.getY(), to.getY()); i < l; i++) { + generator.setBlockAndNotify(world, from.up(i - from.getY()), state); + } + } else { + for (BlockPos pixel : getBresehnamArrays(from, to)) { + generator.setBlockAndNotify(world, pixel, state); + } + } + } + + /** + * Get an array of values that represent a line from point A to point B + */ + public static BlockPos[] getBresehnamArrays(BlockPos src, BlockPos dest) { + return getBresehnamArrays(src.getX(), src.getY(), src.getZ(), dest.getX(), dest.getY(), dest.getZ()); + } + + /** + * Get an array of values that represent a line from point A to point B + * todo 1.9 lazify this into an iterable? + */ + public static BlockPos[] getBresehnamArrays(int x1, int y1, int z1, int x2, int y2, int z2) { + int i, dx, dy, dz, absDx, absDy, absDz, x_inc, y_inc, z_inc, err_1, err_2, doubleAbsDx, doubleAbsDy, doubleAbsDz; + + BlockPos pixel = new BlockPos(x1, y1, z1); + BlockPos lineArray[]; + + dx = x2 - x1; + dy = y2 - y1; + dz = z2 - z1; + x_inc = (dx < 0) ? -1 : 1; + absDx = Math.abs(dx); + y_inc = (dy < 0) ? -1 : 1; + absDy = Math.abs(dy); + z_inc = (dz < 0) ? -1 : 1; + absDz = Math.abs(dz); + doubleAbsDx = absDx << 1; + doubleAbsDy = absDy << 1; + doubleAbsDz = absDz << 1; + + if ((absDx >= absDy) && (absDx >= absDz)) { + err_1 = doubleAbsDy - absDx; + err_2 = doubleAbsDz - absDx; + lineArray = new BlockPos[absDx + 1]; + for (i = 0; i < absDx; i++) { + lineArray[i] = pixel; + if (err_1 > 0) { + pixel = pixel.up(y_inc); + err_1 -= doubleAbsDx; + } + if (err_2 > 0) { + pixel = pixel.south(z_inc); + err_2 -= doubleAbsDx; + } + err_1 += doubleAbsDy; + err_2 += doubleAbsDz; + pixel = pixel.east(x_inc); + } + } else if ((absDy >= absDx) && (absDy >= absDz)) { + err_1 = doubleAbsDx - absDy; + err_2 = doubleAbsDz - absDy; + lineArray = new BlockPos[absDy + 1]; + for (i = 0; i < absDy; i++) { + lineArray[i] = pixel; + if (err_1 > 0) { + pixel = pixel.east(x_inc); + err_1 -= doubleAbsDy; + } + if (err_2 > 0) { + pixel = pixel.south(z_inc); + err_2 -= doubleAbsDy; + } + err_1 += doubleAbsDx; + err_2 += doubleAbsDz; + pixel = pixel.up(y_inc); + } + } else { + err_1 = doubleAbsDy - absDz; + err_2 = doubleAbsDx - absDz; + lineArray = new BlockPos[absDz + 1]; + for (i = 0; i < absDz; i++) { + lineArray[i] = pixel; + if (err_1 > 0) { + pixel = pixel.up(y_inc); + err_1 -= doubleAbsDz; + } + if (err_2 > 0) { + pixel = pixel.east(x_inc); + err_2 -= doubleAbsDz; + } + err_1 += doubleAbsDy; + err_2 += doubleAbsDx; + pixel = pixel.south(z_inc); + } + } + lineArray[lineArray.length - 1] = pixel; + + return lineArray; + } + + /** + * Draw a flat blob (circle) of leaves + */ + public static void makeLeafCircle(IBlockSettable generator, World world, BlockPos pos, int rad, IBlockState state, boolean useHack) { + // trace out a quadrant + for (byte dx = 0; dx <= rad; dx++) { + for (byte dz = 0; dz <= rad; dz++) { + int dist = Math.max(dx, dz) + (Math.min(dx, dz) >> 1); + + //hack! I keep getting failing leaves at a certain position. + if (useHack && dx == 3 && dz == 3) { + dist = 6; + } + + // if we're inside the blob, fill it + if (dist <= rad) { + // do four at a time for easiness! + putLeafBlock(generator, world, pos.add(+dx, 0, +dz), state); + putLeafBlock(generator, world, pos.add(+dx, 0, -dz), state); + putLeafBlock(generator, world, pos.add(-dx, 0, +dz), state); + putLeafBlock(generator, world, pos.add(-dx, 0, -dz), state); + } + } + } + } + + /** + * Draw a flat blob (circle) of leaves. This one makes it offset to surround a 2x2 area instead of a 1 block area + */ + public static void makeLeafCircle2(IBlockSettable generator, World world, BlockPos pos, int rad, IBlockState state, boolean useHack) { + // trace out a quadrant + for (byte dx = 0; dx <= rad; dx++) { + for (byte dz = 0; dz <= rad; dz++) { +// int dist = Math.max(dx, dz) + (int)(Math.min(dx, dz) * 0.6F); +// +// //hack! I keep getting failing leaves at a certain position. +// if (useHack && dx == 3 && dz == 3) { +// dist = 6; +// } + + // if we're inside the blob, fill it + if (dx * dx + dz * dz <= rad * rad) { + // do four at a time for easiness! + putLeafBlock(generator, world, pos.add(1 + dx, 0, 1 + dz), state); + putLeafBlock(generator, world, pos.add(1 + dx, 0, -dz), state); + putLeafBlock(generator, world, pos.add(-dx, 0, 1 + dz), state); + putLeafBlock(generator, world, pos.add(-dx, 0, -dz), state); + } + } + } + } + + /** + * Put a leaf only in spots where leaves can go! + */ + public static void putLeafBlock(IBlockSettable generator, World world, BlockPos pos, IBlockState state) { + IBlockState whatsThere = world.getBlockState(pos); + + if (whatsThere.getBlock().canBeReplacedByLeaves(whatsThere, world, pos) && whatsThere.getBlock() != state.getBlock()) { + generator.setBlockAndNotify(world, pos, state); + } + } + + /** + * Gets either cobblestone or mossy cobblestone, randomly. Used for ruins. + */ + protected static IBlockState randStone(Random rand, int howMuch) { + return rand.nextInt(howMuch) >= 1 ? Blocks.COBBLESTONE.getDefaultState() : Blocks.MOSSY_COBBLESTONE.getDefaultState(); + } + + /** + * Checks an area to see if it consists of flat natural ground below and air above + */ + protected static boolean isAreaSuitable(World world, Random rand, BlockPos pos, int width, int height, int depth) { + boolean flag = true; + + + // check if there's anything within the diameter + for (int cx = 0; cx < width; cx++) { + for (int cz = 0; cz < depth; cz++) { + BlockPos pos_ = pos.add(cx, 0, cz); + // check if the blocks even exist? + if (world.isBlockLoaded(pos_)) { + // is there grass, dirt or stone below? + Material m = world.getBlockState(pos_.down()).getMaterial(); + if (m != Material.GROUND && m != Material.GRASS && m != Material.ROCK) { + flag = false; + } + + for (int cy = 0; cy < height; cy++) { + // blank space above? + if (!world.isAirBlock(pos_.up(cy))) { + flag = false; + } + } + } else { + flag = false; + } + } + } + + // Okie dokie + return flag; + + } + + /** + * Draw a giant blob of whatevs. + */ + public static void drawBlob(IBlockSettable generator, World world, BlockPos pos, int rad, IBlockState state) { + // then trace out a quadrant + for (byte dx = 0; dx <= rad; dx++) { + for (byte dy = 0; dy <= rad; dy++) { + for (byte dz = 0; dz <= rad; dz++) { + // determine how far we are from the center. + int dist = 0; + if (dx >= dy && dx >= dz) { + dist = dx + (Math.max(dy, dz) >> 1) + (Math.min(dy, dz) >> 2); + } else if (dy >= dx && dy >= dz) { + dist = dy + (Math.max(dx, dz) >> 1) + (Math.min(dx, dz) >> 2); + } else { + dist = dz + (Math.max(dx, dy) >> 1) + (Math.min(dx, dy) >> 2); + } + + + // if we're inside the blob, fill it + if (dist <= rad) { + // do eight at a time for easiness! + generator.setBlockAndNotify(world, pos.add(+dx, +dy, +dz), state); + generator.setBlockAndNotify(world, pos.add(+dx, +dy, -dz), state); + generator.setBlockAndNotify(world, pos.add(-dx, +dy, +dz), state); + generator.setBlockAndNotify(world, pos.add(-dx, +dy, -dz), state); + generator.setBlockAndNotify(world, pos.add(+dx, -dy, +dz), state); + generator.setBlockAndNotify(world, pos.add(+dx, -dy, -dz), state); + generator.setBlockAndNotify(world, pos.add(-dx, -dy, +dz), state); + generator.setBlockAndNotify(world, pos.add(-dx, -dy, -dz), state); + } + } + } + } + } + + /** + * Draw a giant blob of leaves. + */ + public static void drawLeafBlob(IBlockSettable generator, World world, BlockPos pos, int rad, IBlockState state) { + // then trace out a quadrant + for (byte dx = 0; dx <= rad; dx++) { + for (byte dy = 0; dy <= rad; dy++) { + for (byte dz = 0; dz <= rad; dz++) { + // determine how far we are from the center. + int dist = 0; + if (dx >= dy && dx >= dz) { + dist = dx + (Math.max(dy, dz) >> 1) + (Math.min(dy, dz) >> 2); + } else if (dy >= dx && dy >= dz) { + dist = dy + (Math.max(dx, dz) >> 1) + (Math.min(dx, dz) >> 2); + } else { + dist = dz + (Math.max(dx, dy) >> 1) + (Math.min(dx, dy) >> 2); + } + + + // if we're inside the blob, fill it + if (dist <= rad) { + // do eight at a time for easiness! + putLeafBlock(generator, world, pos.add(+dx, +dy, +dz), state); + putLeafBlock(generator, world, pos.add(+dx, +dy, -dz), state); + putLeafBlock(generator, world, pos.add(-dx, +dy, +dz), state); + putLeafBlock(generator, world, pos.add(-dx, +dy, -dz), state); + putLeafBlock(generator, world, pos.add(+dx, -dy, +dz), state); + putLeafBlock(generator, world, pos.add(+dx, -dy, -dz), state); + putLeafBlock(generator, world, pos.add(-dx, -dy, +dz), state); + putLeafBlock(generator, world, pos.add(-dx, -dy, -dz), state); + } + } + } + } + } + + /** + * Does the block have only air blocks adjacent + */ + protected static boolean surroundedByAir(IBlockAccess world, BlockPos pos) { + for (EnumFacing e : EnumFacing.VALUES) { + if (!world.isAirBlock(pos.offset(e))) { + return false; + } + } + + return true; + } + + /** + * Does the block have at least 1 air block adjacent + */ + protected static boolean hasAirAround(World world, BlockPos pos) { + for (EnumFacing e : EnumFacing.VALUES) { + if (e == EnumFacing.DOWN) + continue; // todo 1.9 was in old logic + if (world.isBlockLoaded(pos.offset(e)) + && world.isAirBlock(pos.offset(e))) { + return true; + } + } + + return false; + } + + protected static boolean isNearSolid(World world, BlockPos pos) { + for (EnumFacing e : EnumFacing.HORIZONTALS) { + if (world.isBlockLoaded(pos.offset(e)) + && world.getBlockState(pos.offset(e)).getMaterial().isSolid()) { + return true; + } + } + + return false; + } +} diff --git a/src/main/java/twilightforest/world/feature/TFTreeGenerator.java b/src/main/java/twilightforest/world/feature/TFTreeGenerator.java new file mode 100644 index 0000000000..48b96d6b01 --- /dev/null +++ b/src/main/java/twilightforest/world/feature/TFTreeGenerator.java @@ -0,0 +1,108 @@ +package twilightforest.world.feature; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockDirectional; +import net.minecraft.block.BlockLog; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenAbstractTree; +import net.minecraftforge.common.IPlantable; +import twilightforest.block.BlockTFHedge; +import twilightforest.block.BlockTFLog; +import twilightforest.block.TFBlocks; +import twilightforest.enums.HedgeVariant; +import twilightforest.enums.WoodVariant; + +public abstract class TFTreeGenerator extends WorldGenAbstractTree implements IBlockSettable { + + protected IBlockState treeState = TFBlocks.twilight_log.getDefaultState(); + protected IBlockState branchState = TFBlocks.twilight_log.getDefaultState().withProperty(BlockTFLog.LOG_AXIS, BlockLog.EnumAxis.NONE).withProperty(BlockTFLog.VARIANT, WoodVariant.DARK); + protected IBlockState leafState = TFBlocks.hedge.getDefaultState().withProperty(BlockTFHedge.VARIANT, HedgeVariant.DARKWOOD_LEAVES); + protected IBlockState rootState = TFBlocks.root.getDefaultState(); + + protected IPlantable source = TFBlocks.twilight_sapling; + + public TFTreeGenerator() { + this(false); + } + + public TFTreeGenerator(boolean notify) { + super(notify); + } + + @Override + public final void setBlockAndNotify(World world, BlockPos pos, IBlockState state) { + setBlockAndNotifyAdequately(world, pos, state); + } + + @Override + protected boolean canGrowInto(Block blockType) { + return TFGenHollowTree.canGrowInto(blockType); + } + + /** + * Build a root, but don't let it stick out too far into thin air because that's weird + */ + protected void buildRoot(World world, BlockPos pos, double offset, int b) { + BlockPos dest = TFGenerator.translate(pos.down(b + 2), 5, 0.3 * b + offset, 0.8); + + // go through block by block and stop drawing when we head too far into open air + BlockPos[] lineArray = TFGenerator.getBresehnamArrays(pos.down(), dest); + for (BlockPos coord : lineArray) { + this.placeRootBlock(world, coord, rootState); + } + } + + /** + * Function used to actually place root blocks if they're not going to break anything important + */ + protected void placeRootBlock(World world, BlockPos pos, IBlockState state) { + if (canRootGrowIn(world, pos)) { + this.setBlockAndNotifyAdequately(world, pos, state); + } + } + + public static boolean canRootGrowIn(World world, BlockPos pos) { + IBlockState blockState = world.getBlockState(pos); + Block blockID = blockState.getBlock(); + + if (blockID.isAir(blockState, world, pos)) { + // roots can grow through air if they are near a solid block + return TFGenerator.isNearSolid(world, pos); + } else { + return (blockState.getBlockHardness(world, pos) >= 0) + && blockID != TFBlocks.stronghold_shield + && blockID != TFBlocks.trophy_pedestal + && blockID != TFBlocks.boss_spawner + && (blockState.getMaterial() == Material.GRASS || blockState.getMaterial() == Material.GROUND || blockState.getMaterial() == Material.ROCK); + } + } + + /** + * Add a firefly at the specified height and angle. + * + * @param height how far up the tree + * @param angle from 0 - 1 rotation around the tree + */ + protected void addFirefly(World world, BlockPos pos, int height, double angle) { + int iAngle = (int) (angle * 4.0); + if (iAngle == 0) { + setIfEmpty(world, pos.add( 1, height, 0), TFBlocks.firefly.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.EAST)); + } else if (iAngle == 1) { + setIfEmpty(world, pos.add(-1, height, 0), TFBlocks.firefly.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.WEST)); + } else if (iAngle == 2) { + setIfEmpty(world, pos.add( 0, height, 1), TFBlocks.firefly.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.SOUTH)); + } else if (iAngle == 3) { + setIfEmpty(world, pos.add( 0, height, -1), TFBlocks.firefly.getDefaultState().withProperty(BlockDirectional.FACING, EnumFacing.NORTH)); + } + } + + private void setIfEmpty(World world, BlockPos pos, IBlockState state) { + if (world.isAirBlock(pos)) { + this.setBlockAndNotifyAdequately(world, pos, state); + } + } +} \ No newline at end of file diff --git a/src/main/java/twilightforest/world/layer/GenLayerTF.java b/src/main/java/twilightforest/world/layer/GenLayerTF.java deleted file mode 100644 index 768ba01f00..0000000000 --- a/src/main/java/twilightforest/world/layer/GenLayerTF.java +++ /dev/null @@ -1,74 +0,0 @@ -package twilightforest.world.layer; - -import net.minecraft.world.gen.layer.GenLayer; -import net.minecraft.world.gen.layer.GenLayerSmooth; -import net.minecraft.world.gen.layer.GenLayerVoronoiZoom; -import net.minecraft.world.gen.layer.GenLayerZoom; - -public abstract class GenLayerTF extends GenLayer { - - public GenLayerTF(long l) { - super(l); - // TODO Auto-generated constructor stub - } - - public static GenLayer[] makeTheWorld(long l) { - GenLayer biomes = new GenLayerTFBiomes1Point7(1L); - biomes = new GenLayerTFKeyBiomes(1000L, biomes); - biomes = new GenLayerTFCompanionBiomes(1000L, biomes); - - biomes = new GenLayerZoom(1000L, biomes); - biomes = new GenLayerZoom(1001, biomes); - - biomes = new GenLayerTFBiomeStabilize(700L, biomes); - - biomes = new GenLayerTFThornBorder(500L, biomes); - - biomes = new GenLayerZoom(1002, biomes); - biomes = new GenLayerZoom(1003, biomes); - biomes = new GenLayerZoom(1004, biomes); - biomes = new GenLayerZoom(1005, biomes); - - GenLayer riverLayer = new GenLayerTFStream(1L, biomes); - riverLayer = new GenLayerSmooth(7000L, riverLayer); - biomes = new GenLayerTFRiverMix(100L, biomes, riverLayer); - - // do "voronoi" zoom - GenLayer genlayervoronoizoom = new GenLayerVoronoiZoom(10L, biomes); - - biomes.initWorldGenSeed(l); - genlayervoronoizoom.initWorldGenSeed(l); - - return (new GenLayer[] { biomes, genlayervoronoizoom }); - } - - public static GenLayer[] makeTheWorldOldMapGen(long l) { - GenLayer biomes = new GenLayerTFBiomes(1L); - - biomes = new GenLayerZoom(1000L, biomes); - biomes = new GenLayerZoom(1001, biomes); - - biomes = new GenLayerTFBiomeStabilize(700L, biomes); - - biomes = new GenLayerZoom(1002, biomes); - - biomes = new GenLayerTFBiomeBorders(500L, biomes); - - biomes = new GenLayerZoom(1003, biomes); - biomes = new GenLayerZoom(1004, biomes); - biomes = new GenLayerZoom(1005, biomes); - - GenLayer riverLayer = new GenLayerTFStream(1L, biomes); - riverLayer = new GenLayerSmooth(7000L, riverLayer); - biomes = new GenLayerTFRiverMix(100L, biomes, riverLayer); - - // do "voronoi" zoom - GenLayer genlayervoronoizoom = new GenLayerVoronoiZoom(10L, biomes); - - biomes.initWorldGenSeed(l); - genlayervoronoizoom.initWorldGenSeed(l); - - return (new GenLayer[] { biomes, genlayervoronoizoom }); - } - -} diff --git a/src/main/java/twilightforest/world/layer/GenLayerTF5x5Preset.java b/src/main/java/twilightforest/world/layer/GenLayerTF5x5Preset.java index 87977edc9a..fef48a3b86 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTF5x5Preset.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTF5x5Preset.java @@ -1,36 +1,28 @@ package twilightforest.world.layer; - public class GenLayerTF5x5Preset extends GenLayerTF7x7Preset { - - - public GenLayerTF5x5Preset(long par1) { - super(par1); + + public GenLayerTF5x5Preset(long seed) { + super(seed); initPresets(); } - - - private void initPresets() - { - char[][] map = { - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, - { 'P', 'P', 'H', 'H', 'L', 'D', 'D', 'P', 'P' }, - { 'P', 'P', 'H', 'H', 'm', 'M', 'D', 'P', 'P' }, - { 'P', 'P', 'F', 'F', 'F', 'C', 'E', 'P', 'P' }, - { 'P', 'P', 'S', 'f', 'F', 'F', 'O', 'P', 'P' }, - { 'P', 'P', 'Y', 'S', 'F', 'O', 'G', 'P', 'P' }, - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' } }; - - for (int x = 0; x < map.length; x++) - { - for (int z = 0; z < map[x].length; z++) - { - preset[x][z] = getBiomeFor(map[z][x]); + private void initPresets() { + char[][] map = { + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, + {'P', 'P', 'H', 'H', 'L', 'D', 'D', 'P', 'P'}, + {'P', 'P', 'H', 'H', 'm', 'M', 'D', 'P', 'P'}, + {'P', 'P', 'F', 'F', 'F', 'C', 'E', 'P', 'P'}, + {'P', 'P', 'S', 'f', 'F', 'F', 'O', 'P', 'P'}, + {'P', 'P', 'Y', 'S', 'F', 'O', 'G', 'P', 'P'}, + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}}; + + for (int x = 0; x < map.length; x++) { + for (int z = 0; z < map[x].length; z++) { + preset[x][z] = map[z][x]; } } - } } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTF6x6Preset.java b/src/main/java/twilightforest/world/layer/GenLayerTF6x6Preset.java index 9713721ce6..7937619b10 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTF6x6Preset.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTF6x6Preset.java @@ -1,37 +1,28 @@ package twilightforest.world.layer; - public class GenLayerTF6x6Preset extends GenLayerTF7x7Preset { - - public GenLayerTF6x6Preset(long par1) { - super(par1); + + public GenLayerTF6x6Preset(long seed) { + super(seed); initPresets(); } - - private void initPresets() - { - char[][] map = { - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, - { 'P', 'P', 'H', 'H', 'H', 'D', 'D', 'D', 'P' }, - { 'P', 'P', 'H', 'H', 'H', 'M', 'D', 'D', 'P' }, - { 'P', 'P', 'F', 'F', 'C', 'm', 'm', 'D', 'P' }, - { 'P', 'P', 'f', 'f', 'F', 'E', 'F', 'O', 'P' }, - { 'P', 'P', 'S', 'S', 'f', 'f', 'O', 'G', 'P' }, - { 'P', 'P', 'Y', 'S', 'f', 'L', 'O', 'G', 'P' }, - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' } }; - - for (int x = 0; x < map.length; x++) - { - for (int z = 0; z < map[x].length; z++) - { - preset[x][z] = getBiomeFor(map[z][x]); + private void initPresets() { + char[][] map = { + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, + {'P', 'P', 'H', 'H', 'H', 'D', 'D', 'D', 'P'}, + {'P', 'P', 'H', 'H', 'H', 'M', 'D', 'D', 'P'}, + {'P', 'P', 'F', 'F', 'C', 'm', 'm', 'D', 'P'}, + {'P', 'P', 'f', 'f', 'F', 'E', 'F', 'O', 'P'}, + {'P', 'P', 'S', 'S', 'f', 'f', 'O', 'G', 'P'}, + {'P', 'P', 'Y', 'S', 'f', 'L', 'O', 'G', 'P'}, + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}}; + + for (int x = 0; x < map.length; x++) { + for (int z = 0; z < map[x].length; z++) { + preset[x][z] = map[z][x]; } } - } - - - } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTF7x7Preset.java b/src/main/java/twilightforest/world/layer/GenLayerTF7x7Preset.java index 1171a12ffc..8afb672de7 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTF7x7Preset.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTF7x7Preset.java @@ -1,107 +1,93 @@ package twilightforest.world.layer; -import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.init.Biomes; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; public class GenLayerTF7x7Preset extends GenLayer { - - - BiomeGenBase preset[][] = new BiomeGenBase[9][9]; - public GenLayerTF7x7Preset(long par1) { - super(par1); + char[][] preset = new char[9][9]; + + public GenLayerTF7x7Preset(long seed) { + super(seed); initPresets(); } - + @Override - public int[] getInts(int x, int z, int width, int depth) - { - int dest[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - int sx = x + dx + 4; - int sz = z + dz + 4; - - if (sx >= 0 && sx < 8 && sz >= 0 && sz < 8) - { - dest[dx + dz * width] = preset[sx][sz].biomeID; - } - else - { - dest[dx + dz * width] = BiomeGenBase.ocean.biomeID; - } - } + public int[] getInts(int x, int z, int width, int depth) { - } - - return dest; + int dest[] = IntCache.getIntCache(width * depth); - } + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { - private void initPresets() - { - char[][] map = { - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' }, - { 'P', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'P' }, - { 'P', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'P' }, - { 'P', 'F', 'f', 'F', 'm', 'M', 'D', 'D', 'P' }, - { 'P', 'F', 'F', 'F', 'C', 'm', 'D', 'D', 'P' }, - { 'P', 'F', 'f', 'f', 'F', 'E', 'O', 'O', 'P' }, - { 'P', 'S', 'S', 'S', 'L', 'L', 'O', 'G', 'P' }, - { 'P', 'Y', 'S', 'S', 'L', 'L', 'O', 'G', 'P' }, - { 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P' } }; + int sx = x + dx + 4; + int sz = z + dz + 4; - - for (int x = 0; x < map.length; x++) - { - for (int z = 0; z < map[x].length; z++) - { - preset[x][z] = getBiomeFor(map[z][x]); + if (sx >= 0 && sx < 8 && sz >= 0 && sz < 8) { + dest[dx + dz * width] = Biome.getIdForBiome(getBiomeFor(preset[sx][sz])); + } else { + dest[dx + dz * width] = Biome.getIdForBiome(Biomes.OCEAN); + } } } - + + return dest; } - protected BiomeGenBase getBiomeFor(char c) - { - switch (c) - { - default : - return BiomeGenBase.ocean; -// case 'P' : -// return BiomeGenBase.plains; - case 'F' : - return TFBiomeBase.twilightForest; - case 'f' : - return TFBiomeBase.twilightForest2; - case 'E' : - return TFBiomeBase.enchantedForest; - case 'm' : - return TFBiomeBase.mushrooms; - case 'M' : - return TFBiomeBase.deepMushrooms; - case 'C' : - return TFBiomeBase.clearing; - case 'S' : - return TFBiomeBase.tfSwamp; - case 'Y' : - return TFBiomeBase.fireSwamp; - case 'D' : - return TFBiomeBase.darkForest; - case 'L' : - return TFBiomeBase.tfLake; - case 'O' : - return TFBiomeBase.tfSnow; - case 'G' : - return TFBiomeBase.glacier; - case 'H' : - return TFBiomeBase.highlands; + private void initPresets() { + char[][] map = { + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}, + {'P', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'P'}, + {'P', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'P'}, + {'P', 'F', 'f', 'F', 'm', 'M', 'D', 'D', 'P'}, + {'P', 'F', 'F', 'F', 'C', 'm', 'D', 'D', 'P'}, + {'P', 'F', 'f', 'f', 'F', 'E', 'O', 'O', 'P'}, + {'P', 'S', 'S', 'S', 'L', 'L', 'O', 'G', 'P'}, + {'P', 'Y', 'S', 'S', 'L', 'L', 'O', 'G', 'P'}, + {'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'}}; + + for (int x = 0; x < map.length; x++) { + for (int z = 0; z < map[x].length; z++) { + preset[x][z] = map[z][x]; + } } } - + protected final Biome getBiomeFor(char c) { + switch (c) { + default: + return Biomes.OCEAN; +// case 'P' : +// return Biome.plains; + case 'F': + return TFBiomes.twilightForest; + case 'f': + return TFBiomes.denseTwilightForest; + case 'E': + return TFBiomes.enchantedForest; + case 'm': + return TFBiomes.mushrooms; + case 'M': + return TFBiomes.deepMushrooms; + case 'C': + return TFBiomes.clearing; + case 'S': + return TFBiomes.tfSwamp; + case 'Y': + return TFBiomes.fireSwamp; + case 'D': + return TFBiomes.darkForest; + case 'L': + return TFBiomes.tfLake; + case 'O': + return TFBiomes.snowy_forest; + case 'G': + return TFBiomes.glacier; + case 'H': + return TFBiomes.highlands; + } + } } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFBiomeBorders.java b/src/main/java/twilightforest/world/layer/GenLayerTFBiomeBorders.java index 9f54f070f8..6df2ccfbc5 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFBiomeBorders.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFBiomeBorders.java @@ -1,75 +1,73 @@ package twilightforest.world.layer; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; - +import twilightforest.biomes.TFBiomes; public class GenLayerTFBiomeBorders extends GenLayer { - public GenLayerTFBiomeBorders(long l, GenLayer genlayer) - { - super(l); - parent = genlayer; - } + public GenLayerTFBiomeBorders(long l, GenLayer genlayer) { + super(l); + parent = genlayer; + } - /** - * Turn specific biomes into other biomes along their borders - */ + /** + * Turn specific biomes into other biomes along their borders + */ @Override - public int[] getInts(int x, int z, int width, int depth) - { - int nx = x - 1; - int nz = z - 1; - int nwidth = width + 2; - int ndepth = depth + 2; - int input[] = parent.getInts(nx, nz, nwidth, ndepth); - int output[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - int right = input[dx + 0 + (dz + 1) * nwidth]; - int left = input[dx + 2 + (dz + 1) * nwidth]; - int up = input[dx + 1 + (dz + 0) * nwidth]; - int down = input[dx + 1 + (dz + 2) * nwidth]; - int center = input[dx + 1 + (dz + 1) * nwidth]; - if (onBorder(TFBiomeBase.tfLake.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.fireflyForest.biomeID; - } - else if (onBorder(TFBiomeBase.clearing.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.oakSavanna.biomeID; - } - else if (onBorder(TFBiomeBase.deepMushrooms.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.mushrooms.biomeID; - } - else if (onBorder(TFBiomeBase.glacier.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.tfSnow.biomeID; - } - else - { - output[dx + dz * width] = center; - } - } + public int[] getInts(int x, int z, int width, int depth) { + + int nx = x - 1; + int nz = z - 1; + int nwidth = width + 2; + int ndepth = depth + 2; + int input[] = parent.getInts(nx, nz, nwidth, ndepth); + int output[] = IntCache.getIntCache(width * depth); + + int lake = Biome.getIdForBiome(TFBiomes.tfLake); + int fireflyForest = Biome.getIdForBiome(TFBiomes.fireflyForest); + int clearing = Biome.getIdForBiome(TFBiomes.clearing); + int oakSavanna = Biome.getIdForBiome(TFBiomes.oakSavanna); + int deepMushrooms = Biome.getIdForBiome(TFBiomes.deepMushrooms); + int mushrooms = Biome.getIdForBiome(TFBiomes.mushrooms); + int glacier = Biome.getIdForBiome(TFBiomes.glacier); + int snowyForest = Biome.getIdForBiome(TFBiomes.snowy_forest); + + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { - } + int right = input[dx + 0 + (dz + 1) * nwidth]; + int left = input[dx + 2 + (dz + 1) * nwidth]; + int up = input[dx + 1 + (dz + 0) * nwidth]; + int down = input[dx + 1 + (dz + 2) * nwidth]; + int center = input[dx + 1 + (dz + 1) * nwidth]; + + if (onBorder(lake, center, right, left, up, down)) { + output[dx + dz * width] = fireflyForest; + } else if (onBorder(clearing, center, right, left, up, down)) { + output[dx + dz * width] = oakSavanna; + } else if (onBorder(deepMushrooms, center, right, left, up, down)) { + output[dx + dz * width] = mushrooms; + } else if (onBorder(glacier, center, right, left, up, down)) { + output[dx + dz * width] = snowyForest; + } else { + output[dx + dz * width] = center; + } + } + } + + return output; + } - return output; - } - /** * Returns true if the center biome is the specified biome and any of the surrounding biomes are not */ - boolean onBorder(int biome, int center, int right, int left, int up, int down) { - + private boolean onBorder(int biome, int center, int right, int left, int up, int down) { + if (center != biome) { return false; } - if (right != biome) { return true; } @@ -82,8 +80,7 @@ boolean onBorder(int biome, int center, int right, int left, int up, int down) { if (down != biome) { return true; } - + return false; } - } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFBiomeStabilize.java b/src/main/java/twilightforest/world/layer/GenLayerTFBiomeStabilize.java index fc6dfe19fc..27f426f772 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFBiomeStabilize.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFBiomeStabilize.java @@ -6,60 +6,51 @@ public class GenLayerTFBiomeStabilize extends GenLayer { - public GenLayerTFBiomeStabilize(long l, GenLayer genlayer) - { - super(l); - parent = genlayer; - } - - /** - * When we are near the center of each biome, make nearby areas that biome too - */ + public GenLayerTFBiomeStabilize(long l, GenLayer genlayer) { + super(l); + parent = genlayer; + } + + /** + * When we are near the center of each biome, make nearby areas that biome too + */ @Override - public int[] getInts(int x, int z, int width, int depth) - { - int nx = x - 1; - int nz = z - 1; - int nwidth = width + 2; - int ndepth = depth + 2; - int input[] = parent.getInts(nx, nz, nwidth, ndepth); - int output[] = IntCache.getIntCache(width * depth); - - - int offX = x & 3; - int offZ = z & 3; - - for (int dz = 0; dz < depth; dz++) - { - for (int dx = 0; dx < width; dx++) - { - int centerX = ((dx + offX + 1) & 0xFFFFFFFC) - offX; - int centerZ = ((dz + offZ + 1) & 0xFFFFFFFC) - offZ; - - //System.out.println("dx = " + dx + ", centerX = " + centerX + " dz = " + dz + ", centerZ = " + centerZ); - + public int[] getInts(int x, int z, int width, int depth) { + int nx = x - 1; + int nz = z - 1; + int nwidth = width + 2; + int ndepth = depth + 2; + int input[] = parent.getInts(nx, nz, nwidth, ndepth); + int output[] = IntCache.getIntCache(width * depth); + + + int offX = x & 3; + int offZ = z & 3; + + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { + int centerX = ((dx + offX + 1) & 0xFFFFFFFC) - offX; + int centerZ = ((dz + offZ + 1) & 0xFFFFFFFC) - offZ; + // if (dx == centerX && dz == centerZ) // { // output[dx + dz * width] = input[centerX + 1 + (centerZ + 1) * nwidth]; -//// output[dx + dz * width] = TFBiomeBase.glacier.biomeID; +//// output[dx + dz * width] = BiomeLibrary.glacier.biomeID; // } // else - if (dx <= centerX + 1 && dx >= centerX - 1 && dz <= centerZ + 1 && dz >= centerZ - 1) - { - output[dx + dz * width] = input[centerX + 1 + (centerZ + 1) * nwidth]; -// output[dx + dz * width] = BiomeGenBase.desert.biomeID; + if (dx <= centerX + 1 && dx >= centerX - 1 && dz <= centerZ + 1 && dz >= centerZ - 1) { + output[dx + dz * width] = input[centerX + 1 + (centerZ + 1) * nwidth]; +// output[dx + dz * width] = Biome.desert.biomeID; // output[dx + dz * width] = input[dx + 1 + (dz + 1) * nwidth]; - } - else - { - output[dx + dz * width] = input[dx + 1 + (dz + 1) * nwidth]; - } - } + } else { + output[dx + dz * width] = input[dx + 1 + (dz + 1) * nwidth]; + } + } + + } - } + return output; + } - return output; - } - } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFBiomes.java b/src/main/java/twilightforest/world/layer/GenLayerTFBiomes.java index f92cee2b22..f03073843c 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFBiomes.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFBiomes.java @@ -1,57 +1,65 @@ package twilightforest.world.layer; -import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; /** * Applies the twilight forest biomes to the map - * - * @author Ben * + * @author Ben */ -public class GenLayerTFBiomes extends GenLayer -{ +public class GenLayerTFBiomes extends GenLayer { + + private static final int RARE_BIOME_CHANCE = 15; - protected BiomeGenBase commonBiomes[] = (new BiomeGenBase[] { - TFBiomeBase.twilightForest, TFBiomeBase.twilightForest2, TFBiomeBase.highlands, TFBiomeBase.mushrooms, TFBiomeBase.tfSwamp, TFBiomeBase.clearing, TFBiomeBase.darkForest - }); - protected BiomeGenBase rareBiomes[] = (new BiomeGenBase[] { - TFBiomeBase.tfLake, TFBiomeBase.glacier, TFBiomeBase.deepMushrooms, TFBiomeBase.enchantedForest, TFBiomeBase.fireSwamp - }); + protected static final List> commonBiomes = Arrays.asList( + () -> TFBiomes.twilightForest, + () -> TFBiomes.denseTwilightForest, + () -> TFBiomes.mushrooms, + () -> TFBiomes.oakSavanna, + () -> TFBiomes.fireflyForest + ); + protected static final List> rareBiomes = Arrays.asList( + () -> TFBiomes.tfLake, + () -> TFBiomes.deepMushrooms, + () -> TFBiomes.enchantedForest, + () -> TFBiomes.clearing, + () -> TFBiomes.spookyForest + ); - public GenLayerTFBiomes(long l, GenLayer genlayer) - { - super(l); - parent = genlayer; - } + public GenLayerTFBiomes(long l, GenLayer genlayer) { + super(l); + parent = genlayer; + } - public GenLayerTFBiomes(long l) { + public GenLayerTFBiomes(long l) { super(l); } - public int[] getInts(int x, int z, int width, int depth) - { - int dest[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - initChunkSeed(dx + x, dz + z); - if (nextInt(15) == 0 ) { - // make rare biome - dest[dx + dz * width] = rareBiomes[nextInt(rareBiomes.length)].biomeID; - } - else { - // make common biome - dest[dx + dz * width] = commonBiomes[nextInt(commonBiomes.length)].biomeID; - } - } + @Override + public int[] getInts(int x, int z, int width, int depth) { + + int dest[] = IntCache.getIntCache(width * depth); + + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { + initChunkSeed(dx + x, dz + z); + if (nextInt(RARE_BIOME_CHANCE) == 0) { + // make rare biome + dest[dx + dz * width] = Biome.getIdForBiome(getRandomBiome(rareBiomes)); + } else { + // make common biome + dest[dx + dz * width] = Biome.getIdForBiome(getRandomBiome(commonBiomes)); + } + } + } - } - // for (int i = 0; i < width * depth; i++) // { // if (dest[i] < 0 || dest[i] > TFBiomeBase.fireSwamp.biomeID) @@ -60,6 +68,10 @@ public int[] getInts(int x, int z, int width, int depth) // } // } - return dest; - } + return dest; + } + + private Biome getRandomBiome(List> biomes) { + return biomes.get(nextInt(biomes.size())).get(); + } } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFBiomes1Point7.java b/src/main/java/twilightforest/world/layer/GenLayerTFBiomes1Point7.java deleted file mode 100644 index 7144be2730..0000000000 --- a/src/main/java/twilightforest/world/layer/GenLayerTFBiomes1Point7.java +++ /dev/null @@ -1,67 +0,0 @@ -package twilightforest.world.layer; - -import net.minecraft.world.biome.BiomeGenBase; -import net.minecraft.world.gen.layer.GenLayer; -import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; - - -/** - * Applies the twilight forest biomes to the map - * - * @author Ben - * - */ -public class GenLayerTFBiomes1Point7 extends GenLayer -{ - - private static final int RARE_BIOME_CHANCE = 15; - protected BiomeGenBase commonBiomes[] = (new BiomeGenBase[] { - TFBiomeBase.twilightForest, TFBiomeBase.twilightForest2, TFBiomeBase.mushrooms, TFBiomeBase.oakSavanna, TFBiomeBase.fireflyForest - }); - protected BiomeGenBase rareBiomes[] = (new BiomeGenBase[] { - TFBiomeBase.tfLake, TFBiomeBase.deepMushrooms, TFBiomeBase.enchantedForest, TFBiomeBase.clearing - }); - - public GenLayerTFBiomes1Point7(long l, GenLayer genlayer) - { - super(l); - parent = genlayer; - } - - public GenLayerTFBiomes1Point7(long l) { - super(l); - } - - @Override - public int[] getInts(int x, int z, int width, int depth) - { - int dest[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - initChunkSeed(dx + x, dz + z); - if (nextInt(RARE_BIOME_CHANCE) == 0 ) { - // make rare biome - dest[dx + dz * width] = rareBiomes[nextInt(rareBiomes.length)].biomeID; - } - else { - // make common biome - dest[dx + dz * width] = commonBiomes[nextInt(commonBiomes.length)].biomeID; - } - } - - } - -// for (int i = 0; i < width * depth; i++) -// { -// if (dest[i] < 0 || dest[i] > TFBiomeBase.fireSwamp.biomeID) -// { -// System.err.printf("Made a bad ID, %d at %d, %d while generating\n", dest[i], x, z); -// } -// } - - return dest; - } -} diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFCheckBad.java b/src/main/java/twilightforest/world/layer/GenLayerTFCheckBad.java deleted file mode 100644 index b34ea732e2..0000000000 --- a/src/main/java/twilightforest/world/layer/GenLayerTFCheckBad.java +++ /dev/null @@ -1,36 +0,0 @@ -package twilightforest.world.layer; - -import net.minecraft.world.gen.layer.GenLayer; -import twilightforest.biomes.TFBiomeBase; - -public class GenLayerTFCheckBad extends GenLayer { - - private String stage; - - public GenLayerTFCheckBad(long par1, GenLayer par3GenLayer, String stage) - { - super(par1); - super.parent = par3GenLayer; - - this.stage = stage; - } - - @Override - public int[] getInts(int x, int z, int width, int depth) - { - int input[] = parent.getInts(x, z, width, depth); - - - for (int i = 0; i < width * depth; i++) - { - if (input[i] < 0 || input[i] > TFBiomeBase.fireSwamp.biomeID) - { - System.err.printf("Got a bad ID, %d at %d, %d while checking during stage %s\n", input[i], x, z, this.stage); - } - } - - - return input; - } - -} diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFCompanionBiomes.java b/src/main/java/twilightforest/world/layer/GenLayerTFCompanionBiomes.java index 4536a04275..9fccaf4862 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFCompanionBiomes.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFCompanionBiomes.java @@ -1,72 +1,70 @@ package twilightforest.world.layer; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; - +import twilightforest.biomes.TFBiomes; public class GenLayerTFCompanionBiomes extends GenLayer { - public GenLayerTFCompanionBiomes(long l, GenLayer genlayer) - { - super(l); - parent = genlayer; - } + public GenLayerTFCompanionBiomes(long l, GenLayer genlayer) { + super(l); + parent = genlayer; + } - /** - * If we are next to one of the 4 "key" biomes, we randomly turn into a companion biome for that center biome - */ + /** + * If we are next to one of the 4 "key" biomes, we randomly turn into a companion biome for that center biome + */ @Override - public int[] getInts(int x, int z, int width, int depth) - { - int nx = x - 1; - int nz = z - 1; - int nwidth = width + 2; - int ndepth = depth + 2; - int input[] = parent.getInts(nx, nz, nwidth, ndepth); - int output[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - int right = input[dx + 0 + (dz + 1) * nwidth]; - int left = input[dx + 2 + (dz + 1) * nwidth]; - int up = input[dx + 1 + (dz + 0) * nwidth]; - int down = input[dx + 1 + (dz + 2) * nwidth]; - int center = input[dx + 1 + (dz + 1) * nwidth]; - if (isKey(TFBiomeBase.fireSwamp.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.tfSwamp.biomeID; - } - else if (isKey(TFBiomeBase.glacier.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.tfSnow.biomeID; - } - else if (isKey(TFBiomeBase.darkForestCenter.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.darkForest.biomeID; - } - else if (isKey(TFBiomeBase.highlandsCenter.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.highlands.biomeID; - } - else - { - output[dx + dz * width] = center; - } - } + public int[] getInts(int x, int z, int width, int depth) { + + int nx = x - 1; + int nz = z - 1; + int nwidth = width + 2; + int ndepth = depth + 2; + int input[] = parent.getInts(nx, nz, nwidth, ndepth); + int output[] = IntCache.getIntCache(width * depth); + + int fireSwamp = Biome.getIdForBiome(TFBiomes.fireSwamp); + int swamp = Biome.getIdForBiome(TFBiomes.tfSwamp); + int glacier = Biome.getIdForBiome(TFBiomes.glacier); + int snowyForest = Biome.getIdForBiome(TFBiomes.snowy_forest); + int darkForestCenter = Biome.getIdForBiome(TFBiomes.darkForestCenter); + int darkForest = Biome.getIdForBiome(TFBiomes.darkForest); + int highlandsCenter = Biome.getIdForBiome(TFBiomes.highlandsCenter); + int highlands = Biome.getIdForBiome(TFBiomes.highlands); - } + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { + + int right = input[dx + 0 + (dz + 1) * nwidth]; + int left = input[dx + 2 + (dz + 1) * nwidth]; + int up = input[dx + 1 + (dz + 0) * nwidth]; + int down = input[dx + 1 + (dz + 2) * nwidth]; + int center = input[dx + 1 + (dz + 1) * nwidth]; + + if (isKey(fireSwamp, center, right, left, up, down)) { + output[dx + dz * width] = swamp; + } else if (isKey(glacier, center, right, left, up, down)) { + output[dx + dz * width] = snowyForest; + } else if (isKey(darkForestCenter, center, right, left, up, down)) { + output[dx + dz * width] = darkForest; + } else if (isKey(highlandsCenter, center, right, left, up, down)) { + output[dx + dz * width] = highlands; + } else { + output[dx + dz * width] = center; + } + } + } + + return output; + } - return output; - } - /** * Returns true if any of the surrounding biomes is the specified biome */ boolean isKey(int biome, int center, int right, int left, int up, int down) { - + return center != biome && (right == biome || left == biome || up == biome || down == biome); } - } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFFeatureZoom.java b/src/main/java/twilightforest/world/layer/GenLayerTFFeatureZoom.java deleted file mode 100644 index 0b78c71fd8..0000000000 --- a/src/main/java/twilightforest/world/layer/GenLayerTFFeatureZoom.java +++ /dev/null @@ -1,56 +0,0 @@ -package twilightforest.world.layer; - -import net.minecraft.world.gen.layer.GenLayer; -import net.minecraft.world.gen.layer.IntCache; - - -public class GenLayerTFFeatureZoom extends GenLayer -{ - - public GenLayerTFFeatureZoom(long l, GenLayer genlayer) - { - super(l); - this.parent = genlayer; - } - - public int[] getInts(int x, int z, int width, int depth) - { - int sx = x >> 1; - int sz = z >> 1; - int swidth = (width >> 1) + 3; - int sdepth = (depth >> 1) + 3; - int src[] = parent.getInts(sx, sz, swidth, sdepth); - int dest[] = IntCache.getIntCache(swidth * 2 * (sdepth * 2)); - int doubleWidth = swidth << 1; - for (int dz = 0; dz < sdepth - 1; dz++) - { - for (int dx = 0; dx < swidth - 1; dx++) - { - dest[(dx * 2 + 0) + (dz * 2 + 0) * doubleWidth] = src[dx + (dz * swidth)]; - dest[(dx * 2 + 1) + (dz * 2 + 0) * doubleWidth] = 0; - dest[(dx * 2 + 0) + (dz * 2 + 1) * doubleWidth] = 0; - dest[(dx * 2 + 1) + (dz * 2 + 1) * doubleWidth] = 0; - } - } - - int output[] = IntCache.getIntCache(width * depth); - for (int copyZ = 0; copyZ < depth; copyZ++) - { - System.arraycopy(dest, (copyZ + (z & 1)) * (swidth << 1) + (x & 1), output, copyZ * width, width); - } - - return output; - } - - - public static GenLayer multipleZoom(long seed, GenLayer genlayer, int loops) - { - GenLayer layer = genlayer; - for (int i = 0; i < loops; i++) - { - layer = new GenLayerTFFeatureZoom(seed + (long)i, layer); - } - - return layer; - } -} diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFKeyBiomes.java b/src/main/java/twilightforest/world/layer/GenLayerTFKeyBiomes.java index 6b914558fa..6e4ad11c60 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFKeyBiomes.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFKeyBiomes.java @@ -1,104 +1,88 @@ package twilightforest.world.layer; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; /** * Puts key biomes in the proper positions - * - * @author Ben * + * @author Ben */ -public class GenLayerTFKeyBiomes extends GenLayer -{ +public class GenLayerTFKeyBiomes extends GenLayer { - public GenLayerTFKeyBiomes(long l, GenLayer genlayer) - { - super(l); - parent = genlayer; - } + public GenLayerTFKeyBiomes(long l, GenLayer genlayer) { + super(l); + parent = genlayer; + } - public GenLayerTFKeyBiomes(long l) { + public GenLayerTFKeyBiomes(long l) { super(l); } - public int[] getInts(int x, int z, int width, int depth) - { - int src[] = this.parent.getInts(x, z, width, depth); - int dest[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - // get offsets - initChunkSeed(((dx + x) | 3), ((dz + z) | 3)); - - int ox = this.nextInt(3) + 1; - int oz = this.nextInt(3) + 1; + @Override + public int[] getInts(int x, int z, int width, int depth) { + int src[] = this.parent.getInts(x, z, width, depth); + int dest[] = IntCache.getIntCache(width * depth); + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { + // get offsets + initChunkSeed(((dx + x) | 3), ((dz + z) | 3)); + + int ox = this.nextInt(3) + 1; + int oz = this.nextInt(3) + 1; + + if (((dx + x) & 3) == ox && ((dz + z) & 3) == oz) { + // determine which of the 4 + if (((dx + x) & 4) == 0) { + if (((dz + z) & 4) == 0) { + dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 0); + } else { + dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 1); + } + } else { + if (((dz + z) & 4) == 0) { + dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 2); + } else { + dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 3); + } + } + + } else { + dest[dx + dz * width] = src[dx + dz * width]; + } + } + } - if (((dx + x) & 3) == ox && ((dz + z) & 3) == oz) - { - // determine which of the 4 - if (((dx + x) & 4) == 0) - { - if (((dz + z) & 4) == 0) - { - dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 0); - } - else - { - dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 1); - } - } - else - { - if (((dz + z) & 4) == 0) - { - dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 2); - } - else - { - dest[dx + dz * width] = getKeyBiomeFor(dx + x, dz + z, 3); - } - } - - } - else - { - dest[dx + dz * width] = src[dx + dz * width]; - } - } - } + return dest; + } - return dest; - } - /** * Determine which map "region" the specified points are in. Assign the 0-3 of the index to the key biomes based on that region. */ private int getKeyBiomeFor(int mapX, int mapZ, int index) { - + int regionX = (mapX + 4) >> 3; - int regionZ = (mapZ + 4) >> 3; - - this.initChunkSeed(regionX, regionZ); - int offset = this.nextInt(4); - - // do we need to shuffle this better? - // the current version just "rotates" the 4 key biomes + int regionZ = (mapZ + 4) >> 3; + + this.initChunkSeed(regionX, regionZ); + int offset = this.nextInt(4); + + // do we need to shuffle this better? + // the current version just "rotates" the 4 key biomes switch ((index + offset) % 4) { - case 0: - default: - return TFBiomeBase.glacier.biomeID; - case 1: - return TFBiomeBase.fireSwamp.biomeID; - case 2: - return TFBiomeBase.darkForestCenter.biomeID; - case 3: - return TFBiomeBase.highlandsCenter.biomeID; + case 0: + default: + return Biome.getIdForBiome(TFBiomes.glacier); + case 1: + return Biome.getIdForBiome(TFBiomes.fireSwamp); + case 2: + return Biome.getIdForBiome(TFBiomes.darkForestCenter); + case 3: + return Biome.getIdForBiome(TFBiomes.highlandsCenter); } } } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFRiverMix.java b/src/main/java/twilightforest/world/layer/GenLayerTFRiverMix.java index 168bfd01f1..f76f94003f 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFRiverMix.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFRiverMix.java @@ -1,43 +1,48 @@ package twilightforest.world.layer; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; public class GenLayerTFRiverMix extends GenLayer { - private GenLayer biomeLayer; + private GenLayer biomeLayer; private GenLayer riverLayer; - public GenLayerTFRiverMix(long par1, GenLayer par3GenLayer, GenLayer par4GenLayer) { - super(par1); - this.biomeLayer = par3GenLayer; - this.riverLayer = par4GenLayer; - } - - /** - * Initialize layer's local worldGenSeed based on its own baseSeed and the world's global seed (passed in as an - * argument). - */ - public void initWorldGenSeed(long par1) - { - this.biomeLayer.initWorldGenSeed(par1); - this.riverLayer.initWorldGenSeed(par1); - super.initWorldGenSeed(par1); - } + public GenLayerTFRiverMix(long seed, GenLayer biomeLayer, GenLayer riverLayer) { + super(seed); + this.biomeLayer = biomeLayer; + this.riverLayer = riverLayer; + } + + /** + * Initialize layer's local worldGenSeed based on its own baseSeed and the world's global seed (passed in as an + * argument). + */ + @Override + public void initWorldGenSeed(long seed) { + this.biomeLayer.initWorldGenSeed(seed); + this.riverLayer.initWorldGenSeed(seed); + super.initWorldGenSeed(seed); + } /** * Returns a list of integer values generated by this layer. These may be * interpreted as temperatures, rainfall amounts, or biomeList[] indices * based on the particular GenLayer subclass. */ - public int[] getInts(int par1, int par2, int par3, int par4) { - int[] biomeInputs = this.biomeLayer.getInts(par1, par2, par3, par4); - int[] riverInputs = this.riverLayer.getInts(par1, par2, par3, par4); - int[] outputs = IntCache.getIntCache(par3 * par4); + @Override + public int[] getInts(int x, int z, int width, int depth) { + + int[] biomeInputs = this.biomeLayer.getInts(x, z, width, depth); + int[] riverInputs = this.riverLayer.getInts(x, z, width, depth); + int[] outputs = IntCache.getIntCache(width * depth); - for (int i = 0; i < par3 * par4; ++i) { - if (riverInputs[i] == TFBiomeBase.stream.biomeID) { + int stream = Biome.getIdForBiome(TFBiomes.stream); + + for (int i = 0; i < width * depth; ++i) { + if (riverInputs[i] == stream) { outputs[i] = riverInputs[i] & 255; } else { outputs[i] = biomeInputs[i]; @@ -46,5 +51,4 @@ public int[] getInts(int par1, int par2, int par3, int par4) { return outputs; } - } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFStream.java b/src/main/java/twilightforest/world/layer/GenLayerTFStream.java index 6b17da0c50..1e9269baf3 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFStream.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFStream.java @@ -1,141 +1,130 @@ -// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. -// Jad home page: http://www.kpdus.com/jad.html -// Decompiler options: packimports(3) braces deadcode - package twilightforest.world.layer; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; +import twilightforest.biomes.TFBiomes; + +public class GenLayerTFStream extends GenLayer { + public GenLayerTFStream(long l, GenLayer genlayer) { + super(l); + super.parent = genlayer; + } + @Override + public int[] getInts(int x, int z, int width, int depth) { -// Referenced classes of package net.minecraft.src: -// GenLayer, IntCache, BiomeGenBase + int nx = x - 1; + int nz = z - 1; + int nwidth = width + 2; + int ndepth = depth + 2; + int input[] = parent.getInts(nx, nz, nwidth, ndepth); + int output[] = IntCache.getIntCache(width * depth); -public class GenLayerTFStream extends GenLayer -{ + int stream = Biome.getIdForBiome(TFBiomes.stream); - public GenLayerTFStream(long l, GenLayer genlayer) - { - super(l); - super.parent = genlayer; - } + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { - public int[] getInts(int x, int z, int width, int depth) - { - int nx = x - 1; - int nz = z - 1; - int nwidth = width + 2; - int ndepth = depth + 2; - int input[] = parent.getInts(nx, nz, nwidth, ndepth); - int output[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - int left = input[dx + 0 + (dz + 1) * nwidth]; - int right = input[dx + 2 + (dz + 1) * nwidth]; - int down = input[dx + 1 + (dz + 0) * nwidth]; - int up = input[dx + 1 + (dz + 2) * nwidth]; - int mid = input[dx + 1 + (dz + 1) * nwidth]; + int left = input[dx + 0 + (dz + 1) * nwidth]; + int right = input[dx + 2 + (dz + 1) * nwidth]; + int down = input[dx + 1 + (dz + 0) * nwidth]; + int up = input[dx + 1 + (dz + 2) * nwidth]; + int mid = input[dx + 1 + (dz + 1) * nwidth]; // if(mid == 0 || left == 0 || right == 0 || down == 0 || up == 0) // { -// output[dx + dz * width] = TFBiomeBase.stream.biomeID; +// output[dx + dz * width] = Biome.getIdForBiome(BiomeLibrary.stream); // continue; // } - if(shouldStream(mid, left, down, right, up)) - { - output[dx + dz * width] = TFBiomeBase.stream.biomeID; - } else - { - output[dx + dz * width] = -1; - } - } + if (shouldStream(mid, left, down, right, up)) { + output[dx + dz * width] = stream; + } else { + output[dx + dz * width] = -1; + } + } + } + + return output; + } + + boolean shouldStream(int mid, int left, int down, int right, int up) { + if (shouldStream(mid, left)) { + return true; + } else if (shouldStream(mid, right)) { + return true; + } else if (shouldStream(mid, down)) { + return true; + } else if (shouldStream(mid, up)) { + return true; + } else { + return false; + } + } + + boolean shouldStream(int id1, int id2) { + + if (id1 == id2) { + return false; + } + if (id1 == -id2) { + return false; + } - } + Biome biome1 = Biome.getBiomeForId(id1); + Biome biome2 = Biome.getBiomeForId(id2); - return output; - } - - boolean shouldStream (int mid, int left, int down, int right, int up) { - if (shouldStream(mid, left)) { - return true; - } - else if (shouldStream(mid, right)) { - return true; - } - else if (shouldStream(mid, down)) { - return true; - } - else if (shouldStream(mid, up)) { - return true; - } - else { - return false; - } - } - - boolean shouldStream (int biome1, int biome2) { - if (biome1 == biome2) { - return false; - } - if (biome1 == -biome2) { - return false; - } - // glacier and snow have no border - if (biome1 == TFBiomeBase.glacier.biomeID && biome2 == TFBiomeBase.tfSnow.biomeID) { - return false; - } - if (biome1 == TFBiomeBase.tfSnow.biomeID && biome2 == TFBiomeBase.glacier.biomeID) { - return false; - } - // mushrooms - if (biome1 == TFBiomeBase.deepMushrooms.biomeID && biome2 == TFBiomeBase.mushrooms.biomeID) { - return false; - } - if (biome1 == TFBiomeBase.mushrooms.biomeID && biome2 == TFBiomeBase.deepMushrooms.biomeID) { - return false; - } - // fire swamp - if (biome1 == TFBiomeBase.tfSwamp.biomeID && biome2 == TFBiomeBase.fireSwamp.biomeID) { - return false; - } - if (biome1 == TFBiomeBase.fireSwamp.biomeID && biome2 == TFBiomeBase.tfSwamp.biomeID) { - return false; - } - // highlands - if (biome1 == TFBiomeBase.highlands.biomeID && biome2 == TFBiomeBase.highlandsCenter.biomeID) { - return false; - } - if (biome1 == TFBiomeBase.highlandsCenter.biomeID && biome2 == TFBiomeBase.highlands.biomeID) { - return false; - } - // dark forest - if (biome1 == TFBiomeBase.darkForest.biomeID && biome2 == TFBiomeBase.darkForestCenter.biomeID) { - return false; - } - if (biome1 == TFBiomeBase.darkForestCenter.biomeID && biome2 == TFBiomeBase.darkForest.biomeID) { - return false; - } - // no lake border - if (biome1 == TFBiomeBase.tfLake.biomeID || biome2 == TFBiomeBase.tfLake.biomeID) { - return false; - } - // clearing - if (biome1 == TFBiomeBase.clearing.biomeID || biome2 == TFBiomeBase.oakSavanna.biomeID) { - return false; - } - if (biome1 == TFBiomeBase.oakSavanna.biomeID || biome2 == TFBiomeBase.clearing.biomeID) { - return false; - } - // thorns need no stream - if (biome1 == TFBiomeBase.thornlands.biomeID || biome2 == TFBiomeBase.thornlands.biomeID) { - return false; - } + // glacier and snow have no border + if (biome1 == TFBiomes.glacier && biome2 == TFBiomes.snowy_forest) { + return false; + } + if (biome1 == TFBiomes.snowy_forest && biome2 == TFBiomes.glacier) { + return false; + } + // mushrooms + if (biome1 == TFBiomes.deepMushrooms && biome2 == TFBiomes.mushrooms) { + return false; + } + if (biome1 == TFBiomes.mushrooms && biome2 == TFBiomes.deepMushrooms) { + return false; + } + // fire swamp + if (biome1 == TFBiomes.tfSwamp && biome2 == TFBiomes.fireSwamp) { + return false; + } + if (biome1 == TFBiomes.fireSwamp && biome2 == TFBiomes.tfSwamp) { + return false; + } + // highlands + if (biome1 == TFBiomes.highlands && biome2 == TFBiomes.highlandsCenter) { + return false; + } + if (biome1 == TFBiomes.highlandsCenter && biome2 == TFBiomes.highlands) { + return false; + } + // dark forest + if (biome1 == TFBiomes.darkForest && biome2 == TFBiomes.darkForestCenter) { + return false; + } + if (biome1 == TFBiomes.darkForestCenter && biome2 == TFBiomes.darkForest) { + return false; + } + // no lake border + if (biome1 == TFBiomes.tfLake || biome2 == TFBiomes.tfLake) { + return false; + } + // clearing + if (biome1 == TFBiomes.clearing || biome2 == TFBiomes.oakSavanna) { + return false; + } + if (biome1 == TFBiomes.oakSavanna || biome2 == TFBiomes.clearing) { + return false; + } + // thorns need no stream + if (biome1 == TFBiomes.thornlands || biome2 == TFBiomes.thornlands) { + return false; + } - - return true; - } - + return true; + } } diff --git a/src/main/java/twilightforest/world/layer/GenLayerTFThornBorder.java b/src/main/java/twilightforest/world/layer/GenLayerTFThornBorder.java index 179fd65c87..c48087a27d 100644 --- a/src/main/java/twilightforest/world/layer/GenLayerTFThornBorder.java +++ b/src/main/java/twilightforest/world/layer/GenLayerTFThornBorder.java @@ -1,71 +1,69 @@ package twilightforest.world.layer; +import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.IntCache; -import twilightforest.biomes.TFBiomeBase; - +import twilightforest.biomes.TFBiomes; public class GenLayerTFThornBorder extends GenLayer { - public GenLayerTFThornBorder(long l, GenLayer genlayer) - { - super(l); - parent = genlayer; - } + public GenLayerTFThornBorder(long l, GenLayer genlayer) { + super(l); + parent = genlayer; + } - /** - * Turn specific biomes into other biomes along their borders - */ + /** + * Turn specific biomes into other biomes along their borders + */ @Override - public int[] getInts(int x, int z, int width, int depth) - { - int nx = x - 1; - int nz = z - 1; - int nwidth = width + 2; - int ndepth = depth + 2; - int input[] = parent.getInts(nx, nz, nwidth, ndepth); - int output[] = IntCache.getIntCache(width * depth); - for(int dz = 0; dz < depth; dz++) - { - for(int dx = 0; dx < width; dx++) - { - int right = input[dx + 0 + (dz + 1) * nwidth]; - int left = input[dx + 2 + (dz + 1) * nwidth]; - int up = input[dx + 1 + (dz + 0) * nwidth]; - int down = input[dx + 1 + (dz + 2) * nwidth]; - int center = input[dx + 1 + (dz + 1) * nwidth]; - // thorn border requires also checking diagonally - int ur = input[dx + 0 + (dz + 0) * nwidth]; - int ul = input[dx + 2 + (dz + 0) * nwidth]; - int dr = input[dx + 0 + (dz + 2) * nwidth]; - int dl = input[dx + 2 + (dz + 2) * nwidth]; - if (onBorder(TFBiomeBase.highlandsCenter.biomeID, center, right, left, up, down)) - { - output[dx + dz * width] = TFBiomeBase.thornlands.biomeID; - } - else if (onBorder(TFBiomeBase.highlandsCenter.biomeID, center, ur, ul, dr, dl)) - { - output[dx + dz * width] = TFBiomeBase.thornlands.biomeID; - } - else - { - output[dx + dz * width] = center; - } - } - - } - - return output; - } - + public int[] getInts(int x, int z, int width, int depth) { + + int nx = x - 1; + int nz = z - 1; + int nwidth = width + 2; + int ndepth = depth + 2; + int input[] = parent.getInts(nx, nz, nwidth, ndepth); + int output[] = IntCache.getIntCache(width * depth); + + int highlandsCenter = Biome.getIdForBiome(TFBiomes.highlandsCenter); + int thornlands = Biome.getIdForBiome(TFBiomes.thornlands); + + for (int dz = 0; dz < depth; dz++) { + for (int dx = 0; dx < width; dx++) { + + int right = input[dx + 0 + (dz + 1) * nwidth]; + int left = input[dx + 2 + (dz + 1) * nwidth]; + int up = input[dx + 1 + (dz + 0) * nwidth]; + int down = input[dx + 1 + (dz + 2) * nwidth]; + int center = input[dx + 1 + (dz + 1) * nwidth]; + + // thorn border requires also checking diagonally + int ur = input[dx + 0 + (dz + 0) * nwidth]; + int ul = input[dx + 2 + (dz + 0) * nwidth]; + int dr = input[dx + 0 + (dz + 2) * nwidth]; + int dl = input[dx + 2 + (dz + 2) * nwidth]; + + if (onBorder(highlandsCenter, center, right, left, up, down)) { + output[dx + dz * width] = thornlands; + } else if (onBorder(highlandsCenter, center, ur, ul, dr, dl)) { + output[dx + dz * width] = thornlands; + } else { + output[dx + dz * width] = center; + } + } + } + + return output; + } + /** * Returns true if the center biome is the first specified biome and any of the surrounding biomes are the second bioms */ private boolean onBorder(int biomeID, int biomeID2, int center, int right, int left, int up, int down) { + if (center != biomeID) { return false; } - if (right == biomeID2) { return true; } @@ -78,15 +76,15 @@ private boolean onBorder(int biomeID, int biomeID2, int center, int right, int l if (down == biomeID2) { return true; } - + return false; } /** * Returns true if the center biome is not the specified biome and any of the surrounding biomes are the specified biomes */ - private boolean onBorder(int biomeID, int center, int right, int left, - int up, int down) { + private boolean onBorder(int biomeID, int center, int right, int left, int up, int down) { + if (center == biomeID) { return false; } else if (right == biomeID) { @@ -101,5 +99,4 @@ private boolean onBorder(int biomeID, int center, int right, int left, return false; } } - } diff --git a/src/main/java/twilightforest/world/package-info.java b/src/main/java/twilightforest/world/package-info.java new file mode 100644 index 0000000000..0c118c780d --- /dev/null +++ b/src/main/java/twilightforest/world/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package twilightforest.world; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/resources/META-INF/tf_at.cfg b/src/main/resources/META-INF/tf_at.cfg new file mode 100644 index 0000000000..fafaabeb7b --- /dev/null +++ b/src/main/resources/META-INF/tf_at.cfg @@ -0,0 +1,48 @@ +# Comment each AT with where it needed to be used + +# EntityTFTowerGhast +public net.minecraft.entity.monster.EntityGhast$AILookAround + +# TileEntityTFCinderFurnace +protected net.minecraft.tileentity.TileEntityFurnace * + +# EntityTFFallingIce +protected net.minecraft.entity.item.EntityFallingBlock field_145809_g # hurtEntities +protected net.minecraft.entity.item.EntityFallingBlock field_145815_h # fallHurtMax +protected net.minecraft.entity.item.EntityFallingBlock field_145816_i # fallHurtAmount + +# EntityTFHydraMortar and other projectiles +public net.minecraft.entity.projectile.EntityThrowable field_70192_c # thrower + +# TFSkyRenderer +public net.minecraft.client.renderer.RenderGlobal field_72771_w # glSkyList +public net.minecraft.client.renderer.RenderGlobal field_72781_x # glSkyList2 +public net.minecraft.client.renderer.RenderGlobal field_175012_t # skyVBO +public net.minecraft.client.renderer.RenderGlobal field_175011_u # sky2VBO + +# ShaderManager +public net.minecraft.client.renderer.OpenGlHelper field_153214_y # arbShaders + +# StructureTFComponent +protected net.minecraft.world.gen.structure.StructureComponent field_186169_c # rotation +protected net.minecraft.world.gen.structure.StructureComponent field_186168_b # mirror +protected net.minecraft.world.gen.structure.StructureComponent field_74885_f # coordBaseMode + +# TFBiomeProvider +protected net.minecraft.world.biome.BiomeProvider field_76944_d # genBiomes +protected net.minecraft.world.biome.BiomeProvider field_76945_e # biomeIndexLayer + +# MapGenTFMajorFeature +protected net.minecraft.world.gen.structure.MapGenStructure field_143029_e # structureData + +# TFClientProxy +public net.minecraft.client.multiplayer.ClientAdvancementManager field_192803_d # advancementToProgress + +# TextureAtlasSprite +public net.minecraft.client.renderer.texture.TextureAtlasSprite field_110982_k # animationMetadata + +# TFEventListener +public net.minecraft.entity.EntityLivingBase func_184583_d(Lnet/minecraft/util/DamageSource;)Z # canBlockDamageSource + +# EntityTFBighorn +protected net.minecraft.entity.passive.EntitySheep func_175511_a(Lnet/minecraft/entity/passive/EntityAnimal;Lnet/minecraft/entity/passive/EntityAnimal;)Lnet/minecraft/item/EnumDyeColor; # getDyeColorMixFromParents diff --git a/src/main/resources/assets/tconstruct/textures/items/arrow/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/arrow/head_fierymetal.png new file mode 100644 index 0000000000..77f5308a00 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/arrow/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/arrow/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/arrow/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/arrow/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/arrow/shaft_broken_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/arrow/shaft_broken_fierymetal.png new file mode 100644 index 0000000000..12e2b77556 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/arrow/shaft_broken_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/arrow/shaft_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/arrow/shaft_fierymetal.png new file mode 100644 index 0000000000..5d50d1f077 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/arrow/shaft_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/battlesign/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/battlesign/broken_head_fierymetal.png new file mode 100644 index 0000000000..1e17ad2ad3 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/battlesign/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/battlesign/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/battlesign/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/battlesign/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/battlesign/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/battlesign/handle_fierymetal.png new file mode 100644 index 0000000000..40ac497383 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/battlesign/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/battlesign/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/battlesign/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/battlesign/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/battlesign/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/battlesign/head_fierymetal.png new file mode 100644 index 0000000000..d979e093c0 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/battlesign/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/battlesign/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/battlesign/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/battlesign/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/bolt/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/bolt/head_fierymetal.png new file mode 100644 index 0000000000..bd4bdaa00b Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/bolt/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/bolt/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/bolt/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/bolt/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/bolt/shaft_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/bolt/shaft_fierymetal.png new file mode 100644 index 0000000000..b9de18fe4c Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/bolt/shaft_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/bolt/shaft_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/bolt/shaft_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/bolt/shaft_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/broadsword/blade_fierymetal.png new file mode 100644 index 0000000000..0eb01915f0 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/broadsword/blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/broadsword/blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/broadsword/blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/broken_blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/broadsword/broken_blade_fierymetal.png new file mode 100644 index 0000000000..81075381d8 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/broadsword/broken_blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/broken_blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/broadsword/broken_blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/broadsword/broken_blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/guard_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/broadsword/guard_fierymetal.png new file mode 100644 index 0000000000..ff035e0d5b Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/broadsword/guard_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/guard_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/broadsword/guard_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/broadsword/guard_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/broadsword/handle_fierymetal.png new file mode 100644 index 0000000000..e736eb3c36 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/broadsword/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/broadsword/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/broadsword/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/broadsword/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/cleaver/broken_head_fierymetal.png new file mode 100644 index 0000000000..90c1a2cebe Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/cleaver/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/cleaver/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/cleaver/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/guard_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/cleaver/guard_fierymetal.png new file mode 100644 index 0000000000..8b720915f6 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/cleaver/guard_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/guard_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/cleaver/guard_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/cleaver/guard_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/cleaver/head_fierymetal.png new file mode 100644 index 0000000000..8b395814b5 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/cleaver/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/cleaver/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/cleaver/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/shield_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/cleaver/shield_fierymetal.png new file mode 100644 index 0000000000..9c6eb9c92c Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/cleaver/shield_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/cleaver/shield_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/cleaver/shield_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/cleaver/shield_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/crossbow/binding_fierymetal.png new file mode 100644 index 0000000000..c1b02e7c02 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/crossbow/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/crossbow/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/crossbow/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/body_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/crossbow/body_fierymetal.png new file mode 100644 index 0000000000..eeea3e7b84 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/crossbow/body_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/body_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/crossbow/body_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/crossbow/body_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_2_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_2_fierymetal.png new file mode 100644 index 0000000000..048ff211dd Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_2_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_2_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_2_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_2_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_3_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_3_fierymetal.png new file mode 100644 index 0000000000..338ff51be0 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_3_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_3_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_3_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_3_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_fierymetal.png new file mode 100644 index 0000000000..173dd7d285 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/crossbow/limb_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/excavator/binding_fierymetal.png new file mode 100644 index 0000000000..8cd11eb2c0 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/excavator/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/excavator/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/excavator/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/excavator/broken_head_fierymetal.png new file mode 100644 index 0000000000..c4fe4d6bb7 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/excavator/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/excavator/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/excavator/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/grip_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/excavator/grip_fierymetal.png new file mode 100644 index 0000000000..e4b7fc3370 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/excavator/grip_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/grip_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/excavator/grip_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/excavator/grip_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/excavator/handle_fierymetal.png new file mode 100644 index 0000000000..e4fd438e14 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/excavator/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/excavator/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/excavator/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/excavator/head_fierymetal.png new file mode 100644 index 0000000000..0e176f0f6a Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/excavator/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/excavator/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/excavator/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/excavator/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/frypan/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/frypan/broken_head_fierymetal.png new file mode 100644 index 0000000000..8f64638112 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/frypan/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/frypan/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/frypan/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/frypan/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/frypan/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/frypan/head_fierymetal.png new file mode 100644 index 0000000000..f8e874944b Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/frypan/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/frypan/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/frypan/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/frypan/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/back_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hammer/back_fierymetal.png new file mode 100644 index 0000000000..3fb8d66b1b Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hammer/back_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/back_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hammer/back_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hammer/back_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/broken_handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hammer/broken_handle_fierymetal.png new file mode 100644 index 0000000000..b9a4c80908 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hammer/broken_handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/broken_handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hammer/broken_handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hammer/broken_handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/front_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hammer/front_fierymetal.png new file mode 100644 index 0000000000..3c178d7dcb Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hammer/front_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/front_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hammer/front_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hammer/front_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hammer/handle_fierymetal.png new file mode 100644 index 0000000000..7e1e638c91 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hammer/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hammer/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hammer/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hammer/head_fierymetal.png new file mode 100644 index 0000000000..72dbbf4a89 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hammer/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hammer/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hammer/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hammer/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hatchet/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hatchet/binding_fierymetal.png new file mode 100644 index 0000000000..5d79bf3b7c Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hatchet/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hatchet/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hatchet/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hatchet/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hatchet/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hatchet/broken_head_fierymetal.png new file mode 100644 index 0000000000..a3377f386a Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hatchet/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hatchet/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hatchet/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hatchet/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/hatchet/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/hatchet/head_fierymetal.png new file mode 100644 index 0000000000..a1eeccfd3d Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/hatchet/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/hatchet/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/hatchet/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/hatchet/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/kama/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/kama/binding_fierymetal.png new file mode 100644 index 0000000000..c8769220ad Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/kama/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/kama/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/kama/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/kama/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/kama/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/kama/broken_head_fierymetal.png new file mode 100644 index 0000000000..684bee4fb0 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/kama/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/kama/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/kama/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/kama/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/kama/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/kama/head_fierymetal.png new file mode 100644 index 0000000000..6f3075b14f Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/kama/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/kama/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/kama/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/kama/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/grip_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longbow/grip_fierymetal.png new file mode 100644 index 0000000000..af17ffeff0 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longbow/grip_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/grip_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longbow/grip_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longbow/grip_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_2_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_2_fierymetal.png new file mode 100644 index 0000000000..6366bdad94 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_2_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_2_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_2_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_2_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_3_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_3_fierymetal.png new file mode 100644 index 0000000000..02c33abccd Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_3_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_3_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_3_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_3_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_fierymetal.png new file mode 100644 index 0000000000..594e3e0b01 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_bottom_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_2_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_2_fierymetal.png new file mode 100644 index 0000000000..2c4292fe27 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_2_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_2_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_2_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_2_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_3_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_3_fierymetal.png new file mode 100644 index 0000000000..f591d8df2f Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_3_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_3_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_3_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_3_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_fierymetal.png new file mode 100644 index 0000000000..de4ac7ef11 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longbow/limb_top_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longsword/blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longsword/blade_fierymetal.png new file mode 100644 index 0000000000..25de96c6ff Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longsword/blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longsword/blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longsword/blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longsword/blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longsword/broken_blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longsword/broken_blade_fierymetal.png new file mode 100644 index 0000000000..a33580f4fc Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longsword/broken_blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longsword/broken_blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longsword/broken_blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longsword/broken_blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/longsword/guard_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/longsword/guard_fierymetal.png new file mode 100644 index 0000000000..db9443c9f9 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/longsword/guard_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/longsword/guard_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/longsword/guard_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/longsword/guard_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/binding_fierymetal.png new file mode 100644 index 0000000000..931b1fab98 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/broken_head_fierymetal.png new file mode 100644 index 0000000000..0f66bc8f3c Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/handle_fierymetal.png new file mode 100644 index 0000000000..8317ce88b3 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/head_fierymetal.png new file mode 100644 index 0000000000..e92cdc7dd3 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/shield_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/shield_fierymetal.png new file mode 100644 index 0000000000..08cb8b8a28 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/shield_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/lumberaxe/shield_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/shield_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/lumberaxe/shield_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/back_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/mattock/back_fierymetal.png new file mode 100644 index 0000000000..1eafce6893 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/mattock/back_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/back_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/mattock/back_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/mattock/back_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/mattock/broken_head_fierymetal.png new file mode 100644 index 0000000000..dd29bc44d1 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/mattock/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/mattock/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/mattock/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/mattock/handle_fierymetal.png new file mode 100644 index 0000000000..97e5bf9dc4 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/mattock/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/mattock/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/mattock/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/mattock/head_fierymetal.png new file mode 100644 index 0000000000..90a20008ec Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/mattock/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/mattock/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/mattock/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/mattock/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/arrow_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_head_fierymetal.png new file mode 100644 index 0000000000..24936f8e3a Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/arrow_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/arrow_shaft_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_shaft_fierymetal.png new file mode 100644 index 0000000000..549b58e864 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_shaft_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/arrow_shaft_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_shaft_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/arrow_shaft_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/binding_fierymetal.png new file mode 100644 index 0000000000..13fd40e760 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/knife_blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/knife_blade_fierymetal.png new file mode 100644 index 0000000000..718be29bc0 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/knife_blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/knife_blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/knife_blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/knife_blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/large_plate_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/large_plate_fierymetal.png new file mode 100644 index 0000000000..c1d954f58f Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/large_plate_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/large_plate_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/large_plate_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/large_plate_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/shard_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/shard_fierymetal.png new file mode 100644 index 0000000000..329cae6dac Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/shard_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/shard_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/shard_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/shard_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/sharpening_kit_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/sharpening_kit_fierymetal.png new file mode 100644 index 0000000000..7dc4fb6ca4 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/sharpening_kit_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/sharpening_kit_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/sharpening_kit_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/sharpening_kit_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/sword_blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/sword_blade_fierymetal.png new file mode 100644 index 0000000000..94705bc572 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/sword_blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/sword_blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/sword_blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/sword_blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/tool_rod_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/tool_rod_fierymetal.png new file mode 100644 index 0000000000..549b58e864 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/tool_rod_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/tool_rod_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/tool_rod_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/tool_rod_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/tough_binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/tough_binding_fierymetal.png new file mode 100644 index 0000000000..ee2d574f4e Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/tough_binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/tough_binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/tough_binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/tough_binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/tough_tool_rod_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/tough_tool_rod_fierymetal.png new file mode 100644 index 0000000000..a345e079b2 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/tough_tool_rod_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/tough_tool_rod_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/tough_tool_rod_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/tough_tool_rod_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/wide_guard_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/parts/wide_guard_fierymetal.png new file mode 100644 index 0000000000..95ac8bd966 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/parts/wide_guard_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/parts/wide_guard_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/parts/wide_guard_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/parts/wide_guard_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/pickaxe/binding_fierymetal.png new file mode 100644 index 0000000000..27ea50ea76 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/pickaxe/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/pickaxe/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/pickaxe/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/pickaxe/broken_head_fierymetal.png new file mode 100644 index 0000000000..10fb8bbc2c Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/pickaxe/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/pickaxe/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/pickaxe/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/pickaxe/handle_fierymetal.png new file mode 100644 index 0000000000..8afee42689 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/pickaxe/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/pickaxe/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/pickaxe/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/pickaxe/head_fierymetal.png new file mode 100644 index 0000000000..f69727fd03 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/pickaxe/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/pickaxe/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/pickaxe/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/pickaxe/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/rapier/blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/rapier/blade_fierymetal.png new file mode 100644 index 0000000000..550e323a95 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/rapier/blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/rapier/blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/rapier/blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/rapier/blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/rapier/broken_blade_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/rapier/broken_blade_fierymetal.png new file mode 100644 index 0000000000..a1a6be7bd2 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/rapier/broken_blade_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/rapier/broken_blade_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/rapier/broken_blade_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/rapier/broken_blade_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/rapier/guard_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/rapier/guard_fierymetal.png new file mode 100644 index 0000000000..820364c978 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/rapier/guard_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/rapier/guard_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/rapier/guard_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/rapier/guard_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/accessory_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/scythe/accessory_fierymetal.png new file mode 100644 index 0000000000..f3cdc95ac2 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/scythe/accessory_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/accessory_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/scythe/accessory_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/scythe/accessory_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/scythe/binding_fierymetal.png new file mode 100644 index 0000000000..9d4e768d11 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/scythe/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/scythe/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/scythe/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/scythe/broken_head_fierymetal.png new file mode 100644 index 0000000000..a26a9de014 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/scythe/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/scythe/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/scythe/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/scythe/handle_fierymetal.png new file mode 100644 index 0000000000..bf0146cc24 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/scythe/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/scythe/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/scythe/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/scythe/head_fierymetal.png new file mode 100644 index 0000000000..35f91bca60 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/scythe/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/scythe/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/scythe/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/scythe/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_2_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_2_fierymetal.png new file mode 100644 index 0000000000..03054756cf Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_2_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_2_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_2_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_2_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_3_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_3_fierymetal.png new file mode 100644 index 0000000000..1b9db76878 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_3_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_3_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_3_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_3_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_fierymetal.png new file mode 100644 index 0000000000..28057fc6fd Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_bottom_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_2_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_2_fierymetal.png new file mode 100644 index 0000000000..696b4513a1 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_2_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_2_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_2_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_2_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_3_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_3_fierymetal.png new file mode 100644 index 0000000000..e93cc6fbbf Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_3_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_3_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_3_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_3_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_fierymetal.png new file mode 100644 index 0000000000..a0b2d2715a Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shortbow/limb_top_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/binding_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shovel/binding_fierymetal.png new file mode 100644 index 0000000000..0c29200e7d Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shovel/binding_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/binding_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shovel/binding_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shovel/binding_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/broken_head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shovel/broken_head_fierymetal.png new file mode 100644 index 0000000000..37f70aeba1 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shovel/broken_head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/broken_head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shovel/broken_head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shovel/broken_head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/handle_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shovel/handle_fierymetal.png new file mode 100644 index 0000000000..af798958eb Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shovel/handle_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/handle_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shovel/handle_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shovel/handle_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/head_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shovel/head_fierymetal.png new file mode 100644 index 0000000000..fd401644a9 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shovel/head_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shovel/head_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shovel/head_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shovel/head_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken2_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken2_fierymetal.png new file mode 100644 index 0000000000..0161202a18 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken2_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken2_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken2_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken2_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken3_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken3_fierymetal.png new file mode 100644 index 0000000000..163609da24 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken3_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken3_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken3_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken3_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken4_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken4_fierymetal.png new file mode 100644 index 0000000000..bb7f162792 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken4_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken4_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken4_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken4_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken_fierymetal.png b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken_fierymetal.png new file mode 100644 index 0000000000..ef1d05cc04 Binary files /dev/null and b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken_fierymetal.png differ diff --git a/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken_fierymetal.png.mcmeta b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken_fierymetal.png.mcmeta new file mode 100644 index 0000000000..73e44a04d8 --- /dev/null +++ b/src/main/resources/assets/tconstruct/textures/items/shuriken/shuriken_fierymetal.png.mcmeta @@ -0,0 +1,11 @@ +{ + "animation": { + "interpolate": true, + "width": 1, + "height": 2, + "frametime": 18, + "frames": [ + 0, 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/dark_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/dark_forest.json new file mode 100644 index 0000000000..6d48b4c283 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/dark_forest.json @@ -0,0 +1,16 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:dark_forest" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/dark_forest_center" } + } + }, + "requirements": [ + [ "0", "1" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/dark_forest_center.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/dark_forest_center.json new file mode 100644 index 0000000000..c0b980295b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/dark_forest_center.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:dark_forest_center" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/deep_mushroom_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/deep_mushroom_forest.json new file mode 100644 index 0000000000..3f90f461ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/deep_mushroom_forest.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:deep_mushroom_forest" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/dense_twilight_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/dense_twilight_forest.json new file mode 100644 index 0000000000..1f9702cd2c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/dense_twilight_forest.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:dense_twilight_forest" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/enchanted_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/enchanted_forest.json new file mode 100644 index 0000000000..d3773add80 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/enchanted_forest.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:enchanted_forest" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/fire_swamp.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/fire_swamp.json new file mode 100644 index 0000000000..fec21f2e4a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/fire_swamp.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:fire_swamp" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/firefly_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/firefly_forest.json new file mode 100644 index 0000000000..a46841b348 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/firefly_forest.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:firefly_forest" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/general_biomes.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/general_biomes.json new file mode 100644 index 0000000000..a331071907 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/general_biomes.json @@ -0,0 +1,40 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/twilight_forest" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/firefly_forest" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/twilight_clearing" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/oak_savannah" } + }, + "4": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/dense_twilight_forest" } + }, + "5": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/mushroom_forest" } + }, + "6": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/deep_mushroom_forest" } + }, + "7": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/twilight_lake" } + } + }, + "requirements": [ + [ "0", "1", "2", "3", "4", "5", "6", "7" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/highlands_center.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/highlands_center.json new file mode 100644 index 0000000000..9c382b95d2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/highlands_center.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:highlands_center" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/mushroom_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/mushroom_forest.json new file mode 100644 index 0000000000..7ce166ce29 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/mushroom_forest.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:mushroom_forest" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/oak_savannah.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/oak_savannah.json new file mode 100644 index 0000000000..ccf1061b7b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/oak_savannah.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:oak_savannah" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/snowy_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/snowy_forest.json new file mode 100644 index 0000000000..9bf891ef24 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/snowy_forest.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:snowy_forest" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/thornlands.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/thornlands.json new file mode 100644 index 0000000000..f6ed7ee31b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/thornlands.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:thornlands" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_clearing.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_clearing.json new file mode 100644 index 0000000000..d4614b2b29 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_clearing.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:twilight_clearing" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_forest.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_forest.json new file mode 100644 index 0000000000..207862c910 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_forest.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:twilight_forest" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_glacier.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_glacier.json new file mode 100644 index 0000000000..b2faff4602 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_glacier.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:twilight_glacier" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_highlands.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_highlands.json new file mode 100644 index 0000000000..d69b5f7fe4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_highlands.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:twilight_highlands" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_lake.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_lake.json new file mode 100644 index 0000000000..759a1fe968 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_lake.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:twilight_lake" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_swamp.json b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_swamp.json new file mode 100644 index 0000000000..04230c7afe --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/biomes/twilight_swamp.json @@ -0,0 +1,16 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "minecraft:location", + "conditions": { "biome": "twilightforest:twilight_swamp" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/biomes/fire_swamp" } + } + }, + "requirements": [ + [ "0", "1" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/compat/ie_shaders.json b/src/main/resources/assets/twilightforest/advancements/alt/compat/ie_shaders.json new file mode 100644 index 0000000000..101fcc308a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/compat/ie_shaders.json @@ -0,0 +1,16 @@ +{ + "conditions": [{ + "type": "forge:mod_loaded", + "modid": "immersiveengineering" + }], + "parent": "twilightforest:alt/root", + "criteria": { + "ie_shader" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "immersiveengineering:shader" }]}}, + "ie_shader_bag": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "immersiveengineering:shader_bag" }]}}, + "tf_shader" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:shader" }]}}, + "tf_shader_bag": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:shader_bag" }]}} + }, + "requirements": [ + [ "ie_shader", "ie_shader_bag", "tf_shader", "tf_shader_bag" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/compat/tc_aspects.json b/src/main/resources/assets/twilightforest/advancements/alt/compat/tc_aspects.json new file mode 100644 index 0000000000..6cc19128c3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/compat/tc_aspects.json @@ -0,0 +1,15 @@ +{ + "conditions": [{ + "type": "forge:mod_loaded", + "modid": "thaumcraft" + }], + "parent": "twilightforest:alt/root", + "criteria": { + "thaumonomicon" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "thaumcraft:thaumonomicon" }]}}, + "crystal_essence": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "thaumcraft:crystal_essence" }]}}, + "thaumometer" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "thaumcraft:thaumometer" }]}} + }, + "requirements": [ + [ "thaumonomicon", "crystal_essence", "thaumometer" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/compat/tconstruct.json b/src/main/resources/assets/twilightforest/advancements/alt/compat/tconstruct.json new file mode 100644 index 0000000000..7e69e33bcd --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/compat/tconstruct.json @@ -0,0 +1,22 @@ +{ + "conditions": [{ + "type": "forge:mod_loaded", + "modid": "tconstruct" + }], + "parent": "twilightforest:alt/root", + "criteria": { + "book" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:book" }]}}, + "cast" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:cast" }]}}, + "clay_cast" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:clay_cast" }]}}, + "pattern" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:pattern" }]}}, + "tooltable1" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:tooltables", "data": 1 }]}}, + "tooltable2" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:tooltables", "data": 2 }]}}, + "tooltable3" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:tooltables", "data": 3 }]}}, + "tooltable4" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:tooltables", "data": 4 }]}}, + "tooltable5" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:tooltables", "data": 5 }]}}, + "toolforge" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "tconstruct:toolforge" }]}} + }, + "requirements": [ + [ "book", "cast", "clay_cast", "pattern", "tooltable1", "tooltable2", "tooltable3", "tooltable4", "tooltable5", "toolforge" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/adherent.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/adherent.json new file mode 100644 index 0000000000..2901a28300 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/adherent.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:adherent" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:adherent" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:adherent" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:adherent" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:adherent" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:adherent" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/animals.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/animals.json new file mode 100644 index 0000000000..c2bbdeb2de --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/animals.json @@ -0,0 +1,40 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/bighorn_sheep" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/bunny" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/deer" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/raven" } + }, + "4": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/squirrel" } + }, + "5": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/wild_boar" } + }, + "6": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/wild_boar" } + }, + "7": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/penguin" } + } + }, + "requirements": [ + [ "0", "1", "2", "3", "4", "5", "6", "7" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/armored_giant.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/armored_giant.json new file mode 100644 index 0000000000..4bb9e888a9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/armored_giant.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:armored_giant" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:armored_giant" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:armored_giant" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:armored_giant" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:armored_giant" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:armored_giant" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/arthopods.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/arthopods.json new file mode 100644 index 0000000000..b5f39bb738 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/arthopods.json @@ -0,0 +1,44 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/hedge_spider" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/swarm_spider" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/slime_beetle" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/fire_beetle" } + }, + "4": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/pinch_beetle" } + }, + "5": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/mosquito_swarm" } + }, + "6": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/king_spider" } + }, + "7": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/tower_termite" } + }, + "8": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/tower_broodling" } + } + }, + "requirements": [ + [ "0", "1", "2", "3", "4", "5", "6", "7", "8" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/bighorn_sheep.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/bighorn_sheep.json new file mode 100644 index 0000000000..fa9fb1ac29 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/bighorn_sheep.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:bighorn_sheep" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:bighorn_sheep" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:bighorn_sheep" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:bighorn_sheep" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:bighorn_sheep" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:bighorn_sheep" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/blockchain_goblin.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/blockchain_goblin.json new file mode 100644 index 0000000000..fb7e5d6bd6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/blockchain_goblin.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:blockchain_goblin" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:blockchain_goblin" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:blockchain_goblin" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:blockchain_goblin" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:blockchain_goblin" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:blockchain_goblin" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/bunny.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/bunny.json new file mode 100644 index 0000000000..b02ac9df55 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/bunny.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:bunny" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:bunny" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:bunny" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:bunny" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:bunny" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:bunny" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/castle_guardian.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/castle_guardian.json new file mode 100644 index 0000000000..264a2f28a9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/castle_guardian.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:castle_guardian" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:castle_guardian" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:castle_guardian" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:castle_guardian" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:castle_guardian" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:castle_guardian" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/death_tome.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/death_tome.json new file mode 100644 index 0000000000..71558b1f91 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/death_tome.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:death_tome" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:death_tome" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:death_tome" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:death_tome" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:death_tome" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:death_tome" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/deer.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/deer.json new file mode 100644 index 0000000000..a363c70b3f --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/deer.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:deer" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:deer" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:deer" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:deer" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:deer" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:deer" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/fire_beetle.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/fire_beetle.json new file mode 100644 index 0000000000..e625eca68c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/fire_beetle.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:fire_beetle" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:fire_beetle" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:fire_beetle" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:fire_beetle" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:fire_beetle" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:fire_beetle" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/ghasts.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/ghasts.json new file mode 100644 index 0000000000..fe21cc58be --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/ghasts.json @@ -0,0 +1,16 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/mini_ghast" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/tower_ghast" } + } + }, + "requirements": [ + [ "0", "1" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/giant_miner.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/giant_miner.json new file mode 100644 index 0000000000..d5d0646598 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/giant_miner.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:giant_miner" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:giant_miner" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:giant_miner" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:giant_miner" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:giant_miner" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:giant_miner" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/giants.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/giants.json new file mode 100644 index 0000000000..a89839355a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/giants.json @@ -0,0 +1,16 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/giant_miner" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/armored_giant" } + } + }, + "requirements": [ + [ "0", "1" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/goblin_knight.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/goblin_knight.json new file mode 100644 index 0000000000..cb369a963e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/goblin_knight.json @@ -0,0 +1,60 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:goblin_knight_upper" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_upper" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_upper" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_upper" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_upper" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_upper" }} + }, + "hurt_by_indirect_alt": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:goblin_knight_lower" }}} + }, + "slain_by_alt": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_lower" }} + }, + "hurt_alt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_lower" }} + }, + "slay_alt": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_lower" }} + }, + "summon_alt": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_lower" }} + }, + "tame_alt": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:goblin_knight_lower" }} + } + }, + "requirements": [ + [ + "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame", + "hurt_by_indirect_alt", "slain_by_alt", "hurt_alt", "slay_alt", "summon_alt", "tame_alt" + ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/goblins.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/goblins.json new file mode 100644 index 0000000000..db4f399a34 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/goblins.json @@ -0,0 +1,24 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/redcap" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/redcap_sapper" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/goblin_knight" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/blockchain_goblin" } + } + }, + "requirements": [ + [ "0", "1", "2", "3" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/harbinger_cube.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/harbinger_cube.json new file mode 100644 index 0000000000..d68c3ca46d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/harbinger_cube.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:harbinger_cube" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:harbinger_cube" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:harbinger_cube" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:harbinger_cube" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:harbinger_cube" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:harbinger_cube" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/hedge_spider.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/hedge_spider.json new file mode 100644 index 0000000000..9c21cbb81e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/hedge_spider.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:hedge_spider" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:hedge_spider" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:hedge_spider" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:hedge_spider" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:hedge_spider" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:hedge_spider" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/helmet_crab.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/helmet_crab.json new file mode 100644 index 0000000000..c7adfe3084 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/helmet_crab.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:helmet_crab" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:helmet_crab" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:helmet_crab" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:helmet_crab" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:helmet_crab" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:helmet_crab" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/hostile_wolf.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/hostile_wolf.json new file mode 100644 index 0000000000..2c69e64697 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/hostile_wolf.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:hostile_wolf" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:hostile_wolf" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:hostile_wolf" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:hostile_wolf" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:hostile_wolf" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:hostile_wolf" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/hydra.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/hydra.json new file mode 100644 index 0000000000..e4dec7d9b9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/hydra.json @@ -0,0 +1,60 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:hydra" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:hydra" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:hydra" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:hydra" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:hydra" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:hydra" }} + }, + "hurt_by_indirect_alt": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:hydra_head" }}} + }, + "slain_by_alt": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:hydra_head" }} + }, + "hurt_alt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:hydra_head" }} + }, + "slay_alt": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:hydra_head" }} + }, + "summon_alt": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:hydra_head" }} + }, + "tame_alt": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:hydra_head" }} + } + }, + "requirements": [ + [ + "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame", + "hurt_by_indirect_alt", "slain_by_alt", "hurt_alt", "slay_alt", "summon_alt", "tame_alt" + ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/ice_cores.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/ice_cores.json new file mode 100644 index 0000000000..3579624d4e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/ice_cores.json @@ -0,0 +1,16 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/stable_ice_core" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/unstable_ice_core" } + } + }, + "requirements": [ + [ "0", "1" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/ice_crystal.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/ice_crystal.json new file mode 100644 index 0000000000..e2d17f070f --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/ice_crystal.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:ice_crystal" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:ice_crystal" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:ice_crystal" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:ice_crystal" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:ice_crystal" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:ice_crystal" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/king_spider.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/king_spider.json new file mode 100644 index 0000000000..bae4864807 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/king_spider.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:king_spider" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:king_spider" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:king_spider" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:king_spider" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:king_spider" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:king_spider" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/knight_phantom.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/knight_phantom.json new file mode 100644 index 0000000000..a464874688 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/knight_phantom.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:knight_phantom" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:knight_phantom" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:knight_phantom" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:knight_phantom" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:knight_phantom" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:knight_phantom" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/kobold.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/kobold.json new file mode 100644 index 0000000000..cc2281f091 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/kobold.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:kobold" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:kobold" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:kobold" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:kobold" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:kobold" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:kobold" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/lich.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/lich.json new file mode 100644 index 0000000000..5bd7eec57e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/lich.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:lich" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:lich" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:lich" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:lich" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:lich" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:lich" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/lich_zombies.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/lich_zombies.json new file mode 100644 index 0000000000..aab0b9be73 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/lich_zombies.json @@ -0,0 +1,60 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:loyal_zombie" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:loyal_zombie" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:loyal_zombie" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:loyal_zombie" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:loyal_zombie" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:loyal_zombie" }} + }, + "hurt_by_indirect_alt": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:lich_minion" }}} + }, + "slain_by_alt": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:lich_minion" }} + }, + "hurt_alt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:lich_minion" }} + }, + "slay_alt": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:lich_minion" }} + }, + "summon_alt": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:lich_minion" }} + }, + "tame_alt": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:lich_minion" }} + } + }, + "requirements": [ + [ + "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame", + "hurt_by_indirect_alt", "slain_by_alt", "hurt_alt", "slay_alt", "summon_alt", "tame_alt" + ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/maze_slime.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/maze_slime.json new file mode 100644 index 0000000000..4733de0e2b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/maze_slime.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:maze_slime" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:maze_slime" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:maze_slime" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:maze_slime" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:maze_slime" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:maze_slime" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/mini_ghast.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/mini_ghast.json new file mode 100644 index 0000000000..0e87974450 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/mini_ghast.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:mini_ghast" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:mini_ghast" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:mini_ghast" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:mini_ghast" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:mini_ghast" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:mini_ghast" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/minoshroom.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/minoshroom.json new file mode 100644 index 0000000000..59e63ff28b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/minoshroom.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:minoshroom" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:minoshroom" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:minoshroom" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:minoshroom" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:minoshroom" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:minoshroom" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/minotaur.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/minotaur.json new file mode 100644 index 0000000000..b7dcfbd2da --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/minotaur.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:minotaur" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:minotaur" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:minotaur" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:minotaur" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:minotaur" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:minotaur" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/mist_wolf.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/mist_wolf.json new file mode 100644 index 0000000000..b3f9865b2d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/mist_wolf.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:mist_wolf" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:mist_wolf" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:mist_wolf" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:mist_wolf" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:mist_wolf" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:mist_wolf" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/mosquito_swarm.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/mosquito_swarm.json new file mode 100644 index 0000000000..c7437f7eb8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/mosquito_swarm.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:mosquito_swarm" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:mosquito_swarm" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:mosquito_swarm" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:mosquito_swarm" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:mosquito_swarm" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:mosquito_swarm" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/naga.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/naga.json new file mode 100644 index 0000000000..2674757958 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/naga.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:naga" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:naga" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:naga" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:naga" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:naga" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:naga" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/penguin.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/penguin.json new file mode 100644 index 0000000000..9fc76dafd4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/penguin.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:penguin" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:penguin" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:penguin" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:penguin" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:penguin" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:penguin" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/pinch_beetle.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/pinch_beetle.json new file mode 100644 index 0000000000..f54bb3f4b6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/pinch_beetle.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:pinch_beetle" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:pinch_beetle" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:pinch_beetle" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:pinch_beetle" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:pinch_beetle" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:pinch_beetle" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/raven.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/raven.json new file mode 100644 index 0000000000..8f46294668 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/raven.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:raven" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:raven" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:raven" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:raven" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:raven" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:raven" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/redcap.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/redcap.json new file mode 100644 index 0000000000..7c238e0988 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/redcap.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:redcap" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:redcap" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:redcap" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:redcap" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:redcap" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:redcap" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/redcap_sapper.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/redcap_sapper.json new file mode 100644 index 0000000000..c1230dfa6b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/redcap_sapper.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:redcap_sapper" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:redcap_sapper" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:redcap_sapper" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:redcap_sapper" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:redcap_sapper" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:redcap_sapper" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/roving_cube.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/roving_cube.json new file mode 100644 index 0000000000..42b9932382 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/roving_cube.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:roving_cube" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:roving_cube" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:roving_cube" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:roving_cube" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:roving_cube" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:roving_cube" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/skeleton_druid.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/skeleton_druid.json new file mode 100644 index 0000000000..3d5e6b2680 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/skeleton_druid.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:skeleton_druid" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:skeleton_druid" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:skeleton_druid" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:skeleton_druid" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:skeleton_druid" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:skeleton_druid" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/slider.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/slider.json new file mode 100644 index 0000000000..a9da638066 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/slider.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:slider" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:slider" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:slider" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:slider" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:slider" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:slider" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/slime_beetle.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/slime_beetle.json new file mode 100644 index 0000000000..72fa8c89cf --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/slime_beetle.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:slime_beetle" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:slime_beetle" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:slime_beetle" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:slime_beetle" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:slime_beetle" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:slime_beetle" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/snow_guardian.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/snow_guardian.json new file mode 100644 index 0000000000..e11822db7d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/snow_guardian.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:snow_guardian" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:snow_guardian" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:snow_guardian" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:snow_guardian" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:snow_guardian" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:snow_guardian" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/snow_queen.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/snow_queen.json new file mode 100644 index 0000000000..92778e03a6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/snow_queen.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:snow_queen" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:snow_queen" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:snow_queen" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:snow_queen" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:snow_queen" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:snow_queen" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/squirrel.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/squirrel.json new file mode 100644 index 0000000000..07ef7352a3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/squirrel.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:squirrel" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:squirrel" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:squirrel" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:squirrel" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:squirrel" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:squirrel" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/stable_ice_core.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/stable_ice_core.json new file mode 100644 index 0000000000..f17faf35cf --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/stable_ice_core.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:stable_ice_core" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:stable_ice_core" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:stable_ice_core" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:stable_ice_core" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:stable_ice_core" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:stable_ice_core" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/swarm_spider.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/swarm_spider.json new file mode 100644 index 0000000000..3a872bcc5b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/swarm_spider.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:swarm_spider" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:swarm_spider" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:swarm_spider" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:swarm_spider" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:swarm_spider" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:swarm_spider" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/tiny_bird.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/tiny_bird.json new file mode 100644 index 0000000000..60a0a4186a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/tiny_bird.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:tiny_bird" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:tiny_bird" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:tiny_bird" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:tiny_bird" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:tiny_bird" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:tiny_bird" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_broodling.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_broodling.json new file mode 100644 index 0000000000..4507047979 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_broodling.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:tower_broodling" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:tower_broodling" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:tower_broodling" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:tower_broodling" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:tower_broodling" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:tower_broodling" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_ghast.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_ghast.json new file mode 100644 index 0000000000..29894ea042 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_ghast.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:tower_ghast" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:tower_ghast" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:tower_ghast" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:tower_ghast" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:tower_ghast" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:tower_ghast" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_golem.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_golem.json new file mode 100644 index 0000000000..297b172101 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_golem.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:tower_golem" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:tower_golem" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:tower_golem" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:tower_golem" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:tower_golem" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:tower_golem" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_termite.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_termite.json new file mode 100644 index 0000000000..99d53f7b17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/tower_termite.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:tower_termite" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:tower_termite" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:tower_termite" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:tower_termite" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:tower_termite" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:tower_termite" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/troll.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/troll.json new file mode 100644 index 0000000000..bad9601c6e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/troll.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:troll" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:troll" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:troll" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:troll" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:troll" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:troll" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/undead.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/undead.json new file mode 100644 index 0000000000..8fb37a2b16 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/undead.json @@ -0,0 +1,20 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/skeleton_druid" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/wraith" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/snow_guardian" } + } + }, + "requirements": [ + [ "0", "1", "2" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/unstable_ice_core.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/unstable_ice_core.json new file mode 100644 index 0000000000..f055b0ec42 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/unstable_ice_core.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:unstable_ice_core" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:unstable_ice_core" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:unstable_ice_core" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:unstable_ice_core" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:unstable_ice_core" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:unstable_ice_core" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/ur_ghast.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/ur_ghast.json new file mode 100644 index 0000000000..2dcbec5da5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/ur_ghast.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:ur_ghast" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:ur_ghast" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:ur_ghast" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:ur_ghast" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:ur_ghast" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:ur_ghast" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/wild_boar.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/wild_boar.json new file mode 100644 index 0000000000..e2aa0245d4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/wild_boar.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:wild_boar" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:wild_boar" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:wild_boar" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:wild_boar" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:wild_boar" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:wild_boar" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/winter_wolf.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/winter_wolf.json new file mode 100644 index 0000000000..f82b590955 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/winter_wolf.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:winter_wolf" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:winter_wolf" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:winter_wolf" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:winter_wolf" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:winter_wolf" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:winter_wolf" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/wolves.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/wolves.json new file mode 100644 index 0000000000..d4363dd75b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/wolves.json @@ -0,0 +1,20 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/hostile_wolf" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/mist_wolf" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/entities/winter_wolf" } + } + }, + "requirements": [ + [ "0", "1", "2" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/wraith.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/wraith.json new file mode 100644 index 0000000000..6cf0032d0d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/wraith.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:wraith" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:wraith" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:wraith" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:wraith" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:wraith" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:wraith" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/yeti.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/yeti.json new file mode 100644 index 0000000000..4eb2bcc4be --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/yeti.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:yeti" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:yeti" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:yeti" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:yeti" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:yeti" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:yeti" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/entities/yeti_alpha.json b/src/main/resources/assets/twilightforest/advancements/alt/entities/yeti_alpha.json new file mode 100644 index 0000000000..0771104d95 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/entities/yeti_alpha.json @@ -0,0 +1,33 @@ +{ + "parent": "twilightforest:alt/root", + "__hidden": "This advancement should not be visible. There is no display tag group. This is for Patchouli to track if you've interacted with an entity.", + "criteria": { + "hurt_by_indirect": { + "trigger": "minecraft:entity_hurt_player", + "conditions": { "damage": { "source_entity": { "type": "twilightforest:yeti_alpha" }}} + }, + "slain_by": { + "trigger": "minecraft:entity_killed_player", + "conditions": { "entity": { "type": "twilightforest:yeti_alpha" }} + }, + "hurt": { + "trigger": "minecraft:player_hurt_entity", + "conditions": { "entity": { "type": "twilightforest:yeti_alpha" }} + }, + "slay": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:yeti_alpha" }} + }, + "summon": { + "trigger": "minecraft:summoned_entity", + "conditions": { "entity": { "type": "twilightforest:yeti_alpha" }} + }, + "tame": { + "trigger": "minecraft:tame_animal", + "conditions": { "entity": { "type": "twilightforest:yeti_alpha" }} + } + }, + "requirements": [ + [ "hurt_by_indirect", "slain_by", "hurt", "slay", "summon", "tame" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/dark_tower.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/dark_tower.json new file mode 100644 index 0000000000..6201cd1ed6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/dark_tower.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:dark_tower" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/final_castle.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/final_castle.json new file mode 100644 index 0000000000..0b254bf7c9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/final_castle.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:final_castle" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/giant_cloud.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/giant_cloud.json new file mode 100644 index 0000000000..8f4c8a7f9b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/giant_cloud.json @@ -0,0 +1,12 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { + "feature": "twilightforest:troll_lairs", + "position": { "y": { "min": 150 } } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hedge_maze.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hedge_maze.json new file mode 100644 index 0000000000..51c1a0d524 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hedge_maze.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:hedge_maze" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hollow_hills.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hollow_hills.json new file mode 100644 index 0000000000..c324135227 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hollow_hills.json @@ -0,0 +1,20 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/major_landmarks/small_hollow_hill" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/major_landmarks/medium_hollow_hill" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/major_landmarks/large_hollow_hill" } + } + }, + "requirements": [ + [ "0", "1", "2" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hydra_lair.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hydra_lair.json new file mode 100644 index 0000000000..11c49d979b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/hydra_lair.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:hydra_lair" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/ice_tower.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/ice_tower.json new file mode 100644 index 0000000000..cbe8541aa2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/ice_tower.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:ice_tower" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/knight_stronghold.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/knight_stronghold.json new file mode 100644 index 0000000000..4cad96d6b0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/knight_stronghold.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:knight_stronghold", "position": { "y": { "max": 30 } } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/labyrinth.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/labyrinth.json new file mode 100644 index 0000000000..044893940a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/labyrinth.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:labyrinth", "position": { "y": { "max": 30 } } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/large_hollow_hill.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/large_hollow_hill.json new file mode 100644 index 0000000000..6056aa98ae --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/large_hollow_hill.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:large_hollow_hill" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/lich_tower.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/lich_tower.json new file mode 100644 index 0000000000..cb0c1110bf --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/lich_tower.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:lich_tower" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/medium_hollow_hill.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/medium_hollow_hill.json new file mode 100644 index 0000000000..536d66da8a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/medium_hollow_hill.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:medium_hollow_hill" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/mushroom_tower.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/mushroom_tower.json new file mode 100644 index 0000000000..c09964a168 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/mushroom_tower.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:mushroom_tower" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/naga_courtyard.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/naga_courtyard.json new file mode 100644 index 0000000000..58cbddb16a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/naga_courtyard.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:naga_courtyard" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/quest_grove.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/quest_grove.json new file mode 100644 index 0000000000..f960de95ae --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/quest_grove.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:quest_grove" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/small_hollow_hill.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/small_hollow_hill.json new file mode 100644 index 0000000000..2ed6c1f36b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/small_hollow_hill.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:small_hollow_hill" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/troll_lairs.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/troll_lairs.json new file mode 100644 index 0000000000..2d505c3d07 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/troll_lairs.json @@ -0,0 +1,12 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { + "feature": "twilightforest:troll_lairs", + "position": { "y": { "max": 50 } } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/yeti_lairs.json b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/yeti_lairs.json new file mode 100644 index 0000000000..951e6a5054 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/major_landmarks/yeti_lairs.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:yeti_lairs" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/root.json b/src/main/resources/assets/twilightforest/advancements/alt/root.json new file mode 100644 index 0000000000..74cf4c462a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/root.json @@ -0,0 +1 @@ +{ "criteria": { "hidden": { "trigger": "minecraft:impossible" }}} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/arctic_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/arctic_armor_set.json new file mode 100644 index 0000000000..48f76a5d09 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/arctic_armor_set.json @@ -0,0 +1,13 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:arctic_fur" }]}}, + "helmet" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:arctic_helmet" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:arctic_chestplate" }]}}, + "leggings" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:arctic_leggings" }]}}, + "boots" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:arctic_boots" }]}} + }, + "requirements": [ + [ "ingredient", "helmet", "chestplate", "leggings", "boots" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/armors.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/armors.json new file mode 100644 index 0000000000..595b3e17e2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/armors.json @@ -0,0 +1,36 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/ironwood_armor_set" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/naga_armor_set" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/steeleaf_armor_set" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/fiery_armor_set" } + }, + "4": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/knightmetal_armor_set" } + }, + "6": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/arctic_armor_set" } + }, + "7": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/yeti_armor_set" } + } + }, + "requirements": [ + [ "0", "1", "2", "3", "4", "6", "7" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/bows.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/bows.json new file mode 100644 index 0000000000..0372e84fa6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/bows.json @@ -0,0 +1,24 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/triple_bow" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/ice_bow" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/seeker_bow" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/triple_bow" } + } + }, + "requirements": [ + [ "0", "1", "2", "3" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/carminite.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/carminite.json new file mode 100644 index 0000000000..f540c70ac9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/carminite.json @@ -0,0 +1,15 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "carminite" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:carminite" }]}}, + "carminite_block" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:block_storage", "data": 4 }]}}, + "carminite_recipe": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [ + { "item": "twilightforest:borer_essence" }, + { "item": "minecraft:redstone" }, + { "item": "minecraft:ghast_tear" } + ]}} + }, + "requirements": [ + [ "carminite", "carminite_block", "carminite_recipe" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/charm_of_keeping.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/charm_of_keeping.json new file mode 100644 index 0000000000..42a0358669 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/charm_of_keeping.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "1": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:charm_of_keeping_1" }]}}, + "2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:charm_of_keeping_2" }]}}, + "3": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:charm_of_keeping_3" }]}} + }, + "requirements": [ + [ "1", "2", "3" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/charm_of_life.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/charm_of_life.json new file mode 100644 index 0000000000..eac3057f02 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/charm_of_life.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "1": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:charm_of_life_1" }]}}, + "2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:charm_of_life_2" }]}} + }, + "requirements": [ + [ "1", "2" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/charms.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/charms.json new file mode 100644 index 0000000000..5b880fb6f6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/charms.json @@ -0,0 +1,16 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/charm_of_life" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/charm_of_keeping" } + } + }, + "requirements": [ + [ "0", "1" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/crumble_horn.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/crumble_horn.json new file mode 100644 index 0000000000..4a66e1a7b9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/crumble_horn.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "crumble_horn": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:crumble_horn" }]}}, + "used" : { "trigger": "twilightforest:has_advancement", "conditions": { "advancement": "twilightforest:alt/treasures/crumble_horn_used" }} + }, + "requirements": [ + [ "crumble_horn", "used" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/crumble_horn_used.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/crumble_horn_used.json new file mode 100644 index 0000000000..398afef59f --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/crumble_horn_used.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "crumble_horn": { "trigger": "twilightforest:on_item_use", "conditions": { "item": { "item": "twilightforest:crumble_horn" }}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/encased_fire_jet.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/encased_fire_jet.json new file mode 100644 index 0000000000..c35f861702 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/encased_fire_jet.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fire_jet", "data": 3 }]}}, + "ingredient2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:tower_wood", "data": 1 }]}}, + "encased_jet": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fire_jet", "data": 6 }]}} + }, + "requirements": [ + [ "ingredient", "ingredient2", "encased_jet" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/encased_smoker.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/encased_smoker.json new file mode 100644 index 0000000000..74d6b10861 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/encased_smoker.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fire_jet", "data": 0 }]}}, + "ingredient2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:tower_wood", "data": 1 }]}}, + "encased_jet": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fire_jet", "data": 1 }]}} + }, + "requirements": [ + [ "ingredient", "ingredient2", "encased_jet" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/ender_bow.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ender_bow.json new file mode 100644 index 0000000000..c61a08f569 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ender_bow.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "bow": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ender_bow" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_armor_set.json new file mode 100644 index 0000000000..69ac83d568 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_armor_set.json @@ -0,0 +1,15 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_blood" }]}}, + "ingredien2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_tears" }]}}, + "ingredien3": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_ingot" }]}}, + "helmet" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_helmet" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_chestplate" }]}}, + "leggings" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_leggings" }]}}, + "boots" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_boots" }]}} + }, + "requirements": [ + [ "ingredient", "ingredien2", "ingredien3", "helmet", "chestplate", "leggings", "boots" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_blood_tears.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_blood_tears.json new file mode 100644 index 0000000000..74c0a8e7d3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_blood_tears.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "armor": { "trigger": "twilightforest:has_advancement", "conditions": { "advancement": "twilightforest:alt/treasures/fiery_armor_set" }}, + "tools": { "trigger": "twilightforest:has_advancement", "conditions": { "advancement": "twilightforest:alt/treasures/fiery_tool_set" }} + }, + "requirements": [ + [ "armor", "tools" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_tool_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_tool_set.json new file mode 100644 index 0000000000..d46e3e61f0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fiery_tool_set.json @@ -0,0 +1,13 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_blood" }]}}, + "ingredien2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_tears" }]}}, + "ingredien3": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_ingot" }]}}, + "pickaxe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_pickaxe" }]}}, + "sword" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fiery_sword" }]}} + }, + "requirements": [ + [ "ingredient", "ingredien2", "ingredien3", "pickaxe", "sword" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/fire_jet.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fire_jet.json new file mode 100644 index 0000000000..fd59a8430c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/fire_jet.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "fire_jet": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fire_jet", "data": 3 }] }}, + "fire_swamp": { "trigger": "twilightforest:has_advancement", "conditions": { "advancement": "twilightforest:alt/biomes/fire_swamp" }} + }, + "requirements": [ + [ "fire_jet", "fire_swamp" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/any.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/any.json new file mode 100644 index 0000000000..6fd13e2e29 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/any.json @@ -0,0 +1,32 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/foods/hydra_chop" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/foods/maze_wafer" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/foods/meef" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/foods/vension" } + }, + "4": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_labyrinth" } + }, + "5": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/foods/experiment_115" } + } + }, + "requirements": [ + [ "0", "1", "2", "3", "4", "5" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/experiment_115.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/experiment_115.json new file mode 100644 index 0000000000..e3131c785c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/experiment_115.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "food": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:experiment_115" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/hydra_chop.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/hydra_chop.json new file mode 100644 index 0000000000..ef56184b13 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/hydra_chop.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "food": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:hydra_chop" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/maze_wafer.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/maze_wafer.json new file mode 100644 index 0000000000..e07edc54ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/maze_wafer.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "food": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:maze_wafer" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/meef.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/meef.json new file mode 100644 index 0000000000..c53dfe8200 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/meef.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "raw": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:raw_meef" }]}}, + "cooked": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:cooked_meef" }]}} + }, + "requirements": [ + [ "raw", "cooked" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/vension.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/vension.json new file mode 100644 index 0000000000..6187b013e7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/foods/vension.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "raw": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:raw_venison" }]}}, + "cooked": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:cooked_venison" }]}} + }, + "requirements": [ + [ "raw", "cooked" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/giant_blocks.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/giant_blocks.json new file mode 100644 index 0000000000..30b54f995d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/giant_blocks.json @@ -0,0 +1,12 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "giant_cobblestone" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_cobblestone" }]}}, + "giant_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_log" }]}}, + "giant_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_leaves" }]}}, + "giant_obsidian" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_obsidian" }]}} + }, + "requirements": [ + [ "giant_cobblestone", "giant_log", "giant_leaves", "giant_obsidian" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/giant_tool_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/giant_tool_set.json new file mode 100644 index 0000000000..c7067caef9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/giant_tool_set.json @@ -0,0 +1,12 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_cobblestone" }]}}, + "ingredien2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_log" }]}}, + "pickaxe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_pickaxe" }]}}, + "sword" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_sword" }]}} + }, + "requirements": [ + [ "ingredient", "ingredien2", "pickaxe", "sword" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/glass_sword.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/glass_sword.json new file mode 100644 index 0000000000..a7c2f782bc --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/glass_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "glass_sword": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:glass_sword" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_bomb.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_bomb.json new file mode 100644 index 0000000000..e23682f8ab --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_bomb.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ice_bomb": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ice_bomb" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_bow.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_bow.json new file mode 100644 index 0000000000..33ad34594c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_bow.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "bow": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ice_bow" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_sword.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_sword.json new file mode 100644 index 0000000000..e4dcdda411 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ice_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ice_sword": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ice_sword" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/ironwood_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ironwood_armor_set.json new file mode 100644 index 0000000000..ae18a412d0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ironwood_armor_set.json @@ -0,0 +1,14 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_raw" }]}}, + "ingredien2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_ingot" }]}}, + "helmet" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_helmet" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_chestplate" }]}}, + "leggings" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_leggings" }]}}, + "boots" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_boots" }]}} + }, + "requirements": [ + [ "ingredient", "ingredien2", "helmet", "chestplate", "leggings", "boots" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/ironwood_tool_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ironwood_tool_set.json new file mode 100644 index 0000000000..9237d2c381 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ironwood_tool_set.json @@ -0,0 +1,15 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_raw" }]}}, + "ingredien2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_ingot" }]}}, + "pickaxe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_pickaxe" }]}}, + "sword" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_sword" }]}}, + "axe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_axe" }]}}, + "shovel" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_shovel" }]}}, + "hoe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ironwood_hoe" }]}} + }, + "requirements": [ + [ "ingredient", "ingredien2", "pickaxe", "sword", "axe", "shovel", "hoe" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/knightmetal_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/knightmetal_armor_set.json new file mode 100644 index 0000000000..1e4d18567d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/knightmetal_armor_set.json @@ -0,0 +1,15 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:armor_shard" }]}}, + "ingredien2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:armor_shard_cluster" }]}}, + "ingredien3": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_ingot" }]}}, + "helmet" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_helmet" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_chestplate" }]}}, + "leggings" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_leggings" }]}}, + "boots" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_boots" }]}} + }, + "requirements": [ + [ "ingredient", "ingredien2", "ingredien3", "helmet", "chestplate", "leggings", "boots" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/knightmetal_tool_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/knightmetal_tool_set.json new file mode 100644 index 0000000000..048b49775b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/knightmetal_tool_set.json @@ -0,0 +1,17 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:armor_shard" }]}}, + "ingredien2": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:armor_shard_cluster" }]}}, + "ingredien3": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_ingot" }]}}, + "ingredien4": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_ring" }]}}, + "pickaxe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_pickaxe" }]}}, + "sword" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_sword" }]}}, + "axe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_axe" }]}}, + "shield" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:knightmetal_shield" }]}}, + "blockchain": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:block_and_chain" }]}} + }, + "requirements": [ + [ "ingredient", "ingredien2", "ingredien3", "ingredien4", "pickaxe", "sword", "axe", "shield", "blockchain" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/lifedrain_scepter.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/lifedrain_scepter.json new file mode 100644 index 0000000000..017a2618c0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/lifedrain_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "scepter": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:lifedrain_scepter" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_beans.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_beans.json new file mode 100644 index 0000000000..4940193d8c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_beans.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "beans": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_beans" }]}}, + "used": { "trigger": "twilightforest:has_advancement", "conditions": { "advancement": "twilightforest:alt/treasures/magic_beanstalk" }} + }, + "requirements": [ + [ "beans", "used" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_beanstalk.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_beanstalk.json new file mode 100644 index 0000000000..d526fb6dd8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_beanstalk.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "beans": { "trigger": "twilightforest:on_item_use", "conditions": { "items": [{ "item": "twilightforest:magic_beans" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_map.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_map.json new file mode 100644 index 0000000000..6af6eaf951 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_map.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "magic_map_focus": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_map_focus" }]}}, + "magic_map_empty": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_map_empty" }]}}, + "magic_map" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_map" }]}} + }, + "requirements": [ + [ "magic_map_focus", "magic_map_empty", "magic_map" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_trees.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_trees.json new file mode 100644 index 0000000000..ccf5bf05b0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/magic_trees.json @@ -0,0 +1,24 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/tree_of_time" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/tree_of_transformation" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/tree_of_mining" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/tree_of_sorting" } + } + }, + "requirements": [ + [ "0", "1", "2", "3" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/maps.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/maps.json new file mode 100644 index 0000000000..52a69f448e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/maps.json @@ -0,0 +1,20 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/magic_map" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/maze_map" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/ore_map" } + } + }, + "requirements": [ + [ "0", "1", "2" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/maze_map.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/maze_map.json new file mode 100644 index 0000000000..9c76f148ae --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/maze_map.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "maze_map_focus": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:maze_map_focus" }]}}, + "maze_map_empty": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:maze_map_empty" }]}}, + "maze_map" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:maze_map" }]}} + }, + "requirements": [ + [ "maze_map_focus", "maze_map_empty", "maze_map" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/mazebreaker_pickaxe.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/mazebreaker_pickaxe.json new file mode 100644 index 0000000000..63d2b7bc43 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/mazebreaker_pickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "mazebreaker_pickaxe": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mazebreaker_pickaxe" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axe_diamond.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axe_diamond.json new file mode 100644 index 0000000000..305b63565c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axe_diamond.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "axe": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:minotaur_axe" }]}} + }, + "requirements": [ + [ "axe" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axe_gold.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axe_gold.json new file mode 100644 index 0000000000..aa72a638d8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axe_gold.json @@ -0,0 +1,9 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "axe": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:minotaur_axe_gold" }]}} + }, + "requirements": [ + [ "axe" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axes.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axes.json new file mode 100644 index 0000000000..dd67953991 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/minotaur_axes.json @@ -0,0 +1,16 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "gold": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/minotaur_axe_gold" } + }, + "diamond": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/minotaur_axe_diamond" } + } + }, + "requirements": [ + [ "gold", "diamond" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/moon_dial.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/moon_dial.json new file mode 100644 index 0000000000..285d9c1eef --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/moon_dial.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "moon_dial": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:moon_dial" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/naga_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/naga_armor_set.json new file mode 100644 index 0000000000..2e3f89972a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/naga_armor_set.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:naga_scale" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:naga_chestplate" }]}}, + "leggings" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:naga_leggings" }]}} + }, + "requirements": [ + [ "ingredient", "chestplate", "leggings" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/ore_map.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ore_map.json new file mode 100644 index 0000000000..775c6dd399 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/ore_map.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ore_map_empty": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ore_map_empty" }]}}, + "ore_map" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:ore_map" }]}} + }, + "requirements": [ + [ "ore_map_empty", "ore_map" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/phantom_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/phantom_armor_set.json new file mode 100644 index 0000000000..9c1b225a8b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/phantom_armor_set.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "helmet" : { "trigger": "minecraft:inventory_changed" , "conditions": { "items": [{ "item": "twilightforest:phantom_helmet" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed" , "conditions": { "items": [{ "item": "twilightforest:phantom_chestplate" }]}}, + "worn" : { "trigger": "twilightforest:has_advancement", "conditions": { "advancement": "twilightforest:alt/treasures/phantom_armor_worn" }} + }, + "requirements": [ + [ "helmet", "chestplate", "worn" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/phantom_armor_worn.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/phantom_armor_worn.json new file mode 100644 index 0000000000..e56714f999 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/phantom_armor_worn.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "helmet" : { "trigger": "twilightforest:armor_changed", "conditions": { "to": { "item": "twilightforest:phantom_helmet" }}}, + "chestplate": { "trigger": "twilightforest:armor_changed", "conditions": { "to": { "item": "twilightforest:phantom_chestplate" }}} + }, + "requirements": [ + [ "helmet", "chestplate" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/scepters.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/scepters.json new file mode 100644 index 0000000000..0b2e955078 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/scepters.json @@ -0,0 +1,24 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/twilight_scepter" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/lifedrain_scepter" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/zombie_scepter" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/shield_scepter" } + } + }, + "requirements": [ + [ "0", "1", "2", "3" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/seeker_bow.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/seeker_bow.json new file mode 100644 index 0000000000..46af46b4d4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/seeker_bow.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "bow": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:seeker_bow" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/shield_scepter.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/shield_scepter.json new file mode 100644 index 0000000000..e807e197cb --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/shield_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "scepter": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:shield_scepter" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/smoking_block.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/smoking_block.json new file mode 100644 index 0000000000..24130c8bdb --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/smoking_block.json @@ -0,0 +1,10 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "smoking_block": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:fire_jet", "data": 0 }] }}, + "fire_swamp": { "trigger": "twilightforest:has_advancement", "conditions": { "advancement": "twilightforest:alt/biomes/fire_swamp" }} + }, + "requirements": [ + [ "smoking_block", "fire_swamp" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/steeleaf_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/steeleaf_armor_set.json new file mode 100644 index 0000000000..3165c592e5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/steeleaf_armor_set.json @@ -0,0 +1,13 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_ingot" }]}}, + "helmet" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_helmet" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_chestplate" }]}}, + "leggings" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_leggings" }]}}, + "boots" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_boots" }]}} + }, + "requirements": [ + [ "ingredient", "helmet", "chestplate", "leggings", "boots" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/steeleaf_tool_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/steeleaf_tool_set.json new file mode 100644 index 0000000000..c79c327aba --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/steeleaf_tool_set.json @@ -0,0 +1,14 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_ingot" }]}}, + "pickaxe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_pickaxe" }]}}, + "sword" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_sword" }]}}, + "axe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_axe" }]}}, + "shovel" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_shovel" }]}}, + "hoe" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:steeleaf_hoe" }]}} + }, + "requirements": [ + [ "ingredient", "pickaxe", "sword", "axe", "shovel", "hoe" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/tools.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tools.json new file mode 100644 index 0000000000..8eb7d9f3b3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tools.json @@ -0,0 +1,40 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/ironwood_tool_set" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/steeleaf_tool_set" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/fiery_tool_set" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/fiery_tool_set" } + }, + "4": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/knightmetal_tool_set" } + }, + "5": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/ice_sword" } + }, + "6": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/glass_sword" } + }, + "7": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:alt/treasures/giant_tool_set" } + } + }, + "requirements": [ + [ "0", "1", "2", "3", "4", "5", "6", "7" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_mining.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_mining.json new file mode 100644 index 0000000000..853e5bfbaf --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_mining.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "sapling": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling", "data": 7 }]}}, + "log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 2 }]}}, + "leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 2 }]}} + }, + "requirements": [ + [ "sapling", "log", "leaves" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_sorting.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_sorting.json new file mode 100644 index 0000000000..325f319fd5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_sorting.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "sapling": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling", "data": 8 }]}}, + "log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 3 }]}}, + "leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 3 }]}} + }, + "requirements": [ + [ "sapling", "log", "leaves" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_time.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_time.json new file mode 100644 index 0000000000..398b5245a3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_time.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "sapling": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling", "data": 5 }]}}, + "log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 0 }]}}, + "leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 0 }]}} + }, + "requirements": [ + [ "sapling", "log", "leaves" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_transformation.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_transformation.json new file mode 100644 index 0000000000..56d4e55140 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/tree_of_transformation.json @@ -0,0 +1,11 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "sapling": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling", "data": 6 }]}}, + "log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 1 }]}}, + "leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 1 }]}} + }, + "requirements": [ + [ "sapling", "log", "leaves" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/triple_bow.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/triple_bow.json new file mode 100644 index 0000000000..d71dc96381 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/triple_bow.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "bow": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:triple_bow" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/trophies.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/trophies.json new file mode 100644 index 0000000000..1196282362 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/trophies.json @@ -0,0 +1,44 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "0": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_trophy_pedestal" } + }, + "1": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_naga" } + }, + "2": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_lich" } + }, + "3": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_labyrinth" } + }, + "4": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_hydra" } + }, + "5": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_knights" } + }, + "6": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_ur_ghast" } + }, + "7": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_yeti" } + }, + "8": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_glacier" } + } + }, + "requirements": [ + [ "0", "1", "2", "3", "4", "5", "6", "7", "8" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/trophy_pedestal.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/trophy_pedestal.json new file mode 100644 index 0000000000..d2711cf2c1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/trophy_pedestal.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "trophy_pedestal": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trophy_pedestal" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/twilight_scepter.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/twilight_scepter.json new file mode 100644 index 0000000000..750ddb2c84 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/twilight_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "scepter": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_scepter" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/uncrafting_table.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/uncrafting_table.json new file mode 100644 index 0000000000..24131e7e6d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/uncrafting_table.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "uncrafting_table": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:uncrafting_table" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/yeti_armor_set.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/yeti_armor_set.json new file mode 100644 index 0000000000..7d999c5e02 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/yeti_armor_set.json @@ -0,0 +1,13 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "ingredient": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:alpha_fur" }]}}, + "helmet" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:yeti_helmet" }]}}, + "chestplate": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:yeti_chestplate" }]}}, + "leggings" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:yeti_leggings" }]}}, + "boots" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:yeti_boots" }]}} + }, + "requirements": [ + [ "ingredient", "helmet", "chestplate", "leggings", "boots" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/alt/treasures/zombie_scepter.json b/src/main/resources/assets/twilightforest/advancements/alt/treasures/zombie_scepter.json new file mode 100644 index 0000000000..9e23e56272 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/alt/treasures/zombie_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:alt/root", + "criteria": { + "scepter": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:zombie_scepter" }]}} + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/arborist.json b/src/main/resources/assets/twilightforest/advancements/arborist.json new file mode 100644 index 0000000000..1f851ea3af --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/arborist.json @@ -0,0 +1,114 @@ +{ + "display": { + "icon": { + "item": "twilightforest:twilight_oak_fence" + }, + "title": { + "translate": "advancement.twilightforest.arborist" + }, + "description": { + "translate": "advancement.twilightforest.arborist.desc" + }, + "frame": "challenge" + }, + "parent": "twilightforest:root", + "criteria": { + "root_strands" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_plant" , "data": 8 }]}}, + "root" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:root" , "data": 0 }]}}, + "liveroot" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:root" , "data": 1 }]}}, + "liveroots" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:liveroot" }]}}, + "twilight_oak_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_log" , "data": 0 }]}}, + "twilight_oak_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_leaves" , "data": 0 }]}}, + "rainbow_oak_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_leaves" , "data": 3 }]}}, + "twilight_oak_sapling": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 0 }]}}, + "robust_oak_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 4 }]}}, + "rainbow_oak_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 9 }]}}, + "twilight_oak_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_oak_planks" }]}}, + "twilight_oak_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_oak_stairs" }]}}, + "twilight_oak_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_oak_slab" }]}}, + "twilight_oak_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_oak_button" }]}}, + "twilight_oak_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_oak_fence" }]}}, + "twilight_oak_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_oak_gate" }]}}, + "twilight_oak_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_oak_plate" }]}}, + "canopy_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_log" , "data": 1 }]}}, + "canopy_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_leaves" , "data": 1 }]}}, + "canopy_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 1 }]}}, + "canopy_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:canopy_planks" }]}}, + "canopy_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:canopy_stairs" }]}}, + "canopy_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:canopy_slab" }]}}, + "canopy_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:canopy_button" }]}}, + "canopy_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:canopy_fence" }]}}, + "canopy_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:canopy_gate" }]}}, + "canopy_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:canopy_plate" }]}}, + "mangrove_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_log" , "data": 2 }]}}, + "mangrove_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_leaves" , "data": 2 }]}}, + "mangrove_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 2 }]}}, + "mangrove_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mangrove_planks" }]}}, + "mangrove_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mangrove_stairs" }]}}, + "mangrove_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mangrove_slab" }]}}, + "mangrove_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mangrove_button" }]}}, + "mangrove_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mangrove_fence" }]}}, + "mangrove_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mangrove_gate" }]}}, + "mangrove_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mangrove_plate" }]}}, + "dark_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_log" , "data": 3 }]}}, + "dark_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_leaves" , "data": 0 }]}}, + "dark_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 3 }]}}, + "dark_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_planks" }]}}, + "tower_wood" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:tower_wood" }]}}, + "dark_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_stairs" }]}}, + "dark_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_slab" }]}}, + "dark_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_button" }]}}, + "dark_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_fence" }]}}, + "dark_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_gate" }]}}, + "dark_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:dark_plate" }]}}, + "time_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 0 }]}}, + "time_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 0 }]}}, + "time_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 5 }]}}, + "time_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:time_planks" }]}}, + "time_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:time_stairs" }]}}, + "time_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:time_slab" }]}}, + "time_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:time_button" }]}}, + "time_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:time_fence" }]}}, + "time_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:time_gate" }]}}, + "time_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:time_plate" }]}}, + "trans_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 1 }]}}, + "trans_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 1 }]}}, + "trans_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 6 }]}}, + "trans_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trans_planks" }]}}, + "trans_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trans_stairs" }]}}, + "trans_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trans_slab" }]}}, + "trans_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trans_button" }]}}, + "trans_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trans_fence" }]}}, + "trans_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trans_gate" }]}}, + "trans_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:trans_plate" }]}}, + "mine_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 2 }]}}, + "mine_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 2 }]}}, + "mine_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 7 }]}}, + "mine_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mine_planks" }]}}, + "mine_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mine_stairs" }]}}, + "mine_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mine_slab" }]}}, + "mine_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mine_button" }]}}, + "mine_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mine_fence" }]}}, + "mine_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mine_gate" }]}}, + "mine_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:mine_plate" }]}}, + "sort_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_log" , "data": 3 }]}}, + "sort_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:magic_leaves" , "data": 3 }]}}, + "sort_sapling" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_sapling" , "data": 8 }]}}, + "sort_planks" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:sort_planks" }]}}, + "sort_stairs" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:sort_stairs" }]}}, + "sort_slab" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:sort_slab" }]}}, + "sort_button" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:sort_button" }]}}, + "sort_fence" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:sort_fence" }]}}, + "sort_gate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:sort_gate" }]}}, + "sort_plate" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:sort_plate" }]}}, + "giant_log" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_log" }]}}, + "giant_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:giant_leaves" }]}}, + "huge_stalk" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:huge_stalk" }]}}, + "thorn_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_leaves_3" , "data": 0 }]}}, + "beanstalk_leaves" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:twilight_leaves_3" , "data": 1 }]}}, + "thorn_rose" : { "trigger": "minecraft:inventory_changed", "conditions": { "items": [{ "item": "twilightforest:thorn_rose" }]}} + }, + "rewards": { + "experience": 1000 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/arctic_armor_dyed.json b/src/main/resources/assets/twilightforest/advancements/arctic_armor_dyed.json new file mode 100644 index 0000000000..4006f24a3c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/arctic_armor_dyed.json @@ -0,0 +1,69 @@ +{ + "display": { + "icon": { + "item": "twilightforest:arctic_chestplate" + }, + "title": { + "translate": "advancement.twilightforest.arctic_dyed" + }, + "description": { + "translate": "advancement.twilightforest.arctic_dyed.desc" + } + }, + "parent": "twilightforest:progress_yeti", + "criteria": { + "helmet": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:arctic_helmet", + "nbt": "{display:{hasColor:true}}" + } + ] + } + }, + "chest": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:arctic_chestplate", + "nbt": "{display:{hasColor:true}}" + } + ] + } + }, + "legs": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:arctic_leggings", + "nbt": "{display:{hasColor:true}}" + } + ] + } + }, + "boots": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:arctic_boots", + "nbt": "{display:{hasColor:true}}" + } + ] + } + } + }, + "rewards": { + "experience": 25 + }, + "requirements": [ + [ "helmet" ], + [ "chest" ], + [ "legs" ], + [ "boots" ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/break_glass_sword.json b/src/main/resources/assets/twilightforest/advancements/break_glass_sword.json new file mode 100644 index 0000000000..2175b82c8e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/break_glass_sword.json @@ -0,0 +1,31 @@ +{ + "display": { + "icon": { + "item": "twilightforest:glass_sword" + }, + "title": { + "translate": "advancement.twilightforest.glass_sword" + }, + "description": { + "translate": "advancement.twilightforest.glass_sword.desc" + }, + "frame": "challenge", + "hidden": true + }, + "parent": "twilightforest:progress_yeti", + "criteria": { + "broken_sword": { + "trigger": "minecraft:item_durability_changed", + "conditions": { + "item": { + "item": "twilightforest:glass_sword" + }, + "durability": -1 + } + } + }, + "rewards": { + "experience": 42, + "loot": [ "twilightforest:glass_sword" ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/experiment_115.json b/src/main/resources/assets/twilightforest/advancements/experiment_115.json new file mode 100644 index 0000000000..bc36a7ec6a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/experiment_115.json @@ -0,0 +1,24 @@ +{ + "display": { + "icon": { + "item": "twilightforest:experiment_115" + }, + "title": { + "translate": "advancement.twilightforest.experiment_115" + }, + "description": { + "translate": "advancement.twilightforest.experiment_115.desc" + } + }, + "parent": "twilightforest:progress_knights", + "criteria": { + "eat_experiment_115": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:experiment_115" + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/experiment_115_115.json b/src/main/resources/assets/twilightforest/advancements/experiment_115_115.json new file mode 100644 index 0000000000..eb947846bf --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/experiment_115_115.json @@ -0,0 +1,32 @@ +{ + "display": { + "icon": { + "item": "twilightforest:experiment_115", + "data": 2 + }, + "title": { + "translate": "advancement.twilightforest.experiment_115_3" + }, + "description": { + "translate": "advancement.twilightforest.experiment_115_3.desc" + }, + "frame": "challenge", + "hidden": true + }, + "parent": "twilightforest:experiment_115", + "criteria": { + "eat_115_1": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "__comment": "TEMP UNTIL WE FIGURE OUT HOW TO FIGURE OUT THAT THE PLAYER ATE 115 OF THEM", + "item": "twilightforest:experiment_115", + "count": { + "max": 115, + "min": 63 + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/experiment_115_self_replenishing.json b/src/main/resources/assets/twilightforest/advancements/experiment_115_self_replenishing.json new file mode 100644 index 0000000000..4758e3bb29 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/experiment_115_self_replenishing.json @@ -0,0 +1,29 @@ +{ + "display": { + "icon": { + "item": "twilightforest:experiment_115", + "data": 1 + }, + "title": { + "translate": "advancement.twilightforest.experiment_115_2" + }, + "description": { + "translate": "advancement.twilightforest.experiment_115_2.desc" + }, + "frame": "challenge", + "hidden": true + }, + "parent": "twilightforest:experiment_115", + "criteria": { + "place_complete_experiment_115": { + "trigger": "minecraft:placed_block", + "conditions": { + "block": "twilightforest:experiment_115", + "state": { + "omnomnom": 0, + "regenerate": true + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/fiery_set.json b/src/main/resources/assets/twilightforest/advancements/fiery_set.json new file mode 100644 index 0000000000..a7a3c1f3c5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/fiery_set.json @@ -0,0 +1,84 @@ +{ + "display": { + "icon": { + "item": "twilightforest:fiery_sword" + }, + "title": { + "translate": "advancement.twilightforest.fiery_set" + }, + "description": { + "translate": "advancement.twilightforest.fiery_set.desc" + }, + "frame": "challenge" + }, + "parent": "twilightforest:progress_hydra", + "criteria": { + "sword": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_sword" + } + ] + } + }, + "pick": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_pickaxe" + } + ] + } + }, + "head": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_helmet" + } + ] + } + }, + "chest": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_chestplate" + } + ] + } + }, + "legs": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_leggings" + } + ] + } + }, + "feet": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_boots" + } + ] + } + } + }, + "requirements": [ + [ "sword", "pick" ], + [ "head", "chest", "legs", "feet" ] + ], + "rewards": { + "experience": 75 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/ghast_trap.json b/src/main/resources/assets/twilightforest/advancements/ghast_trap.json new file mode 100644 index 0000000000..2698678fdd --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/ghast_trap.json @@ -0,0 +1,25 @@ +{ + "display": { + "icon": { + "item": "twilightforest:tower_device", + "data": 10 + }, + "title": { + "translate": "advancement.twilightforest.ghast_trap" + }, + "description": { + "translate": "advancement.twilightforest.ghast_trap.desc", + "with": [ + { "translate": "entity.twilightforest.mini_ghast.name" }, + { "translate": "tile.twilightforest.TowerDevice.10.name" }, + { "translate": "entity.twilightforest.ur_ghast.name" } + ] + } + }, + "parent": "twilightforest:progress_knights", + "criteria": { + "activate_ghast_trap": { + "trigger": "twilightforest:activate_ghast_trap" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/hedge.json b/src/main/resources/assets/twilightforest/advancements/hedge.json new file mode 100644 index 0000000000..992c6b5508 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/hedge.json @@ -0,0 +1,44 @@ +{ + "display": { + "icon": { + "item": "twilightforest:hedge" + }, + "title": { + "translate": "advancement.twilightforest.hedge" + }, + "description": { + "translate": "advancement.twilightforest.hedge.desc", + "with": [ + { "translate": "structure.hedge_maze.name" } + ] + } + }, + "parent": "twilightforest:root", + "criteria": { + "hedge_spider": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:hedge_spider", + "location": { + "feature": "twilightforest:hedge_maze" + } + } + } + }, + "swarm_spider": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:swarm_spider", + "location": { + "feature": "twilightforest:hedge_maze" + } + } + } + } + }, + "requirements": [ + [ "hedge_spider", "swarm_spider" ] + ] +} diff --git a/src/main/resources/assets/twilightforest/advancements/hill1.json b/src/main/resources/assets/twilightforest/advancements/hill1.json new file mode 100644 index 0000000000..a89de3aee4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/hill1.json @@ -0,0 +1,45 @@ +{ + "display": { + "icon": { + "item": "minecraft:iron_boots" + }, + "title": { + "translate": "advancement.twilightforest.hill1" + }, + "description": { + "translate": "advancement.twilightforest.hill1.desc", + "with": [ + { "translate": "entity.twilightforest.redcap.name" }, + { "translate": "structure.hollow_hill.name" } + ] + } + }, + "parent": "twilightforest:root", + "criteria": { + "boggard": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:boggard", + "location": { + "feature": "twilightforest:small_hollow_hill" + } + } + } + }, + "redcap": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:redcap", + "location": { + "feature": "twilightforest:small_hollow_hill" + } + } + } + } + }, + "requirements": [ + [ "boggard", "redcap" ] + ] +} diff --git a/src/main/resources/assets/twilightforest/advancements/hill2.json b/src/main/resources/assets/twilightforest/advancements/hill2.json new file mode 100644 index 0000000000..660ba1cc2e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/hill2.json @@ -0,0 +1,31 @@ +{ + "display": { + "icon": { + "item": "twilightforest:ironwood_pickaxe" + }, + "title": { + "translate": "advancement.twilightforest.hill2" + }, + "description": { + "translate": "advancement.twilightforest.hill2.desc", + "with": [ + { "translate": "entity.twilightforest.redcap_sapper.name" }, + { "translate": "structure.hollow_hill.name" } + ] + } + }, + "parent": "twilightforest:hill1", + "criteria": { + "redcap_sapper": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:redcap_sapper", + "location": { + "feature": "twilightforest:medium_hollow_hill" + } + } + } + } + } +} diff --git a/src/main/resources/assets/twilightforest/advancements/hill3.json b/src/main/resources/assets/twilightforest/advancements/hill3.json new file mode 100644 index 0000000000..2da3f54b12 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/hill3.json @@ -0,0 +1,31 @@ +{ + "display": { + "icon": { + "item": "minecraft:glowstone_dust" + }, + "title": { + "translate": "advancement.twilightforest.hill3" + }, + "description": { + "translate": "advancement.twilightforest.hill3.desc", + "with": [ + { "translate": "entity.twilightforest.wraith.name" }, + { "translate": "structure.hollow_hill.name" } + ] + } + }, + "parent": "twilightforest:hill2", + "criteria": { + "wraith": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:wraith", + "location": { + "feature": "twilightforest:large_hollow_hill" + } + } + } + } + } +} diff --git a/src/main/resources/assets/twilightforest/advancements/hydra_chop.json b/src/main/resources/assets/twilightforest/advancements/hydra_chop.json new file mode 100644 index 0000000000..2467cecd05 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/hydra_chop.json @@ -0,0 +1,22 @@ +{ + "display": { + "icon": { + "item": "twilightforest:hydra_chop" + }, + "title": { + "translate": "advancement.twilightforest.hydra_chop" + }, + "description": { + "translate": "advancement.twilightforest.hydra_chop.desc", + "with": [ + { "translate": "entity.twilightforest.hydra.name" } + ] + } + }, + "parent": "twilightforest:progress_hydra", + "criteria": { + "hydra_chop": { + "trigger": "twilightforest:consume_hydra_chop_on_low_hunger" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/lich_scepters.json b/src/main/resources/assets/twilightforest/advancements/lich_scepters.json new file mode 100644 index 0000000000..9aa4a61617 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/lich_scepters.json @@ -0,0 +1,40 @@ +{ + "display": { + "icon": { + "item": "twilightforest:zombie_scepter" + }, + "title": { + "translate": "advancement.twilightforest.lich_scepters" + }, + "description": { + "translate": "advancement.twilightforest.lich_scepters.desc" + }, + "frame": "challenge", + "hidden": true + }, + "parent": "twilightforest:progress_lich", + "criteria": { + "scepters": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:lifedrain_scepter" + }, + { + "item": "twilightforest:twilight_scepter" + }, + { + "item": "twilightforest:zombie_scepter" + }, + { + "item": "twilightforest:shield_scepter" + } + ] + } + } + }, + "rewards": { + "experience": 100 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/magic_map.json b/src/main/resources/assets/twilightforest/advancements/magic_map.json new file mode 100644 index 0000000000..4947ca79d8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/magic_map.json @@ -0,0 +1,27 @@ +{ + "display": { + "icon": { + "item": "twilightforest:magic_map" + }, + "title": { + "translate": "advancement.twilightforest.magic_map" + }, + "description": { + "translate": "advancement.twilightforest.magic_map.desc", + "with": [ { "translate": "item.twilightforest.magicMap.name" } ] + } + }, + "parent": "twilightforest:magic_map_focus", + "criteria": { + "map": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:magic_map" + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/magic_map_focus.json b/src/main/resources/assets/twilightforest/advancements/magic_map_focus.json new file mode 100644 index 0000000000..2fcf871f0a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/magic_map_focus.json @@ -0,0 +1,32 @@ +{ + "display": { + "icon": { + "item": "twilightforest:magic_map_focus" + }, + "title": { + "translate": "advancement.twilightforest.magic_map_focus" + }, + "description": { + "translate": "advancement.twilightforest.magic_map_focus.desc", + "with": [ + { "translate": "item.twilightforest.magicMapFocus.name" }, + { "translate": "item.twilightforest.tfFeather.name" }, + { "translate": "item.yellowDust.name" }, + { "translate": "item.twilightforest.torchberries.name" } + ] + } + }, + "parent": "twilightforest:twilight_hunter", + "criteria": { + "focus": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:magic_map_focus" + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/maze_map.json b/src/main/resources/assets/twilightforest/advancements/maze_map.json new file mode 100644 index 0000000000..3ddfc30f1e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/maze_map.json @@ -0,0 +1,29 @@ +{ + "display": { + "icon": { + "item": "twilightforest:maze_map" + }, + "title": { + "translate": "advancement.twilightforest.maze_map" + }, + "description": { + "translate": "advancement.twilightforest.maze_map.desc", + "with": [ + { "translate": "item.twilightforest.mazeMap.name" } + ] + } + }, + "parent": "twilightforest:magic_map", + "criteria": { + "map": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:maze_map" + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/mazebreaker.json b/src/main/resources/assets/twilightforest/advancements/mazebreaker.json new file mode 100644 index 0000000000..500a0ce09f --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/mazebreaker.json @@ -0,0 +1,33 @@ +{ + "display": { + "icon": { + "item": "twilightforest:mazebreaker_pickaxe" + }, + "title": { + "translate": "advancement.twilightforest.mazebreaker" + }, + "description": { + "translate": "advancement.twilightforest.mazebreaker.desc", + "with": [ + { "translate": "item.twilightforest.mazebreakerPick.name" } + ] + }, + "frame": "challenge" + }, + "parent": "twilightforest:progress_labyrinth", + "criteria": { + "pick": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:mazebreaker_pickaxe" + } + ] + } + } + }, + "rewards": { + "experience": 50 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/naga_armors.json b/src/main/resources/assets/twilightforest/advancements/naga_armors.json new file mode 100644 index 0000000000..54c0e832f5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/naga_armors.json @@ -0,0 +1,36 @@ +{ + "display": { + "icon": { + "item": "twilightforest:naga_chestplate" + }, + "title": { + "translate": "advancement.twilightforest.naga_armors" + }, + "description": { + "translate": "advancement.twilightforest.naga_armors.desc", + "with": [ + { "translate": "item.twilightforest.nagaScale.name" } + ] + }, + "frame": "challenge" + }, + "parent": "twilightforest:progress_naga", + "criteria": { + "armor": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:naga_chestplate" + }, + { + "item": "twilightforest:naga_leggings" + } + ] + } + } + }, + "rewards": { + "experience": 25 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/ore_map.json b/src/main/resources/assets/twilightforest/advancements/ore_map.json new file mode 100644 index 0000000000..4fd9ab21a7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/ore_map.json @@ -0,0 +1,31 @@ +{ + "display": { + "icon": { + "item": "twilightforest:ore_map" + }, + "title": { + "translate": "advancement.twilightforest.ore_map" + }, + "description": { + "translate": "advancement.twilightforest.ore_map.desc", + "with": [ + { "translate": "item.twilightforest.oreMap.name" } + ] + }, + "frame": "challenge", + "hidden": true + }, + "parent": "twilightforest:maze_map", + "criteria": { + "map": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:ore_map" + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_castle.json b/src/main/resources/assets/twilightforest/advancements/progress_castle.json new file mode 100644 index 0000000000..7bd033269b --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_castle.json @@ -0,0 +1,28 @@ +{ + "display": { + "icon": { + "item": "twilightforest:castle_rune_brick", + "data": 3 + }, + "title": { + "translate": "advancement.twilightforest.progress_castle" + }, + "description": { + "translate": "advancement.twilightforest.progress_castle.desc" + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_thorns", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:final_castle" } + }, + "previous_progression": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_thorns" + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_glacier.json b/src/main/resources/assets/twilightforest/advancements/progress_glacier.json new file mode 100644 index 0000000000..0a77bece4e --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_glacier.json @@ -0,0 +1,54 @@ +{ + "display": { + "icon": { + "item": "twilightforest:trophy", + "data": 5 + }, + "title": { + "translate": "advancement.twilightforest.progress_glacier" + }, + "description": { + "translate": "advancement.twilightforest.progress_glacier.desc", + "with": [ + { "translate": "entity.twilightforest.snow_queen.name" }, + { "translate": "structure.aurora_palace.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_yeti", + "criteria": { + "queen": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:snow_queen" + } + } + }, + "trophy": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:trophy", + "data": 5 + } + ] + } + }, + "previous_progression": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_yeti" + } + } + }, + "requirements": [ + [ "queen", "trophy" ], + [ "previous_progression" ] + ], + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_hydra.json b/src/main/resources/assets/twilightforest/advancements/progress_hydra.json new file mode 100644 index 0000000000..8060b863f7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_hydra.json @@ -0,0 +1,63 @@ +{ + "display": { + "icon": { + "item": "twilightforest:trophy", + "data": 2 + }, + "title": { + "translate": "advancement.twilightforest.kill_hydra" + }, + "description": { + "translate": "advancement.twilightforest.kill_hydra.desc", + "with": [ + { "translate": "entity.twilightforest.hydra.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_labyrinth", + "criteria": { + "hydra": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:hydra" + } + } + }, + "trophy": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:trophy", + "data": 2 + } + ] + } + }, + "blood": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_blood" + } + ] + } + }, + "stroganoff": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_labyrinth" + } + } + }, + "requirements": [ + [ "hydra", "trophy", "blood" ], + [ "stroganoff" ] + ], + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_knights.json b/src/main/resources/assets/twilightforest/advancements/progress_knights.json new file mode 100644 index 0000000000..707cf54db2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_knights.json @@ -0,0 +1,57 @@ +{ + "display": { + "icon": { + "item": "twilightforest:trophy", + "data": 4 + }, + "title": { + "translate": "advancement.twilightforest.progress_knights" + }, + "description": { + "translate": "advancement.twilightforest.progress_knights.desc" + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_trophy_pedestal", + "criteria": { + "knight": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:knight_phantom" + } + } + }, + "trophy": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:trophy", + "data": 4 + } + ] + } + }, + "structure": { + "trigger": "twilightforest:structure_cleared", + "conditions": { + "structure": "knight_stronghold" + } + }, + "previous_progression": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_trophy_pedestal" + } + } + }, + "requirements": [ + [ "knight", "trophy" ], + [ "structure" ], + [ "previous_progression" ] + ], + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_labyrinth.json b/src/main/resources/assets/twilightforest/advancements/progress_labyrinth.json new file mode 100644 index 0000000000..3c711f6600 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_labyrinth.json @@ -0,0 +1,34 @@ +{ + "display": { + "icon": { + "item": "twilightforest:meef_stroganoff" + }, + "title": { + "translate": "advancement.twilightforest.progress_labyrinth" + }, + "description": { + "translate": "advancement.twilightforest.progress_labyrinth.desc" + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_lich", + "criteria": { + "meef": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:meef_stroganoff" + } + } + }, + "kill_lich": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_lich" + } + } + }, + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_lich.json b/src/main/resources/assets/twilightforest/advancements/progress_lich.json new file mode 100644 index 0000000000..f831cb724c --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_lich.json @@ -0,0 +1,93 @@ +{ + "display": { + "icon": { + "item": "twilightforest:miniature_structure", + "data": 6 + }, + "title": { + "translate": "advancement.twilightforest.kill_lich" + }, + "description": { + "translate": "advancement.twilightforest.kill_lich.desc", + "with": [ + { "translate": "entity.twilightforest.lich.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_naga", + "criteria": { + "kill_lich": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:lich" + } + } + }, + "trophy": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:trophy", + "data": 1 + } + ] + } + }, + "lifedrain_scepter": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:lifedrain_scepter" + } + ] + } + }, + "twilight_scepter": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:twilight_scepter" + } + ] + } + }, + "zombie_scepter": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:zombie_scepter" + } + ] + } + }, + "shield_scepter": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:shield_scepter" + } + ] + } + }, + "kill_naga": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_naga" + } + } + }, + "requirements": [ + [ "kill_lich", "trophy", "lifedrain_scepter", "twilight_scepter", "zombie_scepter", "shield_scepter" ], + [ "kill_naga" ] + ], + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_merge.json b/src/main/resources/assets/twilightforest/advancements/progress_merge.json new file mode 100644 index 0000000000..85b381538a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_merge.json @@ -0,0 +1,29 @@ +{ + "display": { + "icon" : { "item" : "twilightforest:uberous_soil" }, + "title" : { "translate": "advancement.twilightforest.progress_merge" }, + "description": { "translate": "advancement.twilightforest.progress_merge.desc", + "with" : [ + { "translate": "entity.twilightforest.hydra.name" }, + { "translate": "entity.twilightforest.ur_ghast.name" }, + { "translate": "entity.twilightforest.snow_queen.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_lich", + "criteria": { + "hydra": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_hydra" } + }, + "snow_queen": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_glacier" } + }, + "ur_ghast": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_ur_ghast" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_naga.json b/src/main/resources/assets/twilightforest/advancements/progress_naga.json new file mode 100644 index 0000000000..87081282d9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_naga.json @@ -0,0 +1,53 @@ +{ + "display": { + "icon": { + "item": "twilightforest:miniature_structure", + "data": 5 + }, + "title": { + "translate": "advancement.twilightforest.kill_naga" + }, + "description": { + "translate": "advancement.twilightforest.kill_naga.desc", + "with": [ + { "translate": "entity.twilightforest.naga.name" }, + { "translate": "item.twilightforest.nagaScale.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:twilight_hunter", + "criteria": { + "naga": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:naga" + } + } + }, + "scale": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:naga_scale" + } + ] + } + }, + "kill_mob": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:twilight_hunter" + } + } + }, + "requirements": [ + [ "naga", "scale" ], + [ "kill_mob" ] + ], + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_thorns.json b/src/main/resources/assets/twilightforest/advancements/progress_thorns.json new file mode 100644 index 0000000000..f3687da923 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_thorns.json @@ -0,0 +1,27 @@ +{ + "display": { + "icon": { + "item": "twilightforest:thorns" + }, + "title": { + "translate": "advancement.twilightforest.progress_thorns" + }, + "description": { + "translate": "advancement.twilightforest.progress_thorns.desc" + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_troll", + "criteria": { + "discover": { + "trigger": "minecraft:location", + "conditions": { "feature": "twilightforest:final_castle" } + }, + "previous_progression": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_troll" + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_troll.json b/src/main/resources/assets/twilightforest/advancements/progress_troll.json new file mode 100644 index 0000000000..9cd90b0b8a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_troll.json @@ -0,0 +1,23 @@ +{ + "display": { + "icon" : { "item" : "twilightforest:lamp_of_cinders" }, + "title" : { "translate": "advancement.twilightforest.progress_troll" }, + "description": { "translate": "advancement.twilightforest.progress_troll.desc", + "with" : [ + { "translate": "item.twilightforest.lampOfCinders.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_merge", + "criteria": { + "lamp": { + "trigger": "minecraft:inventory_changed", + "conditions": { "items": [ { "item": "twilightforest:lamp_of_cinders" } ] } + }, + "previous_progression": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_merge" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_trophy_pedestal.json b/src/main/resources/assets/twilightforest/advancements/progress_trophy_pedestal.json new file mode 100644 index 0000000000..bda32bf82d --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_trophy_pedestal.json @@ -0,0 +1,24 @@ +{ + "display": { + "icon": { + "item": "twilightforest:trophy_pedestal" + }, + "title": { + "translate": "advancement.twilightforest.progress_trophy_pedestal" + }, + "description": { + "translate": "advancement.twilightforest.progress_trophy_pedestal.desc" + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_lich", + "criteria": { + "trophy_pedestal": { + "trigger": "twilightforest:placed_on_trophy_pedestal" + }, + "kill_lich": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_lich" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_ur_ghast.json b/src/main/resources/assets/twilightforest/advancements/progress_ur_ghast.json new file mode 100644 index 0000000000..4824e4e453 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_ur_ghast.json @@ -0,0 +1,63 @@ +{ + "display": { + "icon": { + "item": "twilightforest:trophy", + "data": 3 + }, + "title": { + "translate": "advancement.twilightforest.progress_ur_ghast" + }, + "description": { + "translate": "advancement.twilightforest.progress_ur_ghast.desc", + "with": [ + { "translate": "entity.twilightforest.ur_ghast.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:ghast_trap", + "criteria": { + "ghast": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:ur_ghast" + } + } + }, + "trophy": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:trophy", + "data": 3 + } + ] + } + }, + "tear": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "twilightforest:fiery_tears" + } + ] + } + }, + "previous_progression": { + "trigger": "twilightforest:has_advancement", + "conditions": { + "advancement": "twilightforest:progress_knights" + } + } + }, + "requirements": [ + [ "ghast", "trophy", "tear" ], + [ "previous_progression" ] + ], + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/progress_yeti.json b/src/main/resources/assets/twilightforest/advancements/progress_yeti.json new file mode 100644 index 0000000000..0aa059064a --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/progress_yeti.json @@ -0,0 +1,39 @@ +{ + "display": { + "icon": { + "item": "twilightforest:alpha_fur" + }, + "title": { + "translate": "advancement.twilightforest.progress_yeti" + }, + "description": { + "translate": "advancement.twilightforest.progress_yeti.desc", + "with": [ + { "translate": "entity.twilightforest.yeti_alpha.name" } + ] + }, + "frame": "goal" + }, + "parent": "twilightforest:progress_lich", + "criteria": { + "yeti": { + "trigger": "minecraft:player_killed_entity", + "conditions": { "entity": { "type": "twilightforest:yeti_alpha" } } + }, + "fur": { + "trigger": "minecraft:inventory_changed", + "conditions": { "items": [ { "item": "twilightforest:alpha_fur" } ] } + }, + "previous_progression": { + "trigger": "twilightforest:has_advancement", + "conditions": { "advancement": "twilightforest:progress_lich" } + } + }, + "requirements": [ + [ "yeti", "fur" ], + [ "previous_progression" ] + ], + "rewards": { + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/quest_ram.json b/src/main/resources/assets/twilightforest/advancements/quest_ram.json new file mode 100644 index 0000000000..d206cfb331 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/quest_ram.json @@ -0,0 +1,27 @@ +{ + "display": { + "icon": { + "item": "twilightforest:trophy", + "data": 8 + }, + "title": { + "translate": "advancement.twilightforest.quest_ram" + }, + "description": { + "translate": "advancement.twilightforest.quest_ram.desc", + "with": [ + { "translate": "entity.twilightforest.quest_ram.name" } + ] + } + }, + "parent": "twilightforest:root", + "criteria": { + "quest_ram_complete": { + "trigger": "twilightforest:complete_quest_ram" + } + }, + "rewards": { + "experience": 100, + "function": "twilightforest:give_3_shields" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/root.json b/src/main/resources/assets/twilightforest/advancements/root.json new file mode 100644 index 0000000000..96933bb60f --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/root.json @@ -0,0 +1,30 @@ +{ + "display": { + "icon": { + "item": "twilightforest:miniature_structure" + }, + "title": { + "translate": "itemGroup.twilightForest" + }, + "description": { + "translate": "advancement.twilightforest.root.desc" + }, + "background": "twilightforest:textures/blocks/mazestone_large_brick.png", + "announce_to_chat": false + }, + "criteria": { + "in_tf": { + "trigger": "minecraft:location", + "conditions": { + "dimension": "twilight_forest" + } + }, + "make_portal": { + "trigger": "twilightforest:make_tf_portal" + } + }, + "requirements": [[ + "in_tf", + "make_portal" + ]] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/twilight_dinner.json b/src/main/resources/assets/twilightforest/advancements/twilight_dinner.json new file mode 100644 index 0000000000..6b0fe90035 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/twilight_dinner.json @@ -0,0 +1,92 @@ +{ + "display": { + "icon": { + "item": "minecraft:bowl" + }, + "title": { + "translate": "advancement.twilightforest.twilight_dining" + }, + "description": { + "translate": "advancement.twilightforest.twilight_dining.desc" + }, + "frame": "challenge" + }, + "parent": "twilightforest:root", + "criteria": { + "raw_venison": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:raw_venison" + } + } + }, + "cooked_venison": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:cooked_venison" + } + } + }, + "raw_meef": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:raw_meef" + } + } + }, + "cooked_meef": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:cooked_meef" + } + } + }, + "meef_stroganoff": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:meef_stroganoff" + } + } + }, + "hydra_chop": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:hydra_chop" + } + } + }, + "maze_wafer": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:maze_wafer" + } + } + }, + "experiment_115": { + "trigger": "minecraft:consume_item", + "conditions": { + "item": { + "item": "twilightforest:experiment_115" + } + } + } + }, + "requirements": [ + [ "raw_venison", "cooked_venison" ], + [ "raw_meef", "cooked_meef" ], + [ "meef_stroganoff" ], + [ "hydra_chop" ], + [ "maze_wafer" ], + [ "experiment_115" ] + ], + "rewards": { + "experience": 75 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/advancements/twilight_hunter.json b/src/main/resources/assets/twilightforest/advancements/twilight_hunter.json new file mode 100644 index 0000000000..89e9f3c317 --- /dev/null +++ b/src/main/resources/assets/twilightforest/advancements/twilight_hunter.json @@ -0,0 +1,480 @@ +{ + "display": { + "icon": { + "item": "twilightforest:raven_feather" + }, + "title": { + "translate": "advancement.twilightforest.twilight_hunter" + }, + "description": { + "translate": "advancement.twilightforest.twilight_hunter.desc" + } + }, + "parent": "twilightforest:root", + "criteria": { + "adherent": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:adherent", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "blockchain_goblin": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:blockchain_goblin", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "boggard": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:boggard", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "death_tome": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:death_tome", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "fire_beetle": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:fire_beetle", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "hedge_spider": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:hedge_spider", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "helmet_crab": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:helmet_crab", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "hostile_wolf": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:hostile_wolf", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "stable_ice_core": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:stable_ice_core", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "unstable_ice_core": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:unstable_ice_core", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "kobold": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:kobold", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "minotaur": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:minotaur", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "mosquito_swarm": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:mosquito_swarm", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "pinch_beetle": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:pinch_beetle", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "redcap": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:redcap", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "redcap_sapper": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:redcap_sapper", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "skeleton_druid": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:skeleton_druid", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "slime_beetle": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:slime_beetle", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "swarm_spider": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:swarm_spider", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "troll": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:troll", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "wraith": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:wraith", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "yeti": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:yeti", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + + "hydra": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:hydra", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "knight_phantom": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:knight_phantom", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "lich": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:lich", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "lich_minion": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:lich_minion", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "naga": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:naga", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "snow_queen": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:snow_queen", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "ur_ghast": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:ur_ghast", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "yeti_alpha": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:yeti_alpha", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + + "bighorn_sheep": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:bighorn_sheep", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "wild_boar": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:wild_boar", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "bunny": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:bunny", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "deer": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:deer", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "penguin": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:penguin", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "raven": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:raven", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "squirrel": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:squirrel", + "location": { + "dimension": "twilight_forest" + } + } + } + }, + "tiny_bird": { + "trigger": "minecraft:player_killed_entity", + "conditions": { + "entity": { + "type": "twilightforest:tiny_bird", + "location": { + "dimension": "twilight_forest" + } + } + } + } + }, + "requirements": [ + [ + "adherent", + "blockchain_goblin", + "boggard", + "death_tome", + "fire_beetle", + "hedge_spider", + "helmet_crab", + "hostile_wolf", + "stable_ice_core", + "unstable_ice_core", + "kobold", + "minotaur", + "mosquito_swarm", + "pinch_beetle", + "redcap", + "redcap_sapper", + "skeleton_druid", + "slime_beetle", + "swarm_spider", + "troll", + "wraith", + "yeti", + + "hydra", + "knight_phantom", + "lich", + "lich_minion", + "naga", + "snow_queen", + "ur_ghast", + "yeti_alpha", + + "bighorn_sheep", + "wild_boar", + "bunny", + "deer", + "penguin", + "raven", + "squirrel", + "tiny_bird" + ] + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/aurora_block.json b/src/main/resources/assets/twilightforest/blockstates/aurora_block.json new file mode 100644 index 0000000000..df13e8146d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/aurora_block.json @@ -0,0 +1,72 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/tinted_cube_all" + }, + "variants": { + "variant=0" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick0" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick1" }, "weight":1 } + ], + "variant=1" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick1" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick2" }, "weight":1 } + ], + "variant=2" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick2" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick3" }, "weight":1 } + ], + "variant=3" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick3" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick4" }, "weight":1 } + ], + "variant=4" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick4" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick5" }, "weight":1 } + ], + "variant=5" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick5" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick6" }, "weight":1 } + ], + "variant=6" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick6" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick7" }, "weight":1 } + ], + "variant=7" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick7" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick8" }, "weight":1 } + ], + "variant=8" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick8" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick9" }, "weight":1 } + ], + "variant=9" : [ + { "textures": { "all": "twilightforest:blocks/aurorabrick9" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick10" }, "weight":1 } + ], + "variant=10": [ + { "textures": { "all": "twilightforest:blocks/aurorabrick10" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick11" }, "weight":1 } + ], + "variant=11": [ + { "textures": { "all": "twilightforest:blocks/aurorabrick11" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick12" }, "weight":1 } + ], + "variant=12": [ + { "textures": { "all": "twilightforest:blocks/aurorabrick12" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick13" }, "weight":1 } + ], + "variant=13": [ + { "textures": { "all": "twilightforest:blocks/aurorabrick13" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick14" }, "weight":1 } + ], + "variant=14": [ + { "textures": { "all": "twilightforest:blocks/aurorabrick14" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick15" }, "weight":1 } + ], + "variant=15": [ + { "textures": { "all": "twilightforest:blocks/aurorabrick15" }, "weight":3 }, + { "textures": { "all": "twilightforest:blocks/aurorabrick0" }, "weight":1 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/aurora_pillar.json b/src/main/resources/assets/twilightforest/blockstates/aurora_pillar.json new file mode 100644 index 0000000000..2e896cf6df --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/aurora_pillar.json @@ -0,0 +1,17 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/tinted_cube_column", + "textures": { + "end": "twilightforest:blocks/aurora_pillar_top", + "side": "twilightforest:blocks/aurora_pillar_side" + } + }, + "variants": { + "axis": { + "y": {}, + "z": { "x": 90 }, + "x": { "x": 90, "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/aurora_slab.json b/src/main/resources/assets/twilightforest/blockstates/aurora_slab.json new file mode 100644 index 0000000000..534e8ca1a3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/aurora_slab.json @@ -0,0 +1,13 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/tinted_slab", + "textures": { + "top": "twilightforest:blocks/aurora_pillar_top", + "side": "twilightforest:blocks/aurora_slab_side", + "bottom": "twilightforest:blocks/aurora_pillar_top" + }, + "uvlock": true + }, + "variants": { "half": { "bottom": {}, "top": { "x": 180 } } } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/auroralized_glass.json b/src/main/resources/assets/twilightforest/blockstates/auroralized_glass.json new file mode 100644 index 0000000000..fb387e0f0e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/auroralized_glass.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:util/tinted_cube_all" }, + "variants": { + "inventory": [{}], + "normal": [{ "textures": { "all": "twilightforest:blocks/auroralized_glass" }}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/block_storage.json b/src/main/resources/assets/twilightforest/blockstates/block_storage.json new file mode 100644 index 0000000000..0d91c9d643 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/block_storage.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "inventory_fiery" : [{ "textures": { "all": "twilightforest:blocks/fiery_block" } }], + "variant=ironwood": [{ "model": "twilightforest:ironwood_block" }], + "variant=fiery": [{ "model": "twilightforest:fiery_block" }], + "variant=steelleaf": [ + { "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "y": 90, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "y":180, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "y":270, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 90, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 90, "y": 90, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 90, "y":180, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 90, "y":270, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 180, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 180, "y": 90, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 180, "y":180, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 180, "y":270, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 270, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 270, "y": 90, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 270, "y":180, "textures": { "all": "twilightforest:blocks/steelleaf_block" } }, + { "x": 270, "y":270, "textures": { "all": "twilightforest:blocks/steelleaf_block" } } + ], + "variant=arctic_fur": [{ "textures": { "all": "twilightforest:blocks/arctic_fur_block" } }], + "variant=carminite": [ + { "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "y": 90, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "y":180, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "y":270, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 90, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 90, "y": 90, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 90, "y":180, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 90, "y":270, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 180, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 180, "y": 90, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 180, "y":180, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 180, "y":270, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 270, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 270, "y": 90, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 270, "y":180, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } }, + { "x": 270, "y":270, "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/carminite_block", "all2": "twilightforest:blocks/carminite_block_overlay" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/boss_spawner.json b/src/main/resources/assets/twilightforest/blockstates/boss_spawner.json new file mode 100644 index 0000000000..e8461ae0fe --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/boss_spawner.json @@ -0,0 +1,5 @@ +{ + "forge_marker": 1, + "defaults": { "model": "mob_spawner_cage" }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/burnt_thorns.json b/src/main/resources/assets/twilightforest/blockstates/burnt_thorns.json new file mode 100644 index 0000000000..fb5a70892f --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/burnt_thorns.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "transform": "forge:default-block", + "textures": { + "end": "twilightforest:blocks/burnt_thorns_top", + "side": "twilightforest:blocks/burnt_thorns_side", + "particle": "#end" + }, + "model": "twilightforest:thorns_main" + }, + "variants": { + "axis":{ + "x":{ "x": 90, "y": 90 }, + "y":{}, + "z":{ "x": 270, "y": 180 } + }, + "north":{ + "true":{ "submodel": { "key_n": { "model": "twilightforest:thorns_section_top", "y": 270 } } }, + "false":{} + }, + "south":{ + "true":{ "submodel": { "key_s": { "model": "twilightforest:thorns_section_bottom", "y": 270 } } }, + "false":{} + }, + "east":{ + "true":{ "submodel": { "key_e": { "model": "twilightforest:thorns_section_top", "y": 0 } } }, + "false":{} + }, + "west":{ + "true":{ "submodel": { "key_w": { "model": "twilightforest:thorns_section_bottom", "y": 0 } } }, + "false":{} + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_button.json b/src/main/resources/assets/twilightforest/blockstates/canopy_button.json new file mode 100644 index 0000000000..5d5189bf19 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_door.json b/src/main/resources/assets/twilightforest/blockstates/canopy_door.json new file mode 100644 index 0000000000..339acb8aa0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/canopy_lower", + "top" : "twilightforest:blocks/wood/door/canopy_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/canopy_doubleslab.json new file mode 100644 index 0000000000..ce0f8d2ede --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_canopy_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_canopy_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_canopy_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_canopy_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_fence.json b/src/main/resources/assets/twilightforest/blockstates/canopy_fence.json new file mode 100644 index 0000000000..db54d99a63 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_gate.json b/src/main/resources/assets/twilightforest/blockstates/canopy_gate.json new file mode 100644 index 0000000000..15ba11bea0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_planks.json b/src/main/resources/assets/twilightforest/blockstates/canopy_planks.json new file mode 100644 index 0000000000..48095dd8f8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_canopy_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_canopy_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_canopy_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_canopy_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_plate.json b/src/main/resources/assets/twilightforest/blockstates/canopy_plate.json new file mode 100644 index 0000000000..407267ebe7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_canopy_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_slab.json b/src/main/resources/assets/twilightforest/blockstates/canopy_slab.json new file mode 100644 index 0000000000..0602ba6233 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_0", + "top" : "twilightforest:blocks/wood/planks_canopy_0", + "side" : "twilightforest:blocks/wood/planks_canopy_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_0", + "top" : "twilightforest:blocks/wood/planks_canopy_0", + "side" : "twilightforest:blocks/wood/planks_canopy_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_1", + "top" : "twilightforest:blocks/wood/planks_canopy_1", + "side" : "twilightforest:blocks/wood/planks_canopy_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_2", + "top" : "twilightforest:blocks/wood/planks_canopy_2", + "side" : "twilightforest:blocks/wood/planks_canopy_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_3", + "top" : "twilightforest:blocks/wood/planks_canopy_3", + "side" : "twilightforest:blocks/wood/planks_canopy_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_0", + "top" : "twilightforest:blocks/wood/planks_canopy_0", + "side" : "twilightforest:blocks/wood/planks_canopy_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_1", + "top" : "twilightforest:blocks/wood/planks_canopy_1", + "side" : "twilightforest:blocks/wood/planks_canopy_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_2", + "top" : "twilightforest:blocks/wood/planks_canopy_2", + "side" : "twilightforest:blocks/wood/planks_canopy_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_3", + "top" : "twilightforest:blocks/wood/planks_canopy_3", + "side" : "twilightforest:blocks/wood/planks_canopy_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_stairs.json b/src/main/resources/assets/twilightforest/blockstates/canopy_stairs.json new file mode 100644 index 0000000000..a915a3093f --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_canopy_0", + "top" : "twilightforest:blocks/wood/planks_canopy_0", + "side" : "twilightforest:blocks/wood/planks_canopy_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_0", "top": "twilightforest:blocks/wood/planks_canopy_0", "side": "twilightforest:blocks/wood/planks_canopy_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_1", "top": "twilightforest:blocks/wood/planks_canopy_1", "side": "twilightforest:blocks/wood/planks_canopy_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_2", "top": "twilightforest:blocks/wood/planks_canopy_2", "side": "twilightforest:blocks/wood/planks_canopy_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_canopy_3", "top": "twilightforest:blocks/wood/planks_canopy_3", "side": "twilightforest:blocks/wood/planks_canopy_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/canopy_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/canopy_trapdoor.json new file mode 100644 index 0000000000..23ee16763b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/canopy_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/canopy_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_brick.json b/src/main/resources/assets/twilightforest/blockstates/castle_brick.json new file mode 100644 index 0000000000..276e51ee8e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_brick.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_all"}, + "variants": { + "variant=normal": [{ "textures": { "all": "twilightforest:blocks/castleblock_brick" } }], + "variant=worn": [{ "textures": { "all": "twilightforest:blocks/castleblock_faded" } }], + "variant=cracked": [{ "textures": { "all": "twilightforest:blocks/castleblock_cracked" } }], + "variant=roof": [ + { "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "y": 90, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "y":180, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "y":270, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 90, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 90, "y": 90, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 90, "y":180, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 90, "y":270, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 180, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 180, "y": 90, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 180, "y":180, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 180, "y":270, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 270, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 270, "y": 90, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 270, "y":180, "textures": { "all": "twilightforest:blocks/castleblock_roof" } }, + { "x": 270, "y":270, "textures": { "all": "twilightforest:blocks/castleblock_roof" } } + ], + "variant=mossy": [{ "textures": { "all": "twilightforest:blocks/castleblock_mossy" } }], + "variant=frame": [{ "model": "twilightforest:castleblock_frame" }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_door.json b/src/main/resources/assets/twilightforest/blockstates/castle_door.json new file mode 100644 index 0000000000..73b3a79d53 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_door.json @@ -0,0 +1,10 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:castle_door", + "textures": { "all": "twilightforest:blocks/castle_door" } }, + "inventory": [{}], + "variants": { + "lock_index": { "0": {}, "1": {}, "2": {}, "3": {} }, + "active": { "true": {}, "false": {} } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_door_vanished.json b/src/main/resources/assets/twilightforest/blockstates/castle_door_vanished.json new file mode 100644 index 0000000000..ee29894b1a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_door_vanished.json @@ -0,0 +1,12 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:castle_door" }, + "inventory": [{}], + "variants": { + "lock_index": { "0": {}, "1": {}, "2": {}, "3": {} }, + "active": { + "true": { "textures": { "all": "twilightforest:blocks/castle_door_vanished_active" } }, + "false": { "textures": { "all": "twilightforest:blocks/castle_door_vanished" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_pillar.json b/src/main/resources/assets/twilightforest/blockstates/castle_pillar.json new file mode 100644 index 0000000000..adc365cf58 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_pillar.json @@ -0,0 +1,27 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/cube_column_rotationally_correct", + "textures": { "particle": "#side" } + }, + "variants": { + "axis": { + "y": { "model": "cube_column" }, + "z": { "model": "twilightforest:util/cube_column_rotationally_correct_z", "x": 90 }, + "x": { "model": "twilightforest:util/cube_column_rotationally_correct_x", "x": 90, "y": 90 }, + "none": { "model": "cube_all" } + }, + "variant": { + "encased": { "textures": { + "end": "twilightforest:blocks/castle_pillar_encased_end" , + "side": "twilightforest:blocks/castle_pillar_encased_side", + "all": "twilightforest:blocks/castle_pillar_encased_end" + } }, + "bold": { "textures": { + "end": "twilightforest:blocks/castle_pillar_bold_end" , + "side": "twilightforest:blocks/castle_pillar_bold_side" , + "all": "twilightforest:blocks/castle_pillar_bold_tiles" + } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_rune_brick.json b/src/main/resources/assets/twilightforest/blockstates/castle_rune_brick.json new file mode 100644 index 0000000000..379ba73534 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_rune_brick.json @@ -0,0 +1,46 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:util/cube_all_2_layer", "textures": { "all": "twilightforest:blocks/castleblock_brick" } }, + "variants": { + "color=pink": [ + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_0" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_1" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_2" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_3" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_4" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_5" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_6" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_7" } } + ], + "color=blue": [ + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_0" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_1" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_2" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_3" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_4" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_5" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_6" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_7" } } + ], + "color=yellow": [ + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_0" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_1" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_2" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_3" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_4" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_5" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_6" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_7" } } + ], + "color=purple": [ + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_0" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_1" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_2" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_3" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_4" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_5" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_6" } }, + { "textures": { "all2": "twilightforest:blocks/castleblock_magic_7" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_stairs.json b/src/main/resources/assets/twilightforest/blockstates/castle_stairs.json new file mode 100644 index 0000000000..f1877c940e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_stairs.json @@ -0,0 +1,107 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/stairs", + "textures": { + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "twilightforest:util/outer_stairs" }, + "outer_left": { "model": "twilightforest:util/outer_stairs" }, + "inner_right":{ "model": "twilightforest:util/inner_stairs" }, + "inner_left": { "model": "twilightforest:util/inner_stairs" } + }, + "variant": { + "encased": { "textures": { + "end": "twilightforest:blocks/castleblock_tile", + "half": "twilightforest:blocks/castleblock_roof", + "side": "twilightforest:blocks/castle_pillar_encased_h" + } }, + "bold": { "textures": { + "end": "twilightforest:blocks/castle_pillar_bold_tiles", + "half": "twilightforest:blocks/castle_pillar_bold_tiles", + "side": "twilightforest:blocks/castle_pillar_bold_tiles" + } } + }, + "facing=east,half=bottom,shape=outer_left,variant=encased": { "y": 270 }, + "facing=west,half=bottom,shape=outer_left,variant=encased": { "y": 90 }, + "facing=south,half=bottom,shape=outer_left,variant=encased": { "y": 0 }, + "facing=north,half=bottom,shape=outer_left,variant=encased": { "y": 180 }, + + "facing=east,half=bottom,shape=inner_left,variant=encased": { "y": 270 }, + "facing=west,half=bottom,shape=inner_left,variant=encased": { "y": 90 }, + "facing=south,half=bottom,shape=inner_left,variant=encased": { "y": 0 }, + "facing=north,half=bottom,shape=inner_left,variant=encased": { "y": 180 }, + + "facing=west,half=top,shape=straight,variant=encased": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight,variant=encased": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight,variant=encased": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=outer_right,variant=encased": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right,variant=encased": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right,variant=encased": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right,variant=encased": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=outer_left,variant=encased": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=outer_left,variant=encased": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left,variant=encased": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left,variant=encased": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=inner_right,variant=encased": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right,variant=encased": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right,variant=encased": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right,variant=encased": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=inner_left,variant=encased": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=inner_left,variant=encased": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left,variant=encased": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left,variant=encased": { "x": 180, "y": 270 }, + + + "facing=east,half=bottom,shape=outer_left,variant=bold": { "y": 270 }, + "facing=west,half=bottom,shape=outer_left,variant=bold": { "y": 90 }, + "facing=south,half=bottom,shape=outer_left,variant=bold": { "y": 0 }, + "facing=north,half=bottom,shape=outer_left,variant=bold": { "y": 180 }, + + "facing=east,half=bottom,shape=inner_left,variant=bold": { "y": 270 }, + "facing=west,half=bottom,shape=inner_left,variant=bold": { "y": 90 }, + "facing=south,half=bottom,shape=inner_left,variant=bold": { "y": 0 }, + "facing=north,half=bottom,shape=inner_left,variant=bold": { "y": 180 }, + + "facing=west,half=top,shape=straight,variant=bold": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight,variant=bold": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight,variant=bold": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=outer_right,variant=bold": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right,variant=bold": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right,variant=bold": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right,variant=bold": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=outer_left,variant=bold": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=outer_left,variant=bold": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left,variant=bold": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left,variant=bold": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=inner_right,variant=bold": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right,variant=bold": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right,variant=bold": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right,variant=bold": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=inner_left,variant=bold": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=inner_left,variant=bold": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left,variant=bold": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left,variant=bold": { "x": 180, "y": 270 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_stairs_brick.json b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_brick.json new file mode 100644 index 0000000000..b10494f348 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_brick.json @@ -0,0 +1,63 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/castle_stair", + "top" : "twilightforest:blocks/castle_stair", + "side" : "twilightforest:blocks/castle_stair", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "minecraft:outer_stairs" }, + "outer_left": { "model": "minecraft:outer_stairs" }, + "inner_right":{ "model": "minecraft:inner_stairs" }, + "inner_left": { "model": "minecraft:inner_stairs" } + }, + "facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "facing=north,half=bottom,shape=outer_left": { "y": 180 }, + + "facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "facing=north,half=bottom,shape=inner_left": { "y": 180 }, + + "facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_stairs_cracked.json b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_cracked.json new file mode 100644 index 0000000000..b515949273 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_cracked.json @@ -0,0 +1,63 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/castle_stair_cracked", + "top" : "twilightforest:blocks/castle_stair_cracked", + "side" : "twilightforest:blocks/castle_stair_cracked", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "minecraft:outer_stairs" }, + "outer_left": { "model": "minecraft:outer_stairs" }, + "inner_right":{ "model": "minecraft:inner_stairs" }, + "inner_left": { "model": "minecraft:inner_stairs" } + }, + "facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "facing=north,half=bottom,shape=outer_left": { "y": 180 }, + + "facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "facing=north,half=bottom,shape=inner_left": { "y": 180 }, + + "facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_stairs_mossy.json b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_mossy.json new file mode 100644 index 0000000000..f7620d2b8d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_mossy.json @@ -0,0 +1,63 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/castle_stair_mossy", + "top" : "twilightforest:blocks/castle_stair_mossy", + "side" : "twilightforest:blocks/castle_stair_mossy", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "minecraft:outer_stairs" }, + "outer_left": { "model": "minecraft:outer_stairs" }, + "inner_right":{ "model": "minecraft:inner_stairs" }, + "inner_left": { "model": "minecraft:inner_stairs" } + }, + "facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "facing=north,half=bottom,shape=outer_left": { "y": 180 }, + + "facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "facing=north,half=bottom,shape=inner_left": { "y": 180 }, + + "facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_stairs_worn.json b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_worn.json new file mode 100644 index 0000000000..539d8ddddb --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_stairs_worn.json @@ -0,0 +1,63 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/castle_stair_faded", + "top" : "twilightforest:blocks/castle_stair_faded", + "side" : "twilightforest:blocks/castle_stair_faded", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "minecraft:outer_stairs" }, + "outer_left": { "model": "minecraft:outer_stairs" }, + "inner_right":{ "model": "minecraft:inner_stairs" }, + "inner_left": { "model": "minecraft:inner_stairs" } + }, + "facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "facing=north,half=bottom,shape=outer_left": { "y": 180 }, + + "facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "facing=north,half=bottom,shape=inner_left": { "y": 180 }, + + "facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + + "facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + + "facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/castle_unlock.json b/src/main/resources/assets/twilightforest/blockstates/castle_unlock.json new file mode 100644 index 0000000000..781b31f79b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/castle_unlock.json @@ -0,0 +1,5 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_all", "textures": { "all": "twilightforest:blocks/castle_door" } }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/cicada.json b/src/main/resources/assets/twilightforest/blockstates/cicada.json new file mode 100644 index 0000000000..d642d74b2b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/cicada.json @@ -0,0 +1,9 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/dummy", + "textures": { "particle": "blocks/slime" }, + "transform": "forge:default-item" + }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/cinder_furnace.json b/src/main/resources/assets/twilightforest/blockstates/cinder_furnace.json new file mode 100644 index 0000000000..5c45ca150d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/cinder_furnace.json @@ -0,0 +1,21 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "orientable", + "textures": { + "side": "blocks/furnace_side", + "top": "blocks/furnace_top", + "front": "blocks/furnace_front_off" + }, + "uvlock": true + }, + "inventory": [{}], + "variants": { + "facing": { + "north": {}, + "south": { "y": 180 }, + "west": { "y": 270 }, + "east": { "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/cinder_furnace_lit.json b/src/main/resources/assets/twilightforest/blockstates/cinder_furnace_lit.json new file mode 100644 index 0000000000..d824d0805a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/cinder_furnace_lit.json @@ -0,0 +1,21 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "orientable", + "textures": { + "side": "blocks/furnace_side", + "top": "blocks/furnace_top", + "front": "blocks/furnace_front_on" + }, + "uvlock": true + }, + "inventory": [{}], + "variants": { + "facing": { + "north": {}, + "south": { "y": 180 }, + "west": { "y": 270 }, + "east": { "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/cinder_log.json b/src/main/resources/assets/twilightforest/blockstates/cinder_log.json new file mode 100644 index 0000000000..8e8f2a4ade --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/cinder_log.json @@ -0,0 +1,18 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_column", + "textures": { + "side": "twilightforest:blocks/cinder_log_side", + "end": "twilightforest:blocks/cinder_log_end" + } + }, + "variants": { + "axis": { + "y": {}, + "z": { "x": 90 }, + "x": { "x": 90, "y": 90 }, + "none": { "model": "cube_all", "textures": { "all": "#side" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_button.json b/src/main/resources/assets/twilightforest/blockstates/dark_button.json new file mode 100644 index 0000000000..e7864088c3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_door.json b/src/main/resources/assets/twilightforest/blockstates/dark_door.json new file mode 100644 index 0000000000..8e1005371e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/dark_lower", + "top" : "twilightforest:blocks/wood/door/dark_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/dark_doubleslab.json new file mode 100644 index 0000000000..3a1de02a4e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_darkwood_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_darkwood_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_darkwood_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_darkwood_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_fence.json b/src/main/resources/assets/twilightforest/blockstates/dark_fence.json new file mode 100644 index 0000000000..ef19325c57 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_gate.json b/src/main/resources/assets/twilightforest/blockstates/dark_gate.json new file mode 100644 index 0000000000..6aa0a9810b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_leaves.json b/src/main/resources/assets/twilightforest/blockstates/dark_leaves.json new file mode 100644 index 0000000000..ced739e20c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_leaves.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "leaves", + "textures": { "all": "twilightforest:blocks/darkwood_leaves2" } + }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_planks.json b/src/main/resources/assets/twilightforest/blockstates/dark_planks.json new file mode 100644 index 0000000000..b13f38f954 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_darkwood_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_darkwood_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_darkwood_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_darkwood_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_plate.json b/src/main/resources/assets/twilightforest/blockstates/dark_plate.json new file mode 100644 index 0000000000..fbfddee092 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_darkwood_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_slab.json b/src/main/resources/assets/twilightforest/blockstates/dark_slab.json new file mode 100644 index 0000000000..5ff39d1c90 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_0", + "top" : "twilightforest:blocks/wood/planks_darkwood_0", + "side" : "twilightforest:blocks/wood/planks_darkwood_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_0", + "top" : "twilightforest:blocks/wood/planks_darkwood_0", + "side" : "twilightforest:blocks/wood/planks_darkwood_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_1", + "top" : "twilightforest:blocks/wood/planks_darkwood_1", + "side" : "twilightforest:blocks/wood/planks_darkwood_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_2", + "top" : "twilightforest:blocks/wood/planks_darkwood_2", + "side" : "twilightforest:blocks/wood/planks_darkwood_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_3", + "top" : "twilightforest:blocks/wood/planks_darkwood_3", + "side" : "twilightforest:blocks/wood/planks_darkwood_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_0", + "top" : "twilightforest:blocks/wood/planks_darkwood_0", + "side" : "twilightforest:blocks/wood/planks_darkwood_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_1", + "top" : "twilightforest:blocks/wood/planks_darkwood_1", + "side" : "twilightforest:blocks/wood/planks_darkwood_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_2", + "top" : "twilightforest:blocks/wood/planks_darkwood_2", + "side" : "twilightforest:blocks/wood/planks_darkwood_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_3", + "top" : "twilightforest:blocks/wood/planks_darkwood_3", + "side" : "twilightforest:blocks/wood/planks_darkwood_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_stairs.json b/src/main/resources/assets/twilightforest/blockstates/dark_stairs.json new file mode 100644 index 0000000000..60cd2b53cb --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_darkwood_0", + "top" : "twilightforest:blocks/wood/planks_darkwood_0", + "side" : "twilightforest:blocks/wood/planks_darkwood_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_0", "top": "twilightforest:blocks/wood/planks_darkwood_0", "side": "twilightforest:blocks/wood/planks_darkwood_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_1", "top": "twilightforest:blocks/wood/planks_darkwood_1", "side": "twilightforest:blocks/wood/planks_darkwood_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_2", "top": "twilightforest:blocks/wood/planks_darkwood_2", "side": "twilightforest:blocks/wood/planks_darkwood_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_darkwood_3", "top": "twilightforest:blocks/wood/planks_darkwood_3", "side": "twilightforest:blocks/wood/planks_darkwood_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/dark_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/dark_trapdoor.json new file mode 100644 index 0000000000..dd43f68ccc --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/dark_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/dark_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/deadrock.json b/src/main/resources/assets/twilightforest/blockstates/deadrock.json new file mode 100644 index 0000000000..ca2ea41430 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/deadrock.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_all" }, + "variants": { + "variant=surface": [ + { "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "y":180, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "y":270, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 90, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 90, "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 90, "y":180, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 90, "y":270, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 180, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 180, "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 180, "y":180, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 180, "y":270, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 270, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 270, "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 270, "y":180, "textures": { "all": "twilightforest:blocks/deadrock_surface" } }, + { "x": 270, "y":270, "textures": { "all": "twilightforest:blocks/deadrock_surface" } } + ], + "variant=cracked": [ + { "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "y":180, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "y":270, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 90, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 90, "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 90, "y":180, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 90, "y":270, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 180, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 180, "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 180, "y":180, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 180, "y":270, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 270, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 270, "y": 90, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 270, "y":180, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } }, + { "x": 270, "y":270, "textures": { "all": "twilightforest:blocks/deadrock_cracked" } } + ], + "variant=solid": [ + { "textures": { "all": "twilightforest:blocks/deadrock_solid" } }, + { "y":180, "textures": { "all": "twilightforest:blocks/deadrock_solid" } }, + { "model": "twilightforest:util/cube_mirrored_all", "textures": { "all": "twilightforest:blocks/deadrock_solid" } }, + { "model": "twilightforest:util/cube_mirrored_all", "y":180, "textures": { "all": "twilightforest:blocks/deadrock_solid" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/double_aurora_slab.json b/src/main/resources/assets/twilightforest/blockstates/double_aurora_slab.json new file mode 100644 index 0000000000..80acd48b1b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/double_aurora_slab.json @@ -0,0 +1,11 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/tinted_cube_column", + "textures": { + "end": "twilightforest:blocks/aurora_pillar_top", + "side": "twilightforest:blocks/aurora_slab_side" + } + }, + "variants": { "normal": [{}] } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/etched_nagastone.json b/src/main/resources/assets/twilightforest/blockstates/etched_nagastone.json new file mode 100644 index 0000000000..cd2c595527 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/etched_nagastone.json @@ -0,0 +1,61 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube", + "textures": { + "particle": "twilightforest:blocks/etched_nagastone_up" + } + }, + "variants": { + "facing": { + "up": { "textures": { + "up": "twilightforest:blocks/stone_tiles", + "down": "twilightforest:blocks/stone_tiles", + "north" : "twilightforest:blocks/etched_nagastone_up", + "south" : "twilightforest:blocks/etched_nagastone_up", + "east" : "twilightforest:blocks/etched_nagastone_up", + "west" : "twilightforest:blocks/etched_nagastone_up" + } }, + "down": { "textures": { + "up": "twilightforest:blocks/stone_tiles", + "down": "twilightforest:blocks/stone_tiles", + "north" : "twilightforest:blocks/etched_nagastone_down", + "south" : "twilightforest:blocks/etched_nagastone_down", + "east" : "twilightforest:blocks/etched_nagastone_down", + "west" : "twilightforest:blocks/etched_nagastone_down" + } }, + "north": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_up", + "down": "twilightforest:blocks/etched_nagastone_up", + "north" : "twilightforest:blocks/stone_tiles", + "south" : "twilightforest:blocks/stone_tiles", + "east" : "twilightforest:blocks/etched_nagastone_right", + "west" : "twilightforest:blocks/etched_nagastone_left" + } }, + "south": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_down", + "down": "twilightforest:blocks/etched_nagastone_down", + "north" : "twilightforest:blocks/stone_tiles", + "south" : "twilightforest:blocks/stone_tiles", + "east" : "twilightforest:blocks/etched_nagastone_left", + "west" : "twilightforest:blocks/etched_nagastone_right" + } }, + "east": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_right", + "down": "twilightforest:blocks/etched_nagastone_left", + "north" : "twilightforest:blocks/etched_nagastone_left", + "south" : "twilightforest:blocks/etched_nagastone_right", + "east" : "twilightforest:blocks/stone_tiles", + "west" : "twilightforest:blocks/stone_tiles" + } }, + "west": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_left", + "down": "twilightforest:blocks/etched_nagastone_right", + "north" : "twilightforest:blocks/etched_nagastone_right", + "south" : "twilightforest:blocks/etched_nagastone_left", + "east" : "twilightforest:blocks/stone_tiles", + "west" : "twilightforest:blocks/stone_tiles" + } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/etched_nagastone_mossy.json b/src/main/resources/assets/twilightforest/blockstates/etched_nagastone_mossy.json new file mode 100644 index 0000000000..265add33b5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/etched_nagastone_mossy.json @@ -0,0 +1,61 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube", + "textures": { + "particle": "twilightforest:blocks/etched_nagastone_up_mossy" + } + }, + "variants": { + "facing": { + "up": { "textures": { + "up": "twilightforest:blocks/stone_tiles_mossy", + "down": "twilightforest:blocks/stone_tiles_mossy", + "north" : "twilightforest:blocks/etched_nagastone_up_mossy", + "south" : "twilightforest:blocks/etched_nagastone_up_mossy", + "east" : "twilightforest:blocks/etched_nagastone_up_mossy", + "west" : "twilightforest:blocks/etched_nagastone_up_mossy" + } }, + "down": { "textures": { + "up": "twilightforest:blocks/stone_tiles_mossy", + "down": "twilightforest:blocks/stone_tiles_mossy", + "north" : "twilightforest:blocks/etched_nagastone_down_mossy", + "south" : "twilightforest:blocks/etched_nagastone_down_mossy", + "east" : "twilightforest:blocks/etched_nagastone_down_mossy", + "west" : "twilightforest:blocks/etched_nagastone_down_mossy" + } }, + "north": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_up_mossy", + "down": "twilightforest:blocks/etched_nagastone_up_mossy", + "north" : "twilightforest:blocks/stone_tiles_mossy", + "south" : "twilightforest:blocks/stone_tiles_mossy", + "east" : "twilightforest:blocks/etched_nagastone_right_mossy", + "west" : "twilightforest:blocks/etched_nagastone_left_mossy" + } }, + "south": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_down_mossy", + "down": "twilightforest:blocks/etched_nagastone_down_mossy", + "north" : "twilightforest:blocks/stone_tiles_mossy", + "south" : "twilightforest:blocks/stone_tiles_mossy", + "east" : "twilightforest:blocks/etched_nagastone_left_mossy", + "west" : "twilightforest:blocks/etched_nagastone_right_mossy" + } }, + "east": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_right_mossy", + "down": "twilightforest:blocks/etched_nagastone_left_mossy", + "north" : "twilightforest:blocks/etched_nagastone_left_mossy", + "south" : "twilightforest:blocks/etched_nagastone_right_mossy", + "east" : "twilightforest:blocks/stone_tiles_mossy", + "west" : "twilightforest:blocks/stone_tiles_mossy" + } }, + "west": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_left_mossy", + "down": "twilightforest:blocks/etched_nagastone_right_mossy", + "north" : "twilightforest:blocks/etched_nagastone_right_mossy", + "south" : "twilightforest:blocks/etched_nagastone_left_mossy", + "east" : "twilightforest:blocks/stone_tiles_mossy", + "west" : "twilightforest:blocks/stone_tiles_mossy" + } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/etched_nagastone_weathered.json b/src/main/resources/assets/twilightforest/blockstates/etched_nagastone_weathered.json new file mode 100644 index 0000000000..b70279cd3e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/etched_nagastone_weathered.json @@ -0,0 +1,61 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube", + "textures": { + "particle": "twilightforest:blocks/etched_nagastone_up_weathered" + } + }, + "variants": { + "facing": { + "up": { "textures": { + "up": "twilightforest:blocks/stone_tiles_weathered", + "down": "twilightforest:blocks/stone_tiles_weathered", + "north" : "twilightforest:blocks/etched_nagastone_up_weathered", + "south" : "twilightforest:blocks/etched_nagastone_up_weathered", + "east" : "twilightforest:blocks/etched_nagastone_up_weathered", + "west" : "twilightforest:blocks/etched_nagastone_up_weathered" + } }, + "down": { "textures": { + "up": "twilightforest:blocks/stone_tiles_weathered", + "down": "twilightforest:blocks/stone_tiles_weathered", + "north" : "twilightforest:blocks/etched_nagastone_down_weathered", + "south" : "twilightforest:blocks/etched_nagastone_down_weathered", + "east" : "twilightforest:blocks/etched_nagastone_down_weathered", + "west" : "twilightforest:blocks/etched_nagastone_down_weathered" + } }, + "north": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_up_weathered", + "down": "twilightforest:blocks/etched_nagastone_up_weathered", + "north" : "twilightforest:blocks/stone_tiles_weathered", + "south" : "twilightforest:blocks/stone_tiles_weathered", + "east" : "twilightforest:blocks/etched_nagastone_right_weathered", + "west" : "twilightforest:blocks/etched_nagastone_left_weathered" + } }, + "south": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_down_weathered", + "down": "twilightforest:blocks/etched_nagastone_down_weathered", + "north" : "twilightforest:blocks/stone_tiles_weathered", + "south" : "twilightforest:blocks/stone_tiles_weathered", + "east" : "twilightforest:blocks/etched_nagastone_left_weathered", + "west" : "twilightforest:blocks/etched_nagastone_right_weathered" + } }, + "east": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_right_weathered", + "down": "twilightforest:blocks/etched_nagastone_left_weathered", + "north" : "twilightforest:blocks/etched_nagastone_left_weathered", + "south" : "twilightforest:blocks/etched_nagastone_right_weathered", + "east" : "twilightforest:blocks/stone_tiles_weathered", + "west" : "twilightforest:blocks/stone_tiles_weathered" + } }, + "west": { "textures": { + "up": "twilightforest:blocks/etched_nagastone_left_weathered", + "down": "twilightforest:blocks/etched_nagastone_right_weathered", + "north" : "twilightforest:blocks/etched_nagastone_right_weathered", + "south" : "twilightforest:blocks/etched_nagastone_left_weathered", + "east" : "twilightforest:blocks/stone_tiles_weathered", + "west" : "twilightforest:blocks/stone_tiles_weathered" + } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/experiment_115.json b/src/main/resources/assets/twilightforest/blockstates/experiment_115.json new file mode 100755 index 0000000000..d4798d58e3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/experiment_115.json @@ -0,0 +1,32 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "particle": "twilightforest:blocks/experiment115/experiment115_bottom", + "bottom": "twilightforest:blocks/experiment115/experiment115_bottom", + "inside": "twilightforest:blocks/experiment115/experiment115_inner", + "top": "twilightforest:blocks/experiment115/experiment115_top", + "side": "twilightforest:blocks/experiment115/experiment115_side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:items/experiment_115" }}], + "inventory_full": [{ "model": "twilightforest:experiment115_8_8", "textures": { "top_2": "twilightforest:blocks/experiment115/experiment115_sprinkle" }}], + "inventory_think": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:items/think115" }}], + "omnomnom": { + 0: { "model": "twilightforest:experiment115_8_8" }, + 1: { "model": "twilightforest:experiment115_7_8" }, + 2: { "model": "twilightforest:experiment115_6_8" }, + 3: { "model": "twilightforest:experiment115_5_8" }, + 4: { "model": "twilightforest:experiment115_4_8" }, + 5: { "model": "twilightforest:experiment115_3_8" }, + 6: { "model": "twilightforest:experiment115_2_8" }, + 7: { "model": "twilightforest:experiment115_1_8" } + }, + "regenerate": { + "true": { "textures": { "top_2": "twilightforest:blocks/experiment115/experiment115_sprinkle" } }, + "false": { "textures": { "top_2": "twilightforest:blocks/experiment115/experiment115_top" } } + } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/fiery_essence.json b/src/main/resources/assets/twilightforest/blockstates/fiery_essence.json new file mode 100644 index 0000000000..1c10ea2c4b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/fiery_essence.json @@ -0,0 +1,9 @@ +{ + "forge_marker": 1, + "variants": { + "fluid": { + "model": "forge:fluid", + "custom": { "fluid": "fiery_essence" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/fire_jet.json b/src/main/resources/assets/twilightforest/blockstates/fire_jet.json new file mode 100644 index 0000000000..42dbc368d8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/fire_jet.json @@ -0,0 +1,75 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:jet", + "textures": { + "particle": "blocks/furnace_top" + } + }, + "variants": { + "variant=smoker": [{},{ "y": 90 }, { "y": 180 }, { "y": 270 }], + "variant=jet_idle": [{},{ "y": 90 }, { "y": 180 }, { "y": 270 }], + "variant=jet_popping": [{},{ "y": 90 }, { "y": 180 }, { "y": 270 }], + "variant=jet_flame": [{},{ "y": 90 }, { "y": 180 }, { "y": 270 }], + "variant=encased_smoker_off": [{ + "model": "twilightforest:util/cube_bottom_top_3_layer", + "textures": { + "top": "twilightforest:blocks/towerdev_ghasttraplid_off", + "side": "twilightforest:blocks/towerdev_smoker_off", + "bottom": "twilightforest:blocks/towerwood_encased", + "top2": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_off_1", + "side2": "twilightforest:blocks/tower_device_level_1/towerdev_smoker_1", + "top3": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_off_1", + "side3": "twilightforest:blocks/tower_device_level_2/towerdev_smoker_off_1" + } + }], + "variant=encased_smoker_on": [{ + "model": "twilightforest:util/cube_bottom_top_3_layer", + "textures": { + "top": "twilightforest:blocks/towerdev_ghasttraplid_on", + "side": "twilightforest:blocks/towerdev_smoker_on", + "bottom": "twilightforest:blocks/towerwood_encased", + "top2": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_on_1", + "side2": "twilightforest:blocks/tower_device_level_1/towerdev_smoker_1", + "top3": "twilightforest:blocks/tower_device_level_3/towerdev_ghasttraplid_on_2", + "side3": "twilightforest:blocks/tower_device_level_2/towerdev_smoker_on_1" + } + }], + "variant=encased_jet_idle": [{ + "model": "twilightforest:util/cube_bottom_top_3_layer", + "textures": { + "top": "twilightforest:blocks/towerdev_ghasttraplid_off", + "side": "twilightforest:blocks/towerdev_firejet_off", + "bottom": "twilightforest:blocks/towerwood_encased", + "top2": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_off_1", + "side2": "twilightforest:blocks/tower_device_level_1/towerdev_firejet_1", + "top3": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_off_1", + "side3": "twilightforest:blocks/tower_device_level_2/towerdev_firejet_off_1" + } + }], + "variant=encased_jet_popping": [{ + "model": "twilightforest:util/cube_bottom_top_3_layer", + "textures": { + "top": "twilightforest:blocks/towerdev_ghasttraplid_on", + "side": "twilightforest:blocks/towerdev_firejet_on", + "bottom": "twilightforest:blocks/towerwood_encased", + "top2": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_on_1", + "side2": "twilightforest:blocks/tower_device_level_1/towerdev_firejet_1", + "top3": "twilightforest:blocks/tower_device_level_3/towerdev_ghasttraplid_on_2", + "side3": "twilightforest:blocks/tower_device_level_2/towerdev_firejet_on_1" + } + }], + "variant=encased_jet_flame": [{ + "model": "twilightforest:util/cube_bottom_top_3_layer", + "textures": { + "top": "twilightforest:blocks/towerdev_ghasttraplid_on", + "side": "twilightforest:blocks/towerdev_firejet_on", + "bottom": "twilightforest:blocks/towerwood_encased", + "top2": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_on_1", + "side2": "twilightforest:blocks/tower_device_level_1/towerdev_firejet_1", + "top3": "twilightforest:blocks/tower_device_level_3/towerdev_ghasttraplid_on_2", + "side3": "twilightforest:blocks/tower_device_level_2/towerdev_firejet_on_1" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/firefly.json b/src/main/resources/assets/twilightforest/blockstates/firefly.json new file mode 100644 index 0000000000..d642d74b2b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/firefly.json @@ -0,0 +1,9 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/dummy", + "textures": { "particle": "blocks/slime" }, + "transform": "forge:default-item" + }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/firefly_jar.json b/src/main/resources/assets/twilightforest/blockstates/firefly_jar.json new file mode 100644 index 0000000000..70554b03b7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/firefly_jar.json @@ -0,0 +1,5 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:jar" }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/fluffy_cloud.json b/src/main/resources/assets/twilightforest/blockstates/fluffy_cloud.json new file mode 100644 index 0000000000..6045ee182d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/fluffy_cloud.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/fluffy_cloud" } + }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/force_field.json b/src/main/resources/assets/twilightforest/blockstates/force_field.json new file mode 100755 index 0000000000..f55543bb9b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/force_field.json @@ -0,0 +1,34 @@ +{ + "forge_marker": 1, + "defaults": { + "transform": "forge:default-item", + "model": "twilightforest:util/pane/post", + "textures": { "edge": "#pane", "pane": "twilightforest:blocks/forcefield_white" }, + "uvlock":true + }, + "variants": { + "inventory": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/forcefield_white"}}], + "axis": { + "x":{ "x": 90, "y": 90 }, + "y":{}, + "z":{ "x": 270, "y": 180 } + }, + "color": { "purple": { }, "pink": { }, "orange": { }, "green": { }, "blue": { } }, + "north": { + "true" : { "submodel": { "key_n": { "model": "twilightforest:util/pane/side" } } }, + "false": { "submodel": { "key_n": { "model": "twilightforest:util/pane/noside" } } } + }, + "east" : { + "true" : { "submodel": { "key_e": { "model": "twilightforest:util/pane/side", "y": 90 } } }, + "false": { "submodel": { "key_e": { "model": "twilightforest:util/pane/noside_alt" } } } + }, + "south": { + "true" : { "submodel": { "key_s": { "model": "twilightforest:util/pane/side_alt" } } }, + "false": { "submodel": { "key_s": { "model": "twilightforest:util/pane/noside_alt", "y": 90 } } } + }, + "west" : { + "true" : { "submodel": { "key_w": { "model": "twilightforest:util/pane/side_alt", "y": 90 } } }, + "false": { "submodel": { "key_w": { "model": "twilightforest:util/pane/noside", "y": 270 } } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/giant_cobblestone.json b/src/main/resources/assets/twilightforest/blockstates/giant_cobblestone.json new file mode 100755 index 0000000000..d18a8deffb --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/giant_cobblestone.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { "textures": { "all": "minecraft:blocks/cobblestone" } }, + "variants": { + "inventory": [{ "model": "cube_all" }], + "normal": [{ "model": "twilightforest:util/giant_block" }] + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/giant_leaves.json b/src/main/resources/assets/twilightforest/blockstates/giant_leaves.json new file mode 100755 index 0000000000..3ea52a35f8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/giant_leaves.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { "textures": { "all": "minecraft:blocks/leaves_oak" } }, + "variants": { + "inventory": [{ "model": "leaves" }], + "normal": [{ "model": "twilightforest:util/giant_block" }] + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/giant_log.json b/src/main/resources/assets/twilightforest/blockstates/giant_log.json new file mode 100755 index 0000000000..f413639e62 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/giant_log.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { "textures": { "side": "minecraft:blocks/log_oak", "end": "minecraft:blocks/log_oak_top" } }, + "variants": { + "inventory": [{ "model": "cube_column" }], + "normal": [{ "model": "twilightforest:util/giant_column" }] + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/giant_obsidian.json b/src/main/resources/assets/twilightforest/blockstates/giant_obsidian.json new file mode 100755 index 0000000000..92a479b83b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/giant_obsidian.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { "textures": { "all": "minecraft:blocks/obsidian" } }, + "variants": { + "inventory": [{ "model": "cube_all" }], + "normal": [{ "model": "twilightforest:util/giant_block" }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/giant_pickaxe.json b/src/main/resources/assets/twilightforest/blockstates/giant_pickaxe.json new file mode 100644 index 0000000000..ff6d750ed7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/giant_pickaxe.json @@ -0,0 +1,44 @@ +{ + "forge_marker": 1, + "__comment": "Transforms are item/generated and item/handheld, converted to forge format. Firstperson scales are multiplied by 2.5, all others by 5", + "defaults": { + "model": "builtin/generated", + "textures": { + "layer0": "items/stone_pickaxe" + }, + "transform": { + "ground": { + "translation": [ 0, 0.125, 0], + "scale": [ 2.5, 2.5, 2.5 ] + }, + "head": { + "rotation": { "y": 180 }, + "translation": [ 0, 0.8125, 0.4375], + "scale":[ 5, 5, 5 ] + }, + "thirdperson_righthand": { + "rotation": [{ "y": -90 }, { "z": 55 }], + "translation": [ 0, 1, -0.5 ], + "scale": [ 4.25, 4.25, 4.25 ] + }, + "thirdperson_lefthand": { + "rotation": [{ "y": 90 }, { "z": -55 }], + "translation": [ 0, 1, -0.5 ], + "scale": [ 4.25, 4.25, 4.25 ] + }, + "firstperson_righthand": { + "rotation": [{ "y": -90 }, { "z": 25 }], + "translation": [ 0.070625, 0.2, 0.070625 ], + "scale": [ 1.7, 1.7, 1.7 ] + }, + "firstperson_lefthand": { + "rotation": [{ "y": 90 }, { "z": -25 }], + "translation": [ 0.070625, 0.2, 0.070625 ], + "scale": [ 1.7, 1.7, 1.7 ] + } + } + }, + "variants": { + "inventory": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/giant_sword.json b/src/main/resources/assets/twilightforest/blockstates/giant_sword.json new file mode 100644 index 0000000000..8058d02f08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/giant_sword.json @@ -0,0 +1,44 @@ +{ + "forge_marker": 1, + "__comment": "Transforms are item/generated and item/handheld, converted to forge format. Firstperson scales are multiplied by 2.5, all others by 5", + "defaults": { + "model": "builtin/generated", + "textures": { + "layer0": "items/stone_sword" + }, + "transform": { + "ground": { + "translation": [ 0, 0.125, 0], + "scale": [ 2.5, 2.5, 2.5 ] + }, + "head": { + "rotation": { "y": 180 }, + "translation": [ 0, 0.8125, 0.4375], + "scale":[ 5, 5, 5 ] + }, + "thirdperson_righthand": { + "rotation": [{ "y": -90 }, { "z": 55 }], + "translation": [ 0, 1.5, -0.4 ], + "scale": [ 4.25, 4.25, 4.25 ] + }, + "thirdperson_lefthand": { + "rotation": [{ "y": 90 }, { "z": -55 }], + "translation": [ 0, 1.5, -0.4 ], + "scale": [ 4.25, 4.25, 4.25 ] + }, + "firstperson_righthand": { + "rotation": [{ "y": -90 }, { "z": 25 }], + "translation": [ 0.070625, 0.2, 0.070625 ], + "scale": [ 1.7, 1.7, 1.7 ] + }, + "firstperson_lefthand": { + "rotation": [{ "y": 90 }, { "z": -25 }], + "translation": [ 0.070625, 0.2, 0.070625 ], + "scale": [ 1.7, 1.7, 1.7 ] + } + } + }, + "variants": { + "inventory": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/hedge.json b/src/main/resources/assets/twilightforest/blockstates/hedge.json new file mode 100644 index 0000000000..f4b7fc84ca --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/hedge.json @@ -0,0 +1,10 @@ +{ + "forge_marker": 1, + "variants": { + "variant=hedge" : [ + { "model": "cube_all", "textures": { "all": "twilightforest:blocks/hedge" }, "weight": 10 }, + { "model": "cube_all", "textures": { "all": "twilightforest:blocks/hedge_rose" }, "weight": 1 } + ], + "variant=darkwood_leaves": [{ "model": "leaves", "textures": { "all": "twilightforest:blocks/darkwood_leaves2" } }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/huge_lilypad.json b/src/main/resources/assets/twilightforest/blockstates/huge_lilypad.json new file mode 100644 index 0000000000..5a7415570e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/huge_lilypad.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "waterlily" + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:blocks/huge_lilypad"}}], + + "facing=north,piece=nw": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_1" } }], + "facing=north,piece=ne": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_0" } }], + "facing=north,piece=se": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_3" } }], + "facing=north,piece=sw": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_2" } }], + + "facing=south,piece=nw": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_3" }, "y": 180 }], + "facing=south,piece=ne": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_2" }, "y": 180 }], + "facing=south,piece=se": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_1" }, "y": 180 }], + "facing=south,piece=sw": [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_0" }, "y": 180 }], + + "facing=west,piece=nw" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_0" }, "y": 270 }], + "facing=west,piece=ne" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_3" }, "y": 270 }], + "facing=west,piece=se" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_2" }, "y": 270 }], + "facing=west,piece=sw" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_1" }, "y": 270 }], + + "facing=east,piece=nw" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_2" }, "y": 90 }], + "facing=east,piece=ne" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_1" }, "y": 90 }], + "facing=east,piece=se" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_0" }, "y": 90 }], + "facing=east,piece=sw" : [{ "textures": { "texture": "twilightforest:blocks/huge_lilypad_3" }, "y": 90 }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/huge_mushgloom.json b/src/main/resources/assets/twilightforest/blockstates/huge_mushgloom.json new file mode 100755 index 0000000000..bd1424af13 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/huge_mushgloom.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "inside":"twilightforest:blocks/huge_gloom_inside", + "outside":"twilightforest:blocks/huge_gloom_cap", + "stem":"twilightforest:blocks/huge_gloom_stem" + }, + "uvlock": true + }, + "variants": { + "variant": { + "north_west": { "model": "twilightforest:util/mushgloom/block_nw" }, + "north": { "model": "twilightforest:util/mushgloom/block_n" }, + "north_east": { "model": "twilightforest:util/mushgloom/block_nw", "y": 90 }, + "west": { "model": "twilightforest:util/mushgloom/block_n" , "y": 270 }, + "center": { "model": "cube_top", "textures": { "top": "#outside", "side": "#inside" } }, + "east": { "model": "twilightforest:util/mushgloom/block_n" , "y": 90 }, + "south_west": { "model": "twilightforest:util/mushgloom/block_nw", "y": 270 }, + "south": { "model": "twilightforest:util/mushgloom/block_n" , "y": 180 }, + "south_east": { "model": "twilightforest:util/mushgloom/block_nw", "y": 180 }, + "stem": { "model": "cube_column", "textures": { "end": "#inside", "side": "#stem" } }, + "all_stem": { "model": "cube_all", "textures": { "all": "#stem" } }, + "all_outside": { "model": "cube_all", "textures": { "all": "#outside" } }, + "all_inside": { "model": "cube_all", "textures": { "all": "#inside" } } + } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/huge_stalk.json b/src/main/resources/assets/twilightforest/blockstates/huge_stalk.json new file mode 100644 index 0000000000..28c2c14ae2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/huge_stalk.json @@ -0,0 +1,5 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_column", "textures": { "end": "twilightforest:blocks/huge_stalk_top", "side": "twilightforest:blocks/huge_stalk" } }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/huge_waterlily.json b/src/main/resources/assets/twilightforest/blockstates/huge_waterlily.json new file mode 100644 index 0000000000..823923ca8a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/huge_waterlily.json @@ -0,0 +1,11 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cross", + "textures": { "cross": "twilightforest:blocks/huge_waterlily" } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:blocks/huge_waterlily"}}], + "normal": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/iron_ladder.json b/src/main/resources/assets/twilightforest/blockstates/iron_ladder.json new file mode 100644 index 0000000000..6180a0437b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/iron_ladder.json @@ -0,0 +1,21 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:util/dummy", "textures": { "particle": "twilightforest:blocks/ladder_iron" } }, + "variants": { + "inventory": { "model": "twilightforest:iron_ladder" }, + "facing": { + "north": { }, + "east" : { "y": 90 }, + "south": { "y": 180 }, + "west" : { "y": 270 } + }, + "left": { + "true" : { "submodel": { "left": { "model": "twilightforest:iron_ladder_left_connection" } } }, + "false": { "submodel": { "left": { "model": "twilightforest:iron_ladder_left" } } } + }, + "right": { + "true" : { "submodel": { "right": { "model": "twilightforest:iron_ladder_right_connection" } } }, + "false": { "submodel": { "right": { "model": "twilightforest:iron_ladder_right" } } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/knightmetal_block.json b/src/main/resources/assets/twilightforest/blockstates/knightmetal_block.json new file mode 100644 index 0000000000..4e9c482f52 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/knightmetal_block.json @@ -0,0 +1,5 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:knightmetal_block" }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/lapis_block.json b/src/main/resources/assets/twilightforest/blockstates/lapis_block.json new file mode 100644 index 0000000000..92c94d6816 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/lapis_block.json @@ -0,0 +1,13 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_all" }, + "variants": { + "inventory": [{}], + "normal": [ + { "textures": { "all": "twilightforest:blocks/lapis_shale_0" }}, + { "textures": { "all": "twilightforest:blocks/lapis_shale_1" }}, + { "textures": { "all": "twilightforest:blocks/lapis_shale_2" }}, + { "textures": { "all": "twilightforest:blocks/lapis_shale_3" }} + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/magic_leaves.json b/src/main/resources/assets/twilightforest/blockstates/magic_leaves.json new file mode 100644 index 0000000000..d616dfe9e1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/magic_leaves.json @@ -0,0 +1,14 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "leaves" + }, + "variants": { + "variant": { + "time": { "textures": { "all": "twilightforest:blocks/time_leaves" } }, + "trans": { "textures": { "all": "twilightforest:blocks/trans_leaves" } }, + "mine": { "textures": { "all": "twilightforest:blocks/time_leaves" } }, + "sort": { "textures": { "all": "twilightforest:blocks/sort_leaves" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/magic_log.json b/src/main/resources/assets/twilightforest/blockstates/magic_log.json new file mode 100644 index 0000000000..dde855f8dd --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/magic_log.json @@ -0,0 +1,20 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_column" + }, + "variants": { + "axis": { + "y": {}, + "z": { "x": 90 }, + "x": { "x": 90, "y": 90 }, + "none": { "model": "cube_all", "textures": { "all": "#side" } } + }, + "variant": { + "time": { "textures": { "end":"twilightforest:blocks/time_section" , "side":"twilightforest:blocks/time_side" } }, + "trans": { "textures": { "end":"twilightforest:blocks/trans_section", "side":"twilightforest:blocks/trans_side" } }, + "mine": { "textures": { "end":"twilightforest:blocks/mine_section" , "side":"twilightforest:blocks/mine_side" } }, + "sort": { "textures": { "end":"twilightforest:blocks/sort_section" , "side":"twilightforest:blocks/sort_side" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/magic_log_core.json b/src/main/resources/assets/twilightforest/blockstates/magic_log_core.json new file mode 100644 index 0000000000..a251d17b09 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/magic_log_core.json @@ -0,0 +1,37 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_column", "textures": { "side": "#side_off" } }, + "variants": { + "axis": { "y": {}, "z": {}, "x": {}, "none": { "textures": { "side": "#side_on" } } }, + "variant": { + "time": { + "textures": { + "side_off": "twilightforest:blocks/time_clock_off", + "side_on": "twilightforest:blocks/time_clock", + "end": "twilightforest:blocks/time_section" + } + }, + "trans":{ + "textures":{ + "side_off": "twilightforest:blocks/trans_heart_off", + "side_on": "twilightforest:blocks/trans_heart", + "end": "twilightforest:blocks/trans_section" + } + }, + "mine": { + "textures":{ + "side_off": "twilightforest:blocks/mine_gem_off", + "side_on": "twilightforest:blocks/mine_gem", + "end": "twilightforest:blocks/mine_section" + } + }, + "sort": { + "textures":{ + "side_off": "twilightforest:blocks/sort_eye_off", + "side_on": "twilightforest:blocks/sort_eye", + "end": "twilightforest:blocks/sort_section" + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_button.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_button.json new file mode 100644 index 0000000000..ca559f2c2c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_door.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_door.json new file mode 100644 index 0000000000..562a2b6b0c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/mangrove_lower", + "top" : "twilightforest:blocks/wood/door/mangrove_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_doubleslab.json new file mode 100644 index 0000000000..ad03178996 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_mangrove_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_mangrove_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mangrove_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mangrove_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_fence.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_fence.json new file mode 100644 index 0000000000..ad7f006453 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_gate.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_gate.json new file mode 100644 index 0000000000..5aeddef750 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_planks.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_planks.json new file mode 100644 index 0000000000..def436e3da --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_mangrove_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_mangrove_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mangrove_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mangrove_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_plate.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_plate.json new file mode 100644 index 0000000000..0201357d5a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mangrove_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_slab.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_slab.json new file mode 100644 index 0000000000..fb3e1bbc22 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_0", + "top" : "twilightforest:blocks/wood/planks_mangrove_0", + "side" : "twilightforest:blocks/wood/planks_mangrove_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_0", + "top" : "twilightforest:blocks/wood/planks_mangrove_0", + "side" : "twilightforest:blocks/wood/planks_mangrove_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_1", + "top" : "twilightforest:blocks/wood/planks_mangrove_1", + "side" : "twilightforest:blocks/wood/planks_mangrove_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_2", + "top" : "twilightforest:blocks/wood/planks_mangrove_2", + "side" : "twilightforest:blocks/wood/planks_mangrove_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_3", + "top" : "twilightforest:blocks/wood/planks_mangrove_3", + "side" : "twilightforest:blocks/wood/planks_mangrove_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_0", + "top" : "twilightforest:blocks/wood/planks_mangrove_0", + "side" : "twilightforest:blocks/wood/planks_mangrove_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_1", + "top" : "twilightforest:blocks/wood/planks_mangrove_1", + "side" : "twilightforest:blocks/wood/planks_mangrove_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_2", + "top" : "twilightforest:blocks/wood/planks_mangrove_2", + "side" : "twilightforest:blocks/wood/planks_mangrove_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_3", + "top" : "twilightforest:blocks/wood/planks_mangrove_3", + "side" : "twilightforest:blocks/wood/planks_mangrove_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_stairs.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_stairs.json new file mode 100644 index 0000000000..072a18043c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mangrove_0", + "top" : "twilightforest:blocks/wood/planks_mangrove_0", + "side" : "twilightforest:blocks/wood/planks_mangrove_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_0", "top": "twilightforest:blocks/wood/planks_mangrove_0", "side": "twilightforest:blocks/wood/planks_mangrove_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_1", "top": "twilightforest:blocks/wood/planks_mangrove_1", "side": "twilightforest:blocks/wood/planks_mangrove_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_2", "top": "twilightforest:blocks/wood/planks_mangrove_2", "side": "twilightforest:blocks/wood/planks_mangrove_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mangrove_3", "top": "twilightforest:blocks/wood/planks_mangrove_3", "side": "twilightforest:blocks/wood/planks_mangrove_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mangrove_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/mangrove_trapdoor.json new file mode 100644 index 0000000000..1e7b5df7ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mangrove_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/mangrove_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/maze_stone.json b/src/main/resources/assets/twilightforest/blockstates/maze_stone.json new file mode 100644 index 0000000000..ed2fd9ac43 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/maze_stone.json @@ -0,0 +1,18 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_column" }, + "variants": { + "variant=plain": [ + { "model": "cube_all", "textures": { "all": "twilightforest:blocks/mazestone_plain" } }, + { "model": "cube_all", "textures": { "all": "twilightforest:blocks/mazestone_plain" }, "x": 90 , "y": 90 }, + { "model": "cube_all", "textures": { "all": "twilightforest:blocks/mazestone_plain" }, "x": 270 , "y": 270 } + ], + "variant=brick": [{ "model": "cube_all", "textures": { "all": "twilightforest:blocks/mazestone_brick" } }], + "variant=chiseled": [{ "textures": { "side": "twilightforest:blocks/mazestone_pillar", "end": "twilightforest:blocks/mazestone_plain" } }], + "variant=decorative":[{ "textures": { "side": "twilightforest:blocks/mazestone_decorative", "end": "twilightforest:blocks/mazestone_plain" } }], + "variant=cracked": [{ "model": "cube_all", "textures": { "all": "twilightforest:blocks/mazestone_cracked" } }], + "variant=mossy": [{ "model": "cube_all", "textures": { "all": "twilightforest:blocks/mazestone_mossy" } }], + "variant=mosaic": [{ "textures": { "side": "twilightforest:blocks/mazestone_brick", "end": "twilightforest:blocks/mazestone_mosaic" } }], + "variant=border": [{ "textures": { "side": "twilightforest:blocks/mazestone_brick", "end": "twilightforest:blocks/mazestone_border" } }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_button.json b/src/main/resources/assets/twilightforest/blockstates/mine_button.json new file mode 100644 index 0000000000..a6e1363931 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_door.json b/src/main/resources/assets/twilightforest/blockstates/mine_door.json new file mode 100644 index 0000000000..d6471b6f49 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/mine_lower", + "top" : "twilightforest:blocks/wood/door/mine_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/mine_doubleslab.json new file mode 100644 index 0000000000..6d0b1c20ff --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_mine_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_mine_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mine_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mine_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_fence.json b/src/main/resources/assets/twilightforest/blockstates/mine_fence.json new file mode 100644 index 0000000000..3ff6661182 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_gate.json b/src/main/resources/assets/twilightforest/blockstates/mine_gate.json new file mode 100644 index 0000000000..56074c94bd --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_planks.json b/src/main/resources/assets/twilightforest/blockstates/mine_planks.json new file mode 100644 index 0000000000..0114c3d2c9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_mine_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_mine_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mine_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_mine_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_plate.json b/src/main/resources/assets/twilightforest/blockstates/mine_plate.json new file mode 100644 index 0000000000..72ad0e0408 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_mine_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_slab.json b/src/main/resources/assets/twilightforest/blockstates/mine_slab.json new file mode 100644 index 0000000000..5752f42baf --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_0", + "top" : "twilightforest:blocks/wood/planks_mine_0", + "side" : "twilightforest:blocks/wood/planks_mine_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_0", + "top" : "twilightforest:blocks/wood/planks_mine_0", + "side" : "twilightforest:blocks/wood/planks_mine_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_1", + "top" : "twilightforest:blocks/wood/planks_mine_1", + "side" : "twilightforest:blocks/wood/planks_mine_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_2", + "top" : "twilightforest:blocks/wood/planks_mine_2", + "side" : "twilightforest:blocks/wood/planks_mine_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_3", + "top" : "twilightforest:blocks/wood/planks_mine_3", + "side" : "twilightforest:blocks/wood/planks_mine_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_0", + "top" : "twilightforest:blocks/wood/planks_mine_0", + "side" : "twilightforest:blocks/wood/planks_mine_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_1", + "top" : "twilightforest:blocks/wood/planks_mine_1", + "side" : "twilightforest:blocks/wood/planks_mine_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_2", + "top" : "twilightforest:blocks/wood/planks_mine_2", + "side" : "twilightforest:blocks/wood/planks_mine_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_3", + "top" : "twilightforest:blocks/wood/planks_mine_3", + "side" : "twilightforest:blocks/wood/planks_mine_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_stairs.json b/src/main/resources/assets/twilightforest/blockstates/mine_stairs.json new file mode 100644 index 0000000000..c72258a60c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_mine_0", + "top" : "twilightforest:blocks/wood/planks_mine_0", + "side" : "twilightforest:blocks/wood/planks_mine_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_0", "top": "twilightforest:blocks/wood/planks_mine_0", "side": "twilightforest:blocks/wood/planks_mine_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_1", "top": "twilightforest:blocks/wood/planks_mine_1", "side": "twilightforest:blocks/wood/planks_mine_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_2", "top": "twilightforest:blocks/wood/planks_mine_2", "side": "twilightforest:blocks/wood/planks_mine_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_mine_3", "top": "twilightforest:blocks/wood/planks_mine_3", "side": "twilightforest:blocks/wood/planks_mine_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/mine_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/mine_trapdoor.json new file mode 100644 index 0000000000..21051ee47a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/mine_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/mine_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/miniature_structure.json b/src/main/resources/assets/twilightforest/blockstates/miniature_structure.json new file mode 100644 index 0000000000..977f3730cb --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/miniature_structure.json @@ -0,0 +1,37 @@ +{ + "forge_marker": 1, + "variants": { + "inventory_twilight_portal": [{ "model": "twilightforest:miniature/portal" }], + "inventory_hedge_maze": [{ "model": "twilightforest:miniature/portal" }], + "inventory_hollow_hill": [{ "model": "twilightforest:miniature/portal" }], + "inventory_quest_grove": [{ "model": "twilightforest:miniature/portal" }], + "inventory_mushroom_tower": [{ "model": "twilightforest:miniature/portal" }], + "inventory_naga_courtyard": [{ "model": "twilightforest:miniature/naga_courtyard" }], + "inventory_lich_tower": [{ "model": "twilightforest:miniature/twilight_lich_tower" }], + "inventory_minotaur_labyrinth": [{ "model": "twilightforest:miniature/portal" }], + "inventory_hydra_lair": [{ "model": "twilightforest:miniature/portal" }], + "inventory_goblin_stronghold": [{ "model": "twilightforest:miniature/portal" }], + "inventory_dark_tower": [{ "model": "twilightforest:miniature/portal" }], + "inventory_yeti_cave": [{ "model": "twilightforest:miniature/portal" }], + "inventory_aurora_palace": [{ "model": "twilightforest:miniature/portal" }], + "inventory_troll_cave_and_cloud_castle": [{ "model": "twilightforest:miniature/portal" }], + "inventory_final_castle": [{ "model": "twilightforest:miniature/portal" }], + "variant": { + "twilight_portal": { "model": "twilightforest:miniature/portal" }, + "hedge_maze": { "model": "twilightforest:miniature/portal" }, + "hollow_hill": { "model": "twilightforest:miniature/portal" }, + "quest_grove": { "model": "twilightforest:miniature/portal" }, + "mushroom_tower": { "model": "twilightforest:miniature/portal" }, + "naga_courtyard": { "model": "twilightforest:miniature/naga_courtyard" }, + "lich_tower": { "model": "twilightforest:miniature/twilight_lich_tower" }, + "minotaur_labyrinth": { "model": "twilightforest:miniature/portal" }, + "hydra_lair": { "model": "twilightforest:miniature/portal" }, + "goblin_stronghold": { "model": "twilightforest:miniature/portal" }, + "dark_tower": { "model": "twilightforest:miniature/portal" }, + "yeti_cave": { "model": "twilightforest:miniature/portal" }, + "aurora_palace": { "model": "twilightforest:miniature/portal" }, + "troll_cave_and_cloud_castle": { "model": "twilightforest:miniature/portal" }, + "final_castle": { "model": "twilightforest:miniature/portal" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/molten_fierymetal.json b/src/main/resources/assets/twilightforest/blockstates/molten_fierymetal.json new file mode 100644 index 0000000000..707d3aaf65 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/molten_fierymetal.json @@ -0,0 +1,9 @@ +{ + "forge_marker": 1, + "variants": { + "fluid": { + "model": "forge:fluid", + "custom": { "fluid": "fierymetal" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/molten_knightmetal.json b/src/main/resources/assets/twilightforest/blockstates/molten_knightmetal.json new file mode 100644 index 0000000000..0d6bf79b0b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/molten_knightmetal.json @@ -0,0 +1,9 @@ +{ + "forge_marker": 1, + "variants": { + "fluid": { + "model": "forge:fluid", + "custom": { "fluid": "knightmetal" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/moonworm.json b/src/main/resources/assets/twilightforest/blockstates/moonworm.json new file mode 100644 index 0000000000..d642d74b2b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/moonworm.json @@ -0,0 +1,9 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/dummy", + "textures": { "particle": "blocks/slime" }, + "transform": "forge:default-item" + }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/naga_stone.json b/src/main/resources/assets/twilightforest/blockstates/naga_stone.json new file mode 100644 index 0000000000..521b7a57fa --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/naga_stone.json @@ -0,0 +1,30 @@ +{ + "forge_marker": 1, + "defaults": { "textures": { "particle": "twilightforest:blocks/nagastone_cross_section" } }, + "variants": { + "variant": { + "north_head": { "model": "twilightforest:naga_segment/head" , "y": 90 }, + "south_head": { "model": "twilightforest:naga_segment/head" , "y": 270 }, + "west_head": { "model": "twilightforest:naga_segment/head" }, + "east_head": { "model": "twilightforest:naga_segment/head" , "y": 180 }, + "north_down": { "model": "twilightforest:naga_segment/down" , "y": 270 }, + "south_down": { "model": "twilightforest:naga_segment/down" , "y": 90 }, + "west_down": { "model": "twilightforest:naga_segment/down" , "y": 180 }, + "east_down": { "model": "twilightforest:naga_segment/down" }, + "north_up": { "model": "twilightforest:naga_segment/up" , "y": 270 }, + "south_up": { "model": "twilightforest:naga_segment/up" , "y": 90 }, + "west_up": { "model": "twilightforest:naga_segment/up" , "y": 180 }, + "east_up": { "model": "twilightforest:naga_segment/up" }, + "axis_x": { "model": "twilightforest:naga_segment/hortizontal" }, + "axis_y": { "model": "twilightforest:naga_segment/vertical" }, + "axis_z": { "model": "twilightforest:naga_segment/hortizontal", "y": 90 }, + "solid": { + "model": "cube_bottom_top", "textures": { + "side": "twilightforest:blocks/nagastone_long_side", + "top": "twilightforest:blocks/nagastone_turn_top" , + "bottom": "twilightforest:blocks/nagastone_bottom_long" + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar.json b/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar.json new file mode 100644 index 0000000000..712fb27c37 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar.json @@ -0,0 +1,25 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_column", + "textures": { + "side": "twilightforest:blocks/nagastone_pillar_side", + "end" : "twilightforest:blocks/nagastone_pillar_end" + } + }, + "variants": { + "axis": { + "y": {}, + "z": { "x": -90 }, + "x": { "x": -90, "y": -90 } + }, + "reversed": { + "true": { + "textures": { + "side": "twilightforest:blocks/nagastone_pillar_side_alt" + } + }, + "false": {} + } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar_mossy.json b/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar_mossy.json new file mode 100644 index 0000000000..946970be5f --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar_mossy.json @@ -0,0 +1,25 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_column", + "textures": { + "side": "twilightforest:blocks/nagastone_pillar_side_mossy", + "end" : "twilightforest:blocks/nagastone_pillar_end_mossy" + } + }, + "variants": { + "axis": { + "y": {}, + "z": { "x": -90 }, + "x": { "x": -90, "y": -90 } + }, + "reversed": { + "true": { + "textures": { + "side": "twilightforest:blocks/nagastone_pillar_side_mossy_alt" + } + }, + "false": {} + } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar_weathered.json b/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar_weathered.json new file mode 100644 index 0000000000..830f62b081 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/nagastone_pillar_weathered.json @@ -0,0 +1,25 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_column", + "textures": { + "side": "twilightforest:blocks/nagastone_pillar_side_weathered", + "end" : "twilightforest:blocks/nagastone_pillar_end_weathered" + } + }, + "variants": { + "axis": { + "y": {}, + "z": { "x": -90 }, + "x": { "x": -90, "y": -90 } + }, + "reversed": { + "true": { + "textures": { + "side": "twilightforest:blocks/nagastone_pillar_side_weathered_alt" + } + }, + "false": {} + } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs.json b/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs.json new file mode 100644 index 0000000000..48138c0bfe --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/stairs", + "textures": { + "end": "twilightforest:blocks/stone_tiles", + "half": "twilightforest:blocks/nagastone_bare", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "twilightforest:util/outer_stairs" }, + "outer_left": { "model": "twilightforest:util/outer_stairs" }, + "inner_right":{ "model": "twilightforest:util/inner_stairs" }, + "inner_left": { "model": "twilightforest:util/inner_stairs" } + }, + "direction": { + "left": { "textures": { + "side": "twilightforest:blocks/etched_nagastone_left" + } }, + "right": { "textures": { + "side": "twilightforest:blocks/etched_nagastone_right" + } } + }, + "direction=left,facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "direction=left,facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "direction=left,facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "direction=left,facing=north,half=bottom,shape=outer_left": { "y": 180 }, + + "direction=left,facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "direction=left,facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "direction=left,facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "direction=left,facing=north,half=bottom,shape=inner_left": { "y": 180 }, + + "direction=left,facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + + "direction=left,facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "direction=left,facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "direction=left,facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "direction=left,facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + + "direction=left,facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=left,facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + + "direction=left,facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "direction=left,facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=left,facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "direction=left,facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + + "direction=left,facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=left,facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 }, + + + "direction=right,facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "direction=right,facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "direction=right,facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "direction=right,facing=north,half=bottom,shape=outer_left": { "y": 180 }, + + "direction=right,facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "direction=right,facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "direction=right,facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "direction=right,facing=north,half=bottom,shape=inner_left": { "y": 180 }, + + "direction=right,facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "direction=right,facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "direction=right,facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + + "direction=right,facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "direction=right,facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "direction=right,facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "direction=right,facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + + "direction=right,facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=right,facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "direction=right,facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "direction=right,facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + + "direction=right,facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "direction=right,facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=right,facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "direction=right,facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + + "direction=right,facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=right,facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "direction=right,facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "direction=right,facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs_mossy.json b/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs_mossy.json new file mode 100644 index 0000000000..74e7c8ac84 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs_mossy.json @@ -0,0 +1,91 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/stairs", + "textures": { + "end": "twilightforest:blocks/stone_tiles_mossy", + "half": "twilightforest:blocks/nagastone_bare_mossy", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "twilightforest:util/outer_stairs" }, + "outer_left": { "model": "twilightforest:util/outer_stairs" }, + "inner_right":{ "model": "twilightforest:util/inner_stairs" }, + "inner_left": { "model": "twilightforest:util/inner_stairs" } + }, + "direction": { + "left": { "textures": { + "side": "twilightforest:blocks/etched_nagastone_left_mossy" + } }, + "right": { "textures": { + "side": "twilightforest:blocks/etched_nagastone_right_mossy" + } } + }, + "direction=left,facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "direction=left,facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "direction=left,facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "direction=left,facing=north,half=bottom,shape=outer_left": { "y": 180 }, + "direction=left,facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "direction=left,facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "direction=left,facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "direction=left,facing=north,half=bottom,shape=inner_left": { "y": 180 }, + "direction=left,facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + "direction=left,facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "direction=left,facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "direction=left,facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "direction=left,facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + "direction=left,facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=left,facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + "direction=left,facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "direction=left,facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=left,facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "direction=left,facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + "direction=left,facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=left,facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 }, + + "direction=right,facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "direction=right,facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "direction=right,facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "direction=right,facing=north,half=bottom,shape=outer_left": { "y": 180 }, + "direction=right,facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "direction=right,facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "direction=right,facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "direction=right,facing=north,half=bottom,shape=inner_left": { "y": 180 }, + "direction=right,facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "direction=right,facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "direction=right,facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + "direction=right,facing=west,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "direction=right,facing=south,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "direction=right,facing=north,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "direction=right,facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=right,facing=west,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=right,facing=south,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "direction=right,facing=north,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "direction=right,facing=east,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=right,facing=west,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "direction=right,facing=south,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=right,facing=north,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "direction=right,facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=right,facing=west,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=right,facing=south,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "direction=right,facing=north,half=top,shape=inner_left": { "x": 180, "y": 90 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs_weathered.json b/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs_weathered.json new file mode 100644 index 0000000000..cb9c1d38f9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/nagastone_stairs_weathered.json @@ -0,0 +1,91 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/stairs", + "textures": { + "end": "twilightforest:blocks/stone_tiles_weathered", + "half": "twilightforest:blocks/nagastone_bare_weathered", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "facing": { + "east": { }, + "west": { "y": 180 }, + "south": { "y": 90 }, + "north": { "y": 270 } + }, "half":{ + "bottom": { }, + "top": { "x": 180 } + }, "shape": { + "straight":{}, + "outer_right":{ "model": "twilightforest:util/outer_stairs" }, + "outer_left": { "model": "twilightforest:util/outer_stairs" }, + "inner_right":{ "model": "twilightforest:util/inner_stairs" }, + "inner_left": { "model": "twilightforest:util/inner_stairs" } + }, + "direction": { + "left": { "textures": { + "side": "twilightforest:blocks/etched_nagastone_left_weathered" + } }, + "right": { "textures": { + "side": "twilightforest:blocks/etched_nagastone_right_weathered" + } } + }, + "direction=left,facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "direction=left,facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "direction=left,facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "direction=left,facing=north,half=bottom,shape=outer_left": { "y": 180 }, + "direction=left,facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "direction=left,facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "direction=left,facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "direction=left,facing=north,half=bottom,shape=inner_left": { "y": 180 }, + "direction=left,facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + "direction=left,facing=east,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "direction=left,facing=west,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "direction=left,facing=south,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "direction=left,facing=north,half=top,shape=outer_right": { "x": 180, "y": 0 }, + "direction=left,facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=left,facing=west,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=outer_left": { "x": 180, "y": 270 }, + "direction=left,facing=east,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "direction=left,facing=west,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=left,facing=south,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "direction=left,facing=north,half=top,shape=inner_right": { "x": 180, "y": 0 }, + "direction=left,facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=left,facing=west,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "direction=left,facing=south,half=top,shape=inner_left": { "x": 180, "y": 90 }, + "direction=left,facing=north,half=top,shape=inner_left": { "x": 180, "y": 270 }, + + "direction=right,facing=east,half=bottom,shape=outer_left": { "y": 270 }, + "direction=right,facing=west,half=bottom,shape=outer_left": { "y": 90 }, + "direction=right,facing=south,half=bottom,shape=outer_left": { "y": 0 }, + "direction=right,facing=north,half=bottom,shape=outer_left": { "y": 180 }, + "direction=right,facing=east,half=bottom,shape=inner_left": { "y": 270 }, + "direction=right,facing=west,half=bottom,shape=inner_left": { "y": 90 }, + "direction=right,facing=south,half=bottom,shape=inner_left": { "y": 0 }, + "direction=right,facing=north,half=bottom,shape=inner_left": { "y": 180 }, + "direction=right,facing=west,half=top,shape=straight": { "x": 180, "y": 180 }, + "direction=right,facing=south,half=top,shape=straight": { "x": 180, "y": 90 }, + "direction=right,facing=north,half=top,shape=straight": { "x": 180, "y": 270 }, + "direction=right,facing=west,half=top,shape=outer_right": { "x": 180, "y": 90 }, + "direction=right,facing=south,half=top,shape=outer_right": { "x": 180, "y": 270 }, + "direction=right,facing=north,half=top,shape=outer_right": { "x": 180, "y": 180 }, + "direction=right,facing=east,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=right,facing=west,half=top,shape=outer_left": { "x": 180, "y": 0 }, + "direction=right,facing=south,half=top,shape=outer_left": { "x": 180, "y": 180 }, + "direction=right,facing=north,half=top,shape=outer_left": { "x": 180, "y": 90 }, + "direction=right,facing=east,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=right,facing=west,half=top,shape=inner_right": { "x": 180, "y": 90 }, + "direction=right,facing=south,half=top,shape=inner_right": { "x": 180, "y": 270 }, + "direction=right,facing=north,half=top,shape=inner_right": { "x": 180, "y": 180 }, + "direction=right,facing=east,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=right,facing=west,half=top,shape=inner_left": { "x": 180, "y": 0 }, + "direction=right,facing=south,half=top,shape=inner_left": { "x": 180, "y": 180 }, + "direction=right,facing=north,half=top,shape=inner_left": { "x": 180, "y": 90 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/root.json b/src/main/resources/assets/twilightforest/blockstates/root.json new file mode 100644 index 0000000000..996a3ad1a5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/root.json @@ -0,0 +1,12 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "variant": { + "root": { "textures": { "all": "twilightforest:blocks/rootblock" } }, + "liveroot": { "textures": { "all": "twilightforest:blocks/oreroots" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/slider.json b/src/main/resources/assets/twilightforest/blockstates/slider.json new file mode 100644 index 0000000000..806d603807 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/slider.json @@ -0,0 +1,17 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:slider", + "textures": { + "side": "twilightforest:blocks/slider_v", + "end": "twilightforest:blocks/slider_top" + } + }, + "variants": { + "axis": { + "y": {}, + "z": { "textures": { "side": "twilightforest:blocks/slider_h_90" }, "x": 90 }, + "x": { "textures": { "side": "twilightforest:blocks/slider_h_90" }, "x": 90, "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_button.json b/src/main/resources/assets/twilightforest/blockstates/sort_button.json new file mode 100644 index 0000000000..5eb057a412 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_door.json b/src/main/resources/assets/twilightforest/blockstates/sort_door.json new file mode 100644 index 0000000000..3fae81ccb7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/sort_lower", + "top" : "twilightforest:blocks/wood/door/sort_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/sort_doubleslab.json new file mode 100644 index 0000000000..0b02fc93a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_sort_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_sort_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_sort_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_sort_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_fence.json b/src/main/resources/assets/twilightforest/blockstates/sort_fence.json new file mode 100644 index 0000000000..0a0d82ea4a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_gate.json b/src/main/resources/assets/twilightforest/blockstates/sort_gate.json new file mode 100644 index 0000000000..3cd8da6145 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_planks.json b/src/main/resources/assets/twilightforest/blockstates/sort_planks.json new file mode 100644 index 0000000000..dbe02c4112 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_sort_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_sort_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_sort_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_sort_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_plate.json b/src/main/resources/assets/twilightforest/blockstates/sort_plate.json new file mode 100644 index 0000000000..6d42667e0a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_sort_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_slab.json b/src/main/resources/assets/twilightforest/blockstates/sort_slab.json new file mode 100644 index 0000000000..a4f368a780 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_0", + "top" : "twilightforest:blocks/wood/planks_sort_0", + "side" : "twilightforest:blocks/wood/planks_sort_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_0", + "top" : "twilightforest:blocks/wood/planks_sort_0", + "side" : "twilightforest:blocks/wood/planks_sort_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_1", + "top" : "twilightforest:blocks/wood/planks_sort_1", + "side" : "twilightforest:blocks/wood/planks_sort_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_2", + "top" : "twilightforest:blocks/wood/planks_sort_2", + "side" : "twilightforest:blocks/wood/planks_sort_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_3", + "top" : "twilightforest:blocks/wood/planks_sort_3", + "side" : "twilightforest:blocks/wood/planks_sort_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_0", + "top" : "twilightforest:blocks/wood/planks_sort_0", + "side" : "twilightforest:blocks/wood/planks_sort_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_1", + "top" : "twilightforest:blocks/wood/planks_sort_1", + "side" : "twilightforest:blocks/wood/planks_sort_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_2", + "top" : "twilightforest:blocks/wood/planks_sort_2", + "side" : "twilightforest:blocks/wood/planks_sort_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_3", + "top" : "twilightforest:blocks/wood/planks_sort_3", + "side" : "twilightforest:blocks/wood/planks_sort_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_stairs.json b/src/main/resources/assets/twilightforest/blockstates/sort_stairs.json new file mode 100644 index 0000000000..397d1b889b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_sort_0", + "top" : "twilightforest:blocks/wood/planks_sort_0", + "side" : "twilightforest:blocks/wood/planks_sort_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_0", "top": "twilightforest:blocks/wood/planks_sort_0", "side": "twilightforest:blocks/wood/planks_sort_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_1", "top": "twilightforest:blocks/wood/planks_sort_1", "side": "twilightforest:blocks/wood/planks_sort_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_2", "top": "twilightforest:blocks/wood/planks_sort_2", "side": "twilightforest:blocks/wood/planks_sort_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_sort_3", "top": "twilightforest:blocks/wood/planks_sort_3", "side": "twilightforest:blocks/wood/planks_sort_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/sort_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/sort_trapdoor.json new file mode 100644 index 0000000000..b0227a2928 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/sort_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/sort_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/stone_twist.json b/src/main/resources/assets/twilightforest/blockstates/stone_twist.json new file mode 100644 index 0000000000..1dcc6e1d6e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/stone_twist.json @@ -0,0 +1,18 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_column", + "textures": { + "end" : "twilightforest:blocks/stone_twist/twist_end", + "side": "twilightforest:blocks/stone_twist/twist_side" + } + }, + "variants": { + "inventory": [{}], + "axis": { + "y": {}, + "z": { "x": 90 }, + "x": { "x": 90, "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/stone_twist_thin.json b/src/main/resources/assets/twilightforest/blockstates/stone_twist_thin.json new file mode 100644 index 0000000000..c47096c5ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/stone_twist_thin.json @@ -0,0 +1,94 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "blank" : "twilightforest:blocks/stone_twist/twist_blank", + "crown" : "twilightforest:blocks/stone_twist/twist_crown" + }, + "model": "twilightforest:pillar/pillar_12_ctm", + "uvlock": true + }, + "variants": { + "inventory": [{ + "textures": { + "side_x" : "twilightforest:blocks/stone_twist/twist_y", + "side_z" : "twilightforest:blocks/stone_twist/twist_y", + + "bottom_x" : "twilightforest:blocks/stone_twist/cap/y" , + "bottom_z" : "twilightforest:blocks/stone_twist/cap/y" , + "bottom_cap": "twilightforest:blocks/stone_twist/cap/end", + "top_x" : "twilightforest:blocks/stone_twist/cap/y" , + "top_z" : "twilightforest:blocks/stone_twist/cap/y" , + "top_cap" : "twilightforest:blocks/stone_twist/cap/end" + } + }], + "axis": { + "x": { + "textures": { + "side_x" : "twilightforest:blocks/stone_twist/twist_x" , + "side_z" : "twilightforest:blocks/stone_twist/twist_x" , + + "bottom_x" : "twilightforest:blocks/stone_twist/cap/x_x_bottom" , + "bottom_z" : "twilightforest:blocks/stone_twist/cap/x_x_bottom" , + "bottom_cap": "twilightforest:blocks/stone_twist/cap/end_bottom_x", + "top_x" : "twilightforest:blocks/stone_twist/cap/x_x_top" , + "top_z" : "twilightforest:blocks/stone_twist/cap/x_x_top" , + "top_cap" : "twilightforest:blocks/stone_twist/cap/end_top_x" + }, + "x": 90, + "y": 90 + }, + "y": { + "textures": { + "side_x" : "twilightforest:blocks/stone_twist/twist_y" , + "side_z" : "twilightforest:blocks/stone_twist/twist_y" , + + "bottom_x" : "twilightforest:blocks/stone_twist/cap/y_y_bottom" , + "bottom_z" : "twilightforest:blocks/stone_twist/cap/y_y_bottom" , + "bottom_cap": "twilightforest:blocks/stone_twist/cap/end_bottom_y", + "top_x" : "twilightforest:blocks/stone_twist/cap/y_y_top" , + "top_z" : "twilightforest:blocks/stone_twist/cap/y_y_top" , + "top_cap" : "twilightforest:blocks/stone_twist/cap/end_top_y" + } + }, + "z": { + "textures": { + "side_x" : "twilightforest:blocks/stone_twist/twist_x" , + "side_z" : "twilightforest:blocks/stone_twist/twist_y" , + + "bottom_x" : "twilightforest:blocks/stone_twist/cap/x_z_bottom" , + "bottom_z" : "twilightforest:blocks/stone_twist/cap/y_z_bottom" , + "bottom_cap": "twilightforest:blocks/stone_twist/cap/end_bottom_z", + "top_x" : "twilightforest:blocks/stone_twist/cap/x_z_top" , + "top_z" : "twilightforest:blocks/stone_twist/cap/y_z_top" , + "top_cap" : "twilightforest:blocks/stone_twist/cap/end_top_z" + }, + "x": 90 + } + }, + "down": { + "true": {}, + "false": { "submodel": "twilightforest:pillar/pillar_bottom" } + }, + "up":{ + "true": {}, + "false": { "submodel": "twilightforest:pillar/pillar_top" } + }, + "north": { + "true": {}, + "false": {} + }, + "south": { + "true": {}, + "false": {} + }, + "east": { + "true": {}, + "false": {} + }, + "west": { + "true": {}, + "false": {} + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/stronghold_shield.json b/src/main/resources/assets/twilightforest/blockstates/stronghold_shield.json new file mode 100644 index 0000000000..be1d340961 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/stronghold_shield.json @@ -0,0 +1,21 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_top", + "textures": { + "side": "twilightforest:blocks/shield_outside", + "top": "twilightforest:blocks/shield_inside" + }, + "uvlock": true + }, + "variants": { + "facing": { + "up": {}, + "down": { "x": 180 }, + "north": { "x": 90 }, + "south": { "x": 270 }, + "west": { "x": 90, "y": 270 }, + "east": { "x": 90, "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/terrorcotta_circle.json b/src/main/resources/assets/twilightforest/blockstates/terrorcotta_circle.json new file mode 100644 index 0000000000..7a08717dec --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/terrorcotta_circle.json @@ -0,0 +1,22 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/terracotta", + "textures": { + "down" : "twilightforest:blocks/terrorcotta_c", + "up" : "twilightforest:blocks/terrorcotta_d", + "top_left" : "twilightforest:blocks/terrorcotta_b", + "top_right": "twilightforest:blocks/terrorcotta_a", + "bot_left" : "twilightforest:blocks/terrorcotta_d", + "bot_right": "twilightforest:blocks/terrorcotta_c" + }, + "uvlock": true + }, + "variants": { + "inventory" : [{}], + "facing=north": [{ "textures": { "up": "twilightforest:blocks/terrorcotta_a", "down": "twilightforest:blocks/terrorcotta_b" } }], + "facing=west" : [{ "textures": { "up": "twilightforest:blocks/terrorcotta_c", "down": "twilightforest:blocks/terrorcotta_d" }, "y": 270 }], + "facing=south": [{ "y": 180 }], + "facing=east" : [{ "textures": { "up": "twilightforest:blocks/terrorcotta_b", "down": "twilightforest:blocks/terrorcotta_a" }, "y": 90 }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/terrorcotta_diagonal.json b/src/main/resources/assets/twilightforest/blockstates/terrorcotta_diagonal.json new file mode 100644 index 0000000000..ce5a330dfe --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/terrorcotta_diagonal.json @@ -0,0 +1,20 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/terracotta", + "textures": { + "down" : "twilightforest:blocks/terrorcotta_0", + "up" : "twilightforest:blocks/terrorcotta_0", + "top_left" : "twilightforest:blocks/terrorcotta_0", + "top_right": "twilightforest:blocks/terrorcotta_1", + "bot_left" : "twilightforest:blocks/terrorcotta_0", + "bot_right": "twilightforest:blocks/terrorcotta_1" + }, + "uvlock": true + }, + "variants": { + "inventory" : [{}], + "is_rotated=false": [{}], + "is_rotated=true" : [{ "textures": { "up": "twilightforest:blocks/terrorcotta_1", "down": "twilightforest:blocks/terrorcotta_1" }, "y": 90 }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/thorn_rose.json b/src/main/resources/assets/twilightforest/blockstates/thorn_rose.json new file mode 100644 index 0000000000..0cf0247329 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/thorn_rose.json @@ -0,0 +1,11 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cross", + "textures": { "cross": "twilightforest:blocks/thorn_rose" } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:blocks/thorn_rose"}}], + "normal": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/thorns.json b/src/main/resources/assets/twilightforest/blockstates/thorns.json new file mode 100644 index 0000000000..0a3a00a09c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/thorns.json @@ -0,0 +1,44 @@ +{ + "forge_marker": 1, + "defaults": { + "transform": "forge:default-block", + "textures": { + "end": "twilightforest:blocks/brown_thorns_top", + "side": "twilightforest:blocks/brown_thorns_side", + "particle": "#end" + }, + "model": "twilightforest:thorns_main" + }, + "variants": { + "axis":{ + "x":{ "x": 90, "y": 90 }, + "y":{}, + "z":{ "x": 270, "y": 180 } + }, + "north":{ + "true":{ "submodel": { "key_n": { "model": "twilightforest:thorns_section_top", "y": 270 } } }, + "false":{} + }, + "south":{ + "true":{ "submodel": { "key_s": { "model": "twilightforest:thorns_section_bottom", "y": 270 } } }, + "false":{} + }, + "east":{ + "true":{ "submodel": { "key_e": { "model": "twilightforest:thorns_section_top", "y": 0 } } }, + "false":{} + }, + "west":{ + "true":{ "submodel": { "key_w": { "model": "twilightforest:thorns_section_bottom", "y": 0 } } }, + "false":{} + }, + "variant": { + "brown": {}, + "green":{ + "textures": { + "end": "twilightforest:blocks/green_thorns_top", + "side": "twilightforest:blocks/green_thorns_side" + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_button.json b/src/main/resources/assets/twilightforest/blockstates/time_button.json new file mode 100644 index 0000000000..a06d89045d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_door.json b/src/main/resources/assets/twilightforest/blockstates/time_door.json new file mode 100644 index 0000000000..e8a447f0d5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/time_lower", + "top" : "twilightforest:blocks/wood/door/time_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/time_doubleslab.json new file mode 100644 index 0000000000..889f575df0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_time_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_time_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_time_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_time_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_fence.json b/src/main/resources/assets/twilightforest/blockstates/time_fence.json new file mode 100644 index 0000000000..58bad5fdb3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_gate.json b/src/main/resources/assets/twilightforest/blockstates/time_gate.json new file mode 100644 index 0000000000..bf3dc7b70c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_planks.json b/src/main/resources/assets/twilightforest/blockstates/time_planks.json new file mode 100644 index 0000000000..5bab1f62d2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_time_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_time_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_time_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_time_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_plate.json b/src/main/resources/assets/twilightforest/blockstates/time_plate.json new file mode 100644 index 0000000000..b53f16a7cf --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_time_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_slab.json b/src/main/resources/assets/twilightforest/blockstates/time_slab.json new file mode 100644 index 0000000000..7403f88e4f --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_0", + "top" : "twilightforest:blocks/wood/planks_time_0", + "side" : "twilightforest:blocks/wood/planks_time_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_0", + "top" : "twilightforest:blocks/wood/planks_time_0", + "side" : "twilightforest:blocks/wood/planks_time_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_1", + "top" : "twilightforest:blocks/wood/planks_time_1", + "side" : "twilightforest:blocks/wood/planks_time_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_2", + "top" : "twilightforest:blocks/wood/planks_time_2", + "side" : "twilightforest:blocks/wood/planks_time_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_3", + "top" : "twilightforest:blocks/wood/planks_time_3", + "side" : "twilightforest:blocks/wood/planks_time_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_0", + "top" : "twilightforest:blocks/wood/planks_time_0", + "side" : "twilightforest:blocks/wood/planks_time_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_1", + "top" : "twilightforest:blocks/wood/planks_time_1", + "side" : "twilightforest:blocks/wood/planks_time_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_2", + "top" : "twilightforest:blocks/wood/planks_time_2", + "side" : "twilightforest:blocks/wood/planks_time_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_3", + "top" : "twilightforest:blocks/wood/planks_time_3", + "side" : "twilightforest:blocks/wood/planks_time_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_stairs.json b/src/main/resources/assets/twilightforest/blockstates/time_stairs.json new file mode 100644 index 0000000000..830d1432cb --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_time_0", + "top" : "twilightforest:blocks/wood/planks_time_0", + "side" : "twilightforest:blocks/wood/planks_time_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_0", "top": "twilightforest:blocks/wood/planks_time_0", "side": "twilightforest:blocks/wood/planks_time_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_time_1", "top": "twilightforest:blocks/wood/planks_time_1", "side": "twilightforest:blocks/wood/planks_time_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_2", "top": "twilightforest:blocks/wood/planks_time_2", "side": "twilightforest:blocks/wood/planks_time_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_time_3", "top": "twilightforest:blocks/wood/planks_time_3", "side": "twilightforest:blocks/wood/planks_time_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/time_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/time_trapdoor.json new file mode 100644 index 0000000000..59686bea0d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/time_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/time_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/tower_device.json b/src/main/resources/assets/twilightforest/blockstates/tower_device.json new file mode 100644 index 0000000000..364bdc9d02 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/tower_device.json @@ -0,0 +1,116 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:util/cube_all_3_layer" }, + "variants": { + "variant": { + "reappearing_inactive": { + "textures": { + "all": "twilightforest:blocks/towerdev_reappearing_off", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_reappearing_off_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_reappearing_off_2" + } + }, + "reappearing_active": { + "textures": { + "all": "twilightforest:blocks/towerdev_reappearing_on", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_reappearing_on_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_reappearing_on_2" + } + }, + "vanish_inactive": { + "textures": { + "all": "twilightforest:blocks/towerdev_vanish_off", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_vanish_off_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_vanish_off_2" + } + }, + "vanish_active": { + "textures": { + "all": "twilightforest:blocks/towerdev_vanish_on", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_vanish_on_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_vanish_on_2" + } + }, + "vanish_unlocked": { + "textures": { + "all": "twilightforest:blocks/towerdev_lock_off", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_lock_off_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_lock_off_2" + } + }, + "vanish_locked": { + "textures": { + "all": "twilightforest:blocks/towerdev_lock_on", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_lock_on_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_lock_on_2" + } + }, + "builder_inactive": { + "textures": { + "all": "twilightforest:blocks/towerdev_builder_off", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_builder_off_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_builder_off_2" + } + }, + "builder_active": { + "textures": { + "all": "twilightforest:blocks/towerdev_builder_on", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_builder_on_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_builder_on_2" + } + }, + "builder_timeout": { + "textures": { + "all": "twilightforest:blocks/towerdev_builder_timeout", + "all2": "twilightforest:blocks/tower_device_level_2/towerdev_builder_timeout_1", + "all3": "twilightforest:blocks/tower_device_level_3/towerdev_builder_timeout_2" + } + }, + "antibuilder": { + "textures": { + "all": "twilightforest:blocks/towerdev_antibuilder", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_antibuilder_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_antibuilder_2" + } + }, + "ghasttrap_inactive": { + "model": "twilightforest:util/cube_bottom_top_3_layer", + "textures": { + "top": "twilightforest:blocks/towerdev_ghasttraplid_off", + "side": "twilightforest:blocks/towerdev_ghasttrap_off", + "bottom": "twilightforest:blocks/towerwood_encased", + "top2": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_off_1", + "side2": "twilightforest:blocks/tower_device_level_1/towerdev_ghasttrap_off_1", + "top3": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_off_1", + "side3": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttrap_off_2" + } + }, + "ghasttrap_active": { + "model": "twilightforest:util/cube_bottom_top_3_layer", + "textures": { + "top": "twilightforest:blocks/towerdev_ghasttraplid_on", + "side": "twilightforest:blocks/towerdev_ghasttrap_on", + "bottom": "twilightforest:blocks/towerwood_encased", + "top2": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttraplid_on_1", + "side2": "twilightforest:blocks/tower_device_level_1/towerdev_ghasttrap_on_1", + "top3": "twilightforest:blocks/tower_device_level_3/towerdev_ghasttraplid_on_2", + "side3": "twilightforest:blocks/tower_device_level_2/towerdev_ghasttrap_on_2" + } + }, + "reactor_inactive": { + "textures": { + "all": "twilightforest:blocks/towerdev_reactor_off", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_reactor_off_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_reactor_off_2" + } + }, + "reactor_active": { + "textures": { + "all": "twilightforest:blocks/towerdev_reactor_on", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_reactor_on_1", + "all3": "twilightforest:blocks/tower_device_level_2/towerdev_reactor_on_2" + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/tower_translucent.json b/src/main/resources/assets/twilightforest/blockstates/tower_translucent.json new file mode 100644 index 0000000000..dc73be921f --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/tower_translucent.json @@ -0,0 +1,40 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/cube_all_2_layer_no_shade", + "textures": { "particle": "twilightforest:blocks/tower_device_level_1/towerdev_antibuilder_1" } + }, + "variants": { + "variant": { + "reappearing_inactive": { + "model": "twilightforest:util/4_cubed", + "textures": { "all": "twilightforest:blocks/towerdev_reappearing_trace_off" } + }, + "reappearing_active": { + "model": "twilightforest:util/4_cubed", + "textures": { "all": "twilightforest:blocks/towerdev_reappearing_trace_on" } + }, + "built_inactive": { + "textures": { + "all": "twilightforest:blocks/towerdev_built_off", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_builder_off_1" + } + }, + "built_active": { + "textures": { + "all": "twilightforest:blocks/towerdev_built_on", + "all2": "twilightforest:blocks/tower_device_level_1/towerdev_builder_on_1" + } + }, + "reverter_replacement": { + "textures": { + "all": "twilightforest:blocks/towerdev_antibuilt", + "all2": "twilightforest:blocks/tower_device_level_2/towerdev_antibuilt_1" + } + }, + "reactor_debris": { "model": "cube_all", "textures": { "all": "blocks/destroy_stage_9" } }, + "fake_gold": { "model": "gold_block" }, + "fake_diamond": { "model": "diamond_block" } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/tower_wood.json b/src/main/resources/assets/twilightforest/blockstates/tower_wood.json new file mode 100644 index 0000000000..2e57b6d45c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/tower_wood.json @@ -0,0 +1,27 @@ +{ + "forge_marker": 1, + "defaults": { "model": "leaves" }, + "variants": { + "variant=plain": [ + { "textures": { "all": "twilightforest:blocks/towerwood_planks" } }, + { "textures": { "all": "twilightforest:blocks/towerwood_planks" }, "model": "twilightforest:util/leaves_flipped_v" } + ], + "variant=encased": [ + { "textures": { "all": "twilightforest:blocks/towerwood_encased" } } + ], + "variant=cracked": [ + { "textures": { "all": "twilightforest:blocks/towerwood_cracked" } }, + { "textures": { "all": "twilightforest:blocks/towerwood_alt" } }, + { "textures": { "all": "twilightforest:blocks/towerwood_cracked" }, "model": "twilightforest:util/leaves_flipped_v" }, + { "textures": { "all": "twilightforest:blocks/towerwood_alt" }, "model": "twilightforest:util/leaves_flipped_v" } + ], + "variant=mossy": [ + { "textures": { "all": "twilightforest:blocks/towerwood_mossy" } }, + { "textures": { "all": "twilightforest:blocks/towerwood_mossy" }, "model": "twilightforest:util/leaves_flipped_v" } + ], + "variant=infested": [ + { "textures": { "all": "twilightforest:blocks/towerwood_infested" } }, + { "textures": { "all": "twilightforest:blocks/towerwood_infested" }, "model": "twilightforest:util/leaves_flipped_v" } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_button.json b/src/main/resources/assets/twilightforest/blockstates/trans_button.json new file mode 100644 index 0000000000..b9663217e7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_door.json b/src/main/resources/assets/twilightforest/blockstates/trans_door.json new file mode 100644 index 0000000000..2f4242841a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/twilight_oak_lower", + "top" : "twilightforest:blocks/wood/door/twilight_oak_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/trans_doubleslab.json new file mode 100644 index 0000000000..349d3175d3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_trans_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_trans_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_trans_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_trans_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_fence.json b/src/main/resources/assets/twilightforest/blockstates/trans_fence.json new file mode 100644 index 0000000000..3c7894b4eb --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_gate.json b/src/main/resources/assets/twilightforest/blockstates/trans_gate.json new file mode 100644 index 0000000000..0f9992ff7c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_planks.json b/src/main/resources/assets/twilightforest/blockstates/trans_planks.json new file mode 100644 index 0000000000..affc8b470b --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_trans_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_trans_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_trans_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_trans_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_plate.json b/src/main/resources/assets/twilightforest/blockstates/trans_plate.json new file mode 100644 index 0000000000..91bc7fa71d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_trans_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_slab.json b/src/main/resources/assets/twilightforest/blockstates/trans_slab.json new file mode 100644 index 0000000000..26e414fc67 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_0", + "top" : "twilightforest:blocks/wood/planks_trans_0", + "side" : "twilightforest:blocks/wood/planks_trans_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_0", + "top" : "twilightforest:blocks/wood/planks_trans_0", + "side" : "twilightforest:blocks/wood/planks_trans_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_1", + "top" : "twilightforest:blocks/wood/planks_trans_1", + "side" : "twilightforest:blocks/wood/planks_trans_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_2", + "top" : "twilightforest:blocks/wood/planks_trans_2", + "side" : "twilightforest:blocks/wood/planks_trans_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_3", + "top" : "twilightforest:blocks/wood/planks_trans_3", + "side" : "twilightforest:blocks/wood/planks_trans_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_0", + "top" : "twilightforest:blocks/wood/planks_trans_0", + "side" : "twilightforest:blocks/wood/planks_trans_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_1", + "top" : "twilightforest:blocks/wood/planks_trans_1", + "side" : "twilightforest:blocks/wood/planks_trans_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_2", + "top" : "twilightforest:blocks/wood/planks_trans_2", + "side" : "twilightforest:blocks/wood/planks_trans_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_3", + "top" : "twilightforest:blocks/wood/planks_trans_3", + "side" : "twilightforest:blocks/wood/planks_trans_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_stairs.json b/src/main/resources/assets/twilightforest/blockstates/trans_stairs.json new file mode 100644 index 0000000000..06cf2b5050 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_trans_0", + "top" : "twilightforest:blocks/wood/planks_trans_0", + "side" : "twilightforest:blocks/wood/planks_trans_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_0", "top": "twilightforest:blocks/wood/planks_trans_0", "side": "twilightforest:blocks/wood/planks_trans_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_1", "top": "twilightforest:blocks/wood/planks_trans_1", "side": "twilightforest:blocks/wood/planks_trans_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_2", "top": "twilightforest:blocks/wood/planks_trans_2", "side": "twilightforest:blocks/wood/planks_trans_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_trans_3", "top": "twilightforest:blocks/wood/planks_trans_3", "side": "twilightforest:blocks/wood/planks_trans_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trans_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/trans_trapdoor.json new file mode 100644 index 0000000000..1b79684cfc --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trans_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/twilight_oak_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/trollber.json b/src/main/resources/assets/twilightforest/blockstates/trollber.json new file mode 100644 index 0000000000..2e6df77756 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trollber.json @@ -0,0 +1,15 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/cross_2_layer", + "textures": { + "cross": "twilightforest:blocks/ripe_torch_cluster", + "cross2": "twilightforest:blocks/ripe_torch_cluster_glow" + }, + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:blocks/ripe_torch_cluster"}}], + "normal": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trollsteinn.json b/src/main/resources/assets/twilightforest/blockstates/trollsteinn.json new file mode 100644 index 0000000000..3768589aa7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trollsteinn.json @@ -0,0 +1,23 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube", + "textures": { + "up": "twilightforest:blocks/trollsteinn", + "down": "twilightforest:blocks/trollsteinn", + "west": "twilightforest:blocks/trollsteinn", + "north": "twilightforest:blocks/trollsteinn", + "east": "twilightforest:blocks/trollsteinn", + "south": "twilightforest:blocks/trollsteinn", + "particle": "twilightforest:blocks/trollsteinn" + } + }, + "variants": { + "up": { "true": { "textures": { "up": "twilightforest:blocks/trollsteinn_light" } }, "false": {} }, + "down": { "true": { "textures": { "down": "twilightforest:blocks/trollsteinn_light" } }, "false": {} }, + "north": { "true": { "textures": { "north": "twilightforest:blocks/trollsteinn_light" } }, "false": {} }, + "south": { "true": { "textures": { "south": "twilightforest:blocks/trollsteinn_light" } }, "false": {} }, + "east": { "true": { "textures": { "east": "twilightforest:blocks/trollsteinn_light" } }, "false": {} }, + "west": { "true": { "textures": { "west": "twilightforest:blocks/trollsteinn_light" } }, "false": {} } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trollvidr.json b/src/main/resources/assets/twilightforest/blockstates/trollvidr.json new file mode 100644 index 0000000000..a804fb947d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trollvidr.json @@ -0,0 +1,11 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cross", + "textures": { "cross": "twilightforest:blocks/troll_root" } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:blocks/troll_root"}}], + "normal": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trophy.json b/src/main/resources/assets/twilightforest/blockstates/trophy.json new file mode 100644 index 0000000000..4815c72886 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trophy.json @@ -0,0 +1,18 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/dummy", + "textures": { + "particle": "blocks/soul_sand" + }, + "transform": "forge:default-item" + }, + "variants": { + "normal": [{}], + "inventory_naga": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:items/naga_trophy" } }], + "inventory_hydra": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:items/hydra_trophy" } }], + "inventory_lich": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:items/lich_trophy" } }], + "inventory_snow_queen": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:items/snow_queen_trophy" } }], + "inventory_ur_ghast": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:items/ur_ghast_trophy" } }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trophy_pedestal.json b/src/main/resources/assets/twilightforest/blockstates/trophy_pedestal.json new file mode 100644 index 0000000000..915ea67862 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trophy_pedestal.json @@ -0,0 +1,364 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/pedestal", + "uvlock": true, + "textures": { + "particle": "twilightforest:blocks/pedestal/top" + } + }, + "variants": { + "latent=true": [{ + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }], + "latent=false" : [{ + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/naga_flat", + "south": "twilightforest:blocks/pedestal/lich_flat", + "west" : "twilightforest:blocks/pedestal/hydra_flat", + "east" : "twilightforest:blocks/pedestal/ur-ghast_flat" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/snow_queen_flat", + "south": "twilightforest:blocks/pedestal/naga_flat", + "west" : "twilightforest:blocks/pedestal/lich_flat", + "east" : "twilightforest:blocks/pedestal/hydra_flat" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/ur-ghast_flat", + "south": "twilightforest:blocks/pedestal/snow_queen_flat", + "west" : "twilightforest:blocks/pedestal/naga_flat", + "east" : "twilightforest:blocks/pedestal/lich_flat" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/hydra_flat", + "south": "twilightforest:blocks/pedestal/ur-ghast_flat", + "west" : "twilightforest:blocks/pedestal/snow_queen_flat", + "east" : "twilightforest:blocks/pedestal/naga_flat" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/lich_flat", + "south": "twilightforest:blocks/pedestal/hydra_flat", + "west" : "twilightforest:blocks/pedestal/ur-ghast_flat", + "east" : "twilightforest:blocks/pedestal/snow_queen_flat" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/naga_flat", + "south": "twilightforest:blocks/pedestal/lich_flat", + "west" : "twilightforest:blocks/pedestal/hydra_flat", + "east" : "twilightforest:blocks/pedestal/ur-ghast_flat" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/snow_queen_flat", + "south": "twilightforest:blocks/pedestal/naga_flat", + "west" : "twilightforest:blocks/pedestal/lich_flat", + "east" : "twilightforest:blocks/pedestal/hydra_flat" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/ur-ghast_flat", + "south": "twilightforest:blocks/pedestal/snow_queen_flat", + "west" : "twilightforest:blocks/pedestal/naga_flat", + "east" : "twilightforest:blocks/pedestal/lich_flat" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/hydra_flat", + "south": "twilightforest:blocks/pedestal/ur-ghast_flat", + "west" : "twilightforest:blocks/pedestal/snow_queen_flat", + "east" : "twilightforest:blocks/pedestal/naga_flat" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/lich_flat", + "south": "twilightforest:blocks/pedestal/hydra_flat", + "west" : "twilightforest:blocks/pedestal/ur-ghast_flat", + "east" : "twilightforest:blocks/pedestal/snow_queen_flat" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/naga_flat", + "south": "twilightforest:blocks/pedestal/lich_flat", + "west" : "twilightforest:blocks/pedestal/hydra_flat", + "east" : "twilightforest:blocks/pedestal/ur-ghast_flat" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/snow_queen_flat", + "south": "twilightforest:blocks/pedestal/naga_flat", + "west" : "twilightforest:blocks/pedestal/lich_flat", + "east" : "twilightforest:blocks/pedestal/hydra_flat" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/ur-ghast_flat", + "south": "twilightforest:blocks/pedestal/snow_queen_flat", + "west" : "twilightforest:blocks/pedestal/naga_flat", + "east" : "twilightforest:blocks/pedestal/lich_flat" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/hydra_flat", + "south": "twilightforest:blocks/pedestal/ur-ghast_flat", + "west" : "twilightforest:blocks/pedestal/snow_queen_flat", + "east" : "twilightforest:blocks/pedestal/naga_flat" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/lich_flat", + "south": "twilightforest:blocks/pedestal/hydra_flat", + "west" : "twilightforest:blocks/pedestal/ur-ghast_flat", + "east" : "twilightforest:blocks/pedestal/snow_queen_flat" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/naga_flat", + "south": "twilightforest:blocks/pedestal/lich_flat", + "west" : "twilightforest:blocks/pedestal/hydra_flat", + "east" : "twilightforest:blocks/pedestal/ur-ghast_flat" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/snow_queen_flat", + "south": "twilightforest:blocks/pedestal/naga_flat", + "west" : "twilightforest:blocks/pedestal/lich_flat", + "east" : "twilightforest:blocks/pedestal/hydra_flat" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/ur-ghast_flat", + "south": "twilightforest:blocks/pedestal/snow_queen_flat", + "west" : "twilightforest:blocks/pedestal/naga_flat", + "east" : "twilightforest:blocks/pedestal/lich_flat" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/hydra_flat", + "south": "twilightforest:blocks/pedestal/ur-ghast_flat", + "west" : "twilightforest:blocks/pedestal/snow_queen_flat", + "east" : "twilightforest:blocks/pedestal/naga_flat" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top_flat", + "north": "twilightforest:blocks/pedestal/lich_flat", + "south": "twilightforest:blocks/pedestal/hydra_flat", + "west" : "twilightforest:blocks/pedestal/ur-ghast_flat", + "east" : "twilightforest:blocks/pedestal/snow_queen_flat" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/trophy_pedestal_ctm.json b/src/main/resources/assets/twilightforest/blockstates/trophy_pedestal_ctm.json new file mode 100644 index 0000000000..3bc76d407d --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/trophy_pedestal_ctm.json @@ -0,0 +1,484 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/pedestal", + "uvlock": true, + "textures": { + "particle": "twilightforest:blocks/pedestal/top" + } + }, + "variants": { + "latent=true": [{ + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/naga_latent", + "south": "twilightforest:blocks/pedestal/lich_latent", + "west" : "twilightforest:blocks/pedestal/hydra_latent", + "east" : "twilightforest:blocks/pedestal/ur-ghast_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/snow_queen_latent", + "south": "twilightforest:blocks/pedestal/naga_latent", + "west" : "twilightforest:blocks/pedestal/lich_latent", + "east" : "twilightforest:blocks/pedestal/hydra_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/ur-ghast_latent", + "south": "twilightforest:blocks/pedestal/snow_queen_latent", + "west" : "twilightforest:blocks/pedestal/naga_latent", + "east" : "twilightforest:blocks/pedestal/lich_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/hydra_latent", + "south": "twilightforest:blocks/pedestal/ur-ghast_latent", + "west" : "twilightforest:blocks/pedestal/snow_queen_latent", + "east" : "twilightforest:blocks/pedestal/naga_latent" + } + }, { + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north": "twilightforest:blocks/pedestal/lich_latent", + "south": "twilightforest:blocks/pedestal/hydra_latent", + "west" : "twilightforest:blocks/pedestal/ur-ghast_latent", + "east" : "twilightforest:blocks/pedestal/snow_queen_latent" + } + }], + "latent=false" : [{ + "model": "twilightforest:util/pedestal_2_layer", + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/naga", + "south" : "twilightforest:blocks/pedestal/lich", + "west" : "twilightforest:blocks/pedestal/hydra", + "east" : "twilightforest:blocks/pedestal/ur-ghast", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/naga_glow", + "south2": "twilightforest:blocks/pedestal/lich_glow", + "west2" : "twilightforest:blocks/pedestal/hydra_glow", + "east2" : "twilightforest:blocks/pedestal/ur-ghast_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/snow_queen", + "south" : "twilightforest:blocks/pedestal/naga", + "west" : "twilightforest:blocks/pedestal/lich", + "east" : "twilightforest:blocks/pedestal/hydra", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/snow_queen_glow", + "south2": "twilightforest:blocks/pedestal/naga_glow", + "west2" : "twilightforest:blocks/pedestal/lich_glow", + "east2" : "twilightforest:blocks/pedestal/hydra_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/ur-ghast", + "south" : "twilightforest:blocks/pedestal/snow_queen", + "west" : "twilightforest:blocks/pedestal/naga", + "east" : "twilightforest:blocks/pedestal/lich", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "south2": "twilightforest:blocks/pedestal/snow_queen_glow", + "west2" : "twilightforest:blocks/pedestal/naga_glow", + "east2" : "twilightforest:blocks/pedestal/lich_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/hydra", + "south" : "twilightforest:blocks/pedestal/ur-ghast", + "west" : "twilightforest:blocks/pedestal/snow_queen", + "east" : "twilightforest:blocks/pedestal/naga", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/hydra_glow", + "south2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "west2" : "twilightforest:blocks/pedestal/snow_queen_glow", + "east2" : "twilightforest:blocks/pedestal/naga_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/lich", + "south" : "twilightforest:blocks/pedestal/hydra", + "west" : "twilightforest:blocks/pedestal/ur-ghast", + "east" : "twilightforest:blocks/pedestal/snow_queen", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/lich_glow", + "south2": "twilightforest:blocks/pedestal/hydra_glow", + "west2" : "twilightforest:blocks/pedestal/ur-ghast_glow", + "east2" : "twilightforest:blocks/pedestal/snow_queen_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/naga", + "south" : "twilightforest:blocks/pedestal/lich", + "west" : "twilightforest:blocks/pedestal/hydra", + "east" : "twilightforest:blocks/pedestal/ur-ghast", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/naga_glow", + "south2": "twilightforest:blocks/pedestal/lich_glow", + "west2" : "twilightforest:blocks/pedestal/hydra_glow", + "east2" : "twilightforest:blocks/pedestal/ur-ghast_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/snow_queen", + "south" : "twilightforest:blocks/pedestal/naga", + "west" : "twilightforest:blocks/pedestal/lich", + "east" : "twilightforest:blocks/pedestal/hydra", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/snow_queen_glow", + "south2": "twilightforest:blocks/pedestal/naga_glow", + "west2" : "twilightforest:blocks/pedestal/lich_glow", + "east2" : "twilightforest:blocks/pedestal/hydra_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/ur-ghast", + "south" : "twilightforest:blocks/pedestal/snow_queen", + "west" : "twilightforest:blocks/pedestal/naga", + "east" : "twilightforest:blocks/pedestal/lich", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "south2": "twilightforest:blocks/pedestal/snow_queen_glow", + "west2" : "twilightforest:blocks/pedestal/naga_glow", + "east2" : "twilightforest:blocks/pedestal/lich_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/hydra", + "south" : "twilightforest:blocks/pedestal/ur-ghast", + "west" : "twilightforest:blocks/pedestal/snow_queen", + "east" : "twilightforest:blocks/pedestal/naga", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/hydra_glow", + "south2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "west2" : "twilightforest:blocks/pedestal/snow_queen_glow", + "east2" : "twilightforest:blocks/pedestal/naga_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 90, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/lich", + "south" : "twilightforest:blocks/pedestal/hydra", + "west" : "twilightforest:blocks/pedestal/ur-ghast", + "east" : "twilightforest:blocks/pedestal/snow_queen", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/lich_glow", + "south2": "twilightforest:blocks/pedestal/hydra_glow", + "west2" : "twilightforest:blocks/pedestal/ur-ghast_glow", + "east2" : "twilightforest:blocks/pedestal/snow_queen_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/naga", + "south" : "twilightforest:blocks/pedestal/lich", + "west" : "twilightforest:blocks/pedestal/hydra", + "east" : "twilightforest:blocks/pedestal/ur-ghast", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/naga_glow", + "south2": "twilightforest:blocks/pedestal/lich_glow", + "west2" : "twilightforest:blocks/pedestal/hydra_glow", + "east2" : "twilightforest:blocks/pedestal/ur-ghast_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/snow_queen", + "south" : "twilightforest:blocks/pedestal/naga", + "west" : "twilightforest:blocks/pedestal/lich", + "east" : "twilightforest:blocks/pedestal/hydra", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/snow_queen_glow", + "south2": "twilightforest:blocks/pedestal/naga_glow", + "west2" : "twilightforest:blocks/pedestal/lich_glow", + "east2" : "twilightforest:blocks/pedestal/hydra_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/ur-ghast", + "south" : "twilightforest:blocks/pedestal/snow_queen", + "west" : "twilightforest:blocks/pedestal/naga", + "east" : "twilightforest:blocks/pedestal/lich", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "south2": "twilightforest:blocks/pedestal/snow_queen_glow", + "west2" : "twilightforest:blocks/pedestal/naga_glow", + "east2" : "twilightforest:blocks/pedestal/lich_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/hydra", + "south" : "twilightforest:blocks/pedestal/ur-ghast", + "west" : "twilightforest:blocks/pedestal/snow_queen", + "east" : "twilightforest:blocks/pedestal/naga", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/hydra_glow", + "south2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "west2" : "twilightforest:blocks/pedestal/snow_queen_glow", + "east2" : "twilightforest:blocks/pedestal/naga_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 180, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/lich", + "south" : "twilightforest:blocks/pedestal/hydra", + "west" : "twilightforest:blocks/pedestal/ur-ghast", + "east" : "twilightforest:blocks/pedestal/snow_queen", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/lich_glow", + "south2": "twilightforest:blocks/pedestal/hydra_glow", + "west2" : "twilightforest:blocks/pedestal/ur-ghast_glow", + "east2" : "twilightforest:blocks/pedestal/snow_queen_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/naga", + "south" : "twilightforest:blocks/pedestal/lich", + "west" : "twilightforest:blocks/pedestal/hydra", + "east" : "twilightforest:blocks/pedestal/ur-ghast", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/naga_glow", + "south2": "twilightforest:blocks/pedestal/lich_glow", + "west2" : "twilightforest:blocks/pedestal/hydra_glow", + "east2" : "twilightforest:blocks/pedestal/ur-ghast_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/snow_queen", + "south" : "twilightforest:blocks/pedestal/naga", + "west" : "twilightforest:blocks/pedestal/lich", + "east" : "twilightforest:blocks/pedestal/hydra", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/snow_queen_glow", + "south2": "twilightforest:blocks/pedestal/naga_glow", + "west2" : "twilightforest:blocks/pedestal/lich_glow", + "east2" : "twilightforest:blocks/pedestal/hydra_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/ur-ghast", + "south" : "twilightforest:blocks/pedestal/snow_queen", + "west" : "twilightforest:blocks/pedestal/naga", + "east" : "twilightforest:blocks/pedestal/lich", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "south2": "twilightforest:blocks/pedestal/snow_queen_glow", + "west2" : "twilightforest:blocks/pedestal/naga_glow", + "east2" : "twilightforest:blocks/pedestal/lich_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/hydra", + "south" : "twilightforest:blocks/pedestal/ur-ghast", + "west" : "twilightforest:blocks/pedestal/snow_queen", + "east" : "twilightforest:blocks/pedestal/naga", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/hydra_glow", + "south2": "twilightforest:blocks/pedestal/ur-ghast_glow", + "west2" : "twilightforest:blocks/pedestal/snow_queen_glow", + "east2" : "twilightforest:blocks/pedestal/naga_glow" + } + }, { + "model": "twilightforest:util/pedestal_2_layer", + "y": 270, + "textures": { + "end" : "twilightforest:blocks/pedestal/top", + "north" : "twilightforest:blocks/pedestal/lich", + "south" : "twilightforest:blocks/pedestal/hydra", + "west" : "twilightforest:blocks/pedestal/ur-ghast", + "east" : "twilightforest:blocks/pedestal/snow_queen", + "end2" : "twilightforest:blocks/pedestal/top_glow", + "north2": "twilightforest:blocks/pedestal/lich_glow", + "south2": "twilightforest:blocks/pedestal/hydra_glow", + "west2" : "twilightforest:blocks/pedestal/ur-ghast_glow", + "east2" : "twilightforest:blocks/pedestal/snow_queen_glow" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_leaves.json b/src/main/resources/assets/twilightforest/blockstates/twilight_leaves.json new file mode 100644 index 0000000000..2757bdfa6e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_leaves.json @@ -0,0 +1,12 @@ +{ + "forge_marker": 1, + "defaults": { "model": "leaves" }, + "variants": { + "variant": { + "oak": { "textures": { "all": "blocks/leaves_oak" } }, + "canopy": { "textures": { "all": "blocks/leaves_spruce" } }, + "mangrove": { "textures": { "all": "blocks/leaves_birch" } }, + "rainboak": { "textures": { "all": "blocks/leaves_oak" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_leaves_3.json b/src/main/resources/assets/twilightforest/blockstates/twilight_leaves_3.json new file mode 100644 index 0000000000..2bea937d42 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_leaves_3.json @@ -0,0 +1,10 @@ +{ + "forge_marker": 1, + "defaults": { "model": "leaves" }, + "variants": { + "variant": { + "thorn": { "textures": { "all": "blocks/leaves_oak" } }, + "beanstalk": { "textures": { "all": "blocks/leaves_spruce" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_log.json b/src/main/resources/assets/twilightforest/blockstates/twilight_log.json new file mode 100644 index 0000000000..9e6c669efe --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_log.json @@ -0,0 +1,20 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_column" + }, + "variants": { + "axis": { + "y": {}, + "z": { "x": 90 }, + "x": { "x": 90, "y": 90 }, + "none": { "model": "cube_all", "textures": { "all": "#side" } } + }, + "variant": { + "oak": { "textures": { "end":"twilightforest:blocks/oak_top" , "side":"twilightforest:blocks/oak_side" } }, + "canopy": { "textures": { "end":"twilightforest:blocks/canopy_top" , "side":"twilightforest:blocks/canopy_side" } }, + "mangrove": { "textures": { "end":"twilightforest:blocks/mangrove_top", "side":"twilightforest:blocks/mangrove_side" } }, + "dark": { "textures": { "end":"twilightforest:blocks/darkwood_top", "side":"twilightforest:blocks/darkwood_side" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_button.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_button.json new file mode 100644 index 0000000000..f425ae6dca --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_button.json @@ -0,0 +1,82 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "button_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }], + + "facing=up,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=down,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180 } + ], + "facing=east,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 , "y": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=false" : [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 , "y": 270 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 , "y": 180 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=false": [ + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 }, + { "model": "button" , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 } + ], + "facing=up,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=down,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180 } + ], + "facing=east,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 , "y": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 , "y": 90 } + ], + "facing=west,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 , "y": 270 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 , "y": 270 } + ], + "facing=south,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 , "y": 180 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 , "y": 180 } + ], + "facing=north,powered=true" : [ + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 90 }, + { "model": "button_pressed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 90 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_door.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_door.json new file mode 100644 index 0000000000..2f4242841a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_door.json @@ -0,0 +1,48 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "bottom": "twilightforest:blocks/wood/door/twilight_oak_lower", + "top" : "twilightforest:blocks/wood/door/twilight_oak_upper" + } + }, + "variants": { + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "half" : { "lower": {}, "upper": {} }, + "hinge" : { "left": {}, "right": {} }, + "open" : { "true": {}, "false": {} }, + + "facing=east,half=lower,hinge=left,open=false" : { "model": "door_bottom" }, + "facing=south,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 90 }, + "facing=west,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 180 }, + "facing=north,half=lower,hinge=left,open=false" : { "model": "door_bottom" , "y": 270 }, + "facing=east,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh" }, + "facing=south,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 90 }, + "facing=west,half=lower,hinge=right,open=false" : { "model": "door_bottom_rh", "y": 180 }, + "facing=north,half=lower,hinge=right,open=false": { "model": "door_bottom_rh", "y": 270 }, + "facing=east,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 90 }, + "facing=south,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 180 }, + "facing=west,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh", "y": 270 }, + "facing=north,half=lower,hinge=left,open=true" : { "model": "door_bottom_rh" }, + "facing=east,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 270 }, + "facing=south,half=lower,hinge=right,open=true" : { "model": "door_bottom" }, + "facing=west,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 90 }, + "facing=north,half=lower,hinge=right,open=true" : { "model": "door_bottom" , "y": 180 }, + "facing=east,half=upper,hinge=left,open=false" : { "model": "door_top" }, + "facing=south,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 90 }, + "facing=west,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 180 }, + "facing=north,half=upper,hinge=left,open=false" : { "model": "door_top" , "y": 270 }, + "facing=east,half=upper,hinge=right,open=false" : { "model": "door_top_rh" }, + "facing=south,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 90 }, + "facing=west,half=upper,hinge=right,open=false" : { "model": "door_top_rh" , "y": 180 }, + "facing=north,half=upper,hinge=right,open=false": { "model": "door_top_rh" , "y": 270 }, + "facing=east,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 90 }, + "facing=south,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 180 }, + "facing=west,half=upper,hinge=left,open=true" : { "model": "door_top_rh" , "y": 270 }, + "facing=north,half=upper,hinge=left,open=true" : { "model": "door_top_rh" }, + "facing=east,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 270 }, + "facing=south,half=upper,hinge=right,open=true" : { "model": "door_top" }, + "facing=west,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 90 }, + "facing=north,half=upper,hinge=right,open=true" : { "model": "door_top" , "y": 180 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_doubleslab.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_doubleslab.json new file mode 100644 index 0000000000..cebc0a96ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_doubleslab.json @@ -0,0 +1,29 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all" + }, + "variants": { + "normal": [{ + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_twilight_oak_0" + } + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_twilight_oak_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_twilight_oak_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_twilight_oak_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_fence.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_fence.json new file mode 100644 index 0000000000..743c167610 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_fence.json @@ -0,0 +1,111 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_inventory", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }}], + + "east=false,north=false,south=false,west=false": [ + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "fence_post" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "fence_post" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + + "east=false,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "east=true,north=false,south=false,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "east=false,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "east=false,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_single" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + + "east=false,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "east=true,north=true,south=false,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "east=true,north=false,south=true,west=false" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "east=false,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_elbow" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + + "east=false,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "east=true,north=false,south=false,west=true" : [ + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_straight", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + + "east=false,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "east=true,north=true,south=false,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "east=true,north=true,south=true,west=false" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "east=true,north=false,south=true,west=true" : [ + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "twilightforest:util/fence_t" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + + "east=true,north=true,south=true,west=true" : [ + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "twilightforest:util/fence_all" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "twilightforest:util/fence_all" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_gate.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_gate.json new file mode 100644 index 0000000000..7d22e01423 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_gate.json @@ -0,0 +1,105 @@ +{ + "forge_marker": 1, + "defaults": { + "uvlock": true + }, + "variants": { + "inventory": [{ "model": "fence_gate_closed", "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }}], + "facing=south,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=west,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=false": [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=false" : [ + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "fence_gate_closed", "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=south,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=west,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=north,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=east,in_wall=false,open=true" : [ + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "fence_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=west,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=false" : [ + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "wall_gate_closed" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=south,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=west,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=north,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=east,in_wall=true,open=true" : [ + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 10, "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "wall_gate_open" , "weight": 1 , "textures": { "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_planks.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_planks.json new file mode 100644 index 0000000000..b0fa452d1e --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_planks.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wood/planks_twilight_oak_0" } + }, + "variants": { + "inventory": [{}], + "normal": [{ + "weight": 10 + }, { + "weight": 10, + "textures": { + "all": "twilightforest:blocks/wood/planks_twilight_oak_1" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_twilight_oak_2" + } + }, { + "weight": 1, + "textures": { + "all": "twilightforest:blocks/wood/planks_twilight_oak_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_plate.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_plate.json new file mode 100644 index 0000000000..44a13a1bf5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_plate.json @@ -0,0 +1,59 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "pressure_plate_up" + }, + "variants": { + "inventory": [{ + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" + } + }], + "powered=false": [{ + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" + } + }, { + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" + } + }, { + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" + } + }], + "powered=true": [{ + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_0" + } + }, { + "model": "pressure_plate_down", + "weight": 10, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_1" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_2" + } + }, { + "model": "pressure_plate_down", + "weight": 1, + "textures": { + "texture": "twilightforest:blocks/wood/planks_twilight_oak_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_slab.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_slab.json new file mode 100644 index 0000000000..02666594a9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_slab.json @@ -0,0 +1,77 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "half_slab" + }, + "variants": { + "inventory": [{ + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_0", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_0" + } + }], + "half=bottom": [{ + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_0", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_0" + } + }, { + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_1", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_1" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_2", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_2" + } + }, { + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_3", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_3" + } + }], + "half=top": [{ + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_0", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_0" + } + }, { + "model": "upper_slab", + "weight": 10, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_1", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_1" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_2", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_2" + } + }, { + "model": "upper_slab", + "weight": 1, + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_3", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_3" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_stairs.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_stairs.json new file mode 100644 index 0000000000..be5e2bf7bf --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_stairs.json @@ -0,0 +1,256 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:stairs", + "textures": { + "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", + "top" : "twilightforest:blocks/wood/planks_twilight_oak_0", + "side" : "twilightforest:blocks/wood/planks_twilight_oak_0", + "particle": "#side" + }, + "uvlock": true + }, + "variants": { + "inventory": [{}], + "facing=east,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=west,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=west,half=bottom,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=outer_right": [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=north,half=bottom,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=east,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=west,half=bottom,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=south,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=north,half=bottom,shape=inner_right": [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=east,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 270 } + ], + "facing=west,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 90 } + ], + "facing=south,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" } }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" } }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" } } + ], + "facing=north,half=bottom,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "y": 180 } + ], + "facing=east,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180 } + ], + "facing=west,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 180 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 90 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=straight" : [ + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 270 }, + { "model": "stairs" , "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=outer_right" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180 } + ], + "facing=east,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180 } + ], + "facing=west,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 180 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 90 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=outer_left" : [ + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 270 }, + { "model": "outer_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 270 } + ], + "facing=east,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 90 } + ], + "facing=west,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 270 } + ], + "facing=south,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 180 } + ], + "facing=north,half=top,shape=inner_right" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180 } + ], + "facing=east,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180 } + ], + "facing=west,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 180 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 180 } + ], + "facing=south,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 90 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 90 } + ], + "facing=north,half=top,shape=inner_left" : [ + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_0", "top": "twilightforest:blocks/wood/planks_twilight_oak_0", "side": "twilightforest:blocks/wood/planks_twilight_oak_0" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 10, "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_1", "top": "twilightforest:blocks/wood/planks_twilight_oak_1", "side": "twilightforest:blocks/wood/planks_twilight_oak_1" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_2", "top": "twilightforest:blocks/wood/planks_twilight_oak_2", "side": "twilightforest:blocks/wood/planks_twilight_oak_2" }, "x": 180, "y": 270 }, + { "model": "inner_stairs", "weight": 1 , "textures": { "bottom": "twilightforest:blocks/wood/planks_twilight_oak_3", "top": "twilightforest:blocks/wood/planks_twilight_oak_3", "side": "twilightforest:blocks/wood/planks_twilight_oak_3" }, "x": 180, "y": 270 } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_oak_trapdoor.json b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_trapdoor.json new file mode 100644 index 0000000000..1b79684cfc --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_oak_trapdoor.json @@ -0,0 +1,35 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "texture": "twilightforest:blocks/wood/trapdoor/twilight_oak_trapdoor" + } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/trapdoor_bottom", "y": 180 }], + + "facing": { "north": {}, "east": {}, "south": {}, "west": {} }, + "open" : { "true": {}, "false": {} }, + "half" : { "bottom": {}, "top": {} }, + + "facing=south,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom" }, + "facing=west,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 90 }, + "facing=north,half=bottom,open=false": { "model": "twilightforest:util/trapdoor_bottom", "y": 180 }, + "facing=east,half=bottom,open=false" : { "model": "twilightforest:util/trapdoor_bottom", "y": 270 }, + + "facing=south,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" }, + "facing=west,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 90 }, + "facing=north,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 180 }, + "facing=east,half=top,open=false" : { "model": "twilightforest:util/trapdoor_top" , "y": 270 }, + + "facing=north,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 } } }, + "facing=east,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 90 } } }, + "facing=south,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "z": 180 }, "rotation": { "y": 180 } } }, + "facing=west,half=bottom,open=true" : { "model": "trapdoor_open" , "transform": { "post-rotation": { "x": 180 }, "rotation": { "y": 270 } } }, + + "facing=north,half=top,open=true" : { "model": "trapdoor_open" }, + "facing=east,half=top,open=true" : { "model": "trapdoor_open" , "y": 90 }, + "facing=south,half=top,open=true" : { "model": "trapdoor_open" , "y": 180 }, + "facing=west,half=top,open=true" : { "model": "trapdoor_open" , "y": 270 } + } +} diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_plant.json b/src/main/resources/assets/twilightforest/blockstates/twilight_plant.json new file mode 100644 index 0000000000..6c7b31e11c --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_plant.json @@ -0,0 +1,71 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cross", + "transform": "forge:default-item" + }, + "variants": { + "inventory_mosspatch": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/patch/moss" }}], + "inventory_mayapple": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/mayapple" }}], + "inventory_cloverpatch": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/patch/clover" }}], + "inventory_fiddlehead": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/fiddlehead" }}], + "inventory_mushgloom": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/mushgloom", "layer1": "twilightforest:blocks/mushgloom_head" }}], + "inventory_forestgrass": [{ "model": "builtin/generated", "textures": { "layer0": "minecraft:blocks/tallgrass" }}], + "inventory_deadbush": [{ "model": "builtin/generated", "textures": { "layer0": "minecraft:blocks/deadbush" }}], + "inventory_torchberry": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/torchberry", "layer1": "twilightforest:blocks/torchberry_glow" }}], + "inventory_root_strand": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/rootstrand" }}], + "inventory_fallen_leaves": [{ "model": "builtin/generated", "textures": { "layer0": "blocks/leaves_spruce" }}], + "variant=mosspatch": [ + { "model": "twilightforest:mosspatch" } + ], + "variant=mayapple": [{ "model": "twilightforest:mayapple" }], + "variant=cloverpatch": [{ + "model": "twilightforest:util/flat_tex", "textures": { + "particle": "twilightforest:blocks/cloverpatch", + "texture": "twilightforest:blocks/patch/clover_0", + "ctm": "twilightforest:blocks/patch/clover_0_ctm" + }}, { + "model": "twilightforest:util/flat_tex", "textures": { + "particle": "twilightforest:blocks/cloverpatch", + "texture": "twilightforest:blocks/patch/clover_1", + "ctm": "twilightforest:blocks/patch/clover_1_ctm" + }}, { + "model": "twilightforest:util/flat_tex", "textures": { + "particle": "twilightforest:blocks/cloverpatch", + "texture": "twilightforest:blocks/patch/clover_2", + "ctm": "twilightforest:blocks/patch/clover_2_ctm" + }}, { + "model": "twilightforest:util/flat_tex", "textures": { + "particle": "twilightforest:blocks/cloverpatch", + "texture": "twilightforest:blocks/patch/clover_3", + "ctm": "twilightforest:blocks/patch/clover_3_ctm" + }} + ], + "variant=fiddlehead": [{ + "model": "tinted_cross", + "textures": { "cross":"twilightforest:blocks/fiddlehead" } + }], + "variant=mushgloom": [{ + "model": "twilightforest:util/cross_2_layer", + "textures": { "cross":"twilightforest:blocks/mushgloom", "cross2":"twilightforest:blocks/mushgloom_head" }, + "uvlock": true + }], + "variant=forestgrass": [{ "model": "tall_grass" }], + "variant=deadbush": [{ "model": "dead_bush" }], + "variant=torchberry": [{ + "model": "twilightforest:util/cross_2_layer", + "textures": { "cross":"twilightforest:blocks/torchberry", "cross2":"twilightforest:blocks/torchberry_glow" }, + "uvlock": true + }], + "variant=root_strand": [{ + "model": "crop", + "textures": { "crop":"twilightforest:blocks/rootstrand" }, + "transform": { + "translation": [ 0, 0.0625, 0 ] + } + }], + "variant=fallen_leaves": [ + { "model": "twilightforest:fallenleaves" } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_portal.json b/src/main/resources/assets/twilightforest/blockstates/twilight_portal.json new file mode 100644 index 0000000000..506689622a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_portal.json @@ -0,0 +1,28 @@ +{ + "forge_marker": 1, + "defaults": { "model": "twilightforest:portal" }, + "variants": { + "inventory": [{ "model": "twilightforest:miniature/portal" }], + "is_one_way": { + "true": { + "submodel": { + "barrier": { + "model": "twilightforest:util/flat", + "textures": { "texture": "twilightforest:blocks/portal_barrier" }, + "transform": { + "translation": [0, 0.84375, 0] + } + }, + "barrier2": { + "model": "twilightforest:util/flat", + "textures": { "texture": "twilightforest:blocks/portal_barrier" }, + "transform": { + "translation": [0, 0.71875, 0] + } + } + } + }, + "false": {} + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/twilight_sapling.json b/src/main/resources/assets/twilightforest/blockstates/twilight_sapling.json new file mode 100644 index 0000000000..bc559cee91 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/twilight_sapling.json @@ -0,0 +1,31 @@ +{ + "forge_marker": 1, + "defaults": { + "transform": "forge:default-item", + "model": "minecraft:cross" + }, + "variants": { + "inventory_oak": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_oak" }}], + "inventory_canopy": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_canopy" }}], + "inventory_mangrove": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_mangrove" }}], + "inventory_darkwood": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_darkwood" }}], + "inventory_hollow_oak": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_hollow_oak" }}], + "inventory_time": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_time" }}], + "inventory_transformation": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_transformation" }}], + "inventory_mining": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_mining" }}], + "inventory_sorting": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_sorting" }}], + "inventory_rainbow": [{ "model": "builtin/generated", "textures": { "layer0": "twilightforest:blocks/sapling_rainboak" }}], + "tf_type":{ + "canopy": { "textures": { "cross": "twilightforest:blocks/sapling_canopy" } }, + "mangrove": { "textures": { "cross": "twilightforest:blocks/sapling_mangrove" } }, + "darkwood": { "textures": { "cross": "twilightforest:blocks/sapling_darkwood" } }, + "hollow_oak": { "textures": { "cross": "twilightforest:blocks/sapling_hollow_oak" } }, + "time": { "textures": { "cross": "twilightforest:blocks/sapling_time" } }, + "transformation": { "textures": { "cross": "twilightforest:blocks/sapling_transformation" } }, + "mining": { "textures": { "cross": "twilightforest:blocks/sapling_mining" } }, + "sorting": { "textures": { "cross": "twilightforest:blocks/sapling_sorting" } }, + "rainbow": { "textures": { "cross": "twilightforest:blocks/sapling_rainboak" } }, + "oak": { "textures": { "cross": "twilightforest:blocks/sapling_oak" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/uberous_soil.json b/src/main/resources/assets/twilightforest/blockstates/uberous_soil.json new file mode 100644 index 0000000000..04b1e95abf --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/uberous_soil.json @@ -0,0 +1,11 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "twilightforest:util/cube_all_2_layer", + "textures": { + "all": "twilightforest:blocks/uberous_soil", + "all2": "twilightforest:blocks/uberous_soil_glow" + } + }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/uncrafting_table.json b/src/main/resources/assets/twilightforest/blockstates/uncrafting_table.json new file mode 100644 index 0000000000..4b144bfdb6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/uncrafting_table.json @@ -0,0 +1,22 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_bottom_top", + "textures": { + "particle": "twilightforest:blocks/uncrafting_particle", + "top": "twilightforest:blocks/uncrafting_particle", + "side": "twilightforest:blocks/uncrafting_side", + "bottom": "blocks/planks_jungle" + } + }, + "variants": { + "normal": [{}], + "ctm": [{ + "model": "twilightforest:util/cube_bottom_double_top", + "textures": { + "top": "twilightforest:blocks/uncrafting_top", + "glow": "twilightforest:blocks/uncrafting_glow" + } + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/underbrick.json b/src/main/resources/assets/twilightforest/blockstates/underbrick.json new file mode 100644 index 0000000000..70d2ceac61 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/underbrick.json @@ -0,0 +1,12 @@ +{ + "forge_marker": 1, + "defaults": { "model": "cube_all" }, + "variants": { + "variant": { + "normal": { "textures": { "all": "twilightforest:blocks/knightbrick" } }, + "mossy": { "textures": { "all": "twilightforest:blocks/knightbrick_mossy" } }, + "cracked": { "textures": { "all": "twilightforest:blocks/knightbrick_cracked" } }, + "floor": { "textures": { "all": "twilightforest:blocks/knightbrick_floor" } } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/unripe_trollber.json b/src/main/resources/assets/twilightforest/blockstates/unripe_trollber.json new file mode 100644 index 0000000000..3823909310 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/unripe_trollber.json @@ -0,0 +1,11 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cross", + "textures": { "cross": "twilightforest:blocks/unripe_torch_cluster" } + }, + "variants": { + "inventory": [{ "model": "twilightforest:util/item", "textures": { "layer0": "twilightforest:blocks/unripe_torch_cluster"}}], + "normal": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/wispy_cloud.json b/src/main/resources/assets/twilightforest/blockstates/wispy_cloud.json new file mode 100644 index 0000000000..4e73999616 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/wispy_cloud.json @@ -0,0 +1,8 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "cube_all", + "textures": { "all": "twilightforest:blocks/wispy_cloud" } + }, + "variants": { "normal": [{}] } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/x_spiral_bricks.json b/src/main/resources/assets/twilightforest/blockstates/x_spiral_bricks.json new file mode 100644 index 0000000000..b141fe1788 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/x_spiral_bricks.json @@ -0,0 +1,41 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "shadow_y": "twilightforest:blocks/spiral_shadow_x", + "shadow_z": "twilightforest:blocks/spiral_shadow_x", + "inner_a": "twilightforest:blocks/spiral_inner_down", + "inner_b": "twilightforest:blocks/spiral_inner_up" + }, + "uvlock": true + }, + "variants": { + "diagonal": { + "bottom_left": { + "textures": { + "inner_a": "twilightforest:blocks/spiral_inner_up" + }, + "model": "twilightforest:spiral_bottom_right", + "submodel": { "otherside": { "model": "twilightforest:spiral_bottom_left", "uvlock": true, "y": 180, "x": 90 } }, + "x": 270 + }, + "bottom_right": { + "model": "twilightforest:spiral_bottom_left", + "submodel": { "otherside": { "model": "twilightforest:spiral_bottom_right", "uvlock": true, "y": 180, "x": 90 } }, + "x": 180 + }, + "top_left": { + "textures": { + "inner_b": "twilightforest:blocks/spiral_inner_down" + }, + "model": "twilightforest:spiral_top_right", + "submodel": { "otherside": { "model": "twilightforest:spiral_top_left", "uvlock": true, "y": 180, "x": 90 } } + }, + "top_right": { + "model": "twilightforest:spiral_top_left", + "submodel": { "otherside": { "model": "twilightforest:spiral_top_right", "uvlock": true, "y": 180, "x": 90 } }, + "x": 90 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/y_spiral_bricks.json b/src/main/resources/assets/twilightforest/blockstates/y_spiral_bricks.json new file mode 100644 index 0000000000..b064803f3a --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/y_spiral_bricks.json @@ -0,0 +1,55 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "shadow_y": "twilightforest:blocks/spiral_shadow_z", + "shadow_z": "twilightforest:blocks/spiral_shadow_z", + "inner_a": "twilightforest:blocks/spiral_inner_right", + "inner_b": "twilightforest:blocks/spiral_inner_left" + }, + "uvlock": true + }, + "variants": { + "diagonal": { + "bottom_left": { + "model": "twilightforest:spiral_bottom_right", + "submodel": { "otherside": { "model": "twilightforest:spiral_bottom_left", "uvlock": true, "y": 180, "x": 90 } }, + "transform": { + "rotation": { "z": 90 } + }, + "textures": { + "inner_a": "twilightforest:blocks/spiral_inner_left", + "inner_b": "twilightforest:blocks/spiral_inner_right" + } + }, + "bottom_right": { + "model": "twilightforest:spiral_bottom_left", + "submodel": { "otherside": { "model": "twilightforest:spiral_bottom_right", "uvlock": true, "y": 180, "x": 90 } }, + "transform": { + "rotation": { "z": 90 }, + "post-rotation": { "x": 90 } + } + }, + "top_left": { + "model": "twilightforest:spiral_top_right", + "submodel": { "otherside": { "model": "twilightforest:spiral_top_left", "uvlock": true, "y": 180, "x": 90 } }, + "transform": { + "rotation": { "z": 90 }, + "post-rotation": { "x": 270 } + }, + "textures": { + "inner_a": "twilightforest:blocks/spiral_inner_left", + "inner_b": "twilightforest:blocks/spiral_inner_right" + } + }, + "top_right": { + "model": "twilightforest:spiral_top_left", + "submodel": { "otherside": { "model": "twilightforest:spiral_top_right", "uvlock": true, "y": 180, "x": 90 } }, + "transform": { + "rotation": { "z": 90 }, + "post-rotation": { "x": 180 } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/blockstates/z_spiral_bricks.json b/src/main/resources/assets/twilightforest/blockstates/z_spiral_bricks.json new file mode 100644 index 0000000000..28e41fa141 --- /dev/null +++ b/src/main/resources/assets/twilightforest/blockstates/z_spiral_bricks.json @@ -0,0 +1,51 @@ +{ + "forge_marker": 1, + "defaults": { + "textures": { + "shadow_y": "twilightforest:blocks/spiral_shadow_z", + "shadow_z": "twilightforest:blocks/spiral_shadow_x", + "inner_a": "twilightforest:blocks/spiral_inner_down", + "inner_b": "twilightforest:blocks/spiral_inner_up" + }, + "uvlock": true + }, + "variants": { + "diagonal": { + "bottom_left": { + "textures": { + "inner_a": "twilightforest:blocks/spiral_inner_right" + }, + "model": "twilightforest:spiral_bottom_right", + "submodel": { "otherside": { "model": "twilightforest:spiral_bottom_left", "uvlock": true, "y": 180, "x": 90 } }, + "x": 270, + "y": 90 + }, + "bottom_right": { + "textures": { + "inner_a": "twilightforest:blocks/spiral_inner_left" + }, + "model": "twilightforest:spiral_bottom_left", + "submodel": { "otherside": { "model": "twilightforest:spiral_bottom_right", "uvlock": true, "y": 180, "x": 90 } }, + "x": 180, + "y": 90 + }, + "top_left": { + "textures": { + "inner_b": "twilightforest:blocks/spiral_inner_right" + }, + "model": "twilightforest:spiral_top_right", + "submodel": { "otherside": { "model": "twilightforest:spiral_top_left", "uvlock": true, "y": 180, "x": 90 } }, + "y": 90 + }, + "top_right": { + "textures": { + "inner_b": "twilightforest:blocks/spiral_inner_left" + }, + "model": "twilightforest:spiral_top_left", + "submodel": { "otherside": { "model": "twilightforest:spiral_top_right", "uvlock": true, "y": 180, "x": 90 } }, + "x": 90, + "y": 90 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/functions/give_3_shields.mcfunction b/src/main/resources/assets/twilightforest/functions/give_3_shields.mcfunction new file mode 100644 index 0000000000..d83b134649 --- /dev/null +++ b/src/main/resources/assets/twilightforest/functions/give_3_shields.mcfunction @@ -0,0 +1 @@ +twilightforest shield @p 3 add false \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/functions/new_world.mcfunction b/src/main/resources/assets/twilightforest/functions/new_world.mcfunction new file mode 100644 index 0000000000..0eb0f141c0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/functions/new_world.mcfunction @@ -0,0 +1,10 @@ +gamerule announceAdvancements false +gamerule doDaylightCycle false +gamerule doEntityDrops false +gamerule doMobLoot false +gamerule doMobSpawning false +gamerule doTileDrops false +gamerule doWeatherCycle false +gamerule keepInventory true +gamerule randomTickSpeed -1 +gamerule tfEnforcedProgression false \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/de_DE.lang b/src/main/resources/assets/twilightforest/lang/de_DE.lang deleted file mode 100644 index ac4044b72a..0000000000 --- a/src/main/resources/assets/twilightforest/lang/de_DE.lang +++ /dev/null @@ -1,410 +0,0 @@ -tile.TFLog.0.name=Twilight Eichenholz -tile.TFLog.1.name=Baldachin Baum-Holz -tile.TFLog.2.name=Mangroven Holz -tile.TFLog.3.name=Dunkelholz -tile.TFLeaves.0.name=Twilight Eichenlaub -tile.TFLeaves.1.name=Baldachin Bltter -tile.TFLeaves.2.name=Mangroven Bltter -tile.TFLeaves.3.name=Regenbogen Eichenlaub -tile.TFFirefly.name=Leuchtkfer -tile.TFCicada.name=Grille -tile.TFPortal.name=Twilight Wald Portal -tile.TFMazestone.0.name=Labyrinthstein -tile.TFMazestone.1.name=Labyrinthstein Ziegel -tile.TFMazestone.2.name=gemeielter Labyrinthstein -tile.TFMazestone.3.name=dekorativer Labyrinthstein Ziegel -tile.TFMazestone.4.name=rissiger Labyrinthstein Ziegel -tile.TFMazestone.5.name=mossiger Labyrinthstein Ziegel -tile.TFMazestone.6.name=Labyrinthstein Mosaik -tile.TFMazestone.7.name=Labyrinthstein Rahmen -tile.TFMazestone.8.name=Labyrinthstein Decke -tile.TFHedge.0.name=Absicherung -tile.TFHedge.1.name=Dunkelholz Bltter -tile.TFHedge.2.name=Absicherung -tile.TFBossSpawner.0.name=Naga Spawner -tile.TFBossSpawner.1.name=Lich Spawner -tile.TFBossSpawner.2.name=Hydra Spawner -tile.TFBossSpawner.3.name=Ur-Ghast Spawner -tile.TFBossSpawner.4.name=Phantom Ritter Spawner -tile.TFFireflyJar.name=Leuchtkfer Glas -tile.TFPlant.3.name=Moosflecken -tile.TFPlant.4.name=Mayapfel -tile.TFPlant.5.name=Kleeflecken [WIP] -tile.TFPlant.8.name=Farnwedel -tile.TFPlant.9.name=Dsterpilz -tile.TFPlant.10.name=Waldgrass -tile.TFPlant.11.name=getrockneter Strauch -tile.TFPlant.13.name=Leutbeeren Pflanze -tile.TFPlant.14.name=Wurzel Adern -tile.TFRoots.0.name=Wurzeln -tile.TFRoots.1.name=Lebenswurzel -tile.TFUncraftingTable.name=Uncrafting Table -tile.TFFireJet.0.name=Rauch-Block -tile.TFFireJet.1.name=Eingehllter Raucher -tile.TFFireJet.2.name=Eingehllter Raucher -tile.TFFireJet.8.name=Feuer Jet -tile.TFFireJet.9.name=knallender Feuer Jet -tile.TFFireJet.10.name=brennender Feuer Jet -tile.TFFireJet.11.name=Eingehllter Feuer Jet -tile.TFFireJet.12.name=Eingehllter knallender Feuer Jet -tile.TFFireJet.13.name=Eingehllter brennender Feuer Jet -tile.TFNagastone.0.name=Nagastein Kopf -tile.TFNagastone.1.name=Nagastein Kopf -tile.TFNagastone.2.name=Nagastein Kopf -tile.TFNagastone.3.name=Nagastein Kopf -tile.TFNagastone.4.name=Nagastein -tile.TFNagastone.5.name=Nagastein -tile.TFNagastone.6.name=Nagastein -tile.TFNagastone.7.name=Nagastein -tile.TFNagastone.8.name=Nagastein -tile.TFNagastone.9.name=Nagastein -tile.TFNagastone.10.name=Nagastein -tile.TFNagastone.11.name=Nagastein -tile.TFNagastone.12.name=Nagastein -tile.TFNagastone.13.name=Nagastein -tile.TFNagastone.14.name=Nagastein -tile.TFNagastone.15.name=Nagastein -tile.TFSapling.0.name=krnklicher Twilight Eichensetzling -tile.TFSapling.1.name=Baldachin Baumsetzling -tile.TFSapling.2.name=Twilight Mangrove Setzling -tile.TFSapling.3.name=Dunkelholz Setzling -tile.TFSapling.4.name=robuster Twilight Eichensetzling -tile.TFSapling.5.name=Baum der Zeit Setzling -tile.TFSapling.6.name=Baum der Verwandlung Setzling -tile.TFSapling.7.name=Berg-Baum Setzling -tile.TFSapling.8.name=sortierter Baum Setzling -tile.TFSapling.9.name=Regenbogen Eichen Setzling -tile.TFMoonworm.name=Mondwurm -tile.TFMagicLog.0.name=Zeitholz -tile.TFMagicLog.1.name=Wandelholz -tile.TFMagicLog.2.name=Bergholz -tile.TFMagicLog.3.name=Sorting-Holz -tile.TFMagicLogSpecial.0.name=Zeitholz Uhr -tile.TFMagicLogSpecial.1.name=Herz der Verwandlung -tile.TFMagicLogSpecial.2.name=Bergholz Kern -tile.TFMagicLogSpecial.3.name=Sorting-Holz Motor -tile.TFMagicLeaves.0.name=Zeitholz Bltter -tile.TFMagicLeaves.1.name=Bltter der Verwandlung -tile.TFMagicLeaves.2.name=Bergholz Bltter -tile.TFMagicLeaves.3.name=Sorting-Holz Bltter -tile.TFTowerStone.0.name=Turmholz Bretter -tile.TFTowerStone.1.name=eingehlltes Turmholz -tile.TFTowerStone.2.name=rissiges Turmholz -tile.TFTowerStone.3.name=mossiges Turmholz -tile.TFTowerStone.4.name=verseuchtes Turmholz -tile.TFTowerDevice.0.name=Wiedererscheinender Block -tile.TFTowerDevice.1.name=aktiver Wiedererscheinender Block -tile.TFTowerDevice.2.name=verschwindender Block -tile.TFTowerDevice.3.name=aktiver verschwindender Block -tile.TFTowerDevice.4.name=verriegelter verschwindender Block -tile.TFTowerDevice.5.name=offener verschwindender Block -tile.TFTowerDevice.6.name=Turmbauer -tile.TFTowerDevice.7.name=aktiver Turmbauer -tile.TFTowerDevice.8.name=inaktiver Turmbauer -tile.TFTowerDevice.9.name=Zerstrer -tile.TFTowerDevice.10.name=Ghast Falle -tile.TFTowerDevice.11.name=aktive Ghast Falle -tile.TFTowerDevice.12.name=Karminit Reaktor -tile.TFTowerDevice.13.name=aktiver Karminit Reaktor -tile.TFTowerTranslucent.0.name=wiedererscheinender Block -tile.TFTowerTranslucent.1.name=aktiver Wiedererscheinender Block -tile.TFTowerTranslucent.2.name=Turm-Block-Erbauer -tile.TFTowerTranslucent.3.name=aktiver Turm-Block-Erbauer -tile.TFTowerTranslucent.4.name=Zerstrer-Block -tile.TFTowerTranslucent.5.name=Karminit Reaktor Schutt -tile.TFTowerTranslucent.6.name=falsches Gold -tile.TFTowerTranslucent.7.name=falsche Diamanten -tile.TFTrophy.name=Twilight Forest Trophen -tile.TFShield.0.name=Hochburg Schild -tile.TFShield.1.name=Hochburg Schild -tile.TFShield.2.name=Hochburg Schild -tile.TFShield.3.name=Hochburg Schild -tile.TFShield.4.name=Hochburg Schild -tile.TFShield.5.name=Hochburg Schild -tile.TFShield.15.name=Hochburg Schild -tile.TFTrophyPedestal.0.name=Trophen Sulen -tile.TFTrophyPedestal.15.name=ungenutzte Trophen Sulen -tile.TFAuroraBrick.name=Aurora Block -tile.TFUnderBrick.0.name=Underbrick -tile.TFUnderBrick.1.name=mossiger Underbrick -tile.TFUnderBrick.2.name=rissiger Underbrick -tile.TFThorns.brown.name=Dornen -tile.TFThorns.green.name=grne Dornen -tile.TFBurntThorns.name=verbrannte Dornen -tile.TFThornRose.name=Dornenrose -tile.TFLeaves3.0.name=Dornenbltter -tile.TFLeaves3.1.name=Bohnenranken Bltter -tile.TFDeadrock.surface.name=verwittertes taubes Gestein -tile.TFDeadrock.cracked.name=rissiges taubes Gestein -tile.TFDeadrock.solid.name=taubes Gestein -tile.DarkLeaves.name=Dunklholz Bltter -tile.AuroraPillar.name=Aurora Sule -tile.AuroraSlab.name=Aurora Stufe -tile.TrollSteinn.name=Trollstein -tile.WispyCloud.name=Rauchige Wolke -tile.FluffyCloud.name=flaumige Wolke -tile.GiantCobble.name=Giant Pflasterstein -tile.GiantLog.name=Giant Holz -tile.GiantLeaves.name=Giant Bltter -tile.GiantObsidian.name=Giant Obsidian -tile.UberousSoil.name=Uberous Substrat -tile.HugeStalk.name=riesiger Stengel -tile.HugeGloomBlock.name=riesiger Dsterpilz -tile.TrollVidr.name=Trollvidr -tile.UnripeTrollBer.name=unreife Trollbeere -tile.TrollBer.name=Trollbeere - -item.nagaScale.name=Naga Schuppen -item.plateNaga.name=Naga Schuppen Tunika -item.legsNaga.name=Naga Schuppen Hose -item.scepterTwilight.name=Zepter des Zwielichts -item.scepterLifeDrain.name=Zepter des Lebensaugers -item.scepterZombie.name=Zombie Zepter -item.oreMeter.name=Erz Messgert [WIP] -item.magicMap.name=magische Karte -item.mazeMap.name=Labyrinth Karte -item.oreMap.name=Labyrinth/Erz Map -item.tfFeather.name=Rabenfeder -item.magicMapFocus.name=magischer Kartenfokus -item.mazeMapFocus.name=Labyrinth Kartenfokus -item.liveRoot.name=Lebenswurzel -item.ironwoodRaw.name=Rohe Eisenholz Materialien -item.ironwoodIngot.name=Eisenholz Barren -item.ironwoodHelm.name=Eisenholz Helm -item.ironwoodPlate.name=Eisenholz Rstung -item.ironwoodLegs.name=Eisenholz Hosen -item.ironwoodBoots.name=Eisenholz Stiefel -item.ironwoodSword.name=Eisenholz Schwert -item.ironwoodShovel.name=Eisenholz Schaufel -item.ironwoodPick.name=Eisenholz Spitzhacke -item.ironwoodAxe.name=Eisenholz Axt -item.ironwoodHoe.name=Eisenholz Sense -item.torchberries.name=Fackelbeeren -item.venisonRaw.name=roher Hirsch -item.venisonCooked.name=Hirsch Steak -item.hydraChop.name=Hydra Leib -item.fieryBlood.name=feuriges Blut -item.fieryIngot.name=feuriger Barren -item.fieryHelm.name=feuriger Helm -item.fieryPlate.name=feurige Rstung -item.fieryLegs.name=feurige Hosen -item.fieryBoots.name=feurige Stiefel -item.fierySword.name=feuriges Schwert -item.fieryPick.name=feurige Spitzhacke -item.steeleafIngot.name=Stahlblatt -item.steeleafHelm.name=Stahlblatt Helm -item.steeleafPlate.name=Stahlblatt Rstung -item.steeleafLegs.name=Stahlblatt Hosen -item.steeleafBoots.name=Stahlblatt Stiefel -item.steeleafSword.name=Stahlblatt Schwert -item.steeleafShovel.name=Stahlblatt Schaufel -item.steeleafPick.name=Stahlblatt Spitzhacke -item.steeleafAxe.name=Stahlblatt Axt -item.steeleafHoe.name=Stahlblatt Sense -item.minotaurAxe.name=Minotaurus Axt -item.mazebreakerPick.name=Labyrinth Brecher -item.transformPowder.name=Verwandlungs Pulver -item.meefRaw.name=rohes Meef -item.meefSteak.name=Meef Steak -item.meefStroganoff.name=Meef Stroganoff -item.mazeWafer.name=Maze Wafer -item.emptyMagicMap.name=leere magische Karte -item.emptyMazeMap.name=leere Labyrinth-Karte -item.emptyOreMap.name=leere Labyrinth/Erz Karte -item.oreMagnet.name=Erzmagnet -item.crumbleHorn.name=brckelndes Horn -item.peacockFan.name=Pfauen-Feder Ventilator -item.moonwormQueen.name=Mondwurm Knigin -item.charmOfLife1.name=Reiz des Lebens I -item.charmOfLife2.name=Reiz des Lebens II -item.charmOfKeeping1.name=Reiz des Halten I -item.charmOfKeeping2.name=Reiz des Halten II -item.charmOfKeeping3.name=Reiz des Halten III -item.towerKey.name=Turmschlssel -item.borerEssence.name=Bohrer Essenz -item.carminite.name=Karminit Mineral -item.trophy.hydra.name=Hydra Trophe -item.trophy.naga.name=Naga Trophe -item.trophy.lich.name=Lich Trophe -item.trophy.ur-ghast.name=Ur-ghast Trophe -item.trophy.snowQueen.name=Schneeknigin Trophe -item.experiment115.name=Experiment 115 -item.armorShards.name=Rstungsscherbe -item.knightMetal.name=Ritter Metallbarren -item.shardCluster.name=Rstungsscherben Cluster -item.knightlyHelm.name=ritterlicher Helm -item.knightlyPlate.name=ritterliche Rstung -item.knightlyLegs.name=ritterlicher Schuhe -item.knightlyBoots.name=ritterliche Stiefel -item.knightlySword.name=ritterliches Schwert -item.knightlyPick.name=ritterliche Spitzhacke -item.knightlyAxe.name=ritterliche Axt -item.phantomHelm.name=Phantom Helm -item.phantomPlate.name=Phantom Rstung -item.lampOfCinders.name=Lampe der Asche -item.fieryTears.name=feurige Trnen -item.iceBomb.name=Eis Bombs -item.yetiHelm.name=gehrnter Yeti-Helm -item.yetiPlate.name=Yeti Jacke -item.yetiLegs.name=Yeti Hose -item.yetiBoots.name=Yeti Schtiefel -item.alphaFur.name=Alpha Yetifell -item.arcticFur.name=Arktischer Pelz -item.arcticHelm.name=Arktische Kapuze -item.arcticPlate.name=Arktische Jacke -item.arcticLegs.name=Arktische Hose -item.arcticBoots.name=Arktische Stiefel -item.magicBeans.name=Magische Bohne -item.giantPick.name=Giant's Spitzhacke -item.giantSword.name=Giant's Schwert -item.tripleBow.name=Dreierbogen -item.seekerBow.name=Sucherbogen -item.iceBow.name=Eisbogen -item.enderBow.name=Enderbogen -item.iceSword.name=Eisschwert -item.glassSword.name=Glasschwert - -item.minotaurAxe.tooltip=Extraschaden bei der Aufladung -item.knightlySword.tooltip=Extraschaden bei gepanzerten Zielen -item.knightlyPick.tooltip=Extraschaden bei gepanzerten Zielen -item.knightlyAxe.tooltip=Extraschaden bei ungepanzerten Zielen -item.giantPick.tooltip=zum Abbauen von Giganten Blcken -item.fieryPick.tooltip=Automatisches Schmelzen -item.fierySword.tooltip=Ziele in Brand setzen -item.fieryHelm.tooltip=Ziele in Brand setzen -item.fieryPlate.tooltip=Ziele in Brand setzen -item.fieryLegs.tooltip=Ziele in Brand setzen -item.fieryBoots.tooltip=Ziele in Brand setzen -item.yetiHelm.tooltip=Ziele verlangsamen -item.yetiPlate.tooltip=Ziele verlangsamen -item.yetiLegs.tooltip=Ziele verlangsamen -item.yetiBoots.tooltip=Ziele verlangsamen - -item.tfspawnegg.name=Spawn - -itemGroup.twilightForest=Twilight Forest - -entity.TwilightForest.Wild Boar.name=Wildschwein -entity.TwilightForest.Bighorn Sheep.name=Mufflonschaf -entity.TwilightForest.Wild Deer.name=wilder Hirsch -entity.TwilightForest.Redcap.name=Rotkppchen -entity.TwilightForest.Swarm Spider.name=Schwarmspinne -entity.TwilightForest.Naga.name=Naga -entity.TwilightForest.Naga Segment.name=Naga Abschnitt -entity.TwilightForest.Skeleton Druid.name=Skelett Druide -entity.TwilightForest.Hostile Wolf.name=feindseliger Wolf -entity.TwilightForest.Twilight Wraith.name=Twilight Gespenst -entity.TwilightForest.Hedge Spider.name=Heckenspinne -entity.TwilightForest.Hydra.name=Hydra -entity.TwilightForest.HydraHead.name=Hydra Kopf -entity.TwilightForest.Twilight Lich.name=Twilight Lich -entity.TwilightForest.Glacier.Penguin.name=Pinguin -entity.TwilightForest.Tiny Bird.name=winziger Vogel -entity.TwilightForest.Forest Squirrel.name=Wald Eichhrnchen -entity.TwilightForest.Forest Bunny.name=Wald-Hschen -entity.TwilightForest.Forest Raven.name=Wald Rabe -entity.TwilightForest.Questing Ram.name=suchender Widder -entity.TwilightForest.Twilight Kobold.name=Kobold -entity.TwilightForest.Boggard.name=Boggard [NYI] -entity.TwilightForest.Lich Minion.name=Lich Diener -entity.TwilightForest.Loyal Zombie.name=loyaler Zombie -entity.TwilightForest.Mosquito Swarm.name=Mckenschwarm -entity.TwilightForest.Death Tome.name=Todwlzer -entity.TwilightForest.Minotaur.name=Minotaurus -entity.TwilightForest.Minoshroom.name=Minotauruspilz -entity.TwilightForest.Fire Beetle.name=Feuerkfer -entity.TwilightForest.Slime Beetle.name=Schleimkfer -entity.TwilightForest.Pinch Beetle.name=Zangenkfer -entity.TwilightForest.Maze Slime.name=Labyrinth Slime -entity.TwilightForest.Redcap Sapper.name=Rotkppchen Sapper -entity.TwilightForest.Mist Wolf.name=Nebelwolf -entity.TwilightForest.King Spider.name=Spinnenknig -entity.TwilightForest.Firefly.name=Leuchtkfer -entity.TwilightForest.Mini Ghast.name=Stachliger Ghastling -entity.TwilightForest.Tower Ghast.name=Stachliger Ghastwchter -entity.TwilightForest.Tower Golem.name=Stachliger Golem -entity.TwilightForest.Tower Termite.name=Turmholzwurm -entity.TwilightForest.Redscale Broodling.name=Stachliger Brtling -entity.TwilightForest.Tower Boss.name=Ur-Ghast -entity.TwilightForest.Block&Chain Goblin.name=Block und Kette Goblin -entity.TwilightForest.Upper Goblin Knight.name=Goblin Oberritter -entity.TwilightForest.Lower Goblin Knight.name=Goblin Unterritter -entity.TwilightForest.Helmet Crab.name=Helmgrabbe -entity.TwilightForest.Knight Phantom.name=Phantomritter -entity.TwilightForest.Yeti.name=Yeti -entity.TwilightForest.Yeti Boss.name=Alpha-Yeti -entity.TwilightForest.WinterWolf.name=Winter Wolf -entity.TwilightForest.SnowGuardian.name=Schneewchter -entity.TwilightForest.Stable Ice Core.name=Stabiler Eiskern -entity.TwilightForest.Unstable Ice Core.name=Instabiler Eiskern -entity.TwilightForest.Snow Queen.name=Schneeknigin -entity.TwilightForest.Troll.name=Hhlentroll -entity.TwilightForest.Giant Miner.name=Bergriese -entity.TwilightForest.Armored Giant.name=Gepanzerter Riesen -entity.TwilightForest.Ice Crystal.name=Eiskristall - -achievement.twilightPortal=Twilight Portal -achievement.twilightPortal.desc=Baue ein Portal in den Zwielicht-Wald. -achievement.twilightArrival=Zwielicht Ankunft -achievement.twilightArrival.desc=Betritt den Zwielicht-Wald. -achievement.twilightHunter=Zwielicht Jger -achievement.twilightHunter.desc=Jage in der lokalen Tierwelt. -achievement.twilightMagicMapFocus=mit Feuer geschrieben -achievement.twilightMagicMapFocus.desc=Crafte den magischen Karten-Fokus mit einer Rabenfeder, Leuchtstein-Staub und Fackelbeeren. -achievement.twilightKillNaga=Naga Jger -achievement.twilightKillNaga.desc=Ttet die Naga in seinem Waldgebiet. -achievement.twilightNagaArmors=Naga Rstung -achievement.twilightNagaArmors.desc=Crafte Naga Brust- und Beinpanzer. -achievement.twilightKillLich=Lich Jger -achievement.twilightKillLich.desc=Ttet den Lich an der Spitze seines Turms. -achievement.twilightLichScepters=Zepter Beherrschung -achievement.twilightLichScepters.desc=Erwerbe alle drei Zepter der Macht. -achievement.twilightHill1=Die Stiefel gehren mir! -achievement.twilightHill1.desc=Besiege einen Rotkppchen Kobold in einem kleinen hohlen Hgel. -achievement.twilightHill2=Was war das fr ein Gerusch? -achievement.twilightHill2.desc=Besiege einen Rotkppchen Pionier in einem mittleren hohlen Hgel. -achievement.twilightHill3=Ich sehe durch Sie hindurch -achievement.twilightHill3.desc=Besiege einen Dmmerungs Geist in einem groen hohlen Hgel. -achievement.twilightHedge=Wanzen-Stampfer -achievement.twilightHedge.desc=Besiege eine Spinne in einem Irrgarten. -achievement.twilightMagicMap=Ich kann meilenweit sehen -achievement.twilightMagicMap.desc=Crafte eine magische Karte. -achievement.twilightMazeMap=Und nun, finde zum Ausgang -achievement.twilightMazeMap.desc=Crafte das Labyrinth Karte nach Erhalt des Fokus aus dem Labyrinth. -achievement.twilightOreMap=Wie kann es das Wert sein? -achievement.twilightOreMap.desc=Crafte die Labyrinth/Erz Karte. -achievement.twilightKillHydra=Hydra Schlchter -achievement.twilightKillHydra.desc=Besiege die mchtige Hydra. -achievement.twilightHydraChop=massiver Hiebe -achievement.twilightHydraChop.desc=Esse das Fleisch der berwltigten Hydra, wenn deine Essen-Leiste leer ist. -achievement.twilightMazebreaker=Brecher des Labyrinths -achievement.twilightMazebreaker.desc=Finde die Labyrinth-Brecher-Spitzhacke im geheimen Labyrinth Gewlbe. -achievement.twilightFierySet=Liter von Blut und Trnen -achievement.twilightFierySet.desc=Nutze ein feuriges Werkzeug oder Waffe beim Tragen mindestens eines Stcks der feurigen Rstung. -achievement.twilightQuestRam=Verbrauchte Baaahs -achievement.twilightQuestRam.desc=Gieb dem Quest-Widder, was ihm fehlt. - -achievement.twilightProgressNaga=schimmernder Umfang -achievement.twilightProgressNaga.desc=Besorge Dir ein Naga-Werkzeug, mit dem die magische Barriere des Lich-Turm berwunden werden kann. -achievement.twilightProgressLich=Von Untoten berhrt -achievement.twilightProgressLich.desc=Verwenden die Magie des Lich-Zepters, um im Sumpf die giftige Mcken zu beseitigen. -achievement.twilightProgressLabyrinth=gewaltiger Stroganow -achievement.twilightProgressLabyrinth.desc=Der Fleisch- und Pilz-Eintopf im Labyrinth macht Dich bereit, den Feuersumpf zu betreten. -achievement.twilightProgressHydra=Das eine Blut -achievement.twilightProgressHydra.desc=Ein Hauch von Hydra Blut im Auge macht den Blindheits-Fluch des dunklen Wald ungeschehen. -achievement.twilightProgressTrophyPedestal=Trophen Meister -achievement.twilightProgressTrophyPedestal.desc=Stelle eine Trophe auf den Sockel in den Ruinen im dunklen Wald. -achievement.twilightProgressKnights=Carminite Eingewhnung -achievement.twilightProgressKnights.desc=Besnftige die rastlosen Gespenster im Ritter-Grab und die Teile des carminite Turms werden Dir gehorchen. -achievement.twilightProgressUrghast=Trnen des Feuers -achievement.twilightProgressUrghast.desc=Berhren die feuerroten Trnen der Ur-Ghasts, um in den Schnee-Wldern der Klte zu widerstehen. -achievement.twilightProgressYeti=Alpha Fell -achievement.twilightProgressYeti.desc=Trage Kleider aus dem weichen Fell vom Alpha Yeti. Sie halten sicher vor der Klte des Gletschers. -achievement.twilightProgressGlacier=wolkenloser Himmel -achievement.twilightProgressGlacier.desc=Besiege die Schneeknigin oben auf dem Aurora-Palast, Damit kein saurer Regen das Hochland mehr heimsucht. -achievement.twilightProgressTroll=Alles soll brennen -achievement.twilightProgressTroll.desc=Finde die Lampe der Asche in den Trollhhle und Du kannst die Dornen-Barriere berwinden. -achievement.twilightProgressThorns=Vorbei an den Dornen -achievement.twilightProgressThorns.desc=Gehe durch das Dornenland, und ffne die Tr des Schlosses. -achievement.twilightProgressCastle=So ein Schloss - Wow -achievement.twilightProgressCastle.desc=Was gibt es noch in dieser Burg?!? \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/de_de.lang b/src/main/resources/assets/twilightforest/lang/de_de.lang new file mode 100644 index 0000000000..61a589e2e3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/de_de.lang @@ -0,0 +1,414 @@ +tile.twilightforest.Log.0.name=Twilight-Eichenholz +tile.twilightforest.Log.1.name=Baldachinholz +tile.twilightforest.Log.2.name=Mangrovenholz +tile.twilightforest.Log.3.name=Dunkelholz +tile.twilightforest.Leaves.0.name=Twilight-Eichenlaub +tile.twilightforest.Leaves.1.name=Baldachinlaub +tile.twilightforest.Leaves.2.name=Mangrovenlaub +tile.twilightforest.Leaves.3.name=Regenbogeneichenlaub +tile.twilightforest.Firefly.name=Leuchtkäfer +tile.twilightforest.Cicada.name=Grille +tile.twilightforest.Portal.name=Twilight-Forest-Portal +tile.twilightforest.Mazestone.0.name=Labyrinthstein +tile.twilightforest.Mazestone.1.name=Labyrinthsteinziegel +tile.twilightforest.Mazestone.2.name=Gemeißelter Labyrinthstein +tile.twilightforest.Mazestone.3.name=Dekorativer Labyrinthsteinziegel +tile.twilightforest.Mazestone.4.name=Rissiger Labyrinthsteinziegel +tile.twilightforest.Mazestone.5.name=Bemooster Labyrinthsteinziegel +tile.twilightforest.Mazestone.6.name=Labyrinthstein Mosaik +tile.twilightforest.Mazestone.7.name=Labyrinthstein Rahmen +tile.twilightforest.Mazestone.8.name=Labyrinthstein Decke +tile.twilightforest.Hedge.0.name=Hecke +tile.twilightforest.Hedge.1.name=Dunkelholzlaub +tile.twilightforest.BossSpawner.0.name=Naga-Spawner +tile.twilightforest.BossSpawner.1.name=Lich-Spawner +tile.twilightforest.BossSpawner.2.name=Hydra-Spawner +tile.twilightforest.BossSpawner.3.name=Ur-Ghast-Spawner +tile.twilightforest.BossSpawner.4.name=Phantomritter-Spawner +tile.twilightforest.FireflyJar.name=Leuchtkäferflasche +tile.twilightforest.Plant.3.name=Moosflecken +tile.twilightforest.Plant.4.name=Maiapfel +tile.twilightforest.Plant.5.name=Kleeflecken [WIP] +tile.twilightforest.Plant.8.name=Farnwedel +tile.twilightforest.Plant.9.name=Düsterpilz +tile.twilightforest.Plant.10.name=Waldgrass +tile.twilightforest.Plant.11.name=Ausgetrockneter Busch +tile.twilightforest.Plant.13.name=Leuchtbeerenpflanze +tile.twilightforest.Plant.14.name=Wurzelenden +tile.twilightforest.Roots.0.name=Wurzeln +tile.twilightforest.Roots.1.name=Lebenswurzel +tile.twilightforest.UncraftingTable.name=Zerlegbank +tile.twilightforest.FireJet.0.name=Rauchblock +tile.twilightforest.FireJet.1.name=Eingehüllter Raucher +tile.twilightforest.FireJet.2.name=Eingehüllter Raucher +tile.twilightforest.FireJet.3.name=Feuerdüse +tile.twilightforest.FireJet.4.name=Knallende Feuerdüse +tile.twilightforest.FireJet.5.name=Brennende Feuerdüse +tile.twilightforest.FireJet.6.name=Eingehüllter Feuerdüse +tile.twilightforest.FireJet.7.name=Eingehüllter Knallende Feuerdüse +tile.twilightforest.FireJet.8.name=Eingehüllter Brennende Feuerdüse +tile.twilightforest.Nagastone.0.name=Nagastein-Kopf +tile.twilightforest.Nagastone.1.name=Nagastein +tile.twilightforest.Sapling.0.name=Kränklicher Twilight-Eichensetzling +tile.twilightforest.Sapling.1.name=Baldachinsetzling +tile.twilightforest.Sapling.2.name=Twilight-Mangrovensetzling +tile.twilightforest.Sapling.3.name=Dunkelholzsetzling +tile.twilightforest.Sapling.4.name=Robuster Twilight-Eichensetzling +tile.twilightforest.Sapling.5.name=Baum der Zeit-Setzling +tile.twilightforest.Sapling.6.name=Baum der Verwandlung-Setzling +tile.twilightforest.Sapling.7.name=Bergwerksbaumsetzling +tile.twilightforest.Sapling.8.name=Sortierbaumsetzling +tile.twilightforest.Sapling.9.name=Regenbogeneichensetzling +tile.twilightforest.Moonworm.name=Mondwurm +tile.twilightforest.MagicLog.0.name=Zeitholz +tile.twilightforest.MagicLog.1.name=Wandelholz +tile.twilightforest.MagicLog.2.name=Bergwerksholz +tile.twilightforest.MagicLog.3.name=Sortierholz +tile.twilightforest.MagicLogSpecial.0.name=Zeitholzuhr +tile.twilightforest.MagicLogSpecial.1.name=Herz der Verwandlung +tile.twilightforest.MagicLogSpecial.2.name=Bergwerkskern +tile.twilightforest.MagicLogSpecial.3.name=Sortiermaschine +tile.twilightforest.MagicLeaves.0.name=Zeitlaub +tile.twilightforest.MagicLeaves.1.name=Wandellaub +tile.twilightforest.MagicLeaves.2.name=Bergwerkslaub +tile.twilightforest.MagicLeaves.3.name=Sortierlaub +tile.twilightforest.TowerStone.0.name=Turmholzbretter +tile.twilightforest.TowerStone.1.name=Eingehülltes Turmholz +tile.twilightforest.TowerStone.2.name=Rissiges Turmholz +tile.twilightforest.TowerStone.3.name=Bemoostes Turmholz +tile.twilightforest.TowerStone.4.name=Turmholz (Würmer) +tile.twilightforest.TowerDevice.0.name=Wiedererscheinender Block +tile.twilightforest.TowerDevice.1.name=Aktiver Wiedererscheinender Block +tile.twilightforest.TowerDevice.2.name=Verschwindender Block +tile.twilightforest.TowerDevice.3.name=Aktiver verschwindender Block +tile.twilightforest.TowerDevice.4.name=Verriegelter verschwindender Block +tile.twilightforest.TowerDevice.5.name=Offener verschwindender Block +tile.twilightforest.TowerDevice.6.name=Turmbauer +tile.twilightforest.TowerDevice.7.name=Aktiver Turmbauer +tile.twilightforest.TowerDevice.8.name=Inaktiver Turmbauer +tile.twilightforest.TowerDevice.9.name=Turmzerstörer +tile.twilightforest.TowerDevice.10.name=Ghastfalle +tile.twilightforest.TowerDevice.11.name=Aktive Ghastfalle +tile.twilightforest.TowerDevice.12.name=Karminit-Reaktor +tile.twilightforest.TowerDevice.13.name=Aktiver Karminit-Reaktor +tile.twilightforest.TowerTranslucent.0.name=Wiedererscheinender Block +tile.twilightforest.TowerTranslucent.1.name=Aktiver Wiedererscheinender Block +tile.twilightforest.TowerTranslucent.2.name=Turmbauerblock +tile.twilightforest.TowerTranslucent.3.name=Aktiver Turmbauerblock +tile.twilightforest.TowerTranslucent.4.name=Turmzerstörer-Block +tile.twilightforest.TowerTranslucent.5.name=Karminit-Reaktortrümmer +tile.twilightforest.TowerTranslucent.6.name=Falsches Gold +tile.twilightforest.TowerTranslucent.7.name=Falsche Diamanten +tile.twilightforest.Trophy.name=Twilight-Forest-Trophäe +tile.twilightforest.Shield.name=Festungsschild +tile.twilightforest.TrophyPedestal.0.name=Trophäensäule +tile.twilightforest.TrophyPedestal.15.name=Ungenutzte Trophäensäule +tile.twilightforest.AuroraBrick.name=Aurorablock +tile.twilightforest.UnderBrick.0.name=Fundamentsziegelstein +tile.twilightforest.UnderBrick.1.name=Bemooster Fundamentsziegelstein +tile.twilightforest.UnderBrick.2.name=Rissiger Fundamentsziegelstein +tile.twilightforest.Thorns.brown.name=Dornen +tile.twilightforest.Thorns.green.name=Grüne Dornen +tile.twilightforest.BurntThorns.name=Verbrannte Dornen +tile.twilightforest.ThornRose.name=Dornenrose +tile.twilightforest.Leaves3.0.name=Dornenlaub +tile.twilightforest.Leaves3.1.name=Bohnenrankenlaub +tile.twilightforest.Deadrock.surface.name=Verwitterter Totenstein +tile.twilightforest.Deadrock.cracked.name=Rissiger Totenstein +tile.twilightforest.Deadrock.solid.name=Totenstein +tile.twilightforest.DarkLeaves.name=Dunklholzlaub +tile.twilightforest.AuroraPillar.name=Aurorasäule +tile.twilightforest.AuroraSlab.name=Aurorastufe +tile.twilightforest.TrollSteinn.name=Trollstein +tile.twilightforest.WispyCloud.name=Dünne Wolke +tile.twilightforest.FluffyCloud.name=Flaumige Wolke +tile.twilightforest.GiantCobble.name=Riesiger Pflasterstein +tile.twilightforest.GiantLog.name=Riesenholz +tile.twilightforest.GiantLeaves.name=Riesenlaub +tile.twilightforest.GiantObsidian.name=Riesenobsidian +tile.twilightforest.UberousSoil.name=Hochwertige Erde +tile.twilightforest.HugeStalk.name=Riesenstengel +tile.twilightforest.HugeGloomBlock.name=Riesendüsterpilz +tile.twilightforest.TrollVidr.name=Trollpflanze +tile.twilightforest.UnripeTrollBer.name=Unreife Trollbeere +tile.twilightforest.TrollBer.name=Trollbeere + +tile.twilightforest.KnightmetalBlock.name=Rittermetallblock +tile.twilightforest.HugeLilyPad.name=Riesenseerosenblatt +tile.twilightforest.HugeWaterLily.name=Riesenseerose +tile.twilightforest.Slider.0.name=Rutschfalle +tile.twilightforest.Slider.1.name=Rutschfalle 1 +tile.twilightforest.Slider.2.name=Rutschfalle 2 +tile.twilightforest.Slider.3.name=Rutschfalle 3 +tile.twilightforest.CastleBrick.0.name=Burgstein +tile.twilightforest.CastleBrick.1.name=Alter Burgstein +tile.twilightforest.CastleBrick.2.name=Rissiger Burgstein +tile.twilightforest.CastleBrick.3.name=Burgdachstein +tile.twilightforest.CastleMagic.0.name=Pinker Burgrunenstein +tile.twilightforest.CastleMagic.1.name=Blauer Burgrunenstein +tile.twilightforest.CastleMagic.2.name=Gelber Burgrunenstein +tile.twilightforest.CastleMagic.3.name=Violetter Burgrunenstein +tile.twilightforest.ForceField.0.name=Violettes Energiefeld +tile.twilightforest.ForceField.1.name=Pinkes Energiefeld +tile.twilightforest.ForceField.2.name=Orangenes Energiefeld +tile.twilightforest.ForceField.3.name=Grünes Energiefeld +tile.twilightforest.ForceField.4.name=Blaues Energiefeld + +item.twilightforest.nagaScale.name=Nagaschuppe +item.twilightforest.plateNaga.name=Nagaschuppenharnisch +item.twilightforest.legsNaga.name=Nagaschuppenbeinschutz +item.twilightforest.scepterTwilight.name=Zepter des Zwielichts +item.twilightforest.scepterLifeDrain.name=Zepter des Lebensaugers +item.twilightforest.scepterZombie.name=Zombiezepter +item.twilightforest.oreMeter.name=Erzmessgerät [WIP] +item.twilightforest.magicMap.name=Magische Karte +item.twilightforest.mazeMap.name=Labyrinthkarte +item.twilightforest.oreMap.name=Labyrinth-Erzkarte +item.twilightforest.tfFeather.name=Rabenfeder +item.twilightforest.magicMapFocus.name=Magischer Kartenfokus +item.twilightforest.mazeMapFocus.name=Labyrinthkartenfokus +item.twilightforest.liveRoot.name=Lebenswurzel +item.twilightforest.ironwoodRaw.name=Eisenholzmaterialien +item.twilightforest.ironwoodIngot.name=Eisenholzbarren +item.twilightforest.ironwoodHelm.name=Eisenholzhelm +item.twilightforest.ironwoodPlate.name=Eisenholzharnisch +item.twilightforest.ironwoodLegs.name=Eisenholzbeinschutz +item.twilightforest.ironwoodBoots.name=Eisenholzstiefel +item.twilightforest.ironwoodSword.name=Eisenholzschwert +item.twilightforest.ironwoodShovel.name=Eisenholzschaufel +item.twilightforest.ironwoodPick.name=Eisenholzspitzhacke +item.twilightforest.ironwoodAxe.name=Eisenholzaxt +item.twilightforest.ironwoodHoe.name=Eisenholzhacke +item.twilightforest.torchberries.name=Fackelbeeren +item.twilightforest.venisonRaw.name=Roher Hirsch +item.twilightforest.venisonCooked.name=Hirschsteak +item.twilightforest.hydraChop.name=Hydrakotelett +item.twilightforest.fieryBlood.name=Feuerblut +item.twilightforest.fieryIngot.name=Feuerbarren +item.twilightforest.fieryHelm.name=Feuerhelm +item.twilightforest.fieryPlate.name=Feuerharnisch +item.twilightforest.fieryLegs.name=Feuerbeinschutz +item.twilightforest.fieryBoots.name=Feuerstiefel +item.twilightforest.fierySword.name=Feuerschwert +item.twilightforest.fieryPick.name=Feuerspitzhacke +item.twilightforest.steeleafIngot.name=Stahlblatt +item.twilightforest.steeleafHelm.name=Stahlblatthelm +item.twilightforest.steeleafPlate.name=Stahlblattharnisch +item.twilightforest.steeleafLegs.name=Stahlblattbeinschutz +item.twilightforest.steeleafBoots.name=Stahlblattstiefel +item.twilightforest.steeleafSword.name=Stahlblattschwert +item.twilightforest.steeleafShovel.name=Stahlblattschaufel +item.twilightforest.steeleafPick.name=Stahlblattspitzhacke +item.twilightforest.steeleafAxe.name=Stahlblattaxt +item.twilightforest.steeleafHoe.name=Stahlblatthacke +item.twilightforest.minotaurAxe.name=Axt des Minotaurus +item.twilightforest.mazebreakerPick.name=Labyrinthbrecher +item.twilightforest.transformPowder.name=Wandelpulver +item.twilightforest.meefRaw.name=Rohes Meeffleisch +item.twilightforest.meefSteak.name=Meefsteak +item.twilightforest.meefStroganoff.name=Meef Stroganoff +item.twilightforest.mazeWafer.name=Labyrinthwaffel +item.twilightforest.emptyMagicMap.name=Leere magische Karte +item.twilightforest.emptyMazeMap.name=Leere Labyrinthkarte +item.twilightforest.emptyOreMap.name=Leere Labyrinth-Erzkarte +item.twilightforest.oreMagnet.name=Erzmagnet +item.twilightforest.crumbleHorn.name=Bröckelhorn +item.twilightforest.peacockFan.name=Pfauenfächer +item.twilightforest.moonwormQueen.name=Mondwurmkönigin +item.twilightforest.charmOfLife1.name=Totem des Lebens I +item.twilightforest.charmOfLife2.name=Totem des Lebens II +item.twilightforest.charmOfKeeping1.name=Totem der Bewahrung I +item.twilightforest.charmOfKeeping2.name=Totem der Bewahrung II +item.twilightforest.charmOfKeeping3.name=Totem der Bewahrung III +item.twilightforest.towerKey.name=Turmschlüssel +item.twilightforest.borerEssence.name=Wurmessenz +item.twilightforest.carminite.name=Karminit +item.twilightforest.trophy.hydra.name=Hydratrophäe +item.twilightforest.trophy.naga.name=Nagatrophäe +item.twilightforest.trophy.lich.name=Lichtrophäe +item.twilightforest.trophy.ur_ghast.name=Ur-Ghasttrophäe +item.twilightforest.trophy.snow_queen.name=Schneekönigintrophäe +item.twilightforest.experiment115.name=Experiment 115 +item.twilightforest.armorShards.name=Rüstungsscherbe +item.twilightforest.knightMetal.name=Rittermetallbarren +item.twilightforest.shardCluster.name=Rüstungsscherbencluster +item.twilightforest.knightlyHelm.name=Ritterlicher Helm +item.twilightforest.knightlyPlate.name=Ritterlicher Harnisch +item.twilightforest.knightlyLegs.name=Ritterlicher Beinschutz +item.twilightforest.knightlyBoots.name=Ritterliche Stiefel +item.twilightforest.knightlySword.name=Ritterliches Schwert +item.twilightforest.knightlyPick.name=Ritterliche Spitzhacke +item.twilightforest.knightlyAxe.name=Ritterliche Axt +item.twilightforest.phantomHelm.name=Phantomhelm +item.twilightforest.phantomPlate.name=Phantomrüstung +item.twilightforest.lampOfCinders.name=Lampe der Asche +item.twilightforest.fieryTears.name=Feuertränen +item.twilightforest.iceBomb.name=Eisbombe +item.twilightforest.yetiHelm.name=Gehörnter Yetihelm +item.twilightforest.yetiPlate.name=Yetijacke +item.twilightforest.yetiLegs.name=Yetihose +item.twilightforest.yetiBoots.name=Yetistiefel +item.twilightforest.alphaFur.name=Alpha-Yetifell +item.twilightforest.arcticFur.name=Arktispelz +item.twilightforest.arcticHelm.name=Arktiskapuze +item.twilightforest.arcticPlate.name=Arktisjacke +item.twilightforest.arcticLegs.name=Arktishose +item.twilightforest.arcticBoots.name=Arktistiefel +item.twilightforest.magicBeans.name=Magische Bohne +item.twilightforest.giantPick.name=Spitzhacke des Riesen +item.twilightforest.giantSword.name=Schwert der Riesen +item.twilightforest.tripleBow.name=Dreierbogen +item.twilightforest.seekerBow.name=Zielbogen +item.twilightforest.iceBow.name=Eisbogen +item.twilightforest.enderBow.name=Enderbogen +item.twilightforest.iceSword.name=Eisschwert +item.twilightforest.glassSword.name=Glasschwert +item.twilightforest.knightmetalRing.name=Ritermetallkettenglied +item.twilightforest.chainBlock.name=Morgenstern +item.twilightforest.cubeTalisman.name=Token des Würfels der Zerstörung +item.twilightforest.cubeOfAnnihilation.name=Würfel der Zerstörung + +item.twilightforest.minotaurAxe.tooltip=Extraschaden beim Sprinten +item.twilightforest.knightlySword.tooltip=Extraschaden bei gepanzerten Gegnern +item.twilightforest.knightlyPick.tooltip=Extraschaden bei gepanzerten Gegnern +item.twilightforest.knightlyAxe.tooltip=Extraschaden bei ungepanzerten Gegnern +item.twilightforest.giantPick.tooltip=Zum Abbauen von Riesenblöcken +item.twilightforest.fieryPick.tooltip=Automatisches Schmelzen +item.twilightforest.fierySword.tooltip=Setzt Gegner in Brand +item.twilightforest.fieryHelm.tooltip=Setzt Angreifer in Brand +item.twilightforest.fieryPlate.tooltip=Setzt Angreifer in Brand +item.twilightforest.fieryLegs.tooltip=Setzt Angreifer in Brand +item.twilightforest.fieryBoots.tooltip=Setzt Angreifer in Brand +item.twilightforest.yetiHelm.tooltip=Friert Angreifer ein +item.twilightforest.yetiPlate.tooltip=Friert Angreifer ein +item.twilightforest.yetiLegs.tooltip=Friert Angreifer ein +item.twilightforest.yetiBoots.tooltip=Friert Angreifer ein + +itemGroup.twilightForest=Twilight-Forest + +entity.twilightforest.wild_boar.name=Wildschwein +entity.twilightforest.bighorn_sheep.name=Dickhornschaf +entity.twilightforest.deer.name=Wilder Hirsch +entity.twilightforest.redcap.name=Rotkäppchen +entity.twilightforest.swarm_spider.name=Schwarmspinne +entity.twilightforest.naga.name=Naga +entity.twilightforest.naga_segment.name=Nagateil +entity.twilightforest.skeleton_druid.name=Skelettdruide +entity.twilightforest.hostile_wolf.name=Böser Wolf +entity.twilightforest.wraith.name=Twilightgespenst +entity.twilightforest.hedge_spider.name=Heckenspinne +entity.twilightforest.hydra.name=Hydra +entity.twilightforest.hydra_head.name=Hydrakopf +entity.twilightforest.lich.name=Twilight-Lich +entity.twilightforest.penguin.name=Pinguin +entity.twilightforest.tiny_bird.name=Kleiner Vogel +entity.twilightforest.squirrel.name=Waldeichhörnchen +entity.twilightforest.bunny.name=Waldhäschen +entity.twilightforest.raven.name=Waldrabe +entity.twilightforest.quest_ram.name=Schafbock der Schatzsuche +entity.twilightforest.kobold.name=Kobold +entity.twilightforest.boggard.name=Boggard [NYI] +entity.twilightforest.lich_minion.name=Diener des Lich +entity.twilightforest.loyal_zombie.name=Loyaler Zombie +entity.twilightforest.mosquito_swarm.name=Mückenschwarm +entity.twilightforest.death_tome.name=Todeswälzer +entity.twilightforest.minotaur.name=Minotaurus +entity.twilightforest.minoshroom.name=Minoschwammerl +entity.twilightforest.fire_beetle.name=Feuerkäfer +entity.twilightforest.slime_beetle.name=Schleimkäfer +entity.twilightforest.pinch_beetle.name=Zangenkäfer +entity.twilightforest.maze_slime.name=Labyrinthschleim +entity.twilightforest.redcap_sapper.name=Rotkäppchenarbeiter +entity.twilightforest.mist_wolf.name=Nebelwolf +entity.twilightforest.king_spider.name=Spinnenkönig +entity.twilightforest.firefly.name=Leuchtkäfer +entity.twilightforest.mini_ghast.name=Karminit-Ghastling +entity.twilightforest.tower_ghast.name=Karminit-Ghastwächter +entity.twilightforest.tower_golem.name=Karminit-Golem +entity.twilightforest.tower_termite.name=Turmholzwurm +entity.twilightforest.tower_broodling.name=Karminitkrabbler +entity.twilightforest.ur_ghast.name=Ur-Ghast +entity.twilightforest.blockchain_goblin.name=Morgenstern-Goblin +entity.twilightforest.goblin_knight_upper.name=Oberritter-Goblin +entity.twilightforest.goblin_knight_lower.name=Ritter-Goblin +entity.twilightforest.helmet_crab.name=Helmgrabbe +entity.twilightforest.knight_phantom.name=Phantomritter +entity.twilightforest.yeti.name=Yeti +entity.twilightforest.yeti_alpha.name=Alpha-Yeti +entity.twilightforest.winter_wolf.name=Winterwolf +entity.twilightforest.snow_guardian.name=Schneewächter +entity.twilightforest.stable_ice_core.name=Stabiler Eiskern +entity.twilightforest.unstable_ice_core.name=Instabiler Eiskern +entity.twilightforest.snow_queen.name=Schneekönigin +entity.twilightforest.troll.name=Höhlentroll +entity.twilightforest.giant_miner.name=Bergriese +entity.twilightforest.armored_giant.name=Gepanzerter Riese +entity.twilightforest.ice_crystal.name=Eiskristall +entity.twilightforest.apocalypse_cube.name=Würfel der Zerstörung [NYI] +entity.twilightforest.adherent.name=Anhänger [NYI] + +advancement.twilight_portal=Twilight-Portal +advancement.twilight_portal.desc=Baue ein Portal in den Twilight-Forest. +advancement.twilight_arrival=Ankunft in der Dämmerung +advancement.twilight_arrival.desc=Betritt den Twilight-Forest. +advancement.twilightforest.twilight_hunter=Düsterjäger +advancement.twilightforest.twilight_hunter.desc=Erlege etwas in der lokalen Tierwelt. +advancement.twilightforest.magic_map_focus=Mit Feuer geschrieben +advancement.twilightforest.magic_map_focus.desc=Stelle den magischen Kartenfokus mit einer Rabenfeder, Glowstonestaub und Fackelbeeren her. +advancement.twilightforest.kill_naga=Schlangenjäger +advancement.twilightforest.kill_naga.desc=Erlege den Naga in seinem Waldhof. +advancement.twilightforest.naga_armors=Naga-Aufrüster +advancement.twilightforest.naga_armors.desc=Stelle Nagaschuppenharnisch und Nagaschuppenbeinschutz her. +advancement.twilightforest.kill_lich=Krieger des Lich +advancement.twilightforest.kill_lich.desc=Töte den Lich an der Spitze seines Turms. +advancement.twilightforest.lich_scepters=Zepterherrscher +advancement.twilightforest.lich_scepters.desc=Erwerbe alle drei Zepter der Macht. +advancement.twilightforest.hill1=Die Stiefel gehören mir! +advancement.twilightforest.hill1.desc=Besiege einen Rotkäppchenkobold in einem kleinen hohlen Hügel. +advancement.twilightforest.hill2=Was war das für ein Geräusch? +advancement.twilightforest.hill2.desc=Besiege einen Rotkäppchen-Pionier in einem mittleren hohlen Hügel. +advancement.twilightforest.hill3=Ich kann dich sehen +advancement.twilightforest.hill3.desc=Besiege ein Twilightgespenst in einem großen hohlen Hügel. +advancement.twilightforest.hedge=Kammerjäger +advancement.twilightforest.hedge.desc=Besiege eine Spinne in einem Irrgarten. +advancement.twilightforest.magic_map=Bis zum Horizont +advancement.twilightforest.magic_map.desc=Stelle eine magische Karte her. +advancement.twilightforest.maze_map=Nichts wie raus hier +advancement.twilightforest.maze_map.desc=Stelle die Labyrinthkarte her, nachdem du einen Labyrinthkartenfokus gefunden hast. +advancement.twilightforest.ore_map=Ist es das denn wert? +advancement.twilightforest.ore_map.desc=Stelle die Labyrinth-Erzkarte her. +advancement.twilightforest.kill_hydra=Hydraschlächter +advancement.twilightforest.kill_hydra.desc=Besiege die mächtige Hydra. +advancement.twilightforest.hydra_chop=Massive Kotletten +advancement.twilightforest.hydra_chop.desc=Esse das übermächtige Fleisch der Hydra, wenn deine Hungerleiste leer ist. +advancement.twilightforest.mazebreaker=Brecher des Labyrinths +advancement.twilightforest.mazebreaker.desc=Finde die Labyrinthbrecher-Spitzhacke im geheimen Labyrinthgewölbe. +advancement.twilightforest.fiery_set=Literweise Blut und Tränen +advancement.twilightforest.fiery_set.desc=Nutze ein Feuerwerkzeug oder eine Feuerwaffe während du mindestens einen Teil der Feuerrüstung trägst. +advancement.twilightforest.quest_ram=Määhige Angelegenheit +advancement.twilightforest.quest_ram.desc=Gieb dem Schafbock der Schatzsuche, was ihm fehlt. + +advancement.twilightforest.progress_naga=Schimmernde Schuppen +advancement.twilightforest.progress_naga.desc=Besorge dir ein Nagawerkzeug, mit dem die magische Barriere des Lich-Turmes überwunden werden kann. +advancement.twilightforest.progress_lich=Von Untoten berührt +advancement.twilightforest.progress_lich.desc=Verwenden die Magie des Zombiezepter, um im Sumpf die giftige Mücken zu beseitigen. +advancement.twilightforest.progress_labyrinth=Gewaltiger Stroganow +advancement.twilightforest.progress_labyrinth.desc=Der Fleisch- und Pilz-Eintopf im Labyrinth macht dich bereit, den Feuersumpf zu betreten. +advancement.twilightforest.progress_hydra=Heldenblut +advancement.twilightforest.progress_hydra.desc=Ein Hauch Hydrablut in deinen Augen macht dich immun gegen den Blindheitsfluch im dunklen Wald. +advancement.twilightforest.progress_trophy_pedestal=Trophäenchampion +advancement.twilightforest.progress_trophy_pedestal.desc=Hol' dir den Titel, indem du eine Trophäe auf den Sockel in den Ruinen im dunklen Wald stellst. +advancement.twilightforest.progress_knights=Karminit-Eingewöhnung +advancement.twilightforest.progress_knights.desc=Besänftige die rastlosen Gespenster im Rittergrab und die Maschinen des Turms werden sich dir beugen. +advancement.twilightforest.progress_ur_ghast=Tränen des Feuers +advancement.twilightforest.progress_ur_ghast.desc=Berühre die feuerroten Tränen des Ur-Ghasts um der Kälte in den Schneewäldern zu widerstehen. +advancement.twilightforest.progress_yeti=Alphafell +advancement.twilightforest.progress_yeti.desc=Trage Kleider aus dem weichen Fell vom Alpha-Yeti. Sie beschützen dich vor der Kälte des Gletschers. +advancement.twilightforest.progress_glacier=Klarer Himmel +advancement.twilightforest.progress_glacier.desc=Besiege die Schneekönigin oben auf dem Aurora-Palast, um das Hochland von saurem Regenfall zu befreien. +advancement.twilightforest.progress_troll=Alles soll brennen +advancement.twilightforest.progress_troll.desc=Finde die Lampe der Asche in den Trollhöhle und du kannst die Dornenbarriere überwinden. +advancement.twilightforest.progress_thorns=An den Dornen vorbei +advancement.twilightforest.progress_thorns.desc=Überwinde das Dornenland und öffne die Tür der Burg. +advancement.twilightforest.progress_castle=Wahnsinnsburg +advancement.twilightforest.progress_castle.desc=Was könnte hier überhaupt drinnen sein? \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/en_US.lang b/src/main/resources/assets/twilightforest/lang/en_US.lang deleted file mode 100644 index 85345ee007..0000000000 --- a/src/main/resources/assets/twilightforest/lang/en_US.lang +++ /dev/null @@ -1,441 +0,0 @@ - -tile.TFLog.0.name=Twilight Oak Wood -tile.TFLog.1.name=Canopy Tree Wood -tile.TFLog.2.name=Mangrove Wood -tile.TFLog.3.name=Darkwood Wood -tile.TFLeaves.0.name=Twilight Oak Leaves -tile.TFLeaves.1.name=Canopy Tree Leaves -tile.TFLeaves.2.name=Mangrove Leaves -tile.TFLeaves.3.name=Rainbow Oak Leaves -tile.TFFirefly.name=Firefly -tile.TFCicada.name=Cicada -tile.TFPortal.name=Twilight Forest Portal -tile.TFMazestone.0.name=Mazestone -tile.TFMazestone.1.name=Mazestone Brick -tile.TFMazestone.2.name=Chiseled Mazestone -tile.TFMazestone.3.name=Decorative Mazestone Brick -tile.TFMazestone.4.name=Cracked Mazestone Brick -tile.TFMazestone.5.name=Mossy Mazestone Brick -tile.TFMazestone.6.name=Mazestone Mosaic -tile.TFMazestone.7.name=Mazestone Border -tile.TFMazestone.8.name=Mazestone Ceiling -tile.TFHedge.0.name=Hedge -tile.TFHedge.1.name=Darkwood Leaves -tile.TFHedge.2.name=Hedge -tile.TFBossSpawner.0.name=Naga Spawner -tile.TFBossSpawner.1.name=Lich Spawner -tile.TFBossSpawner.2.name=Hydra Spawner -tile.TFBossSpawner.3.name=Ur-ghast Spawner -tile.TFBossSpawner.4.name=Knight Phantoms Spawner -tile.TFFireflyJar.name=Firefly Jar -tile.TFPlant.3.name=Moss Patch -tile.TFPlant.4.name=Mayapple -tile.TFPlant.5.name=Clover Patch [WIP] -tile.TFPlant.8.name=Fiddlehead -tile.TFPlant.9.name=Mushgloom -tile.TFPlant.10.name=Forest Grass -tile.TFPlant.11.name=Dried Bush -tile.TFPlant.13.name=Torchberry Plant -tile.TFPlant.14.name=Root Strands -tile.TFRoots.0.name=Roots -tile.TFRoots.1.name=Liveroots -tile.TFUncraftingTable.name=Uncrafting Table -tile.TFFireJet.0.name=Smoking block -tile.TFFireJet.1.name=Encased Smoker -tile.TFFireJet.2.name=Encased Smoker -tile.TFFireJet.8.name=Fire Jet -tile.TFFireJet.9.name=Popping Fire Jet -tile.TFFireJet.10.name=Flaming Fire Jet -tile.TFFireJet.11.name=Encased Fire Jet -tile.TFFireJet.12.name=Encased Popping Fire Jet -tile.TFFireJet.13.name=Encased Flaming Fire Jet -tile.TFNagastone.0.name=Nagastone Head -tile.TFNagastone.1.name=Nagastone Head -tile.TFNagastone.2.name=Nagastone Head -tile.TFNagastone.3.name=Nagastone Head -tile.TFNagastone.4.name=Nagastone -tile.TFNagastone.5.name=Nagastone -tile.TFNagastone.6.name=Nagastone -tile.TFNagastone.7.name=Nagastone -tile.TFNagastone.8.name=Nagastone -tile.TFNagastone.9.name=Nagastone -tile.TFNagastone.10.name=Nagastone -tile.TFNagastone.11.name=Nagastone -tile.TFNagastone.12.name=Nagastone -tile.TFNagastone.13.name=Nagastone -tile.TFNagastone.14.name=Nagastone -tile.TFNagastone.15.name=Nagastone -tile.TFSapling.0.name=Sickly Twilight Oak Sapling -tile.TFSapling.1.name=Canopy Tree Sapling -tile.TFSapling.2.name=Twilight Mangrove Sapling -tile.TFSapling.3.name=Darkwood Sapling -tile.TFSapling.4.name=Robust Twilight Oak Sapling -tile.TFSapling.5.name=Tree of Time Sapling -tile.TFSapling.6.name=Tree of Transformation Sapling -tile.TFSapling.7.name=Miner's Tree Sapling -tile.TFSapling.8.name=Sorting Tree Sapling -tile.TFSapling.9.name=Rainbow Oak Sapling -tile.TFMoonworm.name=Moonworm -tile.TFMagicLog.0.name=Timewood -tile.TFMagicLog.1.name=Transwood -tile.TFMagicLog.2.name=Minewood -tile.TFMagicLog.3.name=Sortingwood -tile.TFMagicLogSpecial.0.name=Timewood Clock -tile.TFMagicLogSpecial.1.name=Heart of Transformation -tile.TFMagicLogSpecial.2.name=Minewood Core -tile.TFMagicLogSpecial.3.name=Sortingwood Engine -tile.TFMagicLeaves.0.name=Timewood Leaves -tile.TFMagicLeaves.1.name=Leaves of Transformation -tile.TFMagicLeaves.2.name=Miner's Leaves -tile.TFMagicLeaves.3.name=Sorting Leaves -tile.TFTowerStone.0.name=Towerwood Planks -tile.TFTowerStone.1.name=Encased Towerwood -tile.TFTowerStone.2.name=Cracked Towerwood -tile.TFTowerStone.3.name=Mossy Towerwood -tile.TFTowerStone.4.name=Infested Towerwood -tile.TFTowerDevice.0.name=Reappearing Block -tile.TFTowerDevice.1.name=Active Reappearing Block -tile.TFTowerDevice.2.name=Vanishing Block -tile.TFTowerDevice.3.name=Active Vanishing Block -tile.TFTowerDevice.4.name=Locked Vanishing Block -tile.TFTowerDevice.5.name=Unlocked Vanishing Block -tile.TFTowerDevice.6.name=Carminite Builder -tile.TFTowerDevice.7.name=Active Carminite Builder -tile.TFTowerDevice.8.name=Inactive Carminite Builder -tile.TFTowerDevice.9.name=Anti-builder -tile.TFTowerDevice.10.name=Ghast Trap -tile.TFTowerDevice.11.name=Active Ghast Trap -tile.TFTowerDevice.12.name=Carminite Reactor -tile.TFTowerDevice.13.name=Active Carminite Reactor -tile.TFTowerTranslucent.0.name=Reappearing Block -tile.TFTowerTranslucent.1.name=Active Reappearing Block -tile.TFTowerTranslucent.2.name=Built Carminite Block -tile.TFTowerTranslucent.3.name=Active Built Carminite Block -tile.TFTowerTranslucent.4.name=Anti-built Block -tile.TFTowerTranslucent.5.name=Carminite Reactor Debris -tile.TFTowerTranslucent.6.name=False Gold -tile.TFTowerTranslucent.7.name=False Diamond -tile.TFTrophy.name=Twilight Forest Trophy -tile.TFShield.0.name=Stronghold Shield -tile.TFShield.1.name=Stronghold Shield -tile.TFShield.2.name=Stronghold Shield -tile.TFShield.3.name=Stronghold Shield -tile.TFShield.4.name=Stronghold Shield -tile.TFShield.5.name=Stronghold Shield -tile.TFShield.15.name=Stronghold Shield -tile.TFTrophyPedestal.0.name=Trophy Pedestal -tile.TFTrophyPedestal.15.name=Latent Trophy Pedestal -tile.TFAuroraBrick.name=Aurora Block -tile.TFUnderBrick.0.name=Underbrick -tile.TFUnderBrick.1.name=Mossy Underbrick -tile.TFUnderBrick.2.name=Cracked Underbrick -tile.TFThorns.brown.name=Thorns -tile.TFThorns.green.name=Green Thorns -tile.TFBurntThorns.name=Burnt Thorns -tile.TFThornRose.name=Thorn Rose -tile.TFLeaves3.0.name=Thorn Leaves -tile.TFLeaves3.1.name=Beanstalk Leaves -tile.TFDeadrock.surface.name=Weathered Deadrock -tile.TFDeadrock.cracked.name=Cracked Deadrock -tile.TFDeadrock.solid.name=Deadrock -tile.DarkLeaves.name=Darkwood Leaves -tile.AuroraPillar.name=Aurora Pillar -tile.AuroraSlab.name=Aurora Slab -tile.TrollSteinn.name=Trollsteinn -tile.WispyCloud.name=Wispy Cloud -tile.FluffyCloud.name=Fluffy Cloud -tile.GiantCobble.name=Giant Cobblestone -tile.GiantLog.name=Giant Log -tile.GiantLeaves.name=Giant Leaves -tile.GiantObsidian.name=Giant Obsidian -tile.UberousSoil.name=Uberous Soil -tile.HugeStalk.name=Huge Stalk -tile.HugeGloomBlock.name=Huge Mushgloom -tile.TrollVidr.name=Trollvidr -tile.UnripeTrollBer.name=Unripe Trollber -tile.TrollBer.name=Trollber -tile.TrollBer.name=Trollber -tile.KnightmetalBlock.name=Block of Knightmetal -tile.HugeLilyPad.name=Huge Lily Pad -tile.HugeWaterLily.name=Huge Water Lily -tile.Slider.0.name=Slide Trap -tile.Slider.1.name=Slide Trap 1 -tile.Slider.2.name=Slide Trap 2 -tile.Slider.3.name=Slide Trap 3 -tile.CastleBrick.0.name=Castle Brick -tile.CastleBrick.1.name=Worn Castle Brick -tile.CastleBrick.2.name=Cracked Castle Brick -tile.CastleBrick.3.name=Castle Roof Tile -tile.CastleMagic.0.name=Pink Castle Rune Brick -tile.CastleMagic.1.name=Blue Castle Rune Brick -tile.CastleMagic.2.name=Yellow Castle Rune Brick -tile.CastleMagic.3.name=Violet Castle Rune Brick -tile.ForceField.0.name=Violet Force Field -tile.ForceField.1.name=Pink Force Field -tile.ForceField.2.name=Orange Force Field -tile.ForceField.3.name=Green Force Field -tile.ForceField.4.name=Blue Force Field - -item.nagaScale.name=Naga Scale -item.plateNaga.name=Naga Scale Tunic -item.legsNaga.name=Naga Scale Leggings -item.scepterTwilight.name=Scepter of Twilight -item.scepterLifeDrain.name=Scepter of Life Draining -item.scepterZombie.name=Zombie Scepter -item.oreMeter.name=Ore Meter [WIP] -item.magicMap.name=Magic Map -item.mazeMap.name=Maze Map -item.oreMap.name=Maze/Ore Map -item.tfFeather.name=Raven's Feather -item.magicMapFocus.name=Magic Map Focus -item.mazeMapFocus.name=Maze Map Focus -item.liveRoot.name=Liveroot -item.ironwoodRaw.name=Raw Ironwood Materials -item.ironwoodIngot.name=Ironwood Ingot -item.ironwoodHelm.name=Ironwood Helm -item.ironwoodPlate.name=Ironwood Plate -item.ironwoodLegs.name=Ironwood Legs -item.ironwoodBoots.name=Ironwood Boots -item.ironwoodSword.name=Ironwood Sword -item.ironwoodShovel.name=Ironwood Shovel -item.ironwoodPick.name=Ironwood Pick -item.ironwoodAxe.name=Ironwood Axe -item.ironwoodHoe.name=Ironwood Hoe -item.torchberries.name=Torchberries -item.venisonRaw.name=Raw Venison -item.venisonCooked.name=Venison Steak -item.hydraChop.name=Hydra Chop -item.fieryBlood.name=Fiery Blood -item.fieryIngot.name=Fiery Ingot -item.fieryHelm.name=Fiery Helm -item.fieryPlate.name=Fiery Plate -item.fieryLegs.name=Fiery Legs -item.fieryBoots.name=Fiery Boots -item.fierySword.name=Fiery Sword -item.fieryPick.name=Fiery Pick -item.steeleafIngot.name=Steeleaf -item.steeleafHelm.name=Steeleaf Helm -item.steeleafPlate.name=Steeleaf Plate -item.steeleafLegs.name=Steeleaf Legs -item.steeleafBoots.name=Steeleaf Boots -item.steeleafSword.name=Steeleaf Sword -item.steeleafShovel.name=Steeleaf Shovel -item.steeleafPick.name=Steeleaf Pick -item.steeleafAxe.name=Steeleaf Axe -item.steeleafHoe.name=Steeleaf Hoe -item.minotaurAxe.name=Minotaur Axe -item.mazebreakerPick.name=Mazebreaker -item.transformPowder.name=Transformation Powder -item.meefRaw.name=Raw Meef -item.meefSteak.name=Meef Steak -item.meefStroganoff.name=Meef Stroganoff -item.mazeWafer.name=Maze Wafer -item.emptyMagicMap.name=Blank Magic Map -item.emptyMazeMap.name=Blank Maze Map -item.emptyOreMap.name=Blank Maze/Ore Map -item.oreMagnet.name=Ore Magnet -item.crumbleHorn.name=Crumble Horn -item.peacockFan.name=Peacock Feather Fan -item.moonwormQueen.name=Moonworm Queen -item.charmOfLife1.name=Charm of Life I -item.charmOfLife2.name=Charm of Life II -item.charmOfKeeping1.name=Charm of Keeping I -item.charmOfKeeping2.name=Charm of Keeping II -item.charmOfKeeping3.name=Charm of Keeping III -item.towerKey.name=Tower Key -item.borerEssence.name=Borer Essence -item.carminite.name=Carminite -item.trophy.hydra.name=Hydra Trophy -item.trophy.naga.name=Naga Trophy -item.trophy.lich.name=Lich Trophy -item.trophy.ur-ghast.name=Ur-ghast Trophy -item.trophy.snowQueen.name=Snow Queen Trophy -item.experiment115.name=Experiment 115 -item.armorShards.name=Armor Shard -item.knightMetal.name=Knightmetal Ingot -item.shardCluster.name=Armor Shard Cluster -item.knightlyHelm.name=Knightly Helm -item.knightlyPlate.name=Knightly Plate -item.knightlyLegs.name=Knightly Greaves -item.knightlyBoots.name=Knightly Boots -item.knightlySword.name=Knightly Sword -item.knightlyPick.name=Knightly Pick -item.knightlyAxe.name=Knightly Axe -item.phantomHelm.name=Phantom Helm -item.phantomPlate.name=Phantom Plate -item.lampOfCinders.name=Lamp of Cinders -item.fieryTears.name=Fiery Tears -item.iceBomb.name=Ice Bomb -item.yetiHelm.name=Yeti Horned Helm -item.yetiPlate.name=Yeti Jacket -item.yetiLegs.name=Yeti Leggings -item.yetiBoots.name=Yeti Boots -item.alphaFur.name=Alpha Yeti Fur -item.arcticFur.name=Arctic Fur -item.arcticHelm.name=Arctic Hood -item.arcticPlate.name=Arctic Jacket -item.arcticLegs.name=Arctic Leggings -item.arcticBoots.name=Arctic Boots -item.magicBeans.name=Magic Beans -item.giantPick.name=Giant's Pickaxe -item.giantSword.name=Giant's Sword -item.tripleBow.name=Tri-bow -item.seekerBow.name=Seeker Bow -item.iceBow.name=Ice Bow -item.enderBow.name=Ender Bow -item.iceSword.name=Ice Sword -item.glassSword.name=Glass Sword -item.knightmetalRing.name=Knightmetal Loop -item.chainBlock.name=Block and Chain -item.cubeTalisman.name=Talisman of the Cube -item.cubeOfAnnihilation.name=Cube of Annihilation - -item.minotaurAxe.tooltip=Extra damage while charging -item.knightlySword.tooltip=Extra damage to armored targets -item.knightlyPick.tooltip=Extra damage to armored targets -item.knightlyAxe.tooltip=Extra damage to unarmored targets -item.giantPick.tooltip=Breaks giant blocks -item.fieryPick.tooltip=Auto-smelting -item.fierySword.tooltip=Burns targets -item.fieryHelm.tooltip=Burns attackers -item.fieryPlate.tooltip=Burns attackers -item.fieryLegs.tooltip=Burns attackers -item.fieryBoots.tooltip=Burns attackers -item.yetiHelm.tooltip=Chills attackers -item.yetiPlate.tooltip=Chills attackers -item.yetiLegs.tooltip=Chills attackers -item.yetiBoots.tooltip=Chills attackers - -item.tfspawnegg.name=Spawn - -itemGroup.twilightForest=Twilight Forest - -entity.TwilightForest.Wild Boar.name=Wild Boar -entity.TwilightForest.Bighorn Sheep.name=Bighorn Sheep -entity.TwilightForest.Wild Deer.name=Wild Deer -entity.TwilightForest.Redcap.name=Redcap -entity.TwilightForest.Swarm Spider.name=Swarm Spider -entity.TwilightForest.Naga.name=Naga -entity.TwilightForest.Naga Segment.name=Naga Segment -entity.TwilightForest.Skeleton Druid.name=Skeleton Druid -entity.TwilightForest.Hostile Wolf.name=Hostile Wolf -entity.TwilightForest.Twilight Wraith.name=Twilight Wraith -entity.TwilightForest.Hedge Spider.name=Hedge Spider -entity.TwilightForest.Hydra.name=Hydra -entity.TwilightForest.HydraHead.name=Hydra Head -entity.TwilightForest.Twilight Lich.name=Twilight Lich -entity.TwilightForest.Glacier Penguin.name=Penguin -entity.TwilightForest.Tiny Bird.name=Tiny Bird -entity.TwilightForest.Forest Squirrel.name=Forest Squirrel -entity.TwilightForest.Forest Bunny.name=Forest Bunny -entity.TwilightForest.Forest Raven.name=Forest Raven -entity.TwilightForest.Questing Ram.name=Questing Ram -entity.TwilightForest.Twilight Kobold.name=Kobold -entity.TwilightForest.Boggard.name=Boggard [NYI] -entity.TwilightForest.Lich Minion.name=Lich Minion -entity.TwilightForest.Loyal Zombie.name=Loyal Zombie -entity.TwilightForest.Mosquito Swarm.name=Mosquito Swarm -entity.TwilightForest.Death Tome.name=Death Tome -entity.TwilightForest.Minotaur.name=Minotaur -entity.TwilightForest.Minoshroom.name=Minoshroom -entity.TwilightForest.Fire Beetle.name=Fire Beetle -entity.TwilightForest.Slime Beetle.name=Slime Beetle -entity.TwilightForest.Pinch Beetle.name=Pinch Beetle -entity.TwilightForest.Maze Slime.name=Maze Slime -entity.TwilightForest.Redcap Sapper.name=Redcap Sapper -entity.TwilightForest.Mist Wolf.name=Mist Wolf -entity.TwilightForest.King Spider.name=King Spider -entity.TwilightForest.Firefly.name=Firefly -entity.TwilightForest.Mini Ghast.name=Carminite Ghastling -entity.TwilightForest.Tower Ghast.name=Carminite Ghastguard -entity.TwilightForest.Tower Golem.name=Carminite Golem -entity.TwilightForest.Tower Termite.name=Towerwood Borer -entity.TwilightForest.Redscale Broodling.name=Carminite Broodling -entity.TwilightForest.Tower Boss.name=Ur-ghast -entity.TwilightForest.Block&Chain Goblin.name=Block and Chain Goblin -entity.TwilightForest.Upper Goblin Knight.name=Upper Goblin Knight -entity.TwilightForest.Lower Goblin Knight.name=Lower Goblin Knight -entity.TwilightForest.Helmet Crab.name=Helmet Crab -entity.TwilightForest.Knight Phantom.name=Knight Phantom -entity.TwilightForest.Yeti.name=Yeti -entity.TwilightForest.Yeti Boss.name=Alpha Yeti -entity.TwilightForest.WinterWolf.name=Winter Wolf -entity.TwilightForest.SnowGuardian.name=Snow Guardian -entity.TwilightForest.Stable Ice Core.name=Stable Ice Core -entity.TwilightForest.Unstable Ice Core.name=Unstable Ice Core -entity.TwilightForest.Snow Queen.name=Snow Queen -entity.TwilightForest.Troll.name=Cave Troll -entity.TwilightForest.Giant Miner.name=Giant Miner -entity.TwilightForest.Armored Giant.name=Armored Giant -entity.TwilightForest.Ice Crystal.name=Ice Crystal -entity.TwilightForest.Apocalypse Cube.name=Apocolypse Cube [NYI] -entity.TwilightForest.Adherent.name=Adherent [NYI] - -achievement.twilightPortal=Twilight Portal -achievement.twilightPortal.desc=Build a portal to the Twilight Forest. -achievement.twilightArrival=Twilight Arrival -achievement.twilightArrival.desc=Arrive in the Twilight Forest. -achievement.twilightHunter=Twilight Hunter -achievement.twilightHunter.desc=Hunt some of the local wildlife. -achievement.twilightMagicMapFocus=With Fire It Writes -achievement.twilightMagicMapFocus.desc=Craft the magic map focus with a raven's feather, glowstone dust, and torchberries. -achievement.twilightKillNaga=Naga Hunter -achievement.twilightKillNaga.desc=Slay the naga in its forest courtyard. -achievement.twilightNagaArmors=Naga Armorer -achievement.twilightNagaArmors.desc=Craft both naga scale chest and leg armor. -achievement.twilightKillLich=Lich Hunter -achievement.twilightKillLich.desc=Slay the lich at the top of his tower. -achievement.twilightLichScepters=Scepter Mastery -achievement.twilightLichScepters.desc=Acquire all three scepters of power. -achievement.twilightHill1=The Boots Are Mine! -achievement.twilightHill1.desc=Defeat a redcap goblin in a small hollow hill. -achievement.twilightHill2=What Was That Noise? -achievement.twilightHill2.desc=Defeat a redcap sapper in a medium hollow hill. -achievement.twilightHill3=I See Right Through You -achievement.twilightHill3.desc=Defeat a twilight wraith in a large hollow hill. -achievement.twilightHedge=Bug Stomper -achievement.twilightHedge.desc=Defeat a spider in a hedge maze. -achievement.twilightMagicMap=I Can See For Miles -achievement.twilightMagicMap.desc=Craft the magic map. -achievement.twilightMazeMap=And Now, to Find the Exit -achievement.twilightMazeMap.desc=Craft the maze map after obtaining the focus from the labyrinth. -achievement.twilightOreMap=How Can That Be Worth It? -achievement.twilightOreMap.desc=Craft the maze/ore map. -achievement.twilightKillHydra=Hydra Slayer -achievement.twilightKillHydra.desc=Defeat the mighty hydra. -achievement.twilightHydraChop=Massive Chops -achievement.twilightHydraChop.desc=Chow down on some overpowered hydra meat when your food bar is empty. -achievement.twilightMazebreaker=Breaking the Maze -achievement.twilightMazebreaker.desc=Find the Mazebreaker pick in the secret labyrinth vault. -achievement.twilightFierySet=Gallons of Blood and Tears -achievement.twilightFierySet.desc=Wield a fiery tool or weapon while wearing at least one piece of fiery armor. -achievement.twilightQuestRam=Consumate Baaahs -achievement.twilightQuestRam.desc=Give the Quest Ram what it is missing. - -achievement.twilightProgressNaga=Shimmering Scale -achievement.twilightProgressNaga.desc=Obtain a naga scale, allowing you to overcome the barrier magic surrounding the Lich's tower. -achievement.twilightProgressLich=Touched by Undeath -achievement.twilightProgressLich.desc=Use the magic of the the Lich's scepter to clear away poisonous mosquitoes in the swamp. -achievement.twilightProgressLabyrinth=Mighty Stroganoff -achievement.twilightProgressLabyrinth.desc=The meat-and-mushroom stew in the labyrinth makes you feel ready to enter the Fire Swamp. -achievement.twilightProgressHydra=Of One Blood -achievement.twilightProgressHydra.desc=A touch of hydra blood in your eyes makes you resist the blindness curse in the Dark Forest. -achievement.twilightProgressTrophyPedestal=Trophied Champion -achievement.twilightProgressTrophyPedestal.desc=Claim your title by placing a trophy on the pedestal in the dark forest ruins. -achievement.twilightProgressKnights=Carminite Acclimation -achievement.twilightProgressKnights.desc=Settle the restless phantoms in the Knight's Tomb and the carminite tower's devices will obey you. -achievement.twilightProgressUrghast=Tears of Fire -achievement.twilightProgressUrghast.desc=Touch the fiery red tears of the Ur-ghast, allowing you to resist the snow forest's chill. -achievement.twilightProgressYeti=Alpha Fur -achievement.twilightProgressYeti.desc=Line your garments with the soft fur from the alpha yeti, keeping you safe from the glacier's cold. -achievement.twilightProgressGlacier=Clear Skies -achievement.twilightProgressGlacier.desc=Defeat the Snow Queen atop the Aurora Palace, clearing away the acid rain from the highlands. -achievement.twilightProgressTroll=I Wish For More Burning -achievement.twilightProgressTroll.desc=Find the Lamp of Cinders in the troll caves, and you can burn away the thorn barriers. -achievement.twilightProgressThorns=Past the Thorns -achievement.twilightProgressThorns.desc=Make it past the thornlands, and unlock the door of the castle. -achievement.twilightProgressCastle=So Castle Very Wow -achievement.twilightProgressCastle.desc=What could even be in that castle?!? - - - diff --git a/src/main/resources/assets/twilightforest/lang/en_us.lang b/src/main/resources/assets/twilightforest/lang/en_us.lang new file mode 100644 index 0000000000..8dbef7e42d --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/en_us.lang @@ -0,0 +1,854 @@ +#PARSE_ESCAPES + +itemGroup.twilightForest=Twilight Forest + +# ADVANCEMENTS +advancement.twilightforest.root.desc=Enter the mysterious magical woodlands; the Twilight Forest. + +# General progression +advancement.twilightforest.hedge=Bug Stomper +advancement.twilightforest.hedge.desc=Defeat a spider in a %s. + +advancement.twilightforest.hill1=The Boots Are Mine! +advancement.twilightforest.hill1.desc=Defeat a %s in a small %s. +advancement.twilightforest.hill2=What Was That Noise? +advancement.twilightforest.hill2.desc=Defeat a %s in a medium %s. +advancement.twilightforest.hill3=I See Right Through You +advancement.twilightforest.hill3.desc=Defeat a %s in a large %s. + +advancement.twilightforest.quest_ram=Consummate Baaahs +advancement.twilightforest.quest_ram.desc=Give the %s what it is missing. + +# Map +advancement.twilightforest.magic_map_focus=With Fire It Writes +advancement.twilightforest.magic_map_focus.desc=Craft the %s with a %s, %s, and %s. +advancement.twilightforest.magic_map=I Can See Forever +advancement.twilightforest.magic_map.desc=Craft the %s. +advancement.twilightforest.maze_map=And Now, to Find the Exit +advancement.twilightforest.maze_map.desc=Craft the %s after obtaining the focus from the labyrinth. +advancement.twilightforest.ore_map=How Can That Be Worth It? +advancement.twilightforest.ore_map.desc=Craft the %s. + +# Mainline beginning progression +advancement.twilightforest.twilight_hunter=The Silence of the Forest +advancement.twilightforest.twilight_hunter.desc=Hunt some of the local wildlife. + +advancement.twilightforest.kill_naga=Time To Even The Scales +advancement.twilightforest.kill_naga.desc=Slay the %s in its forest courtyard and obtain a %s to overcome the barrier magic surrounding the Lich's tower. +advancement.twilightforest.naga_armors=Naga Armorer +advancement.twilightforest.naga_armors.desc=Craft both %s chest and leg armor. + +advancement.twilightforest.kill_lich=Bring Out Your Dead +advancement.twilightforest.kill_lich.desc=Slay the %s at top of his tower and retrieve a scepter to clear poisonous mosquitoes from the Swamp, see through blinding darkness of the Dark Forest's curse, and resist the Snowy Forest's chill. +advancement.twilightforest.lich_scepters=By Our Powers Combined! +advancement.twilightforest.lich_scepters.desc=Acquire all four scepters of power. + +# Swamp Progression +advancement.twilightforest.progress_labyrinth=Mighty Stroganoff +advancement.twilightforest.progress_labyrinth.desc=The meat & mushroom stew pleasantly warms you, enough so that that you feel you're acclimatised enough to venture into the Fire Swamp. +advancement.twilightforest.kill_hydra=Hydra Slayer +advancement.twilightforest.kill_hydra.desc=Defeat the mighty %s and empower yourself. +advancement.twilightforest.mazebreaker=Breaking the Maze +advancement.twilightforest.mazebreaker.desc=Find the %s pickaxe in the secret labyrinth vault. +advancement.twilightforest.hydra_chop=Hydra Chop, Baby! +advancement.twilightforest.hydra_chop.desc=Chow down on some overpowered %s meat when your food bar is empty. + +# Dark Forest Progression +advancement.twilightforest.progress_trophy_pedestal=Trophied Champion +advancement.twilightforest.progress_trophy_pedestal.desc=Claim your title by placing a trophy on the pedestal in the dark forest ruins. +advancement.twilightforest.progress_knights=Carminite Acclimation +advancement.twilightforest.progress_knights.desc=Settle the restless phantoms in the Knight's Tomb and the carminite tower's devices will obey you. +advancement.twilightforest.ghast_trap=Something Strange in Towerwood +advancement.twilightforest.ghast_trap.desc=Slay the %ss around a %s and activate to wrench the %s from the sky! +advancement.twilightforest.progress_ur_ghast=Tears of Fire +advancement.twilightforest.progress_ur_ghast.desc=Touch the fiery red tears of the %s. + +advancement.twilightforest.experiment_115=Mystery Meat? +advancement.twilightforest.experiment_115.desc=It looks like cake, though... +advancement.twilightforest.experiment_115_2=Making a note: Huge Success! +advancement.twilightforest.experiment_115_2.desc=It's so delicious and moist! + +# Snow Forest Progression +advancement.twilightforest.progress_yeti=Alpha Fur +advancement.twilightforest.progress_yeti.desc=Line your garments with the soft fur from the %s, keeping you safe from the Glacier's cold. +advancement.twilightforest.progress_glacier=Clear Skies +advancement.twilightforest.progress_glacier.desc=Defeat the %s atop the %s. +advancement.twilightforest.arctic_dyed=Getting in Fashion +advancement.twilightforest.arctic_dyed.desc=Dye all four pieces of Arctic Armor. + +# Mid-way Misc. Stuff +advancement.twilightforest.glass_sword=One Hit Wonder +advancement.twilightforest.glass_sword.desc=Hope you made good use of that. + +advancement.twilightforest.fiery_set=Gallons of Blood and Tears +advancement.twilightforest.fiery_set.desc=Wield a fiery tool or weapon while wearing at least one piece of fiery armor. + +# Highlands +advancement.twilightforest.progress_merge=Ultimate Showdown +advancement.twilightforest.progress_merge.desc=Slay the %s, %s, and %s to clear the acid rain and embolden yourself for the Highlands. +advancement.twilightforest.progress_troll=I Wish For More Burning +advancement.twilightforest.progress_troll.desc=Find the %s in the troll caves, and you can burn away the thorn barriers. +advancement.twilightforest.progress_thorns=Past the Thorns [NYI] +advancement.twilightforest.progress_thorns.desc=Make it past the Thornlands, and unlock the door of the castle. +advancement.twilightforest.progress_castle=So Castle Very Wow [NYI] +advancement.twilightforest.progress_castle.desc=What could even be in that castle?!? + +# Collections +advancement.twilightforest.twilight_dining=We Dine At Eternal Sundown +advancement.twilightforest.twilight_dining.desc=Eat ALL of the Food exclusive to the Twilight Forest. +advancement.twilightforest.experiment_115_3=Eating 115 Everyday, 115 Years, Forever +advancement.twilightforest.experiment_115_3.desc=eating experiment one-hundred-fifteen all day, forever, one-hundred-fifteen times experiment one-hundred-fifteen, experiment one-hundred-fifteen dot com, double-u double-u double-u dot experiment one-hundred-fifteen dot com, one-hundred-fifteen years, every minute experiment one-hundred-fifteen dot com, double-u double-u double-u dot one-hundred-fifteen times experiment one-hundred-fifteen dot com +advancement.twilightforest.arborist=Maniacal Dendrologist +advancement.twilightforest.arborist.desc=Get your axes and shears ready. Search every nook and cranny and get anything and everything that comes from trees! Craft, loot, obtain every slab... sapling... leaves... more... everything. ALL OF IT! + +twilightforest.twilight_portal.unsafe=It doesn't seem safe here... +twilightforest.trophy_pedestal.ineligible=You are unworthy. +twilightforest.ore_meter.range=Radius: %s, Origin: [%s, %s] +twilightforest.ore_meter.exposed=Exposed: %s +twilightforest.scepter_charges=%d charges left + +# Commands +commands.tffeature.usage=/tffeature +commands.tffeature.not_in_twilight_forest=You are not in the Twilight Forest dimension +commands.tffeature.nearest=The nearest feature is %s +commands.tffeature.center=Center of feature: %s +commands.tffeature.chunk=Are in feature chunk: %s +commands.tffeature.structure.inside=You are in the structure for that feature +commands.tffeature.structure.outside=You are not in the structure for that feature +commands.tffeature.structure.required=You are not in a structure +commands.tffeature.structure.conquer.status=Structure conquer flag: %s +commands.tffeature.structure.conquer.update=Structure conquer flag was %s, changing to %s +commands.tffeature.locate.usage=/tffeature locate + +# Blocks +tile.twilightforest.Log.0.name=Twilight Oak Wood +tile.twilightforest.Log.1.name=Canopy Tree Wood +tile.twilightforest.Log.2.name=Mangrove Wood +tile.twilightforest.Log.3.name=Darkwood +tile.twilightforest.Leaves.0.name=Twilight Oak Leaves +tile.twilightforest.Leaves.1.name=Canopy Tree Leaves +tile.twilightforest.Leaves.2.name=Mangrove Leaves +tile.twilightforest.Leaves.3.name=Rainbow Oak Leaves +tile.twilightforest.Firefly.name=Firefly +tile.twilightforest.Cicada.name=Cicada +tile.twilightforest.Cicada.desc=What if this could be launched at someone with a Railgun...? +item.twilightforest.Portal.name=Twilight Forest Portal +tile.twilightforest.Portal.name=Twilight Forest Portal +tile.twilightforest.Mazestone.0.name=Mazestone +tile.twilightforest.Mazestone.1.name=Mazestone Brick +tile.twilightforest.Mazestone.2.name=Chiseled Mazestone +tile.twilightforest.Mazestone.3.name=Decorative Mazestone Brick +tile.twilightforest.Mazestone.4.name=Cracked Mazestone Brick +tile.twilightforest.Mazestone.5.name=Mossy Mazestone Brick +tile.twilightforest.Mazestone.6.name=Mazestone Mosaic +tile.twilightforest.Mazestone.7.name=Mazestone Border +tile.twilightforest.Mazestone.8.name=Mazestone Ceiling +tile.twilightforest.Hedge.0.name=Hedge +tile.twilightforest.Hedge.1.name=Darkwood Leaves +tile.twilightforest.BossSpawner.0.name=Naga Spawner +tile.twilightforest.BossSpawner.1.name=Lich Spawner +tile.twilightforest.BossSpawner.2.name=Hydra Spawner +tile.twilightforest.BossSpawner.3.name=Ur-Ghast Spawner +tile.twilightforest.BossSpawner.4.name=Knight Phantoms Spawner +tile.twilightforest.BossSpawner.5.name=Snow Queen Spawner +tile.twilightforest.BossSpawner.6.name=Minoshroom Spawner +tile.twilightforest.BossSpawner.7.name=Alpha Yeti Spawner +tile.twilightforest.FireflyJar.name=Firefly Jar +tile.twilightforest.Plant.0.name=Moss Patch +tile.twilightforest.Plant.1.name=Mayapple +tile.twilightforest.Plant.2.name=Clover Patch [WIP] +tile.twilightforest.Plant.3.name=Fiddlehead +tile.twilightforest.Plant.4.name=Mushgloom +tile.twilightforest.Plant.5.name=Forest Grass +tile.twilightforest.Plant.6.name=Dried Bush +tile.twilightforest.Plant.7.name=Torchberry Plant +tile.twilightforest.Plant.8.name=Root Strands +tile.twilightforest.Plant.9.name=Leaf Pile +tile.twilightforest.Roots.0.name=Roots +tile.twilightforest.Roots.1.name=Liveroots +tile.twilightforest.UncraftingTable.name=Uncrafting Table +tile.twilightforest.FireJet.0.name=Smoking Block +tile.twilightforest.FireJet.1.name=Encased Smoker +tile.twilightforest.FireJet.2.name=Encased Smoker +tile.twilightforest.FireJet.3.name=Fire Jet +tile.twilightforest.FireJet.4.name=Popping Fire Jet +tile.twilightforest.FireJet.5.name=Flaming Fire Jet +tile.twilightforest.FireJet.6.name=Encased Fire Jet +tile.twilightforest.FireJet.7.name=Encased Popping Fire Jet +tile.twilightforest.FireJet.8.name=Encased Flaming Fire Jet +tile.twilightforest.Nagastone.0.name=Nagastone Head +tile.twilightforest.Nagastone.1.name=Nagastone +tile.twilightforest.Sapling.name=Twilight Sapling +tile.twilightforest.Sapling.0.name=Sickly Twilight Oak Sapling +tile.twilightforest.Sapling.1.name=Canopy Tree Sapling +tile.twilightforest.Sapling.2.name=Twilight Mangrove Sapling +tile.twilightforest.Sapling.3.name=Darkwood Sapling +tile.twilightforest.Sapling.4.name=Robust Twilight Oak Sapling +tile.twilightforest.Sapling.5.name=Tree of Time Sapling +tile.twilightforest.Sapling.6.name=Tree of Transformation Sapling +tile.twilightforest.Sapling.7.name=Miner's Tree Sapling +tile.twilightforest.Sapling.8.name=Sorting Tree Sapling +tile.twilightforest.Sapling.9.name=Rainbow Oak Sapling +tile.twilightforest.Moonworm.name=Moonworm +tile.twilightforest.MagicLog.0.name=Timewood +tile.twilightforest.MagicLog.1.name=Transwood +tile.twilightforest.MagicLog.2.name=Minewood +tile.twilightforest.MagicLog.3.name=Sortingwood +tile.twilightforest.MagicLogSpecial.0.name=Timewood Clock +tile.twilightforest.MagicLogSpecial.1.name=Heart of Transformation +tile.twilightforest.MagicLogSpecial.2.name=Minewood Core +tile.twilightforest.MagicLogSpecial.3.name=Sortingwood Engine +tile.twilightforest.MagicLeaves.0.name=Timewood Leaves +tile.twilightforest.MagicLeaves.1.name=Leaves of Transformation +tile.twilightforest.MagicLeaves.2.name=Miner's Leaves +tile.twilightforest.MagicLeaves.3.name=Sorting Leaves +tile.twilightforest.TowerStone.0.name=Towerwood Planks +tile.twilightforest.TowerStone.1.name=Encased Towerwood +tile.twilightforest.TowerStone.2.name=Cracked Towerwood +tile.twilightforest.TowerStone.3.name=Mossy Towerwood +tile.twilightforest.TowerStone.4.name=Infested Towerwood +tile.twilightforest.TowerDevice.0.name=Reappearing Block +tile.twilightforest.TowerDevice.1.name=Active Reappearing Block +tile.twilightforest.TowerDevice.2.name=Vanishing Block +tile.twilightforest.TowerDevice.3.name=Active Vanishing Block +tile.twilightforest.TowerDevice.4.name=Locked Vanishing Block +tile.twilightforest.TowerDevice.5.name=Unlocked Vanishing Block +tile.twilightforest.TowerDevice.6.name=Carminite Builder +tile.twilightforest.TowerDevice.7.name=Active Carminite Builder +tile.twilightforest.TowerDevice.8.name=Inactive Carminite Builder +tile.twilightforest.TowerDevice.9.name=Anti-builder +tile.twilightforest.TowerDevice.10.name=Ghast Trap +tile.twilightforest.TowerDevice.11.name=Active Ghast Trap +tile.twilightforest.TowerDevice.12.name=Carminite Reactor +tile.twilightforest.TowerDevice.13.name=Active Carminite Reactor +tile.twilightforest.TowerTranslucent.0.name=Reappearing Block +tile.twilightforest.TowerTranslucent.1.name=Active Reappearing Block +tile.twilightforest.TowerTranslucent.2.name=Built Carminite Block +tile.twilightforest.TowerTranslucent.3.name=Active Built Carminite Block +tile.twilightforest.TowerTranslucent.4.name=Anti-built Block +tile.twilightforest.TowerTranslucent.5.name=Carminite Reactor Debris +tile.twilightforest.TowerTranslucent.6.name=False Gold +tile.twilightforest.TowerTranslucent.7.name=False Diamond +tile.twilightforest.Trophy.name=Twilight Forest Trophy +tile.twilightforest.Shield.name=Stronghold Shield +tile.twilightforest.TrophyPedestal.0.name=Trophy Pedestal +tile.twilightforest.TrophyPedestal.15.name=Latent Trophy Pedestal +tile.twilightforest.AuroraBrick.name=Aurora Block +tile.twilightforest.UnderBrick.0.name=Underbrick +tile.twilightforest.UnderBrick.1.name=Mossy Underbrick +tile.twilightforest.UnderBrick.2.name=Cracked Underbrick +tile.twilightforest.UnderBrick.3.name=Underbrick Floor +tile.twilightforest.Thorns.brown.name=Thorns +tile.twilightforest.Thorns.green.name=Green Thorns +tile.twilightforest.BurntThorns.name=Burnt Thorns +tile.twilightforest.ThornRose.name=Thorn Rose +tile.twilightforest.Leaves3.0.name=Thorn Leaves +tile.twilightforest.Leaves3.1.name=Beanstalk Leaves +tile.twilightforest.Deadrock.surface.name=Weathered Deadrock +tile.twilightforest.Deadrock.cracked.name=Cracked Deadrock +tile.twilightforest.Deadrock.solid.name=Deadrock +tile.twilightforest.DarkLeaves.name=Darkwood Leaves +tile.twilightforest.AuroralizedGlass.name=Auroralized Glass +tile.twilightforest.AuroraPillar.name=Aurora Pillar +tile.twilightforest.AuroraSlab.name=Aurora Slab +tile.twilightforest.TrollSteinn.name=Trollsteinn +tile.twilightforest.WispyCloud.name=Wispy Cloud +tile.twilightforest.FluffyCloud.name=Fluffy Cloud +tile.twilightforest.GiantCobble.name=Giant Cobblestone +tile.twilightforest.GiantLog.name=Giant Log +tile.twilightforest.GiantLeaves.name=Giant Leaves +tile.twilightforest.GiantObsidian.name=Giant Obsidian +tile.twilightforest.UberousSoil.name=Uberous Soil +tile.twilightforest.HugeStalk.name=Huge Stalk +tile.twilightforest.HugeGloomBlock.name=Huge Mushgloom +tile.twilightforest.TrollVidr.name=Trollvidr +tile.twilightforest.UnripeTrollBer.name=Unripe Trollber +tile.twilightforest.TrollBer.name=Trollber +tile.twilightforest.TrollBer.name=Trollber +tile.twilightforest.KnightmetalBlock.name=Block of Knightmetal +tile.twilightforest.HugeLilyPad.name=Huge Lily Pad +tile.twilightforest.HugeWaterLily.name=Huge Water Lily +tile.twilightforest.Slider.0.name=Slide Trap +tile.twilightforest.Slider.1.name=Slide Trap 1 +tile.twilightforest.Slider.2.name=Slide Trap 2 +tile.twilightforest.Slider.3.name=Slide Trap 3 +tile.twilightforest.CastleBrick.0.name=Castle Brick +tile.twilightforest.CastleBrick.1.name=Worn Castle Brick +tile.twilightforest.CastleBrick.2.name=Cracked Castle Brick +tile.twilightforest.CastleBrick.3.name=Castle Roof Tile +tile.twilightforest.CastleBrick.4.name=Mossy Castle Brick +tile.twilightforest.CastleBrick.5.name=Thick Castle Brick +tile.twilightforest.CastleStairsBrick.name=Castle Brick Stairs +tile.twilightforest.CastleStairsWorn.name=Worn Castle Brick Stairs +tile.twilightforest.CastleStairsCracked.name=Cracked Castle Brick Stairs +tile.twilightforest.CastleStairsMossy.name=Mossy Castle Brick Stairs +tile.twilightforest.CastleDoor.0.name=Yellow Castle Door +tile.twilightforest.CastleDoor.1.name=Violet Castle Door +tile.twilightforest.CastleDoor.2.name=Pink Castle Door +tile.twilightforest.CastleDoor.3.name=Blue Castle Door +tile.twilightforest.CastleMagic.0.name=Pink Castle Rune Brick +tile.twilightforest.CastleMagic.1.name=Blue Castle Rune Brick +tile.twilightforest.CastleMagic.2.name=Yellow Castle Rune Brick +tile.twilightforest.CastleMagic.3.name=Violet Castle Rune Brick +tile.twilightforest.CastlePillar.0.name=Encased Castle Brick Pillar +tile.twilightforest.CastlePillar.1.name=Encased Castle Brick Tile +tile.twilightforest.CastlePillar.2.name=Bold Castle Brick Pillar +tile.twilightforest.CastlePillar.3.name=Bold Castle Brick Tiles +tile.twilightforest.CastleStairs.0.name=Encased Castle Brick Stairs +tile.twilightforest.CastleStairs.8.name=Bold Castle Brick Stairs +tile.twilightforest.ForceField.0.name=Violet Force Field +tile.twilightforest.ForceField.1.name=Pink Force Field +tile.twilightforest.ForceField.2.name=Orange Force Field +tile.twilightforest.ForceField.3.name=Green Force Field +tile.twilightforest.ForceField.4.name=Blue Force Field +tile.twilightforest.BlockOfStorage.0.name=Block of Ironwood +tile.twilightforest.BlockOfStorage.1.name=Block of Fiery Metal +tile.twilightforest.BlockOfStorage.2.name=Block of Steeleaf +tile.twilightforest.BlockOfStorage.3.name=Block of Arctic Fur +tile.twilightforest.BlockOfStorage.4.name=Block of Carminite +tile.twilightforest.CinderFurnaceIdle.name=Cinder Furnace [NYI] +tile.twilightforest.CinderLog.name=Cinder Log [NYI] +tile.twilightforest.MiniatureStructure=Miniature %s [NYI] +tile.twilightforest.SpiralBricks.name=Spiral Stone Bricks +tile.twilightforest.BlockOfLapisTF.name=Block Of Lapis [NYI] +tile.twilightforest.EtchedNagastone.name=Etched Nagastone +tile.twilightforest.NagastonePillar.name=Nagastone Pillar +tile.twilightforest.NagastoneStairs.0.name=Nagastone Stairs (Left) +tile.twilightforest.NagastoneStairs.8.name=Nagastone Stairs (Right) +tile.twilightforest.EtchedNagastoneMossy.name=Mossy Etched Nagastone +tile.twilightforest.NagastonePillarMossy.name=Mossy Nagastone Pillar +tile.twilightforest.NagastoneStairsMossy.0.name=Mossy Nagastone Stairs (Left) +tile.twilightforest.NagastoneStairsMossy.8.name=Mossy Nagastone Stairs (Right) +tile.twilightforest.EtchedNagastoneWeathered.name=Ruined Etched Nagastone +tile.twilightforest.NagastonePillarWeathered.name=Ruined Nagastone Pillar +tile.twilightforest.NagastoneStairsWeathered.0.name=Weathered Nagastone Stairs (Left) +tile.twilightforest.NagastoneStairsWeathered.8.name=Weathered Nagastone Stairs (Right) +tile.twilightforest.IronLadder.name=Iron Ladder +tile.twilightforest.TerrorCottaCircle.name=Terrorcotta (Circular) +tile.twilightforest.TerrorCottaDiagonal.name=Terrorcotta (Diagonal) + +tile.twilightforest.CanopyPlanks.name=Canopy Planks +tile.twilightforest.CanopyStairs.name=Canopy Stairs +tile.twilightforest.CanopySlab.name=Canopy Slab +tile.twilightforest.CanopyButton.name=Canopy Button +tile.twilightforest.CanopyFence.name=Canopy Fence +tile.twilightforest.CanopyGate.name=Canopy Gate +tile.twilightforest.CanopyPlate.name=Canopy Pressure Plate +tile.twilightforest.CanopyTrapDoor.name=Canopy Trapdoor +item.tile.twilightforest.CanopyDoor.name=Canopy Door + +tile.twilightforest.DarkPlanks.name=Darkwood Planks +tile.twilightforest.DarkStairs.name=Darkwood Stairs +tile.twilightforest.DarkSlab.name=Darkwood Slab +tile.twilightforest.DarkButton.name=Darkwood Button +tile.twilightforest.DarkFence.name=Darkwood Fence +tile.twilightforest.DarkGate.name=Darkwood Gate +tile.twilightforest.DarkPlate.name=Darkwood Pressure Plate +tile.twilightforest.DarkTrapDoor.name=Darkwood Trapdoor +item.tile.twilightforest.DarkDoor.name=Darkwood Door + +tile.twilightforest.MangrovePlanks.name=Mangrove Planks +tile.twilightforest.MangroveStairs.name=Mangrove Stairs +tile.twilightforest.MangroveSlab.name=Mangrove Slab +tile.twilightforest.MangroveButton.name=Mangrove Button +tile.twilightforest.MangroveFence.name=Mangrove Fence +tile.twilightforest.MangroveGate.name=Mangrove Gate +tile.twilightforest.MangrovePlate.name=Mangrove Pressure Plate +tile.twilightforest.MangroveTrapDoor.name=Mangrove Trapdoor +item.tile.twilightforest.MangroveDoor.name=Mangrove Door + +tile.twilightforest.TwilightOakPlanks.name=Twilight Oak Planks +tile.twilightforest.TwilightOakStairs.name=Twilight Oak Stairs +tile.twilightforest.TwilightOakSlab.name=Twilight Oak Slab +tile.twilightforest.TwilightOakButton.name=Twilight Oak Button +tile.twilightforest.TwilightOakFence.name=Twilight Oak Fence +tile.twilightforest.TwilightOakGate.name=Twilight Oak Gate +tile.twilightforest.TwilightOakPlate.name=Twilight Oak Pressure Plate +tile.twilightforest.TwilightOakTrapDoor.name=Twilight Oak Trapdoor +item.tile.twilightforest.TwilightOakDoor.name=Twilight Oak Door + +tile.twilightforest.TimePlanks.name=Timewood Planks +tile.twilightforest.TimeStairs.name=Timewood Stairs +tile.twilightforest.TimeSlab.name=Timewood Slab +tile.twilightforest.TimeButton.name=Timewood Button +tile.twilightforest.TimeFence.name=Timewood Fence +tile.twilightforest.TimeGate.name=Timewood Gate +tile.twilightforest.TimePlate.name=Timewood Pressure Plate +tile.twilightforest.TimeTrapDoor.name=Timewood Trapdoor +item.tile.twilightforest.TimeDoor.name=Timewood Door + +tile.twilightforest.TransPlanks.name=Transwood Planks +tile.twilightforest.TransStairs.name=Transwood Stairs +tile.twilightforest.TransSlab.name=Transwood Slab +tile.twilightforest.TransButton.name=Transwood Button +tile.twilightforest.TransFence.name=Transwood Fence +tile.twilightforest.TransGate.name=Transwood Gate +tile.twilightforest.TransPlate.name=Transwood Pressure Plate +tile.twilightforest.TransTrapDoor.name=Transwood Trapdoor +item.tile.twilightforest.TransDoor.name=Transwood Door + +tile.twilightforest.MinePlanks.name=Minewood Planks +tile.twilightforest.MineStairs.name=Minewood Stairs +tile.twilightforest.MineSlab.name=Minewood Slab +tile.twilightforest.MineButton.name=Minewood Button +tile.twilightforest.MineFence.name=Minewood Fence +tile.twilightforest.MineGate.name=Minewood Gate +tile.twilightforest.MinePlate.name=Minewood Pressure Plate +tile.twilightforest.MineTrapDoor.name=Minewood Trapdoor +item.tile.twilightforest.MineDoor.name=Minewood Door + +tile.twilightforest.SortPlanks.name=Sortingwood Planks +tile.twilightforest.SortStairs.name=Sortingwood Stairs +tile.twilightforest.SortSlab.name=Sortingwood Slab +tile.twilightforest.SortButton.name=Sortingwood Button +tile.twilightforest.SortFence.name=Sortingwood Fence +tile.twilightforest.SortGate.name=Sortingwood Gate +tile.twilightforest.SortPlate.name=Sortingwood Pressure Plate +tile.twilightforest.SortTrapDoor.name=Sortingwood Trapdoor +item.tile.twilightforest.SortDoor.name=Sortingwood Door + +# Structures +structure.twilight_portal.name=Twilight Portal +structure.hedge_maze.name=Hedge Maze +structure.hollow_hill.name=Hollow Hill +structure.quest_grove.name=Quest Grove +structure.mushroom_tower.name=Mushroom Castle +structure.naga_courtyard.name=Naga Courtyard +structure.lich_tower.name=Lich Tower +structure.minotaur_labyrinth.name=Minotaur Labyrinth +structure.hydra_lair.name=Hydra's Lair +structure.goblin_stronghold.name=Goblin Stronghold +structure.dark_tower.name=Dark Tower +structure.yeti_cave.name=Yeti Cave +structure.aurora_palace.name=Aurora Palace +structure.troll_cave_and_cloud_castle.name=Troll Cave and House in the Clouds +structure.final_castle.name=Final Castle + +# Items +item.twilightforest.nagaScale.name=Naga Scale +item.twilightforest.plateNaga.name=Naga Scale Tunic +item.twilightforest.legsNaga.name=Naga Scale Leggings +item.twilightforest.scepterTwilight.name=Scepter of Twilight +item.twilightforest.scepterLifeDrain.name=Scepter of Life Draining +item.twilightforest.scepterZombie.name=Zombie Scepter +item.twilightforest.scepterShield.name=Scepter of Fortification +item.twilightforest.oreMeter.name=Ore Meter [WIP] +item.twilightforest.magicMap.name=Magic Map +item.twilightforest.mazeMap.name=Maze Map +item.twilightforest.oreMap.name=Maze/Ore Map +item.twilightforest.tfFeather.name=Raven Feather +item.twilightforest.magicMapFocus.name=Magic Map Focus +item.twilightforest.mazeMapFocus.name=Maze Map Focus +item.twilightforest.liveRoot.name=Liveroot +item.twilightforest.ironwoodRaw.name=Raw Ironwood Materials +item.twilightforest.ironwoodIngot.name=Ironwood Ingot +item.twilightforest.ironwoodHelm.name=Ironwood Helm +item.twilightforest.ironwoodPlate.name=Ironwood Plate +item.twilightforest.ironwoodLegs.name=Ironwood Legs +item.twilightforest.ironwoodBoots.name=Ironwood Boots +item.twilightforest.ironwoodSword.name=Ironwood Sword +item.twilightforest.ironwoodShovel.name=Ironwood Shovel +item.twilightforest.ironwoodPick.name=Ironwood Pick +item.twilightforest.ironwoodAxe.name=Ironwood Axe +item.twilightforest.ironwoodHoe.name=Ironwood Hoe +item.twilightforest.torchberries.name=Torchberries +item.twilightforest.venisonRaw.name=Raw Venison +item.twilightforest.venisonCooked.name=Venison Steak +item.twilightforest.hydraChop.name=Hydra Chop +item.twilightforest.fieryBlood.name=Fiery Blood +item.twilightforest.fieryIngot.name=Fiery Ingot +item.twilightforest.fieryHelm.name=Fiery Helm +item.twilightforest.fieryPlate.name=Fiery Plate +item.twilightforest.fieryLegs.name=Fiery Legs +item.twilightforest.fieryBoots.name=Fiery Boots +item.twilightforest.fierySword.name=Fiery Sword +item.twilightforest.fieryPick.name=Fiery Pick +item.twilightforest.steeleafIngot.name=Steeleaf +item.twilightforest.steeleafHelm.name=Steeleaf Helm +item.twilightforest.steeleafPlate.name=Steeleaf Plate +item.twilightforest.steeleafLegs.name=Steeleaf Legs +item.twilightforest.steeleafBoots.name=Steeleaf Boots +item.twilightforest.steeleafSword.name=Steeleaf Sword +item.twilightforest.steeleafShovel.name=Steeleaf Shovel +item.twilightforest.steeleafPick.name=Steeleaf Pick +item.twilightforest.steeleafAxe.name=Steeleaf Axe +item.twilightforest.steeleafHoe.name=Steeleaf Hoe +item.twilightforest.minotaurAxe.name=Diamond Minotaur Axe +item.twilightforest.minotaurAxeGold.name=Golden Minotaur Axe +item.twilightforest.mazebreakerPick.name=Mazebreaker +item.twilightforest.transformPowder.name=Transformation Powder +item.twilightforest.meefRaw.name=Raw Meef +item.twilightforest.meefSteak.name=Meef Steak +item.twilightforest.meefStroganoff.name=Meef Stroganoff +item.twilightforest.mazeWafer.name=Maze Wafer +item.twilightforest.emptyMagicMap.name=Blank Magic Map +item.twilightforest.emptyMazeMap.name=Blank Maze Map +item.twilightforest.emptyOreMap.name=Blank Maze/Ore Map +item.twilightforest.oreMagnet.name=Ore Magnet +item.twilightforest.crumbleHorn.name=Crumble Horn +item.twilightforest.peacockFan.name=Peacock Feather Fan +item.twilightforest.moonwormQueen.name=Moonworm Queen +item.twilightforest.charmOfLife1.name=Charm of Life I +item.twilightforest.charmOfLife2.name=Charm of Life II +item.twilightforest.charmOfKeeping1.name=Charm of Keeping I +item.twilightforest.charmOfKeeping2.name=Charm of Keeping II +item.twilightforest.charmOfKeeping3.name=Charm of Keeping III +item.twilightforest.towerKey.name=Tower Key +item.twilightforest.borerEssence.name=Borer Essence +item.twilightforest.carminite.name=Carminite +item.twilightforest.tf_trophy.name=%s Trophy +item.twilightforest.trophy.hydra.name=Hydra Trophy +item.twilightforest.trophy.naga.name=Naga Trophy +item.twilightforest.trophy.lich.name=Lich Trophy +item.twilightforest.trophy.ur_ghast.name=Ur-Ghast Trophy +item.twilightforest.trophy.snow_queen.name=Snow Queen Trophy +item.twilightforest.experiment115.name=Experiment 115 +item.twilightforest.armorShards.name=Armor Shard +item.twilightforest.knightMetal.name=Knightmetal Ingot +item.twilightforest.shardCluster.name=Armor Shard Cluster +item.twilightforest.knightlyHelm.name=Knightly Helm +item.twilightforest.knightlyPlate.name=Knightly Plate +item.twilightforest.knightlyLegs.name=Knightly Greaves +item.twilightforest.knightlyBoots.name=Knightly Boots +item.twilightforest.knightlySword.name=Knightly Sword +item.twilightforest.knightlyPick.name=Knightly Pick +item.twilightforest.knightlyAxe.name=Knightly Axe +item.twilightforest.knightlyShield.name=Knightly Shield +item.twilightforest.phantomHelm.name=Phantom Helm +item.twilightforest.phantomPlate.name=Phantom Plate +item.twilightforest.lampOfCinders.name=Lamp of Cinders +item.twilightforest.fieryTears.name=Fiery Tears +item.twilightforest.iceBomb.name=Ice Bomb +item.twilightforest.yetiHelm.name=Yeti Horned Helm +item.twilightforest.yetiPlate.name=Yeti Jacket +item.twilightforest.yetiLegs.name=Yeti Leggings +item.twilightforest.yetiBoots.name=Yeti Boots +item.twilightforest.alphaFur.name=Alpha Yeti Fur +item.twilightforest.arcticFur.name=Arctic Fur +item.twilightforest.arcticHelm.name=Arctic Hood +item.twilightforest.arcticPlate.name=Arctic Jacket +item.twilightforest.arcticLegs.name=Arctic Leggings +item.twilightforest.arcticBoots.name=Arctic Boots +item.twilightforest.magicBeans.name=Magic Beans +item.twilightforest.giantPick.name=Giant's Pickaxe +item.twilightforest.giantSword.name=Giant's Sword +item.twilightforest.tripleBow.name=Tri-bow +item.twilightforest.seekerBow.name=Seeker Bow +item.twilightforest.iceBow.name=Ice Bow +item.twilightforest.enderBow.name=Ender Bow +item.twilightforest.iceSword.name=Ice Sword +item.twilightforest.glassSword.name=Glass Sword +item.twilightforest.knightmetalRing.name=Knightmetal Loop +item.twilightforest.chainBlock.name=Block and Chain +item.twilightforest.cubeTalisman.name=Talisman of the Cube +item.twilightforest.cubeOfAnnihilation.name=Cube of Annihilation +item.twilightforest.moonDial.name=Moon Dial + +item.twilightforest.guide.name=Traveller's Logbook + +item.twilightforest.minotaurAxe.tooltip=Extra damage while charging +item.twilightforest.minotaurAxeGold.tooltip=Extra damage while charging +item.twilightforest.knightlySword.tooltip=Extra damage to armored targets +item.twilightforest.knightlyPick.tooltip=Extra damage to armored targets +item.twilightforest.knightlyAxe.tooltip=Extra damage to unarmored targets +item.twilightforest.giantPick.tooltip=Breaks giant blocks +item.twilightforest.fieryPick.tooltip=Auto-smelting +item.twilightforest.fierySword.tooltip=Burns targets +item.twilightforest.fieryHelm.tooltip=Burns attackers +item.twilightforest.fieryPlate.tooltip=Burns attackers +item.twilightforest.fieryLegs.tooltip=Burns attackers +item.twilightforest.fieryBoots.tooltip=Burns attackers +item.twilightforest.phantomHelm.tooltip=Is never lost on death +item.twilightforest.phantomPlate.tooltip=Is never lost on death +item.twilightforest.yetiHelm.tooltip=Chills attackers +item.twilightforest.yetiPlate.tooltip=Chills attackers +item.twilightforest.yetiLegs.tooltip=Chills attackers +item.twilightforest.yetiBoots.tooltip=Chills attackers + +item.twilightforest.arctic_armor.tooltip=Dyeable like Leather Armor + +# Entities +entity.twilightforest.wild_boar.name=Wild Boar +entity.twilightforest.bighorn_sheep.name=Bighorn Sheep +entity.twilightforest.deer.name=Wild Deer +entity.twilightforest.redcap.name=Redcap Goblin +entity.twilightforest.swarm_spider.name=Swarm Spider +entity.twilightforest.naga.name=Naga +entity.twilightforest.naga_segment.name=Naga Segment +entity.twilightforest.skeleton_druid.name=Skeleton Druid +entity.twilightforest.hostile_wolf.name=Hostile Wolf +entity.twilightforest.wraith.name=Twilight Wraith +entity.twilightforest.hedge_spider.name=Hedge Spider +entity.twilightforest.hydra.name=Hydra +entity.twilightforest.hydra_head.name=Hydra Head +entity.twilightforest.lich.name=Twilight Lich +entity.twilightforest.penguin.name=Penguin +entity.twilightforest.tiny_bird.name=Tiny Bird +entity.twilightforest.squirrel.name=Forest Squirrel +entity.twilightforest.bunny.name=Dwarf Rabbit +entity.twilightforest.raven.name=Forest Raven +entity.twilightforest.quest_ram.name=Questing Ram +entity.twilightforest.kobold.name=Kobold +entity.twilightforest.boggard.name=Boggard [NYI] +entity.twilightforest.lich_minion.name=Lich Minion +entity.twilightforest.loyal_zombie.name=Loyal Zombie +entity.twilightforest.mosquito_swarm.name=Mosquito Swarm +entity.twilightforest.death_tome.name=Death Tome +entity.twilightforest.minotaur.name=Minotaur +entity.twilightforest.minoshroom.name=Minoshroom +entity.twilightforest.fire_beetle.name=Fire Beetle +entity.twilightforest.slime_beetle.name=Slime Beetle +entity.twilightforest.pinch_beetle.name=Pinch Beetle +entity.twilightforest.maze_slime.name=Maze Slime +entity.twilightforest.redcap_sapper.name=Redcap Sapper +entity.twilightforest.mist_wolf.name=Mist Wolf +entity.twilightforest.king_spider.name=King Spider +entity.twilightforest.firefly.name=Firefly +entity.twilightforest.mini_ghast.name=Carminite Ghastling +entity.twilightforest.tower_ghast.name=Carminite Ghastguard +entity.twilightforest.tower_golem.name=Carminite Golem +entity.twilightforest.tower_termite.name=Towerwood Borer +entity.twilightforest.tower_broodling.name=Carminite Broodling +entity.twilightforest.ur_ghast.name=Ur-Ghast +entity.twilightforest.blockchain_goblin.name=Block and Chain Goblin +entity.twilightforest.goblin_knight_upper.name=Upper Goblin Knight +entity.twilightforest.goblin_knight_lower.name=Lower Goblin Knight +entity.twilightforest.helmet_crab.name=Helmet Crab +entity.twilightforest.knight_phantom.name=Knight Phantom +entity.twilightforest.yeti.name=Yeti +entity.twilightforest.yeti_alpha.name=Alpha Yeti +entity.twilightforest.winter_wolf.name=Winter Wolf +entity.twilightforest.snow_guardian.name=Snow Guardian +entity.twilightforest.stable_ice_core.name=Stable Ice Core +entity.twilightforest.unstable_ice_core.name=Unstable Ice Core +entity.twilightforest.snow_queen.name=Snow Queen +entity.twilightforest.troll.name=Cave Troll +entity.twilightforest.giant_miner.name=Giant Miner +entity.twilightforest.armored_giant.name=Armored Giant +entity.twilightforest.ice_crystal.name=Ice Crystal +entity.twilightforest.rising_zombie.name=Zombie +entity.twilightforest.apocalypse_cube.name=Apocalypse Cube [NYI] +entity.twilightforest.adherent.name=Adherent [NYI] +entity.twilightforest.castle_guardian.name=Castle Guardian [NYI] + +twilightforest.effect.frosted=Frosted + +twilightforest.misc.wip0=This block is a work in progress and may have bugs or unintended effects that may damage your world. +twilightforest.misc.wip1=Use with caution. +twilightforest.misc.nyi=This block has effects that are not yet implemented. + +twilightforest.loading.title.enter=Whisking you off to the Twilight Forest... +twilightforest.loading.title.leave=Whisking you from the Twilight Forest... + +#Config +twilightforest.config.dimension=Dimension Settings +twilightforest.config.dimension.tooltip=You won't be able to change these settings without some kind of relaunch. +twilightforest.config.dimension_id=Dimension ID +twilightforest.config.dimension_id.tooltip=What ID number to assign to the Twilight Forest dimension. Change if you are having conflicts with another mod. +twilightforest.config.dimension_seed=Dimension Seed +twilightforest.config.dimension_seed.tooltip=If set, this will override the normal world seed when generating parts of the Twilight Forest Dimension. +twilightforest.config.spawn_in_tf=New Players Spawn in Twilight Forest +twilightforest.config.spawn_in_tf.tooltip=If true, players spawning for the first time will spawn in the Twilight Forest. +twilightforest.config.skylight_forest=Skylight Forest [WIP] +twilightforest.config.skylight_forest.tooltip=If true, Twilight Forest will generate as a void except for Major Structures. +twilightforest.config.skylight_oaks=Skylight Oaks [WIP] +twilightforest.config.skylight_oaks.tooltip=If true, giant Twilight Oaks will also spawn in void worlds. + +twilightforest.config.world_gen_weights=World-Gen Weights +twilightforest.config.world_gen_weights.tooltip=Weights for various small features +twilightforest.config.stone_circle_weight=Stone Circle weight +twilightforest.config.well_weight=Well weight +twilightforest.config.stalagmite_weight=Stalagmite weight +twilightforest.config.foundation_weight=Foundation weight +twilightforest.config.monolith_weight=Monolith weight +twilightforest.config.grove_ruins_weight=Grove Ruins weight +twilightforest.config.hollow_stump_weight=Hollow Stump weight +twilightforest.config.fallen_hollow_log_weight=Fallen Hollow Log weight +twilightforest.config.fallen_small_log_weight=Fallen Small Log weight +twilightforest.config.druid_hut_weight=Druid Hut weight + +twilightforest.config.hollow_hill_stalactites=Custom Hollow Hill Stalactites +twilightforest.config.hollow_hill_stalactites.tooltip=Defines custom stalactites generated in hollow hills.\nFormat is \"modid:block<:meta> size maxLength minHeight weight\", where the properties are:\nSize - the maximum length of the stalactite relative to the space between hill floor and ceiling,\nMax length - maximum length of a stalactite in blocks,\nMin height - minimum space between the hill floor and the stalactite to let it generate,\nWeight - how often it generates.\n\nFor example: \"minecraft:iron_ore 0.7 8 1 24\" would add a stalactite equal to the default iron ore stalactite. +twilightforest.config.large_hill=Large Hills +twilightforest.config.large_hill.tooltip=Blocks generating as stalactites in large hills only. +twilightforest.config.medium_hill=Medium and Large Hills +twilightforest.config.medium_hill.tooltip=Blocks generating as stalactites in medium and large hills. +twilightforest.config.small_hill=All Hills +twilightforest.config.small_hill.tooltip=Blocks generating as stalactites in all hills. +twilightforest.config.stalactite_config_only=Only Use the Stalactite Config +twilightforest.config.stalactite_config_only.tooltip=If true, default stalactites and stalactites defined by other mods will not be used. + +twilightforest.config.compat=Compatibility +twilightforest.config.compat.tooltip=Should TF Compatibility load? Turn off if TF's Compatibility is causing crashes or if not desired. + +twilightforest.config.performance=Performance Tweaks +twilightforest.config.performance.tooltip=Lets you sacrifice various things to improve world performance. +twilightforest.config.canopy_coverage=Canopy Coverage +twilightforest.config.canopy_coverage.tooltip=Amount of canopy coverage. Lower numbers improve chunk generation speed at the cost of a thinner forest. +twilightforest.config.twilight_oaks=Twilight Oak Chance +twilightforest.config.twilight_oaks.tooltip=Chance that a chunk in the Twilight Forest will contain a twilight oak tree. Higher numbers reduce the number of trees, increasing performance. +twilightforest.config.leaves_light_opacity=Twilight Leaves opacity +twilightforest.config.leaves_light_opacity.tooltip=This controls the opacity of leaves, changing the amount of light blocked. Can be used to decrease complexity in some lighting checks. +twilightforest.config.glacier_packed_ice=Glaciers made of Packed Ice instead of Ice +twilightforest.config.glacier_packed_ice.tooltip=Setting this true will make Twilight Glaciers generate with Packed Ice instead of regular translucent Ice, decreasing amount of light checking calculations. +twilightforest.config.enable_skylight=Enable Skylight +twilightforest.config.enable_skylight.tooltip=If the dimension has per-block skylight values. Disabling this will significantly improve world generation performance, at the cost of flat lighting everywhere.\nWARNING: Once chunks are loaded without skylight, that data is lost and cannot easily be regenerated. Be careful! + +twilightforest.config.silent_cicadas=Silent Cicadas +twilightforest.config.silent_cicadas.tooltip=Make cicadas silent for those having sound library problems, or otherwise finding them annoying. + +twilightforest.config.first_person_effects=Render 1st Person Effects +twilightforest.config.first_person_effects.tooltip=Controls whether various effects from the mod are rendered while in first-person view. Turn this off if you find them distracting. + +twilightforest.config.origin_dimension=Origin Dimension +twilightforest.config.origin_dimension.tooltip=The dimension you can always travel to the Twilight Forest from, as well as the dimension you will return to. Defaults to the overworld. +twilightforest.config.portals_in_other_dimensions=Portals in other dimensions +twilightforest.config.portals_in_other_dimensions.tooltip=Allow portals to the Twilight Forest to be made outside of the 'origin' dimension. May be considered an exploit. +twilightforest.config.admin_portals=Admin-Only Twilight Portals +twilightforest.config.admin_portals.tooltip=Allow portals only for admins (Operators). This severely reduces the range in which the mod usually scans for valid portal conditions, and it scans near ops only. +twilightforest.config.portals=Disable Twilight Portals +twilightforest.config.portals.tooltip=Disable Twilight Forest portal creation entirely. Provided for server operators looking to restrict action to the dimension. +twilightforest.config.portal_creator=Portal Creation Item +twilightforest.config.portal_creator.tooltip=Registry String IDs of items used to create the Twilight Forest Portal. (domain:regname:meta) meta is optional. +twilightforest.config.portal_lighting=Portal Creation Lightning Fire +twilightforest.config.portal_lighting.tooltip=Set this true if you want the lightning that zaps the portal to not set things on fire. For those who don't like fun. +twilightforest.config.portal_return=Should Portals generate as a two-way portal +twilightforest.config.portal_return.tooltip=If false, the return portal will require the activation item. +twilightforest.config.check_portal_destination=Pre-Check Portal Destination +twilightforest.config.check_portal_destination.tooltip=Determines if new portals should be pre-checked for safety. If enabled, portals will fail to form rather than redirect to a safe alternate destination.\nNote that enabling this also reduces the rate at which portal formation checks are performed. + +twilightforest.config.progression_default=Progression Rule Default +twilightforest.config.progression_default.tooltip=Sets the default value of the game rule controlling enforced progression. + +twilightforest.config.uncrafting=Disable Uncrafting in Uncrafting Table +twilightforest.config.uncrafting.tooltip=Disable the uncrafting function of the uncrafting table. Provided as an option when interaction with other mods produces exploitable recipes. + +twilightforest.config.antibuilder_blacklist=Antibuilder Blacklist +twilightforest.config.antibuilder_blacklist.tooltip=Anti-Builder blacklist. (domain:block:meta) meta is optional. + +twilightforest.config.animate_trophyitem=Rotate Trophy Heads on Item model +twilightforest.config.animate_trophyitem.tooltip=Rotate trophy heads on item model. Has no performance impact at all. For those who don't like fun. + +twilightforest.config.shield_parry=Shield Parrying +twilightforest.config.shield_parry.tooltip=We recommend downloading the Shield Parry mod for parrying, but these controls remain for without. +twilightforest.config.parry_non_twilight=Parry non-Twilight projectiles +twilightforest.config.parry_non_twilight.tooltip=Set to true to parry non-Twilight projectiles. We recommend downloading the Shield Parry mod instead. +twilightforest.config.parry_window_arrow=Timing Windowspan for Arrows +twilightforest.config.parry_window_arrow.tooltip=The amount of ticks after raising a shield that makes it OK to parry an arrow. There is 20 ticks in 1 second. +twilightforest.config.parry_window_fireball=Timing Windowspan for Fireballs +twilightforest.config.parry_window_fireball.tooltip=The amount of ticks after raising a shield that makes it OK to parry a fireball. There is 20 ticks in 1 second. +twilightforest.config.parry_window_throwable=Timing Windowspan for Throwables +twilightforest.config.parry_window_throwable.tooltip=The amount of ticks after raising a shield that makes it OK to parry a thrown item. There is 20 ticks in 1 second. +twilightforest.config.shieldParryTicksBeam=Timing Windowspan for Beams??? +twilightforest.config.shieldParryTicksBeam.tooltip=??? + +twilightforest.config.loading_screen=Loading Screen +twilightforest.config.loading_screen.tooltip=Client only: Controls for the Loading screen +twilightforest.config.loading_icon_enable=Enable Loading Icon Animation +twilightforest.config.loading_icon_enable.tooltip=Wobble the Loading icon. Has no performance impact at all. For those who don't like fun. +twilightforest.config.loading_screen_swap_frequency=Loading Screen switching +twilightforest.config.loading_screen_swap_frequency.tooltip=How many ticks between each loading screen change. Set to 0 to not cycle at all. +twilightforest.config.loading_icon_wobble_bounce_frequency=Icon Animation Speed +twilightforest.config.loading_icon_wobble_bounce_frequency.tooltip=Frequency of wobble and bounce. +twilightforest.config.loading_icon_scale=Icon Scaling +twilightforest.config.loading_icon_scale.tooltip=Scale of whole bouncy loading icon. +twilightforest.config.loading_icon_bounciness=Icon Bounciness +twilightforest.config.loading_icon_bounciness.tooltip=How much the loading icon bounces. +twilightforest.config.loading_icon_tilting=Icon Wobbliness +twilightforest.config.loading_icon_tilting.tooltip=How far the loading icon wobbles. +twilightforest.config.loading_icon_tilt_pushback=Icon Tilt Offset +twilightforest.config.loading_icon_tilt_pushback.tooltip=Pushback value to re-center the wobble of loading icon. + +# Books +twilightforest.book.lichtower.1=\u00A78[[An explorer's notebook, gnawed on by monsters]]\u00A70\n\nI have begun examining the strange aura surrounding this tower. The bricks of the tower are protected by a curse, stronger than any I've seen before. The magic from the curse +twilightforest.book.lichtower.2=is boiling off into the surrounding area.\n\nIn my homeland I would have many options for dealing with this magic, but here my supplies are limited. I shall have to research... +twilightforest.book.lichtower.3=\u00A78[[Many entries later]]\u00A70\n\nA breakthrough! In my journeys I sighted a huge snake-like monster in a decorated courtyard. Nearby, I picked up a worn down, discarded green scale.\n\nThe magic in the scale seems to have the +twilightforest.book.lichtower.4=curse-breaking properties I need, but the magic is too dim. I may need to acquire a fresher specimen, directly from the creature. + +twilightforest.book.labyrinth.1=\u00A78[[An explorer's notebook, written on waterproof paper]]\u00A70\n\nThe mosquitoes in this swamp are vexing, but strange. The vast majority of them seem to have no natural source, nor do they seem to have a role in the local ecology. I have begun to +twilightforest.book.labyrinth.2=suspect that they are some kind of magical curse.\n\n\u00A78[[Next entry]]\u00A70\n\nNow that I have encountered a protection spell on the ruined labyrinth here, I consider my suspicions confirmed. Both the protection +twilightforest.book.labyrinth.3=spell and the mosquitoes are a curse. This curse seems to have a different source from the others I have encountered. I will have to research further...\n\n\u00A78[[Next entry]]\u00A70\n\nThe curse seems to +twilightforest.book.labyrinth.4=be of a type too powerful for one being alone to produce. Several wizards working in combination would be necessary.\n\nIf one of the wizards stopped contributing, the whole of the curse over the entire swamp would fall. Strangely, +twilightforest.book.labyrinth.5=my divinations do not show signs of any nearby living wizards. I did see something interesting in one of the nearby pointy-roofed towers though... + +twilightforest.book.hydralair.1=\u00A78[[An explorer's notebook, written on fireproof paper]]\u00A70\n\nFire is a trivial obstacle for a master explorer such as myself. I have traversed seas of fire, and swam through oceans of lava. The burning air here is an interesting variation, +twilightforest.book.hydralair.2=but ultimately no hinderance.\n\nWhat does stop me though is that I have encountered another protection spell, this time surrounding a mighty creature that must be king of this fire swamp. This is not the first protection spell I have +twilightforest.book.hydralair.3=encountered, and I am beginning to unravel the mysteries of how they work.\n\nIf this spell is like the others, it will be sustained by a powerful creature nearby. Surrounding the fire swamp are several wet swamps, and under those +twilightforest.book.hydralair.4=swamps are labyrinths full of minotaurs. The logical choice to bind such a spell to would be some sort of powerful minotaur, different in some way from the others that surround it... + +twilightforest.book.tfstronghold.1=\u00A78[[An explorer's notebook, written on faintly glowing paper]]\u00A70\n\nThe tendrils of darkness surrounding this area are just a manifestation of a protective spell over the entire dark forest. The spell causes blindness, which is quite vexing. I have +twilightforest.book.tfstronghold.2=seen several interesting things in the area and would like to keep exploring.\n\n\u00A78[[Next entry]]\u00A70\n\nI have found ruins in the dark forest. They belong to a stronghold, of a type usually inhabited by knights. Rather than +twilightforest.book.tfstronghold.3=knights though, this stronghold is full of goblins. They wear knightly armor, but their behavior is most un-knightly.\n\n\u00A78[[Next entry]]\u00A70\n\nDeep in the ruins, I have found a pedestal. The pedestal seems to be of a type that +twilightforest.book.tfstronghold.4=knights would place trophies on to prove their strength.\n\Obtaining a powerful scepter would seem to weaken the curse on the dark forest, and placing a trophy associated with a powerful creature on the pedestal would likely grant access into the +twilightforest.book.tfstronghold.5=main part of the stronghold. + +twilightforest.book.darktower.1=\u00A78[[An explorer's notebook that seems to have survived an explosion]]\u00A70\n\nThis tower clearly has mechanisms that are not responding to me. Their magic almost yearns to acknowledge my touch, but it cannot. It is if the devices of the tower are being +twilightforest.book.darktower.2=suppressed by a powerful group of beings nearby.\n\n\u00A78[[Next entry]]\u00A70\n\nThe magic seems to emanate from deep within the strongholds nearby. It can't come from the goblins, as their magic is charming, but unfocused. There +twilightforest.book.darktower.3=must still be some force still active in the strongholds.\n\n\u00A78[[Next entry]]\u00A70\n\nMy analysis indicates that it comes from several sources, operating as a group. I will head back to the stronghold after I resupply... + +twilightforest.book.yeticave.1=\u00A78[[An explorer's notebook, covered in frost]]\u00A70\n\nThe blizzard surrounding these snowy lands is unceasing. This is no ordinary snowfall--this is a magical phenomenon. I will have to conduct experiments to find +twilightforest.book.yeticave.2=what is capable of causing such an effect.\n\n\u00A78[[Next entry]]\u00A70\n\nThe curse seems to be of a type too powerful for one being alone to produce. Several wizards working in combination would be necessary. +twilightforest.book.yeticave.3=If one of the wizards stopped contributing, the blizzard would calm. Strangely, my divinations do not show signs of any nearby living wizards. I did see something interesting in one of the nearby pointy-roofed towers though... + +twilightforest.book.icetower.1=\u00A78[[An explorer's notebook, caked in ice]]\u00A70\n\nI overcame one blizzard, only to run into this terrible ice storm atop the glacier. My explorations have shown me the splendor of an ice palace, shining with the colors of the polar aurora. It +twilightforest.book.icetower.2=all seems protected by some sort of curse.\n\n\u00A78[[Next entry]]\u00A70\n\nI am no novice. This curse is fed by the power of a creature nearby. The cause of the curse surrounding the fire swamp was built off the power of the leader of the +twilightforest.book.icetower.3=minotaurs nearby.\n\nSurrounding this glacier, there are masses of yetis. Perhaps the yetis have some sort of leader... + +twilightforest.book.trollcave.1=\u00A78[[An explorer's notebook, damaged by acid]]\u00A70\n\nThere seems to be no way to protect myself from the toxic rainstorm surrounding this area. In my brief excursions, I have also encountered another protection spell, similar to the +twilightforest.book.trollcave.2=others I have witnessed. The spell must be connected to the toxic storm in some way. Further research to follow...\n\n\u00A78[[Next entry]]\u00A70\n\nSuch supreme weather magic must be the result of +twilightforest.book.trollcave.3=multiple undefeated great evils in this world. My studies contain several clues pointing at a searing swamp, a forest coated in deep darkness, and a realm coated in snow. + +twilightforest.book.unknown.1=\u00A78[[This book shows signs of having been copied many times]]\u00A70\n\nI cannot explain the field surrounding this structure, but the magic is powerful. If this curse is like the others, then the answer to unlocking it lies elsewhere. Perhaps there is +twilightforest.book.unknown.2=something I have left undone, or some monster I have yet to defeat. I will have to turn back. I will return to this place later, to see if anything has changed. + +# Fluid + +fluid.fierymetal=Molten Fiery +fluid.knightmetal=Molten Knightmetal +fluid.fiery_essence=Fiery Essence + +# TCon + +material.nagascale.name=Naga Scale +material.steeleaf.name=Steeleaf +material.fierymetal.name=Fiery +material.knightmetal.name=Knightly +material.raven_feather.name=Raven Feather + +modifier.twilit.name=Twilit +modifier.twilit.desc=§oThe Twilight Forest's illuminating blessing.§r\nSpeedier in the Twilight Forest.\nMore damage outside the Twilight Forest. +modifier.twilit.extra.speed=Mining Speed in Twilight Forest: +%s +modifier.twilit.extra.damage=Damage outside the Twilight Forest: +%s +modifier.precipitate.name=Precipitate +modifier.precipitate.desc=§oThe last standing escape plan.§r\nThe less health you have, the speedier it is! +modifier.synergy.name=Synergy +modifier.synergy.desc=§oLook ma, no moss!§r\nWill repair itself if you have Steeleaves in your hotbar. +modifier.stalwart.name=Stalwart +modifier.stalwart.desc=§oThe Brave and Bold.§r\nHitting an entity can make you feel emboldened. +modifier.veiled.name=Veiled +modifier.veiled.desc=§oLike a Specter!§r\nProjectile will be invisible. + +# Immersive Engineering +item.tfEngineeringShader=Twilit Shader: %s +item.tfEngineeringShaderBag=Twilit %s Shader Bag + +twilightforest.shader.twilight=Twilight + +twilightforest.shader.snakestone=Snakestone +twilightforest.shader.naga=Naga +twilightforest.shader.lich=Lich + +twilightforest.shader.mazestone=Mazestone +twilightforest.shader.minoshroom=Minoshroom +twilightforest.shader.hydra=Hydra + +twilightforest.shader.underbrick=Underbrick +twilightforest.shader.knight_phantom=Knight Phantom +twilightforest.shader.towerwood=Towerwood +twilightforest.shader.ur-ghast=Ur-Ghast + +twilightforest.shader.alpha_yeti=Alpha Yeti +twilightforest.shader.auroralized=Auroralized +twilightforest.shader.snow_queen=Snow Queen + +twilightforest.shader.final_castle=Final Castle \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/fr_fr.lang b/src/main/resources/assets/twilightforest/lang/fr_fr.lang new file mode 100644 index 0000000000..c191cdb84a --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/fr_fr.lang @@ -0,0 +1,841 @@ +#PARSE_ESCAPES + +itemGroup.twilightForest=Twilight Forest + +# ADVANCEMENTS +advancement.twilightforest.root.desc=Entrer dans le bois magique et mystérieux qu'est la Twilight Forest. + +# General progression +advancement.twilightforest.hedge=Bug Stomper +advancement.twilightforest.hedge.desc=Vaincre une araignée dans un %s. + +advancement.twilightforest.hill1=Ces bottes sont les miennes ! +advancement.twilightforest.hill1.desc=Vaincre un %s dans une petite %s. +advancement.twilightforest.hill2=Quel était ce bruit ? +advancement.twilightforest.hill2.desc=Vaincre un %s dans une %s moyenne. +advancement.twilightforest.hill3=Je te vois +advancement.twilightforest.hill3.desc=Vaincre un %s dans une grande %s. + +advancement.twilightforest.quest_ram=Consomme des bêêê ! +advancement.twilightforest.quest_ram.desc=Donner au %s ce qui lui manque. + +# Map +advancement.twilightforest.magic_map_focus=Il écrit avec du feu +advancement.twilightforest.magic_map_focus.desc=Fabriquer le %s avec une %s, une %s, et une %s. +advancement.twilightforest.magic_map=Je peux voir pour toujours +advancement.twilightforest.magic_map.desc=Fabriquer la %s. +advancement.twilightforest.maze_map=Trouver la sortie +advancement.twilightforest.maze_map.desc=Fabriquer la %s après avoir obtenu le foyer du labyrinthe. +advancement.twilightforest.ore_map=Comment cela peut-il en valoir la peine ? +advancement.twilightforest.ore_map.desc=Fabriquer la %s. + +# Mainline beginning progression +advancement.twilightforest.twilight_hunter=Le silence de la forêt +advancement.twilightforest.twilight_hunter.desc=Chasser un animal de la Twilight Forest. + +advancement.twilightforest.kill_naga=Il est temps de niveler les écailles +advancement.twilightforest.kill_naga.desc=Tuer le %s dans sa cour forestière et obtenir des %s pour surmonter la barrière magique entourant la tour du Liche. +advancement.twilightforest.naga_armors=Armurier du Nâga +advancement.twilightforest.naga_armors.desc=Fabriquer un plastron et des jambières en %s. + +advancement.twilightforest.kill_lich=Faire sortir vos morts +advancement.twilightforest.kill_lich.desc=Tuer le %s en haut de sa tour et récupérer un sceptre pour éliminer les moustiques toxiques du marais, voir à travers l'obscurité aveuglante de la malédiction de la forêt noire et résister au froid de la forêt enneigée. +advancement.twilightforest.lich_scepters=Par nos pouvoirs combinés ! +advancement.twilightforest.lich_scepters.desc=Acquérir les quatre sceptres de pouvoir. + +# Swamp Progression +advancement.twilightforest.progress_labyrinth=Puissant Stroganoff +advancement.twilightforest.progress_labyrinth.desc=Le ragoût de viande et de champignons vous réchauffe agréablement, juste assez pour que vous vous sentiez acclimaté pour vous aventurer dans le marais de feu. +advancement.twilightforest.kill_hydra=Tueur d'Hydre +advancement.twilightforest.kill_hydra.desc=Vaincre le puissant %s et devenez plus puissant. +advancement.twilightforest.mazebreaker=Casser le labyrinthe +advancement.twilightforest.mazebreaker.desc=Trouver la pioche %s dans la voûte secrète du labyrinthe. +advancement.twilightforest.hydra_chop=Tranche d'Hydre ! +advancement.twilightforest.hydra_chop.desc=Se goinfrer de viande super-puissante d'%s lorsque votre barre de nourriture est vide. + +# Dark Forest Progression +advancement.twilightforest.progress_trophy_pedestal=Champion de trophée +advancement.twilightforest.progress_trophy_pedestal.desc=Revendiquez votre titre en plaçant un trophée sur le piédestal des ruines de la forêt noire. +advancement.twilightforest.progress_knights=Acclimatation à la carminite +advancement.twilightforest.progress_knights.desc=Tuer les fantômes agités dans la tombe du chevalier et les appareils de la tour carminite vous obéirons. +advancement.twilightforest.ghast_trap=Quelque chose d'étrange +advancement.twilightforest.ghast_trap.desc=Tuer les %s autour d'un %s et l'activer pour torturer l'%s depuis le ciel ! +advancement.twilightforest.progress_ur_ghast=Larmes de feu +advancement.twilightforest.progress_ur_ghast.desc=Toucher les larmes rouges ardentes de l'%s. + +advancement.twilightforest.experiment_115=Viande mystère ? +advancement.twilightforest.experiment_115.desc=Ça ressemble à du gâteau par contre... +advancement.twilightforest.experiment_115_2=Faire une note : énorme succès ! +advancement.twilightforest.experiment_115_2.desc=C'est tellement délicieux et humide ! + +# Snow Forest Progression +advancement.twilightforest.progress_yeti=Fourrure d'Alpha +advancement.twilightforest.progress_yeti.desc=Améliorez votre garde-robe avec cette douce fourrure du %s, vous protégeant du froid du glacier. +advancement.twilightforest.progress_glacier=Cieux clairs +advancement.twilightforest.progress_glacier.desc=Vaincre la %s au sommet du %s. +advancement.twilightforest.arctic_dyed=Être à la mode +advancement.twilightforest.arctic_dyed.desc=Teindre les quatre pièces de l'armure arctique. + +# Mid-way Misc. Stuff +advancement.twilightforest.glass_sword=Un coup étonnant +advancement.twilightforest.glass_sword.desc=J'espère que tu as fait bon usage de cela. + +advancement.twilightforest.fiery_set=Des litres de sang et de larmes +advancement.twilightforest.fiery_set.desc=Manier une arme ou outil ardent en portant au moins une pièce d'armure ardente. + +# Highlands +advancement.twilightforest.progress_merge=Épreuve de force ultime +advancement.twilightforest.progress_merge.desc=Tuer l'%s, l'%s, et la %s pour nettoyer la pluie acide et vous installer dans les Hauts Plateaux. +advancement.twilightforest.progress_troll=Je souhaite plus de brûlures +advancement.twilightforest.progress_troll.desc=Trouver la %s dans les caves de Trolls, et vous pourrez brûler les barrières épineuses. +advancement.twilightforest.progress_thorns=Passer les épines [NYI] +advancement.twilightforest.progress_thorns.desc=Passez les Thornlands, et déverrouillez la porte du château. +advancement.twilightforest.progress_castle=Très château [NYI] +advancement.twilightforest.progress_castle.desc=Que pourrait-il y avoir dans ce château ?!? + +# Collections +advancement.twilightforest.twilight_dining=Dînons au coucher du soleil +advancement.twilightforest.twilight_dining.desc=Manger TOUS les aliments exclusifs à la Twilight Forest. +advancement.twilightforest.experiment_115_3=Manger 115 tous les jours, pendant 115 ans +advancement.twilightforest.experiment_115_3.desc=manger l'expérience cent quinze toute la journée, pour toujours, cent quinze fois l'expérience cent quinze, expérience cent quinze point com, double-v double-v double-v point expérience cent quinze point com, cent quinze ans, chaque minute expérience cent quinze point com, double-v double-v double-v point cent quinze +advancement.twilightforest.arborist=Dendrologue maniaque +advancement.twilightforest.arborist.desc=Préparez vos haches et cisailles. Fouiller chaque coin et recoin et récupérer tout ce qui provient des arbres ! Fabriquez, récupérez, obtenez chaque dalle... pousse... feuilles.... plus… TOUT. TOUT ! + +twilightforest.twilight_portal.unsafe=Ça n'a pas l'air très sûr ici... +twilightforest.trophy_pedestal.ineligible=Vous êtes indigne. +twilightforest.ore_meter.range=Rayon : %s, Origine : [%s, %s] +twilightforest.ore_meter.exposed=Exposé : %s +twilightforest.scepter_charges=%d charge(s) restante(s) + +# Commands +commands.tffeature.usage=/tffeature +commands.tffeature.not_in_twilight_forest=Vous n'êtes pas dans la dimension Twilight Forest +commands.tffeature.nearest=La structure la plus proche est %s +commands.tffeature.center=Centre de la fonctionnalité : %s +commands.tffeature.chunk=Être dans le chunk de la fonctionnalité : %s +commands.tffeature.structure.inside=Vous êtes dans la structure de cette fonctionnalité +commands.tffeature.structure.outside=Vous n'êtes pas dans la structure pour cette fonctionnalité +commands.tffeature.structure.required=Vous n'êtes pas dans une structure +commands.tffeature.structure.conquer.status=Drapeau de conquête de structure : %s +commands.tffeature.structure.conquer.update=Le drapeau de conquête de structure était %s, changé pour %s +commands.tffeature.locate.usage=/tffeature locate + +# Blocks +tile.twilightforest.Log.0.name=Bois de chêne Twilight +tile.twilightforest.Log.1.name=Bois d'arbre canopée +tile.twilightforest.Log.2.name=Bois de mangrove +tile.twilightforest.Log.3.name=Bois sombre +tile.twilightforest.Leaves.0.name=Feuilles de chêne Twilight +tile.twilightforest.Leaves.1.name=Feuilles d'arbre canopée +tile.twilightforest.Leaves.2.name=Feuilles de mangrove +tile.twilightforest.Leaves.3.name=Feuilles de chêne arc-en-ciel +tile.twilightforest.Firefly.name=Luciole +tile.twilightforest.Cicada.name=Cigale +tile.twilightforest.Cicada.desc=Et si cela pouvait être lancé sur quelqu'un avec un pistolet... ? +item.twilightforest.Portal.name=Portail de la Twilight Forest +tile.twilightforest.Portal.name=Portail de la Twilight Forest +tile.twilightforest.Mazestone.0.name=Pierre du labyrinthe +tile.twilightforest.Mazestone.1.name=Brique du labyrinthe +tile.twilightforest.Mazestone.2.name=Pierre du labyrinthe polie +tile.twilightforest.Mazestone.3.name=Brique de pierre décorée du labyrinthe +tile.twilightforest.Mazestone.4.name=Brique de pierre craquelée du labyrinthe +tile.twilightforest.Mazestone.5.name=Brique de pierre moussue du labyrinthe +tile.twilightforest.Mazestone.6.name=Mosaïque de pierre du labyrinthe +tile.twilightforest.Mazestone.7.name=Bordure de pierre du labyrinthe +tile.twilightforest.Mazestone.8.name=Plafond de pierre du labyrinthe +tile.twilightforest.Hedge.0.name=Haie +tile.twilightforest.Hedge.1.name=Feuilles de bois sombre +tile.twilightforest.BossSpawner.0.name=Générateur de Nâga +tile.twilightforest.BossSpawner.1.name=Générateur de Liche +tile.twilightforest.BossSpawner.2.name=Générateur d'Hydre +tile.twilightforest.BossSpawner.3.name=Générateur d'Ur-Ghast +tile.twilightforest.BossSpawner.4.name=Générateur de Chevalier fantôme +tile.twilightforest.BossSpawner.5.name=Générateur de Reine des Neiges +tile.twilightforest.BossSpawner.6.name=Générateur de Minoshroom +tile.twilightforest.BossSpawner.7.name=Générateur de Yéti Alpha +tile.twilightforest.FireflyJar.name=Bocal à luciole +tile.twilightforest.Plant.0.name=Mousse +tile.twilightforest.Plant.1.name=Podophyllum +tile.twilightforest.Plant.2.name=Trèfle à quatre feuilles [WIP] +tile.twilightforest.Plant.3.name=Crosse de fougère +tile.twilightforest.Plant.4.name=Champignon lumineux +tile.twilightforest.Plant.5.name=Herbe de Forêt +tile.twilightforest.Plant.6.name=Arbuste mort +tile.twilightforest.Plant.7.name=Plante de torche des baies +tile.twilightforest.Plant.8.name=Brins de racine +tile.twilightforest.Roots.0.name=Racines +tile.twilightforest.Roots.1.name=Racines vivantes +tile.twilightforest.UncraftingTable.name=Établi de défabrication +tile.twilightforest.FireJet.0.name=Bloc fumant +tile.twilightforest.FireJet.1.name=Fumeur recouvert +tile.twilightforest.FireJet.2.name=Fumeur recouvert +tile.twilightforest.FireJet.3.name=Jet de feu +tile.twilightforest.FireJet.4.name=Jet de feu bouillant +tile.twilightforest.FireJet.5.name=Jet de feu flamboyant +tile.twilightforest.FireJet.6.name=Jet de feu recouvert +tile.twilightforest.FireJet.7.name=Jet de feu recouvert bouillant +tile.twilightforest.FireJet.8.name=Jet de feu recouvert flamboyant +tile.twilightforest.Nagastone.0.name=Tête de nâgastone +tile.twilightforest.Nagastone.1.name=Nâgastone +tile.twilightforest.Sapling.name=Pousse de la Twilight +tile.twilightforest.Sapling.0.name=Pousse de chêne de la Twilight faible +tile.twilightforest.Sapling.1.name=Pousse d'arbre de canopée +tile.twilightforest.Sapling.2.name=Pousse de mangrove de la Twilight +tile.twilightforest.Sapling.3.name=Pousse d'arbre sombre +tile.twilightforest.Sapling.4.name=Pousse de chêne de la Twilight robuste +tile.twilightforest.Sapling.5.name=Pousse d'arbre du temps +tile.twilightforest.Sapling.6.name=Pousse d'arbre de transformation +tile.twilightforest.Sapling.7.name=Pousse d'arbre du mineur +tile.twilightforest.Sapling.8.name=Pousse d'arbre de Sorting +tile.twilightforest.Sapling.9.name=Pousse de chêne arc-en-ciel +tile.twilightforest.Moonworm.name=Ver de lune +tile.twilightforest.MagicLog.0.name=Bois du temps +tile.twilightforest.MagicLog.1.name=Transwood +tile.twilightforest.MagicLog.2.name=Bois du mineur +tile.twilightforest.MagicLog.3.name=Bois de Sorting +tile.twilightforest.MagicLogSpecial.0.name=Horloge de bois du temps +tile.twilightforest.MagicLogSpecial.1.name=Coeur de transformation +tile.twilightforest.MagicLogSpecial.2.name=Coeur du mineur +tile.twilightforest.MagicLogSpecial.3.name=Moteur du bois de Sorting +tile.twilightforest.MagicLeaves.0.name=Feuilles d'arbre du temps +tile.twilightforest.MagicLeaves.1.name=Feuilles d'arbre de transformation +tile.twilightforest.MagicLeaves.2.name=Feuilles d'arbre du mineur +tile.twilightforest.MagicLeaves.3.name=Feuilles d'arbre de Sorting +tile.twilightforest.TowerStone.0.name=Planches de Towerwood +tile.twilightforest.TowerStone.1.name=Towerwood recouvert +tile.twilightforest.TowerStone.2.name=Towerwood craquelé +tile.twilightforest.TowerStone.3.name=Towerwood moussu +tile.twilightforest.TowerStone.4.name=Towerwood infesté +tile.twilightforest.TowerDevice.0.name=Bloc de réapparition +tile.twilightforest.TowerDevice.1.name=Bloc de réapparition actif +tile.twilightforest.TowerDevice.2.name=Bloc de disparition +tile.twilightforest.TowerDevice.3.name=Bloc de disparition actif +tile.twilightforest.TowerDevice.4.name=Bloc de disparition verrouillé +tile.twilightforest.TowerDevice.5.name=Bloc de disparition déverrouillé +tile.twilightforest.TowerDevice.6.name=Constructeur carminite +tile.twilightforest.TowerDevice.7.name=Constructeur carminite actif +tile.twilightforest.TowerDevice.8.name=Constructeur carminite inactif +tile.twilightforest.TowerDevice.9.name=Anti-constructeur +tile.twilightforest.TowerDevice.10.name=Piège à Ghast +tile.twilightforest.TowerDevice.11.name=Piège à Ghast actif +tile.twilightforest.TowerDevice.12.name=Réacteur carminite +tile.twilightforest.TowerDevice.13.name=Réacteur carminite actif +tile.twilightforest.TowerTranslucent.0.name=Bloc de réapparition +tile.twilightforest.TowerTranslucent.1.name=Bloc de réapparition actif +tile.twilightforest.TowerTranslucent.2.name=Bloc de réapparition construit +tile.twilightforest.TowerTranslucent.3.name=Bloc de réapparition construit actif +tile.twilightforest.TowerTranslucent.4.name=Bloc d'anti-construction +tile.twilightforest.TowerTranslucent.5.name=Débris de réacteur carminite +tile.twilightforest.TowerTranslucent.6.name=Faux or +tile.twilightforest.TowerTranslucent.7.name=Faux diamant +tile.twilightforest.Trophy.name=Trophée de la Twilight Forest +tile.twilightforest.Shield.name=Bouclier stronghold +tile.twilightforest.TrophyPedestal.0.name=Piédestal à trophée +tile.twilightforest.TrophyPedestal.15.name=Piédestal à trophée latent +tile.twilightforest.AuroraBrick.name=Bloc d'aurore +tile.twilightforest.UnderBrick.0.name=Brique des dessous +tile.twilightforest.UnderBrick.1.name=Brique des dessous moussue +tile.twilightforest.UnderBrick.2.name=Brique des dessous craquelée +tile.twilightforest.UnderBrick.3.name=Sol de brique des dessous +tile.twilightforest.Thorns.brown.name=Épines +tile.twilightforest.Thorns.green.name=Épines vertes +tile.twilightforest.BurntThorns.name=Épines brûlées +tile.twilightforest.ThornRose.name=Rose d'épines +tile.twilightforest.Leaves3.0.name=Feuilles d'épines +tile.twilightforest.Leaves3.1.name=Feuilles d'haricot magique +tile.twilightforest.Deadrock.surface.name=Deadrock altérée +tile.twilightforest.Deadrock.cracked.name=Deadrock craquelée +tile.twilightforest.Deadrock.solid.name=Deadrock +tile.twilightforest.DarkLeaves.name=Feuilles de Deadrock +tile.twilightforest.AuroralizedGlass.name=Verre auroralisé +tile.twilightforest.AuroraPillar.name=Pilier auroralisé +tile.twilightforest.AuroraSlab.name=Dalle auroralisée +tile.twilightforest.TrollSteinn.name=Trollsteinn +tile.twilightforest.WispyCloud.name=Nuage vaporeux +tile.twilightforest.FluffyCloud.name=Nuage moelleux +tile.twilightforest.GiantCobble.name=Pierre géante +tile.twilightforest.GiantLog.name=Bois géant +tile.twilightforest.GiantLeaves.name=Feuilles géantes +tile.twilightforest.GiantObsidian.name=Obsidienne géante +tile.twilightforest.UberousSoil.name=Sol herbeux +tile.twilightforest.HugeStalk.name=Énorme tige +tile.twilightforest.HugeGloomBlock.name=Énorme champignon lumieux +tile.twilightforest.TrollVidr.name=Trollvidr +tile.twilightforest.UnripeTrollBer.name=Trollber verte +tile.twilightforest.TrollBer.name=Trollber +tile.twilightforest.TrollBer.name=Trollber +tile.twilightforest.KnightmetalBlock.name=Bloc de métal de chevalier +tile.twilightforest.HugeLilyPad.name=Énorme nénuphar +tile.twilightforest.HugeWaterLily.name=Énorme fleur à nénuphar +tile.twilightforest.Slider.0.name=Piège à glissière +tile.twilightforest.Slider.1.name=Piège à glissière 1 +tile.twilightforest.Slider.2.name=Piège à glissière 2 +tile.twilightforest.Slider.3.name=Piège à glissière 3 +tile.twilightforest.CastleBrick.0.name=Brique de château +tile.twilightforest.CastleBrick.1.name=Brique de château usée +tile.twilightforest.CastleBrick.2.name=Brique de château craquelée +tile.twilightforest.CastleBrick.3.name=Tuile de toit de château +tile.twilightforest.CastleBrick.4.name=Brique de château moussue +tile.twilightforest.CastleBrick.5.name=Brique de château épaisse +tile.twilightforest.CastleStairsBrick.name=Escaliers en pierre de château +tile.twilightforest.CastleStairsWorn.name=Escaliers en pierre de château usée +tile.twilightforest.CastleStairsCracked.name=Escaliers en pierre de château craquelée +tile.twilightforest.CastleStairsMossy.name=Escaliers en pierre de château moussue +tile.twilightforest.CastleDoor.0.name=Porte de château jaune +tile.twilightforest.CastleDoor.1.name=Porte de château violette +tile.twilightforest.CastleDoor.2.name=Porte de château rose +tile.twilightforest.CastleDoor.3.name=Porte de château bleue +tile.twilightforest.CastleMagic.0.name=Rune de brique de château rose +tile.twilightforest.CastleMagic.1.name=Rune de brique de château bleue +tile.twilightforest.CastleMagic.2.name=Rune de brique de château jaune +tile.twilightforest.CastleMagic.3.name=Rune de brique de château violette +tile.twilightforest.CastlePillar.0.name=Pilier de brique de château recouvert +tile.twilightforest.CastlePillar.1.name=Tuille de brique de château recouverte +tile.twilightforest.CastlePillar.2.name=Pilier épais de brique de château +tile.twilightforest.CastlePillar.3.name=Tuille épaisse de brique de château +tile.twilightforest.CastleStairs.0.name=Escaliers en brique de château recouverts +tile.twilightforest.CastleStairs.8.name=Escaliers épais en brique de château +tile.twilightforest.ForceField.0.name=Champ de force violet +tile.twilightforest.ForceField.1.name=Champ de force rose +tile.twilightforest.ForceField.2.name=Champ de force orange +tile.twilightforest.ForceField.3.name=Champ de force vert +tile.twilightforest.ForceField.4.name=Champ de force bleu +tile.twilightforest.BlockOfStorage.0.name=Bloc de bois de fer +tile.twilightforest.BlockOfStorage.1.name=Bloc de métal ardent +tile.twilightforest.BlockOfStorage.2.name=Bloc de Stealeaf +tile.twilightforest.BlockOfStorage.3.name=Bloc de fourrure arctique +tile.twilightforest.BlockOfStorage.4.name=Bloc de carminite +tile.twilightforest.CinderFurnaceIdle.name=Four à cendres [NYI] +tile.twilightforest.CinderLog.name=Bois de cendres [NYI] +tile.twilightforest.MiniatureStructure=%s miniature [NYI] +tile.twilightforest.SpiralBricks.name=Pierre taillée en spirale +tile.twilightforest.BlockOfLapisTF.name=Bloc de lapis [NYI] +tile.twilightforest.EtchedNagastone.name=Nâgastone gravée +tile.twilightforest.NagastonePillar.name=Pilier de nâgastone +tile.twilightforest.NagastoneStairs.0.name=Escaliers en nâgastone (gauche) +tile.twilightforest.NagastoneStairs.8.name=Escaliers en nâgastone (droite) +tile.twilightforest.EtchedNagastoneMossy.name=Nâgastone gravée moussue +tile.twilightforest.NagastonePillarMossy.name=Pilier de nâgastone moussue +tile.twilightforest.NagastoneStairsMossy.0.name=Escaliers de nâgastone moussue (gauche) +tile.twilightforest.NagastoneStairsMossy.8.name=Escaliers de nâgastone moussue (droite) +tile.twilightforest.EtchedNagastoneWeathered.name=Nâgastone gravée en ruine +tile.twilightforest.NagastonePillarWeathered.name=Pilier en nâgastone en ruine +tile.twilightforest.NagastoneStairsWeathered.0.name=Escaliers en nâgastone altérée (gauche) +tile.twilightforest.NagastoneStairsWeathered.8.name=Escaliers en nâgastone altérée (droite) +tile.twilightforest.IronLadder.name=Échelle en fer +tile.twilightforest.TerrorCottaCircle.name=Terrorcotta (circulaire) +tile.twilightforest.TerrorCottaDiagonal.name=Terrorcotta (diagonale) + +tile.twilightforest.CanopyPlanks.name=Planches de canopée +tile.twilightforest.CanopyStairs.name=Escaliers en canopée +tile.twilightforest.CanopySlab.name=Dalle en canopée +tile.twilightforest.CanopyButton.name=Bouton en canopée +tile.twilightforest.CanopyFence.name=Barrière en canopée +tile.twilightforest.CanopyGate.name=Portillon en canopée +tile.twilightforest.CanopyPlate.name=Plaque de pression en canopée +tile.twilightforest.CanopyTrapDoor.name=Trappe en canopée +item.tile.twilightforest.CanopyDoor.name=Porte en canopée + +tile.twilightforest.DarkPlanks.name=Planches de bois sombre +tile.twilightforest.DarkStairs.name=Escaliers en bois sombre +tile.twilightforest.DarkSlab.name=Dalle en bois sombre +tile.twilightforest.DarkButton.name=Bouton en bois sombre +tile.twilightforest.DarkFence.name=Barrière en bois sombre +tile.twilightforest.DarkGate.name=Portillon en bois sombre +tile.twilightforest.DarkPlate.name=Plaque de pression en bois sombre +tile.twilightforest.DarkTrapDoor.name=Trappe en bois sombre +item.tile.twilightforest.DarkDoor.name=Porte en bois sombre + +tile.twilightforest.MangrovePlanks.name=Planches de mangrove +tile.twilightforest.MangroveStairs.name=Escaliers en mangrove +tile.twilightforest.MangroveSlab.name=Dalle en mangrove +tile.twilightforest.MangroveButton.name=Bouton en mangrove +tile.twilightforest.MangroveFence.name=Barrière en mangrove +tile.twilightforest.MangroveGate.name=Portillon en mangrove +tile.twilightforest.MangrovePlate.name=Plaque de pression en mangrove +tile.twilightforest.MangroveTrapDoor.name=Trappe en mangrove +item.tile.twilightforest.MangroveDoor.name=Porte en mangrove + +tile.twilightforest.TwilightOakPlanks.name=Planches de bois de chêne Twilight +tile.twilightforest.TwilightOakStairs.name=Escaliers en bois de chêne Twilight +tile.twilightforest.TwilightOakSlab.name=Dalle en bois de chêne Twilight +tile.twilightforest.TwilightOakButton.name=Bouton en bois de chêne Twilight +tile.twilightforest.TwilightOakFence.name=Barrière en bois de chêne Twilight +tile.twilightforest.TwilightOakGate.name=Portillon en bois de chêne Twilight +tile.twilightforest.TwilightOakPlate.name=Plaque de pression en bois de chêne Twilight +tile.twilightforest.TwilightOakTrapDoor.name=Trappe en bois de chêne Twilight +item.tile.twilightforest.TwilightOakDoor.name=Porte en bois de chêne Twilight + +tile.twilightforest.TimePlanks.name=Planches de bois du temps +tile.twilightforest.TimeStairs.name=Escaliers en bois du temps +tile.twilightforest.TimeSlab.name=Dalle en bois du temps +tile.twilightforest.TimeButton.name=Bouton en bois du temps +tile.twilightforest.TimeFence.name=Barrière en bois du temps +tile.twilightforest.TimeGate.name=Portillon en bois du temps +tile.twilightforest.TimePlate.name=Plaque de pression en bois du temps +tile.twilightforest.TimeTrapDoor.name=Trappe en bois du temps +item.tile.twilightforest.TimeDoor.name=Porte en bois du temps + +tile.twilightforest.TransPlanks.name=Planches de bois de transformation +tile.twilightforest.TransStairs.name=Escaliers en bois de transformation +tile.twilightforest.TransSlab.name=Dalle en bois de transformation +tile.twilightforest.TransButton.name=Bouton en bois de transformation +tile.twilightforest.TransFence.name=Barrière en bois de transformation +tile.twilightforest.TransGate.name=Portillon en bois de transformation +tile.twilightforest.TransPlate.name=Plaque de pression en bois de transformation +tile.twilightforest.TransTrapDoor.name=Trappe en bois de transformation +item.tile.twilightforest.TransDoor.name=Porte en bois de transformation + +tile.twilightforest.MinePlanks.name=Planches de bois de mine +tile.twilightforest.MineStairs.name=Escaliers en bois de mine +tile.twilightforest.MineSlab.name=Dalle en bois de mine +tile.twilightforest.MineButton.name=Bouton en bois de mine +tile.twilightforest.MineFence.name=Barrière en bois de mine +tile.twilightforest.MineGate.name=Portillon +tile.twilightforest.MinePlate.name=Plaque de pression en bois de mine +tile.twilightforest.MineTrapDoor.name=Trappe en bois de mine +item.tile.twilightforest.MineDoor.name=Porte en bois de mine + +tile.twilightforest.SortPlanks.name=Planches de Sortingwood +tile.twilightforest.SortStairs.name=Escaliers en Sortingwood +tile.twilightforest.SortSlab.name=Dalle en Sortingwood +tile.twilightforest.SortButton.name=Bouton en Sortingwood +tile.twilightforest.SortFence.name=Barrière en Sortingwood +tile.twilightforest.SortGate.name=Portillon en Sortingwood +tile.twilightforest.SortPlate.name=Plaque de pression en Sortingwood +tile.twilightforest.SortTrapDoor.name=Trappe en Sortingwood +item.tile.twilightforest.SortDoor.name=Porte en Sortingwood + +# Structures +structure.twilight_portal.name=Portail de la Twilight +structure.hedge_maze.name=Labyrinthe +structure.hollow_hill.name=Colline creuse +structure.quest_grove.name=Jardin de quête +structure.mushroom_tower.name=Château de champignons +structure.naga_courtyard.name=Cour du Nâga +structure.lich_tower.name=Tour du Liche +structure.minotaur_labyrinth.name=Labyrinthe du Minotaure +structure.hydra_lair.name=Repaire de l'Hydre +structure.goblin_stronghold.name=Forteresse du globin +structure.dark_tower.name=Tour noire +structure.yeti_cave.name=Cave du Yéti +structure.aurora_palace.name=Palace d'aurore +structure.troll_cave_and_cloud_castle.name=Cave du Troll et Maison dans les Nuages +structure.final_castle.name=Château final + +# Items +item.twilightforest.nagaScale.name=Écailles de Nâga +item.twilightforest.plateNaga.name=Plastron en écailles de Nâga +item.twilightforest.legsNaga.name=Jambières en écailles de Nâga +item.twilightforest.scepterTwilight.name=Sceptre de la Twilight +item.twilightforest.scepterLifeDrain.name=Sceptre du drainage de vie +item.twilightforest.scepterZombie.name=Sceptre du zombie +item.twilightforest.scepterShield.name=Sceptre de fortification +item.twilightforest.oreMeter.name=Mètre de minerai [WIP] +item.twilightforest.magicMap.name=Carte magique +item.twilightforest.mazeMap.name=Carte de labyrinthe +item.twilightforest.oreMap.name=Carte du labyrinthe/minerai +item.twilightforest.tfFeather.name=Plume de corbeau +item.twilightforest.magicMapFocus.name=Foyer de carte magique +item.twilightforest.mazeMapFocus.name=Foyer de carte de labyrinthe +item.twilightforest.liveRoot.name=Racine vivante +item.twilightforest.ironwoodRaw.name=Matériaux en bois de fer bruts +item.twilightforest.ironwoodIngot.name=Lingot en bois de fer +item.twilightforest.ironwoodHelm.name=Casque en bois de fer +item.twilightforest.ironwoodPlate.name=Plastron en bois de fer +item.twilightforest.ironwoodLegs.name=Jambières en bois de fer +item.twilightforest.ironwoodBoots.name=Bottes en bois de fer +item.twilightforest.ironwoodSword.name=Épée en bois de fer +item.twilightforest.ironwoodShovel.name=Pelle en bois de fer +item.twilightforest.ironwoodPick.name=Pioche en bois de fer +item.twilightforest.ironwoodAxe.name=Hache en bois de fer +item.twilightforest.ironwoodHoe.name=Houe en bois de fer +item.twilightforest.torchberries.name=Torche des baies +item.twilightforest.venisonRaw.name=Chevreuil cru +item.twilightforest.venisonCooked.name=Steak de chevreuil +item.twilightforest.hydraChop.name=Tranche d'Hydre +item.twilightforest.fieryBlood.name=Sang ardent +item.twilightforest.fieryIngot.name=Lingot ardent +item.twilightforest.fieryHelm.name=Casque ardent +item.twilightforest.fieryPlate.name=Plastron ardent +item.twilightforest.fieryLegs.name=Jambières ardentes +item.twilightforest.fieryBoots.name=Bottes ardentes +item.twilightforest.fierySword.name=Épée ardente +item.twilightforest.fieryPick.name=Pioche ardente +item.twilightforest.steeleafIngot.name=Steeleaf +item.twilightforest.steeleafHelm.name=Casque en Stealeaf +item.twilightforest.steeleafPlate.name=Plastron en Stealeaf +item.twilightforest.steeleafLegs.name=Jambières en Stealeaf +item.twilightforest.steeleafBoots.name=Bottes en Stealeaf +item.twilightforest.steeleafSword.name=Épée en Stealeaf +item.twilightforest.steeleafShovel.name=Pelle en Stealeaf +item.twilightforest.steeleafPick.name=Pioche en Stealeaf +item.twilightforest.steeleafAxe.name=Hache en Stealeaf +item.twilightforest.steeleafHoe.name=Houe en Stealeaf +item.twilightforest.minotaurAxe.name=Hache en diamant du Minotaure +item.twilightforest.minotaurAxeGold.nameHache en or du Minotaure +item.twilightforest.mazebreakerPick.name=Mazebreaker +item.twilightforest.transformPowder.name=Poudre de transformation +item.twilightforest.meefRaw.name=Viande de Meef crue +item.twilightforest.meefSteak.name=Steak de Meef +item.twilightforest.meefStroganoff.name=Stroganoff de Meef +item.twilightforest.mazeWafer.name=Tranche de labyrinthe +item.twilightforest.emptyMagicMap.name=Carte magique vierge +item.twilightforest.emptyMazeMap.name=Carte de labyrinthe vierge +item.twilightforest.emptyOreMap.name=Carte du labyrinthe/minerai vierge +item.twilightforest.oreMagnet.name=Aimant à minerais +item.twilightforest.crumbleHorn.name=Corne en ruine +item.twilightforest.peacockFan.name=Éventail de plumes de paon +item.twilightforest.moonwormQueen.name=Reine du ver de lune +item.twilightforest.charmOfLife1.name=Charme de la vie I +item.twilightforest.charmOfLife2.name=Charme de la vie II +item.twilightforest.charmOfKeeping1.name=Charme de Keeping I +item.twilightforest.charmOfKeeping2.name=Charme de Keeping II +item.twilightforest.charmOfKeeping3.name=Charme de Keeping III +item.twilightforest.towerKey.name=Clé de la tour +item.twilightforest.borerEssence.name=Essence de foreur +item.twilightforest.carminite.name=Carminite +item.twilightforest.tf_trophy.name=Trophée de %s +item.twilightforest.trophy.hydra.name=Trophée d'Hydre +item.twilightforest.trophy.naga.name=Trophée de Nâga +item.twilightforest.trophy.lich.name=Trophée de Liche +item.twilightforest.trophy.ur_ghast.name=Trophée d'Ur-Ghast +item.twilightforest.trophy.snow_queen.name=Trophée de la Reine des Neiges +item.twilightforest.experiment115.name=Expérience 115 +item.twilightforest.armorShards.name=Fragment d'armure +item.twilightforest.knightMetal.name=Lingot de métal de chevalier +item.twilightforest.shardCluster.name=Amas de fragments d'armure +item.twilightforest.knightlyHelm.name=Casque chevaleresque +item.twilightforest.knightlyPlate.name=Plastron chevaleresque +item.twilightforest.knightlyLegs.name=Jambières chevaleresques +item.twilightforest.knightlyBoots.name=Bottes chevaleresques +item.twilightforest.knightlySword.name=Épée chevaleresque +item.twilightforest.knightlyPick.name=Pioche chevaleresque +item.twilightforest.knightlyAxe.name=Hache chevaleresque +item.twilightforest.knightlyShield.name=Bouclier chevaleresque +item.twilightforest.phantomHelm.name=Casque de fantôme +item.twilightforest.phantomPlate.name=Plastron de fantôme +item.twilightforest.lampOfCinders.name=Lampe de cendres +item.twilightforest.fieryTears.name=Larmes ardentes +item.twilightforest.iceBomb.name=Bombe glacée +item.twilightforest.yetiHelm.name=Casque orné de Yéti +item.twilightforest.yetiPlate.name=Veste de Yéti +item.twilightforest.yetiLegs.name=Jambières de Yéti +item.twilightforest.yetiBoots.name=Bottes de Yéti +item.twilightforest.alphaFur.name=Fourrure de Yéti Alpha +item.twilightforest.arcticFur.name=Fourrure arctique +item.twilightforest.arcticHelm.name=Capuche arctique +item.twilightforest.arcticPlate.name=Manteau arctique +item.twilightforest.arcticLegs.name=Jambières arctiques +item.twilightforest.arcticBoots.name=Bottes arctiques +item.twilightforest.magicBeans.name=Haricots magiques +item.twilightforest.giantPick.name=Pioche de géant +item.twilightforest.giantSword.name=Épée de géant +item.twilightforest.tripleBow.name=Arc-tri +item.twilightforest.seekerBow.name=Arc du chercheur +item.twilightforest.iceBow.name=Arc gelé +item.twilightforest.enderBow.name=Arc de l'Ender +item.twilightforest.iceSword.name=Épée gelée +item.twilightforest.glassSword.name=Épée en verre +item.twilightforest.knightmetalRing.name=Boucle de métal de chevalier +item.twilightforest.chainBlock.name=Bloc et chaîne +item.twilightforest.cubeTalisman.name=Talisman du cube +item.twilightforest.cubeOfAnnihilation.name=Cube d'annihilation +item.twilightforest.moonDial.name=Cadran lunaire + +item.twilightforest.guide.name=Journal de voyageur + +item.twilightforest.minotaurAxe.tooltip=Bonus de dégâts lorsque vous chargez +item.twilightforest.minotaurAxeGold.tooltip=Bonus de dégâts lorsque vous chargez +item.twilightforest.knightlySword.tooltip=Bonus de dégâts sur les cibles munies d'armure +item.twilightforest.knightlyPick.tooltip=Bonus de dégâts sur les cibles munies d'armure +item.twilightforest.knightlyAxe.tooltip=Bonus de dégâts sur les cibles non-munies d'armure +item.twilightforest.giantPick.tooltip=Casse les blocs géants +item.twilightforest.fieryPick.tooltip=Cuisson automatique +item.twilightforest.fierySword.tooltip=Brûle les cibles +item.twilightforest.fieryHelm.tooltip=Brûle les attaquants +item.twilightforest.fieryPlate.tooltip=Brûle les attaquants +item.twilightforest.fieryLegs.tooltip=Brûle les attaquants +item.twilightforest.fieryBoots.tooltip=Brûle les attaquants +item.twilightforest.phantomHelm.tooltip=N'est jamais perdu lors d'une mort +item.twilightforest.phantomPlate.tooltip=N'est jamais perdu lors d'une mort +item.twilightforest.yetiHelm.tooltip=Ralentit les attaquants +item.twilightforest.yetiPlate.tooltip=Ralentit les attaquants +item.twilightforest.yetiLegs.tooltip=Ralentit les attaquants +item.twilightforest.yetiBoots.tooltip=Ralentit les attaquants + +item.twilightforest.arctic_armor.tooltip=Peut être teinte comme les armures en cuir + +# Entities +entity.twilightforest.wild_boar.name=Sanglier sauvage +entity.twilightforest.bighorn_sheep.name=Mouflon d'Amérique +entity.twilightforest.deer.name=Cerf sauvage +entity.twilightforest.redcap.name=Gobelin à casquette rouge +entity.twilightforest.swarm_spider.name=Essaim d'araignées +entity.twilightforest.naga.name=Nâga +entity.twilightforest.naga_segment.name=Segment de Nâga +entity.twilightforest.skeleton_druid.name=Squelette de druide +entity.twilightforest.hostile_wolf.name=Loup hostile +entity.twilightforest.wraith.name=Spectre de la Twilight +entity.twilightforest.hedge_spider.name=Araignée des haies +entity.twilightforest.hydra.name=Hydre +entity.twilightforest.hydra_head.name=Tête d'Hydre +entity.twilightforest.lich.name=Liche de la Twilight +entity.twilightforest.penguin.name=Manchot +entity.twilightforest.tiny_bird.name=Petit oiseau +entity.twilightforest.squirrel.name=Écureuil de la forêt +entity.twilightforest.bunny.name=Lapin nain +entity.twilightforest.raven.name=Corbeau de la forêt +entity.twilightforest.quest_ram.name=Bélier de quête +entity.twilightforest.kobold.name=Kobold +entity.twilightforest.boggard.name=Boggard [NYI] +entity.twilightforest.lich_minion.name=Serviteur du Liche +entity.twilightforest.loyal_zombie.name=Zombie loyal +entity.twilightforest.mosquito_swarm.name=Essaim de moustiques +entity.twilightforest.death_tome.name=Tome de mort +entity.twilightforest.minotaur.name=Minotaure +entity.twilightforest.minoshroom.name=Minoshroom +entity.twilightforest.fire_beetle.name=Coléoptère de feu +entity.twilightforest.slime_beetle.name=Coléoptère visqueux +entity.twilightforest.pinch_beetle.name=Coléoptère +entity.twilightforest.maze_slime.name=Slime du labyrinthe +entity.twilightforest.redcap_sapper.name=Sapeur à casquette rouge +entity.twilightforest.mist_wolf.name=Loup de la brume +entity.twilightforest.king_spider.name=Reine des araignées +entity.twilightforest.firefly.name=Luciole +entity.twilightforest.mini_ghast.name=Carminite Ghastling +entity.twilightforest.tower_ghast.name=Carminite Ghastguard +entity.twilightforest.tower_golem.name=Golem Carminite +entity.twilightforest.tower_termite.name=Foreur de la Towerwood +entity.twilightforest.tower_broodling.name=Carminite couveuse +entity.twilightforest.ur_ghast.name=Ur-Ghast +entity.twilightforest.blockchain_goblin.name=Goblin de bloc et chaîne +entity.twilightforest.goblin_knight_upper.name=Chevalier goblin supérieur +entity.twilightforest.goblin_knight_lower.name=Chevalier goblin inférieur +entity.twilightforest.helmet_crab.name=Casque crabe +entity.twilightforest.knight_phantom.name=Chevalier fantôme +entity.twilightforest.yeti.name=Yéti +entity.twilightforest.yeti_alpha.name=Yéti Alpha +entity.twilightforest.winter_wolf.name=Loup d'hiver +entity.twilightforest.snow_guardian.name=Gardin de la neige +entity.twilightforest.stable_ice_core.name=Coeur de glace stable +entity.twilightforest.unstable_ice_core.name=Coeur de glace instable +entity.twilightforest.snow_queen.name=Reine des Neiges +entity.twilightforest.troll.name=Troll des caves +entity.twilightforest.giant_miner.name=Mineur géant +entity.twilightforest.armored_giant.name=Géant en armure +entity.twilightforest.ice_crystal.name=Cristal de glace +entity.twilightforest.apocalypse_cube.name=Cube de l'apocalypse [NYI] +entity.twilightforest.adherent.name=Adhérent [NYI] +entity.twilightforest.castle_guardian.name=Garde du château [NYI] + +twilightforest.effect.frosted=Givré + +twilightforest.misc.wip0=Ce bloc est en cours de devéloppement et peut être bugué ou avoir des effets involontaires qui pourraient endommager votre monde. +twilightforest.misc.wip1=Utiliser avec précaution. +twilightforest.misc.nyi=Ce bloc a des effets qui n'ont pas encore été implémentés. + +twilightforest.loading.title.enter=Nous vous emmenons dans la Twilight Forest... +twilightforest.loading.title.leave=Nous vous sortons de la Twilight Forest... + +#Config +twilightforest.config.dimension=Paramètres de la dimension +twilightforest.config.dimension.tooltip=Vous ne pourrez pas modifier ces paramètres sans un relancement du jeu. +twilightforest.config.dimension_id=ID de dimension +twilightforest.config.dimension_id.tooltip=Quel ID à assigner à la dimension de la Twilight Forest. Changez cette valeur si vous avez des conflits avec d'autres mods. +twilightforest.config.dimension_seed=Graine de la dimension +twilightforest.config.dimension_seed.tooltip=Si une graine est ajoutée, elle passera outre la graine de génération par défaut lors de la génération de la Twilight Forest. +twilightforest.config.spawn_in_tf=Nouveaux joueurs apparaissent dans la Twilight Forest +twilightforest.config.spawn_in_tf.tooltip=Si cette fontionnalité est activée, les joueurs qui apparaissent pour la première fois apparaîtront dans la Twilight Forest. +twilightforest.config.skylight_forest=Forêt de ciel [WIP] +twilightforest.config.skylight_forest.tooltip=Si cette fontionnalité est activée, la Twilight Forest sera générée de vide sauf pour les structures. +twilightforest.config.skylight_oaks=Chênes de ciel [WIP] +twilightforest.config.skylight_oaks.tooltip=Si cette fontionnalité est activée, les chênes géants de la Twilight apparaîtront aussi dans la Twilight vide. + +twilightforest.config.world_gen_weights=Hauteurs de génération +twilightforest.config.world_gen_weights.tooltip=Hauteurs pour les diverses structures +twilightforest.config.stone_circle_weight=Hauteur du cercle de roche +twilightforest.config.well_weight=Hauteur de la source +twilightforest.config.stalagmite_weight=Hauteur des stalagmites +twilightforest.config.foundation_weight=Hauteur de la fondation +twilightforest.config.monolith_weight=Hauteur du monolithe +twilightforest.config.grove_ruins_weight=Hauteur du jardin en ruine +twilightforest.config.hollow_stump_weight=Hauteur de la colline creuse +twilightforest.config.fallen_hollow_log_weight=Hauteur de la buche creuse tombée +twilightforest.config.fallen_small_log_weight=Hauteur de la petite buche tombée +twilightforest.config.druid_hut_weight=Hauteur de la hutte du druide + +twilightforest.config.compat=Compatibilité +twilightforest.config.compat.tooltip=La TF devrait-elle charger les compatibilités ? Désactiver si les compatibilités de la TF causent des plantages, ou si vous ne les souhaitez pas. + +twilightforest.config.performance=Paramètres de performances +twilightforest.config.performance.tooltip=Sacrifie diverses choses pour améliorer les performances du monde. +twilightforest.config.canopy_coverage=Couverture du canopée +twilightforest.config.canopy_coverage.tooltip=Nombre de couverture du canopée. Un plus petit nombre améliore la vitesse de génération des chunks mais crée une forêt plus petite. +twilightforest.config.twilight_oaks=Apparition des chênes de la Twilight +twilightforest.config.twilight_oaks.tooltip=Les chances qu'un chunk dans la Twilight Forest contienne un chêne de la Twilight. Les nombres élevés réduisent le nombre d'arbres mais améliorent les performances. +twilightforest.config.leaves_light_opacity=Densité des feuilles +twilightforest.config.leaves_light_opacity.tooltip=Ceci contrôle la densité densité des feuilles, changeant la quantité de lumière bloquée. Peut être utilisé pour diminuer la complexité de certains calculs de lumière. +twilightforest.config.glacier_packed_ice=Glaciers faits de glace compactée au lieu de glace +twilightforest.config.glacier_packed_ice.tooltip=Activer cette fonctionnalité va générer des glaciers faits de glace compactée au lieu de glace transparente, augmentant la vitesse des calculs de lumière. +twilightforest.config.enable_skylight=Activer la skylight +twilightforest.config.enable_skylight.tooltip=Si la dimension a des valeurs de skylight par bloc. Désactiver cela va significativement améliorer les performances de génération, mais la lumière sera monotone partout.\nAVERTISSEMENT : lorsque les chunks sont chargés sans la skylight, la donnée est perdue et ne peut pas être regénérée facilement. Soyez prudents ! + +twilightforest.config.silent_cicadas=Cigales silencieuses +twilightforest.config.silent_cicadas.tooltip=Rendre les cigales silencieuses, pour ceux qui ont des problèmes de sons, ou ceux qui les trouvent agaçantes. + +twilightforest.config.first_person_effects=Rendre les effets 1ère personne +twilightforest.config.first_person_effects.tooltip=Contrôle si les divers effets du mod sont rendus en vue première personne. Désactivez cela si vous les trouvez distrayants. + +twilightforest.config.origin_dimension=Dimension d'origine +twilightforest.config.origin_dimension.tooltip=La dimension qui vous permet toujours de voyager dans la Twilight Forest, en plus d'être la dimension de retour. L'overworld est la dimension par défaut. +twilightforest.config.portals_in_other_dimensions=Portails dans les autres dimensions +twilightforest.config.portals_in_other_dimensions.tooltip=Permet de créer des portails de la Twilight Forest en dehors la dimension d'origine. +twilightforest.config.admin_portals=Portails de la Twilight admins +twilightforest.config.admin_portals.tooltip=Autoriser seulement les admins (opérateurs) à créer des portails. Cela réduit considérablement la plage dans laquelle le mod analyse généralement les condtions de portails valides. +twilightforest.config.portals=Désactiver les portails Twilight +twilightforest.config.portals.tooltip=Désactiver entièrement la création de portails Twilight Forest. Permet aux opérateurs de serveur de limiter l'accès à la dimension. +twilightforest.config.portal_creator=Élément de création de portail +twilightforest.config.portal_creator.tooltip=Les ID des objets à utiliser pour créer un portail de la Twilight Forest (domain:regname:meta) meta est facultatif. +twilightforest.config.portal_lighting=Création de portail ne crée pas de feu +twilightforest.config.portal_lighting.tooltip=Activer cette fonctionnalité pour désactiver le feu généré par l'éclair lors de la création de portail. Pour ceux qui n'aiment pas le fun. +twilightforest.config.portal_return=Les portails devraient-ils créer deux portails +twilightforest.config.portal_return.tooltip=Si désactivé, le portail de retour aura besoin de l'objet d'activation pour être actif. +twilightforest.config.check_portal_destination=Vérifier la destination du portail +twilightforest.config.check_portal_destination.tooltip=Détermine si le nouveau portail devrait être vérifié pour des questions de sécurité. Si activé, les portails ne seront pas créés au lieu de les rediriger vers une destination alternative sécurisée.\nNoter qu'activer cela réduit la fréquence des vérifications de portails. + +twilightforest.config.progression_default=Règle de progression par défaut +twilightforest.config.progression_default.tooltip=Définit la valeur par défaut de la règle de jeu contrôlant la progression forcée. + +twilightforest.config.uncrafting=Désactiver la table de défabrication +twilightforest.config.uncrafting.tooltip=Désactiver la fonctionnalité de défabrication de la table de défabrication. Permet d'empêcher certaines exploitations de bugs avec d'autres mods. + +twilightforest.config.antibuilder_blacklist=Liste noire de l'anti-constructeur +twilightforest.config.antibuilder_blacklist.tooltip=Liste noire de l'anti-constructeur. (domain:block:meta) meta est facultatif. + +twilightforest.config.animate_trophyitem=Pivoter les têtes de trophées sur l'apparence +twilightforest.config.animate_trophyitem.tooltip=Pivoter les têtes de trophées sur l'apparence de l'objet (lorsque tenu en main notamment). N'a pas d'impact sur les performances. Pour ceux qui n'aiment pas le fun. + +twilightforest.config.shield_parry=Parer avec le bouclier +twilightforest.config.shield_parry.tooltip=Nous vous recommandons le mod Shield Parry pour parer. +twilightforest.config.parry_non_twilight=Parer les projectiles non-Twilight +twilightforest.config.parry_non_twilight.tooltip=Activer pour parer les projectiles non-Twilight. Nous vous recommandons d'installer le mod Shield Parry. +twilightforest.config.parry_window_arrow=Délai de windowspan pour flèches +twilightforest.config.parry_window_arrow.tooltip=Le nombre de ticks après avoir levé le bouclier qui permet de parer une flèche. Il y a 20 ticks dans une seconde. +twilightforest.config.parry_window_fireball=Délai de windowspan pour boules de feu +twilightforest.config.parry_window_fireball.tooltip=Le nombre de ticks après avoir levé le bouclier qui permet de parer une boule de feu. Il y a 20 ticks dans une seconde. +twilightforest.config.parry_window_throwable=Délai de windowspan pour les jetables +twilightforest.config.parry_window_throwable.tooltip=Le nombre de ticks après avoir levé le bouclier qui permet de parer un objet jetable. Il y a 20 ticks dans une seconde. +twilightforest.config.shieldParryTicksBeam=Délai de windowspan pour les faisceaux??? +twilightforest.config.shieldParryTicksBeam.tooltip=??? + +twilightforest.config.loading_screen=Écran de chargement +twilightforest.config.loading_screen.tooltip=Client seulement : contrôles pour l'écran de chargement +twilightforest.config.loading_icon_enable=Activer l'animation de chargement +twilightforest.config.loading_icon_enable.tooltip=Fait osciller l'icône de chargement. N'a pas d'impact sur les performances. Pour ceux qui n'aiment pas le fun. +twilightforest.config.loading_screen_swap_frequency=Écran de chargement : fonds +twilightforest.config.loading_screen_swap_frequency.tooltip=Combien de ticks entre chaque changement d'image. Fixer à 0 pour qu'il n'y a pas de cycle. +twilightforest.config.loading_icon_wobble_bounce_frequency=Vitesse d'animation de l'icône +twilightforest.config.loading_icon_wobble_bounce_frequency.tooltip=Vitesse d'oscillement et de rebondissement.. +twilightforest.config.loading_icon_scale=Taille de l'icône +twilightforest.config.loading_icon_scale.tooltip=Taille de l'icône de chargement. +twilightforest.config.loading_icon_bounciness=Rebondissement de l'icône +twilightforest.config.loading_icon_bounciness.tooltip=Vitesse de rebondissement de l'icône. +twilightforest.config.loading_icon_tilting=Vacillement de l'icône +twilightforest.config.loading_icon_tilting.tooltip=Vitesse de vacillement de l'icône +twilightforest.config.loading_icon_tilt_pushback=Position initiale +twilightforest.config.loading_icon_tilt_pushback.tooltip=Modifie la valeur initiale de la position de l'icône. + +# Books +twilightforest.book.lichtower.1=\u00A78[[Un carnet d'explorateur, rongé par des monstres]]\u00A70\n\nJ'ai commencé à examiner l'étrange aura qui entoure cette tour. Les briques de la tour étaient protégées par une malédiction, plus forte que toutes celles que j'ai vues auparavant. Le sort +twilightforest.book.lichtower.2=de la malédiction bouillonne dans les environs.\n\nDans mon pays, j'aurais eu beaucoup d'options pour gérer ce sort, mais ici, mes ressources sont limitées. Je vais devoir faire des recherches... +twilightforest.book.lichtower.3=\u00A78[[Après de nombreux essais]]\u00A70\n\nUne percée ! Au cours de mes voyages, j'ai aperçu un énorme monstre semblable à un serpent dans une cour décorée. À côté, j'ai récupéré un petit ver.\n\nLa magie dans l'écaille +twilightforest.book.lichtower.4=semble avoir des propriétés permettant de briser une malédiction, c'est ce dont j'ai besoin, mais cette magie est si faible. J'ai peut-être besoin d'acquérir un spécimen plus frais, directement depuis la créature. + +twilightforest.book.labyrinth.1=\u00A78[[Un carnet d'explorateur, écrit sur du papier résistant à l'eau]]\u00A70\n\nLes moustiques de ce marais sont contrariants, mais curieux. La vaste majorité d'entre-eux ne semble pas avoir de source naturelle, ni de rôle dans l'écosystème local. +twilightforest.book.labyrinth.2= J'ai commencé à suspecter qu'ils avaient une sorte de malédiction magique.\n\n\u00A78[[Texte suivant]]\u00A70\n\nMaintenant que j'ai rencontré un sort de protection dans ce labyrinthe en ruine, je considère mes suspicions comme confirmées. Les +twilightforest.book.labyrinth.3=moustiques et le sort de protection sont des malédictions. Cette malédiction semble avoir une source différente de celles que j'ai pu rencontrer. Il faut que j'étudie cela en profondeur...\n\n\u00A78[[Texte suivant]]\u00A70\n\nLa malédiction semble +twilightforest.book.labyrinth.4=être d'un type trop puissant pour être produite seule. Plusieurs sorciers associés seraient nécessaires.\n\nSi un des sorciers arrêtait de contribuer, la malédiction toute entière serait annulée sur le marais. Étrangement, +twilightforest.book.labyrinth.5=mes divinations ne montrent pas de signes de sorcier vivant dans les parages. J'ai cependant vu quelque chose de très intéressant dans une des tours pointues du coin... + +twilightforest.book.hydralair.1=\u00A78[[Un carnet d'explorateur, écrit sur du papier résistant au feu]]\u00A70\n\nLe feu est un obstacle banal pour un maître de l'exploration que je suis. J'ai traversé des océans de feu, et nagé dans des océans de lave. Ici, l'air est brûlant, il est +twilightforest.book.hydralair.2=d'une intéressante variation, mais en aucun cas une entrave.\n\nCe qui me freine par contre, c'est cet autre sort de protection que j'ai rencontré, cette fois-ci, celui-ci entoure une créature puissante, qui doit sûrement être le roi +twilightforest.book.hydralair.3=de ce marais de feu. Ce n'est pas le premier sort de protection que je rencontre, et je commence à démêler les mystères de leur fonctionnement.\n\nSi ce sortilège est comme les autres, il sera soutenu par une créature très puissante à proximité. +twilightforest.book.hydralair.4=Autour de ce marais de feu se trouvent de nombreux marais humides, et sous ceux-ci se trouvent des labyrinthes remplis de minotaures. Le choix logique de lier un tel sort serait une sorte de minotaure puissant, différent, en quelque sorte, de ses compagnons... + +twilightforest.book.tfstronghold.1=\u00A78[[Un carnet d'explorateur, écrit sur du papier rougeoyant]]\u00A70\n\nLes vrilles des ténèbres entourant cette zone sont juste une manifestation d'un sort de protection qui s'étend sur toute la forêt noire. Ce sort provoque de la cécité, ce qui est très +twilightforest.book.tfstronghold.2=génant. J'ai vu diverses choses intéressantes dans les parages et aimerais continuer à explorer.\n\n\u00A78[[Texte suivant]]\u00A70\n\nJ'ai trouvé des ruines dans la forêt noire. Elle appartiennent à une forteresse, +twilightforest.book.tfstronghold.3=probablement habitée par des chevaliers. Au lieu d'être peuplée de chevaliers, elle est en fait peuplée de goblins. Ils portent des armures chevaleresques, mais leur comportement, lui, ne l'est pas.\n\n\u00A78[[Texte suivant]]\u00A70\n\nAu fond des ruines, +twilightforest.book.tfstronghold.4=j'y ai trouvé un piédestal. Ce dernier semble être celui que les chevaliers placeraient pour prouver leur force.\n\Obtenir un sceptre semble permettre d'affaiblir la malédiction qui règne dans la forêt noire, et placer un trophée associé à une +twilightforest.book.tfstronghold.5=puissante créature sur un piédestal donnerait probablement accès à la partie principale de la forêt. + +twilightforest.book.darktower.1=\u00A78[[Un carnet d'explorateur qui semble avoir résisté à une explosion]]\u00A70\n\nCette tour a clairement des mécanismes qui ne me répondent pas. Leur magie aspire preque à reconnaître mon contact, mais elle ne le peut pas. C'est comme si les +twilightforest.book.darktower.2=dispositifs de la tour étaient en train d'être supprimés par un groupe d'être-vivants environnant.\n\n\u00A78[[Texte suivant]]\u00A70\n\nLa magie semble émaner des profondeurs des forteresses proches. Elle ne peut pas +twilightforest.book.darktower.3=provenir des goblins, puisque leur magie est séduisante mais floue.\n\n\u00A78[[Texte suivant]]\u00A70\n\nMon analyse indique qu'elle vient de plusieurs sources, opérant comme un groupe. J'y retournerai plus tard. + +twilightforest.book.yeticave.1=\u00A78[[Un carnet d'explorateur, couvert de givre]]\u00A70\n\nLe blizzard qui entoure ces terres enneigées est incessant. Ce n'est pas une tempête de neige ordinaire--c'est un phénomène magique. Il faut que je réalise des expériences pour +twilightforest.book.yeticave.2=trouver ce qui est capable d'un tel effet.\n\n\u00A78[[Texte suivant]]\u00A70\n\nLa malédiction semble être trop puissante pour être créée par une seule créature. Plusieurs sorciers travaillant ensemble seraient nécessaires. +twilightforest.book.yeticave.3=Si un des sorciers arrêtait de contribuer, le blizzard serait plus calme. Étrangement, mes divinations ne montrent pas de signes de présence de sorcières dans les environs. J'ai cependant vu quelque chose d'intéressant dans l'une des tours pointues du coin... + +twilightforest.book.icetower.1=\u00A78[[Un carnet d'explorateur, recouvert de givre]]\u00A70\n\nJ'ai vaincu un blizzard, mais je suis tombé sur cette terrible tempête de verglas au sommet du glacier. Mes explorations m'ont montré la splendeur d'un palais de glace, brillant des couleurs +twilightforest.book.icetower.2=de l'aurore polaire. Tout cela semble protégé par une sorte de malédiction.\n\n\u00A78[[Texte suivant]]\u00A70\n\nJe ne suis pas un novice. Cette malédiction est alimentée par le pouvoir d'une créature à proximité. La malédiction +twilightforest.book.icetower.3=entourant le marais de feu a été construite sur le pouvoir du chef des minotaures à proximité.\n\nAutour de ce glacier, il y a des masses de yétis. Peut-être que les yétis ont une sorte de chef... + +twilightforest.book.trollcave.1=\u00A78[[Un carnet d'explorateur, endommagé par ce l'acide]]\u00A70\n\nIl semble n'y avoir aucun moyen de me protéger de cette pluie acide entourant le secteur. Lors de mes brèves excursions, j'ai rencontré un autre sort de protection, +twilightforest.book.trollcave.2=similaire à ceux dont j'ai été témoin. Le sort doit être lié à cette pluie acide d'une manière ou d'une autre. Il faut que je continue à chercher...\n\n\u00A78[[Texte suivant]]\u00A70\n\nUne telle magie météorologique doit être le résultat +twilightforest.book.trollcave.3=de multiples grands maux invaincus dans ce monde. Mes études contiennent de nombreux indices pointant vers un marais brûlant, une forêt recouverte d'une profonde obscurité et un royaume recouvert de neige. + +twilightforest.book.unknown.1=\u00A78[[Ce livre a des signes comme quoi il a été copié de nombreuses fois]]\u00A70\n\nJe ne peux pas expliquer le champ entourant cette structure, mais cette magie est très puissante. Si cette malédiction est comme les autres, alors la clé pour la faire disparaître se trouve ailleurs. Peut-être qu'il y a +twilightforest.book.unknown.2=quelque chose que je n'ai pas fait ou un monstre que je n'ai pas encore vaincu. Je vais devoir faire demi-tour. Je retournerai à cet endroit plus tard, pour voir si quelque chose a changé. + +# Fluid + +fluid.fierymetal=Matériau ardent en fusion +fluid.knightmetal=Métal de chevalier en fusion +fluid.fiery_essence=Essence ardente + +# TCon + +material.nagascale.name=Écaille de nâga +material.steeleaf.name=Steeleaf +material.fierymetal.name=Ardent +material.knightmetal.name=Chevaleresque +material.raven_feather.name=Plume de corbeau + +modifier.twilit.name=Twilit +modifier.twilit.desc=§oLa bénédiction illuminée de la Twilight Forest.§r\nPlus rapide dans la Twilight Forest.\nPlus de dégâts en dehors de la forêt Twilight. +modifier.twilit.extra.speed=Vitesse de minage dans la Twilight Forest : +%s +modifier.twilit.extra.damage=Dégâts en dehors de la Twilight Forest : +%s +modifier.precipitate.name=Précipité +modifier.precipitate.desc=§oLe dernier plan d'évacuation existant.§r\nMoins vous avez de santé, plus vite il va ! +modifier.synergy.name=Synergie +modifier.synergy.desc=§oRegardez-moi, pas de mousse !§r\nSe réparera si vous avez Steeleaves dans votre barre d'outil. +modifier.stalwart.name=Vigoureux +modifier.stalwart.desc=§oLe courageux et l'audacieux.§r\nFrapper une entité peut vous faire sentir enhardi. +modifier.veiled.name=Invisible +modifier.veiled.desc=§oComme un spectre !§r\nLe projectile sera invisible. + +# Immersive Engineering +item.tfEngineeringShader=Twilit Shader: %s +item.tfEngineeringShaderBag=Twilit %s Sac de shader + +twilightforest.shader.twilight=Twilight + +twilightforest.shader.snakestone=Serpent de pierre +twilightforest.shader.naga=Nâga +twilightforest.shader.lich=Liche + +twilightforest.shader.mazestone=Mazestone +twilightforest.shader.minoshroom=Minoshroom +twilightforest.shader.hydra=Hydre + +twilightforest.shader.underbrick=Brique des dessous +twilightforest.shader.knight_phantom=Chevalier fantôme +twilightforest.shader.towerwood=Towerwood +twilightforest.shader.ur-ghast=Ur-Ghast + +twilightforest.shader.alpha_yeti=Yéti Alpha +twilightforest.shader.auroralized=Auroralisé +twilightforest.shader.snow_queen=Reine des Neiges + +twilightforest.shader.final_castle=Château final diff --git a/src/main/resources/assets/twilightforest/lang/ja_jp.lang b/src/main/resources/assets/twilightforest/lang/ja_jp.lang new file mode 100644 index 0000000000..8c23b42088 --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/ja_jp.lang @@ -0,0 +1,677 @@ +#PARSE_ESCAPES + +itemGroup.twilightForest=Twilight Forest + +# ADVANCEMENTS +advancement.twilightforest.root.desc=黄昏の森へのポータルを作成する。 + +# General progression +advancement.twilightforest.hedge=虫を踏みつける者 +advancement.twilightforest.hedge.desc=生垣迷路で蜘蛛を倒す。 + +advancement.twilightforest.hill1=そのブーツは私のものだ! +advancement.twilightforest.hill1.desc=亡霊鉱山(小)でレッドキャップを倒す。 +advancement.twilightforest.hill2=何の騒音だ? +advancement.twilightforest.hill2.desc=亡霊鉱山(中)でレッドキャップ工兵を倒す。 +advancement.twilightforest.hill3=私にはお見通しだ +advancement.twilightforest.hill3.desc=亡霊鉱山(大)でレイスを倒す。 + +advancement.twilightforest.quest_ram=完璧なもこもこ? +advancement.twilightforest.quest_ram.desc=色食みの羊に探しものを渡す。 + +# Map +advancement.twilightforest.magic_map_focus=火で書き込む +advancement.twilightforest.magic_map_focus.desc=カラスの羽根とグロウストーンダストとトーチベリーで、魔法の羽根をクラフトする。 +advancement.twilightforest.magic_map=何マイル先も見える +advancement.twilightforest.magic_map.desc=魔法の地図(地上)を広げる。 +advancement.twilightforest.maze_map=そして今、出口を見つけるために +advancement.twilightforest.maze_map.desc=魔法の地図(迷宮)を広げる。 +advancement.twilightforest.ore_map=そんなに価値があるのか? +advancement.twilightforest.ore_map.desc=魔法の地図(迷宮/鉱石)を広げる。 + +# Mainline beginning progression +advancement.twilightforest.twilight_hunter=森の静寂 +advancement.twilightforest.twilight_hunter.desc=黄昏の森の野生動物を狩る。 + +advancement.twilightforest.kill_naga=秤を均等にする時だ +advancement.twilightforest.kill_naga.desc=ナーガ神殿でナーガを倒してナーガの鱗を手に入れ、リッチタワーを取り巻く結界魔法を破る。 +advancement.twilightforest.naga_armors=ナーガの甲冑士 +advancement.twilightforest.naga_armors.desc=ナーガアーマー(胴)と(脚)をクラフトして、インベントリに両方を持つ。 + +advancement.twilightforest.kill_lich=死者を差し出せ +advancement.twilightforest.kill_lich.desc=リッチタワーの最上階でリッチを倒して杖を手に入れ、沼地の毒蚊を追い払い、闇の森の盲目の呪いを打ち破り、雪の森の寒さに耐える力を得る。 +advancement.twilightforest.lich_scepters=力を合わせて! +advancement.twilightforest.lich_scepters.desc=リッチの3種類の杖を全て手に入れる。 + +# Swamp Progression +advancement.twilightforest.progress_labyrinth=マイティストロガノフ +advancement.twilightforest.progress_labyrinth.desc=肉とキノコのシチューを食す事で、焼け沼に入る強靭さを得る。 +advancement.twilightforest.kill_hydra=ヒドラスレイヤー +advancement.twilightforest.kill_hydra.desc=強大なヒドラを倒して、自分自身を力づける。 +advancement.twilightforest.mazebreaker=迷宮を砕く者 +advancement.twilightforest.mazebreaker.desc=ラビリンスの納骨堂でメイズブレイカーを手に入れる。 +advancement.twilightforest.hydra_chop=ヒドラ肉だ! +advancement.twilightforest.hydra_chop.desc=満腹度が空の時にヒドラ肉を食べる。 + +# Dark Forest Progression +advancement.twilightforest.progress_trophy_pedestal=トロフィー・チャンピオン +advancement.twilightforest.progress_trophy_pedestal.desc=闇の森の廃墟にある台座にトロフィーを置き、自らの力を示せ。 +advancement.twilightforest.progress_knights=カーミナイト・アクリメーション +advancement.twilightforest.progress_knights.desc=ゴブリン騎士の拠点のナイトファントムを鎮めれば、ダークタワーの装置を動かすことができる。 +advancement.twilightforest.ghast_trap=タワーウッドの不思議なもの +advancement.twilightforest.ghast_trap.desc=ガストトラップの近くでカーミナイトガストリングを倒して起動させ、ウルガストを降下させる。 +advancement.twilightforest.progress_ur_ghast=炎の涙 +advancement.twilightforest.progress_ur_ghast.desc=ウルガストの燃える如く赤い涙に触れる。 + +advancement.twilightforest.experiment_115=神秘的な肉? +advancement.twilightforest.experiment_115.desc=ケーキのように見えるが、これは... +advancement.twilightforest.experiment_115_2=メモ: 大成功! +advancement.twilightforest.experiment_115_2.desc=しっとりとしていてとても美味い! +advancement.twilightforest.experiment_115_3=115日、115年、そして永遠に +advancement.twilightforest.experiment_115_3.desc=エクスペリメント115を食べ続ける。 + +# Snow Forest Progression +advancement.twilightforest.progress_yeti=アルファの毛皮 +advancement.twilightforest.progress_yeti.desc=アルファイエティの柔らかな毛皮の装備を身に着ければ、氷河の極寒から身を守れる。 +advancement.twilightforest.progress_glacier=晴天 +advancement.twilightforest.progress_glacier.desc=オーロラ宮殿の最上階で雪の女王を倒す。 +advancement.twilightforest.arctic_dyed=最新ファッション +advancement.twilightforest.arctic_dyed.desc=全ての防寒装備を染色する。 + +# Mid-way Misc. Stuff +advancement.twilightforest.glass_sword=ワン・ヒット・ワンダー +advancement.twilightforest.glass_sword.desc=ガラスの剣をうまく使ってほしい。 + +advancement.twilightforest.twilight_dining=黄昏の晩餐 +advancement.twilightforest.twilight_dining.desc=黄昏の森で追加された全ての食べ物を食べる(調理した肉を除く) + +advancement.twilightforest.fiery_set=血と涙のガロン +advancement.twilightforest.fiery_set.desc=1箇所以上の焦熱防具と、焦熱武器または道具を装備する。 + + + +# Highlands +advancement.twilightforest.progress_merge=究極の対決 +advancement.twilightforest.progress_merge.desc=ヒドラ、ウルガスト、雪の女王を倒して酸性雨を晴らし、高地へ向かう自身を勇気づける。 +advancement.twilightforest.progress_troll=もっと炎を +advancement.twilightforest.progress_troll.desc=トロールの洞窟で灰のランプを見つけ、茨の障壁を焼き払え。 +advancement.twilightforest.progress_thorns=茨を越えて [制作中] +advancement.twilightforest.progress_thorns.desc=茨の大地を突破し、城の扉を開錠せよ。 +advancement.twilightforest.progress_castle=驚異の城 [制作中] +advancement.twilightforest.progress_castle.desc=その城には一体何が待ち構えているのか!? + +twilightforest.trophyPedestal.ineligible=あなたには資格がありません。 +twilightforest.ore_meter.range=半径: %s, 原点: [%s, %s] +twilightforest.ore_meter.exposed=発見: %s +twilightforest.scepter_charges=残り %d 回 + +tile.twilightforest.Log.0.name=トワイライトオークの原木 +tile.twilightforest.Log.1.name=林冠木の原木 +tile.twilightforest.Log.2.name=マングローブの原木 +tile.twilightforest.Log.3.name=ダークウッドの原木 +tile.twilightforest.Leaves.0.name=トワイライトオークの葉 +tile.twilightforest.Leaves.1.name=林冠木の葉 +tile.twilightforest.Leaves.2.name=マングローブの葉 +tile.twilightforest.Leaves.3.name=レインボーオークの葉 +tile.twilightforest.Firefly.name=ホタル +tile.twilightforest.Cicada.name=セミ +item.twilightforest.Portal.name=黄昏の森ポータル +tile.twilightforest.Portal.name=黄昏の森ポータル +tile.twilightforest.Mazestone.0.name=メイズストーン +tile.twilightforest.Mazestone.1.name=メイズレンガ +tile.twilightforest.Mazestone.2.name=メイズストーン(模様) +tile.twilightforest.Mazestone.3.name=メイズレンガ(装飾) +tile.twilightforest.Mazestone.4.name=メイズレンガ(ヒビ) +tile.twilightforest.Mazestone.5.name=メイズレンガ(苔) +tile.twilightforest.Mazestone.6.name=メイズストーン(モザイク) +tile.twilightforest.Mazestone.7.name=メイズストーン(ボーダー) +tile.twilightforest.Mazestone.8.name=メイズストーン(天井) +tile.twilightforest.Hedge.0.name=生垣ブロック +tile.twilightforest.Hedge.1.name=ダークウッドの葉 +tile.twilightforest.BossSpawner.0.name=ナーガスポナー +tile.twilightforest.BossSpawner.1.name=リッチスポナー +tile.twilightforest.BossSpawner.2.name=ヒドラスポナー +tile.twilightforest.BossSpawner.3.name=ウルガストスポナー +tile.twilightforest.BossSpawner.4.name=ナイトファントムスポナー +tile.twilightforest.FireflyJar.name=瓶詰めホタル +tile.twilightforest.Plant.0.name=苔 +tile.twilightforest.Plant.1.name=メイアップル +tile.twilightforest.Plant.2.name=クローバーパッチ [制作中] +tile.twilightforest.Plant.3.name=巻きシダ +tile.twilightforest.Plant.4.name=ヒカリダケ +tile.twilightforest.Plant.5.name=森の草 +tile.twilightforest.Plant.6.name=乾いた低木 +tile.twilightforest.Plant.7.name=トーチベリー +tile.twilightforest.Plant.8.name=ひげ根 +tile.twilightforest.Roots.0.name=根ブロック +tile.twilightforest.Roots.1.name=根ブロック(苔) +tile.twilightforest.UncraftingTable.name=解体作業台 +tile.twilightforest.FireJet.0.name=噴煙ブロック +tile.twilightforest.FireJet.1.name=噴煙装置 +tile.twilightforest.FireJet.2.name=噴煙装置 +tile.twilightforest.FireJet.3.name=間欠炎ブロック +tile.twilightforest.FireJet.4.name=間欠炎ブロック(破裂) +tile.twilightforest.FireJet.5.name=間欠炎ブロック(炎上) +tile.twilightforest.FireJet.6.name=間欠炎装置 +tile.twilightforest.FireJet.7.name=間欠炎装置(破裂) +tile.twilightforest.FireJet.8.name=間欠炎装置(炎上) +tile.twilightforest.Nagastone.0.name=ナーガストーン(頭) +tile.twilightforest.Nagastone.1.name=ナーガストーン +tile.twilightforest.Sapling.name=黄昏の苗木 +tile.twilightforest.Sapling.0.name=ひ弱なトワイライトオークの苗木 +tile.twilightforest.Sapling.1.name=林冠木の苗木 +tile.twilightforest.Sapling.2.name=トワイライトマングローブの苗木 +tile.twilightforest.Sapling.3.name=ダークウッドの苗木 +tile.twilightforest.Sapling.4.name=丈夫なトワイライトオークの苗木 +tile.twilightforest.Sapling.5.name=刻の木の苗木 +tile.twilightforest.Sapling.6.name=変化の木の苗木 +tile.twilightforest.Sapling.7.name=採掘の木の苗木 +tile.twilightforest.Sapling.8.name=分類の木の苗木 +tile.twilightforest.Sapling.9.name=レインボーオークの苗木 +tile.twilightforest.Moonworm.name=月光虫 +tile.twilightforest.MagicLog.0.name=刻の木の原木 +tile.twilightforest.MagicLog.1.name=変化の木の原木 +tile.twilightforest.MagicLog.2.name=採掘の木の原木 +tile.twilightforest.MagicLog.3.name=分類の木の原木 +tile.twilightforest.MagicLogSpecial.0.name=刻の時辰儀 +tile.twilightforest.MagicLogSpecial.1.name=変化の心 +tile.twilightforest.MagicLogSpecial.2.name=採掘コア +tile.twilightforest.MagicLogSpecial.3.name=分類エンジン +tile.twilightforest.MagicLeaves.0.name=刻の木の葉 +tile.twilightforest.MagicLeaves.1.name=変化の木の葉 +tile.twilightforest.MagicLeaves.2.name=採掘の木の葉 +tile.twilightforest.MagicLeaves.3.name=分類の木の葉 +tile.twilightforest.TowerStone.0.name=タワーウッド +tile.twilightforest.TowerStone.1.name=タワーウッド(緑) +tile.twilightforest.TowerStone.2.name=タワーウッド(ヒビ) +tile.twilightforest.TowerStone.3.name=タワーウッド(苔) +tile.twilightforest.TowerStone.4.name=タワーウッド(シミ) +tile.twilightforest.TowerDevice.0.name=タワーウッド(扉) +tile.twilightforest.TowerDevice.1.name=タワーウッド(扉) +tile.twilightforest.TowerDevice.2.name=タワーウッド(消失扉) +tile.twilightforest.TowerDevice.3.name=タワーウッド(消失扉) +tile.twilightforest.TowerDevice.4.name=タワーウッド(施錠) +tile.twilightforest.TowerDevice.5.name=タワーウッド(開錠) +tile.twilightforest.TowerDevice.6.name=カーミナイトビルダー +tile.twilightforest.TowerDevice.7.name=カーミナイトビルダー(起動) +tile.twilightforest.TowerDevice.8.name=カーミナイトビルダー(停止) +tile.twilightforest.TowerDevice.9.name=アンチビルダー +tile.twilightforest.TowerDevice.10.name=ガストトラップ +tile.twilightforest.TowerDevice.11.name=ガストトラップ(起動) +tile.twilightforest.TowerDevice.12.name=カーミナイトリアクター +tile.twilightforest.TowerDevice.13.name=カーミナイトリアクター(起動) +tile.twilightforest.TowerTranslucent.0.name=タワーウッド扉(開放) +tile.twilightforest.TowerTranslucent.1.name=タワーウッド扉(閉鎖中) +tile.twilightforest.TowerTranslucent.2.name=カーミナイトブロック +tile.twilightforest.TowerTranslucent.3.name=カーミナイトブロック(停止) +tile.twilightforest.TowerTranslucent.4.name=アンチビルトブロック +tile.twilightforest.TowerTranslucent.5.name=破壊された瓦礫 +tile.twilightforest.TowerTranslucent.6.name=ニセモノの金 +tile.twilightforest.TowerTranslucent.7.name=ニセモノのダイアモンド +tile.twilightforest.Trophy.name=黄昏の森トロフィー +tile.twilightforest.Shield.name=拠点の防壁 +tile.twilightforest.TrophyPedestal.0.name=トロフィーの台座 +tile.twilightforest.TrophyPedestal.15.name=トロフィーの台座(作動中) +tile.twilightforest.AuroraBrick.name=オーロラブロック +tile.twilightforest.UnderBrick.0.name=アンダーブリック +tile.twilightforest.UnderBrick.1.name=アンダーブリック(苔) +tile.twilightforest.UnderBrick.2.name=アンダーブリック(ヒビ) +tile.twilightforest.UnderBrick.3.name=アンダーフリック(床) +tile.twilightforest.Thorns.brown.name=茨 +tile.twilightforest.Thorns.green.name=緑の茨 +tile.twilightforest.BurntThorns.name=焦げた茨 +tile.twilightforest.ThornRose.name=野バラ +tile.twilightforest.Leaves3.0.name=茨の葉 +tile.twilightforest.Leaves3.1.name=豆の木の葉 +tile.twilightforest.Deadrock.surface.name=デッドロック(風化) +tile.twilightforest.Deadrock.cracked.name=デッドロック(ヒビ) +tile.twilightforest.Deadrock.solid.name=デッドロック +tile.twilightforest.DarkLeaves.name=ダークウッドの葉 +tile.twilightforest.AuroraPillar.name=オーロラの柱 +tile.twilightforest.AuroraSlab.name=オーロラのハーフブロック +tile.twilightforest.TrollSteinn.name=トロール石 +tile.twilightforest.WispyCloud.name=薄雲 +tile.twilightforest.FluffyCloud.name=ふわふわ雲 +tile.twilightforest.GiantCobble.name=巨人の丸石 +tile.twilightforest.GiantLog.name=巨人の原木 +tile.twilightforest.GiantLeaves.name=巨人の葉 +tile.twilightforest.GiantObsidian.name=巨人の黒曜石 +tile.twilightforest.UberousSoil.name=培養土 +tile.twilightforest.HugeStalk.name=巨大な茎 +tile.twilightforest.HugeGloomBlock.name=巨大ヒカリダケブロック +tile.twilightforest.TrollVidr.name=トロールベリーのツタ +tile.twilightforest.UnripeTrollBer.name=未熟なトロールベリー +tile.twilightforest.TrollBer.name=トロールベリー +tile.twilightforest.TrollBer.name=トロールベリー +tile.twilightforest.KnightmetalBlock.name=ナイトメタルブロック +tile.twilightforest.HugeLilyPad.name=巨大なスイレンの葉 +tile.twilightforest.HugeWaterLily.name=巨大なスイレン +tile.twilightforest.Slider.0.name=滑走トラップ +tile.twilightforest.Slider.1.name=滑走トラップ 1 +tile.twilightforest.Slider.2.name=滑走トラップ 2 +tile.twilightforest.Slider.3.name=滑走トラップ 3 +tile.twilightforest.CastleBrick.0.name=キャッスルレンガ +tile.twilightforest.CastleBrick.1.name=キャッスルレンガ(かすれ) +tile.twilightforest.CastleBrick.2.name=キャッスルレンガ(ヒビ) +tile.twilightforest.CastleBrick.3.name=キャッスルルーフ +tile.twilightforest.CastleBrick.4.name=キャッスルレンガ(苔) +tile.twilightforest.CastleBrick.5.name=厚いキャッスルレンガ +tile.twilightforest.CastleDoor.0.name=キャッスルドア(黄) +tile.twilightforest.CastleDoor.1.name=キャッスルドア(紫) +tile.twilightforest.CastleDoor.2.name=キャッスルドア(赤) +tile.twilightforest.CastleDoor.3.name=キャッスルドア(青) +tile.twilightforest.CastleMagic.0.name=ルーンレンガ(赤) +tile.twilightforest.CastleMagic.1.name=ルーンレンガ(青) +tile.twilightforest.CastleMagic.2.name=ルーンレンガ(黄) +tile.twilightforest.CastleMagic.3.name=ルーンレンガ(紫) +tile.twilightforest.CastlePillar.0.name=キャッスルレンガの柱(斑) +tile.twilightforest.CastlePillar.1.name=キャッスルレンガ(斑) +tile.twilightforest.CastlePillar.2.name=キャッスルレンガの柱(チェック) +tile.twilightforest.CastlePillar.3.name=キャッスルレンガ(チェック) +tile.twilightforest.CastleStairs.0.name=キャッスルレンガの階段(斑) +tile.twilightforest.CastleStairs.8.name=キャッスルレンガの階段(チェック) +tile.twilightforest.ForceField.0.name=フォースフィールド(紫) +tile.twilightforest.ForceField.1.name=フォースフィールド(赤) +tile.twilightforest.ForceField.2.name=フォースフィールド(橙) +tile.twilightforest.ForceField.3.name=フォースフィールド(緑) +tile.twilightforest.ForceField.4.name=フォースフィールド(青) +tile.twilightforest.BlockOfStorage.0.name=樹鉄ブロック +tile.twilightforest.BlockOfStorage.1.name=焦熱ブロック +tile.twilightforest.BlockOfStorage.2.name=葉鋼ブロック +tile.twilightforest.BlockOfStorage.3.name=防寒毛皮ブロック +tile.twilightforest.BlockOfStorage.4.name=カーミナイトブロック +tile.twilightforest.CinderFurnaceIdle.name=灰のかまど [未実装] +tile.twilightforest.CinderLog.name=灰の原木 [未実装] +tile.twilightforest.MiniatureStructure=%sのミニチュア [未実装] +tile.twilightforest.SpiralBricks.name=螺旋状の石レンガ [製作中] +tile.twilightforest.BlockOfLapisTF.name=ラピスラズリブロック [未実装] +tile.twilightforest.EtchedNagastone.name=エッチングナーガストーン +tile.twilightforest.NagastonePillar.name=ナーガストーンの柱 +tile.twilightforest.NagastoneStairs.0.name=ナーガストーンの階段(左) +tile.twilightforest.NagastoneStairs.8.name=ナーガストーンの階段(右) +tile.twilightforest.EtchedNagastoneMossy.name=エッチングナーガストーン(苔) +tile.twilightforest.NagastonePillarMossy.name=ナーガストーンの柱(苔) +tile.twilightforest.NagastoneStairsMossy.0.name=ナーガストーンの階段(左)(苔) +tile.twilightforest.NagastoneStairsMossy.8.name=ナーガストーンの階段(右)(苔) +tile.twilightforest.EtchedNagastoneWeathered.name=エッチングナーガストーン(風化) +tile.twilightforest.NagastonePillarWeathered.name=ナーガストーンの柱(風化) +tile.twilightforest.NagastoneStairsWeathered.0.name=ナーガストーンの階段(左)(風化) +tile.twilightforest.NagastoneStairsWeathered.8.name=ナーガストーンの階段(右)(風化) + +structure.twilight_portal.name=黄昏のポータル +structure.hedge_maze.name=生垣迷路 +structure.hollow_hill.name=亡霊鉱山 +structure.quest_grove.name=霊羊の遺跡 +structure.mushroom_tower.name=キノコの城 +structure.naga_courtyard.name=ナーガ神殿 +structure.lich_tower.name=リッチタワー +structure.minotaur_labyrinth.name=ラビリンス +structure.hydra_lair.name=ヒドラの巣 +structure.goblin_stronghold.name=ゴブリン騎士の拠点 +structure.dark_tower.name=ダークタワー +structure.yeti_cave.name=イエティの洞窟 +structure.aurora_palace.name=オーロラ宮殿 +structure.troll_cave_and_cloud_castle.name=トロールの洞窟とクラウドコテージ +structure.final_castle.name=最後の城 + +item.twilightforest.nagaScale.name=ナーガの鱗 +item.twilightforest.plateNaga.name=ナーガアーマー(胴) +item.twilightforest.legsNaga.name=ナーガアーマー(脚) +item.twilightforest.scepterTwilight.name=魔弾の杖 +item.twilightforest.scepterLifeDrain.name=吸精の杖 +item.twilightforest.scepterZombie.name=召喚の杖 +item.twilightforest.oreMeter.name=鉱石レーダー [制作中] +item.twilightforest.magicMap.name=魔法の地図(地上) +item.twilightforest.mazeMap.name=魔法の地図(迷宮) +item.twilightforest.oreMap.name=魔法の地図(迷宮/鉱石) +item.twilightforest.tfFeather.name=カラスの羽根 +item.twilightforest.magicMapFocus.name=魔法の羽根 +item.twilightforest.mazeMapFocus.name=魔法の金貨 +item.twilightforest.liveRoot.name=生きている根 +item.twilightforest.ironwoodRaw.name=樹鉄の素 +item.twilightforest.ironwoodIngot.name=樹鉄インゴット +item.twilightforest.ironwoodHelm.name=樹鉄ヘルム +item.twilightforest.ironwoodPlate.name=樹鉄プレート +item.twilightforest.ironwoodLegs.name=樹鉄レギンス +item.twilightforest.ironwoodBoots.name=樹鉄ブーツ +item.twilightforest.ironwoodSword.name=樹鉄の剣 +item.twilightforest.ironwoodShovel.name=樹鉄のシャベル +item.twilightforest.ironwoodPick.name=樹鉄のツルハシ +item.twilightforest.ironwoodAxe.name=樹鉄の斧 +item.twilightforest.ironwoodHoe.name=樹鉄のクワ +item.twilightforest.torchberries.name=トーチベリーの実 +item.twilightforest.venisonRaw.name=生の黄昏鹿肉 +item.twilightforest.venisonCooked.name=黄昏鹿肉ステーキ +item.twilightforest.hydraChop.name=ヒドラ肉 +item.twilightforest.fieryBlood.name=焦熱の血 +item.twilightforest.fieryIngot.name=焦熱インゴット +item.twilightforest.fieryHelm.name=焦熱ヘルム +item.twilightforest.fieryPlate.name=焦熱プレート +item.twilightforest.fieryLegs.name=焦熱レギンス +item.twilightforest.fieryBoots.name=焦熱ブーツ +item.twilightforest.fierySword.name=焦熱の剣 +item.twilightforest.fieryPick.name=焦熱のツルハシ +item.twilightforest.steeleafIngot.name=葉鋼 +item.twilightforest.steeleafHelm.name=葉鋼ヘルム +item.twilightforest.steeleafPlate.name=葉鋼プレート +item.twilightforest.steeleafLegs.name=葉鋼レギンス +item.twilightforest.steeleafBoots.name=葉鋼ブーツ +item.twilightforest.steeleafSword.name=葉鋼の剣 +item.twilightforest.steeleafShovel.name=葉鋼のシャベル +item.twilightforest.steeleafPick.name=葉鋼のツルハシ +item.twilightforest.steeleafAxe.name=葉鋼の斧 +item.twilightforest.steeleafHoe.name=葉鋼のクワ +item.twilightforest.minotaurAxe.name=ミノタウロスの斧 +item.twilightforest.mazebreakerPick.name=メイズブレイカー +item.twilightforest.transformPowder.name=変化の粉 +item.twilightforest.meefRaw.name=生のミノ肉 +item.twilightforest.meefSteak.name=ミーフステーキ +item.twilightforest.meefStroganoff.name=ミーフストロガノフ +item.twilightforest.mazeWafer.name=迷宮ウエハース +item.twilightforest.emptyMagicMap.name=白紙の魔法の地図(地上) +item.twilightforest.emptyMazeMap.name=白紙の魔法の地図(迷宮) +item.twilightforest.emptyOreMap.name=白紙の魔法の地図(鉱石/迷宮) +item.twilightforest.oreMagnet.name=鉱石磁石 +item.twilightforest.crumbleHorn.name=山鳴りの角笛 +item.twilightforest.peacockFan.name=孔雀扇 +item.twilightforest.moonwormQueen.name=女王月光虫 +item.twilightforest.charmOfLife1.name=命の護石Lv1 +item.twilightforest.charmOfLife2.name=命の護石Lv2 +item.twilightforest.charmOfKeeping1.name=鍵の護石Lv1 +item.twilightforest.charmOfKeeping2.name=鍵の護石Lv2 +item.twilightforest.charmOfKeeping3.name=鍵の護石Lv3 +item.twilightforest.towerKey.name=タワーキー +item.twilightforest.borerEssence.name=ボーラーエッセンス +item.twilightforest.carminite.name=カーミナイト +item.twilightforest.tf_trophy.name=%sトロフィー +item.twilightforest.trophy.hydra.name=ヒドラトロフィー +item.twilightforest.trophy.naga.name=ナーガトロフィー +item.twilightforest.trophy.lich.name=リッチトロフィー +item.twilightforest.trophy.ur_ghast.name=ウルガストトロフィー +item.twilightforest.trophy.snow_queen.name=雪の女王トロフィー +item.twilightforest.experiment115.name=エクスペリメント115 +item.twilightforest.armorShards.name=アーマーシャード +item.twilightforest.knightMetal.name=ナイトメタルインゴット +item.twilightforest.shardCluster.name=アーマーシャードの塊 +item.twilightforest.knightlyHelm.name=ナイトヘルム +item.twilightforest.knightlyPlate.name=ナイトプレート +item.twilightforest.knightlyLegs.name=ナイトグリーヴ +item.twilightforest.knightlyBoots.name=ナイトブーツ +item.twilightforest.knightlySword.name=ナイトソード +item.twilightforest.knightlyPick.name=ナイトピッケル +item.twilightforest.knightlyAxe.name=ナイトアックス +item.twilightforest.phantomHelm.name=ファントムヘルム +item.twilightforest.phantomPlate.name=ファントムプレート +item.twilightforest.lampOfCinders.name=灰のランプ +item.twilightforest.fieryTears.name=焦熱の涙 +item.twilightforest.iceBomb.name=アイスボム +item.twilightforest.yetiHelm.name=イエティの角兜 +item.twilightforest.yetiPlate.name=イエティジャケット +item.twilightforest.yetiLegs.name=イエティレギンス +item.twilightforest.yetiBoots.name=イエティブーツ +item.twilightforest.alphaFur.name=アルファイエティの毛皮 +item.twilightforest.arcticFur.name=防寒毛皮 +item.twilightforest.arcticHelm.name=防寒フード +item.twilightforest.arcticPlate.name=防寒ジャケット +item.twilightforest.arcticLegs.name=防寒レギンス +item.twilightforest.arcticBoots.name=防寒ブーツ +item.twilightforest.magicBeans.name=魔法の豆 +item.twilightforest.giantPick.name=巨人のツルハシ +item.twilightforest.giantSword.name=巨人の剣 +item.twilightforest.tripleBow.name=トライボウ +item.twilightforest.seekerBow.name=シーカーボウ +item.twilightforest.iceBow.name=アイスボウ +item.twilightforest.enderBow.name=エンダーボウ +item.twilightforest.iceSword.name=アイスソード +item.twilightforest.glassSword.name=ガラスの剣 +item.twilightforest.knightmetalRing.name=ナイトメタルの輪 +item.twilightforest.chainBlock.name=モーニングスター +item.twilightforest.cubeTalisman.name=六面の加護 +item.twilightforest.cubeOfAnnihilation.name=破滅の箱 + +item.twilightforest.minotaurAxe.tooltip=チャージアタック +item.twilightforest.knightlySword.tooltip=武装ターゲット特効 +item.twilightforest.knightlyPick.tooltip=武装ターゲット特効 +item.twilightforest.knightlyAxe.tooltip=非武装ターゲット特効 +item.twilightforest.giantPick.tooltip=巨人ブロック破壊 +item.twilightforest.fieryPick.tooltip=自動精錬 +item.twilightforest.fierySword.tooltip=炎の刻印 +item.twilightforest.fieryHelm.tooltip=炎のオーラ +item.twilightforest.fieryPlate.tooltip=炎のオーラ +item.twilightforest.fieryLegs.tooltip=炎のオーラ +item.twilightforest.fieryBoots.tooltip=炎のオーラ +item.twilightforest.phantomHelm.tooltip=不滅のオーラ +item.twilightforest.phantomPlate.tooltip=不滅のオーラ +item.twilightforest.yetiHelm.tooltip=凍えるオーラ +item.twilightforest.yetiPlate.tooltip=凍えるオーラ +item.twilightforest.yetiLegs.tooltip=凍えるオーラ +item.twilightforest.yetiBoots.tooltip=凍えるオーラ + +item.twilightforest.arctic_armor.tooltip=染色可能 + +entity.twilightforest.wild_boar.name=黄昏イノシシ +entity.twilightforest.bighorn_sheep.name=オオツノヒツジ +entity.twilightforest.deer.name=黄昏鹿 +entity.twilightforest.redcap.name=レッドキャップ +entity.twilightforest.swarm_spider.name=群れ蜘蛛 +entity.twilightforest.naga.name=ナーガ +entity.twilightforest.naga_segment.name=ナーガセグメント +entity.twilightforest.skeleton_druid.name=スケルトンドルイド +entity.twilightforest.hostile_wolf.name=凶暴な狼 +entity.twilightforest.wraith.name=レイス +entity.twilightforest.hedge_spider.name=生垣蜘蛛 +entity.twilightforest.hydra.name=ヒドラ +entity.twilightforest.hydra_head.name=ヒドラの頭 +entity.twilightforest.lich.name=リッチ +entity.twilightforest.penguin.name=ペンギン +entity.twilightforest.tiny_bird.name=小鳥 +entity.twilightforest.squirrel.name=リス +entity.twilightforest.bunny.name=黄昏ウサギ +entity.twilightforest.raven.name=黄昏カラス +entity.twilightforest.quest_ram.name=色食みの羊 +entity.twilightforest.kobold.name=コボルト +entity.twilightforest.boggard.name=幽霊 [未実装] +entity.twilightforest.lich_minion.name=リッチのしもべ +entity.twilightforest.loyal_zombie.name=ロイヤルゾンビ +entity.twilightforest.mosquito_swarm.name=空腹蚊柱 +entity.twilightforest.death_tome.name=死者の書 +entity.twilightforest.minotaur.name=ミノタウロス +entity.twilightforest.minoshroom.name=ミノッシュルーム +entity.twilightforest.fire_beetle.name=ファイアビートル +entity.twilightforest.slime_beetle.name=スライムビートル +entity.twilightforest.pinch_beetle.name=ピンチビートル +entity.twilightforest.maze_slime.name=迷宮スライム +entity.twilightforest.redcap_sapper.name=レッドキャップ工兵 +entity.twilightforest.mist_wolf.name=ミストウルフ +entity.twilightforest.king_spider.name=キングスパイダー +entity.twilightforest.firefly.name=ホタル +entity.twilightforest.mini_ghast.name=カーミナイトガストリング +entity.twilightforest.tower_ghast.name=カーミナイトガストガード +entity.twilightforest.tower_golem.name=カーミナイトゴーレム +entity.twilightforest.tower_termite.name=タワーウッドボーラー +entity.twilightforest.tower_broodling.name=カーミナイトブローディング +entity.twilightforest.ur_ghast.name=ウルガスト +entity.twilightforest.blockchain_goblin.name=鉄球使いゴブリン +entity.twilightforest.goblin_knight_upper.name=ゴブリン騎士(上) +entity.twilightforest.goblin_knight_lower.name=ゴブリン騎士(下) +entity.twilightforest.helmet_crab.name=カブトヤドカリ +entity.twilightforest.knight_phantom.name=ナイトファントム +entity.twilightforest.yeti.name=イエティ +entity.twilightforest.yeti_alpha.name=アルファイエティ +entity.twilightforest.winter_wolf.name=ウィンターウルフ +entity.twilightforest.snow_guardian.name=スノーガーディアン +entity.twilightforest.stable_ice_core.name=アイスコア +entity.twilightforest.unstable_ice_core.name=アイスコア(炸裂) +entity.twilightforest.snow_queen.name=雪の女王 +entity.twilightforest.troll.name=ケイブトロール +entity.twilightforest.giant_miner.name=巨人(ツルハシ) +entity.twilightforest.armored_giant.name=巨人(剣) +entity.twilightforest.ice_crystal.name=アイスクリスタル +entity.twilightforest.apocalypse_cube.name=アポカリプスキューブ [未実装] +entity.twilightforest.adherent.name=使徒 [未実装] +entity.twilightforest.castle_guardian.name=キャッスルガーディアン [未実装] + +twilightforest.effect.frosted=凍結 + +twilightforest.misc.wip0=このブロックは制作中であり、世界を傷つけたり意図しない影響を与えたりするバグが存在する可能性があります。 +twilightforest.misc.wip1=慎重に使用してください。 +twilightforest.misc.nyi=このブロックには、まだ実装されていないエフェクトがあります。 + +twilightforest.loading.title.enter=黄昏の森に入り込んでいます... +twilightforest.loading.title.leave=黄昏の森から抜け出しています... + +#Config +twilightforest.config.dimension=ディメンジョンの設定 +twilightforest.config.dimension.tooltip=Minecraftを再起動するまで有効になりません。 +twilightforest.config.dimension_id=ディメンジョンID +twilightforest.config.dimension_id.tooltip=黄昏の森ディメンジョンに割り当てるID。 他のMODと競合している場合は変更して下さい。 +twilightforest.config.dimension_seed=ディメンジョンシード +twilightforest.config.dimension_seed.tooltip=これを設定すると、黄昏の森ディメンションの一部を 生成するときに、通常のワールドのシードよりも優先されます。 +twilightforest.config.spawn_in_tf=黄昏の森にスポーンする +twilightforest.config.spawn_in_tf.tooltip=trueにすると、初期スポーン地点が黄昏の森になります。 + +twilightforest.config.compat=互換性 +twilightforest.config.compat.tooltip=Twilight Forestの互換設定を有効にします。 クラッシュが起きる場合や、必要でない場合はfalseにして下さい。 + +twilightforest.config.performance=パフォーマンスの調整 +twilightforest.config.performance.tooltip=ワールドのパフォーマンスを向上させるための設定 +twilightforest.config.canopy_coverage=林冠木のカバレッジ +twilightforest.config.canopy_coverage.tooltip=林冠木のカバレッジの量。小さな値にするとワールド生成スピードが向上しますが、薄い森になります。 +twilightforest.config.twilight_oaks=トワイライトオークの出現率 +twilightforest.config.twilight_oaks.tooltip=黄昏の森のチャンク内にトワイライトオークの木が出現する確率。 数値が高いほどトワイライトオークの木の数が少なくなり、パフォーマンスが向上します。 +twilightforest.config.leaves_light_opacity=黄昏の森の木の葉の不透明度 +twilightforest.config.leaves_light_opacity.tooltip=葉が完全な立方体でない場合、遮光量を調整するために葉の不透明度を設定します。 +twilightforest.config.leaves_full_cube=Twilight Forestの木の葉をフルブロックにする +twilightforest.config.leaves_full_cube.tooltip=これをfalseに設定すると、葉は完全な立方体ではなくなります。これにより、光を遮断しなくなるので、ガラスと同等の扱いになります。一部の照明チェックの負担を軽減します。 +twilightforest.config.glacier_packed_ice=氷河の氷を氷塊にする +twilightforest.config.glacier_packed_ice.tooltip=これを設定すると、黄昏の森の氷河が氷ではなく氷塊になり、 光チェックの計算量が減少します。 + +twilightforest.config.silent_cicadas=セミを静かにする +twilightforest.config.silent_cicadas.tooltip=音が気になる人はtrueに設定してください。 + +twilightforest.config.portals_in_other_dimensions=別ディメンジョンでのポータル作成 +twilightforest.config.portals_in_other_dimensions.tooltip=黄昏のポータルをオーバーワールド以外でも作成できるようにします。悪用される可能性があります。 +twilightforest.config.admin_portals=黄昏のポータル作成は管理者のみにする +twilightforest.config.admin_portals.tooltip=黄昏のポータル作成を管理者(OP権限)しかできないようにします。これにより管理者の周辺のみポータル作成条件をスキャンするようになり、負荷が減ります。 +twilightforest.config.portals=黄昏のポータルを無効にする +twilightforest.config.portals.tooltip=黄昏のポータル作成を完全に無効にします。ディメンジョンの移動を無効にしたい場合に設定して下さい。 +twilightforest.config.portal_creator=ポータル作成アイテム +twilightforest.config.portal_creator.tooltip=黄昏のポータルを作成するときに使用するアイテムID。 +twilightforest.config.portal_creator_meta=ポータル作成アイテムのメタデータ +twilightforest.config.portal_creator_meta.tooltip=ポータル作成アイテムのメタデータ。 -1を指定すると全てのメタデータが有効になります。 +twilightforest.config.portal_lighting=ポータル作成時に雷を起こさない +twilightforest.config.portal_lighting.tooltip=trueにすると、ポータル作成時に爆発して火がつかないようになります。好きではない人のための設定。 +twilightforest.config.portal_return=ポータルを両方のディメンジョンに作る +twilightforest.config.portal_return.tooltip=falseに設定すると、帰るときにもポータルを作成する必要があります。 + +twilightforest.config.uncrafting=解体作業台の解体を無効にする +twilightforest.config.uncrafting.tooltip=解体作業台の解体を無効にします。他のMODと併用する際に悪用可能である場合はtrueに設定して下さい。 + +twilightforest.config.antibuilder_blacklist=アンチビルダーのブラックリスト +twilightforest.config.antibuilder_blacklist.tooltip=アンチビルダーが破壊しないブロックのリスト(domain:block:meta)。 metaはオプション。 + +twilightforest.config.animate_trophyitem=インベントリ内でトロフィーを回転させる +twilightforest.config.animate_trophyitem.tooltip=インベントリ内でトロフィーを回転させます。パフォーマンスへの影響は全くありません。好きではない人はfalseにして下さい。 + +twilightforest.config.shield_parry=盾による受け流し +twilightforest.config.shield_parry.tooltip=我々は受け流しのために Shield Parry mod を導入することを推奨しますが、なくても設定は残ります。 +twilightforest.config.parry_non_twilight=黄昏の森以外の飛翔体の受け流し +twilightforest.config.parry_non_twilight.tooltip=trueに設定すると、黄昏の森以外の飛翔体も受け流します。Shield Parry mod をダウンロードすることを推奨します。 +twilightforest.config.parry_window_arrow=矢の受け流し時間 +twilightforest.config.parry_window_arrow.tooltip=盾を上げた後に矢を受け流すことができる時間(ティック)。1秒は20ティックです。 +twilightforest.config.parry_window_fireball=火の玉の受け流し時間 +twilightforest.config.parry_window_fireball.tooltip=盾を上げた後に火の玉を受け流すことができる時間(ティック)。1秒は20ティックです。 +twilightforest.config.parry_window_throwable=投擲物の受け流し時間 +twilightforest.config.parry_window_throwable.tooltip=盾を上げた後に投擲物を受け流すことができる時間(ティック)。1秒は20ティックです。 +twilightforest.config.shieldParryTicksBeam=ビーム???の受け流し時間 +twilightforest.config.shieldParryTicksBeam.tooltip=??? + +twilightforest.config.loading_screen=ローディング画面 +twilightforest.config.loading_screen.tooltip=クライアント限定: ローディング画面を設定します +twilightforest.config.loading_icon_enable=アイテムアイコンのアニメーションを有効にする +twilightforest.config.loading_icon_enable.tooltip=ローディング中のアイテムアイコンを動かします。パフォーマンスへの影響は全くありません。好きではない人はfalseにして下さい。 +twilightforest.config.loading_screen_swap_frequency=ローディング画面の切り替え +twilightforest.config.loading_screen_swap_frequency.tooltip=ローディング画面の切り替え間隔を設定します。 0にすると切り替えません。 +twilightforest.config.loading_icon_wobble_bounce_frequency=アイコンのアニメーション速度 +twilightforest.config.loading_icon_wobble_bounce_frequency.tooltip=アイテムをアニメーションさせる頻度を設定します。 +twilightforest.config.loading_icon_scale=アイコンスケーリング +twilightforest.config.loading_icon_scale.tooltip=ローディング中のアイコンの大きさを設定します。 +twilightforest.config.loading_icon_bounciness=アイコンのバウンド +twilightforest.config.loading_icon_bounciness.tooltip=アイコンをどれだけバウンドさせるか設定します。 +twilightforest.config.loading_icon_tilting=アイコンの揺れ +twilightforest.config.loading_icon_tilting.tooltip=アイコンをどれだけ揺らすか設定します。 +twilightforest.config.loading_icon_tilt_pushback=アイコンの傾き(オフセット) +twilightforest.config.loading_icon_tilt_pushback.tooltip=アイコンの傾きを戻すためのプッシュバック値を設定します。 + +twilightforest.book.lichtower.1=§8[[冒険者のノート]]\nモンスターに齧られている§0\n\n私はこの塔を囲む奇妙なオーラを調べ始めた。塔のレンガは、私が以前見たよりも強い呪いによって保護されている。呪いの魔力は周辺まで広がっている。 +twilightforest.book.lichtower.2=私の故郷では、この魔力を扱う選択肢がたくさんあるが、私にできることは限られている。研究しなければならないだろう... +twilightforest.book.lichtower.3=§8[[数ページ後]]§0\n\n画期的な発見だ!旅の途中、私は飾られた神殿の中に巨大な蛇のようなモンスターを見つけた。そしてその近くで、風化した緑色の鱗を拾った。鱗の魔力は、私が求めていた呪いを打ち破る力を持っているようだが、かなり弱い。 +twilightforest.book.lichtower.4=モンスターから直接鱗を採取する必要があるだろう。 + +twilightforest.book.labyrinth.1=§8[[冒険者のノート]]\n防水紙に書かれている§0\n\nこの沼地の蚊は厄介だが、奇妙だ。それらの大半は自然に発生したようではなく、生態系にも影響していないようだ。 +twilightforest.book.labyrinth.2=この蚊は、何らかの魔法の呪いではないかと疑い始めた。 +twilightforest.book.labyrinth.3=§8[[次のページ]]§0\n\n更に私は、ここでラビリンスの保護呪文にも遭遇した。保護呪文と蚊はどちらも呪いだ。この呪いは私が過去に経験したものとは異なる源泉からなるようだ。更に研究しなければならない。 +twilightforest.book.labyrinth.4=§8[[次のページ]]§0\n\n呪いは、単独では作れないほどの強力なもののようだ。複数の魔法使いが協力する必要がある。魔法使いが一人でも協力を止めると、沼全体の呪いが落ちるようだ。 +twilightforest.book.labyrinth.5=不思議なことに、私の占いでは、この呪いは近くにいる魔法使いのものではなさそうだ。私は、近くの尖った屋根の塔の一つで興味深いものを見つけた... + +twilightforest.book.hydralair.1=§8[[冒険者のノート]]\n耐火性のある紙に書かれている§0\n\n炎は、私のような達人の冒険者にとってはたいした障害ではない。私は火の海を横切り、溶岩の海を泳いだ。この燃えるような大気は興味深いものだが、最終的には何の妨げにもならない。 +twilightforest.book.hydralair.2=私を足止めさせたのは、別の保護呪文である。今回は、この炎の沼地の王である巨大なモンスターを取り囲んでいる。これは私が遭遇した最初の保護呪文ではなく、私はその仕組みの謎を解明し始めている。 +twilightforest.book.hydralair.3=この呪文が他の呪文と同じようなものであるなら、周辺の強力なモンスターによって維持されていると考えられる。炎の沼地を取り囲むようにいくつかの沼地があり、その沼地の地下にはミノタウロスの住処であるラビリンスがある。 +twilightforest.book.hydralair.4=呪文の主は、他のミノタウロスとは異なる、更に強力なミノタウロスのような生物と考えるのが妥当だろう... + +twilightforest.book.tfstronghold.1=§8[[冒険者のノート]]\nかすかに輝く紙に書かれている§0\n\nこのエリアを取り巻く暗闇の渦は、闇の森全体の保護呪文の兆候だろう。この呪文は失明の原因になる。私はこのエリアでいくつかの興味深いものを見つけており、探索を続けたいと思う。 +twilightforest.book.tfstronghold.2=§8[[次のページ]]§0\n\n私は闇の森の中で遺跡を見つけた。これらは騎士が住むタイプの拠点のようだ。しかし、この拠点は騎士ではなくゴブリンだらけだ。彼らは騎士の鎧を身に着けてはいるが、騎士とはかけ離れた振る舞いである。 +twilightforest.book.tfstronghold.3=§8[[次のページ]]§0\n\n遺跡の奥で、私は台座を見つけた。台座は、騎士が自らの強さを証明するためにトロフィーを置くタイプのもののようだ。 +twilightforest.book.tfstronghold.4=強力な杖を手に入れれば、闇の森の呪いを弱めることができそうだ。また、台座の上にトロフィーを置けば、拠点の主要部分にアクセスすることが +twilightforest.book.tfstronghold.5=できそうだ。 + +twilightforest.book.darktower.1=§8[[冒険者のノート]]\n爆発に耐えたようだ§0\n\nこの塔の装置は、私には反応しない。魔法は反応しているようだが、駄目だ。塔の装置が近くの強力なグループによって抑制されているようだ。 +twilightforest.book.darktower.2=§8[[次のページ]]§0\n\n近くの拠点の奥から魔力が供給されているようだ。それはゴブリンのものではなく、強力だが焦点が合っていないようだ。拠点にはまだ何かいるようだ。 +twilightforest.book.darktower.3=§8[[次のページ]]§0\n\n私の分析では、この魔力は何らかのグループから発せられているようだ。補給をして、拠点に戻ることにしよう... + +twilightforest.book.yeticave.1=§8[[冒険者のノート]]\n霜で覆われている§0\n\nこの雪の大地を取り巻く吹雪は絶え間なく続いている。これは普通の雪ではなく、魔法によるものだ。これを引き起こしている原因を見つけるために実験を行う必要がありそうだ。 +twilightforest.book.yeticave.2=§8[[次のページ]]§0\n\n呪いは、単独では作れないほどの強力なもののようだ。複数の魔法使いが協力する必要がある。魔法使いが一人でも協力を止めると、吹雪は止むようだ。 +twilightforest.book.yeticave.3=不思議なことに、私の占いでは、この呪いは近くにいる魔法使いのものではなさそうだ。私は、近くの尖った屋根の塔の一つで興味深いものを見つけた... + +twilightforest.book.icetower.1=§8[[冒険者のノート]]\n氷漬けになっていた§0\n\n私は、吹雪を乗り越え、氷河の頂上にある恐ろしい氷嵐に遭遇した。更に探検し、極地に存在するオーロラ色に輝く素晴らしい氷の宮殿を見つけた。それは何らかの呪いによって保護されているようだ。 +twilightforest.book.icetower.2=§8[[次のページ]]§0\n\n私とて初心者ではない。この手の呪いは、近くのモンスターの力によって与えられているはずだ。 +twilightforest.book.icetower.3=炎の沼地を取り巻く呪いの原因は、ミノタウロスのリーダーだった。氷河の周辺には多くのイエティがいる。恐らく、彼らのリーダーがいるのだろう... + +twilightforest.book.trollcave.1=§8[[冒険者のノート]]\n酸で傷ついている§0\n\nこの地域を取り巻く有毒な暴風雨から身を守る方法はなさそうだ。少し調べたところ、私が過去に遭遇した保護呪文とは異なる保護呪文がかかっているようだ。 +twilightforest.book.trollcave.2=この呪文が何らかの形でこの天候に関わっていると思われる。さらなる研究が必要だ...\n\n§8[[次のページ]]§0\n\nこのような魔法は、この世界の複数の無敗の強大な悪によるものに違いない。 +twilightforest.book.trollcave.3=私の研究では、猛烈な沼地、深い暗闇で覆われた森、そして雪で覆われた地域に手がかりがあるのではないかと思われる。 + +twilightforest.book.unknown.1=§8[[この本は何度もコピーされているようだ]]§0\n\n私にはこの構造を取り巻くフィールドを説明することはできないが、魔法は強力だ。この呪いが他と同様のものなら、それを解く答えはどこかにある。 +twilightforest.book.unknown.2=恐らく、私がやり残したこと、あるいはまだ倒していないモンスターがいるのだろう。私は戻る必要がある。後でこの場所に戻り、何かが変わるかどうか確認してみよう。 + +# Fluid + +fluid.fierymetal=溶融焦熱 +fluid.knightmetal=溶融ナイトメタル +fluid.fiery_essence=焦熱エッセンス + +# TCon + +material.nagascale.name=ナーガの鱗 +material.nagascale.prefix=ナーガの鱗の%s +material.steeleaf.name=葉鋼 +material.steeleaf.prefix=葉鋼の%s +material.fierymetal.name=焦熱 +material.fierymetal.prefix=焦熱の%s +material.knightmetal.name=ナイトメタル +material.knightmetal.prefix=ナイトメタルの%s +material.raven_feather.name=カラスの羽根 +material.raven_feather.prefix=カラスの羽根の%s + +modifier.twilit.name=トワイリット +modifier.twilit.desc=§o黄昏の森の明かりの祝福§r\n黄昏の森での採掘速度が上がる。\n黄昏の森以外では攻撃力が上がる。 +modifier.twilit.extra.speed=黄昏の森での採掘速度: +%s +modifier.twilit.extra.damage=黄昏の森以外でのダメージ増加: +%s +modifier.precipitate.name=まっしぐら +modifier.precipitate.desc=§o最後に残された脱出プラン§r\n体力が減ると採掘速度が上がる! +modifier.synergy.name=シナジー +modifier.synergy.desc=§oほら、苔なしだ!§r\n葉鋼がホットバーにあると、自動的に耐久力を回復させる。 +modifier.stalwart.name=屈強 +modifier.stalwart.desc=§o勇猛果敢§r\n攻撃が当たると勇気が湧いてくる。 +modifier.veiled.name=ヴェール +modifier.veiled.desc=§o幽霊のようだ!§r\n飛翔体が見えなくなる。 \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/ko_kr.lang b/src/main/resources/assets/twilightforest/lang/ko_kr.lang new file mode 100644 index 0000000000..2f6f1094df --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/ko_kr.lang @@ -0,0 +1,666 @@ +#PARSE_ESCAPES + +itemGroup.twilightForest=황혼의 숲 + +# ADVANCEMENTS +advancement.twilightforest.root.desc=신비한 마법이 깃든 숲으로 들어가세요! + +# General progression +advancement.twilightforest.hedge=밟아버리기! +advancement.twilightforest.hedge.desc=미로에 있는 거미를 처치하세요. + +advancement.twilightforest.hill1=그거 내 부츠야! +advancement.twilightforest.hill1.desc=작은 할로우 언덕에 있는 붉은모자고블린을 처치하세요. +advancement.twilightforest.hill2=무슨 소리였지? +advancement.twilightforest.hill2.desc=할로우 언덕에 있는 붉은모자공병고블린을 처치하세요.. +advancement.twilightforest.hill3=아이 씨 유 +advancement.twilightforest.hill3.desc=큰 할로우 언덕에 있는 숲의유령을 처치하세요. + +advancement.twilightforest.quest_ram=바아아~ +advancement.twilightforest.quest_ram.desc=램의 퀘스트를 완료하세요. + +# Map +advancement.twilightforest.magic_map_focus=여정의 시작 +advancement.twilightforest.magic_map_focus.desc=까마귀 깃털, 발광석 가루, 토치베리를 조합해 마법지도를 만드세요. +advancement.twilightforest.magic_map=기나긴 모험 +advancement.twilightforest.magic_map.desc=마법지도를 제작하세요. +advancement.twilightforest.maze_map=미로는 지긋지긋해 +advancement.twilightforest.maze_map.desc=미로지도를 제작하세요. +advancement.twilightforest.ore_map=가치있는 것 +advancement.twilightforest.ore_map.desc=마법/광물지도를 제작하세요. + +# Mainline beginning progression +advancement.twilightforest.twilight_hunter=고요함 +advancement.twilightforest.twilight_hunter.desc=숲의 동물을 사냥하세요. + +advancement.twilightforest.kill_naga=나가 사냥꾼 +advancement.twilightforest.kill_naga.desc=나가 신전에서 나가를 물리치세요! - 그의 비늘이 리치 성의 장막을 무력화할 수도?... +advancement.twilightforest.naga_armors=네 비늘 좋더라 +advancement.twilightforest.naga_armors.desc=나가의 비늘로 가슴과 다리 보호대를 제작하세요. + +advancement.twilightforest.kill_lich=리치 사냥꾼 +advancement.twilightforest.kill_lich.desc=리치 성에서 리치를 물리치세요! - 늪의 독기를 뚫어라. +advancement.twilightforest.lich_scepters=지배자 +advancement.twilightforest.lich_scepters.desc=리치의 도구를 모두 습득하세요. + +# Swamp Progression +advancement.twilightforest.progress_labyrinth=강력한 스트로가노프! +advancement.twilightforest.progress_labyrinth.desc=그 고기스프는 당신을 강하게 해줄겁니다! - 화염의 늪 따위야.. +advancement.twilightforest.kill_hydra=히드라 사냥꾼 +advancement.twilightforest.kill_hydra.desc=히드라를 사냥하세요! - 검은숲을 향하여. +advancement.twilightforest.mazebreaker=미로 부수기 +advancement.twilightforest.mazebreaker.desc=미로의 비밀장소에서 미로파괴자를 획득하세요. +advancement.twilightforest.hydra_chop=만화고기!? +advancement.twilightforest.hydra_chop.desc=배고픔이 한계에 도달했을 때 히드라 고기를 먹으세요. + +# Dark Forest Progression +advancement.twilightforest.progress_trophy_pedestal=트로피 챔피언 +advancement.twilightforest.progress_trophy_pedestal.desc=검은숲 폐허에 있는 트로피 받침대를 장식하세요. +advancement.twilightforest.progress_knights=카미나이트 적응 +advancement.twilightforest.progress_knights.desc=검은숲 폐허에 있는 유령을 해결하고 카미나이트 탑의 장치들을 복종시키세요. +advancement.twilightforest.ghast_trap=기묘한 것들 +advancement.twilightforest.ghast_trap.desc=가스트 트랩 주위의 미니 가스트들을 해치우고 유어-가스트를 약화시키세요. +advancement.twilightforest.progress_ur_ghast=불의 눈물 +advancement.twilightforest.progress_ur_ghast.desc=유어-가스트를 위로하고 그녀의 눈물을 획득하세요. + +advancement.twilightforest.experiment_115=케이크? +advancement.twilightforest.experiment_115.desc=케이크 맞지?? +advancement.twilightforest.experiment_115_2=오늘의 일기: 대성공! +advancement.twilightforest.experiment_115_2.desc=이처럼 맛있고 촉촉할 수가! +advancement.twilightforest.experiment_115_3=115년 동안 매일 No.115를 먹을거야 +advancement.twilightforest.experiment_115_3.desc=No.115를 115개 먹어야지~ + +# Snow Forest Progression +advancement.twilightforest.progress_yeti=알파의 모피 +advancement.twilightforest.progress_yeti.desc=알파 예티의 부드러운 가죽으로 빙하의 추위를 이겨내세요. +advancement.twilightforest.progress_glacier=맑은 하늘 +advancement.twilightforest.progress_glacier.desc=오로라 궁전 꼭대기에 있는 눈의 여왕을 굴복시키세요. +advancement.twilightforest.arctic_dyed=패션의 완성 +advancement.twilightforest.arctic_dyed.desc=모든 아크틱 방어구를 염색하세요. + +# Mid-way Misc. Stuff +advancement.twilightforest.glass_sword=잘 사용해봐 +advancement.twilightforest.glass_sword.desc=쓸모가 있기를 빕니다... + +advancement.twilightforest.twilight_dining=진정한 여행의 목적 +advancement.twilightforest.twilight_dining.desc=황혼의 숲에 있는 모든 음식들을 섭취하세요. + +advancement.twilightforest.fiery_set=피와 눈물 +advancement.twilightforest.fiery_set.desc=적어도 하나의 파이어리 방어구를 입고 파이어리 도구를 사용하세요. + +# Highlands +advancement.twilightforest.progress_merge=쇼다운 +advancement.twilightforest.progress_merge.desc=히드라, 유어-가스트, 눈의 여왕을 해치우고 산성비를 멈춰 고원으로 진입하세요. +advancement.twilightforest.progress_troll=불타오르네 +advancement.twilightforest.progress_troll.desc=트롤 동굴에서 재의 램프를 발견하세요! - 가시덩굴을 잿더미로.. +advancement.twilightforest.progress_thorns=가시덩굴을 지나서 +advancement.twilightforest.progress_thorns.desc=가시로 가득한 곳 너머에 있는 성의 문을 여세요. +advancement.twilightforest.progress_castle=멋져! +advancement.twilightforest.progress_castle.desc=이 멋진 성에 대체 무슨일이?!? + +twilightforest.trophyPedestal.ineligible=넌 자격이 없다. +twilightforest.ore_meter.range=Radius: %s, Origin: [%s, %s] +twilightforest.ore_meter.exposed=Exposed: %s +twilightforest.scepter_charges=%d charges left + +tile.twilightforest.Log.0.name=황혼 참나무 +tile.twilightforest.Log.1.name=케너피 나무 +tile.twilightforest.Log.2.name=맹그로브 나무 +tile.twilightforest.Log.3.name=다크우드 나무 +tile.twilightforest.Leaves.0.name=황혼 참나무 잎 +tile.twilightforest.Leaves.1.name=케너피 나무 잎 +tile.twilightforest.Leaves.2.name=맹그로브 나무 잎 +tile.twilightforest.Leaves.3.name=무지개 참나무 잎 +tile.twilightforest.Firefly.name=반딧불이 +tile.twilightforest.Cicada.name=매미 +item.twilightforest.Portal.name=황혼의 숲 포탈 +tile.twilightforest.Portal.name=황혼의 숲 포탈 +tile.twilightforest.Mazestone.0.name=미로 돌 +tile.twilightforest.Mazestone.1.name=미로 석재 벽돌 +tile.twilightforest.Mazestone.2.name=조각된 미로 돌 +tile.twilightforest.Mazestone.3.name=장식된 미로 석재 벽돌 +tile.twilightforest.Mazestone.4.name=금 간 미로 석재 벽돌 +tile.twilightforest.Mazestone.5.name=이끼 낀 미로 석재 벽돌 +tile.twilightforest.Mazestone.6.name=미로 돌 모자이크 +tile.twilightforest.Mazestone.7.name=미로 돌 테두리 +tile.twilightforest.Mazestone.8.name=미로 돌 천장 +tile.twilightforest.Hedge.0.name=생울타리 +tile.twilightforest.Hedge.1.name=다크우드 나무 잎 +tile.twilightforest.BossSpawner.0.name=나가 스포너 +tile.twilightforest.BossSpawner.1.name=리치 스포너 +tile.twilightforest.BossSpawner.2.name=히드라 스포너 +tile.twilightforest.BossSpawner.3.name=유어-가스트 스포너 +tile.twilightforest.BossSpawner.4.name=유령기사 스포너 +tile.twilightforest.FireflyJar.name=반딧불이 병 +tile.twilightforest.Plant.0.name=이끼 조각 +tile.twilightforest.Plant.1.name=메야플 +tile.twilightforest.Plant.2.name=클로버 조각 [WIP] +tile.twilightforest.Plant.3.name=피들헤드 +tile.twilightforest.Plant.4.name=머쉬그룸 +tile.twilightforest.Plant.5.name=숲 잔디 +tile.twilightforest.Plant.6.name=건조된 덤불 +tile.twilightforest.Plant.7.name=토치베리 가지 +tile.twilightforest.Plant.8.name=뿌리가닥 +tile.twilightforest.Roots.0.name=뿌리 +tile.twilightforest.Roots.1.name=뿌리 +tile.twilightforest.UncraftingTable.name=분해 작업대 +tile.twilightforest.FireJet.0.name=연기 블록 +tile.twilightforest.FireJet.1.name=감싸진 스모커 블록 +tile.twilightforest.FireJet.2.name=감싸진 스모커 블록 +tile.twilightforest.FireJet.3.name=화염 분출기 +tile.twilightforest.FireJet.4.name=터지는 화염 분출기 +tile.twilightforest.FireJet.5.name=불타는 화염 분출기 +tile.twilightforest.FireJet.6.name=감싸진 화염 분출기 +tile.twilightforest.FireJet.7.name=감싸진 터지는 화염 분출기 +tile.twilightforest.FireJet.8.name=감싸진 불타는 화염 분출기 +tile.twilightforest.Nagastone.0.name=나가스톤 머리 +tile.twilightforest.Nagastone.1.name=나가스톤 +tile.twilightforest.Sapling.0.name=병든 황혼 참나무 묘목 +tile.twilightforest.Sapling.1.name=케너피 나무 묘목 +tile.twilightforest.Sapling.2.name=맹그로브 나무 묘목 +tile.twilightforest.Sapling.3.name=다크우드 나무 묘목 +tile.twilightforest.Sapling.4.name=튼튼한 황혼 참나무 묘목 +tile.twilightforest.Sapling.5.name=시간의 나무 묘목 +tile.twilightforest.Sapling.6.name=변화의 나무 묘목 +tile.twilightforest.Sapling.7.name=광부의 나무 묘목 +tile.twilightforest.Sapling.8.name=분류 나무 묘목 +tile.twilightforest.Sapling.9.name=무지개 참나무 묘목 +tile.twilightforest.Moonworm.name=달벌레 +tile.twilightforest.MagicLog.0.name=시간 나무 +tile.twilightforest.MagicLog.1.name=변화 나무 +tile.twilightforest.MagicLog.2.name=광부 나무 +tile.twilightforest.MagicLog.3.name=분류 나무 +tile.twilightforest.MagicLogSpecial.0.name=시간나무 시계 +tile.twilightforest.MagicLogSpecial.1.name=변화의 하트 +tile.twilightforest.MagicLogSpecial.2.name=광부나무 핵 +tile.twilightforest.MagicLogSpecial.3.name=분류나무 엔진 +tile.twilightforest.MagicLeaves.0.name=시간 나무 잎 +tile.twilightforest.MagicLeaves.1.name=변화 나무 잎 +tile.twilightforest.MagicLeaves.2.name=광부 나무 잎 +tile.twilightforest.MagicLeaves.3.name=분류 나무 잎 +tile.twilightforest.TowerStone.0.name=다크우드 나무 판자 +tile.twilightforest.TowerStone.1.name=감싸진 다크우드 나무 +tile.twilightforest.TowerStone.2.name=조각난 다크우드 나무 판자 +tile.twilightforest.TowerStone.3.name=이끼 낀 다크우드 나무 판자 +tile.twilightforest.TowerStone.4.name=감염된 다크우드 나무 판자 +tile.twilightforest.TowerDevice.0.name=구현 블록 +tile.twilightforest.TowerDevice.1.name=작동된 구현 블록 +tile.twilightforest.TowerDevice.2.name=점멸 블록 +tile.twilightforest.TowerDevice.3.name=작동된 점멸 블록 +tile.twilightforest.TowerDevice.4.name=봉인된 점멸 블록 +tile.twilightforest.TowerDevice.5.name=봉인 해제된 점멸 블록 +tile.twilightforest.TowerDevice.6.name=카미나이트 구축기 +tile.twilightforest.TowerDevice.7.name=작동된 카미나이트 구축기 +tile.twilightforest.TowerDevice.8.name=작동을 멈춘 카미나이트 구축기 +tile.twilightforest.TowerDevice.9.name=역구축기 +tile.twilightforest.TowerDevice.10.name=가스트 함정 +tile.twilightforest.TowerDevice.11.name=작동된 가스트 함정 +tile.twilightforest.TowerDevice.12.name=카미나이트 원자로 +tile.twilightforest.TowerDevice.13.name=작동된 카미나이트 원자로 +tile.twilightforest.TowerTranslucent.0.name=구현 블록 +tile.twilightforest.TowerTranslucent.1.name=작동된 구현 블록 +tile.twilightforest.TowerTranslucent.2.name=카미나이트 블록 +tile.twilightforest.TowerTranslucent.3.name=작동된 카미나이트 블록 +tile.twilightforest.TowerTranslucent.4.name=역구축기 블록 +tile.twilightforest.TowerTranslucent.5.name=카미나이트 원자로 파편 +tile.twilightforest.TowerTranslucent.6.name=가짜 금 블록 +tile.twilightforest.TowerTranslucent.7.name=가짜 다이아몬드 블록 +tile.twilightforest.Trophy.name=황혼의 숲 트로피 +tile.twilightforest.Shield.name=성채의 방패 +tile.twilightforest.TrophyPedestal.0.name=트로피 받침대 +tile.twilightforest.TrophyPedestal.15.name=잠복한 트로피 받침대 +tile.twilightforest.AuroraBrick.name=오로라 블록 +tile.twilightforest.UnderBrick.0.name=언더 석재 벽돌 +tile.twilightforest.UnderBrick.1.name=이끼 낀 언더 석재 벽돌 +tile.twilightforest.UnderBrick.2.name=금 간 언더 석재 벽돌 +tile.twilightforest.UnderBrick.2.name=언더 석재 벽돌 바닥 +tile.twilightforest.Thorns.brown.name=가시 +tile.twilightforest.Thorns.green.name=녹색 가시 +tile.twilightforest.BurntThorns.name=타버린 가시 +tile.twilightforest.ThornRose.name=가시장미 +tile.twilightforest.Leaves3.0.name=가시장미 잎 +tile.twilightforest.Leaves3.1.name=콩나무 줄기 잎 +tile.twilightforest.Deadrock.surface.name=풍화된 데드락 +tile.twilightforest.Deadrock.cracked.name=금 간 데드락 +tile.twilightforest.Deadrock.solid.name=데드락 +tile.twilightforest.DarkLeaves.name=다크우드 나무 잎 +tile.twilightforest.AuroraPillar.name=오로라 기둥 +tile.twilightforest.AuroraSlab.name=오로라 반 블록 +tile.twilightforest.TrollSteinn.name=트롤스테인 +tile.twilightforest.WispyCloud.name=구름 +tile.twilightforest.FluffyCloud.name=솜털 구름 +tile.twilightforest.GiantCobble.name=거대 조약돌 +tile.twilightforest.GiantLog.name=거대 통나무 +tile.twilightforest.GiantLeaves.name=거대 나무 잎 +tile.twilightforest.GiantObsidian.name=거대 옵시디언 +tile.twilightforest.UberousSoil.name=양질의 흙 +tile.twilightforest.HugeStalk.name=거대한 줄기 +tile.twilightforest.HugeGloomBlock.name=거대한 머쉬그룸 +tile.twilightforest.TrollVidr.name=트롤비더 +tile.twilightforest.UnripeTrollBer.name=덜익은 트롤버 +tile.twilightforest.TrollBer.name=트롤버 +tile.twilightforest.TrollBer.name=트롤버 +tile.twilightforest.KnightmetalBlock.name=나이트메탈의 블록 +tile.twilightforest.HugeLilyPad.name=거대한 수련 잎 +tile.twilightforest.HugeWaterLily.name=거대한 수련 +tile.twilightforest.Slider.0.name=미끄럼 함정 +tile.twilightforest.Slider.1.name=미끄럼 함정 1 +tile.twilightforest.Slider.2.name=미끄럼 함정 2 +tile.twilightforest.Slider.3.name=미끄럼 함정 3 +tile.twilightforest.CastleBrick.0.name=성 석재 벽돌 +tile.twilightforest.CastleBrick.1.name=해진 성 석재 벽돌 +tile.twilightforest.CastleBrick.2.name=금 간 성 석재 벽돌 +tile.twilightforest.CastleBrick.3.name=성 지붕 타일 +tile.twilightforest.CastleBrick.4.name=이끼 낀 성 석재 벽돌 +tile.twilightforest.CastleBrick.5.name=두꺼운 성 석재 벽돌 +tile.twilightforest.CastleDoor.0.name=노란색 성 문 +tile.twilightforest.CastleDoor.1.name=보라색 성 문 +tile.twilightforest.CastleDoor.2.name=분홍색 성 문 +tile.twilightforest.CastleDoor.3.name=파란색 성 문 +tile.twilightforest.CastleMagic.0.name=분홍색 성 룬 석재 벽돌 +tile.twilightforest.CastleMagic.1.name=파란색 성 룬 석재 벽돌 +tile.twilightforest.CastleMagic.2.name=노란색 성 룬 석재 벽돌 +tile.twilightforest.CastleMagic.3.name=보라색 성 룬 석재 벽돌 +tile.twilightforest.CastlePillar.0.name=감싸진 성 석재 벽돌 기둥 +tile.twilightforest.CastlePillar.1.name=감싸진 성 석재 벽돌 바닥 +tile.twilightforest.CastlePillar.2.name=굵은 성 석재 벽돌 기둥 +tile.twilightforest.CastlePillar.3.name=굵은 성 석재 벽돌 바닥 +tile.twilightforest.CastleStairs.0.name=감싸진 성 석재 벽돌 계단 +tile.twilightforest.CastleStairs.8.name=굵은 성 석재 벽돌 계단 +tile.twilightforest.ForceField.0.name=보라색 역장 +tile.twilightforest.ForceField.1.name=분홍색 역장 +tile.twilightforest.ForceField.2.name=주황색 역장 +tile.twilightforest.ForceField.3.name=초록색 역장 +tile.twilightforest.ForceField.4.name=파란색 역장 +tile.twilightforest.BlockOfStorage.0.name=아이언우드 블록 +tile.twilightforest.BlockOfStorage.1.name=파이어리메탈 블록 +tile.twilightforest.BlockOfStorage.2.name=스틸리프 블록 +tile.twilightforest.BlockOfStorage.3.name=극지모피 블록 +tile.twilightforest.BlockOfStorage.4.name=카미나이트 블록 +tile.twilightforest.CinderFurnaceIdle.name=타버린 화로 [NYI] +tile.twilightforest.CinderLog.name=타버린 나무 [NYI] +tile.twilightforest.MiniatureStructure=모형 %s [NYI] +tile.twilightforest.SpiralBricks.name=나선형 석재 벽돌 +tile.twilightforest.BlockOfLapisTF.name=라피스 블록 [NYI] +tile.twilightforest.EtchedNagastone.name=조각된 나가스톤 +tile.twilightforest.NagastonePillar.name=나가스톤 기둥 +tile.twilightforest.NagastoneStairs.0.name=나가스톤 계단 (Left) +tile.twilightforest.NagastoneStairs.8.name=나가스톤 계단 (Right) +tile.twilightforest.EtchedNagastoneMossy.name=조각된 이끼 낀 나가스톤 +tile.twilightforest.NagastonePillarMossy.name=이끼 낀 나가스톤 기둥 +tile.twilightforest.NagastoneStairsMossy.0.name=이끼 낀 나가스톤 계단 (Left) +tile.twilightforest.NagastoneStairsMossy.8.name=이끼 낀 나가스톤 계단 (Right) +tile.twilightforest.EtchedNagastoneWeathered.name=파괴된 조각된 나가스톤 +tile.twilightforest.NagastonePillarWeathered.name=파괴된 나가스톤 기둥 +tile.twilightforest.NagastoneStairsWeathered.0.name=풍화된 나가스톤 계단 (Left) +tile.twilightforest.NagastoneStairsWeathered.8.name=풍화된 나가스톤 계단 (Right) + +structure.twilight_portal.name=황혼의 숲 포탈 +structure.hedge_maze.name=거대한 미로 +structure.hollow_hill.name=할로우 언덕 +structure.quest_grove.name=퀘스트 숲 +structure.mushroom_tower.name=버섯 성 +structure.naga_courtyard.name=나가 유적 +structure.lich_tower.name=리치의 성 +structure.minotaur_labyrinth.name=미노타우르스 미로 +structure.hydra_lair.name=히드라의 둥지 +structure.goblin_stronghold.name=고블린 요새 +structure.dark_tower.name=검은 탑 +structure.yeti_cave.name=예티 동굴 +structure.aurora_palace.name=오로라 궁전 +structure.troll_cave_and_cloud_castle.name=트롤 동굴과 구름 집 +structure.final_castle.name=최후의 성채 + +item.twilightforest.nagaScale.name=나가 비늘 +item.twilightforest.plateNaga.name=나가 비늘 튜닉 +item.twilightforest.legsNaga.name=나가 비늘 레깅스 +item.twilightforest.scepterTwilight.name=황혼의 지배 +item.twilightforest.scepterLifeDrain.name=생명의 지배 +item.twilightforest.scepterZombie.name=불사의 지배 +item.twilightforest.oreMeter.name=Ore Meter [WIP] +item.twilightforest.magicMap.name=마법 지도 +item.twilightforest.mazeMap.name=미로 지도 +item.twilightforest.oreMap.name=미로/광물 지도 +item.twilightforest.tfFeather.name=까마귀 깃털 +item.twilightforest.magicMapFocus.name=마법 지도 깃털 +item.twilightforest.mazeMapFocus.name=미로 지도 깃털 +item.twilightforest.liveRoot.name=생생한 뿌리 +item.twilightforest.ironwoodRaw.name=아이언우드 뭉치 +item.twilightforest.ironwoodIngot.name=아이언우드 주괴 +item.twilightforest.ironwoodHelm.name=아이언우드 헬름 +item.twilightforest.ironwoodPlate.name=아이언우드 플레이트 +item.twilightforest.ironwoodLegs.name=아이언우드 레그 +item.twilightforest.ironwoodBoots.name=아이언우드 부츠 +item.twilightforest.ironwoodSword.name=아이언우드 검 +item.twilightforest.ironwoodShovel.name=아이언우드 삽 +item.twilightforest.ironwoodPick.name=아이언우드 곡괭이 +item.twilightforest.ironwoodAxe.name=아이언우드 도끼 +item.twilightforest.ironwoodHoe.name=아이언우드 낫 +item.twilightforest.torchberries.name=토치베리 +item.twilightforest.venisonRaw.name=익히지 않은 사슴고기 +item.twilightforest.venisonCooked.name=구운 사슴고기 +item.twilightforest.hydraChop.name=히드라 고깃덩이 +item.twilightforest.fieryBlood.name=불타는 피 +item.twilightforest.fieryIngot.name=파이어리 주괴 +item.twilightforest.fieryHelm.name=파이어리 헬름 +item.twilightforest.fieryPlate.name=파이어리 플레이트 +item.twilightforest.fieryLegs.name=파이어리 레그 +item.twilightforest.fieryBoots.name=파이어리 부츠 +item.twilightforest.fierySword.name=파이어리 검 +item.twilightforest.fieryPick.name=파이어리 곡괭이 +item.twilightforest.steeleafIngot.name=스틸리프 +item.twilightforest.steeleafHelm.name=스틸리프 헬름 +item.twilightforest.steeleafPlate.name=스틸리프 플레이트 +item.twilightforest.steeleafLegs.name=스틸리프 레그 +item.twilightforest.steeleafBoots.name=스틸리프 부츠 +item.twilightforest.steeleafSword.name=스틸리프 검 +item.twilightforest.steeleafShovel.name=스틸리프 삽 +item.twilightforest.steeleafPick.name=스틸리프 곡괭이 +item.twilightforest.steeleafAxe.name=스틸리프 도끼 +item.twilightforest.steeleafHoe.name=스틸리프 낫 +item.twilightforest.minotaurAxe.name=미노타우르스의 도끼 +item.twilightforest.mazebreakerPick.name=미로파괴자 +item.twilightforest.transformPowder.name=변화의 가루 +item.twilightforest.meefRaw.name=익히지 않은 미노타우르스 고기 +item.twilightforest.meefSteak.name=미프 스테이크 +item.twilightforest.meefStroganoff.name=미프 스트로가노프 +item.twilightforest.mazeWafer.name=미로 와퍼 +item.twilightforest.emptyMagicMap.name=빈 마법 지도 +item.twilightforest.emptyMazeMap.name=빈 미로 지도 +item.twilightforest.emptyOreMap.name=빈 미로/광물 지도 +item.twilightforest.oreMagnet.name=광물 자석 +item.twilightforest.crumbleHorn.name=크럼블의 뿔피리 +item.twilightforest.peacockFan.name=공작의 깃털부채 +item.twilightforest.moonwormQueen.name=여왕달벌레 +item.twilightforest.charmOfLife1.name=샴 오브 라이프 I +item.twilightforest.charmOfLife2.name=샴 오브 라이프 II +item.twilightforest.charmOfKeeping1.name=샴 오브 키핑 I +item.twilightforest.charmOfKeeping2.name=샴 오브 키핑 II +item.twilightforest.charmOfKeeping3.name=샴 오브 키핑 III +item.twilightforest.towerKey.name=탑의 열쇠 +item.twilightforest.borerEssence.name=나무좀벌레 진액 +item.twilightforest.carminite.name=카미나이트 +item.twilightforest.tf_trophy.name=%s 트로피 +item.twilightforest.trophy.hydra.name=히드라 트로피 +item.twilightforest.trophy.naga.name=나가 트로피 +item.twilightforest.trophy.lich.name=리치 트로피 +item.twilightforest.trophy.ur_ghast.name=유어-가스트 트로피 +item.twilightforest.trophy.snow_queen.name=눈의여왕 트로피 +item.twilightforest.experiment115.name=실험작 No.115 +item.twilightforest.armorShards.name=갑옷 조각 +item.twilightforest.knightMetal.name=나이트메탈 주괴 +item.twilightforest.shardCluster.name=갑옷 조각 더미 +item.twilightforest.knightlyHelm.name=나이트메탈 헬름 +item.twilightforest.knightlyPlate.name=나이트메탈 플레이트 +item.twilightforest.knightlyLegs.name=나이트메탈 그리브 +item.twilightforest.knightlyBoots.name=나이트메탈 부츠 +item.twilightforest.knightlySword.name=나이트메탈 검 +item.twilightforest.knightlyPick.name=나이트메탈 곡괭이 +item.twilightforest.knightlyAxe.name=나이트메탈 도끼 +item.twilightforest.phantomHelm.name=팬텀 헬름 +item.twilightforest.phantomPlate.name=팬텀 플레이트 +item.twilightforest.lampOfCinders.name=재의 램프 +item.twilightforest.fieryTears.name=불타는 눈물 +item.twilightforest.iceBomb.name=얼음 폭탄 +item.twilightforest.yetiHelm.name=예티 뿔 헬름 +item.twilightforest.yetiPlate.name=예티 자켓 +item.twilightforest.yetiLegs.name=예티 레깅스 +item.twilightforest.yetiBoots.name=예티 부츠 +item.twilightforest.alphaFur.name=알파 예티 모피 +item.twilightforest.arcticFur.name=극지의 모피 +item.twilightforest.arcticHelm.name=아크틱 모자 +item.twilightforest.arcticPlate.name=아크틱 자켓 +item.twilightforest.arcticLegs.name=아크틱 레깅스 +item.twilightforest.arcticBoots.name=아크틱 부츠 +item.twilightforest.magicBeans.name=마법의 콩 +item.twilightforest.giantPick.name=거인의 곡괭이 +item.twilightforest.giantSword.name=거인의 검 +item.twilightforest.tripleBow.name=트리 활 +item.twilightforest.seekerBow.name=씨커 활 +item.twilightforest.iceBow.name=얼음 활 +item.twilightforest.enderBow.name=엔더 활 +item.twilightforest.iceSword.name=얼음 검 +item.twilightforest.glassSword.name=유리 검 +item.twilightforest.knightmetalRing.name=나이트메탈 고리 +item.twilightforest.chainBlock.name=구속 블록 +item.twilightforest.cubeTalisman.name=큐브의 부적 +item.twilightforest.cubeOfAnnihilation.name=무의 큐브 + +item.twilightforest.minotaurAxe.tooltip=충전하는 동안 추가 데미지를 줍니다 +item.twilightforest.knightlySword.tooltip=방어구를 착용한 상대에게 추가 데미지를 줍니다 +item.twilightforest.knightlyPick.tooltip=방어구를 착용한 상대에게 추가 데미지를 줍니다 +item.twilightforest.knightlyAxe.tooltip=방어구를 착용하지 않은 상대에게 추가 데미지를 줍니다 +item.twilightforest.giantPick.tooltip=거대 블록을 부술 수 있습니다 +item.twilightforest.fieryPick.tooltip=자동으로 제련합니다 +item.twilightforest.fierySword.tooltip=상대를 불태웁니다 +item.twilightforest.fieryHelm.tooltip=공격한 상대를 불태웁니다 +item.twilightforest.fieryPlate.tooltip=공격한 상대를 불태웁니다 +item.twilightforest.fieryLegs.tooltip=공격한 상대를 불태웁니다 +item.twilightforest.fieryBoots.tooltip=공격한 상대를 불태웁니다 +item.twilightforest.yetiHelm.tooltip=공격한 상대를 냉각 시킵니다 +item.twilightforest.yetiPlate.tooltip=공격한 상대를 냉각 시킵니다 +item.twilightforest.yetiLegs.tooltip=공격한 상대를 냉각 시킵니다 +item.twilightforest.yetiBoots.tooltip=공격한 상대를 냉각 시킵니다 + +item.twilightforest.arctic_armor.tooltip=염색이 가능합니다. + +entity.twilightforest.wild_boar.name=맷돼지 +entity.twilightforest.bighorn_sheep.name=큰뿔산양 +entity.twilightforest.deer.name=사슴 +entity.twilightforest.redcap.name=붉은모자 고블린 +entity.twilightforest.swarm_spider.name=무리 거미 +entity.twilightforest.naga.name=나가 +entity.twilightforest.naga_segment.name=나가 몸통 +entity.twilightforest.skeleton_druid.name=스켈레톤 드루이드 +entity.twilightforest.hostile_wolf.name=화난 늑대 +entity.twilightforest.wraith.name=황혼숲 유령 +entity.twilightforest.hedge_spider.name=생울타리 거미 +entity.twilightforest.hydra.name=히드라 +entity.twilightforest.hydra_head.name=히드라 머리 +entity.twilightforest.lich.name=황혼숲 리치 +entity.twilightforest.penguin.name=펭귄 +entity.twilightforest.tiny_bird.name=작은 새 +entity.twilightforest.squirrel.name=다람쥐 +entity.twilightforest.bunny.name=숲 토끼 +entity.twilightforest.raven.name=까마귀 +entity.twilightforest.quest_ram.name=렘 +entity.twilightforest.kobold.name=코볼트 +entity.twilightforest.boggard.name=보거드 [NYI] +entity.twilightforest.lich_minion.name=리치의 수하 +entity.twilightforest.loyal_zombie.name=로얄 좀비 +entity.twilightforest.mosquito_swarm.name=모기 무리 +entity.twilightforest.death_tome.name=죽음의 책 +entity.twilightforest.minotaur.name=미노타우르스 +entity.twilightforest.minoshroom.name=미노쉬룸 +entity.twilightforest.fire_beetle.name=불꽃 딱정벌레 +entity.twilightforest.slime_beetle.name=슬라임 딱정벌레 +entity.twilightforest.pinch_beetle.name=집게 딱정벌레 +entity.twilightforest.maze_slime.name=미로 슬라임 +entity.twilightforest.redcap_sapper.name=붉은모자 공병 고블린 +entity.twilightforest.mist_wolf.name=안개 늑대 +entity.twilightforest.king_spider.name=왕거미 +entity.twilightforest.firefly.name=반딧불이 +entity.twilightforest.mini_ghast.name=카미나이트 가스트링 +entity.twilightforest.tower_ghast.name=카미나이트 가스트가드 +entity.twilightforest.tower_golem.name=카미나이트 골렘 +entity.twilightforest.tower_termite.name=나무좀벌레 +entity.twilightforest.tower_broodling.name=카미나이트 거미 +entity.twilightforest.ur_ghast.name=유어-가스트 +entity.twilightforest.blockchain_goblin.name=구속 고블린 +entity.twilightforest.goblin_knight_upper.name=고블린 기사 +entity.twilightforest.goblin_knight_lower.name=고블린 기사 +entity.twilightforest.helmet_crab.name=투구게 +entity.twilightforest.knight_phantom.name=유령 기사 +entity.twilightforest.yeti.name=예티 +entity.twilightforest.yeti_alpha.name=알파 예티 +entity.twilightforest.winter_wolf.name=겨울 늑대 +entity.twilightforest.snow_guardian.name=눈 수호자 +entity.twilightforest.stable_ice_core.name=안정된 얼음 핵 +entity.twilightforest.unstable_ice_core.name=불안정한 얼음 핵 +entity.twilightforest.snow_queen.name=눈의 여왕 +entity.twilightforest.troll.name=동굴 트롤 +entity.twilightforest.giant_miner.name=광부 거인 +entity.twilightforest.armored_giant.name=무장한 거인 +entity.twilightforest.ice_crystal.name=얼음 수정 +entity.twilightforest.apocalypse_cube.name=종말의 큐브 +entity.twilightforest.adherent.name=신관 + +twilightforest.effect.frosted=빙결 + +twilightforest.misc.wip0=This block is a work in progress and may have bugs or unintended effects that may damage your world. +twilightforest.misc.wip1=Use with caution. +twilightforest.misc.nyi=This block has effects that are not yet implemented. + +twilightforest.loading.title.enter=황혼의 숲으로 빨려 들어갑니다... +twilightforest.loading.title.leave=항혼의 숲을 떠납니다... + +#Config +twilightforest.config.dimension=Dimension Settings +twilightforest.config.dimension.tooltip=You won't be able to change these settings without some kind of relaunch. +twilightforest.config.dimension_id=Dimension ID +twilightforest.config.dimension_id.tooltip=What ID number to assign to the Twilight Forest dimension. Change if you are having conflicts with another mod. +twilightforest.config.dimension_seed=Dimension Seed +twilightforest.config.dimension_seed.tooltip=If set, this will override the normal world seed when generating parts of the Twilight Forest Dimension. +twilightforest.config.spawn_in_tf=New Players Spawn in Twilight Forest +twilightforest.config.spawn_in_tf.tooltip=If true, players spawning for the first time will spawn in the Twilight Forest. + +twilightforest.config.compat=Compatibility +twilightforest.config.compat.tooltip=Should TF Compatibility load? Turn off if TF's Compatibility is causing crashes or if not desired. + +twilightforest.config.performance=Performance Tweaks +twilightforest.config.performance.tooltip=Lets you sacrifice various things to improve world performance. +twilightforest.config.canopy_coverage=Canopy Coverage +twilightforest.config.canopy_coverage.tooltip=Amount of canopy coverage. Lower numbers improve chunk generation speed at the cost of a thinner forest. +twilightforest.config.twilight_oaks=Twilight Oak Chance +twilightforest.config.twilight_oaks.tooltip=Chance that a chunk in the Twilight Forest will contain a twilight oak tree. Higher numbers reduce the number of trees, increasing performance. +twilightforest.config.leaves_light_opacity=Twilight Leaves opacity +twilightforest.config.leaves_light_opacity.tooltip="If leaves are not full cubes, this controls the opacity of leaves to control amount of light blocking. +twilightforest.config.leaves_full_cube=Can Twilight Leaves be full blocks +twilightforest.config.leaves_full_cube.tooltip=Setting this false makes leaves not full cubes. This results in not blocking light at all, making them the equivalent of glass in terms of blocking light. Decreases complexity in some lighting checks. +twilightforest.config.glacier_packed_ice=Glaciers made of Packed Ice instead of Ice +twilightforest.config.glacier_packed_ice.tooltip=Setting this true will make Twilight Glaciers generate with Packed Ice instead of regular translucent Ice, decreasing amount of light checking calculations. + +twilightforest.config.silent_cicadas=Silent Cicadas +twilightforest.config.silent_cicadas.tooltip=Make cicadas silent for those having sound library problems, or otherwise finding them annoying. + +twilightforest.config.portals_in_other_dimensions=Portals in other dimensions +twilightforest.config.portals_in_other_dimensions.tooltip=Allow portals to the Twilight Forest to be made outside of dimension 0. May be considered an exploit. +twilightforest.config.admin_portals=Admin-Only Twilight Portals +twilightforest.config.admin_portals.tooltip=Allow portals only for admins (Operators). This severly reduces the range in which the mod usually scans for valid portal conditions, and it scans near ops only. +twilightforest.config.portals=Disable Twilight Portals +twilightforest.config.portals.tooltip=Disable Twilight Forest portal creation entirely. Provided for server operators looking to restrict action to the dimension. +twilightforest.config.portal_creator=Portal Creation Item +twilightforest.config.portal_creator.tooltip=Registry String ID of item used to create the Twilight Forest Portal. +twilightforest.config.portal_creator_meta=Portal Creation Item's Meta +twilightforest.config.portal_creator_meta.tooltip=Meta of item used to create the Twilight Forest Portal. -1 for any metadata. +twilightforest.config.portal_lighting=Portal Creation Lightning Fire +twilightforest.config.portal_lighting.tooltip=Set this true if you want the lightning that zaps the portal to not set things on fire. For those who don't like fun. +twilightforest.config.portal_return=Should Portals generate as a two-way portal +twilightforest.config.portal_return.tooltip=If false, the return portal will require the activation item. + +twilightforest.config.uncrafting=Disable Uncrafting in Uncrafting Table +twilightforest.config.uncrafting.tooltip=Disable the uncrafting function of the uncrafting table. Provided as an option when interaction with other mods produces exploitable recipes. + +twilightforest.config.antibuilder_blacklist=Antibuilder Blacklist +twilightforest.config.antibuilder_blacklist.tooltip=Anti-Builder blacklist. (domain:block:meta) meta is optional. + +twilightforest.config.animate_trophyitem=Rotate Trophy Heads on Item model +twilightforest.config.animate_trophyitem.tooltip=Rotate trophy heads on item model. Has no performance impact at all. For those who don't like fun. + +twilightforest.config.shield_parry=Shield Parrying +twilightforest.config.shield_parry.tooltip=We recommend downloading the Shield Parry mod for parrying, but these controls remain for without. +twilightforest.config.parry_non_twilight=Parry non-Twilight projectiles +twilightforest.config.parry_non_twilight.tooltip=Set to true to parry non-Twilight projectiles. We recommend downloading the Shield Parry mod instead. +twilightforest.config.parry_window_arrow=Timing Windowspan for Arrows +twilightforest.config.parry_window_arrow.tooltip=The amount of ticks after raising a shield that makes it OK to parry an arrow. There is 20 ticks in 1 second. +twilightforest.config.parry_window_fireball=Timing Windowspan for Fireballs +twilightforest.config.parry_window_fireball.tooltip=The amount of ticks after raising a shield that makes it OK to parry a fireball. There is 20 ticks in 1 second. +twilightforest.config.parry_window_throwable=Timing Windowspan for Throwables +twilightforest.config.parry_window_throwable.tooltip=The amount of ticks after raising a shield that makes it OK to parry a throwable. There is 20 ticks in 1 second. +twilightforest.config.shieldParryTicksBeam=Timing Windowspan for Beams??? +twilightforest.config.shieldParryTicksBeam.tooltip=??? + +twilightforest.config.loading_screen=Loading Screen +twilightforest.config.loading_screen.tooltip=Client only: Controls for the Loading screen +twilightforest.config.loading_icon_enable=Enable Loading Icon Animation +twilightforest.config.loading_icon_enable.tooltip=Wobble the Loading icon. Has no performance impact at all. For those who don't like fun. +twilightforest.config.loading_screen_swap_frequency=Loading Screen switching +twilightforest.config.loading_screen_swap_frequency.tooltip=How many ticks between each loading screen change. Set to 0 to not cycle at all. +twilightforest.config.loading_icon_wobble_bounce_frequency=Icon Animation Speed +twilightforest.config.loading_icon_wobble_bounce_frequency.tooltip=Frequency of wobble and bounce. +twilightforest.config.loading_icon_scale=Icon Scaling +twilightforest.config.loading_icon_scale.tooltip=Scale of whole bouncy loading icon. +twilightforest.config.loading_icon_bounciness=Icon Bounciness +twilightforest.config.loading_icon_bounciness.tooltip=How much the loading icon bounces. +twilightforest.config.loading_icon_tilting=Icon Wobbliness +twilightforest.config.loading_icon_tilting.tooltip=How far the loading icon wobbles. +twilightforest.config.loading_icon_tilt_pushback=Icon Tilt Offset +twilightforest.config.loading_icon_tilt_pushback.tooltip=Pushback value to re-center the wobble of loading icon. + +twilightforest.book.lichtower.1=\u00A78[[An explorer's notebook, gnawed on by monsters]]\u00A70\n\nI have begun examining the strange aura surrounding this tower. The bricks of the tower are protected by a curse, stronger than any I've seen before. The magic from the curse +twilightforest.book.lichtower.2=is boiling off into the surrounding area.\n\nIn my homeland I would have many options for dealing with this magic, but here my supplies are limited. I shall have to research... +twilightforest.book.lichtower.3=\u00A78[[Many entries later]]\u00A70\n\nA breakthrough! In my journeys I sighted a huge snake-like monster in a decorated courtyard. Nearby, I picked up a worn down, discarded green scale.\n\nThe magic in the scale seems to have the +twilightforest.book.lichtower.4=curse-breaking properties I need, but the magic is too dim. I may need to acquire a fresher specimen, directly from the creature. + +twilightforest.book.labyrinth.1=\u00A78[[An explorer's notebook, written on waterproof paper]]\u00A70\n\nThe mosquitoes in this swamp are vexing, but strange. The vast majority of them seem to have no natural source, nor do they seem to have a role in the local ecology. I have begun to +twilightforest.book.labyrinth.2=suspect that they are some kind of magical curse.\n\n\u00A78[[Next entry]]\u00A70\n\nNow that I have encountered a protection spell on the ruined labyrinth here, I consider my suspicions confirmed. Both the protection +twilightforest.book.labyrinth.3=spell and the mosquitoes are a curse. This curse seems to have a different source from the others I have encountered. I will have to research further...\n\n\u00A78[[Next entry]]\u00A70\n\nThe curse seems to +twilightforest.book.labyrinth.4=be of a type too powerful for one being alone to produce. Several wizards working in combination would be necessary.\n\nIf one of the wizards stopped contributing, the whole of the curse over the entire swamp would fall. Strangely, +twilightforest.book.labyrinth.5=my divinations do not show signs of any nearby living wizards. I did see something interesting in one of the nearby pointy-roofed towers though... + +twilightforest.book.hydralair.1=\u00A78[[An explorer's notebook, written on fireproof paper]]\u00A70\n\nFire is a trivial obstacle for a master explorer such as myself. I have traversed seas of fire, and swam through oceans of lava. The burning air here is an interesting variation, +twilightforest.book.hydralair.2=but ultimately no hinderance.\n\nWhat does stop me though is that I have encountered another protection spell, this time surrounding a mighty creature that must be king of this fire swamp. This is not the first protection spell I have +twilightforest.book.hydralair.3=encountered, and I am beginning to unravel the mysteries of how they work.\n\nIf this spell is like the others, it will be sustained by a powerful creature nearby. Surrounding the fire swamp are several wet swamps, and under those +twilightforest.book.hydralair.4=swamps are labyrinths full of minotaurs. The logical choice to bind such a spell to would be some sort of powerful minotaur, different in some way from the others that surround it... + +twilightforest.book.tfstronghold.1=\u00A78[[An explorer's notebook, written on faintly glowing paper]]\u00A70\n\nThe tendrils of darkness surrounding this area are just a manifestation of a protective spell over the entire dark forest. The spell causes blindness, which is quite vexing. I have +twilightforest.book.tfstronghold.2=seen several interesting things in the area and would like to keep exploring.\n\n\u00A78[[Next entry]]\u00A70\n\nI have found ruins in the dark forest. They belong to a stronghold, of a type usually inhabited by knights. Rather than +twilightforest.book.tfstronghold.3=knights though, this stronghold is full of goblins. They wear knightly armor, but their behavior is most un-knightly.\n\n\u00A78[[Next entry]]\u00A70\n\nDeep in the ruins, I have found a pedestal. The pedestal seems to be of a type that +twilightforest.book.tfstronghold.4=knights would place trophies on to prove their strength.\n\Obtaining a powerful scepter would seem to weaken the curse on the dark forest, and placing a trophy associated with a powerful creature on the pedestal would likely grant access into the +twilightforest.book.tfstronghold.5=main part of the stronghold. + +twilightforest.book.darktower.1=\u00A78[[An explorer's notebook that seems to have survived an explosion]]\u00A70\n\nThis tower clearly has mechanisms that are not responding to me. Their magic almost yearns to acknowledge my touch, but it cannot. It is if the devices of the tower are being +twilightforest.book.darktower.2=suppressed by a powerful group of beings nearby.\n\n\u00A78[[Next entry]]\u00A70\n\nThe magic seems to emanate from deep within the strongholds nearby. It can't come from the goblins, as their magic is charming, but unfocused. There +twilightforest.book.darktower.3=must still be some force still active in the strongholds.\n\n\u00A78[[Next entry]]\u00A70\n\nMy analysis indicates that it comes from several sources, operating as a group. I will head back to the stronghold after I resupply... + +twilightforest.book.yeticave.1=\u00A78[[An explorer's notebook, covered in frost]]\u00A70\n\nThe blizzard surrounding these snowy lands is unceasing. This is no ordinary snowfall--this is a magical phenomenon. I will have to conduct experiments to find +twilightforest.book.yeticave.2=what is capable of causing such an effect.\n\n\u00A78[[Next entry]]\u00A70\n\nThe curse seems to be of a type too powerful for one being alone to produce. Several wizards working in combination would be necessary. +twilightforest.book.yeticave.3=If one of the wizards stopped contributing, the blizzard would calm. Strangely, my divinations do not show signs of any nearby living wizards. I did see something interesting in one of the nearby pointy-roofed towers though... + +twilightforest.book.icetower.1=\u00A78[[An explorer's notebook, caked in ice]]\u00A70\n\nI overcame one blizzard, only to run into this terrible ice storm atop the glacier. My explorations have shown me the splendor of an ice palace, shining with the colors of the polar aurora. It +twilightforest.book.icetower.2=all seems protected by some sort of curse.\n\n\u00A78[[Next entry]]\u00A70\n\nI am no novice. This curse is fed by the power of a creature nearby. The cause of the curse surrounding the fire swamp was built off the power of the leader of the +twilightforest.book.icetower.3=minotaurs nearby.\n\nSurrounding this glacier, there are masses of yetis. Perhaps the yetis have some sort of leader... + +twilightforest.book.trollcave.1=\u00A78[[An explorer's notebook, damaged by acid]]\u00A70\n\nThere seems to be no way to protect myself from the toxic rainstorm surrounding this area. In my brief excursions, I have also encountered another protection spell, similar to the +twilightforest.book.trollcave.2=others I have witnessed. The spell must be connected to the toxic storm in some way. Further research to follow...\n\n\u00A78[[Next entry]]\u00A70\n\nSuch supreme weather magic must be the result of +twilightforest.book.trollcave.3=multiple undefeated great evils in this world. My studies contain several clues pointing at a searing swamp, a forest coated in deep darkness, and a realm coated in snow. + +twilightforest.book.unknown.1=\u00A78[[This book shows signs of having been copied many times]]\u00A70\n\nI cannot explain the field surrounding this structure, but the magic is powerful. If this curse is like the others, then the answer to unlocking it lies elsewhere. Perhaps there is +twilightforest.book.unknown.2=something I have left undone, or some monster I have yet to defeat. I will have to turn back. I will return to this place later, to see if anything has changed. + +# Fluid + +fluid.fierymetal=융해된 파이어리 +fluid.knightmetal=융해된 나이트메탈 +fluid.fiery_essence=파이어리 에센스 + +# TCon + +material.nagascale.name=나가 비늘 +material.steeleaf.name=스틸리프 +material.fierymetal.name=파이어리 +material.knightmetal.name=나이티 +material.raven_feather.name=까마귀 깃털 + +modifier.twilit.name=황혼 +modifier.twilit.desc=§oThe Twilight Forest's illuminating blessing.§r\nSpeedier in the Twilight Forest.\nMore damage outside the Twilight Forest. +modifier.twilit.extra.speed=채굴 속도(황혼의 숲 전용): +%s +modifier.twilit.extra.damage=데미지(황혼의 숲 제외): +%s +modifier.precipitate.name=고양 +modifier.precipitate.desc=§oThe last standing escape plan.§r\nThe less health you have, the speedier it is! +modifier.synergy.name=시너지 +modifier.synergy.desc=§oLook ma, no moss!§r\nWill repair itself if you have Steeleaves in your hotbar. +modifier.stalwart.name=일꾼 +modifier.stalwart.desc=§oThe Brave and Bold.§r\nHitting an entity can make you feel emboldened. +modifier.veiled.name=은밀함 +modifier.veiled.desc=§oLike a Specter!§r\nProjectile will be invisible. diff --git a/src/main/resources/assets/twilightforest/lang/ru_RU.lang b/src/main/resources/assets/twilightforest/lang/ru_RU.lang deleted file mode 100644 index 6212f19b0e..0000000000 --- a/src/main/resources/assets/twilightforest/lang/ru_RU.lang +++ /dev/null @@ -1,413 +0,0 @@ -tile.TFLog.0.name=Сумеречный дуб -tile.TFLog.1.name=Сумеречная сосна -tile.TFLog.2.name=Сумеречная берёза -tile.TFLog.3.name=Тёмное дерево -tile.TFLeaves.0.name=Листва сумеречного дуба -tile.TFLeaves.1.name=Листва сумеречной сосны -tile.TFLeaves.2.name=Листва сумеречной берёзы -tile.TFLeaves.3.name=Разноцветная листва -tile.TFFirefly.name=Светлячок -tile.TFCicada.name=Цикада -tile.TFPortal.name=Блок портала в сумеречный лес -tile.TFMazestone.0.name=Камень лабиринта -tile.TFMazestone.1.name=Кладка из камня лабиринта -tile.TFMazestone.2.name=Гладкая лабиринтовая кладка -tile.TFMazestone.3.name=Декоративная лабиринтовая кладка -tile.TFMazestone.4.name=Потресканая лабиринтовая кладка -tile.TFMazestone.5.name=Замшелая лабиринтовая кладка -tile.TFMazestone.6.name=Узорчатая лабиринтовая кладка -tile.TFMazestone.7.name=Двойная узорчатая лабиринтовая кладка -tile.TFMazestone.8.name=Потолок из камня лабиринта -tile.TFHedge.0.name=Хеджа -tile.TFHedge.1.name=Листва тёмного дерева -tile.TFHedge.2.name=Хеджа -tile.TFBossSpawner.0.name=Спавнер Наги -tile.TFBossSpawner.1.name=Спавнер Лича -tile.TFBossSpawner.2.name=Спавнер Гидры -tile.TFFireflyJar.name=Баночка со светлячком -tile.TFPlant.8.name=Сверкающая трава -tile.TFPlant.9.name=Светогриб -tile.TFPlant.13.name=Факелонтовый росток -tile.TFPlant.14.name=Висячие корни -tile.TFRoots.0.name=Корни -tile.TFRoots.1.name=Замшелые корни -tile.TFUncraftingTable.name=Анти верстак -tile.TFFireJet.0.name=Дымовой блок -tile.TFFireJet.8.name=Огненный блок -tile.TFFireJet.9.name=Дымящиейся огненный блок -tile.TFFireJet.10.name=Горящий огненный блок -tile.TFNagastone.0.name=Нагакамень -tile.TFNagastone.1.name=Нагакамень -tile.TFNagastone.2.name=Нагакамень -tile.TFNagastone.3.name=Нагакамень -tile.TFNagastone.4.name=Нагакамень -tile.TFNagastone.5.name=Нагакамень -tile.TFNagastone.6.name=Нагакамень -tile.TFNagastone.7.name=Нагакамень -tile.TFNagastone.8.name=Нагакамень -tile.TFNagastone.9.name=Нагакамень -tile.TFNagastone.10.name=Нагакамень -tile.TFNagastone.11.name=Нагакамень -tile.TFNagastone.12.name=Нагакамень -tile.TFNagastone.13.name=Нагакамень -tile.TFNagastone.14.name=Нагакамень -tile.TFNagastone.15.name=Нагакамень -tile.TFAuroraBrick.0.name=Лёгкий блок -tile.TFUnderBrick.0.name=Подземные кирпичи -tile.TFUnderBrick.1.name=Потресканные поздемные кирпичи -tile.TFUnderBrick.2.name=Замшелые подземные кирпичи -tile.TFSapling.0.name=Саженец сумеречного дуба -tile.TFSapling.1.name=Саженец сумеречной сосны -tile.TFSapling.2.name=Саженец сумеречной берёзы -tile.TFSapling.3.name=Саженец тёмного дерева -tile.TFSapling.4.name=Саженец большого сумеречного дуба -tile.TFSapling.5.name=Саженец дерева времени -tile.TFSapling.6.name=Саженец мудрого дерева -tile.TFSapling.7.name=Саженец дерева шахтёра -tile.TFSapling.8.name=Саженец сортировочного дерева -tile.TFSapling.9.name=Саженец разноцветного дерева -tile.TFMoonworm.name=Гусеница -tile.TFMagicLog.0.name=Дерево времени -tile.TFMagicLog.1.name=Загадочное дерево -tile.TFMagicLog.2.name=Дерево шахтёра -tile.TFMagicLog.3.name=Правильное дерево -tile.TFMagicLogSpecial.0.name=Дерево времени -tile.TFMagicLogSpecial.1.name=Мудрое дерево -tile.TFMagicLogSpecial.2.name=Ядро дерева шахтёра -tile.TFMagicLogSpecial.3.name=Ядро дерева сортировки -tile.TFMagicLeaves.0.name=Листва дерева времени -tile.TFMagicLeaves.1.name=Листва мудрого дерева -tile.TFMagicLeaves.2.name=Листва шахтёра -tile.TFMagicLeaves.3.name=Листва сортировки -tile.TFTowerStone.0.name=Планки тёмной башни -tile.TFTowerStone.1.name=Боковые планки тёмной башни -tile.TFTowerStone.2.name=Трестнутые планки тёмной башни -tile.TFTowerStone.3.name=Замшелые планки тёмной башни -tile.TFTowerStone.4.name=Инфицированные планки тёмной башни -tile.TFTowerDevice.0.name=Восстанавливающийся блок -tile.TFTowerDevice.1.name=Активный восстанавливающийся блок -tile.TFTowerDevice.2.name=Исчезающий блок -tile.TFTowerDevice.3.name=Активный исчезающий блок -tile.TFTowerDevice.4.name=Заблокированный восстанавливающийся блок -tile.TFTowerDevice.5.name=Разблокированый восстанавливающийся блок -tile.TFTowerDevice.6.name=Строитель башни -tile.TFTowerDevice.7.name=Активный строитель башни -tile.TFTowerDevice.8.name=Неактивный строитель башни -tile.TFTowerDevice.9.name=Антистроитель -tile.TFTowerTranslucent.0.name=Восстанавливающийся блок -tile.TFTowerTranslucent.1.name=Активный восстанавливающийся блок -tile.TFTowerTranslucent.2.name=Блок строителя башни -tile.TFTowerTranslucent.3.name=Активный блок строители башни -tile.TFTowerTranslucent.4.name=Анти-строитель башни -tile.TFTrophy.0.name=Трофей сумеречного леса -item.experiment115.name=Образец 115 -item.nagaScale.name=Сердце Наги -tile.TFTowerTranslucent.6.name=Поддельное золото -tile.TFTowerTranslucent.7.name=Поддельный алмаз -item.plateNaga.name=Нагрудник из сердец Наги -item.legsNaga.name=Поножи из сердец Наги -item.scepterTwilight.name=Сумеречный посох -item.scepterLifeDrain.name=Посох смерти -entity.TwilightForest.Helmet Crab.name=Шлемовый краб -entity.TwilightForest.Upper Goblin Knight.name=Гоблин-рыцарь с копьём -entity.TwilightForest.Lower Goblin Knight.name=Гоблин-рыцарь -entity.TwilightForest.Block&Chain Goblin.name=Гоблин-рыцарь с булавой -entity.TwilightForest.Knight Phantom.name=Призрак рыцаря -item.scepterZombie.name=Посох мёртвых -item.oreMeter.name=Определитель руд -tile.TFTowerDevice.10.name=Ловушка для гаста -tile.TFTowerDevice.11.name=Активная ловушка для гаста -item.magicMap.name=Магическая карта -item.mazeMap.name=Карта лабиринта -item.oreMap.name=Шахтёрская карта -item.tfFeather.name=Воронье перо -item.phantomHelm.name=Шлем Фантома -item.phantomPlate.name=Нагрудник Фантома -item.magicMapFocus.name=Магическое перо -item.mazeMapFocus.name=Магическое ядро -item.liveRoot.name=Замшелый корень -item.ironwoodRaw.name=Магический материал -item.ironwoodIngot.name=Металл древних -item.ironwoodHelm.name=Шлем древних -item.ironwoodPlate.name=Нагрудник древних -item.ironwoodLegs.name=Поножи древних -item.ironwoodBoots.name=Ботинки древних -item.ironwoodSword.name=Меч древних -item.ironwoodShovel.name=Лопата древних -item.ironwoodPick.name=Кирка древних -item.ironwoodAxe.name=Топор древних -item.ironwoodHoe.name=Мотыга древних -item.torchberries.name=Факелонт -item.venisonRaw.name=Сырая оленятина -item.venisonCooked.name=Олений стейк -item.hydraChop.name=Мясо Гидры -item.fieryBlood.name=Огенная кровь -item.fieryIngot.name=Огненный слиток -item.fieryHelm.name=Огненный шлем -item.fieryPlate.name=Огненный нагрудник -item.fieryLegs.name=Огненные поножи -item.fieryBoots.name=Огненные ботинки -item.fierySword.name=Огненный меч -item.fieryPick.name=Огненная кирка -item.steeleafIngot.name=Магический лист -item.steeleafHelm.name=Шлем из магических листьев -item.steeleafPlate.name=Нагрудник из магических листьев -item.steeleafLegs.name=Поножи из магических листьев -item.steeleafBoots.name=Ботинки из магических листьев -item.steeleafSword.name=Меч из магических листьев -item.steeleafShovel.name=Лопата из магических листьев -item.steeleafPick.name=Кирка из магических листьев -item.steeleafAxe.name=Топор из магических листьев -item.steeleafHoe.name=Мотыга из магических листьев -item.minotaurAxe.name=Топор Минотавра -item.mazebreakerPick.name=Кирка лабиринта -item.transformPowder.name=Порошок трансформации -item.meefRaw.name=Мясо минотавра -item.meefSteak.name=Стейк из минотавра -item.meefStroganoff.name=Суп из минотавра -item.mazeWafer.name=Вафли -tile.TFPlant.3.name=Покров мха -tile.TFPlant.4.name=Четырёхлистный клевер -item.emptyMagicMap.name=Пустая Магическая карта -item.emptyMazeMap.name=Пустая карта лабиринта -item.emptyOreMap.name=Пустая шахтёрская карта -item.oreMagnet.name=Рудный магнит -item.crumbleHorn.name=Рог -item.peacockFan.name=Веер полёта -item.moonwormQueen.name=Королева гусениц -item.charmOfLife1.name=Чарм жизни I -item.charmOfLife2.name=Чарм жизни II -item.charmOfKeeping1.name=Чарм инвентаря I -item.charmOfKeeping2.name=Чарм инвентаря II -item.charmOfKeeping3.name=Чарм инвентаря III -item.towerKey.name=Ключ от башни -tile.TFTowerDevice.12.name=Карминитовый реактор -tile.TFTowerDevice.13.name=Активный карминитовый реактор -entity.TwilightForest.Redscale Broodling.name=Карминитовая скала -entity.TwilightForest.Tower Golem.name=Кариминитовый голем -entity.TwilightForest.Tower Ghast.name=Карминитовый охренник -entity.TwilightForest.Mini Ghast.name=Карминитовый гаст -item.carminite.name=Карминит -entity.TwilightForest.Tower Termite.name=Буровые планки тёмной башни -item.borerEssence.name=Буровая эссенция -entity.TwilightForest.Tower Boss.name=Тёмный гаст - -item.tfspawnegg.name=Призвать существо - - -enchantment.tfFireReact=Аура огня - -itemGroup.twilightForest=Twilight Forest - -entity.TwilightForest.Wild Boar.name=Кабан -entity.TwilightForest.Bighorn Sheep.name=Баран -entity.TwilightForest.Wild Deer.name=Олень -entity.TwilightForest.Redcap.name=Шахтёр -entity.TwilightForest.Swarm Spider.name=Маленький паук -entity.TwilightForest.Naga.name=Нага -entity.TwilightForest.Naga Segment.name=Часть Наги -entity.TwilightForest.Naga.name=Нага -entity.TwilightForest.Skeleton Druid.name=Друид -entity.TwilightForest.Hostile Wolf.name=Злой волк -entity.TwilightForest.Twilight Wraith.name=Призрак -entity.TwilightForest.Hedge Spider.name=Зелёный паук -entity.TwilightForest.Hydra.name=Гидра -entity.TwilightForest.HydraHead.name=Голова Гидры -entity.TwilightForest.Twilight Lich.name=Сумеречный Лич -entity.TwilightForest.Penguin.name=Пингвин -entity.TwilightForest.Tiny Bird.name=Лесная птица -entity.TwilightForest.Penguin.name=Пингвин -entity.TwilightForest.Forest Squirrel.name=Лесная белка -entity.TwilightForest.Forest Bunny.name=Лесной кролик -entity.TwilightForest.Forest Raven.name=Лесная ворона -entity.TwilightForest.Questing Ram.name=Квест Рам -entity.TwilightForest.Twilight Kobold.name=Кобольт -entity.TwilightForest.Boggard.name=Боггард -entity.TwilightForest.Penguin.name=Пингвин -entity.TwilightForest.Lich Minion.name=Слуга Лича -entity.TwilightForest.Loyal Zombie.name=Миньон зомби -entity.TwilightForest.Mosquito Swarm.name=Москиты -entity.TwilightForest.Death Tome.name=Чернокнижник -entity.TwilightForest.Minotaur.name=Минотавр -entity.TwilightForest.Minoshroom.name=Король минотавров -entity.TwilightForest.Fire Beetle.name=Огненный жук -entity.TwilightForest.Slime Beetle.name=Слизневый жук -entity.TwilightForest.Pinch Beetle.name=Жук с клешнями -entity.TwilightForest.Maze Slime.name=Лабиринтовый слизень -entity.TwilightForest.Redcap Sapper.name=Шахтёр-подрывник -entity.TwilightForest.Mist Wolf.name=Король волков -entity.TwilightForest.King Spider.name=Король пауков -entity.TwilightForest.Firefly.name=Светлячок -entity.TwilightForest.Mini Ghast.name=Мини гаст -entity.TwilightForest.Tower Ghast.name=Охранник тёмной башни -entity.TwilightForest.Tower Golem.name=Голем тёмной башни -entity.TwilightForest.Tower Snowman.name=Снеговик тёмной башни -entity.TwilightForest.Tower Termite.name=Чешуйница тёмной башни -entity.TwilightForest.Redscale Broodling.name=Паук тёмной башни -item.trophy.hydra.name=Трофей Гидры -item.trophy.naga.name=Трофей Наги -item.trophy.lich.name=Трофей Сумеречного Лича -item.trophy.ur-ghast.name=Трофей Тёмного Гаста -item.armorShards.name=Осколок королевского металла -item.knightMetal.name=Королевский металл -item.shardCluster.name=Осколки королевского металла -item.knightlyHelm.name=Королевский шлем -item.knightlyPlate.name=Королевский нагрудник -item.knightlyLegs.name=Королевские поножи -item.knightlyBoots.name=Королевские ботинки -item.knightlySword.name=Королевский меч -item.knightlyPick.name=Королевская кирка -item.knightlyAxe.name=Королевский топор -tile.TFShield.0.name=Крепкий щит -tile.TFShield.1.name=Крепкий щит -tile.TFShield.2.name=Крепкий щит -tile.TFShield.3.name=Крепкий щит -tile.TFShield.4.name=Крепкий щит -tile.TFShield.5.name=Крепкий щит -tile.TFShield.15.name=Крепкий щит -tile.TFTrophyPedestal.0.name=Трофейный пьедестал -tile.TFTrophyPedestal.15.name=Активированный трофейный пьедестал -item.lampOfCinders.name=Лампа огня -tile.TFThorns.brown.name=Шипы -tile.TFThorns.green.name=Зелёные шипы -tile.TFBurntThorns.name=Истлевшие шипы -tile.TFThornRose.name=Шипастая роза -tile.TFPlant.10.name=Лесная трава -tile.TFPlant.11.name=Мёртвый куст -item.fieryTears.name=Огненные слёзы -item.iceBomb.name=Снежная бомба -item.yetiHelm.name=Шапка Йети -item.yetiPlate.name=Куртка Йети -item.yetiLegs.name=Штаны Йети -item.yetiBoots.name=Ботинки Йети -item.alphaFur.name=Мех Альмо-йети -item.arcticFur.name=Артический мех -item.arcticHelm.name=Меховой капюшон -item.arcticPlate.name=Меховая куртка -entity.TwilightForest.Yeti.name=Йети -entity.TwilightForest.Yeti Boss.name=Альмо-йети -entity.TwilightForest.WinterWolf.name=Снежный волк -entity.TwilightForest.SnowGuardian.name=Снежный страж -item.arcticLegs.name=Меховые штаны -item.arcticBoots.name=Меховые ботинки -tile.TFAuroraBrick.name=Блок Авроры -tile.TFDeadrock.surface.name=Влажный камень смерти -tile.TFDeadrock.cracked.name=Потрескавшийся камень смерти -tile.TFDeadrock.solid.name=Камень смерти -tile.DarkLeaves.name=Листва тёмного дерева -tile.AuroraPillar.name=Колонна Авроры -tile.AuroraSlab.name=Плита Авроры -achievement.twilightPortal=Почему бы и нет? -achievement.twilightPortal.desc=Постройте портал в сумеречный лес. -achievement.twilightArrival=В сумеречный лес! -achievement.twilightArrival.desc=Прыгните в портал -achievement.twilightHunter=Лесной убийца -achievement.twilightHunter.desc=Убейте существо в сумеречном лесу. -achievement.twilightMagicMapFocus=Написанное огнём -achievement.twilightMagicMapFocus.desc=Сделайте магическое перо. -achievement.twilightKillNaga=Убийца Наги -achievement.twilightKillNaga.desc=Убейте Нагу впервые. -achievement.twilightNagaArmors=Выглядит прочно -achievement.twilightNagaArmors.desc=Сделайте броню из сердец Наги. -achievement.twilightKillLich=Убить мёртвого. -achievement.twilightKillLich.desc=Убейте Лича в его башне. -achievement.twilightLichScepters=Мастер по посохам -achievement.twilightLichScepters.desc=Соберите полную коллекцию посохов. -achievement.twilightHill1=ЭТИ БОТИНКИ МОИ!!! -achievement.twilightHill1.desc=Убейте шахтёра в маленьком холме. -achievement.twilightHill2=Повзрывай мне тут! -achievement.twilightHill2.desc=Убейте шахтёра-подрывника в среднем холме. -achievement.twilightHill3=Я вижу тебя насквозь -achievement.twilightHill3.desc=Встретьте и убейте призрака в большом холме. -achievement.twilightHedge="Любитель" насекомых -achievement.twilightHedge.desc=Убейте паука в хеджовом лабиринте. -achievement.twilightMagicMap=Далеко гляжу -achievement.twilightMagicMap.desc=Сделайте магическую карту. -achievement.twilightMazeMap=Теперь, я найду выход -achievement.twilightMazeMap.desc=Сделайте карту лабиринта. -achievement.twilightOreMap=Почему бы и нет? -achievement.twilightOreMap.desc=Сделайте шахтёрскую карту. -achievement.twilightKillHydra=Убийца Гидры -achievement.twilightKillHydra.desc=Убейте Гидру в её логове. -achievement.twilightHydraChop=Массивные отбивные -achievement.twilightHydraChop.desc=Попробуйте на вкус мясо Гидры. -achievement.twilightMazebreaker=Крушитель лабиринтов -achievement.twilightMazebreaker.desc=Найдите кирку лабиринта в секретном хранилище. -achievement.twilightFierySet=Кровь и слёзы -achievement.twilightFierySet.desc=Наденьте что-нибудь из огненной брони. -achievement.twilightQuestRam=Непревзойдённый -achievement.twilightQuestRam.desc=Завершите квест Рама. -achievement.twilightProgressNaga=Чешуйчатый герой -achievement.twilightProgressNaga.desc=Имея броню из сердец Наги, наведайте Лича. -achievement.twilightProgressLich=Прикосновение нежити -achievement.twilightProgressLich.desc=Это довольно трудно объяснить... -achievement.twilightProgressLabyrinth=Могучий Строганов -achievement.twilightProgressLabyrinth.desc=Суп из минотавра помогает мне пойти на огненное болото. -achievement.twilightProgressHydra=От одной крови -achievement.twilightProgressHydra.desc=Огненная кровь поможет мне пойти в тёмный лес. -achievement.twilightProgressTrophyPedestal=Чемпион с трофеями. -achievement.twilightProgressTrophyPedestal.desc=Заявите о своём титуле, поставив трофей на пьедестал в лесных руинах. -achievement.twilightProgressKnights=Карминитовая акклиматизация -achievement.twilightProgressKnights.desc=Призраки будут слушаться вас. -achievement.twilightProgressUrghast=Слёзы огня -achievement.twilightProgressUrghast.desc=Прикоснитесь к слёзам Тёмного Гаста, чтобы противостоять холоду снежного леса. -achievement.twilightProgressYeti=Тёплый мех -achievement.twilightProgressYeti.desc=Линия одежды с мехом Альмо-йети сохранит вас от мороза -achievement.twilightProgressGlacier=Убийца тролля -achievement.twilightProgressGlacier.desc=Убейте тролля в замке Авроры -achievement.twilightProgressTroll=Я желаю больше огня -achievement.twilightProgressTroll.desc=Найдите лампу огня в пещерах троллей и она поможет вам. -achievement.twilightProgressThorns=Мимо шипов -achievement.twilightProgressThorns.desc=Откройте дверь в замок. -achievement.twilightProgressCastle=Этот замок классный -achievement.twilightProgressCastle.desc=Что может быть ещё в этом замке? -enchantment.tfChillAura=Ледяная аура -item.minotaurAxe.tooltip=Дополнительный урон во время бега -item.knightlySword.tooltip=Дополнительный урон по бронированным целям -item.knightlyPick.tooltip=Дополнительный урон по бронированным целям -item.knightlyAxe.tooltip=Дополнительный урон по не бронированным целям -item.giantPick.name=Кирка гиганта -item.giantSword.name=Меч гиганта -item.tripleBow.name=Тройной лук -item.seekerBow.name=Лук искателя -item.iceBow.name=Ледяной лук -item.enderBow.name=Эндер лук -item.iceSword.name=Ледяной меч -item.glassSword.name=Стеклянный меч -tile.TrollSteinn.name=Тролльштеин -tile.WispyCloud.name=Прозрачное облако -tile.FluffyCloud.name=Взбытое облако -tile.GiantCobble.name=Гигантский булыжник -tile.GiantLog.name=Гигантское дерево -tile.GiantLeaves.name=Гигантские листья -tile.GiantObsidian.name=Гигантский обсидиан -tile.UberousSoil.name=Анбеоновая почва -tile.HugeStalk.name=Огромный стебель -tile.HugeGloomBlock.name=Огромный грибрил -tile.TrollVidr.name=Тролловидр -tile.UnripeTrollBer.name=Спелый тролльбер -tile.TrollBer.name=Тролльбер -tile.TFLeaves3.1.name=Бобовые листья -item.magicBeans.name=Волшебные семена -entity.TwilightForest.Stable Ice Core.name=Стабильное замёрзшее ядро -entity.TwilightForest.Unstable Ice Core.name=Нестабильное замёрзшее ядро -entity.TwilightForest.Snow Queen.name=Снежная королева -entity.TwilightForest.Troll.name=Пещерный тролль -entity.TwilightForest.Giant Miner.name=Гигант шахтёра -entity.TwilightForest.Armored Giant.name=Бронированный гигант -entity.TwilightForest.Ice Crystal.name=Ледяной кристалл -tile.TFFireJet.1.name=Приручённый дымок -tile.TFFireJet.2.name=Приручённый дымок -tile.TFFireJet.11.name=Заключённый огонёк -tile.TFFireJet.12.name=Заключённый шумящий огонёк -tile.TFFireJet.13.name=Заключённый пылающий огонёк -item.fieryPick.tooltip=Авто переплавка -tem.giantPick.tooltip=Ломает гигантские блоки -item.fierySword.tooltip=Поджигает цель -item.fieryHelm.tooltip=Поджигает атакующего -item.fieryPlate.tooltip=Поджигает атакующего -item.fieryLegs.tooltip=Поджигает атакующего -item.fieryBoots.tooltip=Поджигает атакующего -item.yetiHelm.tooltip=Охлаждает атакующего -item.yetiPlate.tooltip=Охлаждает атакующего -item.yetiLegs.tooltip=Охлаждает атакующего -item.yetiBoots.tooltip=Охлаждает атакующего \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/ru_ru.lang b/src/main/resources/assets/twilightforest/lang/ru_ru.lang new file mode 100644 index 0000000000..f47bb1c1a4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/ru_ru.lang @@ -0,0 +1,855 @@ +#PARSE_ESCAPES + +itemGroup.twilightForest=Twilight Forest + +# ADVANCEMENTS +advancement.twilightforest.root.desc=Войдите в загадочные магические леса; Сумеречный лес. + +# General progression +advancement.twilightforest.hedge=Любитель насекомых +advancement.twilightforest.hedge.desc=Победить паука в лабиринте хеджа. + +advancement.twilightforest.hill1=Сапоги мои! +advancement.twilightforest.hill1.desc=Убейте шахтёра в маленьком холме. +advancement.twilightforest.hill2=Что это за шум? +advancement.twilightforest.hill2.desc=Убейте шахтёра-подрывника в среднем холме. +advancement.twilightforest.hill3=Я вижу тебя насквозь +advancement.twilightforest.hill3.desc=Встретьте и убейте призрака в большом холме. + +advancement.twilightforest.quest_ram=Непревзойдённый +advancement.twilightforest.quest_ram.desc=Дайте Квест раму то, что ему не хватает. + +# Map +advancement.twilightforest.magic_map_focus=Написанное огнём +advancement.twilightforest.magic_map_focus.desc=Сделайте магическое перо. +advancement.twilightforest.magic_map=Далеко гляжу +advancement.twilightforest.magic_map.desc=Создайте магическую карту. +advancement.twilightforest.maze_map=Теперь, я найду выход +advancement.twilightforest.maze_map.desc=Создайте карту лабиринта, получив фокус от лабиринта. +advancement.twilightforest.ore_map=Почему бы и нет? +advancement.twilightforest.ore_map.desc=Создайте карту лабиринта/руды. + +# Mainline beginning progression +advancement.twilightforest.twilight_hunter=Лесной убийца +advancement.twilightforest.twilight_hunter.desc=Убейте существо в сумеречном лесу. + +advancement.twilightforest.kill_naga=Убийца наги +advancement.twilightforest.kill_naga.desc=Убейте нагу впервые. +advancement.twilightforest.naga_armors=Броня Наги +advancement.twilightforest.naga_armors.desc=Сделайте броню из сердец наги. + +advancement.twilightforest.kill_lich=Убить мёртвого. +advancement.twilightforest.kill_lich.desc=Убейте лича в его башне. +advancement.twilightforest.lich_scepters=Наши силы объединены! +advancement.twilightforest.lich_scepters.desc=Приобрести все три скипетра власти. + +# Swamp Progression +advancement.twilightforest.progress_labyrinth=Могучий строганов +advancement.twilightforest.progress_labyrinth.desc=Мясо и мускусное блюдо приятно согревает вас, настолько, что вы чувствуете, что достаточно акклиматизированы, чтобы отправиться в Огненное болото. +advancement.twilightforest.kill_hydra=Убийца гидры +advancement.twilightforest.kill_hydra.desc=Убейте гидру в её логове. +advancement.twilightforest.mazebreaker=Крушитель лабиринтов +advancement.twilightforest.mazebreaker.desc=Найдите кирку лабиринта в секретном хранилище. +advancement.twilightforest.hydra_chop=Массивные отбивные +advancement.twilightforest.hydra_chop.desc=Попробуйте на вкус мясо гидры. + +# Dark Forest Progression +advancement.twilightforest.progress_trophy_pedestal=Трофейный чемпион. +advancement.twilightforest.progress_trophy_pedestal.desc=Заявите о своём титуле, поставив трофей на пьедестал в лесных руинах. +advancement.twilightforest.progress_knights=Карминитовая акклиматизация +advancement.twilightforest.progress_knights.desc=Успокойте беспокойные фантомы в Могиле Рыцаря, и устройства карминитовой башни повинуются вам. +advancement.twilightforest.ghast_trap=Что-то странное в Деревянной башне +advancement.twilightforest.ghast_trap.desc=Убейте мини гаста около ловушки гаста и активируйте ключ темного гаста из неба! +advancement.twilightforest.progress_ur_ghast=Слёзы огня +advancement.twilightforest.progress_ur_ghast.desc=Прикоснитесь к слёзам тёмного гаста, чтобы противостоять холоду снежного леса. + +advancement.twilightforest.experiment_115=Таинственное мясо? +advancement.twilightforest.experiment_115.desc=Это похоже на торт, хотя ... +advancement.twilightforest.experiment_115_2=Делаем заметку: Огромный успех! +advancement.twilightforest.experiment_115_2.desc=Это так вкусно и влажно! + +# Snow Forest Progression +advancement.twilightforest.progress_yeti=Тёплый мех +advancement.twilightforest.progress_yeti.desc=Линия одежды с мехом альмо-йети сохранит вас от мороза. +advancement.twilightforest.progress_glacier=Чистое небо +advancement.twilightforest.progress_glacier.desc=Победите Снежную Королеву на вершине дворца Авроры, очистив кислотный дождь от высокогорья. +advancement.twilightforest.arctic_dyed=Получилось модно +advancement.twilightforest.arctic_dyed.desc=Покрасьте все четыре части арктической брони. + +# Mid-way Misc. Stuff +advancement.twilightforest.glass_sword=Один чудо-удар +advancement.twilightforest.glass_sword.desc=Надеюсь, вы хорошо это использовали. + +advancement.twilightforest.fiery_set=Кровь и слёзы +advancement.twilightforest.fiery_set.desc=Используйте огненный инструмент или оружие, неся хотя бы одну часть огненной брони. + +# Highlands + + +advancement.twilightforest.progress_troll=Я желаю больше огня +advancement.twilightforest.progress_troll.desc=Найдите лампу печей в тролль-пещерах, и вы можете сжечь тернистые барьеры. +advancement.twilightforest.progress_thorns=Мимо шипов +advancement.twilightforest.progress_thorns.desc=Пройдите мимо терновников и откройте дверь замка. +advancement.twilightforest.progress_castle=Этот замок классный +advancement.twilightforest.progress_castle.desc=Что может быть ещё в этом замке?!? + +# Collections +advancement.twilightforest.twilight_dining=Мы поужинаем в вечном закате +advancement.twilightforest.twilight_dining.desc=Ешьте ВСЕ продукты исключительно в Сумеречном лесу. +advancement.twilightforest.experiment_115_3=Питание 115 Ежедневно, 115 Лет, Навсегда +advancement.twilightforest.experiment_115_3.desc=ест эксперимента сто пятнадцать весь день, навсегда, сто пятнадцать раз эксперимент сто пятнадцать, эксперимент сто пятнадцать точка ком, дабл-Ю дабл-Ю дабл-Ю точка эксперимента сто пятнадцать точка ком, сто пятнадцать лет, каждую минуту эксперимента сто пятнадцать точка ком, дабл-Ю дабл-Ю дабл-Ю точка сто-пятнадцать раз эксперимент сто пятнадцать точка ком +advancement.twilightforest.arborist=Маникальный дендролог + + +twilightforest.twilight_portal.unsafe=Кажется, здесь небезопасно... +twilightforest.trophy_pedestal.ineligible=Вы недостойны. +twilightforest.ore_meter.range=Радиус: %s, Происхождение: [%s, %s] +twilightforest.ore_meter.exposed=Выставлено: %s +twilightforest.scepter_charges=%d зарядов осталось + +# Commands + + + + + + + + + + + + +# Blocks +tile.twilightforest.Log.0.name=Сумеречный дуб +tile.twilightforest.Log.1.name=Сумеречная сосна +tile.twilightforest.Log.2.name=Сумеречная берёза +tile.twilightforest.Log.3.name=Тёмное дерево +tile.twilightforest.Leaves.0.name=Листва сумеречного дуба +tile.twilightforest.Leaves.1.name=Листва сумеречной сосны +tile.twilightforest.Leaves.2.name=Листва сумеречной берёзы +tile.twilightforest.Leaves.3.name=Разноцветная листва +tile.twilightforest.Firefly.name=Светлячок +tile.twilightforest.Cicada.name=Цикада +tile.twilightforest.Cicada.desc=Что, если запустить это в кого-то рейлганом? +item.twilightforest.Portal.name=Портал в сумеречный лес +tile.twilightforest.Portal.name=Портал в сумеречный лес +tile.twilightforest.Mazestone.0.name=Камень лабиринта +tile.twilightforest.Mazestone.1.name=Кладка из камня лабиринта +tile.twilightforest.Mazestone.2.name=Гладкая лабиринтовая кладка +tile.twilightforest.Mazestone.3.name=Декоративная лабиринтовая кладка +tile.twilightforest.Mazestone.4.name=Потресканая лабиринтовая кладка +tile.twilightforest.Mazestone.5.name=Замшелая лабиринтовая кладка +tile.twilightforest.Mazestone.6.name=Узорчатая лабиринтовая кладка +tile.twilightforest.Mazestone.7.name=Двойная узорчатая лабиринтовая кладка +tile.twilightforest.Mazestone.8.name=Потолок из камня лабиринта +tile.twilightforest.Hedge.0.name=Живая изгородь +tile.twilightforest.Hedge.1.name=Листва тёмного дерева +tile.twilightforest.BossSpawner.0.name=Спавнер наги +tile.twilightforest.BossSpawner.1.name=Спавнер лича +tile.twilightforest.BossSpawner.2.name=Спавнер гидры +tile.twilightforest.BossSpawner.3.name=Спавнер ур-гаста +tile.twilightforest.BossSpawner.4.name=Спавнер рыцаря фантома +tile.twilightforest.BossSpawner.5.name=Спавнер снежной королевы +tile.twilightforest.BossSpawner.6.name=Спавнер гриботавра +tile.twilightforest.BossSpawner.7.name=Спавнер альфа-йети +tile.twilightforest.FireflyJar.name=Банка со светлячком +tile.twilightforest.Plant.0.name=Клочок мха +tile.twilightforest.Plant.1.name=Майское яблоко +tile.twilightforest.Plant.2.name=Лист клевера [WIP] +tile.twilightforest.Plant.3.name=Сверкающая трава +tile.twilightforest.Plant.4.name=Светогриб +tile.twilightforest.Plant.5.name=Лесная трава +tile.twilightforest.Plant.6.name=Высохший куст +tile.twilightforest.Plant.7.name=Факелонтовый росток +tile.twilightforest.Plant.8.name=Висячие корни +tile.twilightforest.Roots.0.name=Корни +tile.twilightforest.Roots.1.name=Замшелые корни +tile.twilightforest.UncraftingTable.name=Разборочный верстак +tile.twilightforest.FireJet.0.name=Дымовой блок +tile.twilightforest.FireJet.1.name=Прирученный дымок +tile.twilightforest.FireJet.2.name=Прирученный дымок +tile.twilightforest.FireJet.3.name=Огненный блок +tile.twilightforest.FireJet.4.name=Дымящийся огненный блок +tile.twilightforest.FireJet.5.name=Горящий огненный блок +tile.twilightforest.FireJet.6.name=Заключённый огонёк +tile.twilightforest.FireJet.7.name=Заключённый шумящий огонёк +tile.twilightforest.FireJet.8.name=Заключённый пылающий огонёк +tile.twilightforest.Nagastone.0.name=Голова нагокамня +tile.twilightforest.Nagastone.1.name=Нагакамень +tile.twilightforest.Sapling.name=Сумеречный саженец +tile.twilightforest.Sapling.0.name=Саженец сумеречного дуба +tile.twilightforest.Sapling.1.name=Саженец сумеречной сосны +tile.twilightforest.Sapling.2.name=Саженец сумеречной берёзы +tile.twilightforest.Sapling.3.name=Саженец тёмного дерева +tile.twilightforest.Sapling.4.name=Саженец большого сумеречного дуба +tile.twilightforest.Sapling.5.name=Саженец дерева времени +tile.twilightforest.Sapling.6.name=Саженец дерева преобразования +tile.twilightforest.Sapling.7.name=Саженец дерева шахтёра +tile.twilightforest.Sapling.8.name=Саженец сортировочного дерева +tile.twilightforest.Sapling.9.name=Саженец разноцветного дерева +tile.twilightforest.Moonworm.name=Гусеница +tile.twilightforest.MagicLog.0.name=Дерево времени +tile.twilightforest.MagicLog.1.name=Загадочное дерево +tile.twilightforest.MagicLog.2.name=Дерево шахтёра +tile.twilightforest.MagicLog.3.name=Правильное дерево +tile.twilightforest.MagicLogSpecial.0.name=Дерево времени +tile.twilightforest.MagicLogSpecial.1.name=Мудрое дерево +tile.twilightforest.MagicLogSpecial.2.name=Ядро дерева шахтёра +tile.twilightforest.MagicLogSpecial.3.name=Ядро дерева сортировки +tile.twilightforest.MagicLeaves.0.name=Листва дерева времени +tile.twilightforest.MagicLeaves.1.name=Листва мудрого дерева +tile.twilightforest.MagicLeaves.2.name=Листва шахтёра +tile.twilightforest.MagicLeaves.3.name=Листва сортировки +tile.twilightforest.TowerStone.0.name=Доски тёмной башни +tile.twilightforest.TowerStone.1.name=Боковые доски тёмной башни +tile.twilightforest.TowerStone.2.name=Треснутые доски тёмной башни +tile.twilightforest.TowerStone.3.name=Замшелые доски тёмной башни +tile.twilightforest.TowerStone.4.name=Инфицированные доски тёмной башни +tile.twilightforest.TowerDevice.0.name=Восстанавливающийся блок +tile.twilightforest.TowerDevice.1.name=Активный восстанавливающийся блок +tile.twilightforest.TowerDevice.2.name=Исчезающий блок +tile.twilightforest.TowerDevice.3.name=Активный исчезающий блок +tile.twilightforest.TowerDevice.4.name=Заблокированный восстанавливающийся блок +tile.twilightforest.TowerDevice.5.name=Разблокированный восстанавливающийся блок +tile.twilightforest.TowerDevice.6.name=Строитель башни +tile.twilightforest.TowerDevice.7.name=Активный строитель башни +tile.twilightforest.TowerDevice.8.name=Неактивный строитель башни +tile.twilightforest.TowerDevice.9.name=Антистроитель +tile.twilightforest.TowerDevice.10.name=Ловушка для гаста +tile.twilightforest.TowerDevice.11.name=Активная ловушка для гаста +tile.twilightforest.TowerDevice.12.name=Карминитовый реактор +tile.twilightforest.TowerDevice.13.name=Активный карминитовый реактор +tile.twilightforest.TowerTranslucent.0.name=Восстанавливающийся блок +tile.twilightforest.TowerTranslucent.1.name=Активный восстанавливающийся блок +tile.twilightforest.TowerTranslucent.2.name=Блок строителя башни +tile.twilightforest.TowerTranslucent.3.name=Активный построенный блок карминита +tile.twilightforest.TowerTranslucent.4.name=Анти-строитель башни +tile.twilightforest.TowerTranslucent.5.name=Обломки реактора карминита +tile.twilightforest.TowerTranslucent.6.name=Поддельное золото +tile.twilightforest.TowerTranslucent.7.name=Поддельный алмаз +tile.twilightforest.Trophy.name=Трофей сумеречного леса +tile.twilightforest.Shield.name=Крепкий щит +tile.twilightforest.TrophyPedestal.0.name=Трофейный пьедестал +tile.twilightforest.TrophyPedestal.15.name=Скрытый трофейный пьедестал +tile.twilightforest.AuroraBrick.name=Блок Авроры +tile.twilightforest.UnderBrick.0.name=Подземные кирпичи +tile.twilightforest.UnderBrick.1.name=Замшелые подземные кирпичи +tile.twilightforest.UnderBrick.2.name=Потресканные подземные кирпичи +tile.twilightforest.UnderBrick.3.name=Подземный пол +tile.twilightforest.Thorns.brown.name=Шипы +tile.twilightforest.Thorns.green.name=Зеленые шипы +tile.twilightforest.BurntThorns.name=Истлевшие шипы +tile.twilightforest.ThornRose.name=Шипастая роза +tile.twilightforest.Leaves3.0.name=Шиповые листья +tile.twilightforest.Leaves3.1.name=Бобовые листья +tile.twilightforest.Deadrock.surface.name=Влажный камень смерти +tile.twilightforest.Deadrock.cracked.name=Потрескавшийся камень смерти +tile.twilightforest.Deadrock.solid.name=Камень смерти +tile.twilightforest.DarkLeaves.name=Листва тёмного дерева +tile.twilightforest.AuroralizedGlass.name=Авроризованное стекло +tile.twilightforest.AuroraPillar.name=Колонна Авроры +tile.twilightforest.AuroraSlab.name=Плита Авроры +tile.twilightforest.TrollSteinn.name=Тролльштейн +tile.twilightforest.WispyCloud.name=Прозрачное облако +tile.twilightforest.FluffyCloud.name=Взбитое облако +tile.twilightforest.GiantCobble.name=Гигантский булыжник +tile.twilightforest.GiantLog.name=Гигантское дерево +tile.twilightforest.GiantLeaves.name=Гигантские листья +tile.twilightforest.GiantObsidian.name=Гигантский обсидиан +tile.twilightforest.UberousSoil.name=Анбеоновая почва +tile.twilightforest.HugeStalk.name=Огромный стебель +tile.twilightforest.HugeGloomBlock.name=Огромный грибрил +tile.twilightforest.TrollVidr.name=Тролловидр +tile.twilightforest.UnripeTrollBer.name=Спелый тролльбер +tile.twilightforest.TrollBer.name=Тролльбер +tile.twilightforest.TrollBer.name=Тролльбер +tile.twilightforest.KnightmetalBlock.name=Блок королевского металла +tile.twilightforest.HugeLilyPad.name=Огромные лилии +tile.twilightforest.HugeWaterLily.name=Огромная кувшинка +tile.twilightforest.Slider.0.name=Скользящая ловушка +tile.twilightforest.Slider.1.name=Скользящая ловушка 1 +tile.twilightforest.Slider.2.name=Скользящая ловушка 2 +tile.twilightforest.Slider.3.name=Скользящая ловушка 3 +tile.twilightforest.CastleBrick.0.name=Кирпич замка +tile.twilightforest.CastleBrick.1.name=Изношенный кирпич замка +tile.twilightforest.CastleBrick.2.name=Потресканный кирпич замка +tile.twilightforest.CastleBrick.3.name=Замковая крыша +tile.twilightforest.CastleBrick.4.name=Замшелый кирпич замка +tile.twilightforest.CastleBrick.5.name=Толстый кирпич замка +tile.twilightforest.CastleStairsBrick.name=Ступени из кирпича замка +tile.twilightforest.CastleStairsWorn.name=Ступени из изношенного кирпича замка +tile.twilightforest.CastleStairsCracked.name=Ступени из потресканного кирпича замка +tile.twilightforest.CastleStairsMossy.name=Ступени из замшелого кирпича замка +tile.twilightforest.CastleDoor.0.name=Жёлтая дверь замка +tile.twilightforest.CastleDoor.1.name=Фиолетовая дверь замка +tile.twilightforest.CastleDoor.2.name=Розовая дверь замка +tile.twilightforest.CastleDoor.3.name=Синяя дверь замка +tile.twilightforest.CastleMagic.0.name=Розовый кирпич замка +tile.twilightforest.CastleMagic.1.name=Синий кирпич замка +tile.twilightforest.CastleMagic.2.name=Жёлтый кирпич замка +tile.twilightforest.CastleMagic.3.name=Фиолетовый кирпич замка +tile.twilightforest.CastlePillar.0.name=Облицованная колонна кирпича замка +tile.twilightforest.CastlePillar.1.name=Облицованная плитка кирпича замка +tile.twilightforest.CastlePillar.2.name=Рельефная колонна кирпича замка +tile.twilightforest.CastlePillar.3.name=Рельефная плитка кирпича замка +tile.twilightforest.CastleStairs.0.name=Облицованные ступеньки кирпича замка +tile.twilightforest.CastleStairs.8.name=Рельефные ступеньки кирпича замка +tile.twilightforest.ForceField.0.name=Фиолетовое силовое поле +tile.twilightforest.ForceField.1.name=Розовое силовое поле +tile.twilightforest.ForceField.2.name=Оранжевое силовое поле +tile.twilightforest.ForceField.3.name=Зеленое силовое поле +tile.twilightforest.ForceField.4.name=Синее силовое поле +tile.twilightforest.BlockOfStorage.0.name=Блок железной древесины +tile.twilightforest.BlockOfStorage.1.name=Блок огненного металла +tile.twilightforest.BlockOfStorage.2.name=Блок стального листа +tile.twilightforest.BlockOfStorage.3.name=Блок арктического меха +tile.twilightforest.BlockOfStorage.4.name=Блок карминита +tile.twilightforest.CinderFurnaceIdle.name=Шлаковая печь [NYI] +tile.twilightforest.CinderLog.name=Шлак древесины [NYI] +tile.twilightforest.MiniatureStructure=Миниатюра %s [NYI] +tile.twilightforest.SpiralBricks.name=Спиральные каменные кирпичи [WIP] +tile.twilightforest.BlockOfLapisTF.name=Блок лазурита [NYI] +tile.twilightforest.EtchedNagastone.name=Гравированный нагакамень +tile.twilightforest.NagastonePillar.name=Колонна из нагакамня +tile.twilightforest.NagastoneStairs.0.name=Ступеньки из нагакамня (левая) +tile.twilightforest.NagastoneStairs.8.name=Ступеньки из нагакамня (правая) +tile.twilightforest.EtchedNagastoneMossy.name=Замшелый гравированный нагакамень +tile.twilightforest.NagastonePillarMossy.name=Замшелая колонна из нагакамня +tile.twilightforest.NagastoneStairsMossy.0.name=Замшелые ступеньки из нагакамня (левая) +tile.twilightforest.NagastoneStairsMossy.8.name=Замшелые ступеньки из нагакамня (правая) +tile.twilightforest.EtchedNagastoneWeathered.name=Разрушенный гравированный нагакамень +tile.twilightforest.NagastonePillarWeathered.name=Разрушенный колонна из нагакамня +tile.twilightforest.NagastoneStairsWeathered.0.name=Выветрившиеся ступеньки из нагакамня (левая) +tile.twilightforest.NagastoneStairsWeathered.8.name=Выветрившиеся ступеньки из нагакамня (правая) +tile.twilightforest.IronLadder.name=Железная лестница +tile.twilightforest.TerrorCottaCircle.name=Терроркотта (круглая) +tile.twilightforest.TerrorCottaDiagonal.name=Терроркотта (диагональная) + +tile.twilightforest.CanopyPlanks.name=Сосновые доски +tile.twilightforest.CanopyStairs.name=Сосновые ступеньки +tile.twilightforest.CanopySlab.name=Сосновая плитка +tile.twilightforest.CanopyButton.name=Сосновая кнопка +tile.twilightforest.CanopyFence.name=Сосновый забор +tile.twilightforest.CanopyGate.name=Сосновая калитка +tile.twilightforest.CanopyPlate.name=Сосновая нажимная плита +tile.twilightforest.CanopyTrapDoor.name=Сосновый люк +item.tile.twilightforest.CanopyDoor.name=Сосновая дверь + +tile.twilightforest.DarkPlanks.name=Тёмные доски +tile.twilightforest.DarkStairs.name=Тёмные ступеньки +tile.twilightforest.DarkSlab.name=Тёмная плита +tile.twilightforest.DarkButton.name=Тёмная кнопка +tile.twilightforest.DarkFence.name=Тёмный забор +tile.twilightforest.DarkGate.name=Тёмная калитка +tile.twilightforest.DarkPlate.name=Тёмная нажимная плита +tile.twilightforest.DarkTrapDoor.name=Тёмный люк + + +tile.twilightforest.MangrovePlanks.name=Доски из сумеречной берёзы +tile.twilightforest.MangroveStairs.name=Ступеньки из сумеречной берёзы +tile.twilightforest.MangroveSlab.name=Плита из сумеречной берёзы +tile.twilightforest.MangroveButton.name=Кнопка из сумеречной берёзы +tile.twilightforest.MangroveFence.name=Забор из сумеречной берёзы +tile.twilightforest.MangroveGate.name=Калитка из сумеречной берёзы +tile.twilightforest.MangrovePlate.name=Нажимная плита из сумеречной берёзы +tile.twilightforest.MangroveTrapDoor.name=Люк из сумеречной берёзы + + +tile.twilightforest.TwilightOakPlanks.name=Доски из сумеречного дуба +tile.twilightforest.TwilightOakStairs.name=Ступеньки из сумеречного дуба +tile.twilightforest.TwilightOakSlab.name=Плита из сумеречного дуба +tile.twilightforest.TwilightOakButton.name=Кнопка из сумеречного дуба +tile.twilightforest.TwilightOakFence.name=Забор из сумеречного дуба +tile.twilightforest.TwilightOakGate.name=Калитка из сумеречного дуба +tile.twilightforest.TwilightOakPlate.name=Нажимная плита из сумеречного дуба +tile.twilightforest.TwilightOakTrapDoor.name=Люк из сумеречного дуба +item.tile.twilightforest.TwilightOakDoor.name=Дверь из сумеречного дуба + +tile.twilightforest.TimePlanks.name=Доски из дерева времени +tile.twilightforest.TimeStairs.name=Ступеньки из дерева времени +tile.twilightforest.TimeSlab.name=Плита из дерева времени +tile.twilightforest.TimeButton.name=Кнопка из дерева времени +tile.twilightforest.TimeFence.name=Забор из дерева времени +tile.twilightforest.TimeGate.name=Калитка из дерева времени +tile.twilightforest.TimePlate.name=Нажимная плита из дерева времени +tile.twilightforest.TimeTrapDoor.name=Люк из дерева времени +item.tile.twilightforest.TimeDoor.name=Дверь из дерева времени + +tile.twilightforest.TransPlanks.name=Доски из загадочного дерева +tile.twilightforest.TransStairs.name=Ступеньки из загадочного дерева +tile.twilightforest.TransSlab.name=Плита из загадочного дерева +tile.twilightforest.TransButton.name=Кнопка из загадочного дерева +tile.twilightforest.TransFence.name=Забор из загадочного дерева +tile.twilightforest.TransGate.name=Калитка из загадочного дерева +tile.twilightforest.TransPlate.name=Нажимная плита из загадочного дерева +tile.twilightforest.TransTrapDoor.name=Люк из загадочного дерева +item.tile.twilightforest.TransDoor.name=Дверь из загадочного дерева + +tile.twilightforest.MinePlanks.name=Доски из дерева шахтёра +tile.twilightforest.MineStairs.name=Ступеньки из дерева шахтёра +tile.twilightforest.MineSlab.name=Плита из дерева шахтёра +tile.twilightforest.MineButton.name=Кнопка из дерева шахтёра +tile.twilightforest.MineFence.name=Забор из дерева шахтёра +tile.twilightforest.MineGate.name=Калитка из дерева шахтёра +tile.twilightforest.MinePlate.name=Нажимная плита из дерева шахтёра +tile.twilightforest.MineTrapDoor.name=Люк из дерева шахтёра +item.tile.twilightforest.MineDoor.name=Дверь из дерева шахтёра + +tile.twilightforest.SortPlanks.name=Доски из правильного дерева +tile.twilightforest.SortStairs.name=Ступеньки из правильного дерева +tile.twilightforest.SortSlab.name=Плита из правильного дерева +tile.twilightforest.SortButton.name=Кнопка из правильного дерева +tile.twilightforest.SortFence.name=Забор из правильного дерева +tile.twilightforest.SortGate.name=Калитка из правильного дерева +tile.twilightforest.SortPlate.name=Нажимная плита из правильного дерева +tile.twilightforest.SortTrapDoor.name=Люк из правильного дерева +item.tile.twilightforest.SortDoor.name=Дверь из правильного дерева + +# Structures +structure.twilight_portal.name=Сумеречный портал +structure.hedge_maze.name=Лабиринт из живой изгороди +structure.hollow_hill.name=Полый холм +structure.quest_grove.name=Роща поисков +structure.mushroom_tower.name=Грибной замок +structure.naga_courtyard.name=Двор Наги +structure.lich_tower.name=Башня Лича +structure.minotaur_labyrinth.name=Лабиринт Минотавра +structure.hydra_lair.name=Логово Гидры +structure.goblin_stronghold.name=Крепость Гоблина +structure.dark_tower.name=Темная башня +structure.yeti_cave.name=Пещера Йети +structure.aurora_palace.name=Дворец Авроры +structure.troll_cave_and_cloud_castle.name=Пещера Тролля и Дом в облаках +structure.final_castle.name=Финальный замок + +# Items +item.twilightforest.nagaScale.name=Чешуя наги +item.twilightforest.plateNaga.name=Нагрудник из чешуи наги +item.twilightforest.legsNaga.name=Поножи из чешуи наги +item.twilightforest.scepterTwilight.name=Сумеречный посох +item.twilightforest.scepterLifeDrain.name=Посох поглощения жизни +item.twilightforest.scepterZombie.name=Посох нежити +item.twilightforest.scepterShield.name=Посох укрепления +item.twilightforest.oreMeter.name=Определитель руд [WIP] +item.twilightforest.magicMap.name=Магическая карта +item.twilightforest.mazeMap.name=Карта лабиринта +item.twilightforest.oreMap.name=Карта шахты +item.twilightforest.tfFeather.name=Воронье перо +item.twilightforest.magicMapFocus.name=Фокус магической карты +item.twilightforest.mazeMapFocus.name=Фокус карты лабиринта +item.twilightforest.liveRoot.name=Замшелый корень +item.twilightforest.ironwoodRaw.name=Железное дерево +item.twilightforest.ironwoodIngot.name=Слиток железного дерева +item.twilightforest.ironwoodHelm.name=Шлем из железного дерева +item.twilightforest.ironwoodPlate.name=Нагрудник из железного дерева +item.twilightforest.ironwoodLegs.name=Поножи из железного дерева +item.twilightforest.ironwoodBoots.name=Ботинки из железного дерева +item.twilightforest.ironwoodSword.name=Меч из железного дерева +item.twilightforest.ironwoodShovel.name=Лопата из железного дерева +item.twilightforest.ironwoodPick.name=Кирка из железного дерева +item.twilightforest.ironwoodAxe.name=Топор из железного дерева +item.twilightforest.ironwoodHoe.name=Мотыга из железного дерева +item.twilightforest.torchberries.name=Факелонт +item.twilightforest.venisonRaw.name=Сырая оленина +item.twilightforest.venisonCooked.name=Олений стейк +item.twilightforest.hydraChop.name=Мясо гидры +item.twilightforest.fieryBlood.name=Огенная кровь +item.twilightforest.fieryIngot.name=Огненный слиток +item.twilightforest.fieryHelm.name=Огненный шлем +item.twilightforest.fieryPlate.name=Огненный нагрудник +item.twilightforest.fieryLegs.name=Огненные поножи +item.twilightforest.fieryBoots.name=Огненные ботинки +item.twilightforest.fierySword.name=Огненный меч +item.twilightforest.fieryPick.name=Огненная кирка +item.twilightforest.steeleafIngot.name=Стальной лист +item.twilightforest.steeleafHelm.name=Шлем из стальных листьев +item.twilightforest.steeleafPlate.name=Нагрудник из стальных листьев +item.twilightforest.steeleafLegs.name=Поножи из стальных листьев +item.twilightforest.steeleafBoots.name=Ботинки из стальных листьев +item.twilightforest.steeleafSword.name=Меч из стальных листьев +item.twilightforest.steeleafShovel.name=Лопата из стальных листьев +item.twilightforest.steeleafPick.name=Кирка из стальных листьев +item.twilightforest.steeleafAxe.name=Топор из стальных листьев +item.twilightforest.steeleafHoe.name=Мотыга из стальных листьев +item.twilightforest.minotaurAxe.name=Алмазный топор минотавра +item.twilightforest.minotaurAxeGold.name=Золотой топор минотавра +item.twilightforest.mazebreakerPick.name=Разрушитель лабиринтов +item.twilightforest.transformPowder.name=Порошок трансформации +item.twilightforest.meefRaw.name=Мясо минотавра +item.twilightforest.meefSteak.name=Стейк из минотавра +item.twilightforest.meefStroganoff.name=Суп из минотавра +item.twilightforest.mazeWafer.name=Вафли +item.twilightforest.emptyMagicMap.name=Пустая магическая карта +item.twilightforest.emptyMazeMap.name=Пустая карта лабиринта +item.twilightforest.emptyOreMap.name=Пустая карта шахты +item.twilightforest.oreMagnet.name=Рудный магнит +item.twilightforest.crumbleHorn.name=Рог +item.twilightforest.peacockFan.name=Веер полёта +item.twilightforest.moonwormQueen.name=Королева гусениц +item.twilightforest.charmOfLife1.name=Амулет жизни I +item.twilightforest.charmOfLife2.name=Амулет жизни II +item.twilightforest.charmOfKeeping1.name=Амулет инвентаря I +item.twilightforest.charmOfKeeping2.name=Амулет инвентаря II +item.twilightforest.charmOfKeeping3.name=Амулет инвентаря III +item.twilightforest.towerKey.name=Ключ от башни +item.twilightforest.borerEssence.name=Буровая эссенция +item.twilightforest.carminite.name=Карминит +item.twilightforest.tf_trophy.name=%s трофей +item.twilightforest.trophy.hydra.name=Трофей гидры +item.twilightforest.trophy.naga.name=Трофей наги +item.twilightforest.trophy.lich.name=Трофей сумеречного лича +item.twilightforest.trophy.ur_ghast.name=Трофей ур-гаста +item.twilightforest.trophy.snow_queen.name=Трофей снежной королевы +item.twilightforest.experiment115.name=Эксперимент 115 +item.twilightforest.armorShards.name=Осколок рыцарского металла +item.twilightforest.knightMetal.name=Слиток рыцарского металла +item.twilightforest.shardCluster.name=Осколки рыцарского металла +item.twilightforest.knightlyHelm.name=Рыцарский шлем +item.twilightforest.knightlyPlate.name=Рыцарский нагрудник +item.twilightforest.knightlyLegs.name=Рыцарские поножи +item.twilightforest.knightlyBoots.name=Рыцарские ботинки +item.twilightforest.knightlySword.name=Рыцарский меч +item.twilightforest.knightlyPick.name=Рыцарская кирка +item.twilightforest.knightlyAxe.name=Рыцарский топор +item.twilightforest.knightlyShield.name=Рыцарский щит +item.twilightforest.phantomHelm.name=Шлем Фантома +item.twilightforest.phantomPlate.name=Нагрудник Фантома +item.twilightforest.lampOfCinders.name=Лампа огня +item.twilightforest.fieryTears.name=Огненные слёзы +item.twilightforest.iceBomb.name=Ледяная бомба +item.twilightforest.yetiHelm.name=Шапка йети +item.twilightforest.yetiPlate.name=Куртка йети +item.twilightforest.yetiLegs.name=Штаны йети +item.twilightforest.yetiBoots.name=Ботинки йети +item.twilightforest.alphaFur.name=Мех Альфа-йети +item.twilightforest.arcticFur.name=Арктический мех +item.twilightforest.arcticHelm.name=Меховой капюшон +item.twilightforest.arcticPlate.name=Меховая куртка +item.twilightforest.arcticLegs.name=Меховые штаны +item.twilightforest.arcticBoots.name=Меховые ботинки +item.twilightforest.magicBeans.name=Волшебные бобы +item.twilightforest.giantPick.name=Гигантская кирка +item.twilightforest.giantSword.name=Гигантский меч +item.twilightforest.tripleBow.name=Тройной лук +item.twilightforest.seekerBow.name=Лук искателя +item.twilightforest.iceBow.name=Ледяной лук +item.twilightforest.enderBow.name=Эндер-лук +item.twilightforest.iceSword.name=Ледяной меч +item.twilightforest.glassSword.name=Стеклянный меч +item.twilightforest.knightmetalRing.name=Петля королевского металла +item.twilightforest.chainBlock.name=Блок цепей +item.twilightforest.cubeTalisman.name=Талисман куба +item.twilightforest.cubeOfAnnihilation.name=Куб аннигиляции +item.twilightforest.moonDial.name=Лунный циферблат + +item.twilightforest.guide.name=Дневник путешественника + +item.twilightforest.minotaurAxe.tooltip=Дополнительный урон во время бега +item.twilightforest.minotaurAxeGold.tooltip=Дополнительный урон во время бега +item.twilightforest.knightlySword.tooltip=Дополнительный урон по бронированным целям +item.twilightforest.knightlyPick.tooltip=Дополнительный урон по бронированным целям +item.twilightforest.knightlyAxe.tooltip=Дополнительный урон по не бронированным целям +item.twilightforest.giantPick.tooltip=Ломает гигантские блоки +item.twilightforest.fieryPick.tooltip=Авто переплавка +item.twilightforest.fierySword.tooltip=Поджигает цель +item.twilightforest.fieryHelm.tooltip=Поджигает атакующего +item.twilightforest.fieryPlate.tooltip=Поджигает атакующего +item.twilightforest.fieryLegs.tooltip=Поджигает атакующего +item.twilightforest.fieryBoots.tooltip=Поджигает атакующего +item.twilightforest.phantomHelm.tooltip=Не утрачивается при смерти +item.twilightforest.phantomPlate.tooltip=Не утрачивается при смерти +item.twilightforest.yetiHelm.tooltip=Охлаждает атакующего +item.twilightforest.yetiPlate.tooltip=Охлаждает атакующего +item.twilightforest.yetiLegs.tooltip=Охлаждает атакующего +item.twilightforest.yetiBoots.tooltip=Охлаждает атакующего + +item.twilightforest.arctic_armor.tooltip=Красится, как кожаная броня + +# Entities +entity.twilightforest.wild_boar.name=Дикий кабан +entity.twilightforest.bighorn_sheep.name=Снежный баран +entity.twilightforest.deer.name=Дикий олень +entity.twilightforest.redcap.name=Красный колпак +entity.twilightforest.swarm_spider.name=Маленький паук +entity.twilightforest.naga.name=Нага +entity.twilightforest.naga_segment.name=Часть наги +entity.twilightforest.skeleton_druid.name=Скелет друид +entity.twilightforest.hostile_wolf.name=Злой волк +entity.twilightforest.wraith.name=Сумеречный призрак +entity.twilightforest.hedge_spider.name=Зелёный паук +entity.twilightforest.hydra.name=Гидра +entity.twilightforest.hydra_head.name=Голова гидры +entity.twilightforest.lich.name=Сумеречный лич +entity.twilightforest.penguin.name=Пингвин +entity.twilightforest.tiny_bird.name=Маленькая птица +entity.twilightforest.squirrel.name=Белка +entity.twilightforest.bunny.name=Заяц +entity.twilightforest.raven.name=Ворон +entity.twilightforest.quest_ram.name=Квестовый баран +entity.twilightforest.kobold.name=Кобольд +entity.twilightforest.boggard.name=Боггард [NYI] +entity.twilightforest.lich_minion.name=Слуга лича +entity.twilightforest.loyal_zombie.name=Верный зомби +entity.twilightforest.mosquito_swarm.name=Москитный рой +entity.twilightforest.death_tome.name=Том смерти +entity.twilightforest.minotaur.name=Минотавр +entity.twilightforest.minoshroom.name=Гриботавр +entity.twilightforest.fire_beetle.name=Огненный жук +entity.twilightforest.slime_beetle.name=Слизневый жук +entity.twilightforest.pinch_beetle.name=Жук с клешнями +entity.twilightforest.maze_slime.name=Лабиринтовый слизень +entity.twilightforest.redcap_sapper.name=Красный колпак-подрывник +entity.twilightforest.mist_wolf.name=Туманный волк +entity.twilightforest.king_spider.name=Королевский паук +entity.twilightforest.firefly.name=Светлячок +entity.twilightforest.mini_ghast.name=Детёныш карминитового гаста +entity.twilightforest.tower_ghast.name=Крминитовый гаст-охранник +entity.twilightforest.tower_golem.name=Карминитовый голем +entity.twilightforest.tower_termite.name=Термит +entity.twilightforest.tower_broodling.name=Карминитовый паук +entity.twilightforest.ur_ghast.name=Ур-гаст +entity.twilightforest.blockchain_goblin.name=Гоблин-рыцарь с булавой +entity.twilightforest.goblin_knight_upper.name=Гоблин-копейщик +entity.twilightforest.goblin_knight_lower.name=Гоблин-мечник +entity.twilightforest.helmet_crab.name=Шлемовый краб +entity.twilightforest.knight_phantom.name=Призрак рыцаря +entity.twilightforest.yeti.name=Йети +entity.twilightforest.yeti_alpha.name=Альфа-йети +entity.twilightforest.winter_wolf.name=Зимний волк +entity.twilightforest.snow_guardian.name=Снежный страж +entity.twilightforest.stable_ice_core.name=Стабильное ледяное ядро +entity.twilightforest.unstable_ice_core.name=Нестабильное ледяное ядро +entity.twilightforest.snow_queen.name=Снежная королева +entity.twilightforest.troll.name=Пещерный тролль +entity.twilightforest.giant_miner.name=Гигант-шахтёр +entity.twilightforest.armored_giant.name=Бронированный гигант +entity.twilightforest.ice_crystal.name=Ледяной кристалл +entity.twilightforest.apocalypse_cube.name=Куб апокалипсиса [NYI] +entity.twilightforest.adherent.name=Приверженец [NYI] + + +twilightforest.effect.frosted=Заморозка + +twilightforest.misc.wip0=Этот блок является незавершенной работой и может иметь ошибки или непреднамеренные эффекты, которые могут повредить ваш мир. +twilightforest.misc.wip1=Используйте с осторожностью. +twilightforest.misc.nyi=Этот блок имеет эффекты, которые еще не реализованы. + +twilightforest.loading.title.enter=Переносимся Сумеречный лес... +twilightforest.loading.title.leave=Переносимся из Сумеречного леса... + +#Config +twilightforest.config.dimension=Dimension Settings +twilightforest.config.dimension.tooltip=You won't be able to change these settings without some kind of relaunch. +twilightforest.config.dimension_id=Dimension ID +twilightforest.config.dimension_id.tooltip=What ID number to assign to the Twilight Forest dimension. Change if you are having conflicts with another mod. +twilightforest.config.dimension_seed=Dimension Seed +twilightforest.config.dimension_seed.tooltip=If set, this will override the normal world seed when generating parts of the Twilight Forest Dimension. +twilightforest.config.spawn_in_tf=Dimension Seed +twilightforest.config.spawn_in_tf.tooltip=If true, players spawning for the first time will spawn in the Twilight Forest. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +twilightforest.config.compat=Compatibility +twilightforest.config.compat.tooltip=Should TF Compatibility load? Turn off if TF's Compatibility is causing crashes or if not desired. + +twilightforest.config.performance=Performance Tweaks +twilightforest.config.performance.tooltip=Lets you sacrifice various things to improve world performance. +twilightforest.config.canopy_coverage=Canopy Coverage +twilightforest.config.canopy_coverage.tooltip=Amount of canopy coverage. Lower numbers improve chunk generation speed at the cost of a thinner forest. +twilightforest.config.twilight_oaks=Twilight Oak Chance +twilightforest.config.twilight_oaks.tooltip=Chance that a chunk in the Twilight Forest will contain a twilight oak tree. Higher numbers reduce the number of trees, increasing performance. +twilightforest.config.leaves_light_opacity=Twilight Leaves opacity + +twilightforest.config.glacier_packed_ice=Glaciers made of Packed Ice instead of Ice +twilightforest.config.glacier_packed_ice.tooltip=Setting this true will make Twilight Glaciers generate with Packed Ice instead of regular translucent Ice, decreasing amount of light checking calculations. + + + +twilightforest.config.silent_cicadas=Silent Cicadas +twilightforest.config.silent_cicadas.tooltip=Make cicadas silent for those having sound library problems, or otherwise finding them annoying. + + + + + + +twilightforest.config.portals_in_other_dimensions=Portals in other dimensions +twilightforest.config.portals_in_other_dimensions.tooltip=Allow portals to the Twilight Forest to be made outside of dimension 0. May be considered an exploit. +twilightforest.config.admin_portals=Admin-Only Twilight Portals +twilightforest.config.admin_portals.tooltip=Allow portals only for admins (Operators). This severly reduces the range in which the mod usually scans for valid portal conditions, and it scans near ops only. +twilightforest.config.portals=Disable Twilight Portals +twilightforest.config.portals.tooltip=Disable Twilight Forest portal creation entirely. Provided for server operators looking to restrict action to the dimension. +twilightforest.config.portal_creator=Portal Creation Item +twilightforest.config.portal_creator.tooltip=Registry String ID of item used to create the Twilight Forest Portal. +twilightforest.config.portal_lighting=Portal Creation Lightning Fire +twilightforest.config.portal_lighting.tooltip=Set this true if you want the lightning that zaps the portal to not set things on fire. For those who don't like fun. +twilightforest.config.portal_return=Should Portals generate as a two-way portal +twilightforest.config.portal_return.tooltip=If false, the return portal will require the activation item. + + + + + + +twilightforest.config.uncrafting=Disable Uncrafting in Uncrafting Table +twilightforest.config.uncrafting.tooltip=Disable the uncrafting function of the uncrafting table. Provided as an option when interaction with other mods produces exploitable recipes. + +twilightforest.config.antibuilder_blacklist=Antibuilder Blacklist +twilightforest.config.antibuilder_blacklist.tooltip=Anti-Builder blacklist. (domain:block:meta) meta is optional. + +twilightforest.config.animate_trophyitem=Rotate Trophy Heads on Item model +twilightforest.config.animate_trophyitem.tooltip=Rotate trophy heads on item model. Has no performance impact at all. For those who don't like fun. + + + + + + + + + + + + + + +twilightforest.config.loading_screen=Loading Screen +twilightforest.config.loading_screen.tooltip=Client only: Controls for the Loading screen +twilightforest.config.loading_icon_enable=Enable Loading Icon Animation +twilightforest.config.loading_icon_enable.tooltip=Wobble the Loading icon. Has no performance impact at all. For those who don't like fun. +twilightforest.config.loading_screen_swap_frequency=Loading Screen switching +twilightforest.config.loading_screen_swap_frequency.tooltip=How many ticks between each loading screen change. Set to 0 to not cycle at all. +twilightforest.config.loading_icon_wobble_bounce_frequency=Icon Animation Speed +twilightforest.config.loading_icon_wobble_bounce_frequency.tooltip=Frequency of wobble and bounce. +twilightforest.config.loading_icon_scale=Icon Scaling +twilightforest.config.loading_icon_scale.tooltip=Scale of whole bouncy loading icon. +twilightforest.config.loading_icon_bounciness=Icon Bounciness +twilightforest.config.loading_icon_bounciness.tooltip=How much the loading icon bounces. +twilightforest.config.loading_icon_tilting=Icon Wobbliness +twilightforest.config.loading_icon_tilting.tooltip=How far the loading icon wobbles. +twilightforest.config.loading_icon_tilt_pushback=Icon Tilt Offset +twilightforest.config.loading_icon_tilt_pushback.tooltip=Pushback value to re-center the wobble of loading icon. + +# Books +twilightforest.book.lichtower.1=\u00A78[[Записная книжка исследователя, обглоданная монстрами]]\u00A70\n\nЯ начал изучать странную ауру, окружающую эту башню. Кирпичи башни защищены проклятием, сильнее, чем я видел раньше. Магия от проклятия +twilightforest.book.lichtower.2=кипит в окрестностях.\n\nНа моей родине у меня было бы много возможностей справиться с этой магией, но здесь мои запасы ограничены. Мне придется исследовать... +twilightforest.book.lichtower.3=\u00A78[[Много записей позже]]\u00A70\n\nПрорыв! В своих путешествиях я увидел огромного змеиного монстра в украшенном дворе. Рядом я подобрал изношенное, сброшенное, зеленое сердце.\n\nМагия в сердце, кажется, обладает +twilightforest.book.lichtower.4=свойствами проклятия, которые мне нужны, но магия слишком тусклая. Мне может понадобиться приобрести более свежий экземпляр, непосредственно от существа. + +twilightforest.book.labyrinth.1=\u00A78[[Записная книжка проводника, написанная на водонепроницаемой бумаге]]\u00A70\n\nКомары в этом болоте неприятные, но странные. Подавляющее большинство из них, по-видимому, не имеют природного источника и не играют никакой роли в местной экологии. Я уже начал +twilightforest.book.labyrinth.2=подозревать, что это какое-то магическое проклятие.\n\n\u00A78[[Следующая запись]]\u00A70\n\nТеперь, когда я столкнулся с заклинанием защиты на разрушенном лабиринте, я считаю, что мои подозрения подтверждены. И защита +twilightforest.book.labyrinth.3=и москиты - это проклятие. Это проклятие, похоже, имеет другой источник, чем другие, с которыми я столкнулся. Мне придется исследовать дальше...\n\n\u00A78[[Следующая запись]]\u00A70\n\nПроклятие кажется +twilightforest.book.labyrinth.4=слишком сильным для того, чтобы его можно было произвести в одиночку. Было бы полезно несколько мастеров, работающих в комбинации.\n\nЕсли один из волшебников перестанет вносить свой вклад, все проклятие над всем болотом упадет. Как ни странно, +twilightforest.book.labyrinth.5=мои предсказания не показывают признаков близких живых волшебников. Я видел кое-что интересное в одной из близлежащих башен с навесной крышей, хотя ... + +twilightforest.book.hydralair.1=\u00A78[[Записная книжка исследователя, написанная на огнеупорной бумаге]]\u00A70\n\nОгонь является тривиальным препятствием для главного исследователя, такого как я. Я прошел через огненные моря и проплыл через океаны лавы. Горящий воздух здесь-интересная вариация, +twilightforest.book.hydralair.2=но в конечном счете не помеха.\n\nЧто меня останавливает, так это то, что я столкнулся с другим заклинанием защиты, на этот раз окружающим могущественным существом, которое должно быть королем этого болота. Это не первое заклинание защиты, которое у меня есть +twilightforest.book.hydralair.3=и я начинаю разгадывать тайны того, как они работают.\n\nЕсли это заклинание похоже на другие, оно будет поддерживаться мощным существом поблизости. Вокруг огненного болота находятся несколько влажных болот, а под этими +twilightforest.book.hydralair.4=болотами - лабиринты, полные минотавров. Логичным выбором связать такое заклинание было бы какой-то мощный минотавр, который каким-то образом отличается от других, окружающих его... + +twilightforest.book.tfstronghold.1=\u00A78[[Блокнот исследователя, написанный на слегка светящейся бумаге]]\u00A70\n\nУсики тьмы, окружающие эту область, являются всего лишь проявлением защитного заклинания над всем темным лесом. Заклинание вызывает слепоту, что довольно неприятно. Я видел +twilightforest.book.tfstronghold.2=несколько интересных вещей в этом районе и хотел бы продолжить изучение.\n\n\u00A78[[Следующая запись]]\u00A70\n\nЯ нашел развалины в темном лесу. Они принадлежат к крепости, типа обычно населенной рыцарями. Однако, вместо рыцарей, +twilightforest.book.tfstronghold.3=эта крепость полна гоблинов. Они носят рыцарские доспехи, но их поведение более не рыцарское.\n\n\u00A78[[Следующая запись]]\u00A70\n\nГлубоко в руинах я нашел пьедестал. Пьедестал, похоже, относится к типу, который +twilightforest.book.tfstronghold.4=рыцари ставят трофеи, чтобы доказать свою силу.\n\nУбийство могущественного существа, казалось бы, ослабило проклятие в темном лесу, и размещение трофея, связанного с существом на пьедестале, скорее всего, предоставит доступ к +twilightforest.book.tfstronghold.5=главной части крепости.\n\nЕдинственное существо, которое я видел до сих пор, обладающего достаточной властью, - это многоглавый зверь в огневом болоте. Как досадно... + +twilightforest.book.darktower.1=\u00A78[[Блокнот исследователя, который, похоже, пережил взрыв]]\u00A70\n\nУ этой башни явно есть механизмы, которые не отвечают мне. Их магия почти жаждет признать мое прикосновение, но это невозможно. Это если устройства башни +twilightforest.book.darktower.2=подавляются мощной группой существ поблизости.\n\n\u00A78[[Следующая запись]]\u00A70\n\nКажется, что магия исходит из глубины близлежащих крепостей. Он не может исходить от гоблинов, так как их магия очаровательна, но не сфокусирована. Там +twilightforest.book.darktower.3=в крепостях еще должна быть какая-то сила.\n\n\u00A78[[Следующая запись]]\u00A70\n\nМой анализ показывает, что он исходит из нескольких источников, действующих как группа. Я вернусь в крепость после пополнения запасов... + +twilightforest.book.yeticave.1=\u00A78[[Записная книжка исследователя, покрытая морозом]]\u00A70\n\nМетель, окружающая эти заснеженные земли, не утихает. Это не обычный снегопад - это магическое явление. Мне придется провести эксперименты, чтобы найти +twilightforest.book.yeticave.2=то, что способно вызвать такой эффект.\n\n\u00A78[[Следующая запись]]\u00A70\n\nВ центре темного леса, где листья краснеют, а трава отмирает, стоит деревянная башня. Вершины башни крепятся с +twilightforest.book.yeticave.3=с структурами, действуя как антенны. Антенны не являются источником снегопада,а служат лишь для усиления силы проклятия, вызывающего его.\n\nМетель такой интенсивности должна быть вызвана мощным существом, скорее всего найденным + +twilightforest.book.icetower.1=\u00A78[[Блокнот исследователя, застывший во льду]]\u00A70\n\nЯ преодолел одну метель, только чтобы столкнуться с этим ужасным ледяным бурей на вершине ледника. Мои исследования показали мне великолепие ледяного дворца, сияющего цветами полярного сияния. Все это +twilightforest.book.icetower.2=кажется защищенным каким-то проклятием.\n\n\u00A78[[Следующая запись]]\u00A70\n\nЯ не новичок. Это проклятие питается силой существа поблизости. Причина проклятия, окружающего болото, была построена на силе лидера +twilightforest.book.icetower.3=минотавров поблизости.\n\nВокруг этого ледника находятся массы йети. Возможно, у йети есть какой-то лидер... + +twilightforest.book.trollcave.1=\u00A78[[Ноутбук исследователя, поврежденный кислотой]]\u00A70\n\nКажется, нет никакого способа защитить себя от токсичного ливня, окружающего эту область. В своих коротких экскурсиях я также столкнулся с другим защитным заклинанием, подобным +twilightforest.book.trollcave.2=другим, которые я видел. Заклинание должно быть связано с ядовитым штормом. Дальнейшие исследования...\n\n\u00A78[[Следующая запись]]\u00A70\n\nТакая великая погодная магия должна быть результатом непревзойденного погодного +twilightforest.book.trollcave.3=мага. Такой человек, скорее всего, спрячется в экстремальной обстановке, далеко.\n\nОсновываясь на моей логике, я ожидал найти такого человека где-то на леднике, возможно, в какой-то крепости... + +twilightforest.book.unknown.1=\u00A78[[Эта книга показывает признаки того, что были скопированы много раз]]\u00A70\n\nЯ не могу объяснить поле, окружающее эту структуру, но магия мощная. Если это проклятие подобно другим, тогда ответ на его разблокировку лежит в другом месте. Возможно, есть +twilightforest.book.unknown.2=что-то, что я потерял, или какого-то монстра, которого я еще не победил. Мне придется вернуться. Я вернусь к этому месту позже, чтобы увидеть, изменилось ли что-то. + +# Fluid + +fluid.fierymetal=Расплавленное пламя +fluid.knightmetal=Расплавленный королевский металл +fluid.fiery_essence=Огненная эссенция + +# TCon + +material.nagascale.name=Сердце наги +material.steeleaf.name=Магический лист +material.fierymetal.name=Пламя +material.knightmetal.name=Королевский металл +material.raven_feather.name=Воронье перо + +modifier.twilit.name=Сумеречный +modifier.twilit.desc=§oСветлое благословение сумеречного леса.§r\nСкорость быстрее в Сумеречном лесу.\nБольше урона за пределами сумеречного леса. +modifier.twilit.extra.speed=Скорость добычи в Сумеречном лесу: +%s +modifier.twilit.extra.damage=Повреждения за пределами сумеречного леса: +%s +modifier.precipitate.name=Опрометчивый +modifier.precipitate.desc=§oПоследний план побега.§r\nЧем меньше здоровья у вас есть, тем быстрее скорость! +modifier.synergy.name=Синергия +modifier.synergy.desc=§oСмотри Ма, никакого мха!§r\nБудет ремонтировать, если у вас есть магические листья на вашей горячей панели. +modifier.stalwart.name=Крепкий +modifier.stalwart.desc=§oХрабрый и смелый.§r\nУдар по существу может заставить Вас чувствовать себя ободренным. +modifier.veiled.name=Замаскированный +modifier.veiled.desc=§oКак привидение!§r\nСнаряд будет невидим. + +# Immersive Engineering + + + + + + + + + + + + + + + + + + + + + + + +# Missing in original +tile.twilightforest.StonePillar.name=Лесная каменная колонна +tile.twilightforest.StonePillarThin.name=Лесная тонкая каменная колонна \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/zh_CN.lang b/src/main/resources/assets/twilightforest/lang/zh_CN.lang deleted file mode 100644 index b1444a312c..0000000000 --- a/src/main/resources/assets/twilightforest/lang/zh_CN.lang +++ /dev/null @@ -1,309 +0,0 @@ -#translated by MCwolski - -tile.TFLog.0.name=暮色橡树木 -tile.TFLog.1.name=苍穹树木 -tile.TFLog.2.name=红树木 -tile.TFLog.3.name=黑树木 -tile.TFLeaves.0.name=暮色橡木树叶 -tile.TFLeaves.1.name=苍穹树叶 -tile.TFLeaves.2.name=红树树叶 -tile.TFLeaves.3.name=彩虹橡树叶 -tile.TFFirefly.name=萤火虫 -tile.TFCicada.name=蝉 -tile.TFPortal.name=暮色森林入口 -tile.TFMazestone.0.name=遗迹石头 -tile.TFMazestone.1.name=遗迹石砖 -tile.TFMazestone.2.name=雕刻的遗迹石头 -tile.TFMazestone.3.name=装饰的遗迹石砖 -tile.TFMazestone.4.name=破碎的遗迹石砖 -tile.TFMazestone.5.name=遗迹苔石砖 -tile.TFMazestone.6.name=遗迹石方块 -tile.TFMazestone.7.name=遗迹石沿 -tile.TFMazestone.8.name=遗迹天花板 -tile.TFHedge.0.name=树篱 -tile.TFHedge.1.name=黑树树叶 -tile.TFHedge.2.name=树篱 -tile.TFBossSpawner.0.name=生成 娜迦 -tile.TFBossSpawner.1.name=生成 巫妖 -tile.TFBossSpawner.2.name=生成 九头蛇 -tile.TFBossSpawner.3.name=生成 暮色恶魂 -tile.TFBossSpawner.4.name=生成 幻影骑士 -tile.TFFireflyJar.name=萤火虫罐子 -tile.TFPlant.3.name=暮色森林苔藓 -tile.TFPlant.4.name=鬼臼果 -tile.TFPlant.5.name=三叶草 [WIP] -tile.TFPlant.8.name=暮色森林蕨类 -tile.TFPlant.9.name=暮色森林蘑菇 -tile.TFPlant.10.name=林地草 -tile.TFPlant.11.name=枯死的灌木 -tile.TFPlant.13.name=火炬浆果植物 -tile.TFPlant.14.name=根须 -tile.TFRoots.0.name=根茎 -tile.TFRoots.1.name=新鲜根茎 -tile.TFUncraftingTable.name=多功能工作台 -tile.TFFireJet.0.name=烟雾方块 -tile.TFFireJet.1.name=被包裹的烟雾 -tile.TFFireJet.2.name=被包裹的烟雾 -tile.TFFireJet.8.name=火焰喷射 -tile.TFFireJet.9.name=火焰喷射-弹射 -tile.TFFireJet.10.name=火焰喷射-激活 -tile.TFFireJet.11.name=火焰喷射方块 -tile.TFFireJet.12.name=被包裹的凸出火焰喷射 -tile.TFFireJet.13.name=被包裹的炽红火焰喷射 -tile.TFNagastone.0.name=娜迦石方块 头部 -tile.TFNagastone.1.name=娜迦石方块 头部 -tile.TFNagastone.2.name=娜迦石方块 头部 -tile.TFNagastone.3.name=娜迦石方块 头部 -tile.TFNagastone.4.name=娜迦石方块 -tile.TFNagastone.5.name=娜迦石方块 -tile.TFNagastone.6.name=娜迦石方块 -tile.TFNagastone.7.name=娜迦石方块 -tile.TFNagastone.8.name=娜迦石方块 -tile.TFNagastone.9.name=娜迦石方块 -tile.TFNagastone.10.name=娜迦石方块 -tile.TFNagastone.11.name=娜迦石方块 -tile.TFNagastone.12.name=娜迦石方块 -tile.TFNagastone.13.name=娜迦石方块 -tile.TFNagastone.14.name=娜迦石方块 -tile.TFNagastone.15.name=娜迦石方块 -tile.TFSapling.0.name=暮色橡树树苗 -tile.TFSapling.1.name=苍穹树苗 -tile.TFSapling.2.name=红树树苗 -tile.TFSapling.3.name=黑树树苗 -tile.TFSapling.4.name=高大暮色橡树树苗 -tile.TFSapling.5.name=时光树苗 -tile.TFSapling.6.name=变化树苗 -tile.TFSapling.7.name=矿石树苗 -tile.TFSapling.8.name=分类树苗 -tile.TFSapling.9.name=彩虹树苗 -tile.TFMoonworm.name=月光蠕虫 -tile.TFMagicLog.0.name=时光树木 -tile.TFMagicLog.1.name=变化树木 -tile.TFMagicLog.2.name=矿石树木 -tile.TFMagicLog.3.name=分类树木 -tile.TFMagicLogSpecial.0.name=时光树的时钟 -tile.TFMagicLogSpecial.1.name=变化树的心脏 -tile.TFMagicLogSpecial.2.name=矿石树核心 -tile.TFMagicLogSpecial.3.name=分类树的引擎 -tile.TFMagicLeaves.0.name=时光树树叶 -tile.TFMagicLeaves.1.name=变化树树叶 -tile.TFMagicLeaves.2.name=矿石树树叶 -tile.TFMagicLeaves.3.name=分类树树叶 -tile.TFTowerStone.0.name=塔树木板 -tile.TFTowerStone.1.name=塔树板箱 -tile.TFTowerStone.2.name=破裂的塔木 -tile.TFTowerStone.3.name=青苔的塔木 -tile.TFTowerStone.4.name=虫蛀的塔木 -tile.TFTowerDevice.0.name=重现的方块 -tile.TFTowerDevice.1.name=激活的重现方块 -tile.TFTowerDevice.2.name=消失的方块 -tile.TFTowerDevice.3.name=激活消失的方块 -tile.TFTowerDevice.4.name=锁定的消失的方块 -tile.TFTowerDevice.5.name=解锁的消失的方块 -tile.TFTowerDevice.6.name=高塔建設者 -tile.TFTowerDevice.7.name=激活的高塔建設者 -tile.TFTowerDevice.8.name=关闭的高塔建設者 -tile.TFTowerDevice.9.name=反建器 -tile.TFTowerDevice.10.name=可怕的陷阱 -tile.TFTowerDevice.11.name=激活的可怕的陷阱 -tile.TFTowerDevice.12;.name=砷铅铁反应堆 -tile.TFTowerDevice.13.name=激活的砷铅铁反应堆 -tile.TFTowerTranslucent.0.name=再现方块 -tile.TFTowerTranslucent.1.name=激活的再现方块 -tile.TFTowerTranslucent.2.name=建造的砷铅铁方块 -tile.TFTowerTranslucent.3.name=激活的建造的砷铅铁方块 -tile.TFTowerTranslucent.4.name=反建方块 -tile.TFTowerTranslucent.5.name=砷铅铁反应堆碎片 -tile.TFTowerTranslucent.6.name=伪黄金方块 -tile.TFTowerTranslucent.7.name=伪钻石方块 -tile.TFTrophy.name=暮色森林战利品 -tile.TFShield.0.name=堡垒防护屏障 -tile.TFShield.1.name=堡垒防护屏障 -tile.TFShield.2.name=堡垒防护屏障 -tile.TFShield.3.name=堡垒防护屏障 -tile.TFShield.4.name=堡垒防护屏障 -tile.TFShield.5.name=堡垒防护屏障 -tile.TFShield.15.name=堡垒防护屏障 -tile.TFTrophyPedestal.0.name=战利品宝座 -tile.TFTrophyPedestal.15.name=隐藏的战利品宝座 -tile.TFAuroraBrick.0.name=奥罗拉方块 -tile.TFUnderBrick.0.name=地下砖 -tile.TFUnderBrick.1.name=碎裂的地下砖 -tile.TFUnderBrick.2.name=青苔地下砖 - -item.nagaScale.name=娜迦鳞片 -item.plateNaga.name=娜迦胸甲 -item.legsNaga.name=娜迦护腿 -item.scepterTwilight.name=黄昏权杖 -item.scepterLifeDrain.name=吸血权杖 -item.scepterZombie.name=僵尸权杖 -item.oreMeter.name=矿石感应仪 [WIP] -item.magicMap.name=魔法地图 -item.mazeMap.name=迷宮地图 -item.oreMap.name=迷宮/矿石地图 -item.tfFeather.name=乌鸦羽毛 -item.magicMapFocus.name=魔法地图核心 -item.mazeMapFocus.name=迷宮地图核心 -item.liveRoot.name=活根 -item.ironwoodRaw.name=未加工的铁树原料 -item.ironwoodIngot.name=铁树锭 -item.ironwoodHelm.name=铁树头盔 -item.ironwoodPlate.name=铁树铠甲 -item.ironwoodLegs.name=铁树护腿 -item.ironwoodBoots.name=铁树靴 -item.ironwoodSword.name=铁树剑 -item.ironwoodShovel.name=铁树铲 -item.ironwoodPick.name=铁树镐 -item.ironwoodAxe.name=铁树斧 -item.ironwoodHoe.name=铁树锄 -item.torchberries.name=火炬浆果 -item.venisonRaw.name=生鹿肉 -item.venisonCooked.name=鹿肉排 -item.hydraChop.name=九头蛇肉排 -item.fieryBlood.name=炽热的血液 -item.fieryIngot.name=炽热的铁锭 -item.fieryHelm.name=炽热的铁头盔 -item.fieryPlate.name=炽热的铁胸甲 -item.fieryLegs.name=炽热的铁护腿 -item.fieryBoots.name=炽热的铁靴子 -item.fierySword.name=炽热的铁劍 -item.fieryPick.name=炽热的铁镐 -item.steeleafIngot.name=钢叶 -item.steeleafHelm.name=钢叶头盔 -item.steeleafPlate.name=钢叶胸甲 -item.steeleafLegs.name=钢叶护腿 -item.steeleafBoots.name=钢叶靴 -item.steeleafSword.name=钢叶劍 -item.steeleafShovel.name=钢叶铲 -item.steeleafPick.name=钢叶镐 -item.steeleafAxe.name=钢叶斧 -item.steeleafHoe.name=钢叶锄 -item.minotaurAxe.name=米诺陶诺斯战斧 -item.mazebreakerPick.name=迷宮破坏者 -item.transformPowder.name=转换粉 -item.meefRaw.name=生牛头人肉 -item.meefSteak.name=牛头人肉排 -item.meefStroganoff.name=牛头人沙拉酱肉 -item.mazeWafer.name=迷宮薄饼 -item.emptyMagicMap.name=空白魔法地图 -item.emptyMazeMap.name=空白迷宮地图 -item.emptyOreMap.name=空白迷宮/矿石地图 -item.oreMagnet.name=矿石磁铁 -item.crumbleHorn.name=瓦解之号角 -item.peacockFan.name=孔雀羽毛扇 -item.moonwormQueen.name=月光蠕虫女王 -item.charmOfLife1.name=魔力生命 I -item.charmOfLife2.name=魔力生命 II -item.charmOfKeeping1.name=保管符咒 I -item.charmOfKeeping2.name=保管符咒 II -item.charmOfKeeping3.name=保管符咒 III -item.towerKey.name=塔钥匙 -item.borerEssence.name=三化螟精华 -item.carminite.name=砷铅铁矿石 -item.trophy.hydra.name=九头蛇战利品 -item.trophy.naga.name=娜迦战利品 -item.trophy.lich.name=巫妖战利品 -item.trophy.ur-ghast.name=暮色恶魂战利品 -item.experiment115.name=试验物品 115 -item.armorShards.name=装甲碎片 -item.knightMetal.name=骑士金属锭 -item.shardCluster.name=大块装甲碎片 -item.knightlyHelm.name=骑士头盔 -item.knightlyPlate.name=骑士胸甲 -item.knightlyLegs.name=骑士护腿 -item.knightlyBoots.name=骑士靴 -item.knightlySword.name=骑士剑 -item.knightlyPick.name=骑士镐 -item.knightlyAxe.name=骑士斧 -item.phantomHelm.name=幻影头盔 -item.phantomPlate.name=幻影胸甲 - -item.minotaurAxe.tooltip=蓄力时造成额外伤害 -item.knightlySword.tooltip=对有护甲的目标造成额外伤害 -item.knightlyPick.tooltip=对有护甲的目标造成额外伤害 -item.knightlyAxe.tooltip=对无护甲的目标造成额外伤害 - -item.tfspawnegg.name=生成 - -enchantment.tfFireReact=炽热光环 - -itemGroup.twilightForest=暮色森林 - -entity.TwilightForest.Wild Boar.name=野猪 -entity.TwilightForest.Bighorn Sheep.name=大角山羊 -entity.TwilightForest.Wild Deer.name=野鹿 -entity.TwilightForest.Redcap.name=红帽 -entity.TwilightForest.Swarm Spider.name=集群蜘蛛 -entity.TwilightForest.Naga.name=娜迦 -entity.TwilightForest.Naga Segment.name=娜迦身体 -entity.TwilightForest.Skeleton Druid.name=骷髅德鲁伊 -entity.TwilightForest.Hostile Wolf.name=愤怒的狼 -entity.TwilightForest.Twilight Wraith.name=幽灵 -entity.TwilightForest.Hedge Spider.name=树篱蜘蛛 -entity.TwilightForest.Hydra.name=九头蛇 -entity.TwilightForest.HydraHead.name=九头蛇头 -entity.TwilightForest.Twilight Lich.name=巫妖 -entity.TwilightForest.Penguin.name=企鹅 -entity.TwilightForest.Tiny Bird.name=小鸟 -entity.TwilightForest.Forest Squirrel.name=松鼠 -entity.TwilightForest.Forest Bunny.name=兔子 -entity.TwilightForest.Forest Raven.name=乌鸦 -entity.TwilightForest.Questing Ram.name=谜题羊 -entity.TwilightForest.Twilight Kobold.name=哥布林 -entity.TwilightForest.Boggard.name=博加德 [NYI] -entity.TwilightForest.Lich Minion.name=巫妖的仆从 -entity.TwilightForest.Loyal Zombie.name=忠诚的僵尸 -entity.TwilightForest.Mosquito Swarm.name=成群的蚊子 -entity.TwilightForest.Death Tome.name=死神之书 -entity.TwilightForest.Minotaur.name=牛头怪 -entity.TwilightForest.Minoshroom.name=米陶诺 -entity.TwilightForest.Fire Beetle.name=喷火甲虫 -entity.TwilightForest.Slime Beetle.name=粘液甲虫 -entity.TwilightForest.Pinch Beetle.name=枯萎甲虫 -entity.TwilightForest.Maze Slime.name=迷宮史莱姆 -entity.TwilightForest.Redcap Sapper.name=红帽地精 -entity.TwilightForest.Mist Wolf.name=迷雾狼 -entity.TwilightForest.King Spider.name=国王蜘蛛 -entity.TwilightForest.Firefly.name=萤火虫 -entity.TwilightForest.Mini Ghast.name=迷你幽灵 -entity.TwilightForest.Tower Ghast.name=高塔幽灵 -entity.TwilightForest.Tower Golem.name=高塔铁傀儡 -entity.TwilightForest.Tower Termite.name=高塔蠹虫 -entity.TwilightForest.Redscale Broodling.name=寄生虫 -entity.TwilightForest.Tower Boss.name=暮色恶魂 -entity.TwilightForest.Block&Chain Goblin.name=重装哥布林 -entity.TwilightForest.Upper Goblin Knight.name=高阶哥布林骑士 -entity.TwilightForest.Lower Goblin Knight.name=低阶哥布林骑士 -entity.TwilightForest.Helmet Crab.name=寄居蟹 -entity.TwilightForest.Knight Phantom.name=幻影骑士 [WIP] - -achievement.twilightPortal=建造暮色口 -achievement.twilightPortal.desc=建立一个通往暮色森林的传送口 -achievement.twilightArrival=初入暮色 -achievement.twilightArrival.desc=进入暮色森林 -achievement.twilightHunter=暮色猎人 -achievement.twilightHunter.desc=猎杀一些暮色的野生动物 -achievement.twilightMagicMapFocus=用火书写 -achievement.twilightMagicMapFocus.desc=用乌鸦毛, 萤石粉, 火炬浆果合成魔法地图核心 -achievement.twilightNaga=娜迦猎人 -achievement.twilightNaga.desc=干掉娜迦 -achievement.twilightNagaArmors=娜迦装备 -achievement.twilightNagaArmors.desc=合成娜迦鳞胸甲和护腿 -achievement.twilightLich=巫妖猎人 -achievement.twilightLich.desc=干掉巫妖 -achievement.twilightLichScepters=权杖专精 -achievement.twilightLichScepters.desc=学会使用三种权杖 -achievement.twilightHill1=靴子都是我的! -achievement.twilightHill1.desc=在小矿山里击败红帽哥布林 -achievement.twilightHill2=中型矿山 [NYI] -achievement.twilightHill2.desc=在中型矿山内击败任意怪物 -achievement.twilightHill3=我看到你了 -achievement.twilightHill3.desc=在大矿山里杀死一只暮色幽魂 -achievement.twilightHedge=碾碎爬虫 -achievement.twilightHedge.desc=在树篱迷宫杀死一只蜘蛛 -achievement.twilightMagicMap=我有千里眼 -achievement.twilightMagicMap.desc=合成魔法地图 -achievement.twilightMazeMap=现在, 寻找出口 -achievement.twilightMazeMap.desc=从哥布林身上获取用来合成迷宫地图的核心 -achievement.twilightOreMap=怎样才算值得? -achievement.twilightOreMap.desc=合成迷宫/矿石地图 \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/zh_TW.lang b/src/main/resources/assets/twilightforest/lang/zh_TW.lang deleted file mode 100644 index 0380c58b0f..0000000000 --- a/src/main/resources/assets/twilightforest/lang/zh_TW.lang +++ /dev/null @@ -1,314 +0,0 @@ -# Translate by Likol - -itemGroup.twilightForest=暮光森林模組 -item.tfspawnegg.name=生成 -enchantment.tfFireReact=抵抗火焰 -tile.TFLog.0.name=暮光橡樹原木 -tile.TFLog.1.name=垂暮樹原木 -tile.TFLog.2.name=白皮紅樹原木 -tile.TFLog.3.name=漆黑樹原木 -tile.TFLeaves.0.name=暮光橡樹葉子 -tile.TFLeaves.1.name=垂暮樹葉子 -tile.TFLeaves.2.name=白皮紅樹葉子 -tile.TFHedge.1.name=漆黑樹葉子 -tile.TFLeaves.3.name=彩虹橡樹葉子 -tile.TFLeaves.9.name=彩虹橡樹葉子 -tile.TFFirefly.name=螢火蟲 -tile.TFCicada.name=蟬 -tile.TFPortal.name=暮光森林傳送門 -tile.TFMazestone.0.name=遺跡石 -tile.TFMazestone.1.name=遺跡石磚 -tile.TFMazestone.2.name=雕刻過的遺跡石磚 -tile.TFMazestone.3.name=裝飾用的遺跡石磚 -tile.TFMazestone.4.name=破碎的遺跡石磚 -tile.TFMazestone.5.name=長苔的遺跡石磚 -tile.TFMazestone.6.name=裝飾用馬賽克遺跡石 -tile.TFMazestone.7.name=裝飾用邊線遺跡石 -tile.TFMazestone.8.name=裝飾用天花板遺跡石 -tile.TFHedge.0.name=樹籬 -tile.TFHedge.2.name=樹籬 -tile.TFBossSpawner.0.name=[BOSS]納迦生怪磚 -tile.TFBossSpawner.1.name=[BOSS]巫妖王生怪磚 -tile.TFBossSpawner.2.name=[BOSS]九頭蛇生怪磚 -tile.TFBossSpawner.3.name=[BOSS]惡靈烏爾生怪磚 -tile.TFBossSpawner.4.name=[BOSS]幻影騎士生怪磚 -tile.TFBossSpawner.5.name=生怪磚 -tile.TFBossSpawner.6.name=生怪磚 -tile.TFBossSpawner.7.name=生怪磚 -tile.TFBossSpawner.8.name=生怪磚 -tile.TFBossSpawner.9.name=生怪磚 -tile.TFBossSpawner.10.name=生怪磚 -tile.TFBossSpawner.11.name=生怪磚 -tile.TFBossSpawner.12.name=生怪磚 -tile.TFBossSpawner.13.name=生怪磚 -tile.TFBossSpawner.14.name=生怪磚 -tile.TFBossSpawner.15.name=生怪磚 -tile.TFFireflyJar.name=裝著螢火蟲的瓶子 -tile.TFPlant.3.name=暮色苔蘚 -tile.TFPlant.4.name=鬼臼果實 -tile.TFPlant.5.name=幸運草毯 -tile.TFPlant.8.name=捲曲嫩葉 -tile.TFPlant.9.name=暮光菇 -tile.TFPlant.10.name=暮光草 -tile.TFPlant.11.name=乾燥灌木 -tile.TFPlant.13.name=火炬莓 -tile.TFPlant.14.name=根鬚 -tile.TFRoots.0.name=根莖 -tile.TFRoots.1.name=活根莖 -tile.TFUncraftingTable.name=暮光工作台 -tile.TFFireJet.0.name=煙囪方塊 -tile.TFFireJet.1.name=冒煙機關 -tile.TFFireJet.2.name=冒煙機關 -tile.TFFireJet.8.name=火焰噴射方塊 -tile.TFFireJet.9.name=Popping Fire Jet -tile.TFFireJet.10.name=Flaming Fire Jet -tile.TFFireJet.11.name=火焰噴射機關 -tile.TFFireJet.12.name=Encased Popping Fire Jet -tile.TFFireJet.13.name=Encased Flaming Fire Jet -tile.TFNagastone.0.name=納迦石頭部 -tile.TFNagastone.1.name=納迦石頭部 -tile.TFNagastone.2.name=納迦石頭部 -tile.TFNagastone.3.name=納迦石頭部 -tile.TFNagastone.4.name=納迦石方塊 -tile.TFNagastone.5.name=納迦石方塊 -tile.TFNagastone.6.name=納迦石方塊 -tile.TFNagastone.7.name=納迦石方塊 -tile.TFNagastone.8.name=納迦石方塊 -tile.TFNagastone.9.name=納迦石方塊 -tile.TFNagastone.10.name=納迦石方塊 -tile.TFNagastone.11.name=納迦石方塊 -tile.TFNagastone.12.name=納迦石方塊 -tile.TFNagastone.13.name=納迦石方塊 -tile.TFNagastone.14.name=納迦石方塊 -tile.TFNagastone.15.name=納迦石方塊 -tile.TFSapling.0.name=虛弱的暮光橡樹樹苗 -tile.TFSapling.1.name=垂暮樹樹苗 -tile.TFSapling.2.name=白皮紅樹樹苗 -tile.TFSapling.3.name=漆黑樹樹苗 -tile.TFSapling.4.name=健康的暮光橡樹樹苗 -tile.TFSapling.5.name=時間樹樹苗 -tile.TFSapling.6.name=變換樹樹苗 -tile.TFSapling.7.name=礦物樹樹苗 -tile.TFSapling.8.name=分類樹樹苗 -tile.TFSapling.9.name=彩虹橡樹樹苗 -tile.TFMoonworm.name=月光蟲 -tile.TFMagicLog.0.name=時間樹原木 -tile.TFMagicLog.1.name=變換樹原木 -tile.TFMagicLog.2.name=礦物樹原木 -tile.TFMagicLog.3.name=分類樹原木 -tile.TFMagicLogSpecial.0.name=時間樹核心 -tile.TFMagicLogSpecial.1.name=變換樹核心 -tile.TFMagicLogSpecial.2.name=礦物樹核心 -tile.TFMagicLogSpecial.3.name=分類樹核心 -tile.TFMagicLeaves.0.name=時間樹葉子 -tile.TFMagicLeaves.1.name=變換樹葉子 -tile.TFMagicLeaves.2.name=礦物樹葉子 -tile.TFMagicLeaves.3.name=分類樹葉子 -tile.TFTowerStone.0.name=漆黑樹木材 -tile.TFTowerStone.1.name=漆黑樹磚 -tile.TFTowerStone.2.name=破碎的漆黑樹木材 -tile.TFTowerStone.3.name=長苔的漆黑樹木材 -tile.TFTowerStone.4.name=長蟲的漆黑樹木材 -tile.TFTowerDevice.0.name=重現磚 -tile.TFTowerDevice.1.name=啟動的重現磚 -tile.TFTowerDevice.2.name=消失磚 -tile.TFTowerDevice.3.name=啟動的消失磚 -tile.TFTowerDevice.4.name=上鎖的消失磚 -tile.TFTowerDevice.5.name=解鎖的消失磚 -tile.TFTowerDevice.6.name=造橋核心 -tile.TFTowerDevice.7.name=啟動的造橋核心 -tile.TFTowerDevice.8.name=已啟動的造橋核心 -tile.TFTowerDevice.9.name=反建造核心 -tile.TFTowerDevice.10.name=惡靈陷阱 -tile.TFTowerDevice.11.name=啟動的惡靈陷阱 -tile.TFTowerDevice.12.name=虛空反應核心 -tile.TFTowerDevice.13.name=啟動的虛空反應核心 -tile.TFTowerTranslucent.0.name=重現方塊 -tile.TFTowerTranslucent.1.name=啟動重現方塊 -tile.TFTowerTranslucent.2.name=建造的砷鉛鐵礦方塊 -tile.TFTowerTranslucent.3.name=啟動建造的砷鉛鐵礦方塊 -tile.TFTowerTranslucent.4.name=反建造方塊 -tile.TFTowerTranslucent.5.name=破壞反應堆 -tile.TFTowerTranslucent.6.name=擬真金磚 -tile.TFTowerTranslucent.7.name=擬真鑽石磚 -tile.TFTrophy.name=暮色森林獎盃 -tile.TFShield.0.name=迷宮護盾方塊 -tile.TFShield.1.name=迷宮護盾方塊 -tile.TFShield.2.name=迷宮護盾方塊 -tile.TFShield.3.name=迷宮護盾方塊 -tile.TFShield.4.name=迷宮護盾方塊 -tile.TFShield.5.name=迷宮護盾方塊 -tile.TFShield.15.name=迷宮護盾方塊 -tile.TFTrophyPedestal.0.name=失效的獎盃台 -tile.TFTrophyPedestal.15.name=獎盃台 -tile.TFAuroraBrick.0.name=極光方塊 -tile.TFUnderBrick.0.name=底磚 -tile.TFUnderBrick.1.name=破碎的底磚 -tile.TFUnderBrick.2.name=長苔的底磚 -item.nagaScale.name=納迦的鱗片 -item.plateNaga.name=鱗片外衣 -item.legsNaga.name=鱗片護腿 -item.scepterTwilight.name=暮光權杖 -item.scepterLifeDrain.name=生命汲取寶杖 -item.scepterZombie.name=召喚殭屍權杖 -item.oreMeter.name=礦物偵測儀 -item.magicMap.name=魔法地圖 -item.mazeMap.name=迷宮地圖 -item.oreMap.name=昂貴地圖 -item.tfFeather.name=烏鴉羽毛 -item.magicMapFocus.name=魔法地圖指針 -item.mazeMapFocus.name=迷宮地圖指針 -item.liveRoot.name=活根莖 -item.ironwoodRaw.name=混合的鐵木礦 -item.ironwoodIngot.name=鐵木錠 -item.ironwoodHelm.name=鐵木頭盔 -item.ironwoodPlate.name=鐵木盔甲 -item.ironwoodLegs.name=鐵木護腿 -item.ironwoodBoots.name=鐵木鞋子 -item.ironwoodSword.name=鐵木長劍 -item.ironwoodShovel.name=鐵木鏟 -item.ironwoodPick.name=鐵木鎬 -item.ironwoodAxe.name=鐵木斧 -item.ironwoodHoe.name=鐵木鋤 -item.torchberries.name=火炬果實 -item.venisonRaw.name=生鹿肉 -item.venisonCooked.name=烤鹿排 -item.hydraChop.name=營養肉塊 -item.fieryBlood.name=燃燒的血液 -item.fieryIngot.name=燃燒金屬錠 -item.fieryHelm.name=燃燒頭盔 -item.fieryPlate.name=燃燒盔甲 -item.fieryLegs.name=燃燒護腿 -item.fieryBoots.name=燃燒靴子 -item.fierySword.name=燃燒之劍 -item.fieryPick.name=燃燒之鎬 -item.steeleafIngot.name=鋼之葉 -item.steeleafHelm.name=鋼葉頭盔 -item.steeleafPlate.name=鋼葉盔甲 -item.steeleafLegs.name=鋼葉護腿 -item.steeleafBoots.name=鋼葉靴子 -item.steeleafSword.name=鋼葉之劍 -item.steeleafShovel.name=鋼葉鏟 -item.steeleafPick.name=鋼葉鎬 -item.steeleafAxe.name=鋼葉斧 -item.steeleafHoe.name=鋼葉鋤 -item.minotaurAxe.name=彌諾陶洛斯戰斧 -item.mazebreakerPick.name=迷宮破壞者 -item.transformPowder.name=變換粉末 -item.meefRaw.name=生牛頭人肉 -item.meefSteak.name=牛頭人肉排 -item.meefStroganoff.name=酸奶牛頭人肉排 -item.mazeWafer.name=迷宮脆餅 -item.emptyMagicMap.name=空白的魔法地圖 -item.emptyMazeMap.name=空白的迷宮地圖 -item.emptyOreMap.name=空白的昂貴地圖 -item.oreMagnet.name=礦物磁鐵 -item.crumbleHorn.name=破碎號角 -item.peacockFan.name=孔雀羽扇 -item.moonwormQueen.name=月光蟲女王 -item.charmOfLife1.name=生命護石 I -item.charmOfLife2.name=生命護石 II -item.charmOfKeeping1.name=道具護石 I -item.charmOfKeeping2.name=道具護石 II -item.charmOfKeeping3.name=道具護石 III -item.towerKey.name=迷宮鑰匙 -item.borerEssence.name=蠹蟲精華 -item.carminite.name=砷鉛結晶 -item.trophy.hydra.name=[BOSS]九頭蛇獎盃 -item.trophy.naga.name=[BOSS]納迦王獎盃 -item.trophy.lich.name=[BOSS]巫妖王獎盃 -item.trophy.ur-ghast.name=[BOSS]惡靈烏爾獎盃 -item.experiment115.name=實驗品 115 -item.armorShards.name=護甲碎片 -item.knightMetal.name=騎士金屬錠 -item.shardCluster.name=一疊盔甲碎片 -item.knightlyHelm.name=騎士頭盔 -item.knightlyPlate.name=騎士胸甲 -item.knightlyLegs.name=騎士護腿 -item.knightlyBoots.name=騎士長靴 -item.knightlySword.name=騎士之劍 -item.knightlyPick.name=騎士之鎬 -item.knightlyAxe.name=騎士之斧 -item.phantomHelm.name=幻影頭盔 -item.phantomPlate.name=幻影盔甲 -item.minotaurAxe.tooltip=衝鋒時造成額外傷害 -item.knightlySword.tooltip=對裝甲目標造成額外傷害 -item.knightlyPick.tooltip=對裝甲目標造成額外傷害 -item.knightlyAxe.tooltip=對無防禦值目標造成額外傷害 -entity.TwilightForest.Wild Boar.name=野豬 -entity.TwilightForest.Bighorn Sheep.name=大角羊 -entity.TwilightForest.Wild Deer.name=野鹿 -entity.TwilightForest.Redcap.name=礦坑地精 -entity.TwilightForest.Swarm Spider.name=群居蜘蛛 -entity.TwilightForest.Naga.name=[BOSS]納迦 -entity.TwilightForest.Naga Segment.name=[BOSS]納迦的軀幹 -entity.TwilightForest.Skeleton Druid.name=亡靈德魯伊 -entity.TwilightForest.Hostile Wolf.name=憤怒的狼 -entity.TwilightForest.Twilight Wraith.name=暮光幽靈 -entity.TwilightForest.Hedge Spider.name=樹蛛 -entity.TwilightForest.Hydra.name=[BOSS]九頭蛇 -entity.TwilightForest.HydraHead.name=[BOSS]九頭蛇頭部 -entity.TwilightForest.Twilight Lich.name=[BOSS]巫妖王 -entity.TwilightForest.Penguin.name=企鵝 -entity.TwilightForest.Tiny Bird.name=小鳥 -entity.TwilightForest.Forest Squirrel.name=松鼠 -entity.TwilightForest.Forest Bunny.name=森林兔 -entity.TwilightForest.Forest Raven.name=烏鴉 -entity.TwilightForest.Questing Ram.name=暮色公羊 -entity.TwilightForest.Twilight Kobold.name=暮色哥布林 -entity.TwilightForest.Boggard.name=Boggard [未實裝] -entity.TwilightForest.Lich Minion.name=巫妖王隨從 -entity.TwilightForest.Loyal Zombie.name=殭屍僕從 -entity.TwilightForest.Mosquito Swarm.name=成群的蚊子 -entity.TwilightForest.Death Tome.name=死亡之書 -entity.TwilightForest.Minotaur.name=牛頭人戰士 -entity.TwilightForest.Minoshroom.name=彌諾陶洛斯 -entity.TwilightForest.Fire Beetle.name=噴火甲蟲 -entity.TwilightForest.Slime Beetle.name=黏液甲蟲 -entity.TwilightForest.Pinch Beetle.name=長角鍬形蟲 -entity.TwilightForest.Maze Slime.name=迷宮史萊姆 -entity.TwilightForest.Redcap Sapper.name=礦坑工兵 -entity.TwilightForest.Mist Wolf.name=薄霧巨狼 -entity.TwilightForest.King Spider.name=巨大狼蛛 -entity.TwilightForest.Firefly.name=螢火蟲 -entity.TwilightForest.Mini Ghast.name=暮色迷你惡靈 -entity.TwilightForest.Tower Ghast.name=巨大暮色惡靈 -entity.TwilightForest.Tower Golem.name=暮色高崙守衛 -entity.TwilightForest.Tower Termite.name=漆黑木蠹蟲 -entity.TwilightForest.Redscale Broodling.name=暮色孵化者 -entity.TwilightForest.Tower Boss.name=[BOSS]惡靈烏爾 -entity.TwilightForest.Block&Chain Goblin.name=鐵球哥布林戰士 -entity.TwilightForest.Upper Goblin Knight.name=哥布林騎士[上身] -entity.TwilightForest.Lower Goblin Knight.name=哥布林騎士[下身] -entity.TwilightForest.Helmet Crab.name=裝甲寄居蟹 -entity.TwilightForest.Knight Phantom.name=幻影騎士 -achievement.twilightArrival=暮光森林冒險者! -achievement.twilightArrival.desc=進入暮光森林 -achievement.twilightHedge=壞蟲踐踏者! -achievement.twilightHedge.desc=殺死樹籬迷宮內的蜘蛛 -achievement.twilightHill1=這裡的礦產都是我的! -achievement.twilightHill1.desc=在小型礦坑中殺死了一隻礦坑地精 -achievement.twilightHill2=中型礦坑[未實裝] -achievement.twilightHill2.desc=在中型礦坑中殺死了一隻怪物 -achievement.twilightHill3=早就看穿你了 -achievement.twilightHill3.desc=在大型礦坑中殺死了一隻暮光幽靈 -achievement.twilightHunter=暮光森林獵人 -achievement.twilightHunter.desc=在森林中殺死了野生動物 -achievement.twilightLich=巫妖王獵手 -achievement.twilightLich.desc=擊敗了巫妖王 -achievement.twilightLichScepters=魔法大師 -achievement.twilightLichScepters.desc=獲得暮光森林中所有的魔杖 -achievement.twilightMagicMap=萬里眼 -achievement.twilightMagicMap.desc=製作一張魔法地圖 -achievement.twilightMagicMapFocus=魔法文字 -achievement.twilightMagicMapFocus.desc=用烏鴉羽毛, 螢石粉, 火炬果實做出一個魔法地圖指針 -achievement.twilightMazeMap=隨時隨地都找的到出口 -achievement.twilightMazeMap.desc=獲得迷宮指針後製作一張迷宮地圖 -achievement.twilightNaga=納迦獵手 -achievement.twilightNaga.desc=擊敗了納迦 -achievement.twilightNagaArmors=納迦護甲 -achievement.twilightNagaArmors.desc=製作鱗片外衣和鱗片護腿 -achievement.twilightOreMap=這樣應該值得吧? -achievement.twilightOreMap.desc=製作一張昂貴地圖 -achievement.twilightPortal=暮光森林傳送門 -achievement.twilightPortal.desc=建造到暮光森林的傳送門 \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/lang/zh_cn.lang b/src/main/resources/assets/twilightforest/lang/zh_cn.lang new file mode 100644 index 0000000000..73b6f5e136 --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/zh_cn.lang @@ -0,0 +1,854 @@ +#PARSE_ESCAPES + +itemGroup.twilightForest=暮色森林 + +# ADVANCEMENTS +advancement.twilightforest.root.desc=前往那神秘的魔法林地——暮色森林! + +# General progression +advancement.twilightforest.hedge=碾碎爬虫 +advancement.twilightforest.hedge.desc=在%s中杀死一只蜘蛛。 + +advancement.twilightforest.hill1=靴子都是我的! +advancement.twilightforest.hill1.desc=在小%2$s里击败%1$s。 +advancement.twilightforest.hill2=什么动静? +advancement.twilightforest.hill2.desc=在中%2$s里击败%1$s。 +advancement.twilightforest.hill3=我看到你了 +advancement.twilightforest.hill3.desc=在大%2$s里杀死一只%1$s。 + +advancement.twilightforest.quest_ram=博学的羊 +advancement.twilightforest.quest_ram.desc=将遗失的东西交给谜题羊。 + +# Map +advancement.twilightforest.magic_map_focus=用火书写 +advancement.twilightforest.magic_map_focus.desc=用%2$s、%3$s和%4$s合成%1$s。 +advancement.twilightforest.magic_map=我有千里眼 +advancement.twilightforest.magic_map.desc=合成%s。 +advancement.twilightforest.maze_map=现在,寻找出口 +advancement.twilightforest.maze_map.desc=在迷宫中获取迷宫地图的核心,并用其来合成%s。 +advancement.twilightforest.ore_map=这玩意值这么多? +advancement.twilightforest.ore_map.desc=合成%s。 + +# Mainline beginning progression +advancement.twilightforest.twilight_hunter=森林之静 +advancement.twilightforest.twilight_hunter.desc=猎杀一些暮色的野生动物。 + +advancement.twilightforest.kill_naga=娜迦猎人 +advancement.twilightforest.kill_naga.desc=猎杀森林角落里的%s,取得可以帮你突破巫妖塔魔法壁垒的%s。 +advancement.twilightforest.naga_armors=娜迦装备锻造师 +advancement.twilightforest.naga_armors.desc=合成娜迦胸甲和娜迦护腿。 + +advancement.twilightforest.kill_lich=巫妖猎人 +advancement.twilightforest.kill_lich.desc=击败塔顶的%s并取得他的权杖,这权杖可以驱散沼泽的毒蚊群、解除黑暗森林的失明诅咒以及对抗冰雪森林的严寒。 +advancement.twilightforest.lich_scepters=融合! +advancement.twilightforest.lich_scepters.desc=学会使用三种权杖。 + +# Swamp Progression +advancement.twilightforest.progress_labyrinth=强力的牛头人沙拉酱肉 +advancement.twilightforest.progress_labyrinth.desc=在吃下温暖人心的蘑菇炖肉后,你认为你已经做好了前往火焰沼泽的准备。 +advancement.twilightforest.kill_hydra=九头蛇猎人 +advancement.twilightforest.kill_hydra.desc=猎杀强大的%s,这将让你信心倍增。 +advancement.twilightforest.mazebreaker=破坏迷宫 +advancement.twilightforest.mazebreaker.desc=在迷宫的密室中找到%s。 +advancement.twilightforest.hydra_chop=快看!九头蛇的肉! +advancement.twilightforest.hydra_chop.desc=在你的胃空空如也的时候从暴走的%s上砍下来几块肉。 + +# Dark Forest Progression +advancement.twilightforest.progress_trophy_pedestal=受奖冠军 +advancement.twilightforest.progress_trophy_pedestal.desc=将奖杯放置于黑暗森林遗迹中的奖杯基座上,并获得你的头衔。 +advancement.twilightforest.progress_knights=号令砷铅铁机关 +advancement.twilightforest.progress_knights.desc=令骑士之墓的幻影安息,之后你将能控制高塔中的砷铅铁机关。 +advancement.twilightforest.ghast_trap=高塔里的奇怪装置 +advancement.twilightforest.ghast_trap.desc=以%s为祭品,激活%s,把%s拉下来! +advancement.twilightforest.progress_ur_ghast=火之泪 +advancement.twilightforest.progress_ur_ghast.desc=触碰%s那炽红的眼泪。 + +advancement.twilightforest.experiment_115=神秘的肉? +advancement.twilightforest.experiment_115.desc=尽管它看起来像蛋糕…… +advancement.twilightforest.experiment_115_2=做个记录:大胜利! +advancement.twilightforest.experiment_115_2.desc=松软,美味! + +# Snow Forest Progression +advancement.twilightforest.progress_yeti=首领的毛皮 +advancement.twilightforest.progress_yeti.desc=披上雪怪首领松软的毛皮,籍此抵抗冰川里那刺骨的寒风。 +advancement.twilightforest.progress_glacier=澄澈之空 +advancement.twilightforest.progress_glacier.desc=击败%2$s里的%1$s。 +advancement.twilightforest.arctic_dyed=追赶潮流 +advancement.twilightforest.arctic_dyed.desc=给全套极地套装染色。 + +# Mid-way Misc. Stuff +advancement.twilightforest.glass_sword=会心一击 +advancement.twilightforest.glass_sword.desc=望善加利用 + +advancement.twilightforest.fiery_set=血泪成河 +advancement.twilightforest.fiery_set.desc=身着至少一件炽热金属装备时,手持炽热金属工具。 + +# Highlands +advancement.twilightforest.progress_merge=最终对决 +advancement.twilightforest.progress_merge.desc=击杀%s、%s和%s,以驱散高地上空的酸雨;此时,你认为你已经有资格向高地宣战了。 +advancement.twilightforest.progress_troll=让烈焰燃烧得更猛烈些吧! +advancement.twilightforest.progress_troll.desc=在巨魔洞穴中找到%s,用它来焚烧掉荆棘之墙。 +advancement.twilightforest.progress_thorns=穿越荆棘【未实现】 +advancement.twilightforest.progress_thorns.desc=穿越荆棘之地,打开通往城堡的大门。 +advancement.twilightforest.progress_castle=这就是,城堡吗……【未实现】 +advancement.twilightforest.progress_castle.desc=这城堡里究竟有什么?! + +# Collections +advancement.twilightforest.twilight_dining=永恒黄昏之宴 +advancement.twilightforest.twilight_dining.desc=品尝所有只能在暮色森林找到的食物。 +advancement.twilightforest.experiment_115_3=每天都吃 115,坚持 115 年,一刻不要停 +advancement.twilightforest.experiment_115_3.desc=每天都吃实验物品 1-1-5,不要停,115 次实验物品 1-1-5,experiment115 点 com,三 w 点 experiment115 点 com,115 年,每时每刻都来 experiment115 点 com,三 w 点 115xexperiment115 点 com +advancement.twilightforest.arborist=疯狂树木学家 +advancement.twilightforest.arborist.desc=准备好斧子和剪刀。把所有的犄角旮旯全部搜索一遍。然后收集齐所有从树上出来的东西!不论是合成出来还是战利品箱子里搜,不论是台阶还是树苗还是树叶,只要是从树上的哪个部分做出来的都算! + +twilightforest.twilight_portal.unsafe=这里看上去不安全…… +twilightforest.trophy_pedestal.ineligible=你还不够格。 +twilightforest.ore_meter.range=半径:%s,原点:[%d, %d] +twilightforest.ore_meter.exposed=暴露数量:%d +twilightforest.scepter_charges=剩余使用次数:%d + +# Commands +commands.tffeature.usage=/tffeature +commands.tffeature.not_in_twilight_forest=你现在不在暮色森林维度中! +commands.tffeature.nearest=距离当前位置最近的地图特性:%s +commands.tffeature.center=地图特性中心:%s +commands.tffeature.chunk=是否在地图特性区块中:%s +commands.tffeature.structure.inside=你现在在该地图特性的结构中 +commands.tffeature.structure.outside=你现在不在该地图特性的结构中 +commands.tffeature.structure.required=你现在不在某个结构中 +commands.tffeature.structure.conquer.status=当前结构征服标记:%s +commands.tffeature.structure.conquer.update=当前结构征服标记现已从 %s 更改为 %s +commands.tffeature.locate.usage=/tffeature locate + +# Blocks +tile.twilightforest.Log.0.name=暮色橡木 +tile.twilightforest.Log.1.name=苍穹木 +tile.twilightforest.Log.2.name=红木 +tile.twilightforest.Log.3.name=黑木 +tile.twilightforest.Leaves.0.name=暮色橡木树叶 +tile.twilightforest.Leaves.1.name=苍穹树叶 +tile.twilightforest.Leaves.2.name=红树树叶 +tile.twilightforest.Leaves.3.name=彩虹橡树叶 +tile.twilightforest.Firefly.name=萤火虫 +tile.twilightforest.Cicada.name=蝉 +tile.twilightforest.Cicada.desc=如果它能像电磁炮一样用……? +item.twilightforest.Portal.name=暮色森林传送门 +tile.twilightforest.Portal.name=暮色森林传送门 +tile.twilightforest.Mazestone.0.name=遗迹石头 +tile.twilightforest.Mazestone.1.name=遗迹石砖 +tile.twilightforest.Mazestone.2.name=錾制遗迹石头 +tile.twilightforest.Mazestone.3.name=装饰遗迹石砖 +tile.twilightforest.Mazestone.4.name=破碎遗迹石砖 +tile.twilightforest.Mazestone.5.name=遗迹苔石砖 +tile.twilightforest.Mazestone.6.name=遗迹石方块 +tile.twilightforest.Mazestone.7.name=遗迹石沿 +tile.twilightforest.Mazestone.8.name=遗迹天花板 +tile.twilightforest.Hedge.0.name=树篱 +tile.twilightforest.Hedge.1.name=黑树树叶 +tile.twilightforest.BossSpawner.0.name=生成 娜迦 +tile.twilightforest.BossSpawner.1.name=生成 巫妖 +tile.twilightforest.BossSpawner.2.name=生成 九头蛇 +tile.twilightforest.BossSpawner.3.name=生成 暮色恶魂 +tile.twilightforest.BossSpawner.4.name=生成 幻影骑士 +tile.twilightforest.BossSpawner.5.name=生成 冰雪女王 +tile.twilightforest.BossSpawner.6.name=生成 米诺菇 +tile.twilightforest.BossSpawner.7.name=生成 雪怪首领 +tile.twilightforest.FireflyJar.name=萤火虫罐子 +tile.twilightforest.Plant.0.name=暮色森林苔藓 +tile.twilightforest.Plant.1.name=鬼臼果 +tile.twilightforest.Plant.2.name=三叶草 [WIP] +tile.twilightforest.Plant.3.name=暮色森林蕨类 +tile.twilightforest.Plant.4.name=荧光蘑菇 +tile.twilightforest.Plant.5.name=林地草 +tile.twilightforest.Plant.6.name=枯死的灌木 +tile.twilightforest.Plant.7.name=火炬浆果植物 +tile.twilightforest.Plant.8.name=根须 +tile.twilightforest.Plant.9.name=树叶堆 +tile.twilightforest.Roots.0.name=根茎 +tile.twilightforest.Roots.1.name=活根 +tile.twilightforest.UncraftingTable.name=拆解台 +tile.twilightforest.FireJet.0.name=烟雾方块 +tile.twilightforest.FireJet.1.name=被包裹的烟雾 +tile.twilightforest.FireJet.2.name=被包裹的烟雾 +tile.twilightforest.FireJet.3.name=火焰喷射 +tile.twilightforest.FireJet.4.name=火焰喷射-弹射 +tile.twilightforest.FireJet.5.name=火焰喷射-激活 +tile.twilightforest.FireJet.6.name=火焰喷射方块 +tile.twilightforest.FireJet.7.name=被包裹的凸出火焰喷射 +tile.twilightforest.FireJet.8.name=被包裹的炽红火焰喷射 +tile.twilightforest.Nagastone.0.name=娜迦石头部 +tile.twilightforest.Nagastone.1.name=娜迦石 +tile.twilightforest.Sapling.name=暮色树苗 +tile.twilightforest.Sapling.0.name=暮色橡树树苗 +tile.twilightforest.Sapling.1.name=苍穹树树苗 +tile.twilightforest.Sapling.2.name=红树树苗 +tile.twilightforest.Sapling.3.name=黑树树苗 +tile.twilightforest.Sapling.4.name=高大暮色橡树树苗 +tile.twilightforest.Sapling.5.name=时光树树苗 +tile.twilightforest.Sapling.6.name=变化树树苗 +tile.twilightforest.Sapling.7.name=矿石树树苗 +tile.twilightforest.Sapling.8.name=分类树树苗 +tile.twilightforest.Sapling.9.name=彩虹树树苗 +tile.twilightforest.Moonworm.name=月光蠕虫 +tile.twilightforest.MagicLog.0.name=时光树原木 +tile.twilightforest.MagicLog.1.name=变化树原木 +tile.twilightforest.MagicLog.2.name=矿石树原木 +tile.twilightforest.MagicLog.3.name=分类树原木 +tile.twilightforest.MagicLogSpecial.0.name=时光树时钟 +tile.twilightforest.MagicLogSpecial.1.name=变化树心脏 +tile.twilightforest.MagicLogSpecial.2.name=矿石树核心 +tile.twilightforest.MagicLogSpecial.3.name=分类树引擎 +tile.twilightforest.MagicLeaves.0.name=时光树树叶 +tile.twilightforest.MagicLeaves.1.name=变化树树叶 +tile.twilightforest.MagicLeaves.2.name=矿石树树叶 +tile.twilightforest.MagicLeaves.3.name=分类树树叶 +tile.twilightforest.TowerStone.0.name=塔树木板 +tile.twilightforest.TowerStone.1.name=塔树板箱 +tile.twilightforest.TowerStone.2.name=破裂塔木 +tile.twilightforest.TowerStone.3.name=青苔塔木 +tile.twilightforest.TowerStone.4.name=虫蛀塔木 +tile.twilightforest.TowerDevice.0.name=重现的方块 +tile.twilightforest.TowerDevice.1.name=激活的重现方块 +tile.twilightforest.TowerDevice.2.name=消失的方块 +tile.twilightforest.TowerDevice.3.name=激活消失的方块 +tile.twilightforest.TowerDevice.4.name=锁定的消失的方块 +tile.twilightforest.TowerDevice.5.name=解锁的消失的方块 +tile.twilightforest.TowerDevice.6.name=高塔建设者 +tile.twilightforest.TowerDevice.7.name=激活的高塔建设者 +tile.twilightforest.TowerDevice.8.name=关闭的高塔建设者 +tile.twilightforest.TowerDevice.9.name=反建器 +tile.twilightforest.TowerDevice.10.name=恶魂陷阱 +tile.twilightforest.TowerDevice.11.name=激活的恶魂陷阱 +tile.twilightforest.TowerDevice.12.name=砷铅铁反应堆 +tile.twilightforest.TowerDevice.13.name=激活的砷铅铁反应堆 +tile.twilightforest.TowerTranslucent.0.name=再现方块 +tile.twilightforest.TowerTranslucent.1.name=激活的再现方块 +tile.twilightforest.TowerTranslucent.2.name=建造的砷铅铁方块 +tile.twilightforest.TowerTranslucent.3.name=激活的建造的砷铅铁方块 +tile.twilightforest.TowerTranslucent.4.name=反建方块 +tile.twilightforest.TowerTranslucent.5.name=砷铅铁反应堆碎片 +tile.twilightforest.TowerTranslucent.6.name=伪金块 +tile.twilightforest.TowerTranslucent.7.name=伪钻石块 +tile.twilightforest.Trophy.name=暮色森林战利品 +tile.twilightforest.Shield.name=要塞护盾 +tile.twilightforest.TrophyPedestal.0.name=战利品宝座 +tile.twilightforest.TrophyPedestal.15.name=隐藏的战利品宝座 +tile.twilightforest.AuroraBrick.name=极光方块 +tile.twilightforest.UnderBrick.0.name=地下砖 +tile.twilightforest.UnderBrick.1.name=青苔地下砖 +tile.twilightforest.UnderBrick.2.name=碎裂地下砖 +tile.twilightforest.UnderBrick.3.name=抛光地下砖 +tile.twilightforest.Thorns.brown.name=荆棘 +tile.twilightforest.Thorns.green.name=翠绿荆棘 +tile.twilightforest.BurntThorns.name=烧焦荆棘 +tile.twilightforest.ThornRose.name=荆棘玫瑰 +tile.twilightforest.Leaves3.0.name=荆棘叶 +tile.twilightforest.Leaves3.1.name=豆茎叶 +tile.twilightforest.Deadrock.surface.name=风化死岩 +tile.twilightforest.Deadrock.cracked.name=裂纹死岩 +tile.twilightforest.Deadrock.solid.name=死岩 +tile.twilightforest.DarkLeaves.name=黑树树叶 +tile.twilightforest.AuroralizedGlass.name=极光玻璃 +tile.twilightforest.AuroraPillar.name=极光柱 +tile.twilightforest.AuroraSlab.name=极光台阶 +tile.twilightforest.TrollSteinn.name=巨魔岩石 +tile.twilightforest.WispyCloud.name=薄云 +tile.twilightforest.FluffyCloud.name=浮云 +tile.twilightforest.GiantCobble.name=巨型圆石 +tile.twilightforest.GiantLog.name=巨型原木 +tile.twilightforest.GiantLeaves.name=巨型树叶 +tile.twilightforest.GiantObsidian.name=巨型黑曜石 +tile.twilightforest.UberousSoil.name=肥沃泥土 +tile.twilightforest.HugeStalk.name=巨大的茎 +tile.twilightforest.HugeGloomBlock.name=巨型荧光蘑菇 +tile.twilightforest.TrollVidr.name=巨魔藤蔓 +tile.twilightforest.UnripeTrollBer.name=没熟的巨魔莓 +#tile.twilightforest.TrollBer.name=巨魔莓 +tile.twilightforest.TrollBer.name=巨魔莓 +tile.twilightforest.KnightmetalBlock.name=骑士金属块 +tile.twilightforest.HugeLilyPad.name=巨型睡莲 +tile.twilightforest.HugeWaterLily.name=巨型荷花 +tile.twilightforest.Slider.0.name=滑动陷阱 +tile.twilightforest.Slider.1.name=滑动陷阱 甲 +tile.twilightforest.Slider.2.name=滑动陷阱 乙 +tile.twilightforest.Slider.3.name=滑动陷阱 丙 +tile.twilightforest.CastleBrick.0.name=城堡砖 +tile.twilightforest.CastleBrick.1.name=磨损城堡砖 +tile.twilightforest.CastleBrick.2.name=碎裂城堡砖 +tile.twilightforest.CastleBrick.3.name=城堡顶瓦 +tile.twilightforest.CastleBrick.4.name=生苔城堡砖 +tile.twilightforest.CastleBrick.5.name=厚重城堡砖 +tile.twilightforest.CastleStairsBrick.name=城堡砖楼梯 +tile.twilightforest.CastleStairsWorn.name=磨损城堡砖楼梯 +tile.twilightforest.CastleStairsCracked.name=碎裂城堡砖楼梯 +tile.twilightforest.CastleStairsMossy.name=生苔城堡砖楼梯 +tile.twilightforest.CastleDoor.0.name=黄色城堡门 +tile.twilightforest.CastleDoor.1.name=紫色城堡门 +tile.twilightforest.CastleDoor.2.name=粉红色城堡门 +tile.twilightforest.CastleDoor.3.name=蓝色城堡门 +tile.twilightforest.CastleMagic.0.name=粉红色城堡符文砖 +tile.twilightforest.CastleMagic.1.name=蓝色城堡符文砖 +tile.twilightforest.CastleMagic.2.name=黄色城堡符文砖 +tile.twilightforest.CastleMagic.3.name=紫色城堡符文砖 +tile.twilightforest.CastlePillar.0.name=黑纹城堡砖柱 +tile.twilightforest.CastlePillar.1.name=黑纹城堡砖瓦 +tile.twilightforest.CastlePillar.2.name=粗纹城堡砖柱 +tile.twilightforest.CastlePillar.3.name=粗纹城堡砖瓦 +tile.twilightforest.CastleStairs.0.name=黑纹城堡砖楼梯 +tile.twilightforest.CastleStairs.8.name=粗纹城堡砖楼梯 +tile.twilightforest.ForceField.0.name=紫色力场 +tile.twilightforest.ForceField.1.name=粉红色力场 +tile.twilightforest.ForceField.2.name=橙色力场 +tile.twilightforest.ForceField.3.name=绿色力场 +tile.twilightforest.ForceField.4.name=蓝色力场 +tile.twilightforest.BlockOfStorage.0.name=铁树块 +tile.twilightforest.BlockOfStorage.1.name=炽热金属块 +tile.twilightforest.BlockOfStorage.2.name=钢叶块 +tile.twilightforest.BlockOfStorage.3.name=极地毛皮块 +tile.twilightforest.BlockOfStorage.4.name=砷铅铁块 +tile.twilightforest.CinderFurnaceIdle.name=余烬熔炉【未实现】 +tile.twilightforest.CinderLog.name=余烬原木【未实现】 +tile.twilightforest.MiniatureStructure=微缩模型:%s【未实现】 +tile.twilightforest.SpiralBricks.name=螺旋石砖【开发中】 +tile.twilightforest.BlockOfLapisTF.name=青金石块【未实现】 +tile.twilightforest.EtchedNagastone.name=蚀刻娜迦石 +tile.twilightforest.NagastonePillar.name=娜迦石柱 +tile.twilightforest.NagastoneStairs.0.name=娜迦石楼梯(左) +tile.twilightforest.NagastoneStairs.8.name=娜迦石楼梯(右) +tile.twilightforest.EtchedNagastoneMossy.name=蚀刻娜迦苔石 +tile.twilightforest.NagastonePillarMossy.name=娜迦苔石柱 +tile.twilightforest.NagastoneStairsMossy.0.name=娜迦苔石楼梯(左) +tile.twilightforest.NagastoneStairsMossy.8.name=娜迦苔石楼梯(右) +tile.twilightforest.EtchedNagastoneWeathered.name=风化的蚀刻娜迦石 +tile.twilightforest.NagastonePillarWeathered.name=风化的娜迦石柱 +tile.twilightforest.NagastoneStairsWeathered.0.name=风化的娜迦石楼梯(左) +tile.twilightforest.NagastoneStairsWeathered.8.name=风化的娜迦石楼梯(右) +tile.twilightforest.IronLadder.name=铁梯子 +tile.twilightforest.TerrorCottaCircle.name=圈状陶瓦 +tile.twilightforest.TerrorCottaDiagonal.name=对角陶瓦 + +tile.twilightforest.CanopyPlanks.name=苍穹木板 +tile.twilightforest.CanopyStairs.name=苍穹木楼梯 +tile.twilightforest.CanopySlab.name=苍穹木台阶 +tile.twilightforest.CanopyButton.name=苍穹木按钮 +tile.twilightforest.CanopyFence.name=苍穹木栅栏 +tile.twilightforest.CanopyGate.name=苍穹木栅栏门 +tile.twilightforest.CanopyPlate.name=苍穹木压力板 +tile.twilightforest.CanopyTrapDoor.name=苍穹木活板门 +item.tile.twilightforest.CanopyDoor.name=苍穹木门 + +tile.twilightforest.DarkPlanks.name=黑木木板 +tile.twilightforest.DarkStairs.name=黑木楼梯 +tile.twilightforest.DarkSlab.name=黑木台阶 +tile.twilightforest.DarkButton.name=黑木按钮 +tile.twilightforest.DarkFence.name=黑木栅栏 +tile.twilightforest.DarkGate.name=黑木栅栏门 +tile.twilightforest.DarkPlate.name=黑木压力板 +tile.twilightforest.DarkTrapDoor.name=黑木活板门 +item.tile.twilightforest.DarkDoor.name=黑木门 + +tile.twilightforest.MangrovePlanks.name=红木板 +tile.twilightforest.MangroveStairs.name=红木楼梯 +tile.twilightforest.MangroveSlab.name=红木台阶 +tile.twilightforest.MangroveButton.name=红木按钮 +tile.twilightforest.MangroveFence.name=红木栅栏 +tile.twilightforest.MangroveGate.name=红木栅栏门 +tile.twilightforest.MangrovePlate.name=红木压力板 +tile.twilightforest.MangroveTrapDoor.name=红木活板门 +item.tile.twilightforest.MangroveDoor.name=红木门 + +tile.twilightforest.TwilightOakPlanks.name=暮色橡木板 +tile.twilightforest.TwilightOakStairs.name=暮色橡木楼梯 +tile.twilightforest.TwilightOakSlab.name=暮色橡木台阶 +tile.twilightforest.TwilightOakButton.name=暮色橡木按钮 +tile.twilightforest.TwilightOakFence.name=暮色橡木栅栏 +tile.twilightforest.TwilightOakGate.name=暮色橡木栅栏门 +tile.twilightforest.TwilightOakPlate.name=暮色橡木压力板 +tile.twilightforest.TwilightOakTrapDoor.name=暮色橡木活板门 +item.tile.twilightforest.TwilightOakDoor.name=暮色橡木门 + +tile.twilightforest.TimePlanks.name=时光木板 +tile.twilightforest.TimeStairs.name=时光木楼梯 +tile.twilightforest.TimeSlab.name=时光木台阶 +tile.twilightforest.TimeButton.name=时光木按钮 +tile.twilightforest.TimeFence.name=时光木栅栏 +tile.twilightforest.TimeGate.name=时光木栅栏门 +tile.twilightforest.TimePlate.name=时光木压力板 +tile.twilightforest.TimeTrapDoor.name=时光木活板门 +item.tile.twilightforest.TimeDoor.name=时光木门 + +tile.twilightforest.TransPlanks.name=变化木板 +tile.twilightforest.TransStairs.name=变化木楼梯 +tile.twilightforest.TransSlab.name=变化木台阶 +tile.twilightforest.TransButton.name=变化木按钮 +tile.twilightforest.TransFence.name=变化木栅栏 +tile.twilightforest.TransGate.name=变化木栅栏门 +tile.twilightforest.TransPlate.name=变化木压力板 +tile.twilightforest.TransTrapDoor.name=变化木活板门 +item.tile.twilightforest.TransDoor.name=变化木门 + +tile.twilightforest.MinePlanks.name=矿石木板 +tile.twilightforest.MineStairs.name=矿石木楼梯 +tile.twilightforest.MineSlab.name=矿石木台阶 +tile.twilightforest.MineButton.name=矿石木按钮 +tile.twilightforest.MineFence.name=矿石木栅栏 +tile.twilightforest.MineGate.name=矿石木栅栏门 +tile.twilightforest.MinePlate.name=矿石木压力板 +tile.twilightforest.MineTrapDoor.name=矿石木活板门 +item.tile.twilightforest.MineDoor.name=矿石木门 + +tile.twilightforest.SortPlanks.name=分类木板 +tile.twilightforest.SortStairs.name=分类木楼梯 +tile.twilightforest.SortSlab.name=分类木台阶 +tile.twilightforest.SortButton.name=分类木按钮 +tile.twilightforest.SortFence.name=分类木栅栏 +tile.twilightforest.SortGate.name=分类木栅栏门 +tile.twilightforest.SortPlate.name=分类木压力板 +tile.twilightforest.SortTrapDoor.name=分类木活板门 +item.tile.twilightforest.SortDoor.name=分类木门 + +# Structures +structure.twilight_portal.name=暮色森林传送门 +structure.hedge_maze.name=树篱迷宫 +structure.hollow_hill.name=亡灵矿山 +structure.quest_grove.name=谜题羊树丛 +structure.mushroom_tower.name=蘑菇堡 +structure.naga_courtyard.name=娜迦花园 +structure.lich_tower.name=巫妖塔 +structure.minotaur_labyrinth.name=牛头人迷宫 +structure.hydra_lair.name=九头蛇巢穴 +structure.goblin_stronghold.name=哥布林要塞 +structure.dark_tower.name=黑暗之塔 +structure.yeti_cave.name=雪怪洞窟 +structure.aurora_palace.name=极光宫殿 +structure.troll_cave_and_cloud_castle.name=巨魔洞穴与云上楼阁 +structure.final_castle.name=终焉城堡 + +# Items +item.twilightforest.nagaScale.name=娜迦鳞片 +item.twilightforest.plateNaga.name=娜迦胸甲 +item.twilightforest.legsNaga.name=娜迦护腿 +item.twilightforest.scepterTwilight.name=黄昏权杖 +item.twilightforest.scepterLifeDrain.name=吸血权杖 +item.twilightforest.scepterZombie.name=僵尸权杖 +item.twilightforest.scepterShield.name=护盾权杖 +item.twilightforest.oreMeter.name=矿石感应仪【未实现】 +item.twilightforest.magicMap.name=魔法地图 +item.twilightforest.mazeMap.name=迷宫地图 +item.twilightforest.oreMap.name=迷宫 / 矿石地图 +item.twilightforest.tfFeather.name=乌鸦羽毛 +item.twilightforest.magicMapFocus.name=魔法地图核心 +item.twilightforest.mazeMapFocus.name=迷宫地图核心 +item.twilightforest.liveRoot.name=活根 +item.twilightforest.ironwoodRaw.name=生铁树原料 +item.twilightforest.ironwoodIngot.name=铁树锭 +item.twilightforest.ironwoodHelm.name=铁树头盔 +item.twilightforest.ironwoodPlate.name=铁树胸甲 +item.twilightforest.ironwoodLegs.name=铁树护腿 +item.twilightforest.ironwoodBoots.name=铁树靴 +item.twilightforest.ironwoodSword.name=铁树剑 +item.twilightforest.ironwoodShovel.name=铁树铲 +item.twilightforest.ironwoodPick.name=铁树镐 +item.twilightforest.ironwoodAxe.name=铁树斧 +item.twilightforest.ironwoodHoe.name=铁树锄 +item.twilightforest.torchberries.name=火炬浆果 +item.twilightforest.venisonRaw.name=生鹿肉 +item.twilightforest.venisonCooked.name=鹿肉排 +item.twilightforest.hydraChop.name=九头蛇肉排 +item.twilightforest.fieryBlood.name=炽热的血液 +item.twilightforest.fieryIngot.name=炽铁锭 +item.twilightforest.fieryHelm.name=炽铁头盔 +item.twilightforest.fieryPlate.name=炽铁胸甲 +item.twilightforest.fieryLegs.name=炽铁护腿 +item.twilightforest.fieryBoots.name=炽铁靴子 +item.twilightforest.fierySword.name=炽铁剑 +item.twilightforest.fieryPick.name=炽铁镐 +item.twilightforest.steeleafIngot.name=钢叶 +item.twilightforest.steeleafHelm.name=钢叶头盔 +item.twilightforest.steeleafPlate.name=钢叶胸甲 +item.twilightforest.steeleafLegs.name=钢叶护腿 +item.twilightforest.steeleafBoots.name=钢叶靴 +item.twilightforest.steeleafSword.name=钢叶剑 +item.twilightforest.steeleafShovel.name=钢叶铲 +item.twilightforest.steeleafPick.name=钢叶镐 +item.twilightforest.steeleafAxe.name=钢叶斧 +item.twilightforest.steeleafHoe.name=钢叶锄 +item.twilightforest.minotaurAxe.name=钻石米诺陶战斧 +item.twilightforest.minotaurAxeGold.name=金米诺陶战斧 +item.twilightforest.mazebreakerPick.name=迷宫破坏者 +item.twilightforest.transformPowder.name=转换粉 +item.twilightforest.meefRaw.name=生牛头人肉 +item.twilightforest.meefSteak.name=牛头人肉排 +item.twilightforest.meefStroganoff.name=牛头人沙拉酱肉 +item.twilightforest.mazeWafer.name=迷宫薄饼 +item.twilightforest.emptyMagicMap.name=空白魔法地图 +item.twilightforest.emptyMazeMap.name=空白迷宫地图 +item.twilightforest.emptyOreMap.name=空白迷宫 / 矿石地图 +item.twilightforest.oreMagnet.name=矿石磁铁 +item.twilightforest.crumbleHorn.name=瓦解之号角 +item.twilightforest.peacockFan.name=孔雀羽毛扇 +item.twilightforest.moonwormQueen.name=月光蠕虫女王 +item.twilightforest.charmOfLife1.name=生命符咒 I +item.twilightforest.charmOfLife2.name=生命符咒 II +item.twilightforest.charmOfKeeping1.name=保管符咒 I +item.twilightforest.charmOfKeeping2.name=保管符咒 II +item.twilightforest.charmOfKeeping3.name=保管符咒 III +item.twilightforest.towerKey.name=塔钥匙 +item.twilightforest.borerEssence.name=三化螟精华 +item.twilightforest.carminite.name=砷铅铁矿石 +item.twilightforest.tf_trophy.name=%s战利品 +item.twilightforest.trophy.hydra.name=九头蛇战利品 +item.twilightforest.trophy.naga.name=娜迦战利品 +item.twilightforest.trophy.lich.name=巫妖战利品 +item.twilightforest.trophy.ur_ghast.name=暮色恶魂战利品 +item.twilightforest.trophy.snow_queen.name=冰雪女王战利品 +item.twilightforest.experiment115.name=试验物品 115 +item.twilightforest.armorShards.name=装甲碎片 +item.twilightforest.knightMetal.name=骑士金属锭 +item.twilightforest.shardCluster.name=装甲碎片堆 +item.twilightforest.knightlyHelm.name=骑士头盔 +item.twilightforest.knightlyPlate.name=骑士胸甲 +item.twilightforest.knightlyLegs.name=骑士护腿 +item.twilightforest.knightlyBoots.name=骑士靴 +item.twilightforest.knightlySword.name=骑士剑 +item.twilightforest.knightlyPick.name=骑士镐 +item.twilightforest.knightlyAxe.name=骑士斧 +item.twilightforest.knightlyShield.name=骑士盾 +item.twilightforest.phantomHelm.name=幻影头盔 +item.twilightforest.phantomPlate.name=幻影胸甲 +item.twilightforest.lampOfCinders.name=余烬之灯 +item.twilightforest.fieryTears.name=炽热之泪 +item.twilightforest.iceBomb.name=冰霜炸弹 +item.twilightforest.yetiHelm.name=雪怪角盔 +item.twilightforest.yetiPlate.name=雪怪皮衣 +item.twilightforest.yetiLegs.name=雪怪护腿 +item.twilightforest.yetiBoots.name=雪怪靴子 +item.twilightforest.alphaFur.name=雪怪首领毛皮 +item.twilightforest.arcticFur.name=极地毛皮 +item.twilightforest.arcticHelm.name=极地风帽 +item.twilightforest.arcticPlate.name=极地皮衣 +item.twilightforest.arcticLegs.name=极地护腿 +item.twilightforest.arcticBoots.name=极地靴子 +item.twilightforest.magicBeans.name=魔豆 +item.twilightforest.giantPick.name=巨人镐 +item.twilightforest.giantSword.name=巨人剑 +item.twilightforest.tripleBow.name=三发弓 +item.twilightforest.seekerBow.name=追踪弓 +item.twilightforest.iceBow.name=寒冰弓 +item.twilightforest.enderBow.name=末影弓 +item.twilightforest.iceSword.name=寒冰剑 +item.twilightforest.glassSword.name=玻璃剑 +item.twilightforest.knightmetalRing.name=骑士金属环 +item.twilightforest.chainBlock.name=链锤 +item.twilightforest.cubeTalisman.name=立方护符 +item.twilightforest.cubeOfAnnihilation.name=湮灭立方 +item.twilightforest.moonDial.name=月相罗盘 + +item.twilightforest.guide.name=旅行者日记 + +item.twilightforest.minotaurAxe.tooltip=蓄力时造成额外伤害 +item.twilightforest.minotaurAxeGold.tooltip=蓄力时造成额外伤害 +item.twilightforest.knightlySword.tooltip=对有护甲的目标造成额外伤害 +item.twilightforest.knightlyPick.tooltip=对有护甲的目标造成额外伤害 +item.twilightforest.knightlyAxe.tooltip=对无护甲的目标造成额外伤害 +item.twilightforest.giantPick.tooltip=用于破坏巨型方块 +item.twilightforest.fieryPick.tooltip=自动烧炼 +item.twilightforest.fierySword.tooltip=灼烧攻击目标 +item.twilightforest.fieryHelm.tooltip=灼烧攻击者 +item.twilightforest.fieryPlate.tooltip=灼烧攻击者 +item.twilightforest.fieryLegs.tooltip=灼烧攻击者 +item.twilightforest.fieryBoots.tooltip=灼烧攻击者 +item.twilightforest.phantomHelm.tooltip=死亡时不会掉落 +item.twilightforest.phantomPlate.tooltip=死亡时不会掉落 +item.twilightforest.yetiHelm.tooltip=冰冻攻击者 +item.twilightforest.yetiPlate.tooltip=冰冻攻击者 +item.twilightforest.yetiLegs.tooltip=冰冻攻击者 +item.twilightforest.yetiBoots.tooltip=冰冻攻击者 + +item.twilightforest.arctic_armor.tooltip=能像皮革盔甲一样染色 + +# Entities +entity.twilightforest.wild_boar.name=野猪 +entity.twilightforest.bighorn_sheep.name=大角山羊 +entity.twilightforest.deer.name=野鹿 +entity.twilightforest.redcap.name=红帽哥布林 +entity.twilightforest.swarm_spider.name=集群蜘蛛 +entity.twilightforest.naga.name=娜迦 +entity.twilightforest.naga_segment.name=娜迦身体 +entity.twilightforest.skeleton_druid.name=骷髅德鲁伊 +entity.twilightforest.hostile_wolf.name=恶狼 +entity.twilightforest.wraith.name=幽灵 +entity.twilightforest.hedge_spider.name=树篱蜘蛛 +entity.twilightforest.hydra.name=九头蛇 +entity.twilightforest.hydra_head.name=九头蛇头 +entity.twilightforest.lich.name=巫妖 +entity.twilightforest.penguin.name=企鹅 +entity.twilightforest.tiny_bird.name=小鸟 +entity.twilightforest.squirrel.name=松鼠 +entity.twilightforest.bunny.name=小兔子 +entity.twilightforest.raven.name=乌鸦 +entity.twilightforest.quest_ram.name=谜题羊 +entity.twilightforest.kobold.name=哥布林 +entity.twilightforest.boggard.name=博加德【未实现】 +entity.twilightforest.lich_minion.name=巫妖的仆从 +entity.twilightforest.loyal_zombie.name=忠诚的僵尸 +entity.twilightforest.mosquito_swarm.name=蚊群 +entity.twilightforest.death_tome.name=死灵书 +entity.twilightforest.minotaur.name=米诺陶 +entity.twilightforest.minoshroom.name=米诺菇 +entity.twilightforest.fire_beetle.name=喷火甲虫 +entity.twilightforest.slime_beetle.name=粘液甲虫 +entity.twilightforest.pinch_beetle.name=夹虫 +entity.twilightforest.maze_slime.name=迷宫史莱姆 +entity.twilightforest.redcap_sapper.name=红帽地精 +entity.twilightforest.mist_wolf.name=迷雾狼 +entity.twilightforest.king_spider.name=国王蜘蛛 +entity.twilightforest.firefly.name=萤火虫 +entity.twilightforest.mini_ghast.name=迷你幽灵 +entity.twilightforest.tower_ghast.name=高塔幽灵 +entity.twilightforest.tower_golem.name=高塔铁傀儡 +entity.twilightforest.tower_termite.name=高塔螟 +entity.twilightforest.tower_broodling.name=寄生虫 +entity.twilightforest.ur_ghast.name=暮色恶魂 +entity.twilightforest.blockchain_goblin.name=链锤哥布林 +entity.twilightforest.goblin_knight_upper.name=哥布林骑士(上身) +entity.twilightforest.goblin_knight_lower.name=哥布林骑士(下身) +entity.twilightforest.helmet_crab.name=寄居蟹 +entity.twilightforest.knight_phantom.name=幻影骑士 +entity.twilightforest.yeti.name=雪怪 +entity.twilightforest.yeti_alpha.name=雪怪首领 +entity.twilightforest.winter_wolf.name=寒冬狼 +entity.twilightforest.snow_guardian.name=冰雪守卫 +entity.twilightforest.stable_ice_core.name=冰精灵 +entity.twilightforest.unstable_ice_core.name=破碎冰精灵 +entity.twilightforest.snow_queen.name=冰雪女王 +entity.twilightforest.troll.name=洞穴巨魔 +entity.twilightforest.giant_miner.name=巨人矿工 +entity.twilightforest.armored_giant.name=武装巨人 +entity.twilightforest.ice_crystal.name=冰晶 +entity.twilightforest.rising_zombie.name=僵尸 +entity.twilightforest.apocalypse_cube.name=天启立方【未实现】 +entity.twilightforest.adherent.name=信徒【未实现】 +entity.twilightforest.castle_guardian.name=城堡守卫【未实现】 + +twilightforest.effect.frosted=冻结 + +twilightforest.misc.wip0=这个方块仍在制作当中,可能会有能导致存档损坏的 Bug 或不可预料的特性。 +twilightforest.misc.wip1=测试时时刻保持注意。 +twilightforest.misc.nyi=这个方块的部分特性尚未完成。 + +twilightforest.loading.title.enter=正在前往暮色森林…… +twilightforest.loading.title.leave=正在离开暮色森林…… + +#Config +twilightforest.config.dimension=维度设定 +twilightforest.config.dimension.tooltip=这些设定只有在重启后才会生效。 +twilightforest.config.dimension_id=维度 ID +twilightforest.config.dimension_id.tooltip=暮色森林的维度 ID。如果遇到暮色森林和其他 Mod 因此冲突,可在此修改。 +twilightforest.config.dimension_seed=生成种子 +twilightforest.config.dimension_seed.tooltip=设定后会使用给定种子来生成暮色森林维度;默认情况下使用和主世界的地图种子。 +twilightforest.config.spawn_in_tf=新玩家出生于暮色森林 +twilightforest.config.spawn_in_tf.tooltip=启用后,新玩家会直接出生在暮色森林,而不是主世界中。 +twilightforest.config.skylight_forest=天空中的暮色森林【开发中】 +twilightforest.config.skylight_forest.tooltip=启用后,暮色森林将以空岛的风格生成,只在虚空中生成主要建筑。 +twilightforest.config.skylight_oaks=天空中的橡树【开发中】 +twilightforest.config.skylight_oaks.tooltip=启用后,暮色橡树也会在虚空中生成。 + +twilightforest.config.world_gen_weights=世界生成权重 +twilightforest.config.world_gen_weights.tooltip=调整各种世界生成特性的生成权重。 +twilightforest.config.stone_circle_weight=圆石阵权重 +twilightforest.config.well_weight=水井权重 +twilightforest.config.stalagmite_weight=石笋权重 +twilightforest.config.foundation_weight=地基遗迹权重 +twilightforest.config.monolith_weight=黑曜石柱权重 +twilightforest.config.grove_ruins_weight=树丛遗迹权重 +twilightforest.config.hollow_stump_weight=空心树墩权重 +twilightforest.config.fallen_hollow_log_weight=倒下的空心木头权重 +twilightforest.config.fallen_small_log_weight=倒下的小树权重 +twilightforest.config.druid_hut_weight=德鲁伊小屋权重 + +twilightforest.config.hollow_hill_stalactites=自定义矿山钟乳石生成 +twilightforest.config.hollow_hill_stalactites.tooltip=在这里你可以自定义矿山生成的矿物钟乳石类型。\n格式如下:“modid:block<:meta> [尺寸] [最大长度] [最低生成高度] [权重]”,其中各项参数为:\n尺寸 - 钟乳石柱的长度,以矿山高度(矿山内部地面到顶部)衡量。\n最大长度 - 钟乳石柱的最大长度,以方块数量衡量\n最低生成高度 - 最低允许的钟乳石生成位置距离矿山内部地面的距离,低于这个高度时不生成。\n权重 - 决定生成频率。\n\n例如:minecraft:iron_ore 0.7 8 1 24 会增加一次和默认的铁矿石柱一样的生成。 +twilightforest.config.large_hill=大矿山 +twilightforest.config.large_hill.tooltip=定义只在大矿山中以钟乳石柱的形式生成的方块。 +twilightforest.config.medium_hill=中矿山和大矿山 +twilightforest.config.medium_hill.tooltip=定义只在中矿山和大矿山中以钟乳石柱的形式生成的方块。 +twilightforest.config.small_hill=所有矿山 +twilightforest.config.small_hill.tooltip=定义在所有尺寸的矿山中以钟乳石柱的形式生成的方块。 +twilightforest.config.stalactite_config_only=仅使用配置定义的生成 +twilightforest.config.stalactite_config_only.tooltip=启用后,默认的生成和其他 Mod 添加的生成都不会使用,只使用配置文件中定义的生成。 + +twilightforest.config.compat=对其他 Mod 兼容 +twilightforest.config.compat.tooltip=是否加载暮色森林对其他 Mod 的兼容?遇到崩溃时,或者不想要兼容时,请禁用此选项。 + +twilightforest.config.performance=性能 +twilightforest.config.performance.tooltip=这些选项可用于牺牲各种特性以换取更好的性能。 +twilightforest.config.canopy_coverage=树冠覆盖范围 +twilightforest.config.canopy_coverage.tooltip=树冠覆盖的区域的大小。该项数值越小,森林会越稀薄,但区块生成速度会因此加快。 +twilightforest.config.twilight_oaks=暮色橡树生成概率 +twilightforest.config.twilight_oaks.tooltip=暮色森林维度的每一个区块中生成暮色橡树的概率。该项数值越大,生成概率就越小,性能也会因此提升。 +twilightforest.config.leaves_light_opacity=暮色树叶不透明度 +twilightforest.config.leaves_light_opacity.tooltip=若树叶不是全方块,此选项可控制树叶阻挡光线的程度。 +twilightforest.config.glacier_packed_ice=冰川由浮冰组成 +twilightforest.config.glacier_packed_ice.tooltip=启用后,暮色冰川将全部由浮冰组成,其不透光的性质可帮助降低冰川附近的光照计算量。 +twilightforest.config.enable_skylight=启用天空光照 +twilightforest.config.enable_skylight.tooltip=决定暮色森林维度中的方块是否有基于每个方块的天空光照数据。禁用此选项可极大提升世界生成的性能,但代价是没有阴影的平整光照。\n警告:一旦区块在没有天空光照的情况下加载,相应的数据也会一并丢失且难以恢复,请小心操作! + +twilightforest.config.silent_cicadas=禁止蝉鸣 +twilightforest.config.silent_cicadas.tooltip=若声音库出现问题,或者只是觉得蝉很吵,可考虑启用此项。 + +twilightforest.config.first_person_effects=渲染第一人称视角特效 +twilightforest.config.first_person_effects.tooltip=控制暮色森林的诸多特效是否在第一人称视角下显示。觉得很烦的话可以关闭。 + +twilightforest.config.origin_dimension=始发维度 +twilightforest.config.origin_dimension.tooltip=默认使用的能在暮色森林之间往返的维度,默认为原版主世界。 +twilightforest.config.portals_in_other_dimensions=非主世界建造暮色传送门 +twilightforest.config.portals_in_other_dimensions.tooltip=允许在主世界之外的维度建造暮色森林传送门,某些情况下可视作作弊。 +twilightforest.config.admin_portals=仅管理员可使用暮色传送门 +twilightforest.config.admin_portals.tooltip=传送门将只向管理员开放。开启后可大幅降低本 Mod 搜索有效传送门位置的范围。 +twilightforest.config.portals=禁用暮色传送门 +twilightforest.config.portals.tooltip=完全禁用暮色森林传送门;本选项适用于需要严格限制的服务器管理员。 +twilightforest.config.portal_creator=传送门建造物品 +twilightforest.config.portal_creator.tooltip=建造暮色传送门时使用的物品的注册 ID,格式为 domain:regname:meta,其中 meta 部分可不写。 +twilightforest.config.portal_lighting=建造传送门时引发闪电 +twilightforest.config.portal_lighting.tooltip=启用后,建造传送门的时候会有闪电击中传送门方块,同时令周围方块起火。为不苟言笑的人准备的选项。 +twilightforest.config.portal_return=是否生成双向传送门 +twilightforest.config.portal_return.tooltip=禁用后,返回的传送门需要额外的传送门建造物品。 +twilightforest.config.check_portal_destination=传送门目的地预检查 +twilightforest.config.check_portal_destination.tooltip=决定生成传送门时是否应检查目的地是否安全。启用后,新传送门会在目的地不安全时拒绝生成,而不是重定向到一个别的安全目的地。\n注意,启用此选项后也会降低传送门生成检查频率。 + +twilightforest.config.progression_default=默认进度规则 +twilightforest.config.progression_default.tooltip=设定强制进度的游戏规则的默认值。 + +twilightforest.config.uncrafting=禁用拆解台的拆解功能 +twilightforest.config.uncrafting.tooltip=禁用拆解台的拆解功能,可用于防止利用某些合成刷物品。 + +twilightforest.config.antibuilder_blacklist=反建器黑名单 +twilightforest.config.antibuilder_blacklist.tooltip=反建器黑名单。格式:domain:block:meta;其中 meta 为可选项。 + +twilightforest.config.animate_trophyitem=战利品头颅旋转 +twilightforest.config.animate_trophyitem.tooltip=启用后,战利品中的头颅会旋转。对性能没有影响。为不苟言笑的人准备的选项。 + +twilightforest.config.shield_parry=盾牌反弹 +twilightforest.config.shield_parry.tooltip=我们推荐安装 Shield Parry 这个 Mod 来实现一样的效果,但如果你没装,这些便是可供调整的选项。 +twilightforest.config.parry_non_twilight=反弹非暮色森林弹射物 +twilightforest.config.parry_non_twilight.tooltip=启用后,盾牌可以反弹不是暮色森林特有的弹射物。我们推荐安装 Shield Parry 这个 Mod 来实现一样的效果。 +twilightforest.config.parry_window_arrow=箭矢反弹时间 +twilightforest.config.parry_window_arrow.tooltip=要使盾牌反弹箭矢所需要的持盾时间,以刻(tick)为单位,20 tick 为一秒。 +twilightforest.config.parry_window_fireball=火焰弹反弹时间 +twilightforest.config.parry_window_fireball.tooltip=要使盾牌反弹火焰弹所需要的持盾时间,以刻(tick)为单位,20 tick 为一秒。 +twilightforest.config.parry_window_throwable=其他弹射去反弹时间 +twilightforest.config.parry_window_throwable.tooltip=要使盾牌反弹其他弹射物所需要的持盾时间,以刻(tick)为单位,20 tick 为一秒。 +twilightforest.config.shieldParryTicksBeam=激光反弹时间??? +twilightforest.config.shieldParryTicksBeam.tooltip=??? + +twilightforest.config.loading_screen=加载界面 +twilightforest.config.loading_screen.tooltip=客户端专有选项,用于控制进入暮色森林时的加载界面。 +twilightforest.config.loading_icon_enable=启用加载图标动画 +twilightforest.config.loading_icon_enable.tooltip=让加载图标动起来。对性能没有影响。为不苟言笑的人准备的选项。 +twilightforest.config.loading_screen_swap_frequency=加载界面切换 +twilightforest.config.loading_screen_swap_frequency.tooltip=界面切换之间的时间间隔,设定为 0 将使其不会切换。 +twilightforest.config.loading_icon_wobble_bounce_frequency=图标动画速度 +twilightforest.config.loading_icon_wobble_bounce_frequency.tooltip=弹跳和晃动的频率。 +twilightforest.config.loading_icon_scale=图标缩放 +twilightforest.config.loading_icon_scale.tooltip=整个弹跳的图标的尺寸。 +twilightforest.config.loading_icon_bounciness=图标弹跳幅度 +twilightforest.config.loading_icon_bounciness.tooltip=地图加载过程中,图标弹跳的幅度。 +twilightforest.config.loading_icon_tilting=图标晃动幅度 +twilightforest.config.loading_icon_tilting.tooltip=地图加载过程中,图标晃动的幅度。 +twilightforest.config.loading_icon_tilt_pushback=图标倾斜度偏移 +twilightforest.config.loading_icon_tilt_pushback.tooltip=重新令图标居中所使用的后移量。 + +# Books +twilightforest.book.lichtower.1=§8[[被野兽啃坏的探险家笔记]]§0\n\n我开始了对这塔周围奇怪气场的测试。塔身的每一块砖都受一种强力魔咒的保护,这么强大的力量我还是头一次见到。这魔咒甚至还能覆盖塔周围的区域。 +twilightforest.book.lichtower.2=换做是在我的故乡,我有很多对付此类魔法的方法,但是我在这里没多少补给。让我来深入研究一下…… +twilightforest.book.lichtower.3=§8[[若干篇后]]§0\n\n重大进展!我在旅途中看见了一种蛇形的巨兽,它被困在了装饰考究的“庭院”里。当时我捡起了一根破旧的羽毛,忽略了那些绿色的鳞片。 +twilightforest.book.lichtower.4=事实证明,这些绿色的鳞片有我需要的破除魔咒的魔力属性,但是这魔力太过于微弱,我需要直接干掉那个蛇形巨兽,以此拿到更新鲜的样品。 + +twilightforest.book.labyrinth.1=§8[[写在防水纸上的探险家笔记]]§0\n\n沼泽里的蚊群惹人烦,但仍然显得可疑。看上去它们并非自然生物,细细想来也找不出它们在当地生态系统中的作用。 +twilightforest.book.labyrinth.2=我觉得这是某种魔咒。\n\n§8[[下一篇]]§0\n\n现在有一道保护符咒挡住了通往迷宫废墟的路。我觉得我的猜测是正确的。 +twilightforest.book.labyrinth.3=保护符咒和蚊群其实是同一个魔咒,但我觉得我从未见过有什么魔咒有和它一样的来源。让我继续研究下…… \n\n§8[[下一篇]]§0 +twilightforest.book.labyrinth.4=这魔咒看上去强大到了一人无法独自完成的地步,须得是数名巫师同时发力方能完成。\n\n只要这其中一名巫师停止发力,整个魔咒都会因此失效。 +twilightforest.book.labyrinth.5=但是,我自己占卜的结果显示附近并没有巫师居住。倒是附近有一座酷似哥特风格的高塔吸引了我的注意…… + +twilightforest.book.hydralair.1=§8[[写在耐火纸上的探险家笔记]]§0\n\n区区火焰并不能阻挡像我这样的探险家。我也曾下过火海,并在熔岩组成的海洋中游泳。这燃烧的空气倒是很有趣,但终究还不是我的对手。 +twilightforest.book.hydralair.2=最终挡住我前进脚步的是另一个保护符咒——这次的保护对象应当是一种强大到足以统治这火焰沼泽的怪物。 +twilightforest.book.hydralair.3=这当然不是我第一次遇到保护符咒,我渐渐开始解开这符咒背后的谜团了。\n\n如果我的猜测——这些符咒的工作方式高度相似——是成立的,那么这附近就能找到维持符咒法力的强大怪物。火焰沼泽周围是若干湿地,这些湿地则掩埋了一个充斥着牛头人(也有管叫米诺陶的)的迷宫。 +twilightforest.book.hydralair.4=唯一符合逻辑的推测是,这群牛头人里有一种不同寻常的特殊品种,与普通牛头人相比更为强力,但外貌上有所不同…… + +twilightforest.book.tfstronghold.1=§8[[探险家笔记,其纸张微微发光]]§0\n\n笼罩在黑暗森林上的保护符咒以黑暗触手的形式呈现。这个符咒会造成任何闯入的人失明,对探险家来说可谓是令人抓狂。 +twilightforest.book.tfstronghold.2=不过我有我预定的计划要完成。\n\n§8[[下一篇]]§0我在黑暗森林中发现了废墟。这是一种要塞的废墟,而这种要塞的主人通常来说是骑士。 +twilightforest.book.tfstronghold.3=然而,这个要塞废墟是个例外:迎接我的是成群的哥布林。它们身着骑士盔甲,但是它们的行为暗示了它们并非骑士。§8[[下一篇]]§0\n\n废墟深处有个基座。看样子是骑士们用来放奖杯的基座——这是力量的象征。 +twilightforest.book.tfstronghold.4=若能拿到某种强力法杖,我便可以削弱这保护森林的魔咒,而将某座奖杯放在这基座上 +twilightforest.book.tfstronghold.5=便可打开通往要塞的门。 + +twilightforest.book.darktower.1=§8[[疑似从爆炸中生还的探险家笔记]]§0\n\n这塔里的机关显然不受我控制。我几乎是要触碰到机关所蕴含的魔力了,但是就差那么一点。只有一种解释:这机关被附近什么东西的力量压制住了。 +twilightforest.book.darktower.2=§8[[下一篇]]§0\n\n这力量的来源似乎是附近要塞深处散发出的魔法能量。这魔力不可能是哥布林的,因为这魔力虽然吸引人,但并非集中在一起。 +twilightforest.book.darktower.3=要塞里肯定还有什么东西。\n\n§8[[下一篇]]§0\n\n根据我的分析,这股魔力有数股来源,这些来源一个整体的形式工作。让我先等补给过来再说…… + +twilightforest.book.yeticave.1=§8[[封面结霜的探险家笔记]]§0\n\n雪地周围刮着永不停息的暴风雪。这可不是普通的雪——这是一种魔咒。我得做个实验把这暴风雪的源头找出来。 +twilightforest.book.yeticave.2=§8[[下一篇]]§0\n\n这魔咒看上去强大到了一人无法独自完成的地步,须得是数名巫师同时发力方能完成。\n\n只要这其中一名巫师停止发力,整个魔咒都会因此失效。 +twilightforest.book.yeticave.3=但是,我自己占卜的结果显示附近并没有巫师居住。倒是附近有一座酷似哥特风格的高塔吸引了我的注意…… + +twilightforest.book.icetower.1=§8[[冰封的探险家笔记]]§0\n\n我确实冲破了一道暴风雪的阻拦,但随即又被这冰川上的寒冰风暴挡住了。在探险途中,我看到了一座金碧辉煌的冰宫,它散发的光芒有如极光一样五彩缤纷。 +twilightforest.book.icetower.2=看上去是有魔咒的保护。\n\n§8[[下一篇]]§0\n\n我也不再是那个懵懂无知的新人了。这魔咒的力量肯定来自附近的生物,就像火焰沼泽附近的牛头人的首领为火焰沼泽的魔咒提供了魔力一样。 +twilightforest.book.icetower.3=在这冰川周围,住着一群雪怪。雪怪也应该有个带头的对吧…… + +twilightforest.book.trollcave.1=§8[[被酸腐蚀过的探险家笔记]]§0\n\n我觉得我不可能在这样的剧毒暴风雨中生还。我曾在一次短暂的远行中遇到过类似的保护符咒。 +twilightforest.book.trollcave.2=这符咒一定和剧毒风暴有什么关系。需要进一步研究……\n\n§8[[下一篇]]§0\n\n这种强大的天气魔法一定是若干我还没击败的大魔王的力量合为一道的结果。 +twilightforest.book.trollcave.3=我目前收集到的线索指向了这样几个地方:炽热的沼泽、暗无天日的森林以及冰雪覆盖的领域。 + +twilightforest.book.unknown.1=§8[[一本看上去被传抄了无数遍的书]]§0\n\n我的学识实在不足以解释这建筑周围的力场是怎么回事,我只能说这是一种强力魔法。如果这魔咒和之前的魔咒的原理一样,那么我应该在别的地方寻找答案。 +twilightforest.book.unknown.2=也许我还有什么事情没有做,抑或我还没击败什么怪物。我想是时候掉头回去了。当然,我会回来看看看有没有新进展的。 + +# Fluid + +fluid.fierymetal=熔融炽铁 +fluid.knightmetal=熔融骑士金属 +fluid.fiery_essence=炽血精华 + +# TCon + +material.nagascale.name=娜迦鳞片 +material.steeleaf.name=钢叶 +material.fierymetal.name=炽铁 +material.knightmetal.name=骑士金属 +material.raven_feather.name=暗鸦之羽 + +modifier.twilit.name=暮光 +modifier.twilit.desc=§o那微弱的光芒便是暮色森林的祝福。§r\n在暮色森林里速度更快。\n在暮色森林外伤害更高。 +modifier.twilit.extra.speed=在暮色森林内采掘速度 +%s +modifier.twilit.extra.damage=在暮色森林外伤害提升 +%s +modifier.precipitate.name=积淀 +modifier.precipitate.desc=§o最后的逃亡计划。§r\n你的生命值越少,它就越快! +modifier.synergy.name=同调 +modifier.synergy.desc=§o看!没有苔藓!§r\n物品栏里有钢叶的时候会自我修复。 +modifier.stalwart.name=坚毅 +modifier.stalwart.desc=§o勇猛无畏。§r\n击中敌人让你壮胆。 +modifier.veiled.name=遁形 +modifier.veiled.desc=§o就像观察者!§r\n弹射物将会隐形。 + +# Immersive Engineering +item.tfEngineeringShader=暮色皮肤:%s +item.tfEngineeringShaderBag=%s暮色皮肤奖励袋 + +twilightforest.shader.twilight=暮色 + +twilightforest.shader.snakestone=娜迦石 +twilightforest.shader.naga=娜迦 +twilightforest.shader.lich=巫妖 + +twilightforest.shader.mazestone=迷宫石 +twilightforest.shader.minoshroom=米诺菇 +twilightforest.shader.hydra=九头蛇 + +twilightforest.shader.underbrick=地下砖 +twilightforest.shader.knight_phantom=幻影骑士 +twilightforest.shader.towerwood=塔木 +twilightforest.shader.ur-ghast=暮色恶魂 + +twilightforest.shader.alpha_yeti=雪怪首领 +twilightforest.shader.auroralized=极光 +twilightforest.shader.snow_queen=冰雪女王 + +twilightforest.shader.final_castle=终焉城堡 diff --git a/src/main/resources/assets/twilightforest/lang/zh_tw.lang b/src/main/resources/assets/twilightforest/lang/zh_tw.lang new file mode 100644 index 0000000000..6f4d83e826 --- /dev/null +++ b/src/main/resources/assets/twilightforest/lang/zh_tw.lang @@ -0,0 +1,708 @@ +#PARSE_ESCAPES + +itemGroup.twilightForest=暮光森林 + +# ADVANCEMENTS +advancement.twilightforest.root.desc=前往那神秘的魔法林地——暮光森林! + +# General progression +advancement.twilightforest.hedge=爬蟲踐踏者 +advancement.twilightforest.hedge.desc=在樹籬迷宮殺死一隻蜘蛛。 + +advancement.twilightforest.hill1=靴子是我的! +advancement.twilightforest.hill1.desc=在小型礦山裡擊敗一個紅帽哥布林。 +advancement.twilightforest.hill2=這是什麼噪音? +advancement.twilightforest.hill2.desc=在中型礦山裡擊敗一個紅帽地精。 +advancement.twilightforest.hill3=我看到你了 +advancement.twilightforest.hill3.desc=在大型礦山裡擊敗一個暮光幽靈。 + +advancement.twilightforest.quest_ram=博學的羊 +advancement.twilightforest.quest_ram.desc=將缺失的東西轉交給謎題羊。 + +# Map +advancement.twilightforest.magic_map_focus=用火書寫 +advancement.twilightforest.magic_map_focus.desc=用烏鴉羽毛、螢石粉、火炬漿果合成魔法地圖核心。 +advancement.twilightforest.magic_map=我可以看到千里之外 +advancement.twilightforest.magic_map.desc=合成魔法地圖。 +advancement.twilightforest.maze_map=現在,尋找出口 +advancement.twilightforest.maze_map.desc=從哥布林身上獲取用來合成迷宮地圖的核心,並用其來合成迷宮地圖。 +advancement.twilightforest.ore_map=這怎麼可能呢? +advancement.twilightforest.ore_map.desc=合成迷宮/礦石地圖。 + +# Mainline beginning progression +advancement.twilightforest.twilight_hunter=森林的沉默 +advancement.twilightforest.twilight_hunter.desc=獵殺一些暮色的野生動物。 + +advancement.twilightforest.kill_naga=是時候擺平天枰了 +advancement.twilightforest.kill_naga.desc=獵殺森林角落裡的那伽,取得可以幫你突破巫妖塔魔法壁壘的那伽鱗片。 +advancement.twilightforest.naga_armors=那伽鍛甲師 +advancement.twilightforest.naga_armors.desc=合成那伽鱗胸甲和護腿。 + +advancement.twilightforest.kill_lich=帶出你的死亡 +advancement.twilightforest.kill_lich.desc=擊敗塔頂的巫妖,借助他留下的巫妖權杖的魔法來驅散沼澤中的毒蚊。 +advancement.twilightforest.lich_scepters=由我們的力量相結合! +advancement.twilightforest.lich_scepters.desc=獲得所有三個權杖的力量。 + +# Swamp Progression +advancement.twilightforest.progress_labyrinth=強力的牛頭人醬肉 +advancement.twilightforest.progress_labyrinth.desc=在吃下迷宮中找到的牛頭人醬肉後,你覺得你適應了足夠的風險前往火焰沼澤的准備。 +advancement.twilightforest.kill_hydra=九頭蛇殺手 +advancement.twilightforest.kill_hydra.desc=獵殺強大的九頭蛇﹔你在經過它的試煉後,便能抵抗黑暗森林的失明詛咒。 +advancement.twilightforest.mazebreaker=破壞迷宮 +advancement.twilightforest.mazebreaker.desc=在迷宮的秘密房間中找到迷宮破壞者鎬。 +advancement.twilightforest.hydra_chop=九頭蛇肉排,寶貝! +advancement.twilightforest.hydra_chop.desc=當你的飽食度是空的時候,吃一些會吃得過飽的九頭蛇肉。 + +# Dark Forest Progression +advancement.twilightforest.progress_trophy_pedestal=得獎的冠軍 +advancement.twilightforest.progress_trophy_pedestal.desc=將獎杯放置於黑暗森林遺跡中的獎杯基座上,並獲得你的頭銜。 +advancement.twilightforest.progress_knights=號令砷鉛鐵機關 +advancement.twilightforest.progress_knights.desc=令騎士之墓的幻影安息,之後你將能控制高塔中的砷鉛鐵機關。 +advancement.twilightforest.ghast_trap=高塔裡奇怪的東西 +advancement.twilightforest.ghast_trap.desc=在一個幽靈陷阱周圍殺死幽靈,啟動以從天空拉下暮光幽靈! +advancement.twilightforest.progress_ur_ghast=火之淚 +advancement.twilightforest.progress_ur_ghast.desc=觸碰暮光惡魂那熾紅的眼淚,它的熱量可以幫你抵抗冰雪森林的寒冷。 + +advancement.twilightforest.experiment_115=神秘的肉? +advancement.twilightforest.experiment_115.desc=儘管它看起來像蛋糕…… +advancement.twilightforest.experiment_115_2=做個記錄:大勝利! +advancement.twilightforest.experiment_115_2.desc=鬆軟,美味! +advancement.twilightforest.experiment_115_3=每天都吃115,堅持115年,一刻不要停 +advancement.twilightforest.experiment_115_3.desc=每天都吃實驗物品1-1-5,不要停,115次實驗物品1-1-5,experiment1-1-5.com,www.experiment1-1-5.com,115年,每時每刻都來experiment1-1-5.com,www.1-1-5experiment1-1-5.com + +# Snow Forest Progression +advancement.twilightforest.progress_yeti=首領的毛皮 +advancement.twilightforest.progress_yeti.desc=披上雪怪首領鬆軟的毛皮,籍此抵抗冰川裡那刺骨的寒風。 +advancement.twilightforest.progress_glacier=澄澈之空 +advancement.twilightforest.progress_glacier.desc=擊敗極光宮殿裡的冰雪女王,籍此驅散高地上空的酸雨。 +advancement.twilightforest.arctic_dyed=進入時尚 +advancement.twilightforest.arctic_dyed.desc=把四件北極盔甲染色。 + +# Mid-way Misc. Stuff +advancement.twilightforest.glass_sword=一命中奇蹟 +advancement.twilightforest.glass_sword.desc=希望你好好利用。 + +advancement.twilightforest.twilight_dining=我們在永恆的日落用餐 +advancement.twilightforest.twilight_dining.desc=吃掉所有專屬暮光森林的食物。 + +advancement.twilightforest.fiery_set=血淚成河 +advancement.twilightforest.fiery_set.desc=身著至少一件熾熱金屬裝備時,手持熾熱金屬工具。 + +# Highlands +advancement.twilightforest.progress_merge=終極對決 +advancement.twilightforest.progress_merge.desc=殺死九頭蛇,高塔幽靈和冰雪女王,清除酸雨,為高地壯膽。 +advancement.twilightforest.progress_troll=讓烈焰燃燒得更猛烈些吧! +advancement.twilightforest.progress_troll.desc=在巨魔洞穴中找到餘燼之燈,用它來焚燒掉荊棘之牆。 +advancement.twilightforest.progress_thorns=穿越荊棘 +advancement.twilightforest.progress_thorns.desc=穿越荊棘之地,打開通往城堡的大門。 +advancement.twilightforest.progress_castle=這就是……城堡嗎…… +advancement.twilightforest.progress_castle.desc=這城堡裡究竟有什麼?! + +twilightforest.trophyPedestal.ineligible=你不配。 +twilightforest.ore_meter.range=半徑:%s,原點:[%s, %s] +twilightforest.ore_meter.exposed=已露出:%s +twilightforest.scepter_charges=剩下%d充能 + +# Commands +commands.tffeature.usage=用法:/tffeature +commands.tffeature.not_in_twilight_forest=你不在暮光森林維度中 +commands.tffeature.nearest=距離最近的區域是%s +commands.tffeature.center=中心的區域:%s +commands.tffeature.chunk=在區域的區塊中:%s +commands.tffeature.structure.inside=你在區域的建築物內 +commands.tffeature.structure.outside=你不在區域的建築物內 +commands.tffeature.structure.required=你不在建築物內 +commands.tffeature.structure.conquer.status=建築物征服旗幟:%s +commands.tffeature.structure.conquer.update=建築物征服旗幟原本是%s,改變至%s +commands.tffeature.locate.usage=用法:/tffeature locate <區域名稱> + +# Blocks +tile.twilightforest.Log.0.name=暮光橡木 +tile.twilightforest.Log.1.name=蒼穹木 +tile.twilightforest.Log.2.name=紅木 +tile.twilightforest.Log.3.name=黑木 +tile.twilightforest.Leaves.0.name=暮光橡木樹葉 +tile.twilightforest.Leaves.1.name=蒼穹樹葉 +tile.twilightforest.Leaves.2.name=紅樹樹葉 +tile.twilightforest.Leaves.3.name=彩虹橡木樹葉 +tile.twilightforest.Firefly.name=螢火蟲 +tile.twilightforest.Cicada.name=蟬 +tile.twilightforest.Cicada.desc=如果這個可以用軌道炮發射到某些人身上……? +item.twilightforest.Portal.name=暮光森林傳送門 +tile.twilightforest.Portal.name=暮光森林傳送門 +tile.twilightforest.Mazestone.0.name=迷宮石頭 +tile.twilightforest.Mazestone.1.name=迷宮石磚 +tile.twilightforest.Mazestone.2.name=鏨製迷宮石頭 +tile.twilightforest.Mazestone.3.name=裝飾迷宮石磚 +tile.twilightforest.Mazestone.4.name=破碎迷宮石磚 +tile.twilightforest.Mazestone.5.name=青苔迷宮石磚 +tile.twilightforest.Mazestone.6.name=迷宮石頭鑲嵌 +tile.twilightforest.Mazestone.7.name=迷宮石頭邊框 +tile.twilightforest.Mazestone.8.name=迷宮天花板 +tile.twilightforest.Hedge.0.name=樹籬 +tile.twilightforest.Hedge.1.name=黑樹樹葉 +tile.twilightforest.BossSpawner.0.name=生成 那伽 +tile.twilightforest.BossSpawner.1.name=生成 巫妖 +tile.twilightforest.BossSpawner.2.name=生成 九頭蛇 +tile.twilightforest.BossSpawner.3.name=生成 暮色惡魂 +tile.twilightforest.BossSpawner.4.name=生成 幻影騎士 +tile.twilightforest.FireflyJar.name=螢火蟲罐子 +tile.twilightforest.Plant.0.name=暮色森林苔蘚 +tile.twilightforest.Plant.1.name=鬼臼果 +tile.twilightforest.Plant.2.name=三葉草 [在製品] +tile.twilightforest.Plant.3.name=暮色森林蕨類 +tile.twilightforest.Plant.4.name=螢光蘑菇 +tile.twilightforest.Plant.5.name=林地草 +tile.twilightforest.Plant.6.name=枯死的灌木 +tile.twilightforest.Plant.7.name=火炬漿果植物 +tile.twilightforest.Plant.8.name=根須 +tile.twilightforest.Roots.0.name=根莖 +tile.twilightforest.Roots.1.name=活根 +tile.twilightforest.UncraftingTable.name=拆解台 +tile.twilightforest.FireJet.0.name=噴煙方塊 +tile.twilightforest.FireJet.1.name=被封閉的噴煙方塊 +tile.twilightforest.FireJet.2.name=被封閉的噴煙方塊 +tile.twilightforest.FireJet.3.name=火焰噴口 +tile.twilightforest.FireJet.4.name=噴射火焰噴口 +tile.twilightforest.FireJet.5.name=熾盛火焰噴口 +tile.twilightforest.FireJet.6.name=被封閉的火焰噴口 +tile.twilightforest.FireJet.7.name=被封閉的噴射火焰噴口 +tile.twilightforest.FireJet.8.name=被封閉的熾盛火焰噴口 +tile.twilightforest.Nagastone.0.name=那伽石頭顱 +tile.twilightforest.Nagastone.1.name=那伽石 +tile.twilightforest.Sapling.name=暮光樹苗 +tile.twilightforest.Sapling.0.name=暮光橡樹樹苗 +tile.twilightforest.Sapling.1.name=蒼穹樹樹苗 +tile.twilightforest.Sapling.2.name=紅樹樹樹苗 +tile.twilightforest.Sapling.3.name=黑樹樹樹苗 +tile.twilightforest.Sapling.4.name=高大暮光橡樹樹苗 +tile.twilightforest.Sapling.5.name=時光樹樹苗 +tile.twilightforest.Sapling.6.name=變化樹樹苗 +tile.twilightforest.Sapling.7.name=礦石樹樹苗 +tile.twilightforest.Sapling.8.name=分類樹樹苗 +tile.twilightforest.Sapling.9.name=彩虹樹樹苗 +tile.twilightforest.Moonworm.name=月光蠕蟲 +tile.twilightforest.MagicLog.0.name=時光樹原木 +tile.twilightforest.MagicLog.1.name=變化樹原木 +tile.twilightforest.MagicLog.2.name=礦石樹原木 +tile.twilightforest.MagicLog.3.name=分類樹原木 +tile.twilightforest.MagicLogSpecial.0.name=時光樹時鐘 +tile.twilightforest.MagicLogSpecial.1.name=變化樹心臟 +tile.twilightforest.MagicLogSpecial.2.name=礦石樹核心 +tile.twilightforest.MagicLogSpecial.3.name=分類樹引擎 +tile.twilightforest.MagicLeaves.0.name=時光樹樹葉 +tile.twilightforest.MagicLeaves.1.name=變化樹樹葉 +tile.twilightforest.MagicLeaves.2.name=礦石樹樹葉 +tile.twilightforest.MagicLeaves.3.name=分類樹樹葉 +tile.twilightforest.TowerStone.0.name=塔樹木材 +tile.twilightforest.TowerStone.1.name=密封塔木 +tile.twilightforest.TowerStone.2.name=破裂塔木 +tile.twilightforest.TowerStone.3.name=青苔塔木 +tile.twilightforest.TowerStone.4.name=蟲蛀塔木 +tile.twilightforest.TowerDevice.0.name=重現的方塊 +tile.twilightforest.TowerDevice.1.name=啟動的重現方塊 +tile.twilightforest.TowerDevice.2.name=消失的方塊 +tile.twilightforest.TowerDevice.3.name=啟動消失的方塊 +tile.twilightforest.TowerDevice.4.name=鎖定的消失的方塊 +tile.twilightforest.TowerDevice.5.name=解鎖的消失的方塊 +tile.twilightforest.TowerDevice.6.name=高塔建設者 +tile.twilightforest.TowerDevice.7.name=啟動的高塔建設者 +tile.twilightforest.TowerDevice.8.name=關閉的高塔建設者 +tile.twilightforest.TowerDevice.9.name=反建器 +tile.twilightforest.TowerDevice.10.name=可怕的陷阱 +tile.twilightforest.TowerDevice.11.name=啟動的可怕的陷阱 +tile.twilightforest.TowerDevice.12.name=砷鉛鐵反應堆 +tile.twilightforest.TowerDevice.13.name=啟動的砷鉛鐵反應堆 +tile.twilightforest.TowerTranslucent.0.name=再現方塊 +tile.twilightforest.TowerTranslucent.1.name=啟動的再現方塊 +tile.twilightforest.TowerTranslucent.2.name=建造的砷鉛鐵方塊 +tile.twilightforest.TowerTranslucent.3.name=啟動的建造的砷鉛鐵方塊 +tile.twilightforest.TowerTranslucent.4.name=反建方塊 +tile.twilightforest.TowerTranslucent.5.name=砷鉛鐵反應堆碎片 +tile.twilightforest.TowerTranslucent.6.name=偽金塊 +tile.twilightforest.TowerTranslucent.7.name=偽鑽石塊 +tile.twilightforest.Trophy.name=暮色森林戰利品 +tile.twilightforest.Shield.name=要塞護盾 +tile.twilightforest.TrophyPedestal.0.name=戰利品寶座 +tile.twilightforest.TrophyPedestal.15.name=隱藏的戰利品寶座 +tile.twilightforest.AuroraBrick.name=極光方塊 +tile.twilightforest.UnderBrick.0.name=地下磚 +tile.twilightforest.UnderBrick.1.name=青苔地下磚 +tile.twilightforest.UnderBrick.2.name=碎裂地下磚 +tile.twilightforest.UnderBrick.2.name=拋光地下磚 +tile.twilightforest.Thorns.brown.name=荊棘 +tile.twilightforest.Thorns.green.name=翠綠荊棘 +tile.twilightforest.BurntThorns.name=燒焦荊棘 +tile.twilightforest.ThornRose.name=荊棘玫瑰 +tile.twilightforest.Leaves3.0.name=荊棘葉 +tile.twilightforest.Leaves3.1.name=豆莖葉 +tile.twilightforest.Deadrock.surface.name=風化死岩 +tile.twilightforest.Deadrock.cracked.name=裂紋死岩 +tile.twilightforest.Deadrock.solid.name=死岩 +tile.twilightforest.DarkLeaves.name=黑樹樹葉 +tile.twilightforest.AuroraPillar.name=極光柱 +tile.twilightforest.AuroraSlab.name=極光台階 +tile.twilightforest.TrollSteinn.name=巨魔岩石 +tile.twilightforest.WispyCloud.name=薄雲 +tile.twilightforest.FluffyCloud.name=浮雲 +tile.twilightforest.GiantCobble.name=巨型圓石 +tile.twilightforest.GiantLog.name=巨型原木 +tile.twilightforest.GiantLeaves.name=巨型樹葉 +tile.twilightforest.GiantObsidian.name=巨型黑曜石 +tile.twilightforest.UberousSoil.name=肥沃泥土 +tile.twilightforest.HugeStalk.name=巨大的莖 +tile.twilightforest.HugeGloomBlock.name=巨型螢光蘑菇 +tile.twilightforest.TrollVidr.name=巨魔藤蔓 +tile.twilightforest.UnripeTrollBer.name=生巨魔莓 +tile.twilightforest.TrollBer.name=巨魔莓 +tile.twilightforest.TrollBer.name=巨魔莓 +tile.twilightforest.KnightmetalBlock.name=騎士金屬塊 +tile.twilightforest.HugeLilyPad.name=巨型睡蓮 +tile.twilightforest.HugeWaterLily.name=巨型荷花 +tile.twilightforest.Slider.0.name=滑動陷阱 +tile.twilightforest.Slider.1.name=滑動陷阱1 +tile.twilightforest.Slider.2.name=滑動陷阱2 +tile.twilightforest.Slider.3.name=滑動陷阱3 +tile.twilightforest.CastleBrick.0.name=城堡磚 +tile.twilightforest.CastleBrick.1.name=磨損城堡磚 +tile.twilightforest.CastleBrick.2.name=碎裂城堡磚 +tile.twilightforest.CastleBrick.3.name=城堡頂瓦 +tile.twilightforest.CastleBrick.4.name=青苔城堡磚 +tile.twilightforest.CastleBrick.5.name=粗厚城堡磚 +tile.twilightforest.CastleDoor.0.name=黃色城堡門 +tile.twilightforest.CastleDoor.1.name=紫色城堡門 +tile.twilightforest.CastleDoor.2.name=粉紅色城堡門 +tile.twilightforest.CastleDoor.3.name=藍色城堡門 +tile.twilightforest.CastleMagic.0.name=粉紅色城堡符文磚 +tile.twilightforest.CastleMagic.1.name=藍色城堡符文磚 +tile.twilightforest.CastleMagic.2.name=黃色城堡符文磚 +tile.twilightforest.CastleMagic.3.name=紫色城堡符文磚 +tile.twilightforest.CastlePillar.0.name=密封城堡磚支柱 +tile.twilightforest.CastlePillar.1.name=密封城堡磚瓦 +tile.twilightforest.CastlePillar.2.name=粗城堡磚支柱 +tile.twilightforest.CastlePillar.3.name=粗城堡磚瓦 +tile.twilightforest.CastleStairs.0.name=密封城堡磚階梯 +tile.twilightforest.CastleStairs.8.name=粗城堡磚階梯 +tile.twilightforest.ForceField.0.name=紫色力場 +tile.twilightforest.ForceField.1.name=粉紅色力場 +tile.twilightforest.ForceField.2.name=橙色力場 +tile.twilightforest.ForceField.3.name=綠色力場 +tile.twilightforest.ForceField.4.name=藍色力場 +tile.twilightforest.BlockOfStorage.0.name=鐵木磚 +tile.twilightforest.BlockOfStorage.1.name=熾熱金屬磚 +tile.twilightforest.BlockOfStorage.2.name=鋼葉磚 +tile.twilightforest.BlockOfStorage.3.name=極地毛皮磚 +tile.twilightforest.BlockOfStorage.4.name=砷鉛鐵磚 +tile.twilightforest.CinderFurnaceIdle.name=煤渣熔爐[尚無實作] +tile.twilightforest.CinderLog.name=煤渣原木[尚無實作] +tile.twilightforest.MiniatureStructure=縮小模型%s[尚無實作] +tile.twilightforest.SpiralBricks.name=螺旋石磚[在製品] +tile.twilightforest.BlockOfLapisTF.name=青金石磚[尚無實作] +tile.twilightforest.EtchedNagastone.name=蝕刻那伽石 +tile.twilightforest.NagastonePillar.name=那伽石支柱 +tile.twilightforest.NagastoneStairs.0.name=那伽石階梯(左) +tile.twilightforest.NagastoneStairs.8.name=那伽石階梯(右) +tile.twilightforest.EtchedNagastoneMossy.name=青苔蝕刻那伽石 +tile.twilightforest.NagastonePillarMossy.name=青苔那伽石支柱 +tile.twilightforest.NagastoneStairsMossy.0.name=青苔那伽石階梯(左) +tile.twilightforest.NagastoneStairsMossy.8.name=青苔那伽石階梯(右) +tile.twilightforest.EtchedNagastoneWeathered.name=破敗蝕刻那伽石 +tile.twilightforest.NagastonePillarWeathered.name=破敗那伽石支柱 +tile.twilightforest.NagastoneStairsWeathered.0.name=風化那伽石階梯(左) +tile.twilightforest.NagastoneStairsWeathered.8.name=風化那伽石階梯(右) + +structure.twilight_portal.name=暮光傳送門 +structure.hedge_maze.name=對沖迷宮 +structure.hollow_hill.name=空心山丘 +structure.quest_grove.name=尋求樹叢 +structure.mushroom_tower.name=蘑菇城堡 +structure.naga_courtyard.name=那伽庭院 +structure.lich_tower.name=巫妖塔 +structure.minotaur_labyrinth.name=牛頭人迷宮 +structure.hydra_lair.name=九頭蛇的巢穴 +structure.goblin_stronghold.name=哥布林要塞 +structure.dark_tower.name=黑塔 +structure.yeti_cave.name=雪人洞穴 +structure.aurora_palace.name=極光宮殿 +structure.troll_cave_and_cloud_castle.name=在雲裡的巨魔洞穴和房子 +structure.final_castle.name=終結城堡 + +item.twilightforest.nagaScale.name=那伽鱗片 +item.twilightforest.plateNaga.name=那伽胸甲 +item.twilightforest.legsNaga.name=那伽護腿 +item.twilightforest.scepterTwilight.name=黃昏權杖 +item.twilightforest.scepterLifeDrain.name=吸血權杖 +item.twilightforest.scepterZombie.name=殭屍權杖 +item.twilightforest.oreMeter.name=礦石感應儀 [在製品] +item.twilightforest.magicMap.name=魔法地圖 +item.twilightforest.mazeMap.name=迷宮地圖 +item.twilightforest.oreMap.name=迷宮/礦石地圖 +item.twilightforest.tfFeather.name=烏鴉羽毛 +item.twilightforest.magicMapFocus.name=魔法地圖核心 +item.twilightforest.mazeMapFocus.name=迷宮地圖核心 +item.twilightforest.liveRoot.name=活根 +item.twilightforest.ironwoodRaw.name=生鐵木原料 +item.twilightforest.ironwoodIngot.name=鐵木錠 +item.twilightforest.ironwoodHelm.name=鐵木頭盔 +item.twilightforest.ironwoodPlate.name=鐵木鎧甲 +item.twilightforest.ironwoodLegs.name=鐵木護腿 +item.twilightforest.ironwoodBoots.name=鐵木靴子 +item.twilightforest.ironwoodSword.name=鐵木劍 +item.twilightforest.ironwoodShovel.name=鐵木鏟 +item.twilightforest.ironwoodPick.name=鐵木鎬 +item.twilightforest.ironwoodAxe.name=鐵木斧 +item.twilightforest.ironwoodHoe.name=鐵木鋤 +item.twilightforest.torchberries.name=火炬漿果 +item.twilightforest.venisonRaw.name=生鹿肉 +item.twilightforest.venisonCooked.name=鹿肉排 +item.twilightforest.hydraChop.name=九頭蛇肉排 +item.twilightforest.fieryBlood.name=熾熱血 +item.twilightforest.fieryIngot.name=熾熱錠 +item.twilightforest.fieryHelm.name=熾熱頭盔 +item.twilightforest.fieryPlate.name=熾熱胸甲 +item.twilightforest.fieryLegs.name=熾熱護腿 +item.twilightforest.fieryBoots.name=熾熱靴子 +item.twilightforest.fierySword.name=熾熱劍 +item.twilightforest.fieryPick.name=熾熱鎬 +item.twilightforest.steeleafIngot.name=鋼葉錠 +item.twilightforest.steeleafHelm.name=鋼葉頭盔 +item.twilightforest.steeleafPlate.name=鋼葉胸甲 +item.twilightforest.steeleafLegs.name=鋼葉護腿 +item.twilightforest.steeleafBoots.name=鋼葉靴 +item.twilightforest.steeleafSword.name=鋼葉劍 +item.twilightforest.steeleafShovel.name=鋼葉鏟 +item.twilightforest.steeleafPick.name=鋼葉鎬 +item.twilightforest.steeleafAxe.name=鋼葉斧 +item.twilightforest.steeleafHoe.name=鋼葉鋤 +item.twilightforest.minotaurAxe.name=米諾陶戰斧 +item.twilightforest.mazebreakerPick.name=迷宮破壞者 +item.twilightforest.transformPowder.name=轉換粉 +item.twilightforest.meefRaw.name=生牛頭人肉 +item.twilightforest.meefSteak.name=牛頭人肉排 +item.twilightforest.meefStroganoff.name=牛頭人醬肉 +item.twilightforest.mazeWafer.name=迷宮薄餅 +item.twilightforest.emptyMagicMap.name=空白魔法地圖 +item.twilightforest.emptyMazeMap.name=空白迷宮地圖 +item.twilightforest.emptyOreMap.name=空白迷宮/礦石地圖 +item.twilightforest.oreMagnet.name=礦石磁鐵 +item.twilightforest.crumbleHorn.name=瓦解之號角 +item.twilightforest.peacockFan.name=孔雀羽毛扇 +item.twilightforest.moonwormQueen.name=月光蠕蟲女王 +item.twilightforest.charmOfLife1.name=生命符咒 I +item.twilightforest.charmOfLife2.name=生命符咒 II +item.twilightforest.charmOfKeeping1.name=保管符咒 I +item.twilightforest.charmOfKeeping2.name=保管符咒 II +item.twilightforest.charmOfKeeping3.name=保管符咒 III +item.twilightforest.towerKey.name=塔鑰匙 +item.twilightforest.borerEssence.name=三化螟精華 +item.twilightforest.carminite.name=砷鉛鐵礦 +item.twilightforest.tf_trophy.name=%s戰利品 +item.twilightforest.trophy.hydra.name=九頭蛇戰利品 +item.twilightforest.trophy.naga.name=那伽戰利品 +item.twilightforest.trophy.lich.name=巫妖戰利品 +item.twilightforest.trophy.ur_ghast.name=暮光惡魂戰利品 +item.twilightforest.trophy.snow_queen.name=冰雪女王戰利品 +item.twilightforest.experiment115.name=試驗品115 +item.twilightforest.armorShards.name=裝甲碎片 +item.twilightforest.knightMetal.name=騎士金屬錠 +item.twilightforest.shardCluster.name=裝甲碎片堆 +item.twilightforest.knightlyHelm.name=騎士頭盔 +item.twilightforest.knightlyPlate.name=騎士胸甲 +item.twilightforest.knightlyLegs.name=騎士護腿 +item.twilightforest.knightlyBoots.name=騎士靴子 +item.twilightforest.knightlySword.name=騎士劍 +item.twilightforest.knightlyPick.name=騎士鎬 +item.twilightforest.knightlyAxe.name=騎士斧 +item.twilightforest.phantomHelm.name=幻影頭盔 +item.twilightforest.phantomPlate.name=幻影胸甲 +item.twilightforest.lampOfCinders.name=餘燼之燈 +item.twilightforest.fieryTears.name=熾熱之淚 +item.twilightforest.iceBomb.name=冰霜炸彈 +item.twilightforest.yetiHelm.name=雪怪角盔 +item.twilightforest.yetiPlate.name=雪怪皮衣 +item.twilightforest.yetiLegs.name=雪怪護腿 +item.twilightforest.yetiBoots.name=雪怪靴子 +item.twilightforest.alphaFur.name=雪怪首領毛皮 +item.twilightforest.arcticFur.name=極地毛皮 +item.twilightforest.arcticHelm.name=極地風帽 +item.twilightforest.arcticPlate.name=極地皮衣 +item.twilightforest.arcticLegs.name=極地護腿 +item.twilightforest.arcticBoots.name=極地靴子 +item.twilightforest.magicBeans.name=魔豆 +item.twilightforest.giantPick.name=巨人鎬 +item.twilightforest.giantSword.name=巨人劍 +item.twilightforest.tripleBow.name=三發弓 +item.twilightforest.seekerBow.name=追蹤弓 +item.twilightforest.iceBow.name=寒冰弓 +item.twilightforest.enderBow.name=終界弓 +item.twilightforest.iceSword.name=寒冰劍 +item.twilightforest.glassSword.name=玻璃劍 +item.twilightforest.knightmetalRing.name=騎士金屬環 +item.twilightforest.chainBlock.name=鏈錘 +item.twilightforest.cubeTalisman.name=立方護符 +item.twilightforest.cubeOfAnnihilation.name=湮滅立方 + +item.twilightforest.minotaurAxe.tooltip=蓄力時造成額外傷害 +item.twilightforest.knightlySword.tooltip=對有護甲的目標造成額外傷害 +item.twilightforest.knightlyPick.tooltip=對有護甲的目標造成額外傷害 +item.twilightforest.knightlyAxe.tooltip=對無護甲的目標造成額外傷害 +item.twilightforest.giantPick.tooltip=用於破壞巨型方塊 +item.twilightforest.fieryPick.tooltip=自動燒煉 +item.twilightforest.fierySword.tooltip=灼燒攻擊目標 +item.twilightforest.fieryHelm.tooltip=灼燒攻擊者 +item.twilightforest.fieryPlate.tooltip=灼燒攻擊者 +item.twilightforest.fieryLegs.tooltip=灼燒攻擊者 +item.twilightforest.fieryBoots.tooltip=灼燒攻擊者 +item.twilightforest.phantomHelm.tooltip=死亡永遠不會掉落 +item.twilightforest.phantomPlate.tooltip=死亡永遠不會掉落 +item.twilightforest.yetiHelm.tooltip=冰凍攻擊者 +item.twilightforest.yetiPlate.tooltip=冰凍攻擊者 +item.twilightforest.yetiLegs.tooltip=冰凍攻擊者 +item.twilightforest.yetiBoots.tooltip=冰凍攻擊者 + +item.twilightforest.arctic_armor.tooltip=像皮革裝備一樣可染色 + +entity.twilightforest.wild_boar.name=野豬 +entity.twilightforest.bighorn_sheep.name=大角山羊 +entity.twilightforest.deer.name=野鹿 +entity.twilightforest.redcap.name=紅帽 +entity.twilightforest.swarm_spider.name=集群蜘蛛 +entity.twilightforest.naga.name=那伽 +entity.twilightforest.naga_segment.name=那伽身體 +entity.twilightforest.skeleton_druid.name=骷髏德魯伊 +entity.twilightforest.hostile_wolf.name=憤怒的狼 +entity.twilightforest.wraith.name=幽靈 +entity.twilightforest.hedge_spider.name=樹籬蜘蛛 +entity.twilightforest.hydra.name=九頭蛇 +entity.twilightforest.hydra_head.name=九頭蛇頭 +entity.twilightforest.lich.name=巫妖 +entity.twilightforest.penguin.name=企鵝 +entity.twilightforest.tiny_bird.name=小鳥 +entity.twilightforest.squirrel.name=松鼠 +entity.twilightforest.bunny.name=兔子 +entity.twilightforest.raven.name=烏鴉 +entity.twilightforest.quest_ram.name=謎題羊 +entity.twilightforest.kobold.name=哥布林 +entity.twilightforest.boggard.name=博加德 [尚無實作] +entity.twilightforest.lich_minion.name=巫妖的僕從 +entity.twilightforest.loyal_zombie.name=忠誠的僵屍 +entity.twilightforest.mosquito_swarm.name=蚊群 +entity.twilightforest.death_tome.name=死靈書 +entity.twilightforest.minotaur.name=米諾陶 +entity.twilightforest.minoshroom.name=米諾菇 +entity.twilightforest.fire_beetle.name=噴火甲蟲 +entity.twilightforest.slime_beetle.name=粘液甲蟲 +entity.twilightforest.pinch_beetle.name=夾蟲 +entity.twilightforest.maze_slime.name=迷宮史萊姆 +entity.twilightforest.redcap_sapper.name=紅帽地精 +entity.twilightforest.mist_wolf.name=迷霧狼 +entity.twilightforest.king_spider.name=國王蜘蛛 +entity.twilightforest.firefly.name=螢火蟲 +entity.twilightforest.mini_ghast.name=迷你幽靈 +entity.twilightforest.tower_ghast.name=高塔幽靈 +entity.twilightforest.tower_golem.name=高塔鐵傀儡 +entity.twilightforest.tower_termite.name=高塔螟 +entity.twilightforest.tower_broodling.name=寄生蟲 +entity.twilightforest.ur_ghast.name=暮色惡魂 +entity.twilightforest.blockchain_goblin.name=鏈錘哥布林 +entity.twilightforest.goblin_knight_upper.name=哥布林騎士(上身) +entity.twilightforest.goblin_knight_lower.name=哥布林騎士(下身) +entity.twilightforest.helmet_crab.name=寄居蟹 +entity.twilightforest.knight_phantom.name=幻影騎士 +entity.twilightforest.yeti.name=雪怪 +entity.twilightforest.yeti_alpha.name=雪怪首領 +entity.twilightforest.winter_wolf.name=寒冬狼 +entity.twilightforest.snow_guardian.name=冰雪守衛 +entity.twilightforest.stable_ice_core.name=冰精靈 +entity.twilightforest.unstable_ice_core.name=破碎冰精靈 +entity.twilightforest.snow_queen.name=冰雪女王 +entity.twilightforest.troll.name=洞穴巨魔 +entity.twilightforest.giant_miner.name=巨人礦工 +entity.twilightforest.armored_giant.name=武裝巨人 +entity.twilightforest.ice_crystal.name=冰晶 +entity.twilightforest.apocalypse_cube.name=天啟立方 [尚無實作] +entity.twilightforest.adherent.name=信徒 [尚無實作] +entity.twilightforest.castle_guardian.name=城堡衛士 [尚無實作] + +twilightforest.effect.frosted=結霜 + +twilightforest.misc.wip0=這個方塊仍在研製中,可能有錯誤或意想不到的效果,可能會損害你的世界。 +twilightforest.misc.wip1=謹慎使用。 +twilightforest.misc.nyi=該方塊具有尚未實現的效果。 + +twilightforest.loading.title.enter=正在把你送到暮光森林…… +twilightforest.loading.title.leave=正在把你送出暮光森林…… + +#Config +twilightforest.config.dimension=維度設定 +twilightforest.config.dimension.tooltip=沒有某種重新啟動,您將無法更改這些設定。 +twilightforest.config.dimension_id=維度ID +twilightforest.config.dimension_id.tooltip=分配給暮光森林維度的ID號碼。如果與另一個模組發生衝突則更改。 +twilightforest.config.dimension_seed=維度種子 +twilightforest.config.dimension_seed.tooltip=如果設定,這將在生成暮光森林維度的部分時覆蓋正常的世界種子。 +twilightforest.config.spawn_in_tf=在暮光森林出生 +twilightforest.config.spawn_in_tf.tooltip=若是,第一次重生的玩家們會重生在暮光森林裡。 + +twilightforest.config.compat=相容性 +twilightforest.config.compat.tooltip=是否加載暮光森林相容性?如果暮光森林的相容性導致崩潰或不需要,請關閉。 + +twilightforest.config.performance=效能調整 +twilightforest.config.performance.tooltip=讓你犧牲各種東西來改善世界的表現。 +twilightforest.config.canopy_coverage=冠層覆蓋率 +twilightforest.config.canopy_coverage.tooltip=樹冠覆蓋數量。較低的數字以較薄的森林為代價提高了方塊的生成速度。 +twilightforest.config.twilight_oaks=暮光橡樹機率 +twilightforest.config.twilight_oaks.tooltip=暮光森林中的一個區塊會包含的暮光橡樹。更高的數字減少了樹木的數量,提高了效能。 +twilightforest.config.leaves_light_opacity=暮光樹葉不透明度 +twilightforest.config.leaves_light_opacity.tooltip=如果樹葉不是滿的立方體,這控制葉子的不透明度來控制遮光量。 +twilightforest.config.leaves_full_cube=暮光樹葉是否完全的方塊 +twilightforest.config.leaves_full_cube.tooltip=設定否會使樹葉不完全。這樣就不會阻擋光線,使它們在阻擋光線方面等同於玻璃。減少一些照明檢查的複雜性。 +twilightforest.config.glacier_packed_ice=由冰磚製成的冰川而不是冰 +twilightforest.config.glacier_packed_ice.tooltip=設定為是將使暮光冰川由冰磚生成,而不是普通的半透明的冰,減少檢查計算光量。 + +twilightforest.config.silent_cicadas=沉默的蟬 +twilightforest.config.silent_cicadas.tooltip=讓蟬保持沉默,為那些有音效函式庫問題,或者發現牠們很煩人的人而設。 + +twilightforest.config.portals_in_other_dimensions=在其它維度裡的傳送門 +twilightforest.config.portals_in_other_dimensions.tooltip=允許在維度0之外的傳送門進入暮光森林。可能被認為是一個漏洞。 +twilightforest.config.admin_portals=僅管理員暮光傳送門 +twilightforest.config.admin_portals.tooltip=只允許管理員(操作者)的傳送門。這嚴重降低了模組通常掃描有效傳送門條件的範圍,並且僅在管理員附近掃描。 +twilightforest.config.portals=禁用暮光傳送門 +twilightforest.config.portals.tooltip=完全禁用創建暮光森林傳送門。為伺服器主提供了限制維度的操作。 +twilightforest.config.portal_creator=傳送門創建物品 +twilightforest.config.portal_creator.tooltip=用於創建暮光森林傳送門的物品的登錄檔字元串ID。 +twilightforest.config.portal_creator_meta=傳送門創建物品的Meta +twilightforest.config.portal_creator_meta.tooltip=用於創建「暮光森林」傳送門的物品的meta。-1表示任何詮釋資料。 +twilightforest.config.portal_lighting=傳送門創建閃電與火 +twilightforest.config.portal_lighting.tooltip=如果你不想讓傳送門的閃電引發火災,請將其設定為是。為那些不喜歡有趣的人而設。 +twilightforest.config.portal_return=傳送門應否生成一個雙向傳送門 +twilightforest.config.portal_return.tooltip=如果為否,則返回門戶將需要物品啟動。 + +twilightforest.config.uncrafting=禁止在拆解台裡拆解 +twilightforest.config.uncrafting.tooltip=禁用拆解台的拆解功能。當與其它模組交互產生可利用的合成表時,提供一個選項。 + +twilightforest.config.antibuilder_blacklist=防建築者黑名單 +twilightforest.config.antibuilder_blacklist.tooltip=防建築者的黑名單(區域:方塊:meta)meta是可選的。 + +twilightforest.config.animate_trophyitem=旋轉項目模型上的獎杯頭顱 +twilightforest.config.animate_trophyitem.tooltip=旋轉項目模型上的獎杯頭顱。完全沒有效能影響。為那些不喜歡有趣的人而設。 + +twilightforest.config.shield_parry=盾牌格擋 +twilightforest.config.shield_parry.tooltip=我們建議下載盾牌格擋模組(Shield Parry mod)進行格擋,但這些控件保持不用。 +twilightforest.config.parry_non_twilight=格擋非暮光拋射物 +twilightforest.config.parry_non_twilight.tooltip=設定為是以格擋非暮光拋射物。我們建議下載盾牌格擋模組(Shield Parry mod)。 +twilightforest.config.parry_window_arrow=格擋箭矢計時 +twilightforest.config.parry_window_arrow.tooltip=舉起一個盾後多少刻(ticks)可以讓它能夠格擋一支箭矢。1秒內有20刻(ticks)。 +twilightforest.config.parry_window_fireball=格擋火球計時 +twilightforest.config.parry_window_fireball.tooltip=舉起一個盾後多少刻(ticks)可以讓它能夠格擋一支火球。1秒內有20刻(ticks)。 +twilightforest.config.parry_window_throwable=格擋拋出物計時 +twilightforest.config.parry_window_throwable.tooltip=舉起一個盾後多少刻(ticks)可以讓它能夠格擋一支拋出物。1秒內有20刻(ticks)。 +twilightforest.config.shieldParryTicksBeam=(未翻譯) +twilightforest.config.shieldParryTicksBeam.tooltip=(未翻譯) + +twilightforest.config.loading_screen=載入畫面 +twilightforest.config.loading_screen.tooltip=僅限客戶端:控制載入畫面 +twilightforest.config.loading_icon_enable=啟用載入圖標動畫 +twilightforest.config.loading_icon_enable.tooltip=擺動載入圖標。完全沒有效能影響。為那些不喜歡有趣的人而設。 +twilightforest.config.loading_screen_swap_frequency=載入螢幕切換 +twilightforest.config.loading_screen_swap_frequency.tooltip=每個加載螢幕之間相隔多少個ticks產生變化。設定為0則不會循環。 +twilightforest.config.loading_icon_wobble_bounce_frequency=圖標動畫速度 +twilightforest.config.loading_icon_wobble_bounce_frequency.tooltip=搖擺和跳動的頻率。 +twilightforest.config.loading_icon_scale=圖標縮放 +twilightforest.config.loading_icon_scale.tooltip=整個彈性載入圖標的比例。 +twilightforest.config.loading_icon_bounciness=圖標反彈力 +twilightforest.config.loading_icon_bounciness.tooltip=加載圖標反彈多少。 +twilightforest.config.loading_icon_tilting=圖標搖擺度 +twilightforest.config.loading_icon_tilting.tooltip=加載圖標搖擺多遠。 +twilightforest.config.loading_icon_tilt_pushback=圖標傾斜偏移 +twilightforest.config.loading_icon_tilt_pushback.tooltip=將值推回載入圖標的擺動並重新置中。 + +twilightforest.book.lichtower.1=\u00A78[[探險家的筆記本,被怪物啃過]]\u00A70\n\n我已經開始審視這個塔樓周圍的奇怪光環。塔的磚塊受到詛咒的保護,比我之前見過的任何一塊都強。詛咒中的魔法 +twilightforest.book.lichtower.2=正在向周圍地區沸騰。\n\n在我的家鄉,我會有很多選擇來處理這個魔法,但是在這裡我的資源是有限的。我不得不研究…… +twilightforest.book.lichtower.3=\u00A78[[很多條目以後]]\u00A70\n\n一個突破!在我的旅程中,我在裝飾的庭院裡看到了一條巨大的蛇狀怪物。在附近,我拾起了一個磨損、被丟棄的綠色鳞片。\n\n鱗片上的魔法似乎具有 +twilightforest.book.lichtower.4=我所需要的詛咒破壞屬性,但魔法太暗淡了。我可能需要直接從生物身上獲取更新鮮的標本。 + +twilightforest.book.labyrinth.1=\u00A78[[探險家的筆記本,寫在防水紙上]]\u00A70\n\n沼澤中的蚊子令人煩惱,但很奇怪。牠們絕大多數似乎沒有自然資源,似乎也沒有在當地生態中發揮作用。我開始 +twilightforest.book.labyrinth.2=懷疑牠們是某種神奇的詛咒。\n\n\u00A78[[下一項]]\u00A70\n\n現在我在這裡遇到了破敗的迷宮上的保護咒語,我認為我的懷疑得到證實。保護咒語和 +twilightforest.book.labyrinth.3=蚊子都是詛咒。這個詛咒似乎與我遇到的其他人有不同的來源。我不得不進一步研究……\n\n\u00A78[[下一項]]\u00A70\n\n這種詛咒似乎 +twilightforest.book.labyrinth.4=對於一個人獨自創造而言過於強大。幾個組合工作的巫師是必要的。\n\n如果其中一個巫師停止了貢獻,整個沼澤的整個詛咒就會下降。奇怪的是, +twilightforest.book.labyrinth.5=我的占卜並沒有顯示任何附近的生活巫師的跡象。我在附近的一座尖塔上看到了一些有趣的東西…… + +twilightforest.book.hydralair.1=\u00A78[[探險家的筆記本,寫在防火紙上]]\u00A70\n\n對於像我這樣的高手來說,火是一個微不足道的障礙。我穿過火海,游過海洋的熔岩。這裡的燃燒中的空氣是一個有趣的變化, +twilightforest.book.hydralair.2=但最終沒有任何障礙。\n\n然而,阻止我的是我遇到了另一個保護咒語,這次是一個強大的生物,一定是這場火焰沼澤之王。這不是我遇到的第一個保護 +twilightforest.book.hydralair.3=咒語,我開始解開他們工作的奧秘。如果此咒語與其他咒語相同,則會由附近的強大生物維持。在火沼附近有幾塊濕沼澤, +twilightforest.book.hydralair.4=沼澤地下面是充滿牛頭怪的迷宮。將這種咒語綁定的邏輯選擇將是某種強大的牛頭怪,與周圍的其他人不同。 + +twilightforest.book.tfstronghold.1=\u00A78[[探險家的筆記本,寫在微弱的發光紙上]]\u00A70\n\n這個區域周圍黑暗的捲須只是在整個黑暗森林上的一種保護性咒語的體現。這個咒語會導致失明,這很令人煩惱。我已經 +twilightforest.book.tfstronghold.2=看到了該地區的一些有趣的事情,並希望繼續探索。\n\n\u00A78[[下一項]]\u00A70\n\n我在黑暗的森林裡找到了廢墟。他們屬於一個通常由騎士居住的類型的堡壘。雖然不是 +twilightforest.book.tfstronghold.3=騎士,但這個堡壘充滿了哥布林。他們穿著騎士盔甲,但他們的行為最不像騎士。\n\n\u00A78[[下一項]]\u00A70\n\n在廢墟深處,我找到了一個基座。基座似乎是騎士會 +twilightforest.book.tfstronghold.4=放置獎杯來證明他們的力量的一種類型。\n\n殺死一個強大的生物似乎削弱了黑暗森林上的詛咒,並且將與該生物相關的獎杯放置在基座上可能允許進入 +twilightforest.book.tfstronghold.5=大本營的主要部分。\n\n到目前為止,我所見過的唯一生物足夠的力量是火沼澤中的許多頭獸。多麼煩人…… + +twilightforest.book.darktower.1=\u00A78[[似乎在爆炸中倖存下來的探險家的筆記本]]\u00A70\n\n這座塔顯然具有不響應我的機制。他們的魔力幾乎渴望承認我的觸摸,但它不能。這是當塔的設備正在 +twilightforest.book.darktower.2=被附近的一個強大的群眾壓制。\n\n\u00A78[[下一項]]\u00A70\n\n這種魔法似乎是從附近的據點內發出的。它不能來自妖精,因為它們的魅力非常迷人,但卻沒有重點。一定 +twilightforest.book.darktower.3=仍然有一些力量依然活躍在據點。\n\n\u00A78[[下一項]]\u00A70\n\n我的分析表明它來自多個來源,作為一個團體運作。補給後我會回到要塞…… + +twilightforest.book.yeticave.1=\u00A78[[探險家的筆記本,覆蓋着霜]]\u00A70\n\n圍繞這些雪地的暴風雪不斷。這不是普通的降雪,這是一個神奇的現象。我不得不進行實驗以找出 +twilightforest.book.yeticave.2=能夠產生這種效果的因素。\n\n\u00A78[[下一項]]\u00A70\n\n這種詛咒似乎對於一個人獨自創造而言過於強大。幾個組合工作的巫師是必要的。 +twilightforest.book.yeticave.3=如果其中一個巫師停止了貢獻,整個沼澤的整個詛咒就會下降。奇怪的是,我的占卜並沒有顯示任何附近的生活巫師的跡象。我在附近的一座尖塔上看到了一些有趣的東西…… + +twilightforest.book.icetower.1=\u00A78[[一個探險家的筆記本,在冰上結冰]]\u00A70\n\n我克服了一場暴風雪,只是在冰川頂上遇到了這場可怕的冰暴。我的探索向我展示了冰宮的輝煌,閃爍著極光極光的色彩。這 +twilightforest.book.icetower.2=一切似乎都受到某種詛咒的保護。\n\n\u00A78[[下一項]]\u00A70\n\n我不是新手。這個詛咒由附近的生物的力量提供。圍繞火沼澤的詛咒的原因是靠近附近的 +twilightforest.book.icetower.3=牛頭怪頭目的力量。\n\n圍繞著這個冰川,有大量的雪怪。也許這些雪怪有某種首領…… + +twilightforest.book.trollcave.1=\u00A78[[一個探險家的筆記本,被強酸損壞]]\u00A70\n\n似乎沒有辦法保護我自己免受這個地區周圍的有毒暴雨的襲擊。在我短暫的短途旅行中,我也遇到了另一個保護咒語,類似於我見過的 +twilightforest.book.trollcave.2=其它保護咒語。該法術必須以某種方式連接到有毒風暴。進一步的研究要遵循……\n\n\u00A78[[下一項]]\u00A70\n\n這種至高無上的天氣魔法必定是無與倫比的天氣 +twilightforest.book.trollcave.3=魔術師的結果。這樣的人可能會躲藏在極端的環境中,遠離他人。\n\n根據我的邏輯,我期望在冰川的某個地方找到這樣一個人,也許在那裡有一個堡壘…… + +twilightforest.book.unknown.1=\u00A78[[這本書顯示了被多次復制的跡象]]\u00A70\n\n我無法解釋圍繞這個結構的領域,但是魔法是強大的。如果這種詛咒像其他人一樣,那麼解鎖它的答案就在別處。也許有些 +twilightforest.book.unknown.2=東西我還沒有完成,或者還有一些我還沒有擊敗的怪物。我不得不退後。稍後我會回到這個地方,看看有沒有什麼改變。 + +# Fluid + +fluid.fierymetal=熔融熾熱血/淚 +fluid.knightmetal=熔融騎士金屬錠 +fluid.fiery_essence=熾熱精華 + +# TCon + +material.nagascale.name=那伽鱗片 +material.steeleaf.name=鋼葉 +material.fierymetal.name=熾熱血/淚 +material.knightmetal.name=騎士金屬 +material.raven_feather.name=烏鴉羽毛 + +modifier.twilit.name=暮色 +modifier.twilit.desc=§o暮光森林的照明祝福。§r\n在暮光森林裡更快.\n在暮光森林之外造成更多傷害。 +modifier.twilit.extra.speed=在暮光之森的挖掘速度:+%s +modifier.twilit.extra.damage=在暮光森林之外造成的傷害:+%s +modifier.precipitate.name=沉澱 +modifier.precipitate.desc=§o最後一次常規逃生計劃。§r\n你的血量越低,速度越快! +modifier.synergy.name=協同 +modifier.synergy.desc=§o看,媽媽,沒青苔!§r\n如果你的快捷欄中有鋼葉,會自行修復。 +modifier.stalwart.name=偉岸 +modifier.stalwart.desc=§o勇敢和大膽。§r\n擊中一個實體可以讓你感到底氣。 +modifier.veiled.name=含蓄 +modifier.veiled.desc=§o像幽靈一樣!§r\n拋射物將隱形。 + +# Immersive Engineering +item.tfEngineeringShader=皮膚:%s +twilightforest.shader.twilight=暮光森林 + +twilightforest.shader.snakestone=蛇石 +twilightforest.shader.naga=那伽 +twilightforest.shader.lich=巫妖 + +twilightforest.shader.mazestone=迷宮石 +twilightforest.shader.minoshroom=米諾菇 +twilightforest.shader.hydra=九頭蛇 + +twilightforest.shader.underbrick=磚下 +twilightforest.shader.knight_phantom=幻影騎士 +twilightforest.shader.towerwood=塔木 +twilightforest.shader.ur-ghast=暮光惡魂 + +twilightforest.shader.alpha_yeti=雪怪首領 +twilightforest.shader.auroralized=極光化 +twilightforest.shader.snow_queen=冰雪女王 + +twilightforest.shader.final_castle=終結城堡 diff --git a/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/books.json b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/books.json new file mode 100644 index 0000000000..dd77723125 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/books.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "name": "books", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:enchanted_book/common", + "weight": 32 + }, + { + "type": "loot_table", + "name": "twilightforest:enchanted_book/uncommon", + "weight": 8 + }, + { + "type": "loot_table", + "name": "twilightforest:enchanted_book/rare", + "weight": 4 + }, + { + "type": "loot_table", + "name": "twilightforest:enchanted_book/ultrarare", + "weight": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/common.json b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/common.json new file mode 100644 index 0000000000..623229df01 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/common.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:book", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 1, "max": 10 } + }] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/rare.json b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/rare.json new file mode 100644 index 0000000000..589ff17a7d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/rare.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:book", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 21, "max": 30 } + }] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/ultrarare.json new file mode 100644 index 0000000000..f5b389b6ce --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/ultrarare.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "name": "ultrarare", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:book", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 31, "max": 40 } + }] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/uncommon.json new file mode 100644 index 0000000000..8a2fd06c3b --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/enchanted_book/uncommon.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "name": "uncommon", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:book", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 11, "max": 20 } + }] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/adherent.json b/src/main/resources/assets/twilightforest/loot_tables/entities/adherent.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/adherent.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/all_bosses.json b/src/main/resources/assets/twilightforest/loot_tables/entities/all_bosses.json new file mode 100644 index 0000000000..626ae27cf1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/all_bosses.json @@ -0,0 +1,113 @@ +{ + "pools": [{ + "name": "master", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:chest", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Master Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/all_bosses\"}}" + }] + }] + }, { + "name": "questing_ram", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:gray_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Questing Ram's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/questing_ram_rewards\"}}" + }] + }] + }, { + "name": "naga", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:lime_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Naga's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/naga\"}}" + }] + }] + }, { + "name": "lich", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:silver_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Lich's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/lich\"}}" + }] + }] + }, { + "name": "minoshroom", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:red_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Minoshroom's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/minoshroom\"}}" + }] + }] + }, { + "name": "hydra", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:cyan_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Hydra's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/hydra\"}}" + }] + }] + }, { + "name": "knight_phantom", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:green_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Knight Phantoms' Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:structures/stronghold_boss/stronghold_boss\"}}" + }] + }] + }, { + "name": "ur-ghast", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:white_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Ur-Ghast's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:structures/darktower_boss/darktower_boss\"}}" + }] + }] + }, { + "name": "alpha_yeti", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:light_blue_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Alpha Yeti's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/yeti_alpha\"}}" + }] + }] + }, { + "name": "snow_queen", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:blue_shulker_box", + "functions": [{ + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Snow Queen's Loot Crate\"},\"BlockEntityTag\":{\"LootTable\":\"twilightforest:entities/snow_queen\"}}" + }] + }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/armored_giant.json b/src/main/resources/assets/twilightforest/loot_tables/entities/armored_giant.json new file mode 100644 index 0000000000..979345620c --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/armored_giant.json @@ -0,0 +1,13 @@ +{ + "pools": [ + { + "name": "sword", + "rolls": 1, + "conditions": [{ "condition": "killed_by_player" }], + "entries": [{ + "type": "item", + "name": "twilightforest:giant_sword" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/black.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/black.json new file mode 100644 index 0000000000..691aca5d08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/black.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/black" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/blue.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/blue.json new file mode 100644 index 0000000000..5ced08d4e1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/blue.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/blue" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/brown.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/brown.json new file mode 100644 index 0000000000..405773950a --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/brown.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/brown" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/cyan.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/cyan.json new file mode 100644 index 0000000000..bda29cc803 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/cyan.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/cyan" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/gray.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/gray.json new file mode 100644 index 0000000000..fefc649b3c --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/gray.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/gray" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/green.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/green.json new file mode 100644 index 0000000000..0a52f47465 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/green.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/green" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/light_blue.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/light_blue.json new file mode 100644 index 0000000000..81fd3c3fc5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/light_blue.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/light_blue" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/lime.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/lime.json new file mode 100644 index 0000000000..2fd96950e4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/lime.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/lime" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/magenta.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/magenta.json new file mode 100644 index 0000000000..29cc786f8f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/magenta.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/magenta" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/orange.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/orange.json new file mode 100644 index 0000000000..3850e24fa9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/orange.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/orange" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/pink.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/pink.json new file mode 100644 index 0000000000..f1e474e521 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/pink.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/pink" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/purple.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/purple.json new file mode 100644 index 0000000000..ea80632e38 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/purple.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/purple" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/red.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/red.json new file mode 100644 index 0000000000..836c32b904 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/red.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/red" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/sheared.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/sheared.json new file mode 100644 index 0000000000..2b69dae9ff --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/sheared.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/silver.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/silver.json new file mode 100644 index 0000000000..e85dcf9228 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/silver.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/silver" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/white.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/white.json new file mode 100644 index 0000000000..3cb1210ed5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/white.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/white" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/yellow.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/yellow.json new file mode 100644 index 0000000000..df85d4a2b8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bighorn_sheep/yellow.json @@ -0,0 +1,7 @@ +{ + "pools": [{ + "name": "vanilla", + "rolls": 1, + "entries": [{ "type": "loot_table", "name": "minecraft:entities/sheep/yellow" }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bird.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bird.json new file mode 100644 index 0000000000..a453261c25 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bird.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "feather", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:feather", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/block_goblin.json b/src/main/resources/assets/twilightforest/loot_tables/entities/block_goblin.json new file mode 100644 index 0000000000..61bcf4cfbf --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/block_goblin.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "shards", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:armor_shard", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/boar.json b/src/main/resources/assets/twilightforest/loot_tables/entities/boar.json new file mode 100644 index 0000000000..7209532403 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/boar.json @@ -0,0 +1,41 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "weight": 500, + "type": "loot_table", + "name": "minecraft:entities/pig" + }, { + "type": "item", + "name": "minecraft:porkchop", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { "min": 1, "max": 3 } + }, { + "function": "furnace_smelt", + "conditions": [{ + "condition": "entity_properties", + "entity": "this", + "properties": { "on_fire": true } + }] + }, { + "function": "looting_enchant", + "count": { + "min": 0, + "max": 1 + } + }, { + "function": "set_nbt", + "tag": "{\"display\":{\"Name\":\"Boarkchop\"}}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/boggard.json b/src/main/resources/assets/twilightforest/loot_tables/entities/boggard.json new file mode 100644 index 0000000000..9d045f7fea --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/boggard.json @@ -0,0 +1,34 @@ +{ + "pools": [ + { + "name": "map_focus", + "rolls": 1, + "conditions": [{ "condition": "random_chance", "chance": 0.2 }], + "entries": [{ + "type": "item", + "name": "twilightforest:maze_map_focus", + "functions": [{ "function": "looting_enchant", "count": 1 }] + }] + }, + { + "name": "boots", + "rolls": 1, + "conditions": [{ "condition": "random_chance", "chance": 0.1666 }], + "entries": [{ + "type": "item", + "name": "minecraft:iron_boots", + "functions": [{ "function": "looting_enchant", "count": 1 }] + }] + }, + { + "name": "pick", + "rolls": 1, + "conditions": [{ "condition": "random_chance", "chance": 0.1111 }], + "entries": [{ + "type": "item", + "name": "minecraft:iron_pickaxe", + "functions": [{ "function": "looting_enchant", "count": 1 }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/bunny.json b/src/main/resources/assets/twilightforest/loot_tables/entities/bunny.json new file mode 100644 index 0000000000..a5d8f2817f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/bunny.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/rabbit" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/death_tome.json b/src/main/resources/assets/twilightforest/loot_tables/entities/death_tome.json new file mode 100644 index 0000000000..37db2ac18d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/death_tome.json @@ -0,0 +1,50 @@ +{ + "pools": [ + { + "name": "paper", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:paper", + "functions": [ + { "function": "set_count", "count": 3 }, + { "function": "looting_enchant", "count": 1 } + ] + }] + }, + { + "name": "book", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:writable_book", + "weight": 2, + "quality": 3 + }, + { + "type": "item", + "name": "minecraft:book", + "weight": 19 + }, + { + "type": "loot_table", + "name": "twilightforest:enchanted_book/books", + "weight": 1 + } + ] + }, + { + "name": "map_focus", + "rolls": 1, + "conditions": [ + { "condition": "killed_by_player" }, + { "condition": "random_chance_with_looting", "chance": 0.025, "looting_multiplier": 0.005 } + ], + "entries": [{ + "type": "item", + "name": "twilightforest:magic_map_focus" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/death_tome_hurt.json b/src/main/resources/assets/twilightforest/loot_tables/entities/death_tome_hurt.json new file mode 100644 index 0000000000..a8a542648d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/death_tome_hurt.json @@ -0,0 +1,17 @@ +{ + "pools": [ + { + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "empty" + }, + { + "type": "item", + "name": "minecraft:paper" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/deer.json b/src/main/resources/assets/twilightforest/loot_tables/entities/deer.json new file mode 100644 index 0000000000..37921fbaab --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/deer.json @@ -0,0 +1,37 @@ +{ + "pools": [ + { + "name": "leather", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:leather", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "meat", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:raw_venison", + "weight": 1, + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 3 } }, + { + "function": "furnace_smelt", + "conditions": [{ + "condition": "entity_properties", + "entity": "this", + "properties": { "on_fire": true } + }] + }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/fire_beetle.json b/src/main/resources/assets/twilightforest/loot_tables/entities/fire_beetle.json new file mode 100644 index 0000000000..85a6a77eab --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/fire_beetle.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "gunpowder", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:gunpowder", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/giant_miner.json b/src/main/resources/assets/twilightforest/loot_tables/entities/giant_miner.json new file mode 100644 index 0000000000..16e12014eb --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/giant_miner.json @@ -0,0 +1,13 @@ +{ + "pools": [ + { + "name": "pick", + "rolls": 1, + "conditions": [{ "condition": "killed_by_player" }], + "entries": [{ + "type": "item", + "name": "twilightforest:giant_pickaxe" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/goblin_knight.json b/src/main/resources/assets/twilightforest/loot_tables/entities/goblin_knight.json new file mode 100644 index 0000000000..61bcf4cfbf --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/goblin_knight.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "shards", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:armor_shard", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/harbinger_cube.json b/src/main/resources/assets/twilightforest/loot_tables/entities/harbinger_cube.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/harbinger_cube.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/hedge_spider.json b/src/main/resources/assets/twilightforest/loot_tables/entities/hedge_spider.json new file mode 100644 index 0000000000..bb21edf42f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/hedge_spider.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/spider" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/helmet_crab.json b/src/main/resources/assets/twilightforest/loot_tables/entities/helmet_crab.json new file mode 100644 index 0000000000..6f9a7d1c08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/helmet_crab.json @@ -0,0 +1,29 @@ +{ + "pools": [ + { + "name": "shards", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:armor_shard", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "fish", + "rolls": 1, + "conditions": [{ "condition": "random_chance", "chance": 0.5 }], + "entries": [{ + "type": "item", + "name": "minecraft:fish", + "functions": [ + { "function": "set_count", "count": 1 }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/hostile_wolf.json b/src/main/resources/assets/twilightforest/loot_tables/entities/hostile_wolf.json new file mode 100644 index 0000000000..aa024ff5f5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/hostile_wolf.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/wolf" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/hydra.json b/src/main/resources/assets/twilightforest/loot_tables/entities/hydra.json new file mode 100644 index 0000000000..1ead521a47 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/hydra.json @@ -0,0 +1,69 @@ +{ + "pools": [ + { + "name": "meat", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:hydra_chop", + "functions": [ + { "function": "set_count", "count": { "min": 5, "max": 35 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 2 } } + ] + }] + }, + { + "name": "blood", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:fiery_blood", + "functions": [ + { "function": "set_count", "count": { "min": 7, "max": 10 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "trophy", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:trophy", + "functions": [{ "function": "set_data", "data": 2 }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:fiery_blood", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "twilightforest:fiery_blood" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Hydra\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:fiery_blood", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "twilightforest:fiery_blood" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/ice_crystal.json b/src/main/resources/assets/twilightforest/loot_tables/entities/ice_crystal.json new file mode 100644 index 0000000000..5a9c730814 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/ice_crystal.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "snowballs", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:snowball", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/ice_exploder.json b/src/main/resources/assets/twilightforest/loot_tables/entities/ice_exploder.json new file mode 100644 index 0000000000..5a9c730814 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/ice_exploder.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "snowballs", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:snowball", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/ice_shooter.json b/src/main/resources/assets/twilightforest/loot_tables/entities/ice_shooter.json new file mode 100644 index 0000000000..5a9c730814 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/ice_shooter.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "snowballs", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:snowball", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/king_spider.json b/src/main/resources/assets/twilightforest/loot_tables/entities/king_spider.json new file mode 100644 index 0000000000..bb21edf42f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/king_spider.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/spider" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/kobold.json b/src/main/resources/assets/twilightforest/loot_tables/entities/kobold.json new file mode 100644 index 0000000000..2c70161b45 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/kobold.json @@ -0,0 +1,26 @@ +{ + "pools": [ + { + "name": "wheat", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:wheat", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "nuggs", + "rolls": 1, + "conditions": [{ "condition": "random_chance", "chance": 0.5 }], + "entries": [{ + "type": "item", + "name": "minecraft:gold_nugget", + "functions": [{ "function": "looting_enchant", "count": { "min": 0, "max": 1 } }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/lich.json b/src/main/resources/assets/twilightforest/loot_tables/entities/lich.json new file mode 100644 index 0000000000..fbd4615fca --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/lich.json @@ -0,0 +1,142 @@ +{ + "pools": [ + { + "name": "scepter", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:zombie_scepter" + }, + { + "type": "item", + "name": "twilightforest:lifedrain_scepter" + }, + { + "type": "item", + "name": "twilightforest:twilight_scepter" + }, + { + "type": "item", + "name": "twilightforest:shield_scepter" + } + ] + }, + { + "name": "bling", + "rolls": { "min": 2, "max": 4 }, + "entries": [ + { + "type": "item", + "name": "minecraft:golden_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 10, "max": 40 } + }] + }, + { + "type": "item", + "name": "minecraft:golden_helmet", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 10, "max": 40 } + }] + }, + { + "type": "item", + "name": "minecraft:golden_chestplate", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 10, "max": 40 } + }] + }, + { + "type": "item", + "name": "minecraft:golden_leggings", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 10, "max": 40 } + }] + }, + { + "type": "item", + "name": "minecraft:golden_boots", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": { "min": 10, "max": 40 } + }] + } + ] + }, + { + "name": "pearls", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:ender_pearl", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 4 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "bones", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:bone", + "functions": [ + { "function": "set_count", "count": { "min": 5, "max": 9 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "trophy", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:trophy", + "functions": [{ "function": "set_data", "data": 1 }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "minecraft:gold_nugget", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "minecraft:gold_nugget" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Lich\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "minecraft:gold_nugget", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "minecraft:gold_nugget" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/maze_slime.json b/src/main/resources/assets/twilightforest/loot_tables/entities/maze_slime.json new file mode 100644 index 0000000000..b53b9396c9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/maze_slime.json @@ -0,0 +1,24 @@ +{ + "pools": [ + { + "name": "charm", + "rolls": 1, + "conditions": [ + { "condition": "killed_by_player" }, + { "condition": "random_chance_with_looting", "chance": 0.025, "looting_multiplier": 0.005 } + ], + "entries": [{ + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + }] + }, + { + "name": "slime", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "minecraft:entities/slime" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/mini_ghast.json b/src/main/resources/assets/twilightforest/loot_tables/entities/mini_ghast.json new file mode 100644 index 0000000000..6f97f2a896 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/mini_ghast.json @@ -0,0 +1,11 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:is_minion", "inverse": true }], + "entries": [{ + "type": "loot_table", + "name": "minecraft:entities/ghast" + }] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/minoshroom.json b/src/main/resources/assets/twilightforest/loot_tables/entities/minoshroom.json new file mode 100644 index 0000000000..607f2c1913 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/minoshroom.json @@ -0,0 +1,57 @@ +{ + "pools": [ + { + "name": "meat", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:meef_stroganoff", + "functions": [ + { "function": "set_count", "count": { "min": 2, "max": 5} }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "trophy", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:trophy", + "functions": [{ "function": "set_data", "data": 6 }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:maze_map_focus", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "twilightforest:maze_map_focus" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Minoshroom\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:maze_map_focus", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "twilightforest:maze_map_focus" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/minotaur.json b/src/main/resources/assets/twilightforest/loot_tables/entities/minotaur.json new file mode 100644 index 0000000000..773d3865d0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/minotaur.json @@ -0,0 +1,38 @@ +{ + "pools": [ + { + "name": "meat", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:raw_meef", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 1 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1} }, + { + "function": "furnace_smelt", + "conditions": [{ + "condition": "entity_properties", + "entity": "this", + "properties": { + "on_fire": true + } + }] + } + ] + }] + }, + { + "name": "map_focus", + "rolls": 1, + "conditions": [ + { "condition": "killed_by_player" }, + { "condition": "random_chance_with_looting", "chance": 0.025, "looting_multiplier": 0.005 } + ], + "entries": [{ + "type": "item", + "name": "twilightforest:maze_map_focus" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/mist_wolf.json b/src/main/resources/assets/twilightforest/loot_tables/entities/mist_wolf.json new file mode 100644 index 0000000000..aa024ff5f5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/mist_wolf.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/wolf" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/mobile_firefly.json b/src/main/resources/assets/twilightforest/loot_tables/entities/mobile_firefly.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/mobile_firefly.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/mosquito_swarm.json b/src/main/resources/assets/twilightforest/loot_tables/entities/mosquito_swarm.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/mosquito_swarm.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/naga.json b/src/main/resources/assets/twilightforest/loot_tables/entities/naga.json new file mode 100644 index 0000000000..2e65c2b6c7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/naga.json @@ -0,0 +1,53 @@ +{ + "pools": [ + { + "name": "scales", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:naga_scale", + "functions": [{ "function": "set_count", "count": { "min": 6, "max": 11 } }] + }] + }, { + "name": "trophy", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:trophy", + "functions": [{ "function": "set_data", "data": 0 }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:naga_scale", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "twilightforest:naga_scale" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Naga\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:naga_scale", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "twilightforest:naga_scale" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/penguin.json b/src/main/resources/assets/twilightforest/loot_tables/entities/penguin.json new file mode 100644 index 0000000000..bace8cccd1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/penguin.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "bird", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:entities/bird" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/pinch_beetle.json b/src/main/resources/assets/twilightforest/loot_tables/entities/pinch_beetle.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/pinch_beetle.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/quest_ram.json b/src/main/resources/assets/twilightforest/loot_tables/entities/quest_ram.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/quest_ram.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/questing_ram_rewards.json b/src/main/resources/assets/twilightforest/loot_tables/entities/questing_ram_rewards.json new file mode 100644 index 0000000000..fc77731f31 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/questing_ram_rewards.json @@ -0,0 +1,91 @@ +{ + "pools": [ + { + "name": "diamond", + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:diamond_block" } + ] + }, + { + "name": "iron", + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:iron_block" } + ] + }, + { + "name": "emerald", + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:emerald_block" } + ] + }, + { + "name": "gold", + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:gold_block" } + ] + }, + { + "name": "lapis", + "rolls": 1, + "entries": [ + { "type": "item", "name": "minecraft:lapis_block" } + ] + }, + { + "name": "horn", + "rolls": 1, + "entries": [ + { "type": "item", "name": "twilightforest:crumble_horn" } + ] + }, + { + "name": "trophy", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:trophy", + "functions": [ + { "function": "set_data", "data": 8 } + ] + } + ] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "minecraft:coal_block", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "minecraft:coal_block" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Questing Ram\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "coal_block", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "coal_block" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/raven.json b/src/main/resources/assets/twilightforest/loot_tables/entities/raven.json new file mode 100644 index 0000000000..047e6057cc --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/raven.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "leather", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:raven_feather", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/redcap.json b/src/main/resources/assets/twilightforest/loot_tables/entities/redcap.json new file mode 100644 index 0000000000..49ebaa764c --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/redcap.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "coal", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:coal", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/redcap_sapper.json b/src/main/resources/assets/twilightforest/loot_tables/entities/redcap_sapper.json new file mode 100644 index 0000000000..9b61501083 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/redcap_sapper.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "twilight", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:entities/redcap" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/roving_cube.json b/src/main/resources/assets/twilightforest/loot_tables/entities/roving_cube.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/roving_cube.json @@ -0,0 +1,2 @@ +{ +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/skeleton_druid.json b/src/main/resources/assets/twilightforest/loot_tables/entities/skeleton_druid.json new file mode 100644 index 0000000000..3d0e7910e2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/skeleton_druid.json @@ -0,0 +1,28 @@ +{ + "pools": [ + { + "name": "berries", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:torchberries", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "bones", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:bone", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/slime_beetle.json b/src/main/resources/assets/twilightforest/loot_tables/entities/slime_beetle.json new file mode 100644 index 0000000000..fee1e5bac4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/slime_beetle.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "slime", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:slime_ball", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/snow_guardian.json b/src/main/resources/assets/twilightforest/loot_tables/entities/snow_guardian.json new file mode 100644 index 0000000000..5a9c730814 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/snow_guardian.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "snowballs", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:snowball", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/snow_queen.json b/src/main/resources/assets/twilightforest/loot_tables/entities/snow_queen.json new file mode 100644 index 0000000000..85ad22f3fb --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/snow_queen.json @@ -0,0 +1,80 @@ +{ + "pools": [ + { + "name": "bow", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:triple_bow" + }, + { + "type": "item", + "name": "twilightforest:seeker_bow" + } + ] + }, + { + "name": "ice", + "rolls": { "min": 1, "max": 4 }, + "entries": [{ + "type": "item", + "name": "minecraft:packed_ice", + "functions": [ + { "function": "set_count", "count": 7 }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "snowballs", + "rolls": { "min": 5, "max": 9 }, + "entries": [{ + "type": "item", + "name": "minecraft:snowball", + "functions": [{ "function": "set_count", "count": 16 }] + }] + }, + { + "name": "trophy", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:trophy", + "functions": [{ "function": "set_data", "data": 5 }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:ice_bomb", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "twilightforest:ice_bomb" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Snow Queen\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:ice_bomb", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "twilightforest:ice_bomb" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/squirrel.json b/src/main/resources/assets/twilightforest/loot_tables/entities/squirrel.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/squirrel.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/swarm_spider.json b/src/main/resources/assets/twilightforest/loot_tables/entities/swarm_spider.json new file mode 100644 index 0000000000..bb21edf42f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/swarm_spider.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/spider" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/tiny_bird.json b/src/main/resources/assets/twilightforest/loot_tables/entities/tiny_bird.json new file mode 100644 index 0000000000..bace8cccd1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/tiny_bird.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "bird", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:entities/bird" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/tower_broodling.json b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_broodling.json new file mode 100644 index 0000000000..bb21edf42f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_broodling.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/spider" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/tower_ghast.json b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_ghast.json new file mode 100644 index 0000000000..361c87f575 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_ghast.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "name": "vanilla", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "minecraft:entities/ghast" + } + ] + } + ] +} diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/tower_golem.json b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_golem.json new file mode 100644 index 0000000000..2ebcbcc8f9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_golem.json @@ -0,0 +1,22 @@ +{ + "pools": [ + { + "name": "iron", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 0, "max": 2 } }] + }] + }, + { + "name": "wood", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:tower_wood", + "functions": [{ "function": "set_count", "count": { "min": 0, "max": 2 } }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/tower_termite.json b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_termite.json new file mode 100644 index 0000000000..93acebafa3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/tower_termite.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "essence", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:borer_essence", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/troll.json b/src/main/resources/assets/twilightforest/loot_tables/entities/troll.json new file mode 100644 index 0000000000..e77e20bab2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/troll.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "beans", + "rolls": 1, + "conditions": [ + { "condition": "killed_by_player" }, + { "condition": "random_chance_with_looting", "chance": 0.025, "looting_multiplier": 0.005 } + ], + "entries": [{ + "type": "item", + "name": "twilightforest:magic_beans" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/winter_wolf.json b/src/main/resources/assets/twilightforest/loot_tables/entities/winter_wolf.json new file mode 100644 index 0000000000..278998ebeb --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/winter_wolf.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "fur", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:arctic_fur", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/wraith.json b/src/main/resources/assets/twilightforest/loot_tables/entities/wraith.json new file mode 100644 index 0000000000..0518039e00 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/wraith.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "dust", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "minecraft:glowstone_dust", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/yeti.json b/src/main/resources/assets/twilightforest/loot_tables/entities/yeti.json new file mode 100644 index 0000000000..278998ebeb --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/yeti.json @@ -0,0 +1,16 @@ +{ + "pools": [ + { + "name": "fur", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:arctic_fur", + "functions": [ + { "function": "set_count", "count": { "min": 0, "max": 2 } }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/entities/yeti_alpha.json b/src/main/resources/assets/twilightforest/loot_tables/entities/yeti_alpha.json new file mode 100644 index 0000000000..6ba675e374 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/entities/yeti_alpha.json @@ -0,0 +1,60 @@ +{ + "pools": [ + { + "name": "fur", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:alpha_fur", + "functions": [ + { "function": "set_count", "count": 6 }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, + { + "name": "icebombs", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:ice_bomb", + "functions": [ + { "function": "set_count", "count": 6 }, + { "function": "looting_enchant", "count": { "min": 0, "max": 1 } } + ] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:ice_bomb", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "twilightforest:ice_bomb" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Alpha Yeti\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:ice_bomb", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "twilightforest:ice_bomb" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/glass_sword.json b/src/main/resources/assets/twilightforest/loot_tables/glass_sword.json new file mode 100644 index 0000000000..acd9ec1032 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/glass_sword.json @@ -0,0 +1,12 @@ +{ + "pools": [ + { + "name": "sword", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:glass_sword" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_boss/aurora_boss.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_boss/aurora_boss.json new file mode 100644 index 0000000000..62a480fc33 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_boss/aurora_boss.json @@ -0,0 +1,3 @@ +{ + "__comment": "blank, original table in 1.7 was never filled out" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/aurora_cache.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/aurora_cache.json new file mode 100644 index 0000000000..c12940e35d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/aurora_cache.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/aurora_cache/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/aurora_cache/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/aurora_cache/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/aurora_cache/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/common.json new file mode 100644 index 0000000000..293dac370d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/common.json @@ -0,0 +1,43 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:stick", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:coal", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:maze_wafer", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 9 } }] + }, + { + "type": "item", + "name": "minecraft:ice", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:packed_ice", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/rare.json new file mode 100644 index 0000000000..a2130eac25 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/rare.json @@ -0,0 +1,25 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:arctic_fur", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "twilightforest:ice_bow" + }, + { + "type": "item", + "name": "twilightforest:ender_bow" + }, + { + "type": "item", + "name": "twilightforest:ice_sword" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/ultrarare.json new file mode 100644 index 0000000000..63600691aa --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/ultrarare.json @@ -0,0 +1,64 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "entryName": "sharpness", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:sharpness": 4 + } + }] + }, + { + "type": "item", + "entryName": "power", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:power": 4 + } + }] + }, + { + "type": "item", + "entryName": "punch", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:punch": 2 + } + }] + }, + { + "type": "item", + "entryName": "unbreaking", + "name": "minecraft:enchanted_book", + "weight": 2, + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:unbreaking": 2 + } + }] + }, + { + "type": "item", + "entryName": "infinity", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:infinity": 1 + } + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/uncommon.json new file mode 100644 index 0000000000..321979bdcd --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_cache/uncommon.json @@ -0,0 +1,32 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:aurora_block", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + }, + { + "type": "item", + "name": "twilightforest:arctic_fur", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/aurora_room.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/aurora_room.json new file mode 100644 index 0000000000..0f2a8d3024 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/aurora_room.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/aurora_room/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/aurora_room/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/aurora_room/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/common.json new file mode 100644 index 0000000000..9f1d630d7c --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/common.json @@ -0,0 +1,33 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:ice", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:packed_ice", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:maze_wafer", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:ice_bomb", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/rare.json new file mode 100644 index 0000000000..173a9bb14f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/rare.json @@ -0,0 +1,44 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:ice_bow", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 30 + }] + }, + { + "type": "item", + "name": "twilightforest:ender_bow", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 5 + }] + }, + { + "type": "item", + "name": "twilightforest:ice_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 25 + }] + }, + { + "type": "item", + "name": "twilightforest:glass_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/uncommon.json new file mode 100644 index 0000000000..f88dc5cc69 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/aurora_room/uncommon.json @@ -0,0 +1,41 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:arctic_fur", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:arctic_leggings" + }, + { + "type": "item", + "name": "twilightforest:arctic_chestplate" + }, + { + "type": "item", + "name": "twilightforest:arctic_helmet" + }, + { + "type": "item", + "name": "twilightforest:arctic_boots" + }, + { + "type": "item", + "name": "twilightforest:knightmetal_chestplate" + }, + { + "type": "item", + "name": "twilightforest:knightmetal_sword" + }, + { + "type": "item", + "name": "twilightforest:charm_of_life_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/basement/basement.json b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/basement.json new file mode 100644 index 0000000000..19f010fadc --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/basement.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/basement/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/basement/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/basement/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/basement/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/basement/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/common.json new file mode 100644 index 0000000000..b63b6e193f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/common.json @@ -0,0 +1,68 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:water\"}" + }] + }, + { + "type": "item", + "name": "minecraft:rotten_flesh", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:poisonous_potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:wheat", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:carrot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:melon", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:water_bucket" + }, + { + "type": "item", + "name": "minecraft:torch", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:mushroom_stew" + }, + { + "type": "item", + "name": "minecraft:milk_bucket" + }, + { + "type": "item", + "name": "minecraft:melon_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/basement/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/rare.json new file mode 100644 index 0000000000..2a708fd90a --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/rare.json @@ -0,0 +1,25 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:speckled_melon", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:apple", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:map" + },{ + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/basement/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/ultrarare.json new file mode 100644 index 0000000000..32d32b01fa --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/ultrarare.json @@ -0,0 +1,31 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:golden_apple", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:golden_carrot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:cake" + }, + { + "type": "item", + "name": "minecraft:boat" + }, + { + "type": "item", + "name": "twilightforest:twilight_sapling", + "functions": [{ "function": "set_data", "data": 4 }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/basement/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/uncommon.json new file mode 100644 index 0000000000..ffdd6c43b1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/basement/uncommon.json @@ -0,0 +1,38 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bread", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "minecraft:cooked_beef", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:cooked_porkchop", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "minecraft:baked_potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "minecraft:cooked_chicken", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 10 } }] + }, + { + "type": "item", + "name": "minecraft:cooked_fish", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/common.json new file mode 100644 index 0000000000..f593f43eda --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/common.json @@ -0,0 +1,13 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:carminite", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/darktower_boss.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/darktower_boss.json new file mode 100644 index 0000000000..faa6ee70a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/darktower_boss.json @@ -0,0 +1,58 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_boss/common" + }] + }, { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_boss/uncommon" + }] + }, { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_boss/rare" + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:carminite", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "twilightforest:carminite" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Ur-Ghast\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:carminite", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "twilightforest:carminite" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/rare.json new file mode 100644 index 0000000000..ec311088cc --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/rare.json @@ -0,0 +1,13 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:trophy", + "functions": [{ "function": "set_data", "data": 3 }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/uncommon.json new file mode 100644 index 0000000000..4a9745fad6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_boss/uncommon.json @@ -0,0 +1,13 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:fiery_tears", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/common.json new file mode 100644 index 0000000000..335daec123 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/common.json @@ -0,0 +1,41 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:stick", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:coal", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 12 } }, + { "function": "set_data", "data": 1} + ] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:experiment_115", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 9 } }] + }, + { + "type": "item", + "name": "minecraft:wool", + "functions": [{ "function": "set_data", "data": 14 }] + }, + { + "type": "item", + "name": "minecraft:redstone", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/darktower_cache.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/darktower_cache.json new file mode 100644 index 0000000000..549bd2991a --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/darktower_cache.json @@ -0,0 +1,38 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/darktower_cache/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_cache/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_cache/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/rare.json new file mode 100644 index 0000000000..4ce6237d8d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/rare.json @@ -0,0 +1,18 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "minecraft:diamond", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/uncommon.json new file mode 100644 index 0000000000..23b2d1b08a --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_cache/uncommon.json @@ -0,0 +1,32 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:redstone_lamp", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/common.json new file mode 100644 index 0000000000..92fae2e471 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/common.json @@ -0,0 +1,43 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:experiment_115", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "minecraft:redstone", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:glowstone_dust", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/darktower_key.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/darktower_key.json new file mode 100644 index 0000000000..fac34e1753 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/darktower_key.json @@ -0,0 +1,39 @@ +{ + "pools": [ + { + "name": "key", + "rolls": 1, + "entries": [{ + "type": "item", + "name": "twilightforest:tower_key" + }] + }, + + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_key/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_key/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/darktower_key/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/rare.json new file mode 100644 index 0000000000..a682acd3e1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/rare.json @@ -0,0 +1,45 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:charm_of_life_1" + }, + { + "type": "item", + "entryName": "ff", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:feather_falling": 3 + } + }] + }, + { + "type": "item", + "entryName": "knock", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:knockback": 2 + } + }] + }, + { + "type": "item", + "entryName": "eff", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:efficiency": 3 + } + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/uncommon.json new file mode 100644 index 0000000000..2d083d676d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/darktower_key/uncommon.json @@ -0,0 +1,45 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_leggings" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_chestplate" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_helmet" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_boots" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_pickaxe" + }, + { + "type": "item", + "name": "twilightforest:ironwood_chestplate" + }, + { + "type": "item", + "name": "twilightforest:ironwood_sword" + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/common.json new file mode 100644 index 0000000000..59852b1f5d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/common.json @@ -0,0 +1,23 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:pumpkin_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 32 } }] + }, + { + "type": "item", + "name": "twilightforest:torchberries", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 16 } }] + }, + { + "type": "item", + "name": "minecraft:pumpkin_pie", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/graveyard.json b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/graveyard.json new file mode 100644 index 0000000000..27087ec77d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/graveyard.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/graveyard/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/graveyard/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/graveyard/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/rare.json new file mode 100644 index 0000000000..ecdeaae824 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/rare.json @@ -0,0 +1,21 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:golden_apple" + }, + { + "type": "item", + "name": "twilightforest:uncrafting_table" + }, + { + "type": "item", + "name": "twilightforest:transformation_powder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/uncommon.json new file mode 100644 index 0000000000..d4334e9016 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/graveyard/uncommon.json @@ -0,0 +1,18 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:moon_dial", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 1 } }] + }, + { + "type": "item", + "name": "minecraft:diamond", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/common.json new file mode 100644 index 0000000000..9a05f3c8ef --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/common.json @@ -0,0 +1,47 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:planks", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 4 } }, + { + "function": "set_data", + "data": { + "min": 0, + "max": 5 + } + } + ] + }, + { + "type": "item", + "name": "minecraft:brown_mushroom", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:red_mushroom", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:wheat", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:string", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:stick", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/hedge_maze.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/hedge_maze.json new file mode 100644 index 0000000000..53df7036f9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/hedge_maze.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hedge_maze/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/hedge_maze/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/hedge_maze/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hedge_maze/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/rare.json new file mode 100644 index 0000000000..91185e07fd --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/rare.json @@ -0,0 +1,30 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:web", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:shears" + }, + { + "type": "item", + "name": "minecraft:saddle" + }, + { + "type": "item", + "name": "minecraft:bow" + }, + { + "type": "item", + "name": "minecraft:apple", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/ultrarare.json new file mode 100644 index 0000000000..6a499ca693 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/ultrarare.json @@ -0,0 +1,24 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:diamond_hoe" + }, + { + "type": "item", + "name": "minecraft:diamond" + }, + { + "type": "item", + "name": "minecraft:mushroom_stew" + }, + { + "type": "item", + "name": "minecraft:golden_apple" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/uncommon.json new file mode 100644 index 0000000000..81cba6ae59 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hedge_maze/uncommon.json @@ -0,0 +1,33 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:melon", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:melon_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:pumpkin_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/common.json new file mode 100644 index 0000000000..84390bfbcf --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/common.json @@ -0,0 +1,27 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:wheat", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:string", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:bucket" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/hill_1.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/hill_1.json new file mode 100644 index 0000000000..9620bbc5ee --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/hill_1.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hill_1/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/hill_1/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/hill_1/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hill_1/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/rare.json new file mode 100644 index 0000000000..7ccdc031a2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/rare.json @@ -0,0 +1,22 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:gold_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + }, + { + "type": "item", + "name": "minecraft:iron_pickaxe" + }, + { + "type": "item", + "name": "twilightforest:liveroot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/ultrarare.json new file mode 100644 index 0000000000..12d28f1c1f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/ultrarare.json @@ -0,0 +1,22 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:transformation_powder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:diamond" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/uncommon.json new file mode 100644 index 0000000000..aa23047d4e --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_1/uncommon.json @@ -0,0 +1,31 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bread" + }, + { + "type": "item", + "name": "twilightforest:ore_magnet" + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:torch", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/common.json new file mode 100644 index 0000000000..5e83f20a6e --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/common.json @@ -0,0 +1,27 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:carrot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:ladder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:bucket" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/hill_2.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/hill_2.json new file mode 100644 index 0000000000..89d5ede54b --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/hill_2.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hill_2/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/hill_2/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/hill_2/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hill_2/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/rare.json new file mode 100644 index 0000000000..8d053c9b2c --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/rare.json @@ -0,0 +1,21 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:naga_scale" + }, + { + "type": "item", + "name": "twilightforest:uncrafting_table" + }, + { + "type": "item", + "name": "twilightforest:transformation_powder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/ultrarare.json new file mode 100644 index 0000000000..3747f50c69 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/ultrarare.json @@ -0,0 +1,25 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:peacock_fan" + }, + { + "type": "item", + "name": "minecraft:emerald", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:diamond" + }, + { + "type": "item", + "name": "twilightforest:charm_of_life_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/uncommon.json new file mode 100644 index 0000000000..6c4144adb3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_2/uncommon.json @@ -0,0 +1,32 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:baked_potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "twilightforest:ore_magnet" + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:torch", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/common.json new file mode 100644 index 0000000000..cb6f826471 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/common.json @@ -0,0 +1,28 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:gold_nugget", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 9 } }] + }, + { + "type": "item", + "name": "minecraft:potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:fish", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:torchberries", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/hill_3.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/hill_3.json new file mode 100644 index 0000000000..d4fa899fe1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/hill_3.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hill_3/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/hill_3/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/hill_3/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/hill_3/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/rare.json new file mode 100644 index 0000000000..685cc393fd --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/rare.json @@ -0,0 +1,28 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:naga_scale" + }, + { + "type": "item", + "name": "twilightforest:ironwood_pickaxe", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:efficiency": 1, + "minecraft:fortune": 1 + } + }] + }, + { + "type": "item", + "name": "twilightforest:transformation_powder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/ultrarare.json new file mode 100644 index 0000000000..5304b6beae --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/ultrarare.json @@ -0,0 +1,34 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:moonworm_queen", + "weight": 5 + }, + { + "type": "item", + "name": "twilightforest:twilight_sapling", + "weight": 2 + }, + { + "type": "item", + "name": "minecraft:diamond", + "weight": 5, + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "twilightforest:charm_of_life_1", + "weight": 5 + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1", + "weight": 5 + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/uncommon.json new file mode 100644 index 0000000000..9ae3fd91ac --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/hill_3/uncommon.json @@ -0,0 +1,36 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:pumpkin_pie" + }, + { + "type": "item", + "name": "twilightforest:ore_magnet" + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:torch", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/common.json new file mode 100644 index 0000000000..9ef685af2a --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/common.json @@ -0,0 +1,42 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:stick", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:coal", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:maze_wafer", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 9 } }] + }, + { + "type": "item", + "name": "minecraft:paper", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:leather", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:mushroom_stew" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/labyrinth_dead_end.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/labyrinth_dead_end.json new file mode 100644 index 0000000000..bc7f325117 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/labyrinth_dead_end.json @@ -0,0 +1,38 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_dead_end/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_dead_end/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_dead_end/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/rare.json new file mode 100644 index 0000000000..390263e635 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/rare.json @@ -0,0 +1,22 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "minecraft:golden_apple" + }, + { + "type": "item", + "name": "minecraft:blaze_rod", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/uncommon.json new file mode 100644 index 0000000000..56fb2eddeb --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_dead_end/uncommon.json @@ -0,0 +1,36 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:milk_bucket" + }, + { + "type": "item", + "name": "minecraft:paper", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/common.json new file mode 100644 index 0000000000..1f7cb102e7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/common.json @@ -0,0 +1,37 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:maze_wafer", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "minecraft:milk_bucket" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/labyrinth_room.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/labyrinth_room.json new file mode 100644 index 0000000000..a7a94cb199 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/labyrinth_room.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_room/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_room/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_room/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/rare.json new file mode 100644 index 0000000000..1942871b76 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/rare.json @@ -0,0 +1,25 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:maze_map_focus" + }, + { + "type": "item", + "name": "minecraft:tnt", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + }, + { + "type": "item", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_healing\"}" + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/uncommon.json new file mode 100644 index 0000000000..2d083d676d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_room/uncommon.json @@ -0,0 +1,45 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_leggings" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_chestplate" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_helmet" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_boots" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_pickaxe" + }, + { + "type": "item", + "name": "twilightforest:ironwood_chestplate" + }, + { + "type": "item", + "name": "twilightforest:ironwood_sword" + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/common.json new file mode 100644 index 0000000000..1055937317 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/common.json @@ -0,0 +1,55 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 9 } }] + }, + { + "type": "item", + "name": "minecraft:emerald", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "twilightforest:maze_wafer", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 9 } }] + }, + { + "type": "item", + "entryName": "regen 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_regeneration\"}" + }] + }, + { + "type": "item", + "entryName": "health 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_healing\"}" + }] + }, + { + "type": "item", + "entryName": "speed 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_swiftness\"}" + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/labyrinth_vault.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/labyrinth_vault.json new file mode 100644 index 0000000000..c4012d59f2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/labyrinth_vault.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_vault/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_vault/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/labyrinth_vault/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/rare.json new file mode 100644 index 0000000000..907ec2d870 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/rare.json @@ -0,0 +1,63 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:emerald_block" + }, + { + "type": "item", + "name": "minecraft:ender_chest" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_pickaxe", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:efficiency": 4, + "minecraft:silk_touch": 1 + } + }] + }, + { + "type": "item", + "entryName": "sharpknock", + "name": "twilightforest:steeleaf_sword", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:sharpness": 4, + "minecraft:knockback": 2 + } + }] + }, + { + "type": "item", + "entryName": "boafire", + "name": "twilightforest:steeleaf_sword", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:bane_of_arthropods": 5, + "minecraft:fire_aspect": 2 + } + }] + }, + { + "type": "item", + "name": "twilightforest:mazebreaker_pickaxe", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:efficiency": 4, + "minecraft:unbreaking": 3, + "minecraft:fortune": 2 + } + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/uncommon.json new file mode 100644 index 0000000000..fed2dba346 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/labyrinth_vault/uncommon.json @@ -0,0 +1,98 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "entryName": "infpunch", + "name": "minecraft:bow", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:infinity": 1, + "minecraft:punch": 2 + } + }] + }, + { + "type": "item", + "entryName": "powerflame", + "name": "minecraft:bow", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:power": 3, + "minecraft:flame": 1 + } + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_shovel", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:efficiency": 4, + "minecraft:unbreaking": 2 + } + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_axe", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:efficiency": 5 + } + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_chestplate", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:protection": 3 + } + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_leggings", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:fire_protection": 4 + } + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_boots", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:protection": 2 + } + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_helmet", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:respiration": 3 + } + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/common.json new file mode 100644 index 0000000000..60d347b3ab --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/common.json @@ -0,0 +1,35 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:knightmetal_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "twilightforest:knightmetal_pickaxe", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "twilightforest:knightmetal_axe", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/rare.json new file mode 100644 index 0000000000..d4c5a4165e --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/rare.json @@ -0,0 +1,26 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:phantom_helmet", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 30 + }] + }, + { + "type": "item", + "name": "twilightforest:phantom_chestplate", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 30 + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/stronghold_boss.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/stronghold_boss.json new file mode 100644 index 0000000000..47f23c4bb4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/stronghold_boss.json @@ -0,0 +1,65 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_boss/common" + }] + }, { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_boss/uncommon" + }] + }, { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_boss/rare" + }] + }, { + "name": "trophy", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_boss/trophy" + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:knightmetal_ingot", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader", + "default": "twilightforest:knightmetal_ingot" + }, { + "function": "set_nbt", + "tag": "{\"shader_type\":\"Knight Phantom\"}" + }] + }] + }, { + "name": "shader", + "rolls": 1, + "conditions": [{ "condition": "twilightforest:mod_exists", "mod_id": "immersiveengineering" }], + "entries": [{ + "type": "item", + "name": "twilightforest:knightmetal_ingot", + "functions": [{ + "function": "twilightforest:item_or_default", + "item": "twilightforest:shader_bag", + "default": "twilightforest:knightmetal_ingot" + }, { + "function": "set_nbt", + "tag": "{\"shader_rarity\":\"Twilight\"}" + }] + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/trophy.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/trophy.json new file mode 100644 index 0000000000..cc4cae9f8e --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/trophy.json @@ -0,0 +1,15 @@ +{ + "pools": [ + { + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:trophy", + "functions": [{ "function": "set_data", "data": 4 }] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/uncommon.json new file mode 100644 index 0000000000..ecc238ac4d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_boss/uncommon.json @@ -0,0 +1,26 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:phantom_helmet", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "twilightforest:phantom_chestplate", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/common.json new file mode 100644 index 0000000000..5cfdaa8729 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/common.json @@ -0,0 +1,38 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:stick", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:coal", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:arrow", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:maze_wafer", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 9 } }] + }, + { + "type": "item", + "name": "minecraft:wool", + "functions": [{ "function": "set_data", "data": 11 }] + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/rare.json new file mode 100644 index 0000000000..e6ec70fc90 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/rare.json @@ -0,0 +1,49 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:knightmetal_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 8 } }] + }, + { + "type": "item", + "name": "minecraft:bow", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "minecraft:iron_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 15 + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 10 + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/stronghold_cache.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/stronghold_cache.json new file mode 100644 index 0000000000..c0fbe4b103 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/stronghold_cache.json @@ -0,0 +1,38 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_cache/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_cache/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/stronghold_cache/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/stronghold_cache/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/ultrarare.json new file mode 100644 index 0000000000..3030351a79 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/ultrarare.json @@ -0,0 +1,86 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "entryName": "boa", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:bane_of_arthropods": 4 + } + }] + }, + { + "type": "item", + "entryName": "sharp", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:sharpness": 4 + } + }] + }, + { + "type": "item", + "entryName": "smite", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:smite": 4 + } + }] + }, + { + "type": "item", + "entryName": "unbreaking", + "name": "minecraft:enchanted_book", + "weight": 2, + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:unbreaking": 2 + } + }] + }, + { + "type": "item", + "entryName": "prot", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:protection": 3 + } + }] + }, + { + "type": "item", + "entryName": "projprot", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:projectile_protection": 3 + } + }] + }, + { + "type": "item", + "entryName": "ff", + "name": "minecraft:enchanted_book", + "functions": [{ + "function": "twilightforest:enchant", + "enchantments": { + "minecraft:feather_falling": 3 + } + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/uncommon.json new file mode 100644 index 0000000000..683d84e97f --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_cache/uncommon.json @@ -0,0 +1,36 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bucket" + }, + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + }, + { + "type": "item", + "name": "twilightforest:armor_shard", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/common.json new file mode 100644 index 0000000000..1f7cb102e7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/common.json @@ -0,0 +1,37 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:maze_wafer", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:gunpowder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "minecraft:milk_bucket" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/rare.json new file mode 100644 index 0000000000..06c60cefe9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/rare.json @@ -0,0 +1,57 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:maze_map_focus" + }, + { + "type": "item", + "name": "minecraft:bow", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 30 + }] + }, + { + "type": "item", + "name": "minecraft:iron_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 30 + }] + }, + { + "type": "item", + "name": "twilightforest:ironwood_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 25 + }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "minecraft:diamond_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 15 + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/stronghold_room.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/stronghold_room.json new file mode 100644 index 0000000000..f5bf96d255 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/stronghold_room.json @@ -0,0 +1,38 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/stronghold_room/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_room/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/stronghold_room/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/uncommon.json new file mode 100644 index 0000000000..f59f70bf83 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/stronghold_room/uncommon.json @@ -0,0 +1,45 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:steeleaf_ingot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "twilightforest:steeleaf_leggings" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_chestplate" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_helmet" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_boots" + }, + { + "type": "item", + "name": "twilightforest:steeleaf_pickaxe" + }, + { + "type": "item", + "name": "twilightforest:ironwood_chestplate" + }, + { + "type": "item", + "name": "twilightforest:ironwood_sword" + }, + { + "type": "item", + "name": "twilightforest:charm_of_life_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/common.json new file mode 100644 index 0000000000..5310d8ea23 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/common.json @@ -0,0 +1,46 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:glass_bottle", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:water\"}" + }] + }, + { + "type": "item", + "name": "minecraft:ladder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:paper", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:bone", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:gold_nugget", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:clay_ball", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/rare.json new file mode 100644 index 0000000000..a523f72aec --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/rare.json @@ -0,0 +1,67 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:bow", + "functions": [{ + "function": "enchant_with_levels", + "levels": 5 + }] + }, + { + "type": "item", + "name": "minecraft:stone_sword", + "functions": [{ + "function": "enchant_with_levels", + "levels": 10 + }] + }, + { + "type": "item", + "name": "minecraft:wooden_sword", + "functions": [{ + "function": "enchant_with_levels", + "levels": 15 + }] + }, + { + "type": "item", + "name": "minecraft:splash_potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:weakness\"}" + }] + }, + { + "type": "item", + "entryName": "regen 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_regeneration\"}" + }] + }, + { + "type": "item", + "entryName": "health 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_healing\"}" + }] + }, + { + "type": "item", + "entryName": "speed 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_swiftness\"}" + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/tower_library.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/tower_library.json new file mode 100644 index 0000000000..c58397e382 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/tower_library.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/tower_library/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/tower_library/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/tower_library/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/tower_library/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/ultrarare.json new file mode 100644 index 0000000000..69448888d3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/ultrarare.json @@ -0,0 +1,50 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:golden_pickaxe", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 10 + }] + }, + { + "type": "item", + "name": "minecraft:iron_sword", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "minecraft:bow", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 30 + }] + }, + { + "type": "item", + "name": "minecraft:bookshelf", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "minecraft:ender_pearl", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:experience_bottle", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/uncommon.json new file mode 100644 index 0000000000..8c87f4c292 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_library/uncommon.json @@ -0,0 +1,57 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_leggings", + "functions": [{ + "function": "enchant_with_levels", + "levels": 5 + }] + }, + { + "type": "item", + "name": "minecraft:fire_charge", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + }, + { + "type": "item", + "name": "minecraft:book", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "minecraft:map" + }, + { + "type": "item", + "entryName": "awk", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:awkward\"}" + }] + }, + { + "type": "item", + "entryName": "poison", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:poison\"}" + }] + }, + { + "type": "item", + "entryName": "weak", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:weakness\"}" + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/common.json new file mode 100644 index 0000000000..aef0f952ee --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/common.json @@ -0,0 +1,59 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:glass_bottle", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:water\"}" + }] + }, + { + "type": "item", + "name": "minecraft:sugar", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + }, + { + "type": "item", + "name": "minecraft:spider_eye", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + }, + { + "type": "item", + "name": "minecraft:ghast_tear" + }, + { + "type": "item", + "name": "minecraft:magma_cream", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:fermented_spider_eye" + }, + { + "type": "item", + "name": "minecraft:speckled_melon", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:blaze_powder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + }, + { + "type": "item", + "name": "minecraft:paper", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/rare.json new file mode 100644 index 0000000000..7098af2ede --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/rare.json @@ -0,0 +1,66 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:golden_helmet", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 18 + }] + }, + { + "type": "item", + "entryName": "speed 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_swiftness\"}" + }] + }, + { + "type": "item", + "entryName": "regen 2", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_regeneration\"}" + }] + }, + { + "type": "item", + "entryName": "splash heal", + "name": "minecraft:splash_potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:healing\"}" + }] + }, + { + "type": "item", + "entryName": "splash dmg 2", + "name": "minecraft:splash_potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:strong_harming\"}" + }] + }, + { + "type": "item", + "name": "twilightforest:transformation_powder", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:charm_of_life_1" + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/tower_room.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/tower_room.json new file mode 100644 index 0000000000..ef1897289c --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/tower_room.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/tower_room/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/tower_room/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/tower_room/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/tower_room/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/ultrarare.json new file mode 100644 index 0000000000..f86960ef4d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/ultrarare.json @@ -0,0 +1,38 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:golden_axe", + "functions": [{ + "function": "enchant_with_levels", + "treasure": true, + "levels": 20 + }] + }, + { + "type": "item", + "name": "minecraft:ender_pearl" + }, + { + "type": "item", + "name": "minecraft:obsidian", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:diamond" + }, + { + "type": "item", + "name": "twilightforest:moonworm_queen" + }, + { + "type": "item", + "name": "twilightforest:peacock_fan" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/uncommon.json new file mode 100644 index 0000000000..60a9dee7d0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tower_room/uncommon.json @@ -0,0 +1,61 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "entryName": "lvl10", + "name": "minecraft:golden_sword", + "functions": [{ + "function": "enchant_with_levels", + "levels": 10 + }] + }, + { + "type": "item", + "entryName": "lvl7", + "name": "minecraft:golden_sword", + "functions": [{ + "function": "enchant_with_levels", + "levels": 7 + }] + }, + { + "type": "item", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:swiftness\"}" + }] + }, + { + "type": "item", + "entryName": "health", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:healing\"}" + }] + }, + { + "type": "item", + "entryName": "fire", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:fire_resistance\"}" + }] + }, + { + "type": "item", + "entryName": "damage", + "name": "minecraft:potion", + "functions": [{ + "function": "set_nbt", + "tag": "{Potion: \"minecraft:harming\"}" + }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/common.json new file mode 100644 index 0000000000..53a1795cfa --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/common.json @@ -0,0 +1,46 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:poisonous_potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:wheat", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:carrot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:melon", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:water_bucket" + }, + { + "type": "item", + "name": "minecraft:milk_bucket" + }, + { + "type": "item", + "name": "minecraft:melon_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 5 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/rare.json new file mode 100644 index 0000000000..82b5f02581 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/rare.json @@ -0,0 +1,26 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:pumpkin_pie", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "minecraft:apple", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "name": "twilightforest:charm_of_life_1" + }, + { + "type": "item", + "name": "twilightforest:charm_of_keeping_1" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/tree_cache.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/tree_cache.json new file mode 100644 index 0000000000..5080832d3b --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/tree_cache.json @@ -0,0 +1,46 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/useless", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/tree_cache/common", + "weight": 75 + } + ] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/tree_cache/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [ + { + "type": "loot_table", + "name": "twilightforest:structures/tree_cache/ultrarare", + "weight": 25 + }, + { + "type": "loot_table", + "name": "twilightforest:structures/tree_cache/rare", + "weight": 75 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/ultrarare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/ultrarare.json new file mode 100644 index 0000000000..d809d71a40 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/ultrarare.json @@ -0,0 +1,38 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:twilight_sapling", + "entryName": "hollow", + "functions": [{ "function": "set_data", "data": 4 }] + }, + { + "type": "item", + "name": "twilightforest:twilight_sapling", + "entryName": "time", + "functions": [{ "function": "set_data", "data": 5 }] + }, + { + "type": "item", + "name": "twilightforest:twilight_sapling", + "entryName": "trans", + "functions": [{ "function": "set_data", "data": 6 }] + }, + { + "type": "item", + "name": "twilightforest:twilight_sapling", + "entryName": "mining", + "functions": [{ "function": "set_data", "data": 7 }] + }, + { + "type": "item", + "name": "twilightforest:twilight_sapling", + "entryName": "sorting", + "functions": [{ "function": "set_data", "data": 8 }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/uncommon.json new file mode 100644 index 0000000000..e3c084c2b9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/tree_cache/uncommon.json @@ -0,0 +1,49 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:firefly", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 12 } }] + }, + { + "type": "item", + "entryName": "oak", + "name": "twilightforest:twilight_sapling", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 4 } }, + { "function": "set_data", "data": 0 } + ] + }, + { + "type": "item", + "entryName": "canopy", + "name": "twilightforest:twilight_sapling", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 4 } }, + { "function": "set_data", "data": 1 } + ] + }, + { + "type": "item", + "entryName": "mangrove", + "name": "twilightforest:twilight_sapling", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 4 } }, + { "function": "set_data", "data": 2 } + ] + }, + { + "type": "item", + "entryName": "dark", + "name": "twilightforest:twilight_sapling", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 4 } }, + { "function": "set_data", "data": 3 } + ] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/common.json new file mode 100644 index 0000000000..5f1a10251b --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/common.json @@ -0,0 +1,46 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:red_mushroom", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:brown_mushroom", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:wheat_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:carrot", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:potato", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:melon_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:dye", + "functions": [ + { "function": "set_count", "count": { "min": 1, "max": 12 } }, + { "function": "set_data", "data": 15 } + ] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/rare.json new file mode 100644 index 0000000000..1991560edd --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/rare.json @@ -0,0 +1,12 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:magic_beans" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/troll_garden.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/troll_garden.json new file mode 100644 index 0000000000..d04e65c0ab --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/troll_garden.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/troll_garden/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/troll_garden/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/troll_garden/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/uncommon.json new file mode 100644 index 0000000000..4012cb6b3c --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_garden/uncommon.json @@ -0,0 +1,13 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:uberous_soil", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/common.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/common.json new file mode 100644 index 0000000000..125933fac3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/common.json @@ -0,0 +1,23 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:coal", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 32 } }] + }, + { + "type": "item", + "name": "twilightforest:torchberries", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 16 } }] + }, + { + "type": "item", + "name": "minecraft:emerald", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/rare.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/rare.json new file mode 100644 index 0000000000..0158699cd3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/rare.json @@ -0,0 +1,12 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:lamp_of_cinders" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/troll_vault.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/troll_vault.json new file mode 100644 index 0000000000..133ca6c95d --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/troll_vault.json @@ -0,0 +1,30 @@ +{ + "pools": [ + { + "name": "common", + "rolls": 4, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/troll_vault/common" + }] + }, + + { + "name": "uncommon", + "rolls": 2, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/troll_vault/uncommon" + }] + }, + + { + "name": "rare", + "rolls": 1, + "entries": [{ + "type": "loot_table", + "name": "twilightforest:structures/troll_vault/rare" + }] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/uncommon.json b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/uncommon.json new file mode 100644 index 0000000000..be1f9fceec --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/troll_vault/uncommon.json @@ -0,0 +1,18 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "twilightforest:trollsteinn", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + }, + { + "type": "item", + "name": "minecraft:obsidian", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 6 } }] + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/loot_tables/structures/useless.json b/src/main/resources/assets/twilightforest/loot_tables/structures/useless.json new file mode 100644 index 0000000000..26e4dffd08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/loot_tables/structures/useless.json @@ -0,0 +1,56 @@ +{ + "pools": [{ + "name": "main", + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:red_flower", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:yellow_flower", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:feather", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 3 } }] + }, + { + "type": "item", + "name": "minecraft:wheat_seeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:flint", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:cactus", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 2 } }] + }, + { + "type": "item", + "name": "minecraft:reeds", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:sand", + "functions": [{ "function": "set_count", "count": { "min": 1, "max": 4 } }] + }, + { + "type": "item", + "name": "minecraft:flower_pot" + }, + { + "type": "item", + "name": "minecraft:dye" + } + ] + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/materials/fierymetal.json b/src/main/resources/assets/twilightforest/materials/fierymetal.json new file mode 100644 index 0000000000..62df46eb21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/materials/fierymetal.json @@ -0,0 +1,28 @@ +{ + "type": "fierymetal", + "parameters": { + "min_max_texture": false, + "gradient_map" : [ + { + "node" : "1.0", + "color" : "080606" + }, + { + "node" : "0.75", + "color" : "191313" + }, + { + "node" : "0.50", + "color" : "3c2323" + }, + { + "node" : "0.35", + "color" : "fffa96" + }, + { + "node" : "0.2", + "color" : "fb9624" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/materials/knightmetal.json b/src/main/resources/assets/twilightforest/materials/knightmetal.json new file mode 100644 index 0000000000..aa495854b0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/materials/knightmetal.json @@ -0,0 +1,8 @@ +{ + "type": "multicolor", + "parameters": { + "dark": "cccccc", + "mid": "c4d6ae", + "bright": "e7fccd" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/materials/nagascale.json b/src/main/resources/assets/twilightforest/materials/nagascale.json new file mode 100644 index 0000000000..6cd59042d6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/materials/nagascale.json @@ -0,0 +1,8 @@ +{ + "type": "multicolor", + "parameters": { + "dark": "325d25", + "mid": "325d25", + "bright": "577d3f" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/materials/raven_feather.json b/src/main/resources/assets/twilightforest/materials/raven_feather.json new file mode 100644 index 0000000000..3a7790bf60 --- /dev/null +++ b/src/main/resources/assets/twilightforest/materials/raven_feather.json @@ -0,0 +1,25 @@ +{ + "type": "gradient_map_colors", + "suffix": "feather", + "parameters": { + "min_max_texture": true, + "gradient_map" : [ + { + "node" : "1.0", + "color" : "7f848a" + }, + { + "node" : "0.6", + "color" : "474c52" + }, + { + "node" : "0.3", + "color" : "303842" + }, + { + "node" : "0.0", + "color" : "141c26" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/materials/steeleaf.json b/src/main/resources/assets/twilightforest/materials/steeleaf.json new file mode 100644 index 0000000000..92bf8157e0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/materials/steeleaf.json @@ -0,0 +1,6 @@ +{ + "type": "block", + "parameters": { + "texture": "twilightforest:blocks/steelleaf_block" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/castle_door.json b/src/main/resources/assets/twilightforest/models/block/castle_door.json new file mode 100644 index 0000000000..b9f2d18479 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/castle_door.json @@ -0,0 +1,45 @@ +{ + "parent": "block/block", + "textures": { + "particle": "twilightforest:blocks/forcefield_white", + "all2": "twilightforest:blocks/castle_door_rune_corners" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#all" }, + "up": { "texture": "#all" }, + "north": { "texture": "#all" }, + "south": { "texture": "#all" }, + "west": { "texture": "#all" }, + "east": { "texture": "#all" } + } + }, { + "from": [ 0, -0.02, 0 ], + "to": [ 16, 16.02, 16 ], + "shade": false, + "faces": { + "down": { "uvs": [0, 0, 16, 16], "texture": "#all2", "cullface": "down" , "tintindex": 0 }, + "up": { "uvs": [0, 0, 16, 16], "texture": "#all2", "cullface": "up" , "tintindex": 0 } + } + }, { + "from": [ 0, 0, -0.02 ], + "to": [ 16, 16, 16.02 ], + "shade": false, + "faces": { + "north": { "uvs": [0, 0, 16, 16], "texture": "#all2", "cullface": "north", "tintindex": 0 }, + "south": { "uvs": [0, 0, 16, 16], "texture": "#all2", "cullface": "south", "tintindex": 0 } + } + }, { + "from": [ -0.02, 0, 0 ], + "to": [ 16.02, 16, 16 ], + "shade": false, + "faces": { + "west": { "uvs": [0, 0, 16, 16], "texture": "#all2", "cullface": "west" , "tintindex": 0 }, + "east": { "uvs": [0, 0, 16, 16], "texture": "#all2", "cullface": "east" , "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/castleblock_frame.json b/src/main/resources/assets/twilightforest/models/block/castleblock_frame.json new file mode 100644 index 0000000000..57ba003f90 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/castleblock_frame.json @@ -0,0 +1,63 @@ +{ + "parent": "block/block", + "textures": { + "particle": "twilightforest:blocks/castleblock_frame", + "all": "twilightforest:blocks/castleblock_frame", + "all2": "twilightforest:blocks/castle_door_vanished" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#all", "cullface": "down" , "tintindex": 0 }, + "up": { "texture": "#all", "cullface": "up" , "tintindex": 0 }, + "north": { "texture": "#all", "cullface": "north", "tintindex": 0 }, + "south": { "texture": "#all", "cullface": "south", "tintindex": 0 }, + "west": { "texture": "#all", "cullface": "west" , "tintindex": 0 }, + "east": { "texture": "#all", "cullface": "east" , "tintindex": 0 } + } + }, { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#all2", "cullface": "down" , "tintindex": 1 }, + "up": { "texture": "#all2", "cullface": "up" , "tintindex": 1 }, + "north": { "texture": "#all2", "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#all2", "cullface": "south", "tintindex": 1 }, + "west": { "texture": "#all2", "cullface": "west" , "tintindex": 1 }, + "east": { "texture": "#all2", "cullface": "east" , "tintindex": 1 } + } + }, { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#all2", "cullface": "down" , "tintindex": 2 }, + "up": { "texture": "#all2", "cullface": "up" , "tintindex": 2 }, + "north": { "texture": "#all2", "cullface": "north", "tintindex": 2 }, + "south": { "texture": "#all2", "cullface": "south", "tintindex": 2 }, + "west": { "texture": "#all2", "cullface": "west" , "tintindex": 2 }, + "east": { "texture": "#all2", "cullface": "east" , "tintindex": 2 } + } + } + ], + "ctm_version": 1, + "ctm_overrides": { + "0": { "type": "ctm" , "layer": "CUTOUT", "textures": [ "twilightforest:blocks/castleblock_frame_ct" ] }, + "1": { "type": "EDGES_FULL", "layer": "CUTOUT", "textures": [ "twilightforest:blocks/castleblock_frame_edge_v2" ], + "extra": { "connect_to": [ + { "block": "twilightforest:castle_door" }, + { "block": "twilightforest:castle_door_vanished" } + ]} + }, + "2": { "type": "EDGES", "layer": "CUTOUT", "textures": [ + "twilightforest:blocks/castleblock_frame_edge2", + "twilightforest:blocks/castle_door_vanished" + ], + "extra": { "connect_to": [ + { "block": "twilightforest:castle_door" }, + { "block": "twilightforest:castle_door_vanished" } + ] } + } + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_1_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_1_8.json new file mode 100755 index 0000000000..25dbe758f9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_1_8.json @@ -0,0 +1,116 @@ +{ + "parent": "block/block", + "elements": [ + { "from": [ 4, 0, 1 ], + "to": [ 8, 8, 5 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 2, 0, 1 ], + "to": [ 4, 8, 3 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#inside" } + } + }, + { "from": [ 6, 0, 5 ], + "to": [ 8, 8, 7 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 1, 0, 1 ], + "to": [ 2, 8, 2 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#side" } + } + }, + { "from": [ 3, 0, 3 ], + "to": [ 4, 8, 4 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#inside" } + } + }, + { "from": [ 5, 0, 5 ], + "to": [ 6, 8, 6 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#inside" } + } + }, { + "from": [ 7, 0, 7 ], + "to": [ 8, 8, 8 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 4, 8, 1 ], + "to": [ 8, 8, 5 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 2, 8, 1 ], + "to": [ 4, 8, 3 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 6, 8, 5 ], + "to": [ 8, 8, 7 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 1, 8, 1 ], + "to": [ 2, 8, 2 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 3, 8, 3 ], + "to": [ 4, 8, 4 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 5, 8, 5 ], + "to": [ 6, 8, 6 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 7, 8, 7 ], + "to": [ 8, 8, 8 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_2_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_2_8.json new file mode 100755 index 0000000000..1065190ab5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_2_8.json @@ -0,0 +1,23 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 1, 0, 1 ], + "to": [ 8, 8, 8 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 1, 8, 1 ], + "to": [ 8, 8, 8 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_3_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_3_8.json new file mode 100755 index 0000000000..988f9198e3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_3_8.json @@ -0,0 +1,115 @@ +{ + "parent": "block/block", + "elements": [ + { "from": [ 1, 0, 1 ], + "to": [ 8, 8, 9 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 1, 0, 9 ], + "to": [ 5, 8, 12 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 1, 0, 12 ], + "to": [ 3, 8, 14 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 5, 0, 9 ], + "to": [ 7, 8, 10 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 1, 0, 14 ], + "to": [ 2, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 3, 0, 12 ], + "to": [ 4, 8, 13 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 5, 0, 10 ], + "to": [ 6, 8, 11 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "south": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 1, 8, 1 ], + "to": [ 8, 8, 9 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 1, 8, 9 ], + "to": [ 5, 8, 12 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 1, 0, 12 ], + "to": [ 3, 8, 14 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 5, 8, 9 ], + "to": [ 7, 8, 10 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 1, 8, 14 ], + "to": [ 2, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 3, 8, 12 ], + "to": [ 4, 8, 13 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 5, 8, 10 ], + "to": [ 6, 8, 11 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_4_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_4_8.json new file mode 100755 index 0000000000..54268c9c14 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_4_8.json @@ -0,0 +1,24 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 1, 0, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, + { + "from": [ 1, 8, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_5_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_5_8.json new file mode 100755 index 0000000000..cc31a91d4f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_5_8.json @@ -0,0 +1,132 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 1, 0, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 8, 0, 11 ], + "to": [ 12, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "south": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 12, 0, 13 ], + "to": [ 14, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "south": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 8, 0, 9 ], + "to": [ 10, 8, 11 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 8, 0, 8 ], + "to": [ 9, 8, 9 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 10, 0, 10 ], + "to": [ 11, 8, 11 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 12, 0, 12 ], + "to": [ 13, 8, 13 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 14, 0, 14 ], + "to": [ 15, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "south": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { + "from": [ 1, 8, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 8, 8, 11 ], + "to": [ 12, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 12, 8, 13 ], + "to": [ 14, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 8, 8, 9 ], + "to": [ 10, 8, 11 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 8, 8, 8 ], + "to": [ 9, 8, 9 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 10, 8, 10 ], + "to": [ 11, 8, 11 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 12, 8, 12 ], + "to": [ 13, 8, 13 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 14, 8, 14 ], + "to": [ 15, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_6_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_6_8.json new file mode 100755 index 0000000000..fe6913d0c0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_6_8.json @@ -0,0 +1,38 @@ +{ + "parent": "block/block", + "elements": [ + { "from": [ 1, 0, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, { + "from": [ 8, 0, 8 ], + "to": [ 15, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "south": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, { + "from": [ 1, 8, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 8, 8, 8 ], + "to": [ 15, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_7_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_7_8.json new file mode 100755 index 0000000000..7390e9b7da --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_7_8.json @@ -0,0 +1,131 @@ +{ + "parent": "block/block", + "elements": [ + { "from": [ 1, 0, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#inside" } + } + }, + { "from": [ 8, 0, 7 ], + "to": [ 15, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "south": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 11, 0, 4 ], + "to": [ 15, 8, 7 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "west": { "texture": "#inside" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 9, 0, 6 ], + "to": [ 11, 8, 7 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "west": { "texture": "#inside" } + } + }, + { "from": [ 13, 0, 2 ], + "to": [ 15, 8, 4 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "west": { "texture": "#inside" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 10, 0, 5 ], + "to": [ 11, 8, 6 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "west": { "texture": "#inside" } + } + }, + { "from": [ 12, 0, 3 ], + "to": [ 13, 8, 4 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#inside" }, + "west": { "texture": "#inside" } + } + }, { + "from": [ 14, 0, 1 ], + "to": [ 15, 8, 2 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "west": { "texture": "#inside" }, + "east": { "texture": "#side" } + } + }, + { "from": [ 1, 8, 1 ], + "to": [ 8, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 8, 8, 7 ], + "to": [ 15, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 11, 8, 4 ], + "to": [ 15, 8, 7 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 9, 8, 6 ], + "to": [ 11, 8, 7 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 13, 8, 2 ], + "to": [ 15, 8, 4 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 10, 8, 5 ], + "to": [ 11, 8, 6 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, + { "from": [ 12, 8, 3 ], + "to": [ 13, 8, 4 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 14, 8, 1 ], + "to": [ 15, 8, 2 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/experiment115_8_8.json b/src/main/resources/assets/twilightforest/models/block/experiment115_8_8.json new file mode 100755 index 0000000000..14cbc0a77e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/experiment115_8_8.json @@ -0,0 +1,29 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 1, 0, 1 ], + "to": [ 15, 8, 15 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" }, + "north": { "texture": "#side" }, + "south": { "texture": "#side" }, + "west": { "texture": "#side" }, + "east": { "texture": "#side" } + } + }, { + "from": [ 1, 8, 1 ], + "to": [ 15, 8, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + }, { + "from": [ 1, 8, 1 ], + "to": [ 15, 8.02, 15 ], + "faces": { + "up": { "texture": "#top_2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/fallenleaves.json b/src/main/resources/assets/twilightforest/models/block/fallenleaves.json new file mode 100644 index 0000000000..05af474ab2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/fallenleaves.json @@ -0,0 +1,17 @@ +{ + "parent": "block/thin_block", + "textures": { + "particle": "blocks/leaves_spruce", + "texture": "blocks/leaves_spruce" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 0.2, 16 ], + "faces": { + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "tintindex": 0 }, + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/fiery_block.json b/src/main/resources/assets/twilightforest/models/block/fiery_block.json new file mode 100644 index 0000000000..3b97437037 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/fiery_block.json @@ -0,0 +1,101 @@ +{ + "display": { + "gui": { + "rotation": [ 30, 225, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.625, 0.625, 0.625 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0], + "scale":[ 0.25, 0.25, 0.25 ] + }, + "fixed": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 2.5, 0], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 45, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 225, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + }, + "ambientocclusion": false, + "textures": { + "particle": "twilightforest:blocks/fiery_block", + "all": "twilightforest:blocks/fiery_block_inner", + "over": "twilightforest:blocks/fiery_pattern" + }, + "elements": [ + { + "from": [ 0, 1, 0 ], + "to": [ 16, 15, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#all", "tintindex": 0 }, + "up": { "texture": "#all", "tintindex": 0 } + } + }, + { + "from": [ 1, 0, 0 ], + "to": [ 15, 16, 16 ], + "shade": false, + "faces": { + "west": { "texture": "#all", "tintindex": 0 }, + "east": { "texture": "#all", "tintindex": 0 } + } + }, + { + "from": [ 0, 0, 1 ], + "to": [ 16, 16, 15 ], + "shade": false, + "faces": { + "north": { "texture": "#all", "tintindex": 0 }, + "south": { "texture": "#all", "tintindex": 0 } + } + }, + { + "from": [ 16, 16, 16 ], + "to": [ 0, 0, 0 ], + "shade": false, + "faces": { + "down": { "texture": "#over", "cullface": "up" , "tintindex": 1 }, + "up": { "texture": "#over", "cullface": "down" , "tintindex": 1 }, + "north": { "texture": "#over", "cullface": "south", "tintindex": 1 }, + "south": { "texture": "#over", "cullface": "north", "tintindex": 1 }, + "west": { "texture": "#over", "cullface": "east" , "tintindex": 1 }, + "east": { "texture": "#over", "cullface": "west" , "tintindex": 1 } + } + } + ], + "ctm_version_": 1, + "ctm_overrides": { + "0": { + "type": "ctm", + "layer": "CUTOUT", + "textures": [ "twilightforest:blocks/fiery_block_inner_ctm" ], + "extra": { + "light": 15, + "connect_inside": true + } + }, + "1": { + "type": "pattern", + "extra": { + "light": 15, + "size": 2 + } + } + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/iron_ladder.json b/src/main/resources/assets/twilightforest/models/block/iron_ladder.json new file mode 100644 index 0000000000..81f7dc52d3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/iron_ladder.json @@ -0,0 +1,179 @@ +{ + "ambientocclusion": false, + "display": { + "gui": { + "rotation" : [ 0, 180, 0 ] + }, + "ground": { + "rotation" : [ 0 , 0 , 0 ], + "translation": [ 0 , 4 , -3.5 ], + "scale" : [ 0.5, 0.5, 0.5 ] + }, + "head": { + "rotation" : [ 0, 0, 0 ], + "translation": [ 0, 13, 7 ], + "scale" : [ 1, 1, 1 ] + }, + "thirdperson_righthand": { + "rotation" : [ 0 , 180 , 0 ], + "translation": [ 0 , 3 , 5.4 ], + "scale" : [ 0.55, 0.55, 0.55 ] + }, + "firstperson_righthand": { + "rotation" : [ 0, -90, 25 ], + "translation": [ 6.57, 3.2, 1.13 ], + "scale" : [ 0.68, 0.68, 0.68 ] + }, + "fixed": { + "rotation" : [ 0, 0, 0 ], + "translation": [ 0, 0, -7 ], + "scale" : [ 1, 1, 1 ] + } + }, + "textures": { + "particle": "twilightforest:blocks/ladder_iron" + }, + "elements": [ + { + "from": [ 1, 13, 15.2 ], + "to" : [ 15, 15, 16 ], + "faces": { + "up" : { "uv": [ 15 , 0 , 1 , 0.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 1.2, 1 , 2 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 0 , 15 , 2 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 0 , 1 , 2 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 1 , 0 , 1.8, 2 ], "texture": "#particle" }, + "west" : { "uv": [ 14.2, 0 , 15 , 2 ], "texture": "#particle" } + } + }, { + "from": [ 1, 9, 15.2 ], + "to" : [ 15, 11, 16 ], + "faces": { + "up" : { "uv": [ 15 , 4 , 1 , 4.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 5.2, 1 , 6 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 4 , 15 , 6 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 4 , 1 , 6 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 0 , 4 , 0.8, 6 ], "texture": "#particle" }, + "west" : { "uv": [ 14.2, 4 , 15 , 6 ], "texture": "#particle" } + } + }, { + "from": [ 1, 5, 15.2 ], + "to" : [ 15, 7, 16 ], + "faces": { + "up" : { "uv": [ 15 , 8 , 1 , 8.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 9.2, 1 , 10 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 8 , 15 , 10 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 8 , 1 , 10 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 0 , 8 , 0.8, 10 ], "texture": "#particle" }, + "west" : { "uv": [ 14.2, 8 , 15 , 10 ], "texture": "#particle" } + } + }, { + "from": [ 1, 1, 15.2 ], + "to" : [ 15, 3, 16 ], + "faces": { + "up" : { "uv": [ 15 , 12 , 1 , 12.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 13.2, 1 , 14 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 12 , 15 , 14 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 12 , 1 , 14 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 0 , 12 , 0.8, 14 ], "texture": "#particle" }, + "west" : { "uv": [ 14.2, 12 , 15 , 14 ], "texture": "#particle" } + } + }, { + "from": [ 2, 0.5, 14 ], + "to" : [ 4, 2.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 14, 2, 16 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 14, 4, 16 ], "texture": "#particle" }, + "north": { "uv": [ 2, 14, 4, 16 ], "texture": "#particle" }, + "south": { "uv": [ 2, 16, 4, 14 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 14, 2, 16 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 16, 2, 14 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 2.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 12, 0.5, 14 ], + "to" : [ 14, 2.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 14, 12, 16 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 14, 14, 16 ], "texture": "#particle" }, + "north": { "uv": [ 12, 14, 14, 16 ], "texture": "#particle" }, + "south": { "uv": [ 12, 16, 14, 14 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 14, 12, 16 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 16, 12, 14 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 2.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 2, 4.5, 14 ], + "to" : [ 4, 6.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 10, 2, 12 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 10, 4, 12 ], "texture": "#particle" }, + "north": { "uv": [ 2, 10, 4, 12 ], "texture": "#particle" }, + "south": { "uv": [ 2, 12, 4, 10 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 10, 2, 12 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 12, 2, 10 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 6.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 12, 4.5, 14 ], + "to" : [ 14, 6.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 10, 12, 12 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 10, 14, 12 ], "texture": "#particle" }, + "north": { "uv": [ 12, 10, 14, 12 ], "texture": "#particle" }, + "south": { "uv": [ 12, 12, 14, 10 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 10, 12, 12 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 12, 12, 10 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 6.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 2, 8.5, 14 ], + "to" : [ 4, 10.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 6, 2, 8 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 6, 4, 8 ], "texture": "#particle" }, + "north": { "uv": [ 2, 6, 4, 8 ], "texture": "#particle" }, + "south": { "uv": [ 2, 8, 4, 6 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 6, 2, 8 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 8, 2, 6 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 10.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 12, 8.5, 14 ], + "to" : [ 14, 10.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 6, 12, 8 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 6, 14, 8 ], "texture": "#particle" }, + "north": { "uv": [ 12, 6, 14, 8 ], "texture": "#particle" }, + "south": { "uv": [ 12, 8, 14, 6 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 6, 12, 8 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 8, 12, 6 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 10.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 2, 12.5, 14 ], + "to" : [ 4, 14.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 2, 2, 4 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 2, 4, 4 ], "texture": "#particle" }, + "north": { "uv": [ 2, 2, 4, 4 ], "texture": "#particle" }, + "south": { "uv": [ 2, 4, 4, 2 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 2, 2, 4 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 4, 2, 2 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 14.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 12, 12.5, 14 ], + "to" : [ 14, 14.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 2, 12, 4 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 2, 14, 4 ], "texture": "#particle" }, + "north": { "uv": [ 12, 2, 14, 4 ], "texture": "#particle" }, + "south": { "uv": [ 12, 4, 14, 2 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 2, 12, 4 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 4, 12, 2 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 14.5, 16 ], "axis": "x", "angle": -22.5 } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/iron_ladder_left.json b/src/main/resources/assets/twilightforest/models/block/iron_ladder_left.json new file mode 100644 index 0000000000..b8fe1b240c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/iron_ladder_left.json @@ -0,0 +1,97 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "twilightforest:blocks/ladder_iron" + }, + "elements": [ + { + "from": [ 1, 13, 15.2 ], + "to" : [ 8, 15, 16 ], + "faces": { + "up" : { "uv": [ 8 , 0 , 1 , 0.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8 , 1.2, 1 , 2 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 0 , 8 , 2 ], "texture": "#particle" }, + "south": { "uv": [ 8 , 0 , 1 , 2 ], "texture": "#particle", "cullface": "south" }, + "west" : { "uv": [ 14.2, 0 , 15 , 2 ], "texture": "#particle" } + } + }, { + "from": [ 1, 9, 15.2 ], + "to" : [ 8, 11, 16 ], + "faces": { + "up" : { "uv": [ 8 , 4 , 1 , 4.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8 , 5.2, 1 , 6 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 4 , 8 , 6 ], "texture": "#particle" }, + "south": { "uv": [ 8 , 4 , 1 , 6 ], "texture": "#particle", "cullface": "south" }, + "west" : { "uv": [ 14.2, 4 , 15 , 6 ], "texture": "#particle" } + } + }, { + "from": [ 1, 5, 15.2 ], + "to" : [ 8, 7, 16 ], + "faces": { + "up" : { "uv": [ 8 , 8 , 1 , 8.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8 , 9.2, 1 , 10 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 8 , 8 , 10 ], "texture": "#particle" }, + "south": { "uv": [ 8 , 8 , 1 , 10 ], "texture": "#particle", "cullface": "south" }, + "west" : { "uv": [ 14.2, 8 , 15 , 10 ], "texture": "#particle" } + } + }, { + "from": [ 1, 1, 15.2 ], + "to" : [ 8, 3, 16 ], + "faces": { + "up" : { "uv": [ 8 , 12 , 1 , 12.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8 , 13.2, 1 , 14 ], "texture": "#particle" }, + "north": { "uv": [ 1 , 12 , 8 , 14 ], "texture": "#particle" }, + "south": { "uv": [ 8 , 12 , 1 , 14 ], "texture": "#particle", "cullface": "south" }, + "west" : { "uv": [ 14.2, 12 , 15 , 14 ], "texture": "#particle" } + } + }, { + "from": [ 2, 0.5, 14 ], + "to" : [ 4, 2.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 14, 2, 16 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 14, 4, 16 ], "texture": "#particle" }, + "north": { "uv": [ 2, 14, 4, 16 ], "texture": "#particle" }, + "south": { "uv": [ 2, 16, 4, 14 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 14, 2, 16 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 16, 2, 14 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 2.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 2, 4.5, 14 ], + "to" : [ 4, 6.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 10, 2, 12 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 10, 4, 12 ], "texture": "#particle" }, + "north": { "uv": [ 2, 10, 4, 12 ], "texture": "#particle" }, + "south": { "uv": [ 2, 12, 4, 10 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 10, 2, 12 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 12, 2, 10 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 6.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 2, 8.5, 14 ], + "to" : [ 4, 10.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 6, 2, 8 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 6, 4, 8 ], "texture": "#particle" }, + "north": { "uv": [ 2, 6, 4, 8 ], "texture": "#particle" }, + "south": { "uv": [ 2, 8, 4, 6 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 6, 2, 8 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 8, 2, 6 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 10.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 2, 12.5, 14 ], + "to" : [ 4, 14.5, 16 ], + "faces": { + "up" : { "uv": [ 4, 2, 2, 4 ], "texture": "#particle" }, + "down" : { "uv": [ 2, 2, 4, 4 ], "texture": "#particle" }, + "north": { "uv": [ 2, 2, 4, 4 ], "texture": "#particle" }, + "south": { "uv": [ 2, 4, 4, 2 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 4, 2, 2, 4 ], "texture": "#particle" }, + "west" : { "uv": [ 4, 4, 2, 2 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 14.5, 16 ], "axis": "x", "angle": -22.5 } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/iron_ladder_left_connection.json b/src/main/resources/assets/twilightforest/models/block/iron_ladder_left_connection.json new file mode 100644 index 0000000000..c49d43413b --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/iron_ladder_left_connection.json @@ -0,0 +1,45 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "twilightforest:blocks/ladder_iron" + }, + "elements": [ + { + "from": [ 0, 13, 15.2 ], + "to" : [ 8, 15, 16 ], + "faces": { + "up" : { "uv": [ 8, 0 , 0, 0.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8, 1.2, 0, 2 ], "texture": "#particle" }, + "north": { "uv": [ 0, 0 , 8, 2 ], "texture": "#particle" }, + "south": { "uv": [ 8, 0 , 0, 2 ], "texture": "#particle", "cullface": "south" } + } + }, { + "from": [ 0, 9, 15.2 ], + "to" : [ 8, 11, 16 ], + "faces": { + "up" : { "uv": [ 8, 4 , 0, 4.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8, 5.2, 0, 6 ], "texture": "#particle" }, + "north": { "uv": [ 0, 4 , 8, 6 ], "texture": "#particle" }, + "south": { "uv": [ 8, 4 , 0, 6 ], "texture": "#particle", "cullface": "south" } + } + }, { + "from": [ 0, 5, 15.2 ], + "to" : [ 8, 7, 16 ], + "faces": { + "up" : { "uv": [ 8, 8 , 0, 8.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8, 9.2, 0, 10 ], "texture": "#particle" }, + "north": { "uv": [ 0, 8 , 8, 10 ], "texture": "#particle" }, + "south": { "uv": [ 8, 8 , 0, 10 ], "texture": "#particle", "cullface": "south" } + } + }, { + "from": [ 0, 1, 15.2 ], + "to" : [ 8, 3, 16 ], + "faces": { + "up" : { "uv": [ 8, 12 , 0, 12.8 ], "texture": "#particle" }, + "down" : { "uv": [ 8, 13.2, 0, 14 ], "texture": "#particle" }, + "north": { "uv": [ 0, 12 , 8, 14 ], "texture": "#particle" }, + "south": { "uv": [ 8, 12 , 0, 14 ], "texture": "#particle", "cullface": "south" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/iron_ladder_right.json b/src/main/resources/assets/twilightforest/models/block/iron_ladder_right.json new file mode 100644 index 0000000000..c17b692925 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/iron_ladder_right.json @@ -0,0 +1,97 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "twilightforest:blocks/ladder_iron" + }, + "elements": [ + { + "from": [ 8, 13, 15.2 ], + "to" : [ 15, 15, 16 ], + "faces": { + "up" : { "uv": [ 15 , 0 , 8 , 0.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 1.2, 8 , 2 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 0 , 15 , 2 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 0 , 8 , 2 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 1 , 0 , 1.8, 2 ], "texture": "#particle" } + } + }, { + "from": [ 8, 9, 15.2 ], + "to" : [ 15, 11, 16 ], + "faces": { + "up" : { "uv": [ 15 , 4 , 8 , 4.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 5.2, 8 , 6 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 4 , 15 , 6 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 4 , 8 , 6 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 0 , 4 , 0.8, 6 ], "texture": "#particle" } + } + }, { + "from": [ 8, 5, 15.2 ], + "to" : [ 15, 7, 16 ], + "faces": { + "up" : { "uv": [ 15 , 8 , 8 , 8.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 9.2, 8 , 10 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 8 , 15 , 10 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 8 , 8 , 10 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 0 , 8 , 0.8, 10 ], "texture": "#particle" } + } + }, { + "from": [ 8, 1, 15.2 ], + "to" : [ 15, 3, 16 ], + "faces": { + "up" : { "uv": [ 15 , 12 , 8 , 12.8 ], "texture": "#particle" }, + "down" : { "uv": [ 15 , 13.2, 8 , 14 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 12 , 15 , 14 ], "texture": "#particle" }, + "south": { "uv": [ 15 , 12 , 8 , 14 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 0 , 12 , 0.8, 14 ], "texture": "#particle" } + } + }, { + "from": [ 12, 0.5, 14 ], + "to" : [ 14, 2.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 14, 12, 16 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 14, 14, 16 ], "texture": "#particle" }, + "north": { "uv": [ 12, 14, 14, 16 ], "texture": "#particle" }, + "south": { "uv": [ 12, 16, 14, 14 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 14, 12, 16 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 16, 12, 14 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 2.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 12, 4.5, 14 ], + "to" : [ 14, 6.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 10, 12, 12 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 10, 14, 12 ], "texture": "#particle" }, + "north": { "uv": [ 12, 10, 14, 12 ], "texture": "#particle" }, + "south": { "uv": [ 12, 12, 14, 10 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 10, 12, 12 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 12, 12, 10 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 6.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 12, 8.5, 14 ], + "to" : [ 14, 10.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 6, 12, 8 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 6, 14, 8 ], "texture": "#particle" }, + "north": { "uv": [ 12, 6, 14, 8 ], "texture": "#particle" }, + "south": { "uv": [ 12, 8, 14, 6 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 6, 12, 8 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 8, 12, 6 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 10.5, 16 ], "axis": "x", "angle": -22.5 } + }, { + "from": [ 12, 12.5, 14 ], + "to" : [ 14, 14.5, 16 ], + "faces": { + "up" : { "uv": [ 14, 2, 12, 4 ], "texture": "#particle" }, + "down" : { "uv": [ 12, 2, 14, 4 ], "texture": "#particle" }, + "north": { "uv": [ 12, 2, 14, 4 ], "texture": "#particle" }, + "south": { "uv": [ 12, 4, 14, 2 ], "texture": "#particle", "cullface": "south" }, + "east" : { "uv": [ 14, 2, 12, 4 ], "texture": "#particle" }, + "west" : { "uv": [ 14, 4, 12, 2 ], "texture": "#particle" } + }, + "rotation": { "origin": [ 8, 14.5, 16 ], "axis": "x", "angle": -22.5 } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/iron_ladder_right_connection.json b/src/main/resources/assets/twilightforest/models/block/iron_ladder_right_connection.json new file mode 100644 index 0000000000..cd3ede12aa --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/iron_ladder_right_connection.json @@ -0,0 +1,45 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "twilightforest:blocks/ladder_iron" + }, + "elements": [ + { + "from": [ 8, 13, 15.2 ], + "to" : [ 16, 15, 16 ], + "faces": { + "up" : { "uv": [ 16 , 0 , 8 , 0.8 ], "texture": "#particle" }, + "down" : { "uv": [ 16 , 1.2, 8 , 2 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 0 , 16 , 2 ], "texture": "#particle" }, + "south": { "uv": [ 16 , 0 , 8 , 2 ], "texture": "#particle", "cullface": "south" } + } + }, { + "from": [ 8, 9, 15.2 ], + "to" : [ 16, 11, 16 ], + "faces": { + "up" : { "uv": [ 16 , 4 , 8 , 4.8 ], "texture": "#particle" }, + "down" : { "uv": [ 16 , 5.2, 8 , 6 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 4 , 16 , 6 ], "texture": "#particle" }, + "south": { "uv": [ 16 , 4 , 8 , 6 ], "texture": "#particle", "cullface": "south" } + } + }, { + "from": [ 8, 5, 15.2 ], + "to" : [ 16, 7, 16 ], + "faces": { + "up" : { "uv": [ 16 , 8 , 8 , 8.8 ], "texture": "#particle" }, + "down" : { "uv": [ 16 , 9.2, 8 , 10 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 8 , 16 , 10 ], "texture": "#particle" }, + "south": { "uv": [ 16 , 8 , 8 , 10 ], "texture": "#particle", "cullface": "south" } + } + }, { + "from": [ 8, 1, 15.2 ], + "to" : [ 16, 3, 16 ], + "faces": { + "up" : { "uv": [ 16 , 12 , 8 , 12.8 ], "texture": "#particle" }, + "down" : { "uv": [ 16 , 13.2, 8 , 14 ], "texture": "#particle" }, + "north": { "uv": [ 8 , 12 , 16 , 14 ], "texture": "#particle" }, + "south": { "uv": [ 16 , 12 , 8 , 14 ], "texture": "#particle", "cullface": "south" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/ironwood_block.json b/src/main/resources/assets/twilightforest/models/block/ironwood_block.json new file mode 100644 index 0000000000..78bb0e9fed --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/ironwood_block.json @@ -0,0 +1,33 @@ +{ + "parent": "block/block", + "textures": { + "particle": "twilightforest:blocks/ironwood_pattern", + "all": "twilightforest:blocks/ironwood_pattern", + "over": "twilightforest:blocks/ironwood_block" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#all", "cullface": "down" , "tintindex": 0 }, + "up": { "texture": "#all", "cullface": "up" , "tintindex": 0 }, + "north": { "texture": "#all", "cullface": "north", "tintindex": 0 }, + "south": { "texture": "#all", "cullface": "south", "tintindex": 0 }, + "west": { "texture": "#all", "cullface": "west" , "tintindex": 0 }, + "east": { "texture": "#all", "cullface": "east" , "tintindex": 0 } + } + }, { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#over", "cullface": "down" , "tintindex": 1 }, + "up": { "texture": "#over", "cullface": "up" , "tintindex": 1 }, + "north": { "texture": "#over", "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#over", "cullface": "south", "tintindex": 1 }, + "west": { "texture": "#over", "cullface": "west" , "tintindex": 1 }, + "east": { "texture": "#over", "cullface": "east" , "tintindex": 1 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/jar.json b/src/main/resources/assets/twilightforest/models/block/jar.json new file mode 100755 index 0000000000..559992cade --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/jar.json @@ -0,0 +1,35 @@ +{ + "parent": "block/block", + "textures": { + "particle": "blocks/glass", + "side": "twilightforest:blocks/fireflyjar_side", + "end": "twilightforest:blocks/fireflyjar_top", + "cork": "twilightforest:blocks/fireflyjar_cork" + }, + "elements": [ + { + "from": [ 3, 0, 3 ], + "to": [ 13, 14, 13 ], + "faces": { + "down": { "uv": [ 3, 3, 13, 13 ], "texture": "#end", "cullface": "down" }, + "up": { "uv": [ 3, 3, 13, 13 ], "texture": "#end" }, + "north": { "uv": [ 3, 2, 13, 16 ], "texture": "#side" }, + "south": { "uv": [ 3, 2, 13, 16 ], "texture": "#side" }, + "west": { "uv": [ 3, 2, 13, 16 ], "texture": "#side" }, + "east": { "uv": [ 3, 2, 13, 16 ], "texture": "#side" } + } + }, + { + "from": [ 4, 12, 4 ], + "to": [ 12, 16, 12 ], + "faces": { + "down": { "uv": [ 4, 4, 12, 12 ], "texture": "#cork" }, + "up": { "uv": [ 4, 4, 12, 12 ], "texture": "#cork", "cullface": "up" }, + "north": { "uv": [ 4, 0, 12, 4 ], "texture": "#cork" }, + "south": { "uv": [ 4, 0, 12, 4 ], "texture": "#cork" }, + "west": { "uv": [ 4, 0, 12, 4 ], "texture": "#cork" }, + "east": { "uv": [ 4, 0, 12, 4 ], "texture": "#cork" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/jet.json b/src/main/resources/assets/twilightforest/models/block/jet.json new file mode 100755 index 0000000000..a83ec8c8c0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/jet.json @@ -0,0 +1,22 @@ +{ + "parent": "block/block", + "textures": { + "top": "twilightforest:blocks/firejet_top", + "side": "twilightforest:blocks/firejet_side", + "bottom": "blocks/grass_top" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down", "tintindex": 0 }, + "up": { "texture": "#top", "cullface": "up", "tintindex": 0 }, + "north": { "texture": "#side", "cullface": "north", "tintindex": 0 }, + "south": { "texture": "#side", "cullface": "south", "tintindex": 0 }, + "west": { "texture": "#side", "cullface": "west", "tintindex": 0 }, + "east": { "texture": "#side", "cullface": "east", "tintindex": 0 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/knightmetal_block.json b/src/main/resources/assets/twilightforest/models/block/knightmetal_block.json new file mode 100755 index 0000000000..aecd630a39 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/knightmetal_block.json @@ -0,0 +1,301 @@ +{ + "parent": "block/block", + "textures": { + "particle": "twilightforest:blocks/knightmetal_block", + "all": "twilightforest:blocks/knightmetal_block" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 4, 4, 4 ], + "faces": { + "down": { "uv": [ 0, 12, 4, 16 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "north": { "uv": [ 12, 12, 16, 16 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "west": { "uv": [ 0, 12, 4, 16 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" } + } + }, { + "from": [ 6, 0, 0 ], + "to": [ 10, 4, 4 ], + "faces": { + "down": { "uv": [ 6, 12, 10, 16 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "north": { "uv": [ 6, 12, 10, 16 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "west": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "east": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" } + } + }, { + "from": [ 12, 0, 0 ], + "to": [ 16, 4, 4 ], + "faces": { + "down": { "uv": [ 12, 12, 16, 16 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "north": { "uv": [ 0, 12, 4, 16 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "west": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "east": { "uv": [ 12, 12, 16, 16 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 0, 6 ], + "to": [ 4, 4, 10 ], + "faces": { + "down": { "uv": [ 0, 6, 4, 10 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "north": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "south": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "west": { "uv": [ 6, 12, 10, 16 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" } + } + }, { + "from": [ 6, 0, 6 ], + "to": [ 10, 4, 10 ], + "faces": { + "down": { "uv": [ 6, 6, 10, 10 ], "texture": "#all", "cullface": "down" }, + "north": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "south": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "west": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "east": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" } + } + }, { + "from": [ 12, 0, 6 ], + "to": [ 16, 4, 10 ], + "faces": { + "down": { "uv": [ 12, 6, 16, 10 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "north": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "south": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "west": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "east": { "uv": [ 6, 12, 10, 16 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 0, 12 ], + "to": [ 4, 4, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 4, 4 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "north": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "south": { "uv": [ 0, 12, 4, 16 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 12, 16, 16 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" } + } + }, { + "from": [ 6, 0, 12 ], + "to": [ 10, 4, 16 ], + "faces": { + "down": { "uv": [ 6, 0, 10, 4 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "north": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "south": { "uv": [ 6, 12, 10, 16 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "east": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" } + } + }, { + "from": [ 12, 0, 12 ], + "to": [ 16, 4, 16 ], + "faces": { + "down": { "uv": [ 12, 0, 16, 4 ], "texture": "#all", "cullface": "down" }, + "up": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "north": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "south": { "uv": [ 12, 12, 16, 16 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "east": { "uv": [ 0, 12, 4, 16 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 6, 0 ], + "to": [ 4, 10, 4 ], + "faces": { + "down": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "up": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "north": { "uv": [ 12, 6, 16, 10 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "west": { "uv": [ 0, 6, 4, 10 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" } + } + }, { + "from": [ 6, 6, 0 ], + "to": [ 10, 10, 4 ], + "faces": { + "down": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "up": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "north": { "uv": [ 6, 6, 10, 10 ], "texture": "#all", "cullface": "north" }, + "west": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "east": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" } + } + }, { + "from": [ 12, 6, 0 ], + "to": [ 16, 10, 4 ], + "faces": { + "down": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "up": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "north": { "uv": [ 0, 6, 4, 10 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "west": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "east": { "uv": [ 12, 6, 16, 10 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 6, 6 ], + "to": [ 4, 10, 10 ], + "faces": { + "down": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "up": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "north": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "south": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "west": { "uv": [ 6, 6, 10, 10 ], "texture": "#all", "cullface": "west" } + } + }, { + "from": [ 1, 1, 1 ], + "to": [ 15, 15, 15 ], + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#all" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#all" }, + "north": { "uv": [ 1, 1, 15, 15 ], "texture": "#all" }, + "south": { "uv": [ 1, 1, 15, 15 ], "texture": "#all" }, + "west": { "uv": [ 1, 1, 15, 15 ], "texture": "#all" }, + "east": { "uv": [ 1, 1, 15, 15 ], "texture": "#all" } + } + }, { + "from": [ 12, 6, 6 ], + "to": [ 16, 10, 10 ], + "faces": { + "down": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "up": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "north": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "south": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "east": { "uv": [ 6, 6, 10, 10 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 6, 12 ], + "to": [ 4, 10, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "up": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "north": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "south": { "uv": [ 0, 6, 4, 10 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 6, 16, 10 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" } + } + }, { + "from": [ 6, 6, 12 ], + "to": [ 10, 10, 16 ], + "faces": { + "down": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "up": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "south": { "uv": [ 6, 6, 10, 10 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "east": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" } + } + }, { + "from": [ 12, 6, 12 ], + "to": [ 16, 10, 16 ], + "faces": { + "down": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "up": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "north": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "south": { "uv": [ 12, 6, 16, 10 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "east": { "uv": [ 0, 6, 4, 10 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 12, 0 ], + "to": [ 4, 16, 4 ], + "faces": { + "down": { "uv": [ 0, 12, 4, 16 ], "texture": "#all" }, + "up": { "uv": [ 0, 0, 4, 4 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 12, 0, 16, 4 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "west": { "uv": [ 0, 0, 4, 4 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" } + } + }, { + "from": [ 6, 12, 0 ], + "to": [ 10, 16, 4 ], + "faces": { + "down": { "uv": [ 6, 12, 10, 16 ], "texture": "#all" }, + "up": { "uv": [ 6, 0, 10, 4 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 6, 0, 10, 4 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "west": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "east": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" } + } + }, { + "from": [ 12, 12, 0 ], + "to": [ 16, 16, 4 ], + "faces": { + "down": { "uv": [ 12, 12, 16, 16 ], "texture": "#all" }, + "up": { "uv": [ 12, 0, 16, 4 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 0, 0, 4, 4 ], "texture": "#all", "cullface": "north" }, + "south": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "west": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "east": { "uv": [ 12, 0, 16, 4 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 12, 6 ], + "to": [ 4, 16, 10 ], + "faces": { + "down": { "uv": [ 0, 6, 4, 10 ], "texture": "#all" }, + "up": { "uv": [ 0, 6, 4, 10 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "south": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "west": { "uv": [ 6, 0, 10, 4 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" } + } + }, { + "from": [ 6, 12, 6 ], + "to": [ 10, 16, 10 ], + "faces": { + "up": { "uv": [ 6, 6, 10, 10 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "south": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "west": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "east": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" } + } + }, { + "from": [ 12, 12, 6 ], + "to": [ 16, 16, 10 ], + "faces": { + "down": { "uv": [ 12, 6, 16, 10 ], "texture": "#all" }, + "up": { "uv": [ 12, 6, 16, 10 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "south": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "west": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "east": { "uv": [ 6, 0, 10, 4 ], "texture": "#all", "cullface": "east" } + } + }, { + "from": [ 0, 12, 12 ], + "to": [ 4, 16, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "up": { "uv": [ 0, 12, 4, 16 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "south": { "uv": [ 0, 0, 4, 4 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 0, 16, 4 ], "texture": "#all", "cullface": "west" }, + "east": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" } + } + }, { + "from": [ 6, 12, 12 ], + "to": [ 10, 16, 16 ], + "faces": { + "down": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "up": { "uv": [ 6, 12, 10, 16 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 6, 0, 10, 4 ], "texture": "#all" }, + "south": { "uv": [ 6, 0, 10, 4 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "east": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" } + } + }, { + "from": [ 12, 12, 12 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "up": { "uv": [ 12, 12, 16, 16 ], "texture": "#all", "cullface": "up" }, + "north": { "uv": [ 0, 0, 4, 4 ], "texture": "#all" }, + "south": { "uv": [ 12, 0, 16, 4 ], "texture": "#all", "cullface": "south" }, + "west": { "uv": [ 12, 0, 16, 4 ], "texture": "#all" }, + "east": { "uv": [ 0, 0, 4, 4 ], "texture": "#all", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/mayapple.json b/src/main/resources/assets/twilightforest/models/block/mayapple.json new file mode 100644 index 0000000000..9c0dbd76dd --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/mayapple.json @@ -0,0 +1,26 @@ +{ + "textures": { + "particle": "twilightforest:blocks/cloverpatch", + "stem": "twilightforest:blocks/mayapple_side", + "leaf": "twilightforest:blocks/mayapple" + }, + "elements": [ + { + "from": [ 8, 0, 8 ], + "to": [ 9, 6, 9 ], + "faces": { + "north": { "uv": [ 8, 10, 9, 16 ], "texture": "#stem" }, + "south": { "uv": [ 8, 10, 9, 16 ], "texture": "#stem" }, + "west": { "uv": [ 8, 10, 9, 16 ], "texture": "#stem" }, + "east": { "uv": [ 8, 10, 9, 16 ], "texture": "#stem" } + } + }, { + "from": [ 0, 6, 0 ], + "to": [ 16, 6, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#leaf" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#leaf" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/miniature/naga_courtyard.json b/src/main/resources/assets/twilightforest/models/block/miniature/naga_courtyard.json new file mode 100644 index 0000000000..11548de444 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/miniature/naga_courtyard.json @@ -0,0 +1,330 @@ +{ + "display": { + "gui": { + "rotation": [ 30, 235, 0 ], + "translation": [ 0, 1.5, 0 ], + "scale":[ 1, 1, 1 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0 ], + "scale":[ 0.25, 0.25, 0.25 ] + }, + "fixed": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 4, 1.5], + "scale": [ 0.75, 0.75, 0.75 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 45, 0 ], + "translation": [ 0, 2, 0 ], + "scale": [ 0.75, 0.75, 0.75 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 135, 0 ], + "translation": [ 0, 2, 0 ], + "scale": [ 0.75, 0.75, 0.75 ] + } + }, + "textures": { + "particle": "blocks/dirt", + "dirt": "blocks/dirt", + "grass": "blocks/grass_top", + "grass_side": "blocks/grass_side_overlay", + "stone": "blocks/stone", + "brick": "blocks/stonebrick", + "moss_brick": "blocks/stonebrick_mossy", + "slab_side": "blocks/stone_slab_top", + "slab_top": "blocks/stone_slab_top" + }, + "elements": [ { + "from": [ 1, 2, 1 ], + "to": [ 15, 4, 15 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "from": [ 2, 1, 2 ], + "to": [ 14, 2, 14 ], + "faces": { + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "from": [ 2.5, 0, 2.5 ], + "to": [ 13.5, 1, 13.5 ], + "faces": { + "down": { "texture": "#stone" }, + "north": { "texture": "#stone" }, + "south": { "texture": "#stone" }, + "west": { "texture": "#stone" }, + "east": { "texture": "#stone" } + } + }, { + "from": [ 0, 2, 4 ], + "to": [ 1, 4, 12 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "from": [ 15, 2, 4 ], + "to": [ 16, 4, 12 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "from": [ 4, 2, 0 ], + "to": [ 12, 4, 1 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "from": [ 4, 2, 15 ], + "to": [ 12, 4, 16 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "from": [ 1, 2, 1 ], + "to": [ 15, 4, 15 ], + "faces": { + "north": { "uv": [ 1, 1, 15, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 1, 1, 15, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 1, 1, 15, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 1, 1, 15, 3 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "from": [ 4, 2, 0 ], + "to": [ 12, 4, 1 ], + "faces": { + "north": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 0, 1, 1, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 15, 1, 16, 3 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "from": [ 0, 2, 4 ], + "to": [ 1, 4, 12 ], + "faces": { + "north": { "uv": [ 0, 1, 1, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 15, 1, 16, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "from": [ 4, 2, 15 ], + "to": [ 12, 4, 16 ], + "faces": { + "north": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 15, 1, 16, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 0, 1, 1, 3 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "from": [ 15, 2, 4 ], + "to": [ 16, 4, 12 ], + "faces": { + "north": { "uv": [ 0, 1, 1, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 15, 1, 16, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 4, 1, 12, 3 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "from": [ 2, 4, 13 ], + "to": [ 14, 7, 14 ], + "faces": { + "north": { "texture": "#brick" }, + "south": { "texture": "#brick" } + } + }, { + "from": [ 13, 4, 2 ], + "to": [ 14, 7, 14 ], + "faces": { + "west": { "texture": "#brick" }, + "east": { "texture": "#brick" } + } + }, { + "from": [ 2, 4, 2 ], + "to": [ 14, 7, 3 ], + "faces": { + "north": { "texture": "#brick" }, + "south": { "texture": "#brick" } + } + }, { + "from": [ 2, 4, 2 ], + "to": [ 3, 7, 14 ], + "faces": { + "west": { "texture": "#brick" }, + "east": { "texture": "#brick" } + } + }, { + "from": [ 2, 7, 13 ], + "to": [ 14, 8, 14 ], + "faces": { + "up": { "texture": "#slab_top" }, + "north": { "texture": "#slab_side" }, + "south": { "texture": "#slab_side" }, + "west": { "texture": "#slab_side" }, + "east": { "texture": "#slab_side" } + } + }, { + "from": [ 13, 7, 3 ], + "to": [ 14, 8, 13 ], + "faces": { + "up": { "texture": "#slab_top" }, + "west": { "texture": "#slab_side" }, + "east": { "texture": "#slab_side" } + } + }, { + "from": [ 2, 7, 2 ], + "to": [ 14, 8, 3 ], + "faces": { + "up": { "texture": "#slab_top" }, + "north": { "texture": "#slab_side" }, + "south": { "texture": "#slab_side" }, + "west": { "texture": "#slab_side" }, + "east": { "texture": "#slab_side" } + } + }, { + "from": [ 2, 7, 3 ], + "to": [ 3, 8, 13 ], + "faces": { + "up": { "texture": "#slab_top" }, + "west": { "texture": "#slab_side" }, + "east": { "texture": "#slab_side" } + } + }, { + "__COMMENT": "START PILLAR 1", + "from": [ 5.5, 4, 5.5 ], + "to": [ 6.5, 10, 6.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "north": { "texture": "#moss_brick" }, + "south": { "texture": "#moss_brick" }, + "west": { "texture": "#moss_brick" }, + "east": { "texture": "#moss_brick" } + } + }, { + "from": [ 4.5, 10 , 4.5 ], + "to": [ 7.5, 10.5, 7.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "down": { "texture": "#slab_top" }, + "north": { "texture": "#slab_top" }, + "south": { "texture": "#slab_top" }, + "west": { "texture": "#slab_top" }, + "east": { "texture": "#slab_top" } + } + }, { + "from": [ 4.5, 4 , 4.5 ], + "to": [ 7.5, 4.5, 7.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "down": { "texture": "#slab_top" }, + "north": { "texture": "#slab_top" }, + "south": { "texture": "#slab_top" }, + "west": { "texture": "#slab_top" }, + "east": { "texture": "#slab_top" } + } + }, { + "__COMMENT": "START PILLAR 2", + "from": [ 10.5, 4, 6.5 ], + "to": [ 11.5, 10, 7.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "north": { "texture": "#moss_brick" }, + "south": { "texture": "#moss_brick" }, + "west": { "texture": "#moss_brick" }, + "east": { "texture": "#moss_brick" } + } + }, { + "from": [ 9.5, 10 , 5.5 ], + "to": [ 12.5, 10.5, 8.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "down": { "texture": "#slab_top" }, + "north": { "texture": "#slab_top" }, + "south": { "texture": "#slab_top" }, + "west": { "texture": "#slab_top" }, + "east": { "texture": "#slab_top" } + } + }, { + "from": [ 9.5, 4 , 5.5 ], + "to": [ 12.5, 4.5, 8.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "down": { "texture": "#slab_top" }, + "north": { "texture": "#slab_top" }, + "south": { "texture": "#slab_top" }, + "west": { "texture": "#slab_top" }, + "east": { "texture": "#slab_top" } + } + }, { + "__COMMENT": "START PILLAR 3", + "from": [ 6.5, 4, 10.5 ], + "to": [ 7.5, 10, 11.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "north": { "texture": "#moss_brick" }, + "south": { "texture": "#moss_brick" }, + "west": { "texture": "#moss_brick" }, + "east": { "texture": "#moss_brick" } + } + }, { + "from": [ 5.5, 10 , 9.5 ], + "to": [ 8.5, 10.5, 12.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "down": { "texture": "#slab_top" }, + "north": { "texture": "#slab_top" }, + "south": { "texture": "#slab_top" }, + "west": { "texture": "#slab_top" }, + "east": { "texture": "#slab_top" } + } + }, { + "from": [ 5.5, 4 , 9.5 ], + "to": [ 8.5, 4.5, 12.5 ], + "faces": { + "up": { "texture": "#slab_top" }, + "down": { "texture": "#slab_top" }, + "north": { "texture": "#slab_top" }, + "south": { "texture": "#slab_top" }, + "west": { "texture": "#slab_top" }, + "east": { "texture": "#slab_top" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/miniature/portal.json b/src/main/resources/assets/twilightforest/models/block/miniature/portal.json new file mode 100644 index 0000000000..cfab2aa87f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/miniature/portal.json @@ -0,0 +1,254 @@ +{ + "display": { + "gui": { + "rotation": [ 30, 235, 0 ], + "translation": [ 0, 1.5, 0], + "scale":[ 1.1, 1.1, 1.1 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0], + "scale":[ 0.25, 0.25, 0.25 ] + }, + "fixed": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 4, 1.5], + "scale": [ 0.75, 0.75, 0.75 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 45, 0 ], + "translation": [ 0, 2, 0 ], + "scale": [ 0.75, 0.75, 0.75 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 135, 0 ], + "translation": [ 0, 2, 0 ], + "scale": [ 0.75, 0.75, 0.75 ] + } + }, + "textures": { + "particle": "blocks/dirt", + "portal": "blocks/portal", + "dirt": "blocks/dirt", + "grass": "blocks/grass_top", + "grass_side": "blocks/grass_side_overlay", + "stone": "blocks/stone", + "plant": "blocks/flower_rose" + }, + "elements": [ { + "from": [ 4, 0, 4 ], + "to": [ 12, 3, 12 ], + "faces": { + "up": { "texture": "#dirt" }, + "down": { "texture": "#stone" }, + "north": { "texture": "#stone" }, + "south": { "texture": "#stone" }, + "west": { "texture": "#stone" }, + "east": { "texture": "#stone" } + } + }, { + "__comment": "TOP CORNER", + "from": [ 2, 2, 11 ], + "to": [ 5, 7, 14 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "TOP CORNER GRASS", + "from": [ 2, 2, 11 ], + "to": [ 5, 7, 14 ], + "faces": { + "north": { "uv": [ 0, 1, 3, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 0, 1, 3, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 0, 1, 3, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 0, 1, 3, 6 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "__comment": "TOP LEFT EDGE", + "from": [ 5, 1, 12 ], + "to": [ 11, 7, 15 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "TOP RIGHT EDGE", + "from": [ 1, 1, 5 ], + "to": [ 4, 7, 11 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "TOP LEFT EDGE GRASS", + "from": [ 5, 1, 12 ], + "to": [ 11, 7, 15 ], + "faces": { + "north": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 6, 1, 12, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 6, 1, 12, 7 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "__comment": "TOP RIGHT EDGE GRASS", + "from": [ 1, 1, 5 ], + "to": [ 4, 7, 11 ], + "faces": { + "north": { "uv": [ 10, 1, 16, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 10, 1, 16, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "from": [ 4, 6, 4 ], + "to": [ 12, 6, 12 ], + "faces": { "up": { "texture": "#portal" } } + }, { + "__comment": "RIGHT CORNER", + "from": [ 2, 2, 2 ], + "to": [ 5, 7, 5 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "LEFT CORNER", + "from": [ 11, 2, 11 ], + "to": [ 14, 7, 14 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "RIGHT CORNER GRASS", + "from": [ 2, 2, 2 ], + "to": [ 5, 7, 5 ], + "faces": { + "north": { "uv": [ 12, 1, 15, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 12, 1, 15, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 12, 1, 15, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 12, 1, 15, 6 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "__comment": "LEFT CORNER GRASS", + "from": [ 11, 2, 11 ], + "to": [ 14, 7, 14 ], + "faces": { + "north": { "uv": [ 6, 1, 9, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 6, 1, 9, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 6, 1, 9, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 6, 1, 9, 6 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "__comment": "BOTTOM RIGHT EDGE", + "from": [ 5, 1, 1 ], + "to": [ 11, 7, 4 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "BOTTOM LEFT EDGE", + "from": [ 12, 1, 5 ], + "to": [ 15, 7, 11 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "BOTTOM RIGHT EDGE GRASS", + "from": [ 5, 1, 1 ], + "to": [ 11, 7, 4 ], + "faces": { + "north": { "uv": [ 10, 1, 16, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 10, 1, 16, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "__comment": "BOTTOM LEFT EDGE GRASS", + "from": [ 12, 1, 5 ], + "to": [ 15, 7, 11 ], + "faces": { + "north": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 0, 1, 3, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 6, 1, 12, 7 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 6, 1, 12, 7 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "__comment": "BOTTOM CORNER", + "from": [ 11, 2, 2 ], + "to": [ 14, 7, 5 ], + "faces": { + "up": { "texture": "#grass", "tintindex": 0 }, + "down": { "texture": "#dirt" }, + "north": { "texture": "#dirt" }, + "south": { "texture": "#dirt" }, + "west": { "texture": "#dirt" }, + "east": { "texture": "#dirt" } + } + }, { + "__comment": "BOTTOM CORNER GRASS", + "from": [ 10.98, 2, 1.98 ], + "to": [ 14.02, 7, 5.02 ], + "faces": { + "north": { "uv": [ 2, 1, 5, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "south": { "uv": [ 2, 1, 5, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "west": { "uv": [ 9, 1, 12, 6 ], "texture": "#grass_side", "tintindex": 0 }, + "east": { "uv": [ 9, 1, 12, 6 ], "texture": "#grass_side", "tintindex": 0 } + } + }, { + "from": [ -2, 7, 4 ], + "to": [ 10, 19, 4 ], + "shade": false, + "rotation": { "origin": [ 4, 0, 4 ], "axis": "y", "angle": 45 }, + "faces": { + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#plant" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#plant" } + } + }, { + "from": [ 4, 7, -2 ], + "to": [ 4, 19, 10 ], + "shade": false, + "rotation": { "origin": [ 4, 0, 4 ], "axis": "y", "angle": 45 }, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#plant" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#plant" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/miniature/twilight_lich_tower.json b/src/main/resources/assets/twilightforest/models/block/miniature/twilight_lich_tower.json new file mode 100644 index 0000000000..de3b2ad878 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/miniature/twilight_lich_tower.json @@ -0,0 +1,271 @@ +{ + "__comment": "Made by Chaonic for the Twilight Forest <3", + "display": { + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 2.5, 0 ], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "thirdperson_lefthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 2.5, 0 ], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 45, 0 ], + "scale": [ 0.4, 0.4, 0.4 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 45, 0 ], + "scale": [ 0.4, 0.4, 0.4 ] + }, + "gui": { + "rotation": [ 30, 45, 0 ], + "translation": [ 0.75, -0.25, 0 ] + }, + "head": { + "rotation": [ 0, 180, 0 ], + "translation": [ 0, 14.75, 0 ] + }, + "ground": { + "translation": [ 0, 2, 0 ], + "scale": [ 0.5, 0.5, 0.5 ] + }, + "fixed": { + "rotation": [ 0, -90, 0 ], + "translation": [ 0, 0, -2.086 ] + } + }, + "textures": { + "particle": "blocks/stonebrick", + "birchwood": "blocks/planks_birch", + "oakwood": "blocks/planks_oak", + "stonebricks": "blocks/stonebrick" + }, + "elements": [ + { + "from": [ 8, 0, 3 ], + "to": [ 13, 8, 8 ], + "faces": { + "down": { "uv": [ 8, 8, 13, 13 ], "texture": "#stonebricks" }, + "north": { "uv": [ 3, 8, 8, 16 ], "texture": "#stonebricks" }, + "south": { "uv": [ 8, 8, 13, 16 ], "texture": "#stonebricks" }, + "west": { "uv": [ 3, 8, 8, 16 ], "texture": "#stonebricks" }, + "east": { "uv": [ 8, 8, 13, 16 ], "texture": "#stonebricks" } + } + }, + { + "from": [ 7.5, 8, 2.5 ], + "to": [ 13.5, 9, 8.5 ], + "faces": { + "down": { "uv": [ 7.5, 7.5, 13.5, 13.5 ], "texture": "#birchwood" }, + "up": { "uv": [ 7.5, 2.5, 13.5, 8.5 ], "texture": "#birchwood" }, + "north": { "uv": [ 2.5, 7, 8.5, 8 ], "texture": "#birchwood" }, + "south": { "uv": [ 7.5, 7, 13.5, 8 ], "texture": "#birchwood" }, + "west": { "uv": [ 2.5, 7, 8.5, 8 ], "texture": "#birchwood" }, + "east": { "uv": [ 7.5, 7, 13.5, 8 ], "texture": "#birchwood" } + } + }, + { + "from": [ 10.5, 3.5, 8 ], + "to": [ 12.5, 6, 10 ], + "faces": { + "down": { "uv": [ 10.5, 6, 12.5, 8 ], "texture": "#stonebricks" }, + "up": { "uv": [ 10.5, 8, 12.5, 10 ], "texture": "#stonebricks" }, + "south": { "uv": [ 10.5, 10, 12.5, 12.5 ], "texture": "#stonebricks" }, + "west": { "uv": [ 8, 10, 10, 12.5 ], "texture": "#stonebricks" }, + "east": { "uv": [ 6, 10, 8, 12.5 ], "texture": "#stonebricks" } + } + }, + { + "from": [ 8.5, 5.5, 8 ], + "to": [ 10, 7, 10.5 ], + "faces": { + "down": { "uv": [ 8.5, 5.5, 10, 8 ], "texture": "#stonebricks" }, + "up": { "uv": [ 8.5, 8, 10, 10.5 ], "texture": "#stonebricks" }, + "west": { "uv": [ 8, 9, 10.5, 10.5 ], "texture": "#stonebricks" }, + "east": { "uv": [ 5.5, 9, 8, 10.5 ], "texture": "#stonebricks" } + } + }, + { + "from": [ 3.5, 4.5, 2.5 ], + "to": [ 6, 8, 5 ], + "faces": { + "down": { "uv": [ 3.5, 11, 6, 13.5 ], "texture": "#stonebricks" }, + "north": { "uv": [ 10, 8, 12.5, 11.5 ], "texture": "#stonebricks" }, + "south": { "uv": [ 3.5, 8, 6, 11.5 ], "texture": "#stonebricks" }, + "west": { "uv": [ 2.5, 8, 5, 11.5 ], "texture": "#stonebricks" }, + "east": { "uv": [ 11, 8, 13.5, 11.5 ], "texture": "#stonebricks" } + } + }, + { + "from": [ 5.5, 0, 4.5 ], + "to": [ 8, 3.5, 7.5 ], + "faces": { + "down": { "uv": [ 5.5, 8.5, 8, 11.5 ], "texture": "#stonebricks" }, + "up": { "uv": [ 5.5, 4.5, 8, 7.5 ], "texture": "#stonebricks" }, + "north": { "uv": [ 8, 12.5, 10.5, 16 ], "texture": "#stonebricks" }, + "south": { "uv": [ 5.5, 12.5, 8, 16 ], "texture": "#stonebricks" }, + "west": { "uv": [ 4.5, 12.5, 7.5, 16 ], "texture": "#stonebricks" } + } + }, + { + "from": [ 6, 5, 3.5 ], + "to": [ 8, 6.5, 4.5 ], + "faces": { + "down": { "uv": [ 6, 11.5, 8, 12.5 ], "texture": "#stonebricks" }, + "up": { "uv": [ 6, 3.5, 8, 4.5 ], "texture": "#stonebricks" }, + "north": { "uv": [ 8, 9.5, 10, 11 ], "texture": "#stonebricks" }, + "south": { "uv": [ 6, 9.5, 8, 11 ], "texture": "#stonebricks" } + } + }, + { + "from": [ 5.5, 3.5, 7 ], + "to": [ 8, 4, 7.5 ], + "faces": { + "up": { "uv": [ 5.5, 7, 8, 7.5 ], "texture": "#oakwood" }, + "north": { "uv": [ 8, 12, 10.5, 12.5 ], "texture": "#oakwood" }, + "south": { "uv": [ 5.5, 12, 8, 12.5 ], "texture": "#oakwood" }, + "west": { "uv": [ 7, 12, 7.5, 12.5 ], "texture": "#oakwood" } + } + }, + { + "from": [ 5.5, 3.5, 4.5 ], + "to": [ 8, 4, 5 ], + "faces": { + "up": { "uv": [ 5.5, 4.5, 8, 5 ], "texture": "#oakwood" }, + "north": { "uv": [ 8, 12, 10.5, 12.5 ], "texture": "#oakwood" }, + "south": { "uv": [ 5.5, 12, 8, 12.5 ], "texture": "#oakwood" }, + "west": { "uv": [ 4.5, 12, 5, 12.5 ], "texture": "#oakwood" } + } + }, + { + "from": [ 5.5, 3.5, 5 ], + "to": [ 6, 4, 7 ], + "faces": { + "up": { "uv": [ 5.5, 5, 6, 7 ], "texture": "#oakwood" }, + "west": { "uv": [ 5, 12, 7, 12.5 ], "texture": "#oakwood" }, + "east": { "uv": [ 9, 12, 11, 12.5 ], "texture": "#oakwood" } + } + }, + { + "from": [ 10.5, 6, 8 ], + "to": [ 11, 6.5, 10 ], + "faces": { + "up": { "uv": [ 10.5, 8, 11, 10 ], "texture": "#oakwood" }, + "south": { "uv": [ 10.5, 9.5, 11, 10 ], "texture": "#oakwood" }, + "west": { "uv": [ 8, 9.5, 10, 10 ], "texture": "#oakwood" }, + "east": { "uv": [ 6, 9.5, 8, 10 ], "texture": "#oakwood" } + } + }, + { + "from": [ 12, 6, 8 ], + "to": [ 12.5, 6.5, 10 ], + "faces": { + "up": { "uv": [ 12, 8, 12.5, 10 ], "texture": "#oakwood" }, + "south": { "uv": [ 12, 9.5, 12.5, 10 ], "texture": "#oakwood" }, + "west": { "uv": [ 8, 9.5, 10, 10 ], "texture": "#oakwood" }, + "east": { "uv": [ 6, 9.5, 8, 10 ], "texture": "#oakwood" } + } + }, + { + "from": [ 11, 6, 9.5 ], + "to": [ 12, 6.5, 10 ], + "faces": { + "up": { "uv": [ 11, 9.5, 12, 10 ], "texture": "#oakwood" }, + "north": { "uv": [ 4, 9.5, 5, 10 ], "texture": "#oakwood" }, + "south": { "uv": [ 11, 9.5, 12, 10 ], "texture": "#oakwood" } + } + }, + { + "from": [ 3, 8, 2 ], + "to": [ 6.5, 9.5, 5.5 ], + "faces": { + "down": { "uv": [ 3, 10.5, 6.5, 14 ], "texture": "#birchwood" }, + "up": { "uv": [ 3, 2, 6.5, 5.5 ], "texture": "#birchwood" }, + "north": { "uv": [ 9.5, 6.5, 13, 8 ], "texture": "#birchwood" }, + "south": { "uv": [ 3, 6.5, 6.5, 8 ], "texture": "#birchwood" }, + "west": { "uv": [ 2, 6.5, 5.5, 8 ], "texture": "#birchwood" }, + "east": { "uv": [ 10.5, 6.5, 14, 8 ], "texture": "#birchwood" } + } + }, + { + "from": [ 4, 9.5, 3 ], + "to": [ 5.5, 12, 4.5 ], + "faces": { + "up": { "uv": [ 4, 3, 5.5, 4.5 ], "texture": "#birchwood" }, + "north": { "uv": [ 10.5, 4, 12, 6.5 ], "texture": "#birchwood" }, + "south": { "uv": [ 4, 4, 5.5, 6.5 ], "texture": "#birchwood" }, + "west": { "uv": [ 3, 4, 4.5, 6.5 ], "texture": "#birchwood" }, + "east": { "uv": [ 11.5, 4, 13, 6.5 ], "texture": "#birchwood" } + } + }, + { + "from": [ 8.5, 9, 3.5 ], + "to": [ 12.5, 11, 7.5 ], + "faces": { + "up": { "uv": [ 8.5, 3.5, 12.5, 7.5 ], "texture": "#birchwood" }, + "north": { "uv": [ 3.5, 5, 7.5, 7 ], "texture": "#birchwood" }, + "south": { "uv": [ 8.5, 5, 12.5, 7 ], "texture": "#birchwood" }, + "west": { "uv": [ 3.5, 5, 7.5, 7 ], "texture": "#birchwood" }, + "east": { "uv": [ 8.5, 5, 12.5, 7 ], "texture": "#birchwood" } + } + }, + { + "from": [ 9.5, 11, 4.5 ], + "to": [ 11.5, 13, 6.5 ], + "faces": { + "up": { "uv": [ 9.5, 4.5, 11.5, 6.5 ], "texture": "#birchwood" }, + "north": { "uv": [ 4.5, 3, 6.5, 5 ], "texture": "#birchwood" }, + "south": { "uv": [ 9.5, 3, 11.5, 5 ], "texture": "#birchwood" }, + "west": { "uv": [ 4.5, 3, 6.5, 5 ], "texture": "#birchwood" }, + "east": { "uv": [ 9.5, 3, 11.5, 5 ], "texture": "#birchwood" } + } + }, + { + "from": [ 10, 13, 5 ], + "to": [ 11, 15, 6 ], + "faces": { + "up": { "uv": [ 10, 5, 11, 6 ], "texture": "#birchwood" }, + "north": { "uv": [ 5, 1, 6, 3 ], "texture": "#birchwood" }, + "south": { "uv": [ 10, 1, 11, 3 ], "texture": "#birchwood" }, + "west": { "uv": [ 5, 1, 6, 3 ], "texture": "#birchwood" }, + "east": { "uv": [ 10, 1, 11, 3 ], "texture": "#birchwood" } + } + }, + { + "from": [ 8, 4.5, 10.5 ], + "to": [ 10.5, 8, 13 ], + "faces": { + "down": { "uv": [ 8, 3, 10.5, 5.5 ], "texture": "#stonebricks" }, + "north": { "uv": [ 5.5, 8, 8, 11.5 ], "texture": "#stonebricks" }, + "south": { "uv": [ 8, 8, 10.5, 11.5 ], "texture": "#stonebricks" }, + "west": { "uv": [ 10.5, 8, 13, 11.5 ], "texture": "#stonebricks" }, + "east": { "uv": [ 3, 8, 5.5, 11.5 ], "texture": "#stonebricks" } + } + }, + { + "from": [ 7.5, 8, 10 ], + "to": [ 11, 9.5, 13.5 ], + "faces": { + "down": { "uv": [ 7.5, 2.5, 11, 6 ], "texture": "#birchwood" }, + "up": { "uv": [ 7.5, 10, 11, 13.5 ], "texture": "#birchwood" }, + "north": { "uv": [ 5, 6.5, 8.5, 8 ], "texture": "#birchwood" }, + "south": { "uv": [ 7.5, 6.5, 11, 8 ], "texture": "#birchwood" }, + "west": { "uv": [ 10, 6.5, 13.5, 8 ], "texture": "#birchwood" }, + "east": { "uv": [ 2.5, 6.5, 6, 8 ], "texture": "#birchwood" } + } + }, + { + "from": [ 8.5, 9.5, 11 ], + "to": [ 10, 12, 12.5 ], + "faces": { + "up": { "uv": [ 8.5, 11, 10, 12.5 ], "texture": "#birchwood" }, + "north": { "uv": [ 6, 4, 7.5, 6.5 ], "texture": "#birchwood" }, + "south": { "uv": [ 8.5, 4, 10, 6.5 ], "texture": "#birchwood" }, + "west": { "uv": [ 11, 4, 12.5, 6.5 ], "texture": "#birchwood" }, + "east": { "uv": [ 3.5, 4, 5, 6.5 ], "texture": "#birchwood" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/mosspatch.json b/src/main/resources/assets/twilightforest/models/block/mosspatch.json new file mode 100644 index 0000000000..fdb5cdde5f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/mosspatch.json @@ -0,0 +1,1553 @@ +{ + "textures": { + "particle": "twilightforest:blocks/mosspatch", + "texture": "twilightforest:blocks/patch/moss_0", + "ctm": "twilightforest:blocks/patch/moss_0_ctm" + }, + "elements":[ + {"from":[0,0,0],"to":[1,1,1],"faces":{ + "up":{"uv":[0,0,1,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,0,1,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,0,1,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,0,1,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,0,1,1],"texture":"#texture","tintindex":4} + }},{"from":[0,0,1],"to":[1,1,2],"faces":{ + "up":{"uv":[0,1,1,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,1,1,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,1,1,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,1,1,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,1,1,2],"texture":"#texture","tintindex":4} + }},{"from":[0,0,2],"to":[1,1,3],"faces":{ + "up":{"uv":[0,2,1,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,2,1,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,2,1,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,2,1,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,2,1,3],"texture":"#texture","tintindex":4} + }},{"from":[0,0,3],"to":[1,1,4],"faces":{ + "up":{"uv":[0,3,1,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,3,1,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,3,1,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,3,1,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,3,1,4],"texture":"#texture","tintindex":4} + }},{"from":[0,0,4],"to":[1,1,5],"faces":{ + "up":{"uv":[0,4,1,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,4,1,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,4,1,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,4,1,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,4,1,5],"texture":"#texture","tintindex":4} + }},{"from":[0,0,5],"to":[1,1,6],"faces":{ + "up":{"uv":[0,5,1,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,5,1,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,5,1,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,5,1,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,5,1,6],"texture":"#texture","tintindex":4} + }},{"from":[0,0,6],"to":[1,1,7],"faces":{ + "up":{"uv":[0,6,1,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,6,1,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,6,1,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,6,1,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,6,1,7],"texture":"#texture","tintindex":4} + }},{"from":[0,0,7],"to":[1,1,8],"faces":{ + "up":{"uv":[0,7,1,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,7,1,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,7,1,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,7,1,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,7,1,8],"texture":"#texture","tintindex":4} + }},{"from":[0,0,8],"to":[1,1,9],"faces":{ + "up":{"uv":[0,8,1,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,8,1,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,8,1,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,8,1,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,8,1,9],"texture":"#texture","tintindex":4} + }},{"from":[0,0,9],"to":[1,1,10],"faces":{ + "up":{"uv":[0,9,1,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,9,1,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,9,1,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,9,1,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,9,1,10],"texture":"#texture","tintindex":4} + }},{"from":[0,0,10],"to":[1,1,11],"faces":{ + "up":{"uv":[0,10,1,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,10,1,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,10,1,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,10,1,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,10,1,11],"texture":"#texture","tintindex":4} + }},{"from":[0,0,11],"to":[1,1,12],"faces":{ + "up":{"uv":[0,11,1,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,11,1,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,11,1,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,11,1,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,11,1,12],"texture":"#texture","tintindex":4} + }},{"from":[0,0,12],"to":[1,1,13],"faces":{ + "up":{"uv":[0,12,1,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,12,1,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,12,1,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,12,1,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,12,1,13],"texture":"#texture","tintindex":4} + }},{"from":[0,0,13],"to":[1,1,14],"faces":{ + "up":{"uv":[0,13,1,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,13,1,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,13,1,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,13,1,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,13,1,14],"texture":"#texture","tintindex":4} + }},{"from":[0,0,14],"to":[1,1,15],"faces":{ + "up":{"uv":[0,14,1,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,14,1,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,14,1,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,14,1,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,14,1,15],"texture":"#texture","tintindex":4} + }},{"from":[0,0,15],"to":[1,1,16],"faces":{ + "up":{"uv":[0,15,1,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[0,15,1,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,15,1,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,15,1,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,15,1,16],"texture":"#texture","tintindex":4} + }},{"from":[1,0,0],"to":[2,1,1],"faces":{ + "up":{"uv":[1,0,2,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,0,2,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,0,2,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,0,2,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,0,2,1],"texture":"#texture","tintindex":4} + }},{"from":[1,0,1],"to":[2,1,2],"faces":{ + "up":{"uv":[1,1,2,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,1,2,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,1,2,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,1,2,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,1,2,2],"texture":"#texture","tintindex":4} + }},{"from":[1,0,2],"to":[2,1,3],"faces":{ + "up":{"uv":[1,2,2,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,2,2,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,2,2,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,2,2,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,2,2,3],"texture":"#texture","tintindex":4} + }},{"from":[1,0,3],"to":[2,1,4],"faces":{ + "up":{"uv":[1,3,2,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,3,2,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,3,2,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,3,2,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,3,2,4],"texture":"#texture","tintindex":4} + }},{"from":[1,0,4],"to":[2,1,5],"faces":{ + "up":{"uv":[1,4,2,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,4,2,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,4,2,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,4,2,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,4,2,5],"texture":"#texture","tintindex":4} + }},{"from":[1,0,5],"to":[2,1,6],"faces":{ + "up":{"uv":[1,5,2,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,5,2,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,5,2,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,5,2,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,5,2,6],"texture":"#texture","tintindex":4} + }},{"from":[1,0,6],"to":[2,1,7],"faces":{ + "up":{"uv":[1,6,2,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,6,2,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,6,2,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,6,2,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,6,2,7],"texture":"#texture","tintindex":4} + }},{"from":[1,0,7],"to":[2,1,8],"faces":{ + "up":{"uv":[1,7,2,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,7,2,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,7,2,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,7,2,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,7,2,8],"texture":"#texture","tintindex":4} + }},{"from":[1,0,8],"to":[2,1,9],"faces":{ + "up":{"uv":[1,8,2,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,8,2,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,8,2,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,8,2,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,8,2,9],"texture":"#texture","tintindex":4} + }},{"from":[1,0,9],"to":[2,1,10],"faces":{ + "up":{"uv":[1,9,2,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,9,2,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,9,2,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,9,2,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,9,2,10],"texture":"#texture","tintindex":4} + }},{"from":[1,0,10],"to":[2,1,11],"faces":{ + "up":{"uv":[1,10,2,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,10,2,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,10,2,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,10,2,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,10,2,11],"texture":"#texture","tintindex":4} + }},{"from":[1,0,11],"to":[2,1,12],"faces":{ + "up":{"uv":[1,11,2,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,11,2,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,11,2,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,11,2,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,11,2,12],"texture":"#texture","tintindex":4} + }},{"from":[1,0,12],"to":[2,1,13],"faces":{ + "up":{"uv":[1,12,2,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,12,2,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,12,2,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,12,2,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,12,2,13],"texture":"#texture","tintindex":4} + }},{"from":[1,0,13],"to":[2,1,14],"faces":{ + "up":{"uv":[1,13,2,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,13,2,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,13,2,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,13,2,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,13,2,14],"texture":"#texture","tintindex":4} + }},{"from":[1,0,14],"to":[2,1,15],"faces":{ + "up":{"uv":[1,14,2,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,14,2,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,14,2,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,14,2,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,14,2,15],"texture":"#texture","tintindex":4} + }},{"from":[1,0,15],"to":[2,1,16],"faces":{ + "up":{"uv":[1,15,2,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[1,15,2,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,15,2,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,15,2,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,15,2,16],"texture":"#texture","tintindex":4} + }},{"from":[2,0,0],"to":[3,1,1],"faces":{ + "up":{"uv":[2,0,3,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,0,3,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,0,3,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,0,3,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,0,3,1],"texture":"#texture","tintindex":4} + }},{"from":[2,0,1],"to":[3,1,2],"faces":{ + "up":{"uv":[2,1,3,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,1,3,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,1,3,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,1,3,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,1,3,2],"texture":"#texture","tintindex":4} + }},{"from":[2,0,2],"to":[3,1,3],"faces":{ + "up":{"uv":[2,2,3,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,2,3,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,2,3,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,2,3,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,2,3,3],"texture":"#texture","tintindex":4} + }},{"from":[2,0,3],"to":[3,1,4],"faces":{ + "up":{"uv":[2,3,3,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,3,3,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,3,3,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,3,3,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,3,3,4],"texture":"#texture","tintindex":4} + }},{"from":[2,0,4],"to":[3,1,5],"faces":{ + "up":{"uv":[2,4,3,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,4,3,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,4,3,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,4,3,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,4,3,5],"texture":"#texture","tintindex":4} + }},{"from":[2,0,5],"to":[3,1,6],"faces":{ + "up":{"uv":[2,5,3,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,5,3,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,5,3,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,5,3,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,5,3,6],"texture":"#texture","tintindex":4} + }},{"from":[2,0,6],"to":[3,1,7],"faces":{ + "up":{"uv":[2,6,3,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,6,3,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,6,3,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,6,3,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,6,3,7],"texture":"#texture","tintindex":4} + }},{"from":[2,0,7],"to":[3,1,8],"faces":{ + "up":{"uv":[2,7,3,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,7,3,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,7,3,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,7,3,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,7,3,8],"texture":"#texture","tintindex":4} + }},{"from":[2,0,8],"to":[3,1,9],"faces":{ + "up":{"uv":[2,8,3,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,8,3,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,8,3,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,8,3,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,8,3,9],"texture":"#texture","tintindex":4} + }},{"from":[2,0,9],"to":[3,1,10],"faces":{ + "up":{"uv":[2,9,3,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,9,3,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,9,3,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,9,3,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,9,3,10],"texture":"#texture","tintindex":4} + }},{"from":[2,0,10],"to":[3,1,11],"faces":{ + "up":{"uv":[2,10,3,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,10,3,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,10,3,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,10,3,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,10,3,11],"texture":"#texture","tintindex":4} + }},{"from":[2,0,11],"to":[3,1,12],"faces":{ + "up":{"uv":[2,11,3,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,11,3,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,11,3,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,11,3,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,11,3,12],"texture":"#texture","tintindex":4} + }},{"from":[2,0,12],"to":[3,1,13],"faces":{ + "up":{"uv":[2,12,3,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,12,3,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,12,3,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,12,3,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,12,3,13],"texture":"#texture","tintindex":4} + }},{"from":[2,0,13],"to":[3,1,14],"faces":{ + "up":{"uv":[2,13,3,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,13,3,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,13,3,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,13,3,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,13,3,14],"texture":"#texture","tintindex":4} + }},{"from":[2,0,14],"to":[3,1,15],"faces":{ + "up":{"uv":[2,14,3,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,14,3,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,14,3,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,14,3,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,14,3,15],"texture":"#texture","tintindex":4} + }},{"from":[2,0,15],"to":[3,1,16],"faces":{ + "up":{"uv":[2,15,3,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[2,15,3,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,15,3,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,15,3,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,15,3,16],"texture":"#texture","tintindex":4} + }},{"from":[3,0,0],"to":[4,1,1],"faces":{ + "up":{"uv":[3,0,4,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,0,4,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,0,4,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,0,4,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,0,4,1],"texture":"#texture","tintindex":4} + }},{"from":[3,0,1],"to":[4,1,2],"faces":{ + "up":{"uv":[3,1,4,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,1,4,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,1,4,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,1,4,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,1,4,2],"texture":"#texture","tintindex":4} + }},{"from":[3,0,2],"to":[4,1,3],"faces":{ + "up":{"uv":[3,2,4,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,2,4,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,2,4,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,2,4,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,2,4,3],"texture":"#texture","tintindex":4} + }},{"from":[3,0,3],"to":[4,1,4],"faces":{ + "up":{"uv":[3,3,4,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,3,4,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,3,4,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,3,4,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,3,4,4],"texture":"#texture","tintindex":4} + }},{"from":[3,0,4],"to":[4,1,5],"faces":{ + "up":{"uv":[3,4,4,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,4,4,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,4,4,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,4,4,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,4,4,5],"texture":"#texture","tintindex":4} + }},{"from":[3,0,5],"to":[4,1,6],"faces":{ + "up":{"uv":[3,5,4,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,5,4,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,5,4,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,5,4,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,5,4,6],"texture":"#texture","tintindex":4} + }},{"from":[3,0,6],"to":[4,1,7],"faces":{ + "up":{"uv":[3,6,4,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,6,4,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,6,4,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,6,4,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,6,4,7],"texture":"#texture","tintindex":4} + }},{"from":[3,0,7],"to":[4,1,8],"faces":{ + "up":{"uv":[3,7,4,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,7,4,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,7,4,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,7,4,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,7,4,8],"texture":"#texture","tintindex":4} + }},{"from":[3,0,8],"to":[4,1,9],"faces":{ + "up":{"uv":[3,8,4,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,8,4,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,8,4,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,8,4,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,8,4,9],"texture":"#texture","tintindex":4} + }},{"from":[3,0,9],"to":[4,1,10],"faces":{ + "up":{"uv":[3,9,4,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,9,4,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,9,4,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,9,4,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,9,4,10],"texture":"#texture","tintindex":4} + }},{"from":[3,0,10],"to":[4,1,11],"faces":{ + "up":{"uv":[3,10,4,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,10,4,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,10,4,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,10,4,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,10,4,11],"texture":"#texture","tintindex":4} + }},{"from":[3,0,11],"to":[4,1,12],"faces":{ + "up":{"uv":[3,11,4,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,11,4,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,11,4,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,11,4,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,11,4,12],"texture":"#texture","tintindex":4} + }},{"from":[3,0,12],"to":[4,1,13],"faces":{ + "up":{"uv":[3,12,4,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,12,4,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,12,4,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,12,4,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,12,4,13],"texture":"#texture","tintindex":4} + }},{"from":[3,0,13],"to":[4,1,14],"faces":{ + "up":{"uv":[3,13,4,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,13,4,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,13,4,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,13,4,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,13,4,14],"texture":"#texture","tintindex":4} + }},{"from":[3,0,14],"to":[4,1,15],"faces":{ + "up":{"uv":[3,14,4,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,14,4,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,14,4,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,14,4,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,14,4,15],"texture":"#texture","tintindex":4} + }},{"from":[3,0,15],"to":[4,1,16],"faces":{ + "up":{"uv":[3,15,4,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[3,15,4,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,15,4,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,15,4,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,15,4,16],"texture":"#texture","tintindex":4} + }},{"from":[4,0,0],"to":[5,1,1],"faces":{ + "up":{"uv":[4,0,5,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,0,5,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,0,5,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,0,5,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,0,5,1],"texture":"#texture","tintindex":4} + }},{"from":[4,0,1],"to":[5,1,2],"faces":{ + "up":{"uv":[4,1,5,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,1,5,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,1,5,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,1,5,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,1,5,2],"texture":"#texture","tintindex":4} + }},{"from":[4,0,2],"to":[5,1,3],"faces":{ + "up":{"uv":[4,2,5,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,2,5,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,2,5,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,2,5,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,2,5,3],"texture":"#texture","tintindex":4} + }},{"from":[4,0,3],"to":[5,1,4],"faces":{ + "up":{"uv":[4,3,5,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,3,5,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,3,5,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,3,5,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,3,5,4],"texture":"#texture","tintindex":4} + }},{"from":[4,0,4],"to":[5,1,5],"faces":{ + "up":{"uv":[4,4,5,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,4,5,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,4,5,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,4,5,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,4,5,5],"texture":"#texture","tintindex":4} + }},{"from":[4,0,5],"to":[5,1,6],"faces":{ + "up":{"uv":[4,5,5,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,5,5,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,5,5,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,5,5,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,5,5,6],"texture":"#texture","tintindex":4} + }},{"from":[4,0,6],"to":[5,1,7],"faces":{ + "up":{"uv":[4,6,5,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,6,5,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,6,5,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,6,5,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,6,5,7],"texture":"#texture","tintindex":4} + }},{"from":[4,0,7],"to":[5,1,8],"faces":{ + "up":{"uv":[4,7,5,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,7,5,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,7,5,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,7,5,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,7,5,8],"texture":"#texture","tintindex":4} + }},{"from":[4,0,8],"to":[5,1,9],"faces":{ + "up":{"uv":[4,8,5,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,8,5,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,8,5,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,8,5,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,8,5,9],"texture":"#texture","tintindex":4} + }},{"from":[4,0,9],"to":[5,1,10],"faces":{ + "up":{"uv":[4,9,5,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,9,5,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,9,5,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,9,5,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,9,5,10],"texture":"#texture","tintindex":4} + }},{"from":[4,0,10],"to":[5,1,11],"faces":{ + "up":{"uv":[4,10,5,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,10,5,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,10,5,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,10,5,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,10,5,11],"texture":"#texture","tintindex":4} + }},{"from":[4,0,11],"to":[5,1,12],"faces":{ + "up":{"uv":[4,11,5,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,11,5,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,11,5,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,11,5,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,11,5,12],"texture":"#texture","tintindex":4} + }},{"from":[4,0,12],"to":[5,1,13],"faces":{ + "up":{"uv":[4,12,5,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,12,5,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,12,5,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,12,5,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,12,5,13],"texture":"#texture","tintindex":4} + }},{"from":[4,0,13],"to":[5,1,14],"faces":{ + "up":{"uv":[4,13,5,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,13,5,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,13,5,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,13,5,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,13,5,14],"texture":"#texture","tintindex":4} + }},{"from":[4,0,14],"to":[5,1,15],"faces":{ + "up":{"uv":[4,14,5,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,14,5,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,14,5,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,14,5,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,14,5,15],"texture":"#texture","tintindex":4} + }},{"from":[4,0,15],"to":[5,1,16],"faces":{ + "up":{"uv":[4,15,5,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[4,15,5,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,15,5,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,15,5,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,15,5,16],"texture":"#texture","tintindex":4} + }},{"from":[5,0,0],"to":[6,1,1],"faces":{ + "up":{"uv":[5,0,6,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,0,6,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,0,6,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,0,6,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,0,6,1],"texture":"#texture","tintindex":4} + }},{"from":[5,0,1],"to":[6,1,2],"faces":{ + "up":{"uv":[5,1,6,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,1,6,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,1,6,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,1,6,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,1,6,2],"texture":"#texture","tintindex":4} + }},{"from":[5,0,2],"to":[6,1,3],"faces":{ + "up":{"uv":[5,2,6,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,2,6,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,2,6,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,2,6,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,2,6,3],"texture":"#texture","tintindex":4} + }},{"from":[5,0,3],"to":[6,1,4],"faces":{ + "up":{"uv":[5,3,6,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,3,6,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,3,6,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,3,6,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,3,6,4],"texture":"#texture","tintindex":4} + }},{"from":[5,0,4],"to":[6,1,5],"faces":{ + "up":{"uv":[5,4,6,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,4,6,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,4,6,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,4,6,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,4,6,5],"texture":"#texture","tintindex":4} + }},{"from":[5,0,5],"to":[6,1,6],"faces":{ + "up":{"uv":[5,5,6,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,5,6,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,5,6,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,5,6,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,5,6,6],"texture":"#texture","tintindex":4} + }},{"from":[5,0,6],"to":[6,1,7],"faces":{ + "up":{"uv":[5,6,6,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,6,6,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,6,6,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,6,6,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,6,6,7],"texture":"#texture","tintindex":4} + }},{"from":[5,0,7],"to":[6,1,8],"faces":{ + "up":{"uv":[5,7,6,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,7,6,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,7,6,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,7,6,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,7,6,8],"texture":"#texture","tintindex":4} + }},{"from":[5,0,8],"to":[6,1,9],"faces":{ + "up":{"uv":[5,8,6,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,8,6,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,8,6,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,8,6,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,8,6,9],"texture":"#texture","tintindex":4} + }},{"from":[5,0,9],"to":[6,1,10],"faces":{ + "up":{"uv":[5,9,6,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,9,6,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,9,6,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,9,6,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,9,6,10],"texture":"#texture","tintindex":4} + }},{"from":[5,0,10],"to":[6,1,11],"faces":{ + "up":{"uv":[5,10,6,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,10,6,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,10,6,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,10,6,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,10,6,11],"texture":"#texture","tintindex":4} + }},{"from":[5,0,11],"to":[6,1,12],"faces":{ + "up":{"uv":[5,11,6,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,11,6,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,11,6,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,11,6,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,11,6,12],"texture":"#texture","tintindex":4} + }},{"from":[5,0,12],"to":[6,1,13],"faces":{ + "up":{"uv":[5,12,6,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,12,6,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,12,6,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,12,6,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,12,6,13],"texture":"#texture","tintindex":4} + }},{"from":[5,0,13],"to":[6,1,14],"faces":{ + "up":{"uv":[5,13,6,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,13,6,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,13,6,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,13,6,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,13,6,14],"texture":"#texture","tintindex":4} + }},{"from":[5,0,14],"to":[6,1,15],"faces":{ + "up":{"uv":[5,14,6,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,14,6,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,14,6,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,14,6,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,14,6,15],"texture":"#texture","tintindex":4} + }},{"from":[5,0,15],"to":[6,1,16],"faces":{ + "up":{"uv":[5,15,6,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[5,15,6,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,15,6,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,15,6,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,15,6,16],"texture":"#texture","tintindex":4} + }},{"from":[6,0,0],"to":[7,1,1],"faces":{ + "up":{"uv":[6,0,7,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,0,7,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,0,7,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,0,7,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,0,7,1],"texture":"#texture","tintindex":4} + }},{"from":[6,0,1],"to":[7,1,2],"faces":{ + "up":{"uv":[6,1,7,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,1,7,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,1,7,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,1,7,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,1,7,2],"texture":"#texture","tintindex":4} + }},{"from":[6,0,2],"to":[7,1,3],"faces":{ + "up":{"uv":[6,2,7,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,2,7,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,2,7,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,2,7,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,2,7,3],"texture":"#texture","tintindex":4} + }},{"from":[6,0,3],"to":[7,1,4],"faces":{ + "up":{"uv":[6,3,7,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,3,7,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,3,7,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,3,7,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,3,7,4],"texture":"#texture","tintindex":4} + }},{"from":[6,0,4],"to":[7,1,5],"faces":{ + "up":{"uv":[6,4,7,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,4,7,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,4,7,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,4,7,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,4,7,5],"texture":"#texture","tintindex":4} + }},{"from":[6,0,5],"to":[7,1,6],"faces":{ + "up":{"uv":[6,5,7,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,5,7,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,5,7,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,5,7,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,5,7,6],"texture":"#texture","tintindex":4} + }},{"from":[6,0,6],"to":[7,1,7],"faces":{ + "up":{"uv":[6,6,7,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,6,7,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,6,7,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,6,7,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,6,7,7],"texture":"#texture","tintindex":4} + }},{"from":[6,0,7],"to":[7,1,8],"faces":{ + "up":{"uv":[6,7,7,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,7,7,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,7,7,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,7,7,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,7,7,8],"texture":"#texture","tintindex":4} + }},{"from":[6,0,8],"to":[7,1,9],"faces":{ + "up":{"uv":[6,8,7,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,8,7,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,8,7,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,8,7,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,8,7,9],"texture":"#texture","tintindex":4} + }},{"from":[6,0,9],"to":[7,1,10],"faces":{ + "up":{"uv":[6,9,7,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,9,7,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,9,7,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,9,7,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,9,7,10],"texture":"#texture","tintindex":4} + }},{"from":[6,0,10],"to":[7,1,11],"faces":{ + "up":{"uv":[6,10,7,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,10,7,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,10,7,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,10,7,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,10,7,11],"texture":"#texture","tintindex":4} + }},{"from":[6,0,11],"to":[7,1,12],"faces":{ + "up":{"uv":[6,11,7,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,11,7,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,11,7,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,11,7,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,11,7,12],"texture":"#texture","tintindex":4} + }},{"from":[6,0,12],"to":[7,1,13],"faces":{ + "up":{"uv":[6,12,7,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,12,7,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,12,7,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,12,7,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,12,7,13],"texture":"#texture","tintindex":4} + }},{"from":[6,0,13],"to":[7,1,14],"faces":{ + "up":{"uv":[6,13,7,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,13,7,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,13,7,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,13,7,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,13,7,14],"texture":"#texture","tintindex":4} + }},{"from":[6,0,14],"to":[7,1,15],"faces":{ + "up":{"uv":[6,14,7,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,14,7,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,14,7,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,14,7,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,14,7,15],"texture":"#texture","tintindex":4} + }},{"from":[6,0,15],"to":[7,1,16],"faces":{ + "up":{"uv":[6,15,7,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[6,15,7,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,15,7,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,15,7,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,15,7,16],"texture":"#texture","tintindex":4} + }},{"from":[7,0,0],"to":[8,1,1],"faces":{ + "up":{"uv":[7,0,8,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,0,8,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,0,8,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,0,8,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,0,8,1],"texture":"#texture","tintindex":4} + }},{"from":[7,0,1],"to":[8,1,2],"faces":{ + "up":{"uv":[7,1,8,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,1,8,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,1,8,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,1,8,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,1,8,2],"texture":"#texture","tintindex":4} + }},{"from":[7,0,2],"to":[8,1,3],"faces":{ + "up":{"uv":[7,2,8,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,2,8,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,2,8,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,2,8,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,2,8,3],"texture":"#texture","tintindex":4} + }},{"from":[7,0,3],"to":[8,1,4],"faces":{ + "up":{"uv":[7,3,8,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,3,8,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,3,8,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,3,8,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,3,8,4],"texture":"#texture","tintindex":4} + }},{"from":[7,0,4],"to":[8,1,5],"faces":{ + "up":{"uv":[7,4,8,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,4,8,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,4,8,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,4,8,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,4,8,5],"texture":"#texture","tintindex":4} + }},{"from":[7,0,5],"to":[8,1,6],"faces":{ + "up":{"uv":[7,5,8,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,5,8,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,5,8,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,5,8,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,5,8,6],"texture":"#texture","tintindex":4} + }},{"from":[7,0,6],"to":[8,1,7],"faces":{ + "up":{"uv":[7,6,8,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,6,8,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,6,8,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,6,8,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,6,8,7],"texture":"#texture","tintindex":4} + }},{"from":[7,0,7],"to":[8,1,8],"faces":{ + "up":{"uv":[7,7,8,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,7,8,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,7,8,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,7,8,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,7,8,8],"texture":"#texture","tintindex":4} + }},{"from":[7,0,8],"to":[8,1,9],"faces":{ + "up":{"uv":[7,8,8,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,8,8,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,8,8,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,8,8,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,8,8,9],"texture":"#texture","tintindex":4} + }},{"from":[7,0,9],"to":[8,1,10],"faces":{ + "up":{"uv":[7,9,8,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,9,8,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,9,8,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,9,8,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,9,8,10],"texture":"#texture","tintindex":4} + }},{"from":[7,0,10],"to":[8,1,11],"faces":{ + "up":{"uv":[7,10,8,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,10,8,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,10,8,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,10,8,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,10,8,11],"texture":"#texture","tintindex":4} + }},{"from":[7,0,11],"to":[8,1,12],"faces":{ + "up":{"uv":[7,11,8,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,11,8,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,11,8,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,11,8,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,11,8,12],"texture":"#texture","tintindex":4} + }},{"from":[7,0,12],"to":[8,1,13],"faces":{ + "up":{"uv":[7,12,8,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,12,8,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,12,8,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,12,8,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,12,8,13],"texture":"#texture","tintindex":4} + }},{"from":[7,0,13],"to":[8,1,14],"faces":{ + "up":{"uv":[7,13,8,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,13,8,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,13,8,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,13,8,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,13,8,14],"texture":"#texture","tintindex":4} + }},{"from":[7,0,14],"to":[8,1,15],"faces":{ + "up":{"uv":[7,14,8,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,14,8,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,14,8,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,14,8,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,14,8,15],"texture":"#texture","tintindex":4} + }},{"from":[7,0,15],"to":[8,1,16],"faces":{ + "up":{"uv":[7,15,8,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[7,15,8,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,15,8,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,15,8,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,15,8,16],"texture":"#texture","tintindex":4} + }},{"from":[8,0,0],"to":[9,1,1],"faces":{ + "up":{"uv":[8,0,9,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,0,9,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,0,9,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,0,9,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,0,9,1],"texture":"#texture","tintindex":4} + }},{"from":[8,0,1],"to":[9,1,2],"faces":{ + "up":{"uv":[8,1,9,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,1,9,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,1,9,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,1,9,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,1,9,2],"texture":"#texture","tintindex":4} + }},{"from":[8,0,2],"to":[9,1,3],"faces":{ + "up":{"uv":[8,2,9,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,2,9,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,2,9,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,2,9,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,2,9,3],"texture":"#texture","tintindex":4} + }},{"from":[8,0,3],"to":[9,1,4],"faces":{ + "up":{"uv":[8,3,9,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,3,9,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,3,9,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,3,9,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,3,9,4],"texture":"#texture","tintindex":4} + }},{"from":[8,0,4],"to":[9,1,5],"faces":{ + "up":{"uv":[8,4,9,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,4,9,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,4,9,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,4,9,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,4,9,5],"texture":"#texture","tintindex":4} + }},{"from":[8,0,5],"to":[9,1,6],"faces":{ + "up":{"uv":[8,5,9,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,5,9,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,5,9,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,5,9,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,5,9,6],"texture":"#texture","tintindex":4} + }},{"from":[8,0,6],"to":[9,1,7],"faces":{ + "up":{"uv":[8,6,9,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,6,9,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,6,9,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,6,9,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,6,9,7],"texture":"#texture","tintindex":4} + }},{"from":[8,0,7],"to":[9,1,8],"faces":{ + "up":{"uv":[8,7,9,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,7,9,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,7,9,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,7,9,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,7,9,8],"texture":"#texture","tintindex":4} + }},{"from":[8,0,8],"to":[9,1,9],"faces":{ + "up":{"uv":[8,8,9,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,8,9,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,8,9,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,8,9,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,8,9,9],"texture":"#texture","tintindex":4} + }},{"from":[8,0,9],"to":[9,1,10],"faces":{ + "up":{"uv":[8,9,9,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,9,9,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,9,9,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,9,9,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,9,9,10],"texture":"#texture","tintindex":4} + }},{"from":[8,0,10],"to":[9,1,11],"faces":{ + "up":{"uv":[8,10,9,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,10,9,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,10,9,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,10,9,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,10,9,11],"texture":"#texture","tintindex":4} + }},{"from":[8,0,11],"to":[9,1,12],"faces":{ + "up":{"uv":[8,11,9,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,11,9,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,11,9,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,11,9,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,11,9,12],"texture":"#texture","tintindex":4} + }},{"from":[8,0,12],"to":[9,1,13],"faces":{ + "up":{"uv":[8,12,9,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,12,9,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,12,9,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,12,9,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,12,9,13],"texture":"#texture","tintindex":4} + }},{"from":[8,0,13],"to":[9,1,14],"faces":{ + "up":{"uv":[8,13,9,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,13,9,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,13,9,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,13,9,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,13,9,14],"texture":"#texture","tintindex":4} + }},{"from":[8,0,14],"to":[9,1,15],"faces":{ + "up":{"uv":[8,14,9,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,14,9,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,14,9,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,14,9,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,14,9,15],"texture":"#texture","tintindex":4} + }},{"from":[8,0,15],"to":[9,1,16],"faces":{ + "up":{"uv":[8,15,9,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[8,15,9,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,15,9,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,15,9,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,15,9,16],"texture":"#texture","tintindex":4} + }},{"from":[9,0,0],"to":[10,1,1],"faces":{ + "up":{"uv":[9,0,10,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,0,10,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,0,10,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,0,10,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,0,10,1],"texture":"#texture","tintindex":4} + }},{"from":[9,0,1],"to":[10,1,2],"faces":{ + "up":{"uv":[9,1,10,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,1,10,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,1,10,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,1,10,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,1,10,2],"texture":"#texture","tintindex":4} + }},{"from":[9,0,2],"to":[10,1,3],"faces":{ + "up":{"uv":[9,2,10,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,2,10,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,2,10,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,2,10,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,2,10,3],"texture":"#texture","tintindex":4} + }},{"from":[9,0,3],"to":[10,1,4],"faces":{ + "up":{"uv":[9,3,10,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,3,10,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,3,10,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,3,10,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,3,10,4],"texture":"#texture","tintindex":4} + }},{"from":[9,0,4],"to":[10,1,5],"faces":{ + "up":{"uv":[9,4,10,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,4,10,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,4,10,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,4,10,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,4,10,5],"texture":"#texture","tintindex":4} + }},{"from":[9,0,5],"to":[10,1,6],"faces":{ + "up":{"uv":[9,5,10,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,5,10,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,5,10,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,5,10,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,5,10,6],"texture":"#texture","tintindex":4} + }},{"from":[9,0,6],"to":[10,1,7],"faces":{ + "up":{"uv":[9,6,10,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,6,10,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,6,10,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,6,10,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,6,10,7],"texture":"#texture","tintindex":4} + }},{"from":[9,0,7],"to":[10,1,8],"faces":{ + "up":{"uv":[9,7,10,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,7,10,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,7,10,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,7,10,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,7,10,8],"texture":"#texture","tintindex":4} + }},{"from":[9,0,8],"to":[10,1,9],"faces":{ + "up":{"uv":[9,8,10,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,8,10,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,8,10,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,8,10,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,8,10,9],"texture":"#texture","tintindex":4} + }},{"from":[9,0,9],"to":[10,1,10],"faces":{ + "up":{"uv":[9,9,10,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,9,10,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,9,10,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,9,10,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,9,10,10],"texture":"#texture","tintindex":4} + }},{"from":[9,0,10],"to":[10,1,11],"faces":{ + "up":{"uv":[9,10,10,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,10,10,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,10,10,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,10,10,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,10,10,11],"texture":"#texture","tintindex":4} + }},{"from":[9,0,11],"to":[10,1,12],"faces":{ + "up":{"uv":[9,11,10,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,11,10,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,11,10,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,11,10,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,11,10,12],"texture":"#texture","tintindex":4} + }},{"from":[9,0,12],"to":[10,1,13],"faces":{ + "up":{"uv":[9,12,10,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,12,10,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,12,10,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,12,10,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,12,10,13],"texture":"#texture","tintindex":4} + }},{"from":[9,0,13],"to":[10,1,14],"faces":{ + "up":{"uv":[9,13,10,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,13,10,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,13,10,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,13,10,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,13,10,14],"texture":"#texture","tintindex":4} + }},{"from":[9,0,14],"to":[10,1,15],"faces":{ + "up":{"uv":[9,14,10,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,14,10,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,14,10,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,14,10,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,14,10,15],"texture":"#texture","tintindex":4} + }},{"from":[9,0,15],"to":[10,1,16],"faces":{ + "up":{"uv":[9,15,10,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[9,15,10,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,15,10,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,15,10,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,15,10,16],"texture":"#texture","tintindex":4} + }},{"from":[10,0,0],"to":[11,1,1],"faces":{ + "up":{"uv":[10,0,11,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,0,11,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,0,11,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,0,11,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,0,11,1],"texture":"#texture","tintindex":4} + }},{"from":[10,0,1],"to":[11,1,2],"faces":{ + "up":{"uv":[10,1,11,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,1,11,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,1,11,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,1,11,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,1,11,2],"texture":"#texture","tintindex":4} + }},{"from":[10,0,2],"to":[11,1,3],"faces":{ + "up":{"uv":[10,2,11,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,2,11,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,2,11,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,2,11,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,2,11,3],"texture":"#texture","tintindex":4} + }},{"from":[10,0,3],"to":[11,1,4],"faces":{ + "up":{"uv":[10,3,11,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,3,11,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,3,11,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,3,11,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,3,11,4],"texture":"#texture","tintindex":4} + }},{"from":[10,0,4],"to":[11,1,5],"faces":{ + "up":{"uv":[10,4,11,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,4,11,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,4,11,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,4,11,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,4,11,5],"texture":"#texture","tintindex":4} + }},{"from":[10,0,5],"to":[11,1,6],"faces":{ + "up":{"uv":[10,5,11,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,5,11,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,5,11,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,5,11,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,5,11,6],"texture":"#texture","tintindex":4} + }},{"from":[10,0,6],"to":[11,1,7],"faces":{ + "up":{"uv":[10,6,11,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,6,11,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,6,11,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,6,11,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,6,11,7],"texture":"#texture","tintindex":4} + }},{"from":[10,0,7],"to":[11,1,8],"faces":{ + "up":{"uv":[10,7,11,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,7,11,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,7,11,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,7,11,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,7,11,8],"texture":"#texture","tintindex":4} + }},{"from":[10,0,8],"to":[11,1,9],"faces":{ + "up":{"uv":[10,8,11,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,8,11,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,8,11,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,8,11,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,8,11,9],"texture":"#texture","tintindex":4} + }},{"from":[10,0,9],"to":[11,1,10],"faces":{ + "up":{"uv":[10,9,11,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,9,11,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,9,11,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,9,11,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,9,11,10],"texture":"#texture","tintindex":4} + }},{"from":[10,0,10],"to":[11,1,11],"faces":{ + "up":{"uv":[10,10,11,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,10,11,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,10,11,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,10,11,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,10,11,11],"texture":"#texture","tintindex":4} + }},{"from":[10,0,11],"to":[11,1,12],"faces":{ + "up":{"uv":[10,11,11,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,11,11,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,11,11,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,11,11,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,11,11,12],"texture":"#texture","tintindex":4} + }},{"from":[10,0,12],"to":[11,1,13],"faces":{ + "up":{"uv":[10,12,11,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,12,11,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,12,11,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,12,11,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,12,11,13],"texture":"#texture","tintindex":4} + }},{"from":[10,0,13],"to":[11,1,14],"faces":{ + "up":{"uv":[10,13,11,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,13,11,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,13,11,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,13,11,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,13,11,14],"texture":"#texture","tintindex":4} + }},{"from":[10,0,14],"to":[11,1,15],"faces":{ + "up":{"uv":[10,14,11,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,14,11,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,14,11,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,14,11,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,14,11,15],"texture":"#texture","tintindex":4} + }},{"from":[10,0,15],"to":[11,1,16],"faces":{ + "up":{"uv":[10,15,11,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[10,15,11,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,15,11,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,15,11,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,15,11,16],"texture":"#texture","tintindex":4} + }},{"from":[11,0,0],"to":[12,1,1],"faces":{ + "up":{"uv":[11,0,12,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,0,12,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,0,12,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,0,12,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,0,12,1],"texture":"#texture","tintindex":4} + }},{"from":[11,0,1],"to":[12,1,2],"faces":{ + "up":{"uv":[11,1,12,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,1,12,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,1,12,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,1,12,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,1,12,2],"texture":"#texture","tintindex":4} + }},{"from":[11,0,2],"to":[12,1,3],"faces":{ + "up":{"uv":[11,2,12,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,2,12,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,2,12,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,2,12,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,2,12,3],"texture":"#texture","tintindex":4} + }},{"from":[11,0,3],"to":[12,1,4],"faces":{ + "up":{"uv":[11,3,12,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,3,12,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,3,12,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,3,12,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,3,12,4],"texture":"#texture","tintindex":4} + }},{"from":[11,0,4],"to":[12,1,5],"faces":{ + "up":{"uv":[11,4,12,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,4,12,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,4,12,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,4,12,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,4,12,5],"texture":"#texture","tintindex":4} + }},{"from":[11,0,5],"to":[12,1,6],"faces":{ + "up":{"uv":[11,5,12,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,5,12,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,5,12,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,5,12,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,5,12,6],"texture":"#texture","tintindex":4} + }},{"from":[11,0,6],"to":[12,1,7],"faces":{ + "up":{"uv":[11,6,12,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,6,12,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,6,12,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,6,12,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,6,12,7],"texture":"#texture","tintindex":4} + }},{"from":[11,0,7],"to":[12,1,8],"faces":{ + "up":{"uv":[11,7,12,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,7,12,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,7,12,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,7,12,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,7,12,8],"texture":"#texture","tintindex":4} + }},{"from":[11,0,8],"to":[12,1,9],"faces":{ + "up":{"uv":[11,8,12,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,8,12,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,8,12,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,8,12,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,8,12,9],"texture":"#texture","tintindex":4} + }},{"from":[11,0,9],"to":[12,1,10],"faces":{ + "up":{"uv":[11,9,12,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,9,12,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,9,12,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,9,12,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,9,12,10],"texture":"#texture","tintindex":4} + }},{"from":[11,0,10],"to":[12,1,11],"faces":{ + "up":{"uv":[11,10,12,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,10,12,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,10,12,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,10,12,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,10,12,11],"texture":"#texture","tintindex":4} + }},{"from":[11,0,11],"to":[12,1,12],"faces":{ + "up":{"uv":[11,11,12,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,11,12,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,11,12,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,11,12,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,11,12,12],"texture":"#texture","tintindex":4} + }},{"from":[11,0,12],"to":[12,1,13],"faces":{ + "up":{"uv":[11,12,12,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,12,12,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,12,12,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,12,12,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,12,12,13],"texture":"#texture","tintindex":4} + }},{"from":[11,0,13],"to":[12,1,14],"faces":{ + "up":{"uv":[11,13,12,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,13,12,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,13,12,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,13,12,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,13,12,14],"texture":"#texture","tintindex":4} + }},{"from":[11,0,14],"to":[12,1,15],"faces":{ + "up":{"uv":[11,14,12,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,14,12,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,14,12,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,14,12,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,14,12,15],"texture":"#texture","tintindex":4} + }},{"from":[11,0,15],"to":[12,1,16],"faces":{ + "up":{"uv":[11,15,12,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[11,15,12,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,15,12,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,15,12,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,15,12,16],"texture":"#texture","tintindex":4} + }},{"from":[12,0,0],"to":[13,1,1],"faces":{ + "up":{"uv":[12,0,13,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,0,13,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,0,13,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,0,13,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,0,13,1],"texture":"#texture","tintindex":4} + }},{"from":[12,0,1],"to":[13,1,2],"faces":{ + "up":{"uv":[12,1,13,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,1,13,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,1,13,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,1,13,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,1,13,2],"texture":"#texture","tintindex":4} + }},{"from":[12,0,2],"to":[13,1,3],"faces":{ + "up":{"uv":[12,2,13,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,2,13,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,2,13,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,2,13,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,2,13,3],"texture":"#texture","tintindex":4} + }},{"from":[12,0,3],"to":[13,1,4],"faces":{ + "up":{"uv":[12,3,13,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,3,13,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,3,13,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,3,13,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,3,13,4],"texture":"#texture","tintindex":4} + }},{"from":[12,0,4],"to":[13,1,5],"faces":{ + "up":{"uv":[12,4,13,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,4,13,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,4,13,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,4,13,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,4,13,5],"texture":"#texture","tintindex":4} + }},{"from":[12,0,5],"to":[13,1,6],"faces":{ + "up":{"uv":[12,5,13,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,5,13,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,5,13,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,5,13,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,5,13,6],"texture":"#texture","tintindex":4} + }},{"from":[12,0,6],"to":[13,1,7],"faces":{ + "up":{"uv":[12,6,13,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,6,13,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,6,13,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,6,13,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,6,13,7],"texture":"#texture","tintindex":4} + }},{"from":[12,0,7],"to":[13,1,8],"faces":{ + "up":{"uv":[12,7,13,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,7,13,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,7,13,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,7,13,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,7,13,8],"texture":"#texture","tintindex":4} + }},{"from":[12,0,8],"to":[13,1,9],"faces":{ + "up":{"uv":[12,8,13,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,8,13,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,8,13,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,8,13,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,8,13,9],"texture":"#texture","tintindex":4} + }},{"from":[12,0,9],"to":[13,1,10],"faces":{ + "up":{"uv":[12,9,13,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,9,13,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,9,13,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,9,13,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,9,13,10],"texture":"#texture","tintindex":4} + }},{"from":[12,0,10],"to":[13,1,11],"faces":{ + "up":{"uv":[12,10,13,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,10,13,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,10,13,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,10,13,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,10,13,11],"texture":"#texture","tintindex":4} + }},{"from":[12,0,11],"to":[13,1,12],"faces":{ + "up":{"uv":[12,11,13,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,11,13,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,11,13,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,11,13,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,11,13,12],"texture":"#texture","tintindex":4} + }},{"from":[12,0,12],"to":[13,1,13],"faces":{ + "up":{"uv":[12,12,13,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,12,13,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,12,13,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,12,13,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,12,13,13],"texture":"#texture","tintindex":4} + }},{"from":[12,0,13],"to":[13,1,14],"faces":{ + "up":{"uv":[12,13,13,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,13,13,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,13,13,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,13,13,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,13,13,14],"texture":"#texture","tintindex":4} + }},{"from":[12,0,14],"to":[13,1,15],"faces":{ + "up":{"uv":[12,14,13,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,14,13,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,14,13,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,14,13,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,14,13,15],"texture":"#texture","tintindex":4} + }},{"from":[12,0,15],"to":[13,1,16],"faces":{ + "up":{"uv":[12,15,13,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[12,15,13,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,15,13,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,15,13,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,15,13,16],"texture":"#texture","tintindex":4} + }},{"from":[13,0,0],"to":[14,1,1],"faces":{ + "up":{"uv":[13,0,14,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,0,14,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,0,14,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,0,14,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,0,14,1],"texture":"#texture","tintindex":4} + }},{"from":[13,0,1],"to":[14,1,2],"faces":{ + "up":{"uv":[13,1,14,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,1,14,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,1,14,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,1,14,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,1,14,2],"texture":"#texture","tintindex":4} + }},{"from":[13,0,2],"to":[14,1,3],"faces":{ + "up":{"uv":[13,2,14,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,2,14,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,2,14,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,2,14,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,2,14,3],"texture":"#texture","tintindex":4} + }},{"from":[13,0,3],"to":[14,1,4],"faces":{ + "up":{"uv":[13,3,14,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,3,14,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,3,14,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,3,14,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,3,14,4],"texture":"#texture","tintindex":4} + }},{"from":[13,0,4],"to":[14,1,5],"faces":{ + "up":{"uv":[13,4,14,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,4,14,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,4,14,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,4,14,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,4,14,5],"texture":"#texture","tintindex":4} + }},{"from":[13,0,5],"to":[14,1,6],"faces":{ + "up":{"uv":[13,5,14,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,5,14,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,5,14,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,5,14,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,5,14,6],"texture":"#texture","tintindex":4} + }},{"from":[13,0,6],"to":[14,1,7],"faces":{ + "up":{"uv":[13,6,14,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,6,14,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,6,14,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,6,14,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,6,14,7],"texture":"#texture","tintindex":4} + }},{"from":[13,0,7],"to":[14,1,8],"faces":{ + "up":{"uv":[13,7,14,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,7,14,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,7,14,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,7,14,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,7,14,8],"texture":"#texture","tintindex":4} + }},{"from":[13,0,8],"to":[14,1,9],"faces":{ + "up":{"uv":[13,8,14,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,8,14,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,8,14,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,8,14,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,8,14,9],"texture":"#texture","tintindex":4} + }},{"from":[13,0,9],"to":[14,1,10],"faces":{ + "up":{"uv":[13,9,14,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,9,14,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,9,14,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,9,14,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,9,14,10],"texture":"#texture","tintindex":4} + }},{"from":[13,0,10],"to":[14,1,11],"faces":{ + "up":{"uv":[13,10,14,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,10,14,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,10,14,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,10,14,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,10,14,11],"texture":"#texture","tintindex":4} + }},{"from":[13,0,11],"to":[14,1,12],"faces":{ + "up":{"uv":[13,11,14,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,11,14,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,11,14,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,11,14,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,11,14,12],"texture":"#texture","tintindex":4} + }},{"from":[13,0,12],"to":[14,1,13],"faces":{ + "up":{"uv":[13,12,14,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,12,14,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,12,14,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,12,14,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,12,14,13],"texture":"#texture","tintindex":4} + }},{"from":[13,0,13],"to":[14,1,14],"faces":{ + "up":{"uv":[13,13,14,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,13,14,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,13,14,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,13,14,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,13,14,14],"texture":"#texture","tintindex":4} + }},{"from":[13,0,14],"to":[14,1,15],"faces":{ + "up":{"uv":[13,14,14,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,14,14,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,14,14,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,14,14,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,14,14,15],"texture":"#texture","tintindex":4} + }},{"from":[13,0,15],"to":[14,1,16],"faces":{ + "up":{"uv":[13,15,14,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[13,15,14,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,15,14,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,15,14,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,15,14,16],"texture":"#texture","tintindex":4} + }},{"from":[14,0,0],"to":[15,1,1],"faces":{ + "up":{"uv":[14,0,15,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,0,15,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,0,15,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,0,15,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,0,15,1],"texture":"#texture","tintindex":4} + }},{"from":[14,0,1],"to":[15,1,2],"faces":{ + "up":{"uv":[14,1,15,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,1,15,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,1,15,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,1,15,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,1,15,2],"texture":"#texture","tintindex":4} + }},{"from":[14,0,2],"to":[15,1,3],"faces":{ + "up":{"uv":[14,2,15,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,2,15,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,2,15,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,2,15,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,2,15,3],"texture":"#texture","tintindex":4} + }},{"from":[14,0,3],"to":[15,1,4],"faces":{ + "up":{"uv":[14,3,15,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,3,15,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,3,15,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,3,15,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,3,15,4],"texture":"#texture","tintindex":4} + }},{"from":[14,0,4],"to":[15,1,5],"faces":{ + "up":{"uv":[14,4,15,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,4,15,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,4,15,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,4,15,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,4,15,5],"texture":"#texture","tintindex":4} + }},{"from":[14,0,5],"to":[15,1,6],"faces":{ + "up":{"uv":[14,5,15,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,5,15,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,5,15,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,5,15,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,5,15,6],"texture":"#texture","tintindex":4} + }},{"from":[14,0,6],"to":[15,1,7],"faces":{ + "up":{"uv":[14,6,15,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,6,15,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,6,15,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,6,15,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,6,15,7],"texture":"#texture","tintindex":4} + }},{"from":[14,0,7],"to":[15,1,8],"faces":{ + "up":{"uv":[14,7,15,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,7,15,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,7,15,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,7,15,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,7,15,8],"texture":"#texture","tintindex":4} + }},{"from":[14,0,8],"to":[15,1,9],"faces":{ + "up":{"uv":[14,8,15,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,8,15,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,8,15,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,8,15,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,8,15,9],"texture":"#texture","tintindex":4} + }},{"from":[14,0,9],"to":[15,1,10],"faces":{ + "up":{"uv":[14,9,15,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,9,15,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,9,15,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,9,15,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,9,15,10],"texture":"#texture","tintindex":4} + }},{"from":[14,0,10],"to":[15,1,11],"faces":{ + "up":{"uv":[14,10,15,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,10,15,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,10,15,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,10,15,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,10,15,11],"texture":"#texture","tintindex":4} + }},{"from":[14,0,11],"to":[15,1,12],"faces":{ + "up":{"uv":[14,11,15,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,11,15,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,11,15,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,11,15,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,11,15,12],"texture":"#texture","tintindex":4} + }},{"from":[14,0,12],"to":[15,1,13],"faces":{ + "up":{"uv":[14,12,15,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,12,15,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,12,15,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,12,15,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,12,15,13],"texture":"#texture","tintindex":4} + }},{"from":[14,0,13],"to":[15,1,14],"faces":{ + "up":{"uv":[14,13,15,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,13,15,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,13,15,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,13,15,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,13,15,14],"texture":"#texture","tintindex":4} + }},{"from":[14,0,14],"to":[15,1,15],"faces":{ + "up":{"uv":[14,14,15,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,14,15,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,14,15,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,14,15,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,14,15,15],"texture":"#texture","tintindex":4} + }},{"from":[14,0,15],"to":[15,1,16],"faces":{ + "up":{"uv":[14,15,15,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[14,15,15,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,15,15,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,15,15,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,15,15,16],"texture":"#texture","tintindex":4} + }},{"from":[15,0,0],"to":[16,1,1],"faces":{ + "up":{"uv":[15,0,16,1],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,0,16,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,0,16,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,0,16,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,0,16,1],"texture":"#texture","tintindex":4} + }},{"from":[15,0,1],"to":[16,1,2],"faces":{ + "up":{"uv":[15,1,16,2],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,1,16,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,1,16,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,1,16,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,1,16,2],"texture":"#texture","tintindex":4} + }},{"from":[15,0,2],"to":[16,1,3],"faces":{ + "up":{"uv":[15,2,16,3],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,2,16,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,2,16,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,2,16,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,2,16,3],"texture":"#texture","tintindex":4} + }},{"from":[15,0,3],"to":[16,1,4],"faces":{ + "up":{"uv":[15,3,16,4],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,3,16,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,3,16,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,3,16,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,3,16,4],"texture":"#texture","tintindex":4} + }},{"from":[15,0,4],"to":[16,1,5],"faces":{ + "up":{"uv":[15,4,16,5],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,4,16,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,4,16,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,4,16,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,4,16,5],"texture":"#texture","tintindex":4} + }},{"from":[15,0,5],"to":[16,1,6],"faces":{ + "up":{"uv":[15,5,16,6],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,5,16,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,5,16,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,5,16,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,5,16,6],"texture":"#texture","tintindex":4} + }},{"from":[15,0,6],"to":[16,1,7],"faces":{ + "up":{"uv":[15,6,16,7],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,6,16,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,6,16,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,6,16,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,6,16,7],"texture":"#texture","tintindex":4} + }},{"from":[15,0,7],"to":[16,1,8],"faces":{ + "up":{"uv":[15,7,16,8],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,7,16,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,7,16,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,7,16,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,7,16,8],"texture":"#texture","tintindex":4} + }},{"from":[15,0,8],"to":[16,1,9],"faces":{ + "up":{"uv":[15,8,16,9],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,8,16,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,8,16,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,8,16,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,8,16,9],"texture":"#texture","tintindex":4} + }},{"from":[15,0,9],"to":[16,1,10],"faces":{ + "up":{"uv":[15,9,16,10],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,9,16,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,9,16,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,9,16,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,9,16,10],"texture":"#texture","tintindex":4} + }},{"from":[15,0,10],"to":[16,1,11],"faces":{ + "up":{"uv":[15,10,16,11],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,10,16,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,10,16,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,10,16,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,10,16,11],"texture":"#texture","tintindex":4} + }},{"from":[15,0,11],"to":[16,1,12],"faces":{ + "up":{"uv":[15,11,16,12],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,11,16,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,11,16,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,11,16,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,11,16,12],"texture":"#texture","tintindex":4} + }},{"from":[15,0,12],"to":[16,1,13],"faces":{ + "up":{"uv":[15,12,16,13],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,12,16,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,12,16,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,12,16,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,12,16,13],"texture":"#texture","tintindex":4} + }},{"from":[15,0,13],"to":[16,1,14],"faces":{ + "up":{"uv":[15,13,16,14],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,13,16,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,13,16,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,13,16,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,13,16,14],"texture":"#texture","tintindex":4} + }},{"from":[15,0,14],"to":[16,1,15],"faces":{ + "up":{"uv":[15,14,16,15],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,14,16,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,14,16,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,14,16,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,14,16,15],"texture":"#texture","tintindex":4} + }},{"from":[15,0,15],"to":[16,1,16],"faces":{ + "up":{"uv":[15,15,16,16],"texture":"#texture","tintindex":0}, + "north":{"uv":[15,15,16,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,15,16,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,15,16,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,15,16,16],"texture":"#texture","tintindex":4} + }}], + "ctm_version_": 1, + "ctm_overrides": { + "0": { "type": "ctm" , "layer": "CUTOUT", "textures": [ "twilightforest:blocks/patch/moss_0_ctm" ] }, + "1": { "type": "ctm_tf_north", "layer": "CUTOUT", "textures": [ "twilightforest:blocks/patch/moss_0_ctm" ] }, + "2": { "type": "ctm_tf_south", "layer": "CUTOUT", "textures": [ "twilightforest:blocks/patch/moss_0_ctm" ] }, + "3": { "type": "ctm_tf_west" , "layer": "CUTOUT", "textures": [ "twilightforest:blocks/patch/moss_0_ctm" ] }, + "4": { "type": "ctm_tf_east" , "layer": "CUTOUT", "textures": [ "twilightforest:blocks/patch/moss_0_ctm" ] } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/naga_segment/down.json b/src/main/resources/assets/twilightforest/models/block/naga_segment/down.json new file mode 100644 index 0000000000..d04d83ef3a --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/naga_segment/down.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube", + "textures": { + "up": "twilightforest:blocks/nagastone_top_tip", + "down": "twilightforest:blocks/nagastone_cross_section", + "west": "twilightforest:blocks/nagastone_tip_up", + "north": "twilightforest:blocks/nagastone_left_down", + "east": "twilightforest:blocks/nagastone_cross_section", + "south": "twilightforest:blocks/nagastone_right_down" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/naga_segment/head.json b/src/main/resources/assets/twilightforest/models/block/naga_segment/head.json new file mode 100644 index 0000000000..06b3a65c44 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/naga_segment/head.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube", + "textures": { + "up": "twilightforest:blocks/nagastone_top_tip", + "down": "twilightforest:blocks/nagastone_bottom_tip", + "west": "twilightforest:blocks/nagastone_face_front", + "north": "twilightforest:blocks/nagastone_face_right", + "east": "twilightforest:blocks/nagastone_cross_section", + "south": "twilightforest:blocks/nagastone_face_left" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/naga_segment/hortizontal.json b/src/main/resources/assets/twilightforest/models/block/naga_segment/hortizontal.json new file mode 100644 index 0000000000..0286bb2407 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/naga_segment/hortizontal.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube", + "textures": { + "up": "twilightforest:blocks/nagastone_tip_long", + "down": "twilightforest:blocks/nagastone_bottom_long", + "west": "twilightforest:blocks/nagastone_cross_section", + "north": "twilightforest:blocks/nagastone_long_side", + "east": "twilightforest:blocks/nagastone_cross_section", + "south": "twilightforest:blocks/nagastone_long_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/naga_segment/up.json b/src/main/resources/assets/twilightforest/models/block/naga_segment/up.json new file mode 100644 index 0000000000..05307ffdb2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/naga_segment/up.json @@ -0,0 +1,11 @@ +{ + "parent": "block/cube", + "textures": { + "up": "twilightforest:blocks/nagastone_cross_section", + "down": "twilightforest:blocks/nagastone_bottom_tip", + "west": "twilightforest:blocks/nagastone_tip_down", + "north": "twilightforest:blocks/nagastone_left_up", + "east": "twilightforest:blocks/nagastone_cross_section", + "south": "twilightforest:blocks/nagastone_right_up" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/naga_segment/vertical.json b/src/main/resources/assets/twilightforest/models/block/naga_segment/vertical.json new file mode 100644 index 0000000000..51d5d2387e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/naga_segment/vertical.json @@ -0,0 +1,7 @@ +{ + "parent": "block/cube_column", + "textures": { + "end": "twilightforest:blocks/nagastone_cross_section", + "side": "twilightforest:blocks/nagastone_long_vertical" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_12_ctm.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_12_ctm.json new file mode 100644 index 0000000000..bd0fe30bd3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_12_ctm.json @@ -0,0 +1,39 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side_x" + }, + "elements": [{ + "from": [ 2, 0, 0 ], + "to" : [ 14, 16, 16 ], + "faces": { + "west" : { "texture": "#side_x" }, + "east" : { "texture": "#side_x" } + } + }, { + "from": [ 0, 0, 2 ], + "to" : [ 16, 16, 14 ], + "faces": { + "north": { "texture": "#side_z" }, + "south": { "texture": "#side_z" } + } + }, { + "from": [ 0, 3, 0 ], + "to" : [ 16, 13, 16 ], + "faces": { + "up" : { "texture": "#blank", "tintindex": 0 }, + "down": { "texture": "#blank", "tintindex": 0 } + } + }], + "ctm_overrides": { + "1": { + "type": "CTM", + "layer": "CUTOUT", + "textures": [ "#crown" ], + "extra": { + "connect_inside": true + } + } + } +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_bottom.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_bottom.json new file mode 100644 index 0000000000..6129b493bc --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_bottom.json @@ -0,0 +1,16 @@ +{ + "parent": "block/block", + "elements": [{ + "from": [ 0, 0, 0 ], + "to" : [ 16, 3, 16 ], + "faces": { + "down" : { "texture": "#bottom_cap", "cullface": "down" }, + "up" : { "texture": "#bottom_cap" }, + "north": { "texture": "#bottom_z" , "cullface": "north" }, + "south": { "texture": "#bottom_z" , "cullface": "south" }, + "west" : { "texture": "#bottom_x" , "cullface": "west" }, + "east" : { "texture": "#bottom_x" , "cullface": "east" } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_top.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_top.json new file mode 100644 index 0000000000..8339826780 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_top.json @@ -0,0 +1,16 @@ +{ + "parent": "block/block", + "elements": [{ + "from": [ 0, 13, 0 ], + "to" : [ 16, 16, 16 ], + "faces": { + "down" : { "texture": "#top_cap" }, + "up" : { "texture": "#top_cap", "cullface": "up" }, + "north": { "texture": "#top_z" , "cullface": "north" }, + "south": { "texture": "#top_z" , "cullface": "south" }, + "west" : { "texture": "#top_x" , "cullface": "west" }, + "east" : { "texture": "#top_x" , "cullface": "east" } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_x_bottom.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_x_bottom.json new file mode 100644 index 0000000000..3667cd1a5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_x_bottom.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [{ + "from": [ 0, 0, 0 ], + "to" : [ 16, 3, 16 ], + "faces": { + "down" : { "texture": "#bottom_cap", "cullface": "down" , "tintindex": 0 }, + "up" : { "texture": "#bottom_cap" , "tintindex": 0 }, + "north": { "texture": "#bottom_z" , "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#bottom_z" , "cullface": "south", "tintindex": 1 }, + "west" : { "texture": "#bottom_x" , "cullface": "west" , "tintindex": 2 }, + "east" : { "texture": "#bottom_x" , "cullface": "east" , "tintindex": 2 } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_x_top.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_x_top.json new file mode 100644 index 0000000000..82c2df0331 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_x_top.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [{ + "from": [ 0, 13, 0 ], + "to" : [ 16, 16, 16 ], + "faces": { + "down" : { "texture": "#top_cap" , "tintindex": 0 }, + "up" : { "texture": "#top_cap", "cullface": "up" , "tintindex": 0 }, + "north": { "texture": "#top_z" , "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#top_z" , "cullface": "south", "tintindex": 1 }, + "west" : { "texture": "#top_x" , "cullface": "west" , "tintindex": 2 }, + "east" : { "texture": "#top_x" , "cullface": "east" , "tintindex": 2 } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_y_bottom.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_y_bottom.json new file mode 100644 index 0000000000..3667cd1a5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_y_bottom.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [{ + "from": [ 0, 0, 0 ], + "to" : [ 16, 3, 16 ], + "faces": { + "down" : { "texture": "#bottom_cap", "cullface": "down" , "tintindex": 0 }, + "up" : { "texture": "#bottom_cap" , "tintindex": 0 }, + "north": { "texture": "#bottom_z" , "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#bottom_z" , "cullface": "south", "tintindex": 1 }, + "west" : { "texture": "#bottom_x" , "cullface": "west" , "tintindex": 2 }, + "east" : { "texture": "#bottom_x" , "cullface": "east" , "tintindex": 2 } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_y_top.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_y_top.json new file mode 100644 index 0000000000..82c2df0331 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_y_top.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [{ + "from": [ 0, 13, 0 ], + "to" : [ 16, 16, 16 ], + "faces": { + "down" : { "texture": "#top_cap" , "tintindex": 0 }, + "up" : { "texture": "#top_cap", "cullface": "up" , "tintindex": 0 }, + "north": { "texture": "#top_z" , "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#top_z" , "cullface": "south", "tintindex": 1 }, + "west" : { "texture": "#top_x" , "cullface": "west" , "tintindex": 2 }, + "east" : { "texture": "#top_x" , "cullface": "east" , "tintindex": 2 } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_z_bottom.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_z_bottom.json new file mode 100644 index 0000000000..3667cd1a5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_z_bottom.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [{ + "from": [ 0, 0, 0 ], + "to" : [ 16, 3, 16 ], + "faces": { + "down" : { "texture": "#bottom_cap", "cullface": "down" , "tintindex": 0 }, + "up" : { "texture": "#bottom_cap" , "tintindex": 0 }, + "north": { "texture": "#bottom_z" , "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#bottom_z" , "cullface": "south", "tintindex": 1 }, + "west" : { "texture": "#bottom_x" , "cullface": "west" , "tintindex": 2 }, + "east" : { "texture": "#bottom_x" , "cullface": "east" , "tintindex": 2 } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/pillar/pillar_z_top.json b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_z_top.json new file mode 100644 index 0000000000..82c2df0331 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/pillar/pillar_z_top.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [{ + "from": [ 0, 13, 0 ], + "to" : [ 16, 16, 16 ], + "faces": { + "down" : { "texture": "#top_cap" , "tintindex": 0 }, + "up" : { "texture": "#top_cap", "cullface": "up" , "tintindex": 0 }, + "north": { "texture": "#top_z" , "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#top_z" , "cullface": "south", "tintindex": 1 }, + "west" : { "texture": "#top_x" , "cullface": "west" , "tintindex": 2 }, + "east" : { "texture": "#top_x" , "cullface": "east" , "tintindex": 2 } + } + }] +} + diff --git a/src/main/resources/assets/twilightforest/models/block/portal.json b/src/main/resources/assets/twilightforest/models/block/portal.json new file mode 100755 index 0000000000..a50c4ad4c3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/portal.json @@ -0,0 +1,5 @@ +{ + "parent": "block/block", + "textures": { "all": "blocks/portal", "particle": "blocks/portal" }, + "elements": [{ "from": [ 0, 13, 0 ], "to": [ 16, 13, 16 ], "faces": {"up": {"texture": "#all" }}}] +} diff --git a/src/main/resources/assets/twilightforest/models/block/portal_barrier.json b/src/main/resources/assets/twilightforest/models/block/portal_barrier.json new file mode 100755 index 0000000000..a9a6d9c2dc --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/portal_barrier.json @@ -0,0 +1,5 @@ +{ + "parent": "block/block", + "textures": { "all": "twilightforest:blocks/portal_barrier", "particle": "blocks/portal" }, + "elements": [{ "from": [ 0, 14.5, 0 ], "to": [ 16, 14.5, 16 ], "faces": {"up": {"texture": "#all" }}}] +} diff --git a/src/main/resources/assets/twilightforest/models/block/slider.json b/src/main/resources/assets/twilightforest/models/block/slider.json new file mode 100755 index 0000000000..ddb55da537 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/slider.json @@ -0,0 +1,20 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 5, 0, 5 ], + "to": [ 11, 16, 11 ], + "faces": { + "down": { "uv": [ 5, 5, 11, 11 ], "texture": "#end", "cullface": "down" }, + "up": { "uv": [ 5, 5, 11, 11 ], "texture": "#end", "cullface": "up"}, + "north": { "uv": [ 5, 0, 11, 16 ], "texture": "#side"}, + "south": { "uv": [ 5, 0, 11, 16 ], "texture": "#side"}, + "west": { "uv": [ 5, 0, 11, 16 ], "texture": "#side"}, + "east": { "uv": [ 5, 0, 11, 16 ], "texture": "#side"} + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/spiral_bottom_left.json b/src/main/resources/assets/twilightforest/models/block/spiral_bottom_left.json new file mode 100644 index 0000000000..3e32bd408f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/spiral_bottom_left.json @@ -0,0 +1,186 @@ +{ + "parent": "block/block", + "textures": { + "pattern": "twilightforest:blocks/stone_spiral_large", + "border": "blocks/stonebrick_carved", + "particle": "blocks/stonebrick_carved" + }, + "elements": [ + { + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "faces": { + "up": { "texture": "#border", "cullface": "up" }, + "north": { "texture": "#inner_b", "cullface": "north" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 8, 0, 16, 1.5 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 14.5, 1.5, 16, 8 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 0.5, 10, 0 ], + "to": [ 8 , 13, 13 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 1.5, 14.5, 3 ], "texture": "#pattern" } + } + }, + { + "from": [ 1.5, 7, 0 ], + "to": [ 8 , 10, 10 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 3, 13, 4.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 2.5, 4, 0 ], + "to": [ 8 , 7, 7 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 4.5, 11.5, 6 ], "texture": "#pattern" } + } + }, + { + "from": [ 3.5, 1, 0 ], + "to": [ 8 , 4, 4 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 6, 10, 7.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 0.25, 0, 10 ], + "to": [ 8 , 10, 13 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 13, 3, 14.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 1.25, 0, 7 ], + "to": [ 8 , 7, 10 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 11.5, 4.5, 13, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 2.25, 0, 4 ], + "to": [ 8 , 4, 7 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 10, 6, 11.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 3.25, 0, 1 ], + "to": [ 8 , 1, 4 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 8.5, 7.5, 10, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 4.25, 0, 0 ], + "to": [ 8 , 1, 1 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 7.5, 8.5, 8 ], "texture": "#pattern" } + } + }, + { "//COMMENT": "//NO SHADE - INNER SHADOWING", + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "shade": false, + "faces": { + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 0.5, 10, 0 ], + "to": [ 8 , 13, 13 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 1.5, 7, 0 ], + "to": [ 8 , 10, 10 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 2.5, 4, 0 ], + "to": [ 8 , 7, 7 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 3.5, 1, 0 ], + "to": [ 8 , 4, 4 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 0.25, 0, 10 ], + "to": [ 8 , 10, 13 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 1.25, 0, 7 ], + "to": [ 8 , 7, 10 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 2.25, 0, 4 ], + "to": [ 8 , 4, 7 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 3.25, 0, 1 ], + "to": [ 8 , 1, 4 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/spiral_bottom_right.json b/src/main/resources/assets/twilightforest/models/block/spiral_bottom_right.json new file mode 100644 index 0000000000..ab519832c7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/spiral_bottom_right.json @@ -0,0 +1,186 @@ +{ + "parent": "block/block", + "textures": { + "pattern": "twilightforest:blocks/stone_spiral_large", + "border": "blocks/stonebrick_carved", + "particle": "blocks/stonebrick_carved" + }, + "elements": [ + { + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "faces": { + "up": { "texture": "#border", "cullface": "up" }, + "north": { "texture": "#inner_a", "cullface": "north" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 8, 0, 16, 1.5 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 14.5, 1.5, 16, 8 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 0.75, 10, 0 ], + "to": [ 8 , 13, 13 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 1.5, 14.5, 3 ], "texture": "#pattern" } + } + }, + { + "from": [ 1.75, 7, 0 ], + "to": [ 8 , 10, 10 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 3, 13, 4.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 2.75, 4, 0 ], + "to": [ 8 , 7, 7 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 4.5, 11.5, 6 ], "texture": "#pattern" } + } + }, + { + "from": [ 3.75, 1, 0 ], + "to": [ 8 , 4, 4 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 6, 10, 7.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 0.5, 0, 10 ], + "to": [ 8 , 10, 13 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 13, 3, 14.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 1.5, 0, 7 ], + "to": [ 8 , 7, 10 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 11.5, 4.5, 13, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 2.5, 0, 4 ], + "to": [ 8 , 4, 7 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 10, 6, 11.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 3.5, 0, 1 ], + "to": [ 8 , 1, 4 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 8.5, 7.5, 10, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 4.25, 0, 0 ], + "to": [ 8 , 1, 1 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 7.5, 8.5, 8 ], "texture": "#pattern" } + } + }, + { "//COMMENT": "//NO SHADE - INNER SHADOWING", + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "shade": false, + "faces": { + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 0.75, 10, 0 ], + "to": [ 8 , 13, 13 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 1.75, 7, 0 ], + "to": [ 8 , 10, 10 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 2.75, 4, 0 ], + "to": [ 8 , 7, 7 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 3.75, 1, 0 ], + "to": [ 8 , 4, 4 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 0.5, 0, 10 ], + "to": [ 8 , 10, 13 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 1.5, 0, 7 ], + "to": [ 8 , 7, 10 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 2.5, 0, 4 ], + "to": [ 8 , 4, 7 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 3.5, 0, 1 ], + "to": [ 8 , 1, 4 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/spiral_quarter.json b/src/main/resources/assets/twilightforest/models/block/spiral_quarter.json new file mode 100644 index 0000000000..02993a01cd --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/spiral_quarter.json @@ -0,0 +1,112 @@ +{ + "parent": "block/block", + "textures": { + "all": "twilightforest:blocks/stone_spiral_large", + "border": "blocks/stonebrick_carved", + "particle": "blocks/stonebrick_carved" + }, + "elements": [ + { + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "faces": { + "up": { "texture": "#border", "cullface": "up" }, + "down": { "texture": "#border" }, + "north": { "texture": "#border", "cullface": "north" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 8, 0, 16, 1.5 ], "texture": "#all", "cullface": "west" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "faces": { + "down": { "texture": "#border", "cullface": "down" }, + "north": { "texture": "#border" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 14.5, 1.5, 16, 8 ], "texture": "#all", "cullface": "west" } + } + }, + { + "from": [ 0.5, 10, 0 ], + "to": [ 8 , 13, 13 ], + "faces": { + "down": { "texture": "#border" }, + "north": { "texture": "#border", "cullface": "north" }, + "west": { "uv": [ 8, 1.5, 14.5, 3 ], "texture": "#all" } + } + }, + { + "from": [ 1, 7, 0 ], + "to": [ 8, 10, 10 ], + "faces": { + "down": { "texture": "#border" }, + "north": { "texture": "#border", "cullface": "north" }, + "west": { "uv": [ 8, 3, 13, 4.5 ], "texture": "#all" } + } + }, + { + "from": [ 1.5, 4, 0 ], + "to": [ 8 , 7, 7 ], + "faces": { + "down": { "texture": "#border" }, + "north": { "texture": "#border", "cullface": "north" }, + "west": { "uv": [ 8, 4.5, 11.5, 6 ], "texture": "#all" } + } + }, + { + "from": [ 2, 1, 0 ], + "to": [ 8, 4, 4 ], + "faces": { + "down": { "texture": "#border" }, + "north": { "texture": "#border", "cullface": "north" }, + "west": { "uv": [ 8, 6, 10, 7.5 ], "texture": "#all" } + } + }, + { + "from": [ 0.5, 0, 10 ], + "to": [ 8 , 10, 13 ], + "faces": { + "down": { "texture": "#border", "cullface": "down" }, + "north": { "texture": "#border" }, + "west": { "uv": [ 13, 3, 14.5, 8 ], "texture": "#all" } + } + }, + { + "from": [ 1, 0, 7 ], + "to": [ 8, 7, 10 ], + "faces": { + "down": { "texture": "#border", "cullface": "down" }, + "north": { "texture": "#border" }, + "west": { "uv": [ 11.5, 4.5, 13, 8 ], "texture": "#all" } + } + }, + { + "from": [ 1.5, 0, 4 ], + "to": [ 8 , 4, 7 ], + "faces": { + "down": { "texture": "#border", "cullface": "down" }, + "north": { "texture": "#border" }, + "west": { "uv": [ 10, 6, 11.5, 8 ], "texture": "#all" } + } + }, + { + "from": [ 2, 0, 1 ], + "to": [ 8, 1, 4 ], + "faces": { + "down": { "texture": "#border", "cullface": "down" }, + "north": { "texture": "#border" }, + "west": { "uv": [ 8.5, 7.5, 10, 8 ], "texture": "#all" } + } + }, + { + "from": [ 2.5, 0, 0 ], + "to": [ 8 , 1, 1 ], + "faces": { + "down": { "texture": "#border", "cullface": "down" }, + "north": { "texture": "#border", "cullface": "north" }, + "west": { "uv": [ 8, 7.5, 8.5, 8 ], "texture": "#all" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/spiral_top_left.json b/src/main/resources/assets/twilightforest/models/block/spiral_top_left.json new file mode 100644 index 0000000000..1d3a663a9a --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/spiral_top_left.json @@ -0,0 +1,186 @@ +{ + "parent": "block/block", + "textures": { + "pattern": "twilightforest:blocks/stone_spiral_large", + "border": "blocks/stonebrick_carved", + "particle": "blocks/stonebrick_carved" + }, + "elements": [ + { + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "faces": { + "up": { "texture": "#border", "cullface": "up" }, + "north": { "texture": "#inner_b", "cullface": "north" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 8, 0, 16, 1.5 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 14.5, 1.5, 16, 8 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 0.25, 10, 0 ], + "to": [ 8 , 13, 13 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 1.5, 14.5, 3 ], "texture": "#pattern" } + } + }, + { + "from": [ 1.25, 7, 0 ], + "to": [ 8 , 10, 13 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 3, 14.5, 4.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 2.25, 4, 0 ], + "to": [ 8 , 7, 10 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 4.5, 13, 6 ], "texture": "#pattern" } + } + }, + { + "from": [ 3.25, 1, 0 ], + "to": [ 8 , 4, 7 ], + "faces": { + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 6, 11.5, 7.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 1, 0, 10 ], + "to": [ 8, 7, 13 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 13, 4.5, 14.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 2, 0, 7 ], + "to": [ 8, 4, 10 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 11.5, 6, 13, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 3, 0, 4 ], + "to": [ 8, 1, 7 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 10, 7.5, 11.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 4, 0, 1 ], + "to": [ 8, 1, 4 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "west": { "uv": [ 8.5, 7.5, 10, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 4.25, 0, 0 ], + "to": [ 8 , 1, 1 ], + "faces": { + "down": { "texture": "#inner_a", "cullface": "down" }, + "north": { "texture": "#inner_b", "cullface": "north" }, + "west": { "uv": [ 8, 7.5, 8.5, 8 ], "texture": "#pattern" } + } + }, + { "//COMMENT": "//NO SHADE - INNER SHADOWING", + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "shade": false, + "faces": { + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 0.25, 10, 0 ], + "to": [ 8 , 13, 13 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 1.25, 7, 0 ], + "to": [ 8 , 10, 13 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 2.25, 4, 0 ], + "to": [ 8 , 7, 10 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 3.25, 1, 0 ], + "to": [ 8 , 4, 7 ], + "shade": false, + "faces": { + "down": { "texture": "#shadow_z" } + } + }, + { + "from": [ 1, 0, 10 ], + "to": [ 8, 7, 13 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 2, 0, 7 ], + "to": [ 8, 4, 10 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 3, 0, 4 ], + "to": [ 8, 1, 7 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + }, + { + "from": [ 4, 0, 1 ], + "to": [ 8, 1, 4 ], + "shade": false, + "faces": { + "up": { "texture": "#shadow_z" }, + "north": { "texture": "#shadow_y" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/spiral_top_right.json b/src/main/resources/assets/twilightforest/models/block/spiral_top_right.json new file mode 100644 index 0000000000..2e37f56ef9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/spiral_top_right.json @@ -0,0 +1,176 @@ +{ + "parent": "block/block", + "textures": { + "pattern": "twilightforest:blocks/stone_spiral_large", + "border": "blocks/stonebrick_carved", + "particle": "blocks/stonebrick_carved" + }, + "elements": [ + { + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "faces": { + "up": { "texture": "#border", "cullface": "up" }, + "north": { "texture": "#inner_a", "cullface": "north" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 8, 0, 16, 1.5 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "south": { "texture": "#border", "cullface": "south" }, + "west": { "uv": [ 14.5, 1.5, 16, 8 ], "texture": "#pattern", "cullface": "west" } + } + }, + { + "from": [ 1, 10, 0 ], + "to": [ 8, 13, 13 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 1.5, 14.5, 3 ], "texture": "#pattern" } + } + }, + { + "from": [ 2, 7, 0 ], + "to": [ 8, 10, 10 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 3, 13, 4.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 3, 4, 0 ], + "to": [ 8, 7, 7 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 4.5, 11.5, 6 ], "texture": "#pattern" } + } + }, + { + "from": [ 4, 1, 0 ], + "to": [ 8, 4, 4 ], + "faces": { + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 6, 10, 7.5 ], "texture": "#pattern" } + } + }, + { + "from": [ 0.75, 0, 10 ], + "to": [ 8 , 10, 13 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 13, 3, 14.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 1.75, 0, 7 ], + "to": [ 8 , 7, 10 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 11.5, 4.5, 13, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 2.75, 0, 4 ], + "to": [ 8 , 4, 7 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 10, 6, 11.5, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 3.75, 0, 1 ], + "to": [ 8 , 1, 4 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "west": { "uv": [ 8.5, 7.5, 10, 8 ], "texture": "#pattern" } + } + }, + { + "from": [ 4.25, 0, 0 ], + "to": [ 8 , 1, 1 ], + "faces": { + "down": { "texture": "#inner_b", "cullface": "down" }, + "north": { "texture": "#inner_a", "cullface": "north" }, + "west": { "uv": [ 8, 7.5, 8.5, 8 ], "texture": "#pattern" } + } + }, + { "//COMMENT": "//NO SHADE - INNER SHADOWING", + "from": [ 0, 13, 0 ], + "to": [ 8, 16, 16 ], + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 0, 0, 13 ], + "to": [ 8, 13, 16 ], + "faces": { + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 1, 10, 0 ], + "to": [ 8, 13, 13 ], + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 2, 7, 0 ], + "to": [ 8, 10, 10 ], + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 3, 4, 0 ], + "to": [ 8, 7, 7 ], + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 4, 1, 0 ], + "to": [ 8, 4, 4 ], + "faces": { + "down": { "texture": "#shadow_y" } + } + }, + { + "from": [ 0.75, 0, 10 ], + "to": [ 8 , 10, 13 ], + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 1.75, 0, 7 ], + "to": [ 8 , 7, 10 ], + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 2.75, 0, 4 ], + "to": [ 8 , 4, 7 ], + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + }, + { + "from": [ 3.75, 0, 1 ], + "to": [ 8 , 1, 4 ], + "faces": { + "up": { "texture": "#shadow_y" }, + "north": { "texture": "#shadow_z" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/thorns_main.json b/src/main/resources/assets/twilightforest/models/block/thorns_main.json new file mode 100755 index 0000000000..8e11aa32aa --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/thorns_main.json @@ -0,0 +1,47 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 8 ], + "to": [ 16, 16, 8 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" } + } + }, + { + "from": [ 8, 0, 0 ], + "to": [ 8, 16, 16 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#side" } + } + }, + { + "from": [ 3, 0, 3 ], + "to": [ 13, 16, 13 ], + "faces": { + "down": { "texture": "#end", "tintindex": 0, "cullface": "down" }, + "up": { "texture": "#end", "tintindex": 0, "cullface": "up" }, + "north": { "texture": "#side", "tintindex": 0, "uv": [3, 0, 13, 16] }, + "south": { "texture": "#side", "tintindex": 0, "uv": [3, 0, 13, 16] }, + "west": { "texture": "#side", "tintindex": 0, "uv": [13, 0, 3, 16] }, + "east": { "texture": "#side", "tintindex": 0, "uv": [13, 0, 3, 16] } + } + } + ], + "ctm_version_": 1, + "ctm_overrides": { + "0": { + "type":"eldritch", + "layer":"CUTOUT" + } + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/thorns_section_bottom.json b/src/main/resources/assets/twilightforest/models/block/thorns_section_bottom.json new file mode 100755 index 0000000000..83b5aa0d3f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/thorns_section_bottom.json @@ -0,0 +1,31 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 0, 16, 16 ], + "faces": { + "west": { "texture": "#end", "cullface": "west" } + } + }, + { + "from": [ 0, 0, 3 ], + "to": [ 3, 16, 13 ], + "faces": { + "north": { "texture": "#side", "uv": [0, 16, 16, 13], "rotation": 90 }, + "south": { "texture": "#side", "uv": [16, 13, 0, 16], "rotation": 90 } + } + }, + { + "from": [ 0, 3, 0 ], + "to": [ 3, 13, 16 ], + "faces": { + "down": { "texture": "#side", "uv": [0, 13, 16, 16], "rotation": 90 }, + "up": { "texture": "#side", "uv": [0, 13, 16, 16], "rotation": 90 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/thorns_section_top.json b/src/main/resources/assets/twilightforest/models/block/thorns_section_top.json new file mode 100755 index 0000000000..0f492ca42c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/thorns_section_top.json @@ -0,0 +1,31 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 16, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "east": { "texture": "#end", "cullface": "east" } + } + }, + { + "from": [ 13, 0, 3 ], + "to": [ 16, 16, 13 ], + "faces": { + "north": { "texture": "#side", "uv": [0, 3, 16, 0], "rotation": 90 }, + "south": { "texture": "#side", "uv": [16, 0, 0, 3], "rotation": 90 } + } + }, + { + "from": [ 13, 3, 0 ], + "to": [ 16, 13, 16 ], + "faces": { + "down": { "texture": "#side", "uv": [0, 0, 16, 3], "rotation": 90 }, + "up": { "texture": "#side", "uv": [0, 0, 16, 3], "rotation": 90 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/4_cubed.json b/src/main/resources/assets/twilightforest/models/block/util/4_cubed.json new file mode 100644 index 0000000000..58c0e3e104 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/4_cubed.json @@ -0,0 +1,18 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 6, 6, 6 ], + "to": [ 10, 10, 10 ], + "shade": false, + "faces": { + "down": { "texture": "#all" }, + "up": { "texture": "#all" }, + "north": { "texture": "#all" }, + "south": { "texture": "#all" }, + "west": { "texture": "#all" }, + "east": { "texture": "#all" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cross_2_layer.json b/src/main/resources/assets/twilightforest/models/block/util/cross_2_layer.json new file mode 100755 index 0000000000..30d45ff25c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cross_2_layer.json @@ -0,0 +1,44 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "#cross" + }, + "elements": [ + { "from": [ 0.8, 0, 8 ], + "to": [ 15.2, 16, 8 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "north": { "uv": [ 16, 0, 0, 16 ], "texture": "#cross" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" } + } + }, + { "from": [ 8, 0, 0.8 ], + "to": [ 8, 16, 15.2 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" }, + "east": { "uv": [ 16, 0, 0, 16 ], "texture": "#cross" } + } + }, + { "from": [ 0.8, 0, 8 ], + "to": [ 15.2, 16, 8 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "north": { "uv": [ 16, 0, 0, 16 ], "texture": "#cross2" }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross2" } + } + }, + { "from": [ 8, 0, 0.8 ], + "to": [ 8, 16, 15.2 ], + "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, + "shade": false, + "faces": { + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross2" }, + "east": { "uv": [ 16, 0, 0, 16 ], "texture": "#cross2" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer.json b/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer.json new file mode 100644 index 0000000000..acdf425d36 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer.json @@ -0,0 +1,29 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#down" , "cullface": "down" , "tintindex": 16 }, + "up": { "texture": "#up" , "cullface": "up" , "tintindex": 16 }, + "north": { "texture": "#north", "cullface": "north", "tintindex": 16 }, + "south": { "texture": "#south", "cullface": "south", "tintindex": 16 }, + "west": { "texture": "#west" , "cullface": "west" , "tintindex": 16 }, + "east": { "texture": "#east" , "cullface": "east" , "tintindex": 16 } + } + }, { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#down2" , "cullface": "down" , "tintindex": 0 }, + "up": { "texture": "#up2" , "cullface": "up" , "tintindex": 0 }, + "north": { "texture": "#north2", "cullface": "north", "tintindex": 0 }, + "south": { "texture": "#south2", "cullface": "south", "tintindex": 0 }, + "west": { "texture": "#west2" , "cullface": "west" , "tintindex": 0 }, + "east": { "texture": "#east2" , "cullface": "east" , "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer_allshade.json b/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer_allshade.json new file mode 100644 index 0000000000..c11dd048fb --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer_allshade.json @@ -0,0 +1,28 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#down" , "cullface": "down" , "tintindex": 16 }, + "up": { "texture": "#up" , "cullface": "up" , "tintindex": 16 }, + "north": { "texture": "#north", "cullface": "north", "tintindex": 16 }, + "south": { "texture": "#south", "cullface": "south", "tintindex": 16 }, + "west": { "texture": "#west" , "cullface": "west" , "tintindex": 16 }, + "east": { "texture": "#east" , "cullface": "east" , "tintindex": 16 } + } + }, { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#down2" , "cullface": "down" , "tintindex": 0 }, + "up": { "texture": "#up2" , "cullface": "up" , "tintindex": 0 }, + "north": { "texture": "#north2", "cullface": "north", "tintindex": 0 }, + "south": { "texture": "#south2", "cullface": "south", "tintindex": 0 }, + "west": { "texture": "#west2" , "cullface": "west" , "tintindex": 0 }, + "east": { "texture": "#east2" , "cullface": "east" , "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer_no_shade.json b/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer_no_shade.json new file mode 100644 index 0000000000..d121287b32 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_2_layer_no_shade.json @@ -0,0 +1,63 @@ +{ + "display": { + "gui": { + "rotation": [ 30, 225, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.625, 0.625, 0.625 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0], + "scale":[ 0.25, 0.25, 0.25 ] + }, + "fixed": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 45, 0 ], + "translation": [ 0, 2.5, 0], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 45, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 225, 0 ], + "translation": [ 0, 0, 0 ], + "scale": [ 0.40, 0.40, 0.40 ] + } + }, + "ambientocclusion": false, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#down", "cullface": "down" }, + "up": { "texture": "#up", "cullface": "up" }, + "north": { "texture": "#north", "cullface": "north" }, + "south": { "texture": "#south", "cullface": "south" }, + "west": { "texture": "#west", "cullface": "west" }, + "east": { "texture": "#east", "cullface": "east" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#down2", "cullface": "down" }, + "up": { "texture": "#up2", "cullface": "up" }, + "north": { "texture": "#north2", "cullface": "north" }, + "south": { "texture": "#south2", "cullface": "south" }, + "west": { "texture": "#west2", "cullface": "west" }, + "east": { "texture": "#east2", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_3_layer.json b/src/main/resources/assets/twilightforest/models/block/util/cube_3_layer.json new file mode 100644 index 0000000000..e8f46cfa94 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_3_layer.json @@ -0,0 +1,43 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#down", "cullface": "down" }, + "up": { "texture": "#up", "cullface": "up" }, + "north": { "texture": "#north", "cullface": "north" }, + "south": { "texture": "#south", "cullface": "south" }, + "west": { "texture": "#west", "cullface": "west" }, + "east": { "texture": "#east", "cullface": "east" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#down2", "cullface": "down" }, + "up": { "texture": "#up2", "cullface": "up" }, + "north": { "texture": "#north2", "cullface": "north" }, + "south": { "texture": "#south2", "cullface": "south" }, + "west": { "texture": "#west2", "cullface": "west" }, + "east": { "texture": "#east2", "cullface": "east" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "down": { "texture": "#down3", "cullface": "down" }, + "up": { "texture": "#up3", "cullface": "up" }, + "north": { "texture": "#north3", "cullface": "north" }, + "south": { "texture": "#south3", "cullface": "south" }, + "west": { "texture": "#west3", "cullface": "west" }, + "east": { "texture": "#east3", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer.json b/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer.json new file mode 100644 index 0000000000..ce82a8adfd --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer.json @@ -0,0 +1,18 @@ +{ + "parent": "twilightforest:block/util/cube_2_layer", + "textures": { + "particle": "#all", + "down": "#all", + "up": "#all", + "north": "#all", + "east": "#all", + "south": "#all", + "west": "#all", + "down2": "#all2", + "up2": "#all2", + "north2": "#all2", + "east2": "#all2", + "south2": "#all2", + "west2": "#all2" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer_allshade.json b/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer_allshade.json new file mode 100644 index 0000000000..2033a2f7f9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer_allshade.json @@ -0,0 +1,18 @@ +{ + "parent": "twilightforest:block/util/cube_2_layer_allshade", + "textures": { + "particle": "#all", + "down": "#all", + "up": "#all", + "north": "#all", + "east": "#all", + "south": "#all", + "west": "#all", + "down2": "#all2", + "up2": "#all2", + "north2": "#all2", + "east2": "#all2", + "south2": "#all2", + "west2": "#all2" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer_no_shade.json b/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer_no_shade.json new file mode 100644 index 0000000000..f6a466db70 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_all_2_layer_no_shade.json @@ -0,0 +1,19 @@ +{ + "parent": "twilightforest:block/util/cube_2_layer_no_shade", + "ambientocclusion": false, + "textures": { + "particle": "#all", + "down": "#all", + "up": "#all", + "north": "#all", + "east": "#all", + "south": "#all", + "west": "#all", + "down2": "#all2", + "up2": "#all2", + "north2": "#all2", + "east2": "#all2", + "south2": "#all2", + "west2": "#all2" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_all_3_layer.json b/src/main/resources/assets/twilightforest/models/block/util/cube_all_3_layer.json new file mode 100644 index 0000000000..a763b1cabd --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_all_3_layer.json @@ -0,0 +1,24 @@ +{ + "parent": "twilightforest:block/util/cube_3_layer", + "textures": { + "particle": "#all", + "down": "#all", + "up": "#all", + "north": "#all", + "east": "#all", + "south": "#all", + "west": "#all", + "down2": "#all2", + "up2": "#all2", + "north2": "#all2", + "east2": "#all2", + "south2": "#all2", + "west2": "#all2", + "down3": "#all3", + "up3": "#all3", + "north3": "#all3", + "east3": "#all3", + "south3": "#all3", + "west3": "#all3" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_bottom_double_top.json b/src/main/resources/assets/twilightforest/models/block/util/cube_bottom_double_top.json new file mode 100644 index 0000000000..034faf0bd1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_bottom_double_top.json @@ -0,0 +1,24 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top" , "cullface": "up" }, + "north": { "texture": "#side" , "cullface": "north" }, + "south": { "texture": "#side" , "cullface": "south" }, + "west": { "texture": "#side" , "cullface": "west" }, + "east": { "texture": "#side" , "cullface": "east" } + } + }, { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "up": { "texture": "#glow", "cullface": "up" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_bottom_top_3_layer.json b/src/main/resources/assets/twilightforest/models/block/util/cube_bottom_top_3_layer.json new file mode 100644 index 0000000000..e5b87d711d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_bottom_top_3_layer.json @@ -0,0 +1,44 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#bottom" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down" }, + "up": { "texture": "#top", "cullface": "up" }, + "north": { "texture": "#side", "cullface": "north" }, + "south": { "texture": "#side", "cullface": "south" }, + "west": { "texture": "#side", "cullface": "west" }, + "east": { "texture": "#side", "cullface": "east" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "up": { "texture": "#top2", "cullface": "up" }, + "north": { "texture": "#side2", "cullface": "north" }, + "south": { "texture": "#side2", "cullface": "south" }, + "west": { "texture": "#side2", "cullface": "west" }, + "east": { "texture": "#side2", "cullface": "east" } + } + }, + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "shade": false, + "faces": { + "up": { "texture": "#top3", "cullface": "up" }, + "north": { "texture": "#side3", "cullface": "north" }, + "south": { "texture": "#side3", "cullface": "south" }, + "west": { "texture": "#side3", "cullface": "west" }, + "east": { "texture": "#side3", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_column_reverse.json b/src/main/resources/assets/twilightforest/models/block/util/cube_column_reverse.json new file mode 100644 index 0000000000..042c413ff0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_column_reverse.json @@ -0,0 +1,17 @@ +{ + "parent": "minecraft:block/cube_column", + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#down", "cullface": "down" }, + "up": { "texture": "#up", "cullface": "up" }, + "north": { "texture": "#north", "cullface": "north", "uv": [ 16, 0, 0, 16 ] }, + "south": { "texture": "#south", "cullface": "south", "uv": [ 16, 0, 0, 16 ] }, + "west": { "texture": "#west", "cullface": "west", "uv": [ 16, 0, 0, 16 ] }, + "east": { "texture": "#east", "cullface": "east", "uv": [ 16, 0, 0, 16 ] } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_column_rotationally_correct_x.json b/src/main/resources/assets/twilightforest/models/block/util/cube_column_rotationally_correct_x.json new file mode 100755 index 0000000000..b7f2e88da9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_column_rotationally_correct_x.json @@ -0,0 +1,20 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [0, 0, 16, 16], "texture": "#end" , "cullface": "down" }, + "up": { "uv": [16, 16, 0, 0], "texture": "#end" , "cullface": "up" }, + "north": { "uv": [0, 16, 16, 0], "texture": "#side", "cullface": "north" }, + "south": { "uv": [0, 16, 16, 0], "texture": "#side", "cullface": "south" }, + "west": { "uv": [16, 0, 0, 16], "texture": "#side", "cullface": "west" }, + "east": { "uv": [0, 16, 16, 0], "texture": "#side", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_column_rotationally_correct_z.json b/src/main/resources/assets/twilightforest/models/block/util/cube_column_rotationally_correct_z.json new file mode 100755 index 0000000000..d6d5a7916c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_column_rotationally_correct_z.json @@ -0,0 +1,20 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [0, 0, 16, 16], "texture": "#end" , "cullface": "down" }, + "up": { "uv": [16, 16, 0, 0], "texture": "#end" , "cullface": "up" }, + "north": { "uv": [16, 16, 0, 0], "texture": "#side", "cullface": "north" }, + "south": { "uv": [0, 0, 16, 16], "texture": "#side", "cullface": "south" }, + "west": { "uv": [16, 0, 0, 16], "texture": "#side", "cullface": "west" }, + "east": { "uv": [0, 16, 16, 0], "texture": "#side", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/cube_mirrored_all.json b/src/main/resources/assets/twilightforest/models/block/util/cube_mirrored_all.json new file mode 100644 index 0000000000..621efbc9ef --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/cube_mirrored_all.json @@ -0,0 +1,18 @@ +{ + "parent": "minecraft:block/block", + "textures": { "particle": "#all" }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [16, 0, 0, 16], "texture": "#all", "cullface": "down" }, + "up": { "uv": [16, 0, 0, 16], "texture": "#all", "cullface": "up" }, + "north": { "uv": [16, 0, 0, 16], "texture": "#all", "cullface": "north" }, + "south": { "uv": [16, 0, 0, 16], "texture": "#all", "cullface": "south" }, + "west": { "uv": [16, 0, 0, 16], "texture": "#all", "cullface": "west" }, + "east": { "uv": [16, 0, 0, 16], "texture": "#all", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/dummy.json b/src/main/resources/assets/twilightforest/models/block/util/dummy.json new file mode 100644 index 0000000000..7296ef08e4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/dummy.json @@ -0,0 +1,12 @@ +{ + "__comment": "Dummy for TESRS that still want to set their block break particle without using code. Taken from Botania.", + "elements": [ + { + "from": [0, 0, 0], + "to": [0, 0, 0], + "faces": { + "up": { "uv": [ 0, 0, 0, 0 ], "texture": "#edge" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/util/fence_all.json b/src/main/resources/assets/twilightforest/models/block/util/fence_all.json new file mode 100644 index 0000000000..24c2eb5e15 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/fence_all.json @@ -0,0 +1,95 @@ +{ + "textures": { "particle": "#texture" }, + "elements": [{ + "from": [ 6, 0, 6 ], + "to" : [ 10, 16, 10 ], + "faces": { + "down": { "texture": "#texture", "cullface": "down" }, + "up": { "texture": "#texture", "cullface": "up" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west": { "texture": "#texture" }, + "east": { "texture": "#texture" } + } + }, { + "from": [ 7, 12, 0 ], + "to" : [ 9, 15, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 0 ], + "to" : [ 9, 9, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 0, 12, 7 ], + "to" : [ 6, 15, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west" : { "texture": "#texture", "cullface": "west" } + } + }, { + "from": [ 0, 6, 7 ], + "to" : [ 6, 9, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west" : { "texture": "#texture", "cullface": "west" } + } + }, { + "from": [ 7, 12, 10 ], + "to" : [ 9, 15, 16 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "south": { "texture": "#texture", "cullface": "south" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 10 ], + "to" : [ 9, 9, 16 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "south": { "texture": "#texture", "cullface": "south" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 10, 12, 7 ], + "to" : [ 16, 15, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "east" : { "texture": "#texture", "cullface": "east" } + } + }, { + "from": [ 10, 6, 7 ], + "to" : [ 16, 9, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "east" : { "texture": "#texture", "cullface": "east" } + } + }] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/fence_elbow.json b/src/main/resources/assets/twilightforest/models/block/util/fence_elbow.json new file mode 100644 index 0000000000..7f8f59b81e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/fence_elbow.json @@ -0,0 +1,55 @@ +{ + "textures": { "particle": "#texture" }, + "elements": [{ + "from": [ 6, 0, 6 ], + "to" : [ 10, 16, 10 ], + "faces": { + "down": { "texture": "#texture", "cullface": "down" }, + "up": { "texture": "#texture", "cullface": "up" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west": { "texture": "#texture" }, + "east": { "texture": "#texture" } + } + }, { + "from": [ 7, 12, 0 ], + "to" : [ 9, 15, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 0 ], + "to" : [ 9, 9, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 0, 12, 7 ], + "to" : [ 6, 15, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west" : { "texture": "#texture", "cullface": "west" } + } + }, { + "from": [ 0, 6, 7 ], + "to" : [ 6, 9, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west" : { "texture": "#texture", "cullface": "west" } + } + }] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/fence_single.json b/src/main/resources/assets/twilightforest/models/block/util/fence_single.json new file mode 100644 index 0000000000..c91c0a6c7a --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/fence_single.json @@ -0,0 +1,35 @@ +{ + "textures": { "particle": "#texture" }, + "elements": [{ + "from": [ 6, 0, 6 ], + "to" : [ 10, 16, 10 ], + "faces": { + "down": { "texture": "#texture", "cullface": "down" }, + "up": { "texture": "#texture", "cullface": "up" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west": { "texture": "#texture" }, + "east": { "texture": "#texture" } + } + }, { + "from": [ 7, 12, 0 ], + "to" : [ 9, 15, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 0 ], + "to" : [ 9, 9, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/fence_straight.json b/src/main/resources/assets/twilightforest/models/block/util/fence_straight.json new file mode 100644 index 0000000000..a5067b749d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/fence_straight.json @@ -0,0 +1,55 @@ +{ + "textures": { "particle": "#texture" }, + "elements": [{ + "from": [ 6, 0, 6 ], + "to" : [ 10, 16, 10 ], + "faces": { + "down": { "texture": "#texture", "cullface": "down" }, + "up": { "texture": "#texture", "cullface": "up" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west": { "texture": "#texture" }, + "east": { "texture": "#texture" } + } + }, { + "from": [ 7, 12, 0 ], + "to" : [ 9, 15, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 0 ], + "to" : [ 9, 9, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 12, 10 ], + "to" : [ 9, 15, 16 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "south": { "texture": "#texture", "cullface": "south" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 10 ], + "to" : [ 9, 9, 16 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "south": { "texture": "#texture", "cullface": "south" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/fence_t.json b/src/main/resources/assets/twilightforest/models/block/util/fence_t.json new file mode 100644 index 0000000000..6e743fbbef --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/fence_t.json @@ -0,0 +1,75 @@ +{ + "textures": { "particle": "#texture" }, + "elements": [{ + "from": [ 6, 0, 6 ], + "to" : [ 10, 16, 10 ], + "faces": { + "down": { "texture": "#texture", "cullface": "down" }, + "up": { "texture": "#texture", "cullface": "up" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west": { "texture": "#texture" }, + "east": { "texture": "#texture" } + } + }, { + "from": [ 7, 12, 0 ], + "to" : [ 9, 15, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 0 ], + "to" : [ 9, 9, 6 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture", "cullface": "north" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 0, 12, 7 ], + "to" : [ 6, 15, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west" : { "texture": "#texture", "cullface": "west" } + } + }, { + "from": [ 0, 6, 7 ], + "to" : [ 6, 9, 9 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "north": { "texture": "#texture" }, + "south": { "texture": "#texture" }, + "west" : { "texture": "#texture", "cullface": "west" } + } + }, { + "from": [ 7, 12, 10 ], + "to" : [ 9, 15, 16 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "south": { "texture": "#texture", "cullface": "south" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }, { + "from": [ 7, 6, 10 ], + "to" : [ 9, 9, 16 ], + "faces": { + "down" : { "texture": "#texture" }, + "up" : { "texture": "#texture" }, + "south": { "texture": "#texture", "cullface": "south" }, + "west" : { "texture": "#texture" }, + "east" : { "texture": "#texture" } + } + }] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/flat.json b/src/main/resources/assets/twilightforest/models/block/util/flat.json new file mode 100644 index 0000000000..d5678b4400 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/flat.json @@ -0,0 +1,15 @@ +{ + "ambientocclusion": false, + "textures": { + "particle": "#texture" + }, + "elements": [ + { "from": [ 0, 0.25, 0 ], + "to": [ 16, 0.25, 16 ], + "faces": { + "down": { "uv": [ 16, 16, 0, 0 ], "texture": "#texture" }, + "up": { "uv": [ 16, 0, 0, 16 ], "texture": "#texture" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/flat_tex.json b/src/main/resources/assets/twilightforest/models/block/util/flat_tex.json new file mode 100644 index 0000000000..8eb98336cf --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/flat_tex.json @@ -0,0 +1,1286 @@ +{"elements":[ + {"from":[0,0,0],"to":[16,0,16],"faces":{ + "up":{"texture":"#texture","tintindex":0} + }},{"from":[0,1,0],"to":[16,1,16],"faces":{ + "up":{"texture":"#texture","tintindex":0} + }},{"from":[0,0,0],"to":[1,1,1],"faces":{ + "north":{"uv":[0,0,1,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,0,1,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,0,1,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,0,1,1],"texture":"#texture","tintindex":4} + }},{"from":[0,0,1],"to":[1,1,2],"faces":{ + "north":{"uv":[0,1,1,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,1,1,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,1,1,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,1,1,2],"texture":"#texture","tintindex":4} + }},{"from":[0,0,2],"to":[1,1,3],"faces":{ + "north":{"uv":[0,2,1,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,2,1,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,2,1,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,2,1,3],"texture":"#texture","tintindex":4} + }},{"from":[0,0,3],"to":[1,1,4],"faces":{ + "north":{"uv":[0,3,1,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,3,1,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,3,1,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,3,1,4],"texture":"#texture","tintindex":4} + }},{"from":[0,0,4],"to":[1,1,5],"faces":{ + "north":{"uv":[0,4,1,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,4,1,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,4,1,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,4,1,5],"texture":"#texture","tintindex":4} + }},{"from":[0,0,5],"to":[1,1,6],"faces":{ + "north":{"uv":[0,5,1,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,5,1,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,5,1,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,5,1,6],"texture":"#texture","tintindex":4} + }},{"from":[0,0,6],"to":[1,1,7],"faces":{ + "north":{"uv":[0,6,1,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,6,1,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,6,1,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,6,1,7],"texture":"#texture","tintindex":4} + }},{"from":[0,0,7],"to":[1,1,8],"faces":{ + "north":{"uv":[0,7,1,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,7,1,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,7,1,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,7,1,8],"texture":"#texture","tintindex":4} + }},{"from":[0,0,8],"to":[1,1,9],"faces":{ + "north":{"uv":[0,8,1,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,8,1,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,8,1,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,8,1,9],"texture":"#texture","tintindex":4} + }},{"from":[0,0,9],"to":[1,1,10],"faces":{ + "north":{"uv":[0,9,1,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,9,1,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,9,1,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,9,1,10],"texture":"#texture","tintindex":4} + }},{"from":[0,0,10],"to":[1,1,11],"faces":{ + "north":{"uv":[0,10,1,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,10,1,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,10,1,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,10,1,11],"texture":"#texture","tintindex":4} + }},{"from":[0,0,11],"to":[1,1,12],"faces":{ + "north":{"uv":[0,11,1,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,11,1,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,11,1,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,11,1,12],"texture":"#texture","tintindex":4} + }},{"from":[0,0,12],"to":[1,1,13],"faces":{ + "north":{"uv":[0,12,1,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,12,1,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,12,1,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,12,1,13],"texture":"#texture","tintindex":4} + }},{"from":[0,0,13],"to":[1,1,14],"faces":{ + "north":{"uv":[0,13,1,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,13,1,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,13,1,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,13,1,14],"texture":"#texture","tintindex":4} + }},{"from":[0,0,14],"to":[1,1,15],"faces":{ + "north":{"uv":[0,14,1,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,14,1,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,14,1,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,14,1,15],"texture":"#texture","tintindex":4} + }},{"from":[0,0,15],"to":[1,1,16],"faces":{ + "north":{"uv":[0,15,1,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[0,15,1,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[0,15,1,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[0,15,1,16],"texture":"#texture","tintindex":4} + }},{"from":[1,0,0],"to":[2,1,1],"faces":{ + "north":{"uv":[1,0,2,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,0,2,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,0,2,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,0,2,1],"texture":"#texture","tintindex":4} + }},{"from":[1,0,1],"to":[2,1,2],"faces":{ + "north":{"uv":[1,1,2,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,1,2,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,1,2,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,1,2,2],"texture":"#texture","tintindex":4} + }},{"from":[1,0,2],"to":[2,1,3],"faces":{ + "north":{"uv":[1,2,2,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,2,2,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,2,2,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,2,2,3],"texture":"#texture","tintindex":4} + }},{"from":[1,0,3],"to":[2,1,4],"faces":{ + "north":{"uv":[1,3,2,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,3,2,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,3,2,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,3,2,4],"texture":"#texture","tintindex":4} + }},{"from":[1,0,4],"to":[2,1,5],"faces":{ + "north":{"uv":[1,4,2,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,4,2,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,4,2,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,4,2,5],"texture":"#texture","tintindex":4} + }},{"from":[1,0,5],"to":[2,1,6],"faces":{ + "north":{"uv":[1,5,2,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,5,2,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,5,2,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,5,2,6],"texture":"#texture","tintindex":4} + }},{"from":[1,0,6],"to":[2,1,7],"faces":{ + "north":{"uv":[1,6,2,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,6,2,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,6,2,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,6,2,7],"texture":"#texture","tintindex":4} + }},{"from":[1,0,7],"to":[2,1,8],"faces":{ + "north":{"uv":[1,7,2,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,7,2,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,7,2,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,7,2,8],"texture":"#texture","tintindex":4} + }},{"from":[1,0,8],"to":[2,1,9],"faces":{ + "north":{"uv":[1,8,2,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,8,2,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,8,2,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,8,2,9],"texture":"#texture","tintindex":4} + }},{"from":[1,0,9],"to":[2,1,10],"faces":{ + "north":{"uv":[1,9,2,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,9,2,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,9,2,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,9,2,10],"texture":"#texture","tintindex":4} + }},{"from":[1,0,10],"to":[2,1,11],"faces":{ + "north":{"uv":[1,10,2,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,10,2,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,10,2,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,10,2,11],"texture":"#texture","tintindex":4} + }},{"from":[1,0,11],"to":[2,1,12],"faces":{ + "north":{"uv":[1,11,2,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,11,2,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,11,2,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,11,2,12],"texture":"#texture","tintindex":4} + }},{"from":[1,0,12],"to":[2,1,13],"faces":{ + "north":{"uv":[1,12,2,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,12,2,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,12,2,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,12,2,13],"texture":"#texture","tintindex":4} + }},{"from":[1,0,13],"to":[2,1,14],"faces":{ + "north":{"uv":[1,13,2,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,13,2,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,13,2,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,13,2,14],"texture":"#texture","tintindex":4} + }},{"from":[1,0,14],"to":[2,1,15],"faces":{ + "north":{"uv":[1,14,2,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,14,2,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,14,2,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,14,2,15],"texture":"#texture","tintindex":4} + }},{"from":[1,0,15],"to":[2,1,16],"faces":{ + "north":{"uv":[1,15,2,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[1,15,2,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[1,15,2,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[1,15,2,16],"texture":"#texture","tintindex":4} + }},{"from":[2,0,0],"to":[3,1,1],"faces":{ + "north":{"uv":[2,0,3,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,0,3,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,0,3,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,0,3,1],"texture":"#texture","tintindex":4} + }},{"from":[2,0,1],"to":[3,1,2],"faces":{ + "north":{"uv":[2,1,3,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,1,3,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,1,3,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,1,3,2],"texture":"#texture","tintindex":4} + }},{"from":[2,0,2],"to":[3,1,3],"faces":{ + "north":{"uv":[2,2,3,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,2,3,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,2,3,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,2,3,3],"texture":"#texture","tintindex":4} + }},{"from":[2,0,3],"to":[3,1,4],"faces":{ + "north":{"uv":[2,3,3,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,3,3,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,3,3,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,3,3,4],"texture":"#texture","tintindex":4} + }},{"from":[2,0,4],"to":[3,1,5],"faces":{ + "north":{"uv":[2,4,3,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,4,3,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,4,3,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,4,3,5],"texture":"#texture","tintindex":4} + }},{"from":[2,0,5],"to":[3,1,6],"faces":{ + "north":{"uv":[2,5,3,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,5,3,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,5,3,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,5,3,6],"texture":"#texture","tintindex":4} + }},{"from":[2,0,6],"to":[3,1,7],"faces":{ + "north":{"uv":[2,6,3,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,6,3,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,6,3,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,6,3,7],"texture":"#texture","tintindex":4} + }},{"from":[2,0,7],"to":[3,1,8],"faces":{ + "north":{"uv":[2,7,3,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,7,3,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,7,3,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,7,3,8],"texture":"#texture","tintindex":4} + }},{"from":[2,0,8],"to":[3,1,9],"faces":{ + "north":{"uv":[2,8,3,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,8,3,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,8,3,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,8,3,9],"texture":"#texture","tintindex":4} + }},{"from":[2,0,9],"to":[3,1,10],"faces":{ + "north":{"uv":[2,9,3,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,9,3,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,9,3,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,9,3,10],"texture":"#texture","tintindex":4} + }},{"from":[2,0,10],"to":[3,1,11],"faces":{ + "north":{"uv":[2,10,3,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,10,3,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,10,3,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,10,3,11],"texture":"#texture","tintindex":4} + }},{"from":[2,0,11],"to":[3,1,12],"faces":{ + "north":{"uv":[2,11,3,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,11,3,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,11,3,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,11,3,12],"texture":"#texture","tintindex":4} + }},{"from":[2,0,12],"to":[3,1,13],"faces":{ + "north":{"uv":[2,12,3,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,12,3,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,12,3,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,12,3,13],"texture":"#texture","tintindex":4} + }},{"from":[2,0,13],"to":[3,1,14],"faces":{ + "north":{"uv":[2,13,3,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,13,3,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,13,3,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,13,3,14],"texture":"#texture","tintindex":4} + }},{"from":[2,0,14],"to":[3,1,15],"faces":{ + "north":{"uv":[2,14,3,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,14,3,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,14,3,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,14,3,15],"texture":"#texture","tintindex":4} + }},{"from":[2,0,15],"to":[3,1,16],"faces":{ + "north":{"uv":[2,15,3,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[2,15,3,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[2,15,3,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[2,15,3,16],"texture":"#texture","tintindex":4} + }},{"from":[3,0,0],"to":[4,1,1],"faces":{ + "north":{"uv":[3,0,4,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,0,4,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,0,4,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,0,4,1],"texture":"#texture","tintindex":4} + }},{"from":[3,0,1],"to":[4,1,2],"faces":{ + "north":{"uv":[3,1,4,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,1,4,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,1,4,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,1,4,2],"texture":"#texture","tintindex":4} + }},{"from":[3,0,2],"to":[4,1,3],"faces":{ + "north":{"uv":[3,2,4,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,2,4,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,2,4,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,2,4,3],"texture":"#texture","tintindex":4} + }},{"from":[3,0,3],"to":[4,1,4],"faces":{ + "north":{"uv":[3,3,4,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,3,4,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,3,4,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,3,4,4],"texture":"#texture","tintindex":4} + }},{"from":[3,0,4],"to":[4,1,5],"faces":{ + "north":{"uv":[3,4,4,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,4,4,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,4,4,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,4,4,5],"texture":"#texture","tintindex":4} + }},{"from":[3,0,5],"to":[4,1,6],"faces":{ + "north":{"uv":[3,5,4,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,5,4,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,5,4,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,5,4,6],"texture":"#texture","tintindex":4} + }},{"from":[3,0,6],"to":[4,1,7],"faces":{ + "north":{"uv":[3,6,4,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,6,4,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,6,4,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,6,4,7],"texture":"#texture","tintindex":4} + }},{"from":[3,0,7],"to":[4,1,8],"faces":{ + "north":{"uv":[3,7,4,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,7,4,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,7,4,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,7,4,8],"texture":"#texture","tintindex":4} + }},{"from":[3,0,8],"to":[4,1,9],"faces":{ + "north":{"uv":[3,8,4,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,8,4,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,8,4,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,8,4,9],"texture":"#texture","tintindex":4} + }},{"from":[3,0,9],"to":[4,1,10],"faces":{ + "north":{"uv":[3,9,4,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,9,4,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,9,4,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,9,4,10],"texture":"#texture","tintindex":4} + }},{"from":[3,0,10],"to":[4,1,11],"faces":{ + "north":{"uv":[3,10,4,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,10,4,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,10,4,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,10,4,11],"texture":"#texture","tintindex":4} + }},{"from":[3,0,11],"to":[4,1,12],"faces":{ + "north":{"uv":[3,11,4,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,11,4,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,11,4,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,11,4,12],"texture":"#texture","tintindex":4} + }},{"from":[3,0,12],"to":[4,1,13],"faces":{ + "north":{"uv":[3,12,4,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,12,4,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,12,4,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,12,4,13],"texture":"#texture","tintindex":4} + }},{"from":[3,0,13],"to":[4,1,14],"faces":{ + "north":{"uv":[3,13,4,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,13,4,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,13,4,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,13,4,14],"texture":"#texture","tintindex":4} + }},{"from":[3,0,14],"to":[4,1,15],"faces":{ + "north":{"uv":[3,14,4,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,14,4,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,14,4,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,14,4,15],"texture":"#texture","tintindex":4} + }},{"from":[3,0,15],"to":[4,1,16],"faces":{ + "north":{"uv":[3,15,4,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[3,15,4,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[3,15,4,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[3,15,4,16],"texture":"#texture","tintindex":4} + }},{"from":[4,0,0],"to":[5,1,1],"faces":{ + "north":{"uv":[4,0,5,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,0,5,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,0,5,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,0,5,1],"texture":"#texture","tintindex":4} + }},{"from":[4,0,1],"to":[5,1,2],"faces":{ + "north":{"uv":[4,1,5,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,1,5,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,1,5,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,1,5,2],"texture":"#texture","tintindex":4} + }},{"from":[4,0,2],"to":[5,1,3],"faces":{ + "north":{"uv":[4,2,5,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,2,5,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,2,5,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,2,5,3],"texture":"#texture","tintindex":4} + }},{"from":[4,0,3],"to":[5,1,4],"faces":{ + "north":{"uv":[4,3,5,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,3,5,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,3,5,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,3,5,4],"texture":"#texture","tintindex":4} + }},{"from":[4,0,4],"to":[5,1,5],"faces":{ + "north":{"uv":[4,4,5,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,4,5,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,4,5,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,4,5,5],"texture":"#texture","tintindex":4} + }},{"from":[4,0,5],"to":[5,1,6],"faces":{ + "north":{"uv":[4,5,5,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,5,5,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,5,5,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,5,5,6],"texture":"#texture","tintindex":4} + }},{"from":[4,0,6],"to":[5,1,7],"faces":{ + "north":{"uv":[4,6,5,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,6,5,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,6,5,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,6,5,7],"texture":"#texture","tintindex":4} + }},{"from":[4,0,7],"to":[5,1,8],"faces":{ + "north":{"uv":[4,7,5,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,7,5,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,7,5,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,7,5,8],"texture":"#texture","tintindex":4} + }},{"from":[4,0,8],"to":[5,1,9],"faces":{ + "north":{"uv":[4,8,5,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,8,5,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,8,5,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,8,5,9],"texture":"#texture","tintindex":4} + }},{"from":[4,0,9],"to":[5,1,10],"faces":{ + "north":{"uv":[4,9,5,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,9,5,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,9,5,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,9,5,10],"texture":"#texture","tintindex":4} + }},{"from":[4,0,10],"to":[5,1,11],"faces":{ + "north":{"uv":[4,10,5,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,10,5,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,10,5,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,10,5,11],"texture":"#texture","tintindex":4} + }},{"from":[4,0,11],"to":[5,1,12],"faces":{ + "north":{"uv":[4,11,5,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,11,5,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,11,5,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,11,5,12],"texture":"#texture","tintindex":4} + }},{"from":[4,0,12],"to":[5,1,13],"faces":{ + "north":{"uv":[4,12,5,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,12,5,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,12,5,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,12,5,13],"texture":"#texture","tintindex":4} + }},{"from":[4,0,13],"to":[5,1,14],"faces":{ + "north":{"uv":[4,13,5,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,13,5,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,13,5,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,13,5,14],"texture":"#texture","tintindex":4} + }},{"from":[4,0,14],"to":[5,1,15],"faces":{ + "north":{"uv":[4,14,5,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,14,5,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,14,5,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,14,5,15],"texture":"#texture","tintindex":4} + }},{"from":[4,0,15],"to":[5,1,16],"faces":{ + "north":{"uv":[4,15,5,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[4,15,5,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[4,15,5,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[4,15,5,16],"texture":"#texture","tintindex":4} + }},{"from":[5,0,0],"to":[6,1,1],"faces":{ + "north":{"uv":[5,0,6,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,0,6,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,0,6,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,0,6,1],"texture":"#texture","tintindex":4} + }},{"from":[5,0,1],"to":[6,1,2],"faces":{ + "north":{"uv":[5,1,6,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,1,6,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,1,6,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,1,6,2],"texture":"#texture","tintindex":4} + }},{"from":[5,0,2],"to":[6,1,3],"faces":{ + "north":{"uv":[5,2,6,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,2,6,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,2,6,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,2,6,3],"texture":"#texture","tintindex":4} + }},{"from":[5,0,3],"to":[6,1,4],"faces":{ + "north":{"uv":[5,3,6,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,3,6,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,3,6,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,3,6,4],"texture":"#texture","tintindex":4} + }},{"from":[5,0,4],"to":[6,1,5],"faces":{ + "north":{"uv":[5,4,6,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,4,6,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,4,6,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,4,6,5],"texture":"#texture","tintindex":4} + }},{"from":[5,0,5],"to":[6,1,6],"faces":{ + "north":{"uv":[5,5,6,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,5,6,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,5,6,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,5,6,6],"texture":"#texture","tintindex":4} + }},{"from":[5,0,6],"to":[6,1,7],"faces":{ + "north":{"uv":[5,6,6,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,6,6,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,6,6,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,6,6,7],"texture":"#texture","tintindex":4} + }},{"from":[5,0,7],"to":[6,1,8],"faces":{ + "north":{"uv":[5,7,6,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,7,6,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,7,6,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,7,6,8],"texture":"#texture","tintindex":4} + }},{"from":[5,0,8],"to":[6,1,9],"faces":{ + "north":{"uv":[5,8,6,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,8,6,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,8,6,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,8,6,9],"texture":"#texture","tintindex":4} + }},{"from":[5,0,9],"to":[6,1,10],"faces":{ + "north":{"uv":[5,9,6,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,9,6,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,9,6,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,9,6,10],"texture":"#texture","tintindex":4} + }},{"from":[5,0,10],"to":[6,1,11],"faces":{ + "north":{"uv":[5,10,6,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,10,6,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,10,6,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,10,6,11],"texture":"#texture","tintindex":4} + }},{"from":[5,0,11],"to":[6,1,12],"faces":{ + "north":{"uv":[5,11,6,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,11,6,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,11,6,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,11,6,12],"texture":"#texture","tintindex":4} + }},{"from":[5,0,12],"to":[6,1,13],"faces":{ + "north":{"uv":[5,12,6,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,12,6,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,12,6,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,12,6,13],"texture":"#texture","tintindex":4} + }},{"from":[5,0,13],"to":[6,1,14],"faces":{ + "north":{"uv":[5,13,6,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,13,6,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,13,6,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,13,6,14],"texture":"#texture","tintindex":4} + }},{"from":[5,0,14],"to":[6,1,15],"faces":{ + "north":{"uv":[5,14,6,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,14,6,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,14,6,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,14,6,15],"texture":"#texture","tintindex":4} + }},{"from":[5,0,15],"to":[6,1,16],"faces":{ + "north":{"uv":[5,15,6,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[5,15,6,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[5,15,6,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[5,15,6,16],"texture":"#texture","tintindex":4} + }},{"from":[6,0,0],"to":[7,1,1],"faces":{ + "north":{"uv":[6,0,7,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,0,7,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,0,7,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,0,7,1],"texture":"#texture","tintindex":4} + }},{"from":[6,0,1],"to":[7,1,2],"faces":{ + "north":{"uv":[6,1,7,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,1,7,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,1,7,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,1,7,2],"texture":"#texture","tintindex":4} + }},{"from":[6,0,2],"to":[7,1,3],"faces":{ + "north":{"uv":[6,2,7,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,2,7,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,2,7,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,2,7,3],"texture":"#texture","tintindex":4} + }},{"from":[6,0,3],"to":[7,1,4],"faces":{ + "north":{"uv":[6,3,7,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,3,7,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,3,7,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,3,7,4],"texture":"#texture","tintindex":4} + }},{"from":[6,0,4],"to":[7,1,5],"faces":{ + "north":{"uv":[6,4,7,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,4,7,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,4,7,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,4,7,5],"texture":"#texture","tintindex":4} + }},{"from":[6,0,5],"to":[7,1,6],"faces":{ + "north":{"uv":[6,5,7,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,5,7,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,5,7,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,5,7,6],"texture":"#texture","tintindex":4} + }},{"from":[6,0,6],"to":[7,1,7],"faces":{ + "north":{"uv":[6,6,7,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,6,7,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,6,7,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,6,7,7],"texture":"#texture","tintindex":4} + }},{"from":[6,0,7],"to":[7,1,8],"faces":{ + "north":{"uv":[6,7,7,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,7,7,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,7,7,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,7,7,8],"texture":"#texture","tintindex":4} + }},{"from":[6,0,8],"to":[7,1,9],"faces":{ + "north":{"uv":[6,8,7,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,8,7,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,8,7,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,8,7,9],"texture":"#texture","tintindex":4} + }},{"from":[6,0,9],"to":[7,1,10],"faces":{ + "north":{"uv":[6,9,7,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,9,7,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,9,7,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,9,7,10],"texture":"#texture","tintindex":4} + }},{"from":[6,0,10],"to":[7,1,11],"faces":{ + "north":{"uv":[6,10,7,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,10,7,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,10,7,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,10,7,11],"texture":"#texture","tintindex":4} + }},{"from":[6,0,11],"to":[7,1,12],"faces":{ + "north":{"uv":[6,11,7,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,11,7,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,11,7,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,11,7,12],"texture":"#texture","tintindex":4} + }},{"from":[6,0,12],"to":[7,1,13],"faces":{ + "north":{"uv":[6,12,7,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,12,7,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,12,7,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,12,7,13],"texture":"#texture","tintindex":4} + }},{"from":[6,0,13],"to":[7,1,14],"faces":{ + "north":{"uv":[6,13,7,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,13,7,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,13,7,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,13,7,14],"texture":"#texture","tintindex":4} + }},{"from":[6,0,14],"to":[7,1,15],"faces":{ + "north":{"uv":[6,14,7,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,14,7,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,14,7,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,14,7,15],"texture":"#texture","tintindex":4} + }},{"from":[6,0,15],"to":[7,1,16],"faces":{ + "north":{"uv":[6,15,7,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[6,15,7,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[6,15,7,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[6,15,7,16],"texture":"#texture","tintindex":4} + }},{"from":[7,0,0],"to":[8,1,1],"faces":{ + "north":{"uv":[7,0,8,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,0,8,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,0,8,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,0,8,1],"texture":"#texture","tintindex":4} + }},{"from":[7,0,1],"to":[8,1,2],"faces":{ + "north":{"uv":[7,1,8,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,1,8,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,1,8,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,1,8,2],"texture":"#texture","tintindex":4} + }},{"from":[7,0,2],"to":[8,1,3],"faces":{ + "north":{"uv":[7,2,8,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,2,8,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,2,8,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,2,8,3],"texture":"#texture","tintindex":4} + }},{"from":[7,0,3],"to":[8,1,4],"faces":{ + "north":{"uv":[7,3,8,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,3,8,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,3,8,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,3,8,4],"texture":"#texture","tintindex":4} + }},{"from":[7,0,4],"to":[8,1,5],"faces":{ + "north":{"uv":[7,4,8,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,4,8,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,4,8,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,4,8,5],"texture":"#texture","tintindex":4} + }},{"from":[7,0,5],"to":[8,1,6],"faces":{ + "north":{"uv":[7,5,8,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,5,8,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,5,8,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,5,8,6],"texture":"#texture","tintindex":4} + }},{"from":[7,0,6],"to":[8,1,7],"faces":{ + "north":{"uv":[7,6,8,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,6,8,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,6,8,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,6,8,7],"texture":"#texture","tintindex":4} + }},{"from":[7,0,7],"to":[8,1,8],"faces":{ + "north":{"uv":[7,7,8,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,7,8,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,7,8,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,7,8,8],"texture":"#texture","tintindex":4} + }},{"from":[7,0,8],"to":[8,1,9],"faces":{ + "north":{"uv":[7,8,8,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,8,8,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,8,8,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,8,8,9],"texture":"#texture","tintindex":4} + }},{"from":[7,0,9],"to":[8,1,10],"faces":{ + "north":{"uv":[7,9,8,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,9,8,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,9,8,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,9,8,10],"texture":"#texture","tintindex":4} + }},{"from":[7,0,10],"to":[8,1,11],"faces":{ + "north":{"uv":[7,10,8,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,10,8,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,10,8,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,10,8,11],"texture":"#texture","tintindex":4} + }},{"from":[7,0,11],"to":[8,1,12],"faces":{ + "north":{"uv":[7,11,8,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,11,8,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,11,8,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,11,8,12],"texture":"#texture","tintindex":4} + }},{"from":[7,0,12],"to":[8,1,13],"faces":{ + "north":{"uv":[7,12,8,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,12,8,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,12,8,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,12,8,13],"texture":"#texture","tintindex":4} + }},{"from":[7,0,13],"to":[8,1,14],"faces":{ + "north":{"uv":[7,13,8,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,13,8,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,13,8,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,13,8,14],"texture":"#texture","tintindex":4} + }},{"from":[7,0,14],"to":[8,1,15],"faces":{ + "north":{"uv":[7,14,8,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,14,8,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,14,8,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,14,8,15],"texture":"#texture","tintindex":4} + }},{"from":[7,0,15],"to":[8,1,16],"faces":{ + "north":{"uv":[7,15,8,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[7,15,8,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[7,15,8,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[7,15,8,16],"texture":"#texture","tintindex":4} + }},{"from":[8,0,0],"to":[9,1,1],"faces":{ + "north":{"uv":[8,0,9,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,0,9,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,0,9,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,0,9,1],"texture":"#texture","tintindex":4} + }},{"from":[8,0,1],"to":[9,1,2],"faces":{ + "north":{"uv":[8,1,9,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,1,9,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,1,9,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,1,9,2],"texture":"#texture","tintindex":4} + }},{"from":[8,0,2],"to":[9,1,3],"faces":{ + "north":{"uv":[8,2,9,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,2,9,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,2,9,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,2,9,3],"texture":"#texture","tintindex":4} + }},{"from":[8,0,3],"to":[9,1,4],"faces":{ + "north":{"uv":[8,3,9,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,3,9,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,3,9,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,3,9,4],"texture":"#texture","tintindex":4} + }},{"from":[8,0,4],"to":[9,1,5],"faces":{ + "north":{"uv":[8,4,9,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,4,9,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,4,9,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,4,9,5],"texture":"#texture","tintindex":4} + }},{"from":[8,0,5],"to":[9,1,6],"faces":{ + "north":{"uv":[8,5,9,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,5,9,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,5,9,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,5,9,6],"texture":"#texture","tintindex":4} + }},{"from":[8,0,6],"to":[9,1,7],"faces":{ + "north":{"uv":[8,6,9,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,6,9,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,6,9,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,6,9,7],"texture":"#texture","tintindex":4} + }},{"from":[8,0,7],"to":[9,1,8],"faces":{ + "north":{"uv":[8,7,9,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,7,9,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,7,9,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,7,9,8],"texture":"#texture","tintindex":4} + }},{"from":[8,0,8],"to":[9,1,9],"faces":{ + "north":{"uv":[8,8,9,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,8,9,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,8,9,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,8,9,9],"texture":"#texture","tintindex":4} + }},{"from":[8,0,9],"to":[9,1,10],"faces":{ + "north":{"uv":[8,9,9,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,9,9,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,9,9,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,9,9,10],"texture":"#texture","tintindex":4} + }},{"from":[8,0,10],"to":[9,1,11],"faces":{ + "north":{"uv":[8,10,9,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,10,9,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,10,9,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,10,9,11],"texture":"#texture","tintindex":4} + }},{"from":[8,0,11],"to":[9,1,12],"faces":{ + "north":{"uv":[8,11,9,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,11,9,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,11,9,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,11,9,12],"texture":"#texture","tintindex":4} + }},{"from":[8,0,12],"to":[9,1,13],"faces":{ + "north":{"uv":[8,12,9,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,12,9,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,12,9,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,12,9,13],"texture":"#texture","tintindex":4} + }},{"from":[8,0,13],"to":[9,1,14],"faces":{ + "north":{"uv":[8,13,9,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,13,9,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,13,9,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,13,9,14],"texture":"#texture","tintindex":4} + }},{"from":[8,0,14],"to":[9,1,15],"faces":{ + "north":{"uv":[8,14,9,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,14,9,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,14,9,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,14,9,15],"texture":"#texture","tintindex":4} + }},{"from":[8,0,15],"to":[9,1,16],"faces":{ + "north":{"uv":[8,15,9,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[8,15,9,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[8,15,9,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[8,15,9,16],"texture":"#texture","tintindex":4} + }},{"from":[9,0,0],"to":[10,1,1],"faces":{ + "north":{"uv":[9,0,10,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,0,10,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,0,10,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,0,10,1],"texture":"#texture","tintindex":4} + }},{"from":[9,0,1],"to":[10,1,2],"faces":{ + "north":{"uv":[9,1,10,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,1,10,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,1,10,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,1,10,2],"texture":"#texture","tintindex":4} + }},{"from":[9,0,2],"to":[10,1,3],"faces":{ + "north":{"uv":[9,2,10,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,2,10,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,2,10,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,2,10,3],"texture":"#texture","tintindex":4} + }},{"from":[9,0,3],"to":[10,1,4],"faces":{ + "north":{"uv":[9,3,10,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,3,10,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,3,10,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,3,10,4],"texture":"#texture","tintindex":4} + }},{"from":[9,0,4],"to":[10,1,5],"faces":{ + "north":{"uv":[9,4,10,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,4,10,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,4,10,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,4,10,5],"texture":"#texture","tintindex":4} + }},{"from":[9,0,5],"to":[10,1,6],"faces":{ + "north":{"uv":[9,5,10,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,5,10,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,5,10,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,5,10,6],"texture":"#texture","tintindex":4} + }},{"from":[9,0,6],"to":[10,1,7],"faces":{ + "north":{"uv":[9,6,10,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,6,10,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,6,10,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,6,10,7],"texture":"#texture","tintindex":4} + }},{"from":[9,0,7],"to":[10,1,8],"faces":{ + "north":{"uv":[9,7,10,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,7,10,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,7,10,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,7,10,8],"texture":"#texture","tintindex":4} + }},{"from":[9,0,8],"to":[10,1,9],"faces":{ + "north":{"uv":[9,8,10,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,8,10,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,8,10,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,8,10,9],"texture":"#texture","tintindex":4} + }},{"from":[9,0,9],"to":[10,1,10],"faces":{ + "north":{"uv":[9,9,10,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,9,10,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,9,10,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,9,10,10],"texture":"#texture","tintindex":4} + }},{"from":[9,0,10],"to":[10,1,11],"faces":{ + "north":{"uv":[9,10,10,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,10,10,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,10,10,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,10,10,11],"texture":"#texture","tintindex":4} + }},{"from":[9,0,11],"to":[10,1,12],"faces":{ + "north":{"uv":[9,11,10,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,11,10,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,11,10,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,11,10,12],"texture":"#texture","tintindex":4} + }},{"from":[9,0,12],"to":[10,1,13],"faces":{ + "north":{"uv":[9,12,10,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,12,10,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,12,10,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,12,10,13],"texture":"#texture","tintindex":4} + }},{"from":[9,0,13],"to":[10,1,14],"faces":{ + "north":{"uv":[9,13,10,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,13,10,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,13,10,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,13,10,14],"texture":"#texture","tintindex":4} + }},{"from":[9,0,14],"to":[10,1,15],"faces":{ + "north":{"uv":[9,14,10,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,14,10,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,14,10,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,14,10,15],"texture":"#texture","tintindex":4} + }},{"from":[9,0,15],"to":[10,1,16],"faces":{ + "north":{"uv":[9,15,10,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[9,15,10,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[9,15,10,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[9,15,10,16],"texture":"#texture","tintindex":4} + }},{"from":[10,0,0],"to":[11,1,1],"faces":{ + "north":{"uv":[10,0,11,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,0,11,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,0,11,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,0,11,1],"texture":"#texture","tintindex":4} + }},{"from":[10,0,1],"to":[11,1,2],"faces":{ + "north":{"uv":[10,1,11,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,1,11,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,1,11,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,1,11,2],"texture":"#texture","tintindex":4} + }},{"from":[10,0,2],"to":[11,1,3],"faces":{ + "north":{"uv":[10,2,11,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,2,11,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,2,11,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,2,11,3],"texture":"#texture","tintindex":4} + }},{"from":[10,0,3],"to":[11,1,4],"faces":{ + "north":{"uv":[10,3,11,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,3,11,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,3,11,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,3,11,4],"texture":"#texture","tintindex":4} + }},{"from":[10,0,4],"to":[11,1,5],"faces":{ + "north":{"uv":[10,4,11,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,4,11,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,4,11,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,4,11,5],"texture":"#texture","tintindex":4} + }},{"from":[10,0,5],"to":[11,1,6],"faces":{ + "north":{"uv":[10,5,11,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,5,11,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,5,11,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,5,11,6],"texture":"#texture","tintindex":4} + }},{"from":[10,0,6],"to":[11,1,7],"faces":{ + "north":{"uv":[10,6,11,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,6,11,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,6,11,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,6,11,7],"texture":"#texture","tintindex":4} + }},{"from":[10,0,7],"to":[11,1,8],"faces":{ + "north":{"uv":[10,7,11,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,7,11,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,7,11,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,7,11,8],"texture":"#texture","tintindex":4} + }},{"from":[10,0,8],"to":[11,1,9],"faces":{ + "north":{"uv":[10,8,11,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,8,11,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,8,11,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,8,11,9],"texture":"#texture","tintindex":4} + }},{"from":[10,0,9],"to":[11,1,10],"faces":{ + "north":{"uv":[10,9,11,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,9,11,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,9,11,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,9,11,10],"texture":"#texture","tintindex":4} + }},{"from":[10,0,10],"to":[11,1,11],"faces":{ + "north":{"uv":[10,10,11,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,10,11,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,10,11,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,10,11,11],"texture":"#texture","tintindex":4} + }},{"from":[10,0,11],"to":[11,1,12],"faces":{ + "north":{"uv":[10,11,11,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,11,11,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,11,11,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,11,11,12],"texture":"#texture","tintindex":4} + }},{"from":[10,0,12],"to":[11,1,13],"faces":{ + "north":{"uv":[10,12,11,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,12,11,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,12,11,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,12,11,13],"texture":"#texture","tintindex":4} + }},{"from":[10,0,13],"to":[11,1,14],"faces":{ + "north":{"uv":[10,13,11,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,13,11,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,13,11,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,13,11,14],"texture":"#texture","tintindex":4} + }},{"from":[10,0,14],"to":[11,1,15],"faces":{ + "north":{"uv":[10,14,11,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,14,11,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,14,11,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,14,11,15],"texture":"#texture","tintindex":4} + }},{"from":[10,0,15],"to":[11,1,16],"faces":{ + "north":{"uv":[10,15,11,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[10,15,11,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[10,15,11,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[10,15,11,16],"texture":"#texture","tintindex":4} + }},{"from":[11,0,0],"to":[12,1,1],"faces":{ + "north":{"uv":[11,0,12,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,0,12,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,0,12,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,0,12,1],"texture":"#texture","tintindex":4} + }},{"from":[11,0,1],"to":[12,1,2],"faces":{ + "north":{"uv":[11,1,12,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,1,12,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,1,12,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,1,12,2],"texture":"#texture","tintindex":4} + }},{"from":[11,0,2],"to":[12,1,3],"faces":{ + "north":{"uv":[11,2,12,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,2,12,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,2,12,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,2,12,3],"texture":"#texture","tintindex":4} + }},{"from":[11,0,3],"to":[12,1,4],"faces":{ + "north":{"uv":[11,3,12,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,3,12,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,3,12,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,3,12,4],"texture":"#texture","tintindex":4} + }},{"from":[11,0,4],"to":[12,1,5],"faces":{ + "north":{"uv":[11,4,12,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,4,12,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,4,12,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,4,12,5],"texture":"#texture","tintindex":4} + }},{"from":[11,0,5],"to":[12,1,6],"faces":{ + "north":{"uv":[11,5,12,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,5,12,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,5,12,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,5,12,6],"texture":"#texture","tintindex":4} + }},{"from":[11,0,6],"to":[12,1,7],"faces":{ + "north":{"uv":[11,6,12,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,6,12,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,6,12,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,6,12,7],"texture":"#texture","tintindex":4} + }},{"from":[11,0,7],"to":[12,1,8],"faces":{ + "north":{"uv":[11,7,12,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,7,12,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,7,12,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,7,12,8],"texture":"#texture","tintindex":4} + }},{"from":[11,0,8],"to":[12,1,9],"faces":{ + "north":{"uv":[11,8,12,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,8,12,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,8,12,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,8,12,9],"texture":"#texture","tintindex":4} + }},{"from":[11,0,9],"to":[12,1,10],"faces":{ + "north":{"uv":[11,9,12,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,9,12,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,9,12,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,9,12,10],"texture":"#texture","tintindex":4} + }},{"from":[11,0,10],"to":[12,1,11],"faces":{ + "north":{"uv":[11,10,12,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,10,12,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,10,12,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,10,12,11],"texture":"#texture","tintindex":4} + }},{"from":[11,0,11],"to":[12,1,12],"faces":{ + "north":{"uv":[11,11,12,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,11,12,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,11,12,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,11,12,12],"texture":"#texture","tintindex":4} + }},{"from":[11,0,12],"to":[12,1,13],"faces":{ + "north":{"uv":[11,12,12,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,12,12,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,12,12,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,12,12,13],"texture":"#texture","tintindex":4} + }},{"from":[11,0,13],"to":[12,1,14],"faces":{ + "north":{"uv":[11,13,12,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,13,12,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,13,12,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,13,12,14],"texture":"#texture","tintindex":4} + }},{"from":[11,0,14],"to":[12,1,15],"faces":{ + "north":{"uv":[11,14,12,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,14,12,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,14,12,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,14,12,15],"texture":"#texture","tintindex":4} + }},{"from":[11,0,15],"to":[12,1,16],"faces":{ + "north":{"uv":[11,15,12,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[11,15,12,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[11,15,12,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[11,15,12,16],"texture":"#texture","tintindex":4} + }},{"from":[12,0,0],"to":[13,1,1],"faces":{ + "north":{"uv":[12,0,13,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,0,13,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,0,13,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,0,13,1],"texture":"#texture","tintindex":4} + }},{"from":[12,0,1],"to":[13,1,2],"faces":{ + "north":{"uv":[12,1,13,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,1,13,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,1,13,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,1,13,2],"texture":"#texture","tintindex":4} + }},{"from":[12,0,2],"to":[13,1,3],"faces":{ + "north":{"uv":[12,2,13,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,2,13,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,2,13,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,2,13,3],"texture":"#texture","tintindex":4} + }},{"from":[12,0,3],"to":[13,1,4],"faces":{ + "north":{"uv":[12,3,13,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,3,13,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,3,13,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,3,13,4],"texture":"#texture","tintindex":4} + }},{"from":[12,0,4],"to":[13,1,5],"faces":{ + "north":{"uv":[12,4,13,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,4,13,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,4,13,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,4,13,5],"texture":"#texture","tintindex":4} + }},{"from":[12,0,5],"to":[13,1,6],"faces":{ + "north":{"uv":[12,5,13,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,5,13,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,5,13,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,5,13,6],"texture":"#texture","tintindex":4} + }},{"from":[12,0,6],"to":[13,1,7],"faces":{ + "north":{"uv":[12,6,13,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,6,13,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,6,13,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,6,13,7],"texture":"#texture","tintindex":4} + }},{"from":[12,0,7],"to":[13,1,8],"faces":{ + "north":{"uv":[12,7,13,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,7,13,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,7,13,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,7,13,8],"texture":"#texture","tintindex":4} + }},{"from":[12,0,8],"to":[13,1,9],"faces":{ + "north":{"uv":[12,8,13,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,8,13,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,8,13,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,8,13,9],"texture":"#texture","tintindex":4} + }},{"from":[12,0,9],"to":[13,1,10],"faces":{ + "north":{"uv":[12,9,13,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,9,13,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,9,13,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,9,13,10],"texture":"#texture","tintindex":4} + }},{"from":[12,0,10],"to":[13,1,11],"faces":{ + "north":{"uv":[12,10,13,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,10,13,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,10,13,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,10,13,11],"texture":"#texture","tintindex":4} + }},{"from":[12,0,11],"to":[13,1,12],"faces":{ + "north":{"uv":[12,11,13,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,11,13,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,11,13,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,11,13,12],"texture":"#texture","tintindex":4} + }},{"from":[12,0,12],"to":[13,1,13],"faces":{ + "north":{"uv":[12,12,13,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,12,13,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,12,13,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,12,13,13],"texture":"#texture","tintindex":4} + }},{"from":[12,0,13],"to":[13,1,14],"faces":{ + "north":{"uv":[12,13,13,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,13,13,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,13,13,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,13,13,14],"texture":"#texture","tintindex":4} + }},{"from":[12,0,14],"to":[13,1,15],"faces":{ + "north":{"uv":[12,14,13,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,14,13,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,14,13,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,14,13,15],"texture":"#texture","tintindex":4} + }},{"from":[12,0,15],"to":[13,1,16],"faces":{ + "north":{"uv":[12,15,13,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[12,15,13,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[12,15,13,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[12,15,13,16],"texture":"#texture","tintindex":4} + }},{"from":[13,0,0],"to":[14,1,1],"faces":{ + "north":{"uv":[13,0,14,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,0,14,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,0,14,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,0,14,1],"texture":"#texture","tintindex":4} + }},{"from":[13,0,1],"to":[14,1,2],"faces":{ + "north":{"uv":[13,1,14,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,1,14,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,1,14,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,1,14,2],"texture":"#texture","tintindex":4} + }},{"from":[13,0,2],"to":[14,1,3],"faces":{ + "north":{"uv":[13,2,14,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,2,14,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,2,14,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,2,14,3],"texture":"#texture","tintindex":4} + }},{"from":[13,0,3],"to":[14,1,4],"faces":{ + "north":{"uv":[13,3,14,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,3,14,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,3,14,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,3,14,4],"texture":"#texture","tintindex":4} + }},{"from":[13,0,4],"to":[14,1,5],"faces":{ + "north":{"uv":[13,4,14,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,4,14,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,4,14,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,4,14,5],"texture":"#texture","tintindex":4} + }},{"from":[13,0,5],"to":[14,1,6],"faces":{ + "north":{"uv":[13,5,14,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,5,14,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,5,14,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,5,14,6],"texture":"#texture","tintindex":4} + }},{"from":[13,0,6],"to":[14,1,7],"faces":{ + "north":{"uv":[13,6,14,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,6,14,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,6,14,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,6,14,7],"texture":"#texture","tintindex":4} + }},{"from":[13,0,7],"to":[14,1,8],"faces":{ + "north":{"uv":[13,7,14,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,7,14,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,7,14,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,7,14,8],"texture":"#texture","tintindex":4} + }},{"from":[13,0,8],"to":[14,1,9],"faces":{ + "north":{"uv":[13,8,14,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,8,14,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,8,14,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,8,14,9],"texture":"#texture","tintindex":4} + }},{"from":[13,0,9],"to":[14,1,10],"faces":{ + "north":{"uv":[13,9,14,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,9,14,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,9,14,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,9,14,10],"texture":"#texture","tintindex":4} + }},{"from":[13,0,10],"to":[14,1,11],"faces":{ + "north":{"uv":[13,10,14,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,10,14,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,10,14,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,10,14,11],"texture":"#texture","tintindex":4} + }},{"from":[13,0,11],"to":[14,1,12],"faces":{ + "north":{"uv":[13,11,14,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,11,14,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,11,14,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,11,14,12],"texture":"#texture","tintindex":4} + }},{"from":[13,0,12],"to":[14,1,13],"faces":{ + "north":{"uv":[13,12,14,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,12,14,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,12,14,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,12,14,13],"texture":"#texture","tintindex":4} + }},{"from":[13,0,13],"to":[14,1,14],"faces":{ + "north":{"uv":[13,13,14,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,13,14,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,13,14,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,13,14,14],"texture":"#texture","tintindex":4} + }},{"from":[13,0,14],"to":[14,1,15],"faces":{ + "north":{"uv":[13,14,14,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,14,14,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,14,14,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,14,14,15],"texture":"#texture","tintindex":4} + }},{"from":[13,0,15],"to":[14,1,16],"faces":{ + "north":{"uv":[13,15,14,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[13,15,14,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[13,15,14,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[13,15,14,16],"texture":"#texture","tintindex":4} + }},{"from":[14,0,0],"to":[15,1,1],"faces":{ + "north":{"uv":[14,0,15,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,0,15,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,0,15,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,0,15,1],"texture":"#texture","tintindex":4} + }},{"from":[14,0,1],"to":[15,1,2],"faces":{ + "north":{"uv":[14,1,15,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,1,15,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,1,15,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,1,15,2],"texture":"#texture","tintindex":4} + }},{"from":[14,0,2],"to":[15,1,3],"faces":{ + "north":{"uv":[14,2,15,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,2,15,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,2,15,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,2,15,3],"texture":"#texture","tintindex":4} + }},{"from":[14,0,3],"to":[15,1,4],"faces":{ + "north":{"uv":[14,3,15,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,3,15,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,3,15,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,3,15,4],"texture":"#texture","tintindex":4} + }},{"from":[14,0,4],"to":[15,1,5],"faces":{ + "north":{"uv":[14,4,15,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,4,15,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,4,15,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,4,15,5],"texture":"#texture","tintindex":4} + }},{"from":[14,0,5],"to":[15,1,6],"faces":{ + "north":{"uv":[14,5,15,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,5,15,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,5,15,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,5,15,6],"texture":"#texture","tintindex":4} + }},{"from":[14,0,6],"to":[15,1,7],"faces":{ + "north":{"uv":[14,6,15,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,6,15,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,6,15,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,6,15,7],"texture":"#texture","tintindex":4} + }},{"from":[14,0,7],"to":[15,1,8],"faces":{ + "north":{"uv":[14,7,15,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,7,15,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,7,15,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,7,15,8],"texture":"#texture","tintindex":4} + }},{"from":[14,0,8],"to":[15,1,9],"faces":{ + "north":{"uv":[14,8,15,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,8,15,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,8,15,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,8,15,9],"texture":"#texture","tintindex":4} + }},{"from":[14,0,9],"to":[15,1,10],"faces":{ + "north":{"uv":[14,9,15,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,9,15,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,9,15,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,9,15,10],"texture":"#texture","tintindex":4} + }},{"from":[14,0,10],"to":[15,1,11],"faces":{ + "north":{"uv":[14,10,15,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,10,15,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,10,15,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,10,15,11],"texture":"#texture","tintindex":4} + }},{"from":[14,0,11],"to":[15,1,12],"faces":{ + "north":{"uv":[14,11,15,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,11,15,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,11,15,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,11,15,12],"texture":"#texture","tintindex":4} + }},{"from":[14,0,12],"to":[15,1,13],"faces":{ + "north":{"uv":[14,12,15,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,12,15,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,12,15,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,12,15,13],"texture":"#texture","tintindex":4} + }},{"from":[14,0,13],"to":[15,1,14],"faces":{ + "north":{"uv":[14,13,15,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,13,15,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,13,15,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,13,15,14],"texture":"#texture","tintindex":4} + }},{"from":[14,0,14],"to":[15,1,15],"faces":{ + "north":{"uv":[14,14,15,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,14,15,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,14,15,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,14,15,15],"texture":"#texture","tintindex":4} + }},{"from":[14,0,15],"to":[15,1,16],"faces":{ + "north":{"uv":[14,15,15,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[14,15,15,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[14,15,15,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[14,15,15,16],"texture":"#texture","tintindex":4} + }},{"from":[15,0,0],"to":[16,1,1],"faces":{ + "north":{"uv":[15,0,16,1],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,0,16,1],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,0,16,1],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,0,16,1],"texture":"#texture","tintindex":4} + }},{"from":[15,0,1],"to":[16,1,2],"faces":{ + "north":{"uv":[15,1,16,2],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,1,16,2],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,1,16,2],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,1,16,2],"texture":"#texture","tintindex":4} + }},{"from":[15,0,2],"to":[16,1,3],"faces":{ + "north":{"uv":[15,2,16,3],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,2,16,3],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,2,16,3],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,2,16,3],"texture":"#texture","tintindex":4} + }},{"from":[15,0,3],"to":[16,1,4],"faces":{ + "north":{"uv":[15,3,16,4],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,3,16,4],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,3,16,4],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,3,16,4],"texture":"#texture","tintindex":4} + }},{"from":[15,0,4],"to":[16,1,5],"faces":{ + "north":{"uv":[15,4,16,5],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,4,16,5],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,4,16,5],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,4,16,5],"texture":"#texture","tintindex":4} + }},{"from":[15,0,5],"to":[16,1,6],"faces":{ + "north":{"uv":[15,5,16,6],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,5,16,6],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,5,16,6],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,5,16,6],"texture":"#texture","tintindex":4} + }},{"from":[15,0,6],"to":[16,1,7],"faces":{ + "north":{"uv":[15,6,16,7],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,6,16,7],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,6,16,7],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,6,16,7],"texture":"#texture","tintindex":4} + }},{"from":[15,0,7],"to":[16,1,8],"faces":{ + "north":{"uv":[15,7,16,8],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,7,16,8],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,7,16,8],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,7,16,8],"texture":"#texture","tintindex":4} + }},{"from":[15,0,8],"to":[16,1,9],"faces":{ + "north":{"uv":[15,8,16,9],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,8,16,9],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,8,16,9],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,8,16,9],"texture":"#texture","tintindex":4} + }},{"from":[15,0,9],"to":[16,1,10],"faces":{ + "north":{"uv":[15,9,16,10],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,9,16,10],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,9,16,10],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,9,16,10],"texture":"#texture","tintindex":4} + }},{"from":[15,0,10],"to":[16,1,11],"faces":{ + "north":{"uv":[15,10,16,11],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,10,16,11],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,10,16,11],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,10,16,11],"texture":"#texture","tintindex":4} + }},{"from":[15,0,11],"to":[16,1,12],"faces":{ + "north":{"uv":[15,11,16,12],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,11,16,12],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,11,16,12],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,11,16,12],"texture":"#texture","tintindex":4} + }},{"from":[15,0,12],"to":[16,1,13],"faces":{ + "north":{"uv":[15,12,16,13],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,12,16,13],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,12,16,13],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,12,16,13],"texture":"#texture","tintindex":4} + }},{"from":[15,0,13],"to":[16,1,14],"faces":{ + "north":{"uv":[15,13,16,14],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,13,16,14],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,13,16,14],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,13,16,14],"texture":"#texture","tintindex":4} + }},{"from":[15,0,14],"to":[16,1,15],"faces":{ + "north":{"uv":[15,14,16,15],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,14,16,15],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,14,16,15],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,14,16,15],"texture":"#texture","tintindex":4} + }},{"from":[15,0,15],"to":[16,1,16],"faces":{ + "north":{"uv":[15,15,16,16],"texture":"#texture","tintindex":1}, + "south":{"uv":[15,15,16,16],"texture":"#texture","tintindex":2}, + "west":{"uv":[15,15,16,16],"texture":"#texture","tintindex":3}, + "east":{"uv":[15,15,16,16],"texture":"#texture","tintindex":4} + }}]} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/util/giant.json b/src/main/resources/assets/twilightforest/models/block/util/giant.json new file mode 100755 index 0000000000..34fca05c9d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/giant.json @@ -0,0 +1,24 @@ +{ + "parent": "block/block", + "elements": [{ + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down" : { "texture": "#all", "tintindex": 0, "cullface": "down" }, + "up" : { "texture": "#all", "tintindex": 1, "cullface": "up" }, + "north": { "texture": "#all", "tintindex": 2, "cullface": "north" }, + "south": { "texture": "#all", "tintindex": 3, "cullface": "south" }, + "west" : { "texture": "#all", "tintindex": 4, "cullface": "west" }, + "east" : { "texture": "#all", "tintindex": 5, "cullface": "east" } + } + }], + "ctm_version": 1, + "ctm_overrides": { + 0: { "type": "V", "extras": { "size": 4, "x_offset": 0, "y_offset": 0 }}, + 1: { "type": "V", "extras": { "size": 4, "x_offset": 0, "y_offset": 0 }}, + 2: { "type": "V", "extras": { "size": 4, "x_offset": 0, "y_offset": 2 }}, + 3: { "type": "V", "extras": { "size": 4, "x_offset": 0, "y_offset": 2 }}, + 4: { "type": "V", "extras": { "size": 4, "x_offset": 0, "y_offset": 2 }}, + 5: { "type": "V", "extras": { "size": 4, "x_offset": 0, "y_offset": 2 }} + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/giant_block.json b/src/main/resources/assets/twilightforest/models/block/util/giant_block.json new file mode 100755 index 0000000000..8671d2a0e7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/giant_block.json @@ -0,0 +1,27 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#all" + }, + "elements": [{ + "from": [ 0, 0, 0 ], + "to" : [ 16, 16, 16 ], + "faces": { + "down" : { "texture": "#all", "tintindex": 0, "cullface": "down" }, + "up" : { "texture": "#all", "tintindex": 1, "cullface": "up" }, + "north": { "texture": "#all", "tintindex": 2, "cullface": "north" }, + "south": { "texture": "#all", "tintindex": 3, "cullface": "south" }, + "west" : { "texture": "#all", "tintindex": 4, "cullface": "west" }, + "east" : { "texture": "#all", "tintindex": 5, "cullface": "east" } + } + }], + "ctm_version": 1, + "ctm_overrides": { + "0": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 2 }}, + "1": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 1 }}, + "2": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 1 }}, + "3": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 1 }}, + "4": { "type": "V", "extra": { "size": 4, "x_offset": -1, "y_offset": 1 }}, + "5": { "type": "V", "extra": { "size": 4, "x_offset": 1, "y_offset": 1 }} + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/giant_column.json b/src/main/resources/assets/twilightforest/models/block/util/giant_column.json new file mode 100755 index 0000000000..17bcfa9da0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/giant_column.json @@ -0,0 +1,27 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [{ + "from": [ 0, 0, 0 ], + "to" : [ 16, 16, 16 ], + "faces": { + "down" : { "texture": "#end" , "tintindex": 0, "cullface": "down" }, + "up" : { "texture": "#end" , "tintindex": 1, "cullface": "up" }, + "north": { "texture": "#side", "tintindex": 2, "cullface": "north" }, + "south": { "texture": "#side", "tintindex": 3, "cullface": "south" }, + "west" : { "texture": "#side", "tintindex": 4, "cullface": "west" }, + "east" : { "texture": "#side", "tintindex": 5, "cullface": "east" } + } + }], + "ctm_version": 1, + "ctm_overrides": { + "0": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 2 }}, + "1": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 1 }}, + "2": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 1 }}, + "3": { "type": "V", "extra": { "size": 4, "x_offset": 0, "y_offset": 1 }}, + "4": { "type": "V", "extra": { "size": 4, "x_offset": -1, "y_offset": 1 }}, + "5": { "type": "V", "extra": { "size": 4, "x_offset": 1, "y_offset": 1 }} + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/inner_stairs.json b/src/main/resources/assets/twilightforest/models/block/util/inner_stairs.json new file mode 100644 index 0000000000..2acd2060d5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/inner_stairs.json @@ -0,0 +1,7 @@ +{ + "parent": "block/inner_stairs", + "textures": { + "bottom": "#end", + "top": "#half" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/item.json b/src/main/resources/assets/twilightforest/models/block/util/item.json new file mode 100644 index 0000000000..a5461048f8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/item.json @@ -0,0 +1,3 @@ +{ + "parent":"item/generated" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/util/leaves_flipped_v.json b/src/main/resources/assets/twilightforest/models/block/util/leaves_flipped_v.json new file mode 100644 index 0000000000..c45814c406 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/leaves_flipped_v.json @@ -0,0 +1,20 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#all" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down" : { "uv": [ 0, 16, 16, 0 ], "texture": "#all", "tintindex": 0, "cullface": "down" }, + "up" : { "uv": [ 0, 16, 16, 0 ], "texture": "#all", "tintindex": 0, "cullface": "up" }, + "north": { "uv": [ 0, 16, 16, 0 ], "texture": "#all", "tintindex": 0, "cullface": "north" }, + "south": { "uv": [ 0, 16, 16, 0 ], "texture": "#all", "tintindex": 0, "cullface": "south" }, + "west" : { "uv": [ 0, 16, 16, 0 ], "texture": "#all", "tintindex": 0, "cullface": "west" }, + "east" : { "uv": [ 0, 16, 16, 0 ], "texture": "#all", "tintindex": 0, "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/mushgloom/block_n.json b/src/main/resources/assets/twilightforest/models/block/util/mushgloom/block_n.json new file mode 100755 index 0000000000..222bc0b900 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/mushgloom/block_n.json @@ -0,0 +1,12 @@ +{ + "parent": "block/cube", + "textures": { + "particle": "#inside", + "down": "#inside", + "up": "#outside", + "north": "#outside", + "east": "#inside", + "south": "#inside", + "west": "#inside" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/mushgloom/block_nw.json b/src/main/resources/assets/twilightforest/models/block/util/mushgloom/block_nw.json new file mode 100755 index 0000000000..a975ffa17c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/mushgloom/block_nw.json @@ -0,0 +1,12 @@ +{ + "parent": "block/cube", + "textures": { + "particle": "#inside", + "down": "#inside", + "up": "#outside", + "north": "#outside", + "east": "#inside", + "south": "#inside", + "west": "#outside" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/outer_stairs.json b/src/main/resources/assets/twilightforest/models/block/util/outer_stairs.json new file mode 100644 index 0000000000..fcb21c484f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/outer_stairs.json @@ -0,0 +1,7 @@ +{ + "parent": "block/outer_stairs", + "textures": { + "bottom": "#end", + "top": "#half" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/pane/noside.json b/src/main/resources/assets/twilightforest/models/block/util/pane/noside.json new file mode 100755 index 0000000000..9805ce8cb0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/pane/noside.json @@ -0,0 +1,14 @@ +{ + "ambientocclusion": false, + "textures": { "particle": "#pane" }, + "elements": [ + { + "from": [ 7, 0, 7 ], + "to": [ 9, 16, 9 ], + "shade": false, + "faces": { + "north": { "uv": [ 9, 0, 7, 16 ], "texture": "#pane", "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/pane/noside_alt.json b/src/main/resources/assets/twilightforest/models/block/util/pane/noside_alt.json new file mode 100755 index 0000000000..a64771554c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/pane/noside_alt.json @@ -0,0 +1,14 @@ +{ + "ambientocclusion": false, + "textures": { "particle": "#pane" }, + "elements": [ + { + "from": [ 7, 0, 7 ], + "to": [ 9, 16, 9 ], + "shade": false, + "faces": { + "east": { "uv": [ 7, 0, 9, 16 ], "texture": "#pane", "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/pane/post.json b/src/main/resources/assets/twilightforest/models/block/util/pane/post.json new file mode 100755 index 0000000000..d9eaead40a --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/pane/post.json @@ -0,0 +1,15 @@ +{ + "ambientocclusion": false, + "textures": { "particle": "#pane" }, + "elements": [ + { + "from": [ 7, 0, 7 ], + "to": [ 9, 16, 9 ], + "shade": false, + "faces": { + "down": { "uv": [ 7, 7, 9, 9 ], "texture": "#edge", "tintindex": 0, "cullface": "down" }, + "up": { "uv": [ 7, 7, 9, 9 ], "texture": "#edge", "tintindex": 0, "cullface": "up" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/pane/side.json b/src/main/resources/assets/twilightforest/models/block/util/pane/side.json new file mode 100755 index 0000000000..76586782a5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/pane/side.json @@ -0,0 +1,18 @@ +{ + "ambientocclusion": false, + "textures": { "particle": "#pane" }, + "elements": [ + { + "from": [ 7, 0, 0 ], + "to": [ 9, 16, 7 ], + "shade": false, + "faces": { + "down": { "uv": [ 7, 0, 9, 7 ], "texture": "#edge", "tintindex": 0, "cullface": "down" }, + "up": { "uv": [ 7, 0, 9, 7 ], "texture": "#edge", "tintindex": 0, "cullface": "up" }, + "north": { "uv": [ 7, 0, 9, 16 ], "texture": "#edge", "tintindex": 0, "cullface": "north" }, + "west": { "uv": [ 16, 0, 9, 16 ], "texture": "#pane", "tintindex": 0 }, + "east": { "uv": [ 9, 0, 16, 16 ], "texture": "#pane", "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/pane/side_alt.json b/src/main/resources/assets/twilightforest/models/block/util/pane/side_alt.json new file mode 100755 index 0000000000..25df048ce5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/pane/side_alt.json @@ -0,0 +1,18 @@ +{ + "ambientocclusion": false, + "textures": { "particle": "#pane" }, + "elements": [ + { + "from": [ 7, 0, 9 ], + "to": [ 9, 16, 16 ], + "shade": false, + "faces": { + "down": { "uv": [ 7, 0, 9, 7 ], "texture": "#edge", "tintindex": 0, "cullface": "down" }, + "up": { "uv": [ 7, 0, 9, 7 ], "texture": "#edge", "tintindex": 0, "cullface": "up" }, + "south": { "uv": [ 7, 0, 9, 16 ], "texture": "#edge", "tintindex": 0, "cullface": "south" }, + "west": { "uv": [ 7, 0, 0, 16 ], "texture": "#pane", "tintindex": 0 }, + "east": { "uv": [ 0, 0, 7, 16 ], "texture": "#pane", "tintindex": 0 } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/pedestal.json b/src/main/resources/assets/twilightforest/models/block/util/pedestal.json new file mode 100644 index 0000000000..5ebd42b9b4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/pedestal.json @@ -0,0 +1,77 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 2, 3, 2 ], + "to": [ 14, 13, 14 ], + "faces": { + "north": { "uv": [ 2, 3, 14, 13 ], "texture": "#north" }, + "south": { "uv": [ 2, 3, 14, 13 ], "texture": "#south" }, + "west": { "uv": [ 2, 3, 14, 13 ], "texture": "#west" }, + "east": { "uv": [ 2, 3, 14, 13 ], "texture": "#east" } + } + }, { + "from": [ 1, 0, 1 ], + "to": [ 15, 3, 15 ], + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#end", "cullface": "down" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#end" }, + "north": { "uv": [ 1, 13, 15, 16 ], "texture": "#north" }, + "south": { "uv": [ 1, 13, 15, 16 ], "texture": "#south" }, + "west": { "uv": [ 1, 13, 15, 16 ], "texture": "#west" }, + "east": { "uv": [ 1, 13, 15, 16 ], "texture": "#east" } + } + }, { + "from": [ 1, 13, 1 ], + "to": [ 15, 16, 15 ], + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#end" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#end", "cullface": "up" }, + "north": { "uv": [ 1, 0, 15, 3 ], "texture": "#north" }, + "south": { "uv": [ 1, 0, 15, 3 ], "texture": "#south" }, + "west": { "uv": [ 1, 0, 15, 3 ], "texture": "#west" }, + "east": { "uv": [ 1, 0, 15, 3 ], "texture": "#east" } + } + }, { + "from": [ 1, 12, 1 ], + "to": [ 4, 13, 4 ], + "faces": { + "down": { "uv": [ 1, 12, 4, 15 ], "texture": "#end" }, + "north": { "uv": [ 12, 3, 15, 4 ], "texture": "#north" }, + "south": { "uv": [ 1, 3, 4, 4 ], "texture": "#south" }, + "west": { "uv": [ 1, 3, 4, 4 ], "texture": "#west" }, + "east": { "uv": [ 12, 3, 15, 4 ], "texture": "#east" } + } + }, { + "from": [ 12, 12, 1 ], + "to": [ 15, 13, 4 ], + "faces": { + "down": { "uv": [ 12, 12, 15, 15 ], "texture": "#end" }, + "north": { "uv": [ 1, 3, 4, 4 ], "texture": "#north" }, + "south": { "uv": [ 12, 3, 15, 4 ], "texture": "#south" }, + "west": { "uv": [ 1, 3, 4, 4 ], "texture": "#west" }, + "east": { "uv": [ 12, 3, 15, 4 ], "texture": "#east" } + } + }, { + "from": [ 1, 12, 12 ], + "to": [ 4, 13, 15 ], + "faces": { + "down": { "uv": [ 1, 1, 4, 4 ], "texture": "#end" }, + "north": { "uv": [ 12, 3, 15, 4 ], "texture": "#north" }, + "south": { "uv": [ 1, 3, 4, 4 ], "texture": "#south" }, + "west": { "uv": [ 12, 3, 15, 4 ], "texture": "#west" }, + "east": { "uv": [ 1, 3, 4, 4 ], "texture": "#east" } + } + }, { + "from": [ 12, 12, 12 ], + "to": [ 15, 13, 15 ], + "faces": { + "down": { "uv": [ 12, 1, 15, 4 ], "texture": "#end" }, + "north": { "uv": [ 1, 3, 4, 4 ], "texture": "#north" }, + "south": { "uv": [ 12, 3, 15, 4 ], "texture": "#south" }, + "west": { "uv": [ 12, 3, 15, 4 ], "texture": "#west" }, + "east": { "uv": [ 1, 3, 4, 4 ], "texture": "#east" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/util/pedestal_2_layer.json b/src/main/resources/assets/twilightforest/models/block/util/pedestal_2_layer.json new file mode 100644 index 0000000000..3d852449db --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/pedestal_2_layer.json @@ -0,0 +1,93 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 2, 3, 2 ], + "to": [ 14, 13, 14 ], + "faces": { + "north": { "texture": "#north" }, + "south": { "texture": "#south" }, + "west": { "texture": "#west" }, + "east": { "texture": "#east" } + } + }, { + "from": [ 2, 3, 2 ], + "to": [ 14, 13, 14 ], + "faces": { + "north": { "texture": "#north2" }, + "south": { "texture": "#south2" }, + "west": { "texture": "#west2" }, + "east": { "texture": "#east2" } + } + }, { + "from": [ 1, 0, 1 ], + "to": [ 15, 3, 15 ], + "faces": { + "down": { "texture": "#end", "cullface": "down" }, + "up": { "texture": "#end" }, + "north": { "texture": "#north" }, + "south": { "texture": "#south" }, + "west": { "texture": "#west" }, + "east": { "texture": "#east" } + } + }, { + "from": [ 1, 13, 1 ], + "to": [ 15, 16, 15 ], + "faces": { + "down": { "texture": "#end" }, + "up": { "texture": "#end", "cullface": "up" }, + "north": { "texture": "#north" }, + "south": { "texture": "#south" }, + "west": { "texture": "#west" }, + "east": { "texture": "#east" } + } + }, { + "from": [ 1, 0, 1 ], + "to": [ 15, 16, 15 ], + "faces": { + "down": { "texture": "#end2", "cullface": "down" }, + "up": { "texture": "#end2", "cullface": "up" } + } + }, { + "from": [ 1, 12, 1 ], + "to": [ 4, 13, 4 ], + "faces": { + "down": { "texture": "#end" }, + "north": { "texture": "#north" }, + "south": { "texture": "#south" }, + "west": { "texture": "#west" }, + "east": { "texture": "#east" } + } + }, { + "from": [ 12, 12, 1 ], + "to": [ 15, 13, 4 ], + "faces": { + "down": { "texture": "#end" }, + "north": { "texture": "#north" }, + "south": { "texture": "#south" }, + "west": { "texture": "#west" }, + "east": { "texture": "#east" } + } + }, { + "from": [ 1, 12, 12 ], + "to": [ 4, 13, 15 ], + "faces": { + "down": { "texture": "#end" }, + "north": { "texture": "#north" }, + "south": { "texture": "#south" }, + "west": { "texture": "#west" }, + "east": { "texture": "#east" } + } + }, { + "from": [ 12, 12, 12 ], + "to": [ 15, 13, 15 ], + "faces": { + "down": { "texture": "#end" }, + "north": { "texture": "#north" }, + "south": { "texture": "#south" }, + "west": { "texture": "#west" }, + "east": { "texture": "#east" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/util/stairs.json b/src/main/resources/assets/twilightforest/models/block/util/stairs.json new file mode 100644 index 0000000000..379fd9aef5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/stairs.json @@ -0,0 +1,7 @@ +{ + "parent": "block/stairs", + "textures": { + "bottom": "#end", + "top": "#half" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/terracotta.json b/src/main/resources/assets/twilightforest/models/block/util/terracotta.json new file mode 100644 index 0000000000..e29d7458b2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/terracotta.json @@ -0,0 +1,10 @@ +{ + "parent": "block/cube", + "textures": { + "particle": "#up", + "north": "#top_right", + "east": "#bot_left", + "south": "#bot_right", + "west": "#top_left" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/tinted_cube.json b/src/main/resources/assets/twilightforest/models/block/util/tinted_cube.json new file mode 100644 index 0000000000..38f6509f9a --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/tinted_cube.json @@ -0,0 +1,17 @@ +{ + "parent": "block/block", + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#down", "cullface": "down", "tintindex": 0 }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#up", "cullface": "up", "tintindex": 0 }, + "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#north", "cullface": "north", "tintindex": 0 }, + "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#south", "cullface": "south", "tintindex": 0 }, + "west": { "uv": [ 0, 0, 16, 16 ], "texture": "#west", "cullface": "west", "tintindex": 0 }, + "east": { "uv": [ 0, 0, 16, 16 ], "texture": "#east", "cullface": "east", "tintindex": 0 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/util/tinted_cube_all.json b/src/main/resources/assets/twilightforest/models/block/util/tinted_cube_all.json new file mode 100755 index 0000000000..767ca20a65 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/tinted_cube_all.json @@ -0,0 +1,12 @@ +{ + "parent": "twilightforest:block/util/tinted_cube", + "textures": { + "particle": "#all", + "down": "#all", + "up": "#all", + "north": "#all", + "east": "#all", + "south": "#all", + "west": "#all" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/tinted_cube_column.json b/src/main/resources/assets/twilightforest/models/block/util/tinted_cube_column.json new file mode 100755 index 0000000000..173a0e288d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/tinted_cube_column.json @@ -0,0 +1,12 @@ +{ + "parent": "twilightforest:block/util/tinted_cube", + "textures": { + "particle": "#side", + "down": "#end", + "up": "#end", + "north": "#side", + "east": "#side", + "south": "#side", + "west": "#side" + } +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/tinted_slab.json b/src/main/resources/assets/twilightforest/models/block/util/tinted_slab.json new file mode 100755 index 0000000000..83229b189b --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/tinted_slab.json @@ -0,0 +1,20 @@ +{ + "parent": "block/block", + "textures": { + "particle": "#side" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 8, 16 ], + "faces": { + "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down", "tintindex": 0 }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top", "cullface": "up", "tintindex": 0 }, + "north": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "north", "tintindex": 0 }, + "south": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "south", "tintindex": 0 }, + "west": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "west", "tintindex": 0 }, + "east": { "uv": [ 0, 8, 16, 16 ], "texture": "#side", "cullface": "east", "tintindex": 0 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/block/util/trapdoor_bottom.json b/src/main/resources/assets/twilightforest/models/block/util/trapdoor_bottom.json new file mode 100644 index 0000000000..3f8511433e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/trapdoor_bottom.json @@ -0,0 +1,19 @@ +{ + "parent": "block/thin_block", + "textures": { + "particle": "#texture" + }, + "elements": [ + { "from": [ 0, 0, 0 ], + "to": [ 16, 3, 16 ], + "faces": { + "down": { "uv": [ 0, 16, 16, 0 ], "texture": "#texture", "cullface": "down" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture" }, + "north": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "north" }, + "south": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "south" }, + "west": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/block/util/trapdoor_top.json b/src/main/resources/assets/twilightforest/models/block/util/trapdoor_top.json new file mode 100644 index 0000000000..2849d8e454 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/block/util/trapdoor_top.json @@ -0,0 +1,18 @@ +{ + "textures": { + "particle": "#texture" + }, + "elements": [ + { "from": [ 0, 13, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [ 0, 16, 16, 0 ], "texture": "#texture" }, + "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "cullface": "up" }, + "north": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "north" }, + "south": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "south" }, + "west": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "west" }, + "east": { "uv": [ 0, 16, 16, 13 ], "texture": "#texture", "cullface": "east" } + } + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/item/alpha_fur.json b/src/main/resources/assets/twilightforest/models/item/alpha_fur.json new file mode 100644 index 0000000000..c218a56364 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/alpha_fur.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/alpha_fur" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/arctic_boots.json b/src/main/resources/assets/twilightforest/models/item/arctic_boots.json new file mode 100644 index 0000000000..f3d21cdf0d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/arctic_boots.json @@ -0,0 +1,7 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/arctic_boots", + "layer1": "twilightforest:items/arctic_boots_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/arctic_chestplate.json b/src/main/resources/assets/twilightforest/models/item/arctic_chestplate.json new file mode 100644 index 0000000000..63bdfd1a9e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/arctic_chestplate.json @@ -0,0 +1,7 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/arctic_plate", + "layer1": "twilightforest:items/arctic_plate_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/arctic_fur.json b/src/main/resources/assets/twilightforest/models/item/arctic_fur.json new file mode 100644 index 0000000000..96ab902914 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/arctic_fur.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/arctic_fur" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/arctic_helmet.json b/src/main/resources/assets/twilightforest/models/item/arctic_helmet.json new file mode 100644 index 0000000000..532753e8d7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/arctic_helmet.json @@ -0,0 +1,7 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/arctic_helm", + "layer1": "twilightforest:items/arctic_helm_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/arctic_leggings.json b/src/main/resources/assets/twilightforest/models/item/arctic_leggings.json new file mode 100644 index 0000000000..c81e9a09e4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/arctic_leggings.json @@ -0,0 +1,7 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/arctic_legs", + "layer1": "twilightforest:items/arctic_legs_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/armor_shard.json b/src/main/resources/assets/twilightforest/models/item/armor_shard.json new file mode 100644 index 0000000000..4fbd715d93 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/armor_shard.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/armor_shards" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/armor_shard_cluster.json b/src/main/resources/assets/twilightforest/models/item/armor_shard_cluster.json new file mode 100644 index 0000000000..b7212b6875 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/armor_shard_cluster.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/shard_cluster" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/block_and_chain.json b/src/main/resources/assets/twilightforest/models/item/block_and_chain.json new file mode 100644 index 0000000000..fa7cda2c59 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/block_and_chain.json @@ -0,0 +1,14 @@ +{ + "parent": "twilightforest:item/util/overlap_gui_thick", + "textures": { + "layer0": "twilightforest:items/chain_block" + }, + "overrides": [ + { + "predicate": { + "twilightforest:thrown": 1 + }, + "model": "twilightforest:item/block_and_chain_thrown" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/block_and_chain_thrown.json b/src/main/resources/assets/twilightforest/models/item/block_and_chain_thrown.json new file mode 100644 index 0000000000..a21c9cd194 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/block_and_chain_thrown.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/util/overlap_gui_thick", + "textures": { + "layer0": "twilightforest:items/chain_block_thrown" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/borer_essence.json b/src/main/resources/assets/twilightforest/models/item/borer_essence.json new file mode 100644 index 0000000000..a827ccd365 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/borer_essence.json @@ -0,0 +1,7 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/borer_essence", + "layer1": "twilightforest:items/borer_essence_particles" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/carminite.json b/src/main/resources/assets/twilightforest/models/item/carminite.json new file mode 100644 index 0000000000..1ef67e8ac4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/carminite.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/carminite" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_1.json b/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_1.json new file mode 100644 index 0000000000..6438df16a6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_1.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/charm_of_keeping_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_2.json b/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_2.json new file mode 100644 index 0000000000..556e991d47 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_2.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/charm_of_keeping_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_3.json b/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_3.json new file mode 100644 index 0000000000..a4337c3892 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/charm_of_keeping_3.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/charm_of_keeping_3" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/charm_of_life_1.json b/src/main/resources/assets/twilightforest/models/item/charm_of_life_1.json new file mode 100644 index 0000000000..628e841221 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/charm_of_life_1.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/charm_of_life_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/charm_of_life_2.json b/src/main/resources/assets/twilightforest/models/item/charm_of_life_2.json new file mode 100644 index 0000000000..5af0542407 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/charm_of_life_2.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/charm_of_life_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/cicada.json b/src/main/resources/assets/twilightforest/models/item/cicada.json new file mode 100644 index 0000000000..5982de487f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/cicada.json @@ -0,0 +1,45 @@ +{ + "parent": "builtin/entity", + "display": { + "gui": { + "rotation": [ 210, 135, 0 ], + "translation": [ 1, 4, 0 ], + "scale":[ 1, 1, 1 ] + }, + "ground": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3, 0 ], + "scale":[ 0.75, 0.75, 0.75 ] + }, + "head": { + "rotation": [ 0, 180, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 1, 1, 1] + }, + "fixed": { + "rotation": [ 90, 180, 0 ], + "translation": [ 0, 2, -7.5 ], + "scale":[ 1, 1, 1 ] + }, + "thirdperson_righthand": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3.3, 2], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "thirdperson_lefthand": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3.3, 2], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 225, 0, -15 ], + "translation": [ 2, 4, 0 ], + "scale": [ 0.6, 0.6, 0.6 ] + }, + "firstperson_lefthand": { + "rotation": [ 225, 0, -15 ], + "translation": [ 2, 4, 0 ], + "scale": [ 0.6, 0.6, 0.6 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/cooked_meef.json b/src/main/resources/assets/twilightforest/models/item/cooked_meef.json new file mode 100644 index 0000000000..df934c4c62 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/cooked_meef.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/meef_steak" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/cooked_venison.json b/src/main/resources/assets/twilightforest/models/item/cooked_venison.json new file mode 100644 index 0000000000..1cf4b095a2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/cooked_venison.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/venison_cooked" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/crumble_horn.json b/src/main/resources/assets/twilightforest/models/item/crumble_horn.json new file mode 100644 index 0000000000..a8d6a085c7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/crumble_horn.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/crumble_horn" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/cube_of_annihilation.json b/src/main/resources/assets/twilightforest/models/item/cube_of_annihilation.json new file mode 100644 index 0000000000..19b00f4d92 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/cube_of_annihilation.json @@ -0,0 +1,14 @@ +{ + "parent": "twilightforest:item/util/overlap_gui", + "textures": { + "layer0": "twilightforest:items/cube_of_annihilation" + }, + "overrides": [ + { + "predicate": { + "twilightforest:thrown": 1 + }, + "model": "twilightforest:item/cube_of_annihilation_thrown" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/cube_of_annihilation_thrown.json b/src/main/resources/assets/twilightforest/models/item/cube_of_annihilation_thrown.json new file mode 100644 index 0000000000..e6304ab93d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/cube_of_annihilation_thrown.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/util/overlap_gui", + "textures": { + "layer0": "twilightforest:items/cube_of_annihilation_thrown" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/cube_talisman.json b/src/main/resources/assets/twilightforest/models/item/cube_talisman.json new file mode 100644 index 0000000000..46d7a13df5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/cube_talisman.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/cube_talisman" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ender_bow.json b/src/main/resources/assets/twilightforest/models/item/ender_bow.json new file mode 100644 index 0000000000..65626b7ed0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ender_bow.json @@ -0,0 +1,28 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "twilightforest:items/enderbow_standby" + }, + "overrides": [ + { + "predicate": { + "pulling": 1 + }, + "model": "twilightforest:item/ender_bow_pulling_0" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.65 + }, + "model": "twilightforest:item/ender_bow_pulling_1" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.9 + }, + "model": "twilightforest:item/ender_bow_pulling_2" + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_0.json b/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_0.json new file mode 100644 index 0000000000..06fe05a208 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_0.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/ender_bow", + "textures": { + "layer0": "twilightforest:items/enderbow_pulling_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_1.json b/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_1.json new file mode 100644 index 0000000000..1f4741d3c3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_1.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/ender_bow", + "textures": { + "layer0": "twilightforest:items/enderbow_pulling_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_2.json b/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_2.json new file mode 100644 index 0000000000..00f7a20bd3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ender_bow_pulling_2.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/ender_bow", + "textures": { + "layer0": "twilightforest:items/enderbow_pulling_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_blood.json b/src/main/resources/assets/twilightforest/models/item/fiery_blood.json new file mode 100644 index 0000000000..bf408e3cf3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_blood.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/fiery_blood" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_boots.json b/src/main/resources/assets/twilightforest/models/item/fiery_boots.json new file mode 100644 index 0000000000..cf754f7069 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_boots.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/fiery_boots" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_chestplate.json b/src/main/resources/assets/twilightforest/models/item/fiery_chestplate.json new file mode 100644 index 0000000000..9463209c7e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/fiery_plate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_helmet.json b/src/main/resources/assets/twilightforest/models/item/fiery_helmet.json new file mode 100644 index 0000000000..e37ebc55a9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/fiery_helm" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_ingot.json b/src/main/resources/assets/twilightforest/models/item/fiery_ingot.json new file mode 100644 index 0000000000..307e98b87b --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_ingot.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/fiery_ingot" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_leggings.json b/src/main/resources/assets/twilightforest/models/item/fiery_leggings.json new file mode 100644 index 0000000000..2739146a88 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/fiery_legs" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_pickaxe.json b/src/main/resources/assets/twilightforest/models/item/fiery_pickaxe.json new file mode 100644 index 0000000000..8de2b7a4d9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_pickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/fiery_pick" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_sword.json b/src/main/resources/assets/twilightforest/models/item/fiery_sword.json new file mode 100644 index 0000000000..26df07fc54 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/fiery_sword" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/fiery_tears.json b/src/main/resources/assets/twilightforest/models/item/fiery_tears.json new file mode 100644 index 0000000000..bd79ce59b1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/fiery_tears.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/fiery_tears" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/firefly.json b/src/main/resources/assets/twilightforest/models/item/firefly.json new file mode 100644 index 0000000000..bbad99959e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/firefly.json @@ -0,0 +1,45 @@ +{ + "parent": "builtin/entity", + "display": { + "gui": { + "rotation": [ 210, 135, 0 ], + "translation": [ 0, 7, 0 ], + "scale":[ 1.25, 1.25, 1.25 ] + }, + "ground": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3, 0 ], + "scale":[ 0.75, 0.75, 0.75 ] + }, + "head": { + "rotation": [ 0, 180, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 1, 1, 1] + }, + "fixed": { + "rotation": [ 90, 180, 0 ], + "translation": [ 0, 2, -7.5 ], + "scale":[ 1, 1, 1 ] + }, + "thirdperson_righthand": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3.3, 2], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "thirdperson_lefthand": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3.3, 2], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 225, 0, -15 ], + "translation": [ 2, 4, 0 ], + "scale": [ 0.6, 0.6, 0.6 ] + }, + "firstperson_lefthand": { + "rotation": [ 225, 0, -15 ], + "translation": [ 2, 4, 0 ], + "scale": [ 0.6, 0.6, 0.6 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/glass_sword.json b/src/main/resources/assets/twilightforest/models/item/glass_sword.json new file mode 100644 index 0000000000..dc21bf5066 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/glass_sword.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/glass_sword_solid", + "layer1": "twilightforest:items/glass_sword_clear" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/hydra_chop.json b/src/main/resources/assets/twilightforest/models/item/hydra_chop.json new file mode 100644 index 0000000000..cc8fc7f0f7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/hydra_chop.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/hydra_chop" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ice_bomb.json b/src/main/resources/assets/twilightforest/models/item/ice_bomb.json new file mode 100644 index 0000000000..0e3842a960 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ice_bomb.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ice_bomb" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ice_bow.json b/src/main/resources/assets/twilightforest/models/item/ice_bow.json new file mode 100644 index 0000000000..edbf36e248 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ice_bow.json @@ -0,0 +1,29 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "twilightforest:items/ice_bow_solid_standby", + "layer1": "twilightforest:items/ice_bow_clear_standby" + }, + "overrides": [ + { + "predicate": { + "pulling": 1 + }, + "model": "twilightforest:item/ice_bow_pulling_0" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.65 + }, + "model": "twilightforest:item/ice_bow_pulling_1" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.9 + }, + "model": "twilightforest:item/ice_bow_pulling_2" + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_0.json b/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_0.json new file mode 100644 index 0000000000..d6f054975e --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_0.json @@ -0,0 +1,7 @@ +{ + "parent": "twilightforest:item/ice_bow", + "textures": { + "layer0": "twilightforest:items/ice_bow_solid_pulling_0", + "layer1": "twilightforest:items/ice_bow_clear_pulling_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_1.json b/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_1.json new file mode 100644 index 0000000000..f7eea24003 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_1.json @@ -0,0 +1,7 @@ +{ + "parent": "twilightforest:item/ice_bow", + "textures": { + "layer0": "twilightforest:items/ice_bow_solid_pulling_1", + "layer1": "twilightforest:items/ice_bow_clear_pulling_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_2.json b/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_2.json new file mode 100644 index 0000000000..19e5d7c10f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ice_bow_pulling_2.json @@ -0,0 +1,7 @@ +{ + "parent": "twilightforest:item/ice_bow", + "textures": { + "layer0": "twilightforest:items/ice_bow_solid_pulling_2", + "layer1": "twilightforest:items/ice_bow_clear_pulling_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ice_sword.json b/src/main/resources/assets/twilightforest/models/item/ice_sword.json new file mode 100644 index 0000000000..e19e0d19b1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ice_sword.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/ice_sword_solid", + "layer1": "twilightforest:items/ice_sword_clear" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_axe.json b/src/main/resources/assets/twilightforest/models/item/ironwood_axe.json new file mode 100644 index 0000000000..75bc411f25 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_axe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/ironwood_axe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_boots.json b/src/main/resources/assets/twilightforest/models/item/ironwood_boots.json new file mode 100644 index 0000000000..981e1684dd --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_boots.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ironwood_boots" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_chestplate.json b/src/main/resources/assets/twilightforest/models/item/ironwood_chestplate.json new file mode 100644 index 0000000000..c840247b6c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ironwood_plate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_helmet.json b/src/main/resources/assets/twilightforest/models/item/ironwood_helmet.json new file mode 100644 index 0000000000..4edf809e25 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ironwood_helm" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_hoe.json b/src/main/resources/assets/twilightforest/models/item/ironwood_hoe.json new file mode 100644 index 0000000000..2066bebc9f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_hoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/ironwood_hoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_ingot.json b/src/main/resources/assets/twilightforest/models/item/ironwood_ingot.json new file mode 100644 index 0000000000..fabb05e524 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_ingot.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ironwood_ingot" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_leggings.json b/src/main/resources/assets/twilightforest/models/item/ironwood_leggings.json new file mode 100644 index 0000000000..11870587ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ironwood_legs" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_pickaxe.json b/src/main/resources/assets/twilightforest/models/item/ironwood_pickaxe.json new file mode 100644 index 0000000000..ae1d79ed7c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_pickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/ironwood_pick" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_raw.json b/src/main/resources/assets/twilightforest/models/item/ironwood_raw.json new file mode 100644 index 0000000000..9478aa4e61 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_raw.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ironwood_raw" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_shovel.json b/src/main/resources/assets/twilightforest/models/item/ironwood_shovel.json new file mode 100644 index 0000000000..9a4aa557a3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_shovel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/ironwood_shovel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ironwood_sword.json b/src/main/resources/assets/twilightforest/models/item/ironwood_sword.json new file mode 100644 index 0000000000..69349f5f81 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ironwood_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/ironwood_sword" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_axe.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_axe.json new file mode 100644 index 0000000000..11f193ef10 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_axe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/knightly_axe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_boots.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_boots.json new file mode 100644 index 0000000000..c41374cec9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_boots.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/knightly_boots" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_chestplate.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_chestplate.json new file mode 100644 index 0000000000..f9c45d4343 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/knightly_plate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_helmet.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_helmet.json new file mode 100644 index 0000000000..a78f9a495f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/util/overlap_gui", + "textures": { + "layer0": "twilightforest:items/knightly_helm" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_ingot.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_ingot.json new file mode 100644 index 0000000000..1702c4365b --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_ingot.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/knight_metal" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_leggings.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_leggings.json new file mode 100644 index 0000000000..8f5b6c74a3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/knightly_legs" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_pickaxe.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_pickaxe.json new file mode 100644 index 0000000000..2cd7ec47bf --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_pickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/knightly_pick" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_ring.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_ring.json new file mode 100644 index 0000000000..97714a17bf --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_ring.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/knightmetal_ring" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_shield.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_shield.json new file mode 100644 index 0000000000..29ab344abb --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_shield.json @@ -0,0 +1,69 @@ +{ + "display": { + "thirdperson_righthand": { + "rotation": [ 0, 90, 0 ], + "translation": [ 10.51, 6, -4 ], + "scale": [ 1, 1, 1 ] + }, + "thirdperson_lefthand": { + "rotation": [ 0, 90, 0 ], + "translation": [ 10.51, 6, 12 ], + "scale": [ 1, 1, 1 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 180, 5 ], + "translation": [ -10, 2, -10 ], + "scale": [ 1.25, 1.25, 1.25 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 180, 5 ], + "translation": [ 10, 0, -10 ], + "scale": [ 1.25, 1.25, 1.25 ] + }, + "gui": { + "rotation": [ 15, -25, -5 ], + "translation": [ 2, 3, 0 ], + "scale": [ 0.65, 0.65, 0.65 ] + }, + "fixed": { + "rotation": [ 0, 180, 0 ], + "translation": [ -2, 4, -5], + "scale":[ 0.5, 0.5, 0.5] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 4, 4, 2], + "scale":[ 0.25, 0.25, 0.25] + } + }, + "textures": { + "k_shield": "twilightforest:items/knightly_shield", + "v_shield": "minecraft:entity/shield_base" + }, + "elements": [{ + "from": [ -6, -10, -0.5 ], + "to" : [ 6, 10, 1.5 ], + "faces": { + "down": { "uv": [ 7, 0, 13, 1 ], "texture": "#k_shield" }, + "up": { "uv": [ 1, 0, 7, 1 ], "texture": "#k_shield" }, + "north": { "uv": [ 8, 1, 14, 11 ], "texture": "#k_shield" }, + "south": { "uv": [ 1, 1, 7, 11 ], "texture": "#k_shield" }, + "west": { "uv": [ 7, 1, 8, 11 ], "texture": "#k_shield" }, + "east": { "uv": [ 0, 1, 1, 11 ], "texture": "#k_shield" } + } + }, { + "from": [ -1, -3, -5.5 ], + "to" : [ 1, 3, -0.5 ], + "faces": { + "down": { "uv": [ 8.5, 0 , 9 , 1.5 ], "texture": "#v_shield" }, + "up": { "uv": [ 8 , 0 , 8.5, 1.5 ], "texture": "#v_shield" }, + "north": { "uv": [ 8 , 1.5, 8.5, 3 ], "texture": "#v_shield" }, + "west": { "uv": [ 8.5, 1.5, 10 , 3 ], "texture": "#v_shield" }, + "east": { "uv": [ 6.5, 1.5, 8 , 3 ], "texture": "#v_shield" } + } + }], + "overrides": [{ + "predicate": { "blocking": 1 }, + "model": "twilightforest:item/knightmetal_shield_blocking" + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_shield_blocking.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_shield_blocking.json new file mode 100644 index 0000000000..d88cbe2eeb --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_shield_blocking.json @@ -0,0 +1,30 @@ +{ + "parent": "twilightforest:item/knightmetal_shield", + "display": { + "thirdperson_righthand": { + "rotation": [ 45, 135, 0 ], + "translation": [ 3.51, 11, -2 ], + "scale": [ 1, 1, 1 ] + }, + "thirdperson_lefthand": { + "rotation": [ 45, 135, 0 ], + "translation": [ 13.51, 3, 5 ], + "scale": [ 1, 1, 1 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 180, -5 ], + "translation": [ -15, 5, -11 ], + "scale": [ 1.25, 1.25, 1.25 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 180, -5 ], + "translation": [ 5, 5, -11 ], + "scale": [ 1.25, 1.25, 1.25 ] + }, + "gui": { + "rotation": [ 15, -25, -5 ], + "translation": [ 2, 3, 0 ], + "scale": [ 0.65, 0.65, 0.65 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/knightmetal_sword.json b/src/main/resources/assets/twilightforest/models/item/knightmetal_sword.json new file mode 100644 index 0000000000..340f868f38 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/knightmetal_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/knightly_sword" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/lamp_of_cinders.json b/src/main/resources/assets/twilightforest/models/item/lamp_of_cinders.json new file mode 100644 index 0000000000..f0a01d6b44 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/lamp_of_cinders.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/lamp_of_cinders" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/lifedrain_scepter.json b/src/main/resources/assets/twilightforest/models/item/lifedrain_scepter.json new file mode 100644 index 0000000000..84a0ac5c20 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/lifedrain_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/scepter_lifedrain" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/liveroot.json b/src/main/resources/assets/twilightforest/models/item/liveroot.json new file mode 100644 index 0000000000..a517ad2742 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/liveroot.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/liveroot" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/logbook.json b/src/main/resources/assets/twilightforest/models/item/logbook.json new file mode 100644 index 0000000000..c8d3cc718d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/logbook.json @@ -0,0 +1,12 @@ +{ + "parent": "item/generated", + "textures" : { + "layer0": "twilightforest:items/logbook/fresh" + }, + "overrides": [ + { "predicate": { "completion": 0.0 }, "model": "twilightforest:item/logbook/0" }, + { "predicate": { "completion": 0.333 }, "model": "twilightforest:item/logbook/1" }, + { "predicate": { "completion": 0.666 }, "model": "twilightforest:item/logbook/2" }, + { "predicate": { "completion": 1.0 }, "model": "twilightforest:item/logbook/3" } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/logbook/0.json b/src/main/resources/assets/twilightforest/models/item/logbook/0.json new file mode 100644 index 0000000000..fe7cec5ca1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/logbook/0.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/logbook/fresh" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/logbook/1.json b/src/main/resources/assets/twilightforest/models/item/logbook/1.json new file mode 100644 index 0000000000..c9534c9f50 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/logbook/1.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/logbook/used" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/logbook/2.json b/src/main/resources/assets/twilightforest/models/item/logbook/2.json new file mode 100644 index 0000000000..7cb93bec72 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/logbook/2.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/logbook/knowledgable" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/logbook/3.json b/src/main/resources/assets/twilightforest/models/item/logbook/3.json new file mode 100644 index 0000000000..1e2f2047d5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/logbook/3.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/logbook/supreme" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/lunchcase.json b/src/main/resources/assets/twilightforest/models/item/lunchcase.json new file mode 100644 index 0000000000..60c7f09c54 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/lunchcase.json @@ -0,0 +1,264 @@ +{ + "display": { + "gui": { + "rotation" : [ 15 , 202.5 , 0 ], + "translation": [ 0 , 1 , 0 ], + "scale" : [ 0.75, 0.75, 0.75 ] + }, + "ground": { + "rotation" : [ 0 , 0 , 0 ], + "translation": [ 0 , 2 , 0 ], + "scale" : [ 0.5, 0.5, 0.5 ] + }, + "head": { + "rotation" : [ 0, 180, 0 ], + "translation": [ 0, 13, 7 ], + "scale" : [ 1, 1, 1 ] + }, + "thirdperson_righthand": { + "rotation" : [ 0 , 0 , 0 ], + "translation": [ 0 , 3 , 1 ], + "scale" : [ 0.55, 0.55, 0.55 ] + }, + "firstperson_righthand": { + "rotation" : [ 0 , -90 , 25 ], + "translation": [ 1.13, 3.2 , 1.13 ], + "scale" : [ 0.68, 0.68, 0.68 ] + }, + "fixed": { + "rotation" : [ 0, 180, 0 ], + "translation": [ 0, 0, 0 ], + "scale" : [ 1, 1, 1 ] + } + }, + "elements": [{ + "from": [ 2, 10.5, 4 ], + "to" : [ 14, 12 , 12 ], + "faces": { + "up" : { "uv": [ 4, 2, 12, 14 ], "texture": "#side", "tintindex": 1, "rotation": 90 }, + "down" : { "uv": [ 4, 2, 12, 14 ], "texture": "#side", "tintindex": 1, "rotation": 90 }, + "north": { "texture": "#face", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 } + } + }, { + "from": [ 2, 0 , 4 ], + "to" : [ 14, 1.5, 12 ], + "faces": { + "up" : { "texture": "#side", "tintindex": 1, "rotation": 90 }, + "down" : { "texture": "#side", "tintindex": 1, "rotation": 90 }, + "north": { "texture": "#face", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 } + } + }, { + "from": [ 4, 3, 4 ], + "to" : [ 12, 4, 12 ], + "faces": { + "down" : { "texture": "#side", "tintindex": 1, "rotation": 90 }, + "north": { "texture": "#face", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 } + } + }, { + "from": [ 4, 8, 4 ], + "to" : [ 12, 9, 12 ], + "faces": { + "up" : { "texture": "#side", "tintindex": 1, "rotation": 90 }, + "north": { "texture": "#face", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 } + } + }, { + "from": [ 3, 4, 4 ], + "to" : [ 13, 8, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + } + }, { + "from": [ 14.5, 2, 4 ], + "to" : [ 16 , 10, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + } + }, { + "from": [ 0 , 2, 4 ], + "to" : [ 1.5, 10, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + } + }, { + "from": [ 0 , 0, 4 ], + "to" : [ 1.25, 2, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 0, 2, 0 ], + "axis": "z", + "angle": 45, + "rescale": true + } + }, { + "from": [ 3 , 3, 4 ], + "to" : [ 3.5, 4, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 3, 4, 0 ], + "axis": "z", + "angle": 45, + "rescale": true + } + }, { + "from": [ 14.75, 0, 4 ], + "to" : [ 16 , 2, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 16, 2, 0 ], + "axis": "z", + "angle": -45, + "rescale": true + } + }, { + "from": [ 12.5, 3, 4 ], + "to" : [ 13 , 4, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 13, 4, 0 ], + "axis": "z", + "angle": -45, + "rescale": true + } + }, { + "from": [ 0 , 10, 4 ], + "to" : [ 1.25, 12, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 0, 10, 0 ], + "axis": "z", + "angle": -45, + "rescale": true + } + }, { + "from": [ 3 , 8, 4 ], + "to" : [ 3.5, 9, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 3, 8, 0 ], + "axis": "z", + "angle": -45, + "rescale": true + } + }, { + "from": [ 14.75, 10, 4 ], + "to" : [ 16 , 12, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 16, 10, 0 ], + "axis": "z", + "angle": 45, + "rescale": true + } + }, { + "from": [ 12.5, 8, 4 ], + "to" : [ 13 , 9, 12 ], + "faces": { + "north": { "texture": "#face", "tintindex": 1 }, + "east" : { "texture": "#side", "tintindex": 1 }, + "south": { "texture": "#face", "tintindex": 1 }, + "west" : { "texture": "#side", "tintindex": 1 } + }, + "rotation": { + "origin": [ 13, 8, 0 ], + "axis": "z", + "angle": 45, + "rescale": true + } + }, { + "from": [ 1.5, 1.5, 4.5 ], + "to" : [ 14.5, 10.5, 11.5 ], + "faces": { + "north": { "texture": "#face", "tintindex": 0 }, + "south": { "texture": "#face", "tintindex": 0 } + } + }, { + "from": [ 3, 14, 7 ], + "to" : [ 13, 15, 9 ], + "faces": { + "up" : { "texture": "#face", "tintindex": 2 }, + "down" : { "texture": "#face", "tintindex": 2 }, + "north": { "texture": "#face", "tintindex": 2 }, + "east" : { "texture": "#face", "tintindex": 2 }, + "south": { "texture": "#face", "tintindex": 2 }, + "west" : { "texture": "#face", "tintindex": 2 } + } + }, { + "from": [ 4, 11.5 , 6.5 ], + "to" : [ 5, 14.75, 9.5 ], + "faces": { + "up" : { "texture": "#face", "tintindex": 2 }, + "north": { "texture": "#face", "tintindex": 2 }, + "east" : { "texture": "#face", "tintindex": 2 }, + "south": { "texture": "#face", "tintindex": 2 }, + "west" : { "texture": "#face", "tintindex": 2 } + }, + "rotation": { + "origin": [ 4.5, 13, 8 ], + "axis": "z", + "angle": -22.5 + } + }, { + "from": [ 11, 11.5 , 6.5 ], + "to" : [ 12, 14.75, 9.5 ], + "faces": { + "up" : { "texture": "#face", "tintindex": 2 }, + "north": { "texture": "#face", "tintindex": 2 }, + "east" : { "texture": "#face", "tintindex": 2 }, + "south": { "texture": "#face", "tintindex": 2 }, + "west" : { "texture": "#face", "tintindex": 2 } + }, + "rotation": { + "origin": [ 11.5, 13, 8 ], + "axis": "z", + "angle": 22.5 + } + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/magic_beans.json b/src/main/resources/assets/twilightforest/models/item/magic_beans.json new file mode 100644 index 0000000000..ba397d42e3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/magic_beans.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/magic_beans" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/magic_map.json b/src/main/resources/assets/twilightforest/models/item/magic_map.json new file mode 100644 index 0000000000..b024d73395 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/magic_map.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/magic_map" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/magic_map_empty.json b/src/main/resources/assets/twilightforest/models/item/magic_map_empty.json new file mode 100644 index 0000000000..db2db9a0aa --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/magic_map_empty.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/empty_magic_map" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/magic_map_focus.json b/src/main/resources/assets/twilightforest/models/item/magic_map_focus.json new file mode 100644 index 0000000000..ca71e7ff70 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/magic_map_focus.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/magic_map_focus" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/maze_map.json b/src/main/resources/assets/twilightforest/models/item/maze_map.json new file mode 100644 index 0000000000..01f0b939ad --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/maze_map.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/maze_map" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/maze_map_empty.json b/src/main/resources/assets/twilightforest/models/item/maze_map_empty.json new file mode 100644 index 0000000000..bece25d5f8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/maze_map_empty.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/empty_maze_map" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/maze_map_focus.json b/src/main/resources/assets/twilightforest/models/item/maze_map_focus.json new file mode 100644 index 0000000000..b6ba902d02 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/maze_map_focus.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/maze_map_focus" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/maze_wafer.json b/src/main/resources/assets/twilightforest/models/item/maze_wafer.json new file mode 100644 index 0000000000..a2870b6ce9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/maze_wafer.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/maze_wafer" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/mazebreaker_pickaxe.json b/src/main/resources/assets/twilightforest/models/item/mazebreaker_pickaxe.json new file mode 100644 index 0000000000..85d07e6d0f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/mazebreaker_pickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/mazebreaker_pick" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/meef_stroganoff.json b/src/main/resources/assets/twilightforest/models/item/meef_stroganoff.json new file mode 100644 index 0000000000..a9dd83950c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/meef_stroganoff.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/meef_stroganoff" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/minotaur_axe.json b/src/main/resources/assets/twilightforest/models/item/minotaur_axe.json new file mode 100644 index 0000000000..8d1a7c039d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/minotaur_axe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/minotaur_axe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/minotaur_axe_gold.json b/src/main/resources/assets/twilightforest/models/item/minotaur_axe_gold.json new file mode 100644 index 0000000000..6de40c7565 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/minotaur_axe_gold.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/minotaur_axe_gold" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial.json b/src/main/resources/assets/twilightforest/models/item/moon_dial.json new file mode 100644 index 0000000000..48ea1f395f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial.json @@ -0,0 +1,16 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/full" + }, + "overrides": [ + { "predicate": { "phase": 0.0 }, "model": "twilightforest:item/moon_dial/full" }, + { "predicate": { "phase": 0.125 }, "model": "twilightforest:item/moon_dial/waning_gibbous" }, + { "predicate": { "phase": 0.25 }, "model": "twilightforest:item/moon_dial/third_quarter" }, + { "predicate": { "phase": 0.375 }, "model": "twilightforest:item/moon_dial/waning_cresent" }, + { "predicate": { "phase": 0.5 }, "model": "twilightforest:item/moon_dial/new" }, + { "predicate": { "phase": 0.625 }, "model": "twilightforest:item/moon_dial/waxing_cresent" }, + { "predicate": { "phase": 0.75 }, "model": "twilightforest:item/moon_dial/first_quarter" }, + { "predicate": { "phase": 0.875 }, "model": "twilightforest:item/moon_dial/waxing_gibbous" } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/first_quarter.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/first_quarter.json new file mode 100644 index 0000000000..f71e632903 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/first_quarter.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/first_quarter" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/full.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/full.json new file mode 100644 index 0000000000..910c564b02 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/full.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/full" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/new.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/new.json new file mode 100644 index 0000000000..f8a4f2f47c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/new.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/new" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/third_quarter.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/third_quarter.json new file mode 100644 index 0000000000..9a1394a656 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/third_quarter.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/third_quarter" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/waning_cresent.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/waning_cresent.json new file mode 100644 index 0000000000..0635d25b7f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/waning_cresent.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/waning_cresent" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/waning_gibbous.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/waning_gibbous.json new file mode 100644 index 0000000000..df0555cd5b --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/waning_gibbous.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/waning_gibbous" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/waxing_cresent.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/waxing_cresent.json new file mode 100644 index 0000000000..1d22c09688 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/waxing_cresent.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/waxing_cresent" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moon_dial/waxing_gibbous.json b/src/main/resources/assets/twilightforest/models/item/moon_dial/waxing_gibbous.json new file mode 100644 index 0000000000..bb6aef2357 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moon_dial/waxing_gibbous.json @@ -0,0 +1,6 @@ +{ + "parent" : "twilightforest:item/util/readable", + "textures" : { + "layer0": "twilightforest:items/moon_dial/waxing_gibbous" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moonworm.json b/src/main/resources/assets/twilightforest/models/item/moonworm.json new file mode 100644 index 0000000000..3d1b732ccd --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moonworm.json @@ -0,0 +1,45 @@ +{ + "parent": "builtin/entity", + "display": { + "gui": { + "rotation": [ 210, 315, 0 ], + "translation": [ 0.5, 7, 0 ], + "scale":[ 1.35, 1.35, 1.35 ] + }, + "ground": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3, 0 ], + "scale":[ 0.75, 0.75, 0.75 ] + }, + "head": { + "rotation": [ 0, 180, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 1, 1, 1] + }, + "fixed": { + "rotation": [ 90, 180, 0 ], + "translation": [ 0, 2, -7.5 ], + "scale":[ 1, 1, 1 ] + }, + "thirdperson_righthand": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3.3, 2], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "thirdperson_lefthand": { + "rotation": [ 180, 180, 0 ], + "translation": [ 0, 3.3, 2], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 225, 0, -15 ], + "translation": [ 2, 4, 0 ], + "scale": [ 0.6, 0.6, 0.6 ] + }, + "firstperson_lefthand": { + "rotation": [ 225, 0, -15 ], + "translation": [ 2, 4, 0 ], + "scale": [ 0.6, 0.6, 0.6 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moonworm_queen.json b/src/main/resources/assets/twilightforest/models/item/moonworm_queen.json new file mode 100644 index 0000000000..e6e2c7a179 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moonworm_queen.json @@ -0,0 +1,14 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/moonworm_queen" + }, + "overrides": [ + { + "predicate": { + "twilightforest:alt": 1 + }, + "model": "twilightforest:item/moonworm_queen_alt" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/moonworm_queen_alt.json b/src/main/resources/assets/twilightforest/models/item/moonworm_queen_alt.json new file mode 100644 index 0000000000..51ab1bd9c2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/moonworm_queen_alt.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/moonworm_queen_alt" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/naga_chestplate.json b/src/main/resources/assets/twilightforest/models/item/naga_chestplate.json new file mode 100644 index 0000000000..9cdca4b796 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/naga_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/naga_plate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/naga_leggings.json b/src/main/resources/assets/twilightforest/models/item/naga_leggings.json new file mode 100644 index 0000000000..c7196f0005 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/naga_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/naga_legs" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/naga_scale.json b/src/main/resources/assets/twilightforest/models/item/naga_scale.json new file mode 100644 index 0000000000..25b12c1d7c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/naga_scale.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/naga_scale" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ore_magnet.json b/src/main/resources/assets/twilightforest/models/item/ore_magnet.json new file mode 100644 index 0000000000..7f6bb2bfbf --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ore_magnet.json @@ -0,0 +1,22 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ore_magnet" + }, + "overrides": [ + { + "predicate": { + "pulling": 1, + "pull": 0.5 + }, + "model": "twilightforest:item/ore_magnet_pulling_1" + }, + { + "predicate": { + "pulling": 1, + "pull": 1 + }, + "model": "twilightforest:item/ore_magnet_pulling_2" + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/item/ore_magnet_pulling_1.json b/src/main/resources/assets/twilightforest/models/item/ore_magnet_pulling_1.json new file mode 100644 index 0000000000..8fafe7e1e4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ore_magnet_pulling_1.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ore_magnet_pulling_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ore_magnet_pulling_2.json b/src/main/resources/assets/twilightforest/models/item/ore_magnet_pulling_2.json new file mode 100644 index 0000000000..3bae7a2f59 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ore_magnet_pulling_2.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ore_magnet_pulling_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ore_map.json b/src/main/resources/assets/twilightforest/models/item/ore_map.json new file mode 100644 index 0000000000..71d61648c2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ore_map.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/util/overlap_gui", + "textures": { + "layer0": "twilightforest:items/ore_map" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ore_map_empty.json b/src/main/resources/assets/twilightforest/models/item/ore_map_empty.json new file mode 100644 index 0000000000..c1a6b3db77 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ore_map_empty.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/util/overlap_gui", + "textures": { + "layer0": "twilightforest:items/empty_ore_map" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/ore_meter.json b/src/main/resources/assets/twilightforest/models/item/ore_meter.json new file mode 100644 index 0000000000..97d70d26ff --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/ore_meter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/ore_meter" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/peacock_fan.json b/src/main/resources/assets/twilightforest/models/item/peacock_fan.json new file mode 100644 index 0000000000..f546ad7bf5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/peacock_fan.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/peacock_fan" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/phantom_chestplate.json b/src/main/resources/assets/twilightforest/models/item/phantom_chestplate.json new file mode 100644 index 0000000000..e38c1e935b --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/phantom_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/phantom_plate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/phantom_helmet.json b/src/main/resources/assets/twilightforest/models/item/phantom_helmet.json new file mode 100644 index 0000000000..eba8daa5e4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/phantom_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/phantom_helm" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/raven_feather.json b/src/main/resources/assets/twilightforest/models/item/raven_feather.json new file mode 100644 index 0000000000..3d3ca69aab --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/raven_feather.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/feather" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/raw_meef.json b/src/main/resources/assets/twilightforest/models/item/raw_meef.json new file mode 100644 index 0000000000..86e9ee427d --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/raw_meef.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/meef_raw" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/raw_venison.json b/src/main/resources/assets/twilightforest/models/item/raw_venison.json new file mode 100644 index 0000000000..82469498ab --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/raw_venison.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/venison_raw" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/seeker_bow.json b/src/main/resources/assets/twilightforest/models/item/seeker_bow.json new file mode 100644 index 0000000000..171c004a3a --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/seeker_bow.json @@ -0,0 +1,28 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "twilightforest:items/seekerbow_standby" + }, + "overrides": [ + { + "predicate": { + "pulling": 1 + }, + "model": "twilightforest:item/seeker_bow_pulling_0" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.65 + }, + "model": "twilightforest:item/seeker_bow_pulling_1" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.9 + }, + "model": "twilightforest:item/seeker_bow_pulling_2" + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_0.json b/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_0.json new file mode 100644 index 0000000000..3184abac3f --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_0.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/seeker_bow", + "textures": { + "layer0": "twilightforest:items/seekerbow_pulling_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_1.json b/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_1.json new file mode 100644 index 0000000000..70e1792d32 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_1.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/seeker_bow", + "textures": { + "layer0": "twilightforest:items/seekerbow_pulling_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_2.json b/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_2.json new file mode 100644 index 0000000000..fe26233eb6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/seeker_bow_pulling_2.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/seeker_bow", + "textures": { + "layer0": "twilightforest:items/seekerbow_pulling_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/shader.json b/src/main/resources/assets/twilightforest/models/item/shader.json new file mode 100644 index 0000000000..3fa754d5ac --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/shader.json @@ -0,0 +1,8 @@ +{ + "parent": "twilightforest:item/lunchcase", + "textures": { + "missing": "twilightforest:blocks/fluffy_cloud", + "face": "twilightforest:blocks/lunchbox_face", + "side": "twilightforest:blocks/lunchbox_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/shader_bag.json b/src/main/resources/assets/twilightforest/models/item/shader_bag.json new file mode 100644 index 0000000000..fd20e146e4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/shader_bag.json @@ -0,0 +1,3 @@ +{ + "parent": "twilightforest:item/shader" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/shield.json b/src/main/resources/assets/twilightforest/models/item/shield.json new file mode 100644 index 0000000000..bfe4dcf912 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/shield.json @@ -0,0 +1,7 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/lich_shield_frame", + "layer1": "twilightforest:items/lich_shield_fill" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/shield_scepter.json b/src/main/resources/assets/twilightforest/models/item/shield_scepter.json new file mode 100644 index 0000000000..3cdf21e611 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/shield_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/scepter_shielding" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_axe.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_axe.json new file mode 100644 index 0000000000..efac9fd5e0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_axe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/steeleaf_axe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_boots.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_boots.json new file mode 100644 index 0000000000..06aa063dc2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_boots.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/steeleaf_boots" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_chestplate.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_chestplate.json new file mode 100644 index 0000000000..566b5d791b --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/steeleaf_plate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_helmet.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_helmet.json new file mode 100644 index 0000000000..543ba05699 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/steeleaf_helm" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_hoe.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_hoe.json new file mode 100644 index 0000000000..716acc02c8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_hoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/steeleaf_hoe" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_ingot.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_ingot.json new file mode 100644 index 0000000000..414c70dfa6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_ingot.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/steeleaf_ingot" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_leggings.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_leggings.json new file mode 100644 index 0000000000..12f68c16b3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/steeleaf_legs" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_pickaxe.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_pickaxe.json new file mode 100644 index 0000000000..b69b5d9d5c --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_pickaxe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/steeleaf_pick" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_shovel.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_shovel.json new file mode 100644 index 0000000000..403fbaa406 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_shovel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/steeleaf_shovel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/steeleaf_sword.json b/src/main/resources/assets/twilightforest/models/item/steeleaf_sword.json new file mode 100644 index 0000000000..2adfce34e6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/steeleaf_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/steeleaf_sword" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/torchberries.json b/src/main/resources/assets/twilightforest/models/item/torchberries.json new file mode 100644 index 0000000000..92aae50b64 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/torchberries.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/torchberries" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/tower_key.json b/src/main/resources/assets/twilightforest/models/item/tower_key.json new file mode 100644 index 0000000000..ca2fd24461 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/tower_key.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/tower_key" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/transformation_powder.json b/src/main/resources/assets/twilightforest/models/item/transformation_powder.json new file mode 100644 index 0000000000..a533f7c054 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/transformation_powder.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/transform_powder" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/triple_bow.json b/src/main/resources/assets/twilightforest/models/item/triple_bow.json new file mode 100644 index 0000000000..ce9371d181 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/triple_bow.json @@ -0,0 +1,28 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "twilightforest:items/triplebow_standby" + }, + "overrides": [ + { + "predicate": { + "pulling": 1 + }, + "model": "twilightforest:item/triple_bow_pulling_0" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.65 + }, + "model": "twilightforest:item/triple_bow_pulling_1" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.9 + }, + "model": "twilightforest:item/triple_bow_pulling_2" + } + ] +} diff --git a/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_0.json b/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_0.json new file mode 100644 index 0000000000..4d0dd74cc4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_0.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/triple_bow", + "textures": { + "layer0": "twilightforest:items/triplebow_pulling_0" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_1.json b/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_1.json new file mode 100644 index 0000000000..ea4fd50833 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_1.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/triple_bow", + "textures": { + "layer0": "twilightforest:items/triplebow_pulling_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_2.json b/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_2.json new file mode 100644 index 0000000000..27ac5b47de --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/triple_bow_pulling_2.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/triple_bow", + "textures": { + "layer0": "twilightforest:items/triplebow_pulling_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/trophy.json b/src/main/resources/assets/twilightforest/models/item/trophy.json new file mode 100644 index 0000000000..4ec082fcb7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/trophy.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/trophy" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/trophy_minor.json b/src/main/resources/assets/twilightforest/models/item/trophy_minor.json new file mode 100644 index 0000000000..2a2855e854 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/trophy_minor.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/trophy_minor" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/trophy_quest.json b/src/main/resources/assets/twilightforest/models/item/trophy_quest.json new file mode 100644 index 0000000000..749359dd82 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/trophy_quest.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/trophy_quest" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/twilight_scepter.json b/src/main/resources/assets/twilightforest/models/item/twilight_scepter.json new file mode 100644 index 0000000000..15b8dec192 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/twilight_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/scepter_twilight" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/util/overlap_gui.json b/src/main/resources/assets/twilightforest/models/item/util/overlap_gui.json new file mode 100644 index 0000000000..62ce1bc744 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/util/overlap_gui.json @@ -0,0 +1,43 @@ +{ + "parent": "item/generated", + "display": { + "gui": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0 ], + "scale":[ 2, 2, 1 ] + }, + "ground": { + "translation": [ 0, 2, 0 ], + "scale": [ 1, 1, 0.5 ] + }, + "head": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 5, 5, 5 ] + }, + "thirdperson_righthand": { + "rotation": [ 0, -90, 55 ], + "translation": [ 0, 4.0, 0.5 ], + "scale": [ 1.70, 1.70, 0.85 ] + }, + "thirdperson_lefthand": { + "rotation": [ 0, 90, -55 ], + "translation": [ 0, 4.0, 0.5 ], + "scale": [ 1.70, 1.70, 0.85 ] + }, + "firstperson_righthand": { + "rotation": [ 0, -90, 25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 1.36, 1.36, 0.68 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 90, -25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 1.36, 1.36, 0.68 ] + }, + "fixed": { + "rotation": [ 0, 180, 0 ], + "scale": [ 2, 2, 1 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/util/overlap_gui_thick.json b/src/main/resources/assets/twilightforest/models/item/util/overlap_gui_thick.json new file mode 100644 index 0000000000..cfb9c777a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/util/overlap_gui_thick.json @@ -0,0 +1,43 @@ +{ + "parent": "item/generated", + "display": { + "gui": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0 ], + "scale":[ 2, 2, 2 ] + }, + "ground": { + "translation": [ 0, 2, 0 ], + "scale": [ 1, 1, 1 ] + }, + "head": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 5, 5, 5 ] + }, + "thirdperson_righthand": { + "rotation": [ 0, -90, 55 ], + "translation": [ 0, 4.0, 0.5 ], + "scale": [ 1.70, 1.70, 1.70 ] + }, + "thirdperson_lefthand": { + "rotation": [ 0, 90, -55 ], + "translation": [ 0, 4.0, 0.5 ], + "scale": [ 1.70, 1.70, 1.70 ] + }, + "firstperson_righthand": { + "rotation": [ 0, -90, 25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 1.36, 1.36, 1.36 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 90, -25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 1.36, 1.36, 1.36 ] + }, + "fixed": { + "rotation": [ 0, 180, 0 ], + "scale": [ 2, 2, 2 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/util/readable.json b/src/main/resources/assets/twilightforest/models/item/util/readable.json new file mode 100644 index 0000000000..34abbfe8cc --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/util/readable.json @@ -0,0 +1,15 @@ +{ + "parent" : "item/generated", + "display": { + "firstperson_righthand": { + "rotation" : [ 0 , -45 , -5 ], + "translation": [ 0 , 5.3 , 1.13 ], + "scale" : [ 0.68, 0.68, 0.68 ] + }, + "firstperson_lefthand": { + "rotation" : [ 0 , -45 , -5 ], + "translation": [ 0 , 5.3 , 1.13 ], + "scale" : [ 0.68, 0.68, 0.68 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/yeti_boots.json b/src/main/resources/assets/twilightforest/models/item/yeti_boots.json new file mode 100644 index 0000000000..386571f1fd --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/yeti_boots.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/yeti_boots" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/yeti_chestplate.json b/src/main/resources/assets/twilightforest/models/item/yeti_chestplate.json new file mode 100644 index 0000000000..51733075fb --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/yeti_chestplate.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/yeti_plate" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/yeti_helmet.json b/src/main/resources/assets/twilightforest/models/item/yeti_helmet.json new file mode 100644 index 0000000000..2140a53359 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/yeti_helmet.json @@ -0,0 +1,6 @@ +{ + "parent": "twilightforest:item/util/overlap_gui", + "textures": { + "layer0": "twilightforest:items/yeti_helm" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/yeti_leggings.json b/src/main/resources/assets/twilightforest/models/item/yeti_leggings.json new file mode 100644 index 0000000000..b7296705d2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/yeti_leggings.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "twilightforest:items/yeti_legs" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/models/item/zombie_scepter.json b/src/main/resources/assets/twilightforest/models/item/zombie_scepter.json new file mode 100644 index 0000000000..a02eda4bf2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/models/item/zombie_scepter.json @@ -0,0 +1,6 @@ +{ + "parent": "item/handheld", + "textures": { + "layer0": "twilightforest:items/scepter_zombie" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/book.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/book.json new file mode 100644 index 0000000000..6ad6ef76e3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/book.json @@ -0,0 +1,16 @@ +{ + "name": "item.twilightforest.guide.name", + "advancement_namespaces": [ + "twilightforest" + ], + "creative_tab": "twilightForest", + "model": "twilightforest:logbook", + "book_texture": "patchouli:textures/gui/book_green.png", + "filler_texture": "twilightforest:textures/gui/page_filler.png", + "version": "${edition}", + "macros": { + "": "${s}(bold)", + "": "${s}(italic)", + "": "${s}()" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/biomes.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/biomes.json new file mode 100644 index 0000000000..aff1372e22 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/biomes.json @@ -0,0 +1,7 @@ +{ + "parent": "twilightforest:world", + "name": "Biomes", + "description": "Distant lands everywhere!", + "icon": "twilightforest:magic_map", + "sortnum": 0 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/bosses.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/bosses.json new file mode 100644 index 0000000000..47abf929a6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/bosses.json @@ -0,0 +1,7 @@ +{ + "parent": "twilightforest:entities", + "name": "Bosses", + "description": "The very baddest guys!", + "icon": "twilightforest:boss_spawner", + "sortnum": 0 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/devices.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/devices.json new file mode 100644 index 0000000000..fb6ef1bcaa --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/devices.json @@ -0,0 +1,6 @@ +{ + "name": "Devices and Mechanisms", + "description": "Technology in the Twilight Forest", + "icon": "twilightforest:tower_device:0", + "sortnum": 3500 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/entities.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/entities.json new file mode 100644 index 0000000000..323a7c7627 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/entities.json @@ -0,0 +1,6 @@ +{ + "name": "Entities", + "description": "All of the good guys and bad guys!", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:wild_boar\"}}", + "sortnum": 2000 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/major_landmarks.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/major_landmarks.json new file mode 100644 index 0000000000..966d2a5603 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/major_landmarks.json @@ -0,0 +1,7 @@ +{ + "parent": "twilightforest:world", + "name": "Major Landmarks", + "description": "Time to wallop those bosses!", + "icon": "twilightforest:magic_map", + "sortnum": 2000 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/minor_landmarks.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/minor_landmarks.json new file mode 100644 index 0000000000..3bbfa3b1a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/minor_landmarks.json @@ -0,0 +1,7 @@ +{ + "parent": "twilightforest:world", + "name": "Minor Landmarks", + "description": "Huts, Wells, Ruins!", + "icon": "twilightforest:magic_map", + "sortnum": 1000 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/treasures.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/treasures.json new file mode 100644 index 0000000000..d176e96097 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/treasures.json @@ -0,0 +1,6 @@ +{ + "name": "Treasures", + "description": "There's so much treasure!", + "icon": "twilightforest:experiment_115:2", + "sortnum": 3000 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/world.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/world.json new file mode 100644 index 0000000000..8860033fde --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/categories/world.json @@ -0,0 +1,6 @@ +{ + "name": "World", + "description": "It's a whole new world!", + "icon": "twilightforest:twilight_log", + "sortnum": 1000 +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/alpha_yeti.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/alpha_yeti.json new file mode 100644 index 0000000000..d1c21f85c9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/alpha_yeti.json @@ -0,0 +1,14 @@ +{ + "name": "Alpha Yeti", + "icon": "twilightforest:yeti_helmet", + "category": "bosses", + "advancement": "twilightforest:alt/entities/yeti_alpha", + "sortnum": 7030, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:yeti_alpha", + "text": "He so baddie but not so bad, he don't got no trophy yeti" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/hydra.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/hydra.json new file mode 100644 index 0000000000..ddc7859e81 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/hydra.json @@ -0,0 +1,18 @@ +{ + "name": "Hydra", + "icon": "twilightforest:trophy:2", + "category": "bosses", + "advancement": "twilightforest:alt/entities/hydra", + "sortnum": 5110, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:hydra", + "text": "Hail Hydra" + }, + { + "type": "text", + "text": "The great monster of the Fire Swamp, the Hydra has a tough hide and each head having its own mind and method of attacking. Ranging from fiery breaths, exploding mortars, and a devastating bite attack, along with the ability to regenerate heads, this thing will not stop at anything." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/lich.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/lich.json new file mode 100644 index 0000000000..3fe141a559 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/lich.json @@ -0,0 +1,14 @@ +{ + "name": "Lich", + "icon": "twilightforest:trophy:1", + "category": "bosses", + "advancement": "twilightforest:alt/entities/lich", + "sortnum": 4020, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:lich{ForgeCaps:{\"twilightforest:cap_shield\":{permshields:5}},HandItems:[{id:\"twilightforest:twilight_scepter\",Count:1}]}", + "text": "More evil than you can shake a bone at" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/minoshroom.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/minoshroom.json new file mode 100644 index 0000000000..ea52c96148 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/minoshroom.json @@ -0,0 +1,18 @@ +{ + "name": "Minoshroom", + "icon": "twilightforest:trophy:6", + "category": "bosses", + "advancement": "twilightforest:alt/entities/minoshroom", + "sortnum": 5040, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:minoshroom{HandItems:[{id:\"twilightforest:minotaur_axe\",Count:1}]}", + "text": "He just wanted to axe you a question." + }, + { + "type": "text", + "text": "This terrifying beast of the Labyrinth could destroy any uncaring adventurer quickly. Their weapon of choice, a Diamond Minotaur Axe, can tear down any defense, and their charging attack could catch anyone off guard in one fell swoop.$(br)Caution should be exercised while trying to slay the Minoshroom." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/naga.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/naga.json new file mode 100644 index 0000000000..1e5a929084 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/naga.json @@ -0,0 +1,14 @@ +{ + "name": "Naga", + "icon": "twilightforest:trophy:0", + "category": "bosses", + "advancement": "twilightforest:alt/entities/naga", + "sortnum": 3010, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:naga", + "text": "It's an immense green snake-like creature with a human-like face. Its scales have subtle hints of other colors." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/phantom_knights.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/phantom_knights.json new file mode 100644 index 0000000000..f33d6612c2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/phantom_knights.json @@ -0,0 +1,14 @@ +{ + "name": "Knight Phantoms", + "icon": "twilightforest:trophy:4", + "category": "bosses", + "advancement": "twilightforest:alt/entities/knight_phantom", + "sortnum": 6020, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:knight_phantom{ArmorItems:[{},{},{id:\"twilightforest:phantom_chestplate\",Count:1},{id:\"twilightforest:phantom_helmet\",Count:1}],HandItems:[{id:\"twilightforest:knightmetal_sword\",Count:1},{id:\"twilightforest:knightmetal_axe\",Count:1}]}", + "text": "A very bad knightmare" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/snow_queen.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/snow_queen.json new file mode 100644 index 0000000000..bb5c6ca740 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/snow_queen.json @@ -0,0 +1,14 @@ +{ + "name": "Snow Queen", + "icon": "twilightforest:trophy:5", + "category": "bosses", + "advancement": "twilightforest:alt/entities/snow_queen", + "sortnum": 7130, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:snow_queen", + "text": "Best Waifu Material" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/ur_ghast.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/ur_ghast.json new file mode 100644 index 0000000000..68dfdd7a5a --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/bosses/ur_ghast.json @@ -0,0 +1,14 @@ +{ + "name": "Ur-Ghast", + "icon": "twilightforest:trophy:3", + "category": "bosses", + "advancement": "twilightforest:alt/entities/ur_ghast", + "sortnum": 6120, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:ur_ghast", + "text": "Time to call the Ghastbusters" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/anti-builder.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/anti-builder.json new file mode 100644 index 0000000000..918ab40c05 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/anti-builder.json @@ -0,0 +1,15 @@ +{ + "name": "Anti-builder", + "icon": "twilightforest:tower_device:9", + "category": "devices", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6240, + "pages": [ + { + "type": "spotlight", + "title": "Anti-builder", + "item": "twilightforest:tower_device:9", + "text": "There is a strange aura emitted from this block, and it seems to be protecting anything that is within this bound. Any attempts to place a block in this field results in it being broken, and breaking anything augments a strange red-and-green block. There doesn't seem to be a switch to turn it off, but there must be a way." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/carminite_builder.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/carminite_builder.json new file mode 100644 index 0000000000..688033ff67 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/carminite_builder.json @@ -0,0 +1,15 @@ +{ + "name": "Carminite Builder", + "icon": "twilightforest:tower_device:6", + "category": "devices", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6230, + "pages": [ + { + "type": "spotlight", + "title": "Carminite Builder", + "item": "twilightforest:tower_device:6", + "text": "This strange device will augment red transparent blocks when it receives a Redstone signal. Once triggered, the Carminite Builder will create a path and will build depending on where I am looking. This path is only temporary, and will need another Redstone signal to reactivate it." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/carminite_reactor.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/carminite_reactor.json new file mode 100644 index 0000000000..ff4b71d174 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/carminite_reactor.json @@ -0,0 +1,18 @@ +{ + "name": "Carminite Reactor", + "icon": "twilightforest:tower_device:12", + "category": "devices", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6260, + "pages": [ + { + "type": "spotlight", + "title": "Carminite Reactor", + "item": "twilightforest:tower_device:12", + "text": "I cannot seem to understand what this is for. It is a reactor of sorts, so I'd assume it would emit power, but all it does is idle. Perhaps it is the one that needs power?" + }, { + "type": "text", + "text": "Should I be in awe or afraid? If I can give this device enough Redstone power, the surrounding area turns into Gold and Diamond. I cannot describe it, but those blocks are fake, and the reactor implodes on me, releasing Carminite Ghastlings. Whether or not this may have been a failed experiment, I will never know." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/encased_fire_jet.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/encased_fire_jet.json new file mode 100644 index 0000000000..e0010f0fd4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/encased_fire_jet.json @@ -0,0 +1,15 @@ +{ + "name": "Encased Fire Jet", + "icon": "twilightforest:fire_jet:6", + "category": "devices", + "advancement": "twilightforest:alt/treasures/encased_fire_jet", + "sortnum": 5060, + "pages": [ + { + "type": "spotlight", + "title": "Encased Fire Jet", + "item": "twilightforest:fire_jet:6", + "text": "By taking a Fire Jet, and a bit of technical genius, I can create a Fire Jet that is self-sustaining and can fire with the press of a button, or a bit of Redstone signal. Though, a minor flaw with this device seems to be that it needs to warm up before it fires, so I must time the signals right." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/encased_smoker.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/encased_smoker.json new file mode 100644 index 0000000000..4e272bee73 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/encased_smoker.json @@ -0,0 +1,15 @@ +{ + "name": "Encased Smoker", + "icon": "twilightforest:fire_jet:1", + "category": "devices", + "advancement": "twilightforest:alt/treasures/encased_smoker", + "sortnum": 5060, + "pages": [ + { + "type": "spotlight", + "title": "Encased Smoker", + "item": "twilightforest:fire_jet:1", + "text": "Smoking Blocks will always emit smoke, but this is rather inconvenient for me. By wiring up a Smoking Block, I can create a device that will only emit smoke when I activate it. Now I must consider the practicality of such device." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/fire_jet.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/fire_jet.json new file mode 100644 index 0000000000..5712810c3b --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/fire_jet.json @@ -0,0 +1,15 @@ +{ + "name": "Fire Jet", + "icon": "twilightforest:fire_jet:3", + "category": "devices", + "advancement": "twilightforest:alt/treasures/fire_jet", + "sortnum": 5050, + "pages": [ + { + "type": "spotlight", + "title": "Fire Jet", + "item": "twilightforest:fire_jet:3", + "text": "Volatile jets that will shoot streams of fire at random. I have to be careful around these, for they don't seem to be triggered by anything. For some reason, they stop erupting when there's no Lava beneath it, perhaps that is their secret?" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/ghast_trap.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/ghast_trap.json new file mode 100644 index 0000000000..517bc32951 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/ghast_trap.json @@ -0,0 +1,18 @@ +{ + "name": "Ghast Trap", + "icon": "twilightforest:tower_device:10", + "category": "devices", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6250, + "pages": [ + { + "type": "spotlight", + "title": "Ghast Trap", + "item": "twilightforest:tower_device:10", + "text": "Namesake, it appears that this device's sole purpose is to trap Ghasts. It seems giving this thing a Redstone signal does nothing, perhaps it needs some sort of power source?" + }, { + "type": "text", + "text": "It is just what I'm after! If I can kill enough of these weak Ghastlings around one of these traps, it will gain the energy from those killed. There is a quiet pinging noise that emanates from this device, and if it is loud enough, I can trigger a Redstone signal to execute this device and wrench Ghasts from the sky, sucking up their life, too." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/locked_vanishing_block.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/locked_vanishing_block.json new file mode 100644 index 0000000000..80ee4b1fe8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/locked_vanishing_block.json @@ -0,0 +1,18 @@ +{ + "name": "Locked Vanishing Block", + "icon": "twilightforest:tower_device:4", + "category": "devices", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6220, + "pages": [ + { + "type": "spotlight", + "title": "Locked Vanishing Block", + "item": "twilightforest:tower_device:4", + "text": "There's something not right with this thing. No matter what I do to it, nothing happens to it, and neither do the connected Vanishing Blocks. I noticed this strange shape in the center of this device, perhaps it needs a key of some sort?" + }, { + "type": "text", + "text": "Of course, these devices are like locks to doors. If I give one of these a Tower Key, they will be unlocked, and thus interacting with one will cause them to vanish before me, and allow neighboring Vanishing Blocks to disappear." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/reappearing_block.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/reappearing_block.json new file mode 100644 index 0000000000..3c87ecdd0e --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/reappearing_block.json @@ -0,0 +1,15 @@ +{ + "name": "Reappearing Block", + "icon": "twilightforest:tower_device:0", + "category": "devices", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6200, + "pages": [ + { + "type": "spotlight", + "title": "Reappearing Block", + "item": "twilightforest:tower_device:0", + "text": "There appears to be something compelling and intriguing about this device. When I touch this block or give it a Redstone signal, it vanishes before my eyes. It seems to come back after a determined amount of time, but I guess I'll never understand why." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/smoking_block.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/smoking_block.json new file mode 100644 index 0000000000..de2cde0bc1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/smoking_block.json @@ -0,0 +1,15 @@ +{ + "name": "Smoking Block", + "icon": "twilightforest:fire_jet:0", + "category": "devices", + "advancement": "twilightforest:alt/treasures/smoking_block", + "sortnum": 5050, + "pages": [ + { + "type": "spotlight", + "title": "Smoking Block", + "item": "twilightforest:fire_jet:0", + "text": "These seem to be relatively safe to stand over. The soles of my feet aren't blistering and my skin isn't burning, but on the other hand it isn't pleasant to breathe in. This thing does seem to sustain itself, no heat needed; I wonder if that would be useful?" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/vanishing_block.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/vanishing_block.json new file mode 100644 index 0000000000..818d25c522 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/devices/vanishing_block.json @@ -0,0 +1,15 @@ +{ + "name": "Vanishing Block", + "icon": "twilightforest:tower_device:2", + "category": "devices", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6210, + "pages": [ + { + "type": "spotlight", + "title": "Vanishing Block", + "item": "twilightforest:tower_device:2", + "text": "This is more peculiar than I anticipated. When I touch or give this block a Redstone signal, it vanishes before my eyes. Even after waiting, it never comes back, so what purpose can it serve for security?" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/adherent.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/adherent.json new file mode 100644 index 0000000000..1c85f6959c --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/adherent.json @@ -0,0 +1,14 @@ +{ + "name": "Adherent", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:adherent\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/adherent", + "sortnum": 9010, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:adherent", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/animals.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/animals.json new file mode 100644 index 0000000000..561a60f112 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/animals.json @@ -0,0 +1,50 @@ +{ + "name": "Animals", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:wild_boar\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/animals", + "sortnum": 1100, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/bighorn_sheep", + "entity": "twilightforest:bighorn_sheep", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/bunny", + "entity": "twilightforest:bunny", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/deer", + "entity": "twilightforest:deer", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/raven", + "entity": "twilightforest:raven", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/squirrel", + "entity": "twilightforest:squirrel", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/wild_boar", + "entity": "twilightforest:tiny_bird", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/wild_boar", + "entity": "twilightforest:tiny_bird", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/penguin", + "entity": "twilightforest:penguin", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/arthopods.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/arthopods.json new file mode 100644 index 0000000000..a29c6ea054 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/arthopods.json @@ -0,0 +1,55 @@ +{ + "name": "Arthopods", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:pinch_beetle\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/arthopods", + "sortnum": 2100, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/hedge_spider", + "entity": "twilightforest:hedge_spider", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/swarm_spider", + "entity": "twilightforest:swarm_spider", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/slime_beetle", + "entity": "twilightforest:slime_beetle", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/fire_beetle", + "entity": "twilightforest:fire_beetle", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/pinch_beetle", + "entity": "twilightforest:pinch_beetle", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/mosquito_swarm", + "entity": "twilightforest:mosquito_swarm", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/king_spider", + "entity": "twilightforest:king_spider", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/tower_termite", + "entity": "twilightforest:tower_termite", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/tower_broodling", + "entity": "twilightforest:tower_broodling", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/castle_guardians.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/castle_guardians.json new file mode 100644 index 0000000000..93e4f5f2be --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/castle_guardians.json @@ -0,0 +1,8 @@ +{ + "name": "Castle Guardians", + "icon": "minecraft:spawn_egg", + "category": "entities", + "advancement": "twilightforest:alt/major_landmarks/final_castle", + "sortnum": 9010, + "pages": [] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/death_tome.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/death_tome.json new file mode 100644 index 0000000000..87c87f1495 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/death_tome.json @@ -0,0 +1,14 @@ +{ + "name": "Death Tome", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:death_tome\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/death_tome", + "sortnum": 4010, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:death_tome", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/ghasts.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/ghasts.json new file mode 100644 index 0000000000..723c76056e --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/ghasts.json @@ -0,0 +1,20 @@ +{ + "name": "Ghasts", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:mini_ghast\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/ghasts", + "sortnum": 6110, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/mini_ghast", + "entity": "twilightforest:mini_ghast", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/tower_ghast", + "entity": "twilightforest:tower_ghast", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/giants.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/giants.json new file mode 100644 index 0000000000..220c2d17af --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/giants.json @@ -0,0 +1,20 @@ +{ + "name": "Giants", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:giant_miner\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/giants", + "sortnum": 8110, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/giant_miner", + "entity": "twilightforest:giant_miner{HandItems:[{id:\"stone_pickaxe\",Count:1}]}", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/armored_giant", + "entity": "twilightforest:armored_giant{ArmorItems:[{id:\"iron_boots\",Count:1},{id:\"iron_leggings\",Count:1},{id:\"iron_chestplate\",Count:1},{id:\"iron_helmet\",Count:1}],HandItems:[{id:\"stone_sword\",Count:1}]}", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/goblins.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/goblins.json new file mode 100644 index 0000000000..4ab7bc1241 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/goblins.json @@ -0,0 +1,35 @@ +{ + "name": "Goblins", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:blockchain_goblin\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/goblins", + "sortnum": 2100, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/redcap", + "entity": "twilightforest:redcap", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/redcap_sapper", + "entity": "twilightforest:redcap_sapper", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/goblin_knight", + "entity": "twilightforest:goblin_knight_lower{Passengers:[{id:\"twilightforest:goblin_knight_upper\",hasArmor:1b,hasShield:1b}],hasArmor:1b}", + "text": "With Upper Goblin's world always sitting Lower Goblin's shoulders, he has never skipped leg day." + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/goblin_knight", + "entity": "twilightforest:goblin_knight_upper{hasArmor:1b}", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/blockchain_goblin", + "entity": "twilightforest:blockchain_goblin", + "text": "Block & Chain Goblin is ready to blow everyone away with his latest technical mastery of blockchain technologies." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/harbinger_cube.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/harbinger_cube.json new file mode 100644 index 0000000000..6ea2ce2437 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/harbinger_cube.json @@ -0,0 +1,14 @@ +{ + "name": "Harbinger Cube", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:harbinger_cube\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/harbinger_cube", + "sortnum": 9010, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:harbinger_cube", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/ice_cores.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/ice_cores.json new file mode 100644 index 0000000000..9fa07af0b4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/ice_cores.json @@ -0,0 +1,20 @@ +{ + "name": "Ice Cores", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:stable_ice_core\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/ice_cores", + "sortnum": 7120, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/stable_ice_core", + "entity": "twilightforest:stable_ice_core", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/unstable_ice_core", + "entity": "twilightforest:unstable_ice_core", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/kobold.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/kobold.json new file mode 100644 index 0000000000..094028647e --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/kobold.json @@ -0,0 +1,14 @@ +{ + "name": "Kobold", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:kobold\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/kobold", + "sortnum": 2100, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:kobold", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/maze_slime.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/maze_slime.json new file mode 100644 index 0000000000..7716c02ddb --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/maze_slime.json @@ -0,0 +1,18 @@ +{ + "name": "Maze Slime", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:maze_slime\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/maze_slime", + "sortnum": 5020, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:maze_slime{Size:1}", + "text": "" + }, + { + "type": "text", + "text": "Strange Slimes found within the confines of the Labyrinth. They look and feel like any other Slime, but their slimy bodies resemble Mazestone Bricks. Though they appear to be nothing special, they seem to contain a special secret within them; a rare treasure, perhaps?" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/minotaur.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/minotaur.json new file mode 100644 index 0000000000..3b25bec97c --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/minotaur.json @@ -0,0 +1,23 @@ +{ + "name": "Minotaur", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:minotaur\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/minotaur", + "sortnum": 5020, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:minotaur", + "text": "" + }, + { + "type": "text", + "text": "Humanoid beasts that roam the Labyrinth. These part-cow, part-human beasts each have a Golden Axe as their choice of weapon, tearing defenses down. Their charge attack happens quickly and swiftly, and in groups, they overwhelm any careful adventurer." + }, + { + "type": "text", + "advancement": "twilightforest:alt/treasures/minotaur_axe_gold", + "text": "Beware the Minotaurs with the Golden Minotaur Axe. They may be rare, but their different choice of weapon is a deadly choice, with more damage to deal." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/troll.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/troll.json new file mode 100644 index 0000000000..a4aa8cf0c9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/troll.json @@ -0,0 +1,14 @@ +{ + "name": "Troll", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:troll\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/troll", + "sortnum": 8010, + "pages": [ + { + "type": "entity", + "entity": "twilightforest:troll", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/undead.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/undead.json new file mode 100644 index 0000000000..fb7d1fd254 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/undead.json @@ -0,0 +1,25 @@ +{ + "name": "Undead", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:skeleton_druid\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/undead", + "sortnum": 2100, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/skeleton_druid", + "entity": "twilightforest:skeleton_druid", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/wraith", + "entity": "twilightforest:wraith", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/snow_guardian", + "entity": "twilightforest:snow_guardian", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/wolves.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/wolves.json new file mode 100644 index 0000000000..ab04191c41 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/wolves.json @@ -0,0 +1,25 @@ +{ + "name": "Wolves", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:hostile_wolf\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/wolves", + "sortnum": 2100, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/hostile_wolf", + "entity": "twilightforest:hostile_wolf", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/mist_wolf", + "entity": "twilightforest:mist_wolf", + "text": "things and stuff" + }, { + "type": "entity", + "advancement": "twilightforest:alt/entities/winter_wolf", + "entity": "twilightforest:winter_wolf", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/yeti.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/yeti.json new file mode 100644 index 0000000000..8bc1d93ea4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/entities/yeti.json @@ -0,0 +1,15 @@ +{ + "name": "Yeti", + "icon": "minecraft:spawn_egg:0{EntityTag:{id:\"twilightforest:yeti\"}}", + "category": "entities", + "advancement": "twilightforest:alt/entities/yeti", + "sortnum": 7020, + "pages": [ + { + "type": "entity", + "advancement": "twilightforest:alt/entities/yeti", + "entity": "twilightforest:yeti", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/sortnum_reference.txt b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/sortnum_reference.txt new file mode 100644 index 0000000000..c2da0701c2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/sortnum_reference.txt @@ -0,0 +1,214 @@ +How this works: + +Digit 'Thousands' is the main progression zone. + +-1000s are considered pre-TF or at the start. + 1000s are considered very beginning + 2000s are considered 'just under the surface' but no real progression started + + 3000s are Naga Courtyard and everything related + 4000s are Lich Tower and everything related + + 5000s are the Swamp and everything related + 6000s are the Dark Forest and everything related + 7000s are the Snow Forest and everything related + + 8000s are the highlands and everything that's around + + 9000s are the Final Plateau and the Final Castle and all that ends after that + +Digit 'Hundreds' act as "milestones" within the progression zones. +Digit 'Tens' act as "minor steps" within the milestones. +Digit 'Ones' act as minor sorting adjustments. + +If the enumeration of a sortnum is ambiguous whereever it comes before or after another thing, +they can be the same number and the book gui will sort alphabetically. + + +_______________________________________ + + +-1010 +portal.json + +-1000 +magic_map.json + + + +1000 +general_biomes.json + +1100 +animals.json +maps.json +foods.json +armors.json +tools.json +bows.json + +1200 +tc_aspects.json +tconstruct.json +ie_shaders.json + + + +2000 +hollow_hills.json +hedge_maze.json + +2100 +magic_trees.json +charms.json +uncrafting_table.json +kobold.json +druid_hut.json +undead.json +wolves.json +arthopods.json +goblins.json +moon_dial.json + +2200 +enchanted_forest.json + +2310 +crumble_horn.json +trophies.json + + + +3000 +naga_courtyard.json + +3010 +naga.json + + + +4000 +lich_tower.json + +4010 +death_tome.json + +4020 +lich.json + +4030 +scepters.json + + + +5000 +twilight_swamp.json + +5010 +labyrinth.json + +5020 +maze_slime.json +minotaur.json + +5030 +mazebreaker_pickaxe.json +minotaur_axes.json + +5040 +minoshroom.json + +5050 +smoking_block.json +fire_jet.json + +5060 +encased_smoking_block.json +encased_fire_jet.json + +5100 +hydra_lair.json + +5110 +hydra.json + +5120 +fiery_blood_tears.json + + + +6000 +dark_forest.json + +6010 +knight_stronghold.json + +6020 +phantom_knights.json + +6030 +phantom_armor.json + +6100 +dark_tower.json + +6110 +carminite.json +ghasts.json + +6120 +ur_ghast.json + + + +7000 +snow_forest.json + +7010 +yeti_caves.json + +7020 +yeti.json + +7030 +alpha_yeti.json + +7100 +glacier.json + +7110 +aurora_palace.json + +7120 +ice_bomb.json +ice_cores.json +glass_sword.json + +7130 +snow_queen.json + + + +8000 +troll_caves.json + +8010 +giant_blocks.json +magic_beans.json +troll.json + +8100 +giant_house.json + +8110 +giants.json + + + +9000 +final_castle.json + +9010 +adherent.json +harbinger_cube.json +castle_guardians.json \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/armors.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/armors.json new file mode 100644 index 0000000000..47c8f02bbc --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/armors.json @@ -0,0 +1,41 @@ +{ + "name": "Armors", + "icon": "twilightforest:ironwood_chestplate", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/armors", + "sortnum": 1100, + "pages": [ + { + "type": "text", + "text": "Armor Information" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/ironwood_armor_set", + "text": "Ironwood Armors" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/naga_armor_set", + "text": "Naga Scale Armors" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/steeleaf_armor_set", + "text": "Steeleaf Armors" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/fiery_armor_set", + "text": "Fiery Armors" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/knightmetal_armor_set", + "text": "Knightly Armors" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/arctic_armor_set", + "text": "Arctic Armors" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/yeti_armor_set", + "text": "Yeti Armors" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/bows.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/bows.json new file mode 100644 index 0000000000..1bdd5fa6f5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/bows.json @@ -0,0 +1,37 @@ +{ + "name": "Bows", + "icon": "twilightforest:seeker_bow", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/bows", + "sortnum": 1100, + "pages": [ + { + "type": "text", + "text": "Bow Information" + }, { + "type": "spotlight", + "title": "Ender Bow", + "item": "twilightforest:ender_bow", + "advancement": "twilightforest:alt/treasures/ender_bow", + "text": "things and stuff" + }, { + "type": "spotlight", + "title": "Ice Bow", + "item": "twilightforest:ice_bow", + "advancement": "twilightforest:alt/treasures/ice_bow", + "text": "things and stuff" + }, { + "type": "spotlight", + "title": "Seeker Bow", + "item": "twilightforest:seeker_bow", + "advancement": "twilightforest:alt/treasures/seeker_bow", + "text": "things and stuff" + }, { + "type": "spotlight", + "title": "Tri-bow", + "item": "twilightforest:triple_bow", + "advancement": "twilightforest:alt/treasures/triple_bow", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/carminite.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/carminite.json new file mode 100644 index 0000000000..851957ef04 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/carminite.json @@ -0,0 +1,15 @@ +{ + "name": "Carminite", + "icon": "twilightforest:carminite", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/carminite", + "sortnum": 6110, + "pages": [ + { + "type": "spotlight", + "title": "Carminite", + "item": "twilightforest:carminite", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/charms.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/charms.json new file mode 100644 index 0000000000..e2f9354e46 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/charms.json @@ -0,0 +1,37 @@ +{ + "name": "Charms", + "icon": "twilightforest:charm_of_keeping_3", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/charms", + "sortnum": 2100, + "pages": [ + { + "type": "text", + "text": "PLACEHOLDER General information about charms" + }, { + "flag": "!mod:baubles", + "type": "twilightforest:gallery", + "title": "Charms", + "item_list": "twilightforest:charm_of_keeping_1|twilightforest:charm_of_keeping_2|twilightforest:charm_of_keeping_3", + "text": "PLACEHOLDER Charms of Keeping keep various things even after death. THIS VERSION SHOWS UP WHEN BAUBLES DOESN'T EXIST" + }, { + "flag": "mod:baubles", + "type": "twilightforest:gallery", + "title": "Charms", + "item_list": "twilightforest:charm_of_keeping_1|twilightforest:charm_of_keeping_2|twilightforest:charm_of_keeping_3", + "text": "PLACEHOLDER Charms of Keeping keep various things even after death. THIS VERSION SHOWS UP WHEN BAUBLES EXISTS" + }, { + "flag": "!mod:baubles", + "type": "twilightforest:gallery", + "title": "Charms", + "item_list": "twilightforest:charm_of_life_1|twilightforest:charm_of_life_2", + "text": "Aside from it looking like a non-distinct trinket, it has a curious inscription etched into the back: \" \'Til death won't do us part.\"" + }, { + "flag": "mod:baubles", + "type": "twilightforest:gallery", + "title": "Charms", + "item_list": "twilightforest:charm_of_life_1|twilightforest:charm_of_life_2", + "text": "Aside from it looking like a non-distinct trinket, it has a curious inscription etched into the back: \" \'Til death won't do us part.\"$(br2)It's small enough to tuck away where one usually keeps their other baubles and bobs." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/crumble_horn.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/crumble_horn.json new file mode 100644 index 0000000000..e68a2df7c5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/crumble_horn.json @@ -0,0 +1,19 @@ +{ + "name": "Crumble Horn", + "icon": "twilightforest:crumble_horn", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/crumble_horn", + "sortnum": 2310, + "pages": [ + { + "title": "Crumble Horn", + "type": "twilightforest:headed_spotlight", + "item": "twilightforest:crumble_horn", + "text": "The quest for colored wool has come to an end, resulting in the ram gifting me a horn. It almost seems to have the form of an instrument though, perhaps I should try blowing on it." + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/crumble_horn_used", + "text": "The horn has ended up with more value than just a nice mantle piece it seems. When blown in the presence of rock and earth, the sound coming from it resonates in such a way that the material crumbles like snow before the sun. Perhaps there is a way this can be automated in a useful way." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/fiery_blood_tears.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/fiery_blood_tears.json new file mode 100644 index 0000000000..ea70f129fb --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/fiery_blood_tears.json @@ -0,0 +1,15 @@ +{ + "name": "Fiery Blood and Tears", + "icon": "twilightforest:fiery_blood", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/fiery_blood_tears", + "sortnum": 5120, + "pages": [ + { + "type": "twilightforest:gallery", + "title": "Fiery Blood and Tears", + "item_list": "twilightforest:fiery_blood|twilightforest:fiery_tears", + "text": "Small vials containing a hot substance. The burning essence within these vials are so hot, they can be infused into Iron to turn them into a fiery metal usable in crafting. It can be obtained from multiple powerful monsters." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/foods.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/foods.json new file mode 100644 index 0000000000..51e4f18c28 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/foods.json @@ -0,0 +1,45 @@ +{ + "name": "Meats, Meals, and Edibles", + "icon": "twilightforest:experiment_115:2", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/foods/any", + "sortnum": 1100, + "pages": [ + { + "type": "text", + "text": "Food glorious food" + }, { + "type": "spotlight", + "title": "Hydra Chop", + "item": "twilightforest:hydra_chop", + "advancement": "twilightforest:alt/treasures/foods/hydra_chop", + "text": "A filling meal with just a single Hydra Chop. Eating this potent meat greatly satiates hunger and provides temporary rapid healing. Fitting for those that have conquered such a mighty beast." + }, { + "type": "spotlight", + "title": "Maze Wafer", + "item": "twilightforest:maze_wafer", + "advancement": "twilightforest:alt/treasures/foods/maze_wafer", + "text": "Quick little snacks found in mazes. Though barely able to grant some saturation, it is perfect for exploring twisted landmarks when food becomes scarce." + }, { + "type": "text", + "title": "Meef", + "item": "twilightforest:cooked_meef", + "advancement": "twilightforest:alt/treasures/foods/meef", + "text": "Beef from a Minotaur. It's not very much if eaten raw, but cook it up and it is a valuable food item, rivalling the likes of Cooked Chicken." + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/foods/vension", + "text": "things and stuff" + }, { + "type": "spotlight", + "title": "Meef Stroganoff", + "item": "twilightforest:meef_stroganoff", + "advancement": "twilightforest:progress_labyrinth", + "text": "Nutritious and hearty. Eating Meef Stroganoff not only empowers the adventurer but also allows them to enter the Fire Swamp safely without suffering from the heat. How kind of the Minoshroom after all that effort?" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/foods/experiment_115", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/giant_blocks.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/giant_blocks.json new file mode 100644 index 0000000000..3baa2a0f95 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/giant_blocks.json @@ -0,0 +1,33 @@ +{ + "name": "Gigantic Blocks", + "icon": "twilightforest:giant_cobblestone", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/giant_blocks", + "sortnum": 8010, + "pages": [ + { + "type": "text", + "text": "Giant Blocks!" + }, { + "type": "spotlight", + "title": "Giant Cobblestone", + "item": "twilightforest:giant_cobblestone", + "text": "Giant Cobblestone!" + }, { + "type": "spotlight", + "title": "Giant Log", + "item": "twilightforest:giant_log", + "text": "That's a HUGE log, I'd love to have that in my real estate ;) ;)" + }, { + "type": "spotlight", + "title": "Giant Leaves", + "item": "twilightforest:giant_leaves", + "text": "Giant Leaves!" + }, { + "type": "spotlight", + "title": "Giant Obsidian", + "item": "twilightforest:giant_obsidian", + "text": "Giant Obsidian" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/glass_sword.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/glass_sword.json new file mode 100644 index 0000000000..4628c1a00e --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/glass_sword.json @@ -0,0 +1,30 @@ +{ + "name": "Glass Sword", + "icon": "twilightforest:glass_sword", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/glass_sword", + "sortnum": 7120, + "pages": [ + { + "title": "Glass Sword", + "type": "twilightforest:headed_spotlight", + "item": "twilightforest:glass_sword", + "text": "A stunning example of what a master craftsman is able to produce. Not only is the blade of this sabre unparalleled in sharpness beyond anything comparable, but its reflective and see-through surface also cascade the twilight through to cast snowflake like imagery on your surroundings. Truly, this is the height of craftsmanship." + }, { + "type": "text", + "advancement": "twilightforest:break_glass_sword", + "text": "Alas, with great beauty comes great cost. The Glass Sabre turns out to be nothing more than an exhibition of skill in crafting, rather than utility. Its sharpness is still unparalleled, but the brunt of the force is caused by glass shattering into thousands of tiny shards, it's actually rather barbaric as opposed to such a dignified-looking piece. This turned out to be nothing but a mere one-hit-wonder." + } + ], + + + + "pages_EXAMPLE_OF_EDITABLE": [ + { + "type": "twilightforest:editable", + "advancement_key": "twilightforest:break_glass_sword", + "locked" : "A stunning example of what a master craftsman is able to produce. Not only is the blade of this sabre unparalleled in sharpness beyond anything comparable, but its reflective and see-through surface also cascade the twilight through to cast snowflake like imagery on your surroundings. Truly, this is the height of craftsmanship.", + "unlocked": "A stunning example of what a master craftsman is able to produce. Not only is the blade of this sabre unparalleled in sharpness beyond anything comparable, but its reflective and see-through surface also cascade the twilight through to cast snowflake like imagery on your surroundings. Truly, this is the height of craftsmanship.$(br2)Alas, with great beauty comes great cost. The Glass Sabre turns out to be nothing more than an exhibition of skill in crafting, rather than utility. Its sharpness is still unparalleled, but the brunt of the force is caused by glass shattering into thousands of tiny shards, it's actually rather barbaric as opposed to such a dignified-looking piece. This turned out to be nothing but a mere one-hit-wonder." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/ice_bomb.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/ice_bomb.json new file mode 100644 index 0000000000..ae24157c9d --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/ice_bomb.json @@ -0,0 +1,15 @@ +{ + "name": "Ice Bomb", + "icon": "twilightforest:ice_bomb", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/ice_bomb", + "sortnum": 7120, + "pages": [ + { + "type": "spotlight", + "title": "Ice Bomb", + "item": "twilightforest:ice_bomb", + "text": "The Ice Bomb is the best thing ever. It's so chill, and so cool! It's literally da bomb" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/ie_shaders.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/ie_shaders.json new file mode 100644 index 0000000000..f9176e3658 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/ie_shaders.json @@ -0,0 +1,15 @@ +{ + "name": "[IE] Shaders", + "icon": "immersiveengineering:shader_bag{rarity:\"TWILIGHT\"}", + "laggy_icon": "immersiveengineering:revolver:0{\"IE:Shader\":{id:\"twilightforest:shader\",Count:1,tag:{shader_type:\"Twilight\"},Damage:0},upgrades:{electro:1b,melee:6.0,bullets:6}}", + "category": "treasures", + "flag": "mod:immersiveengineering", + "advancement": "twilightforest:alt/compat/ie_shaders", + "sortnum": 1200, + "pages": [ + { + "type": "text", + "text": "Immersive Engineering Shaders Info" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/magic_beans.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/magic_beans.json new file mode 100644 index 0000000000..6bff27fb51 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/magic_beans.json @@ -0,0 +1,20 @@ +{ + "name": "Magic Beans", + "icon": "twilightforest:magic_beans", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/magic_beans", + "sortnum": 8010, + "pages": [ + { + "title": "Magic Beans", + "type": "twilightforest:headed_spotlight", + "item": "twilightforest:magic_beans", + "text": "These beans are huge! It is fairly obvious that beans this large wont be properly accommodated by just any regular soil, if they're found here then surely their natural habitat must be around these highlands as well." + }, { + "type": "spotlight", + "advancement": "twilightforest:alt/treasures/magic_beanstalk", + "item": "twilightforest:huge_stalk", + "text": "The beans instantly reacted to to the incredible fertility of the soil, the result is rather spectacular. The beanstalk has grown in a way that is reminiscent of a rudimentary staircase, it feels as if it's whispering me to push on and upwards. I fear nothing when I do nothing wrong, and so I toddle on my way and sing a merry song." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/magic_trees.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/magic_trees.json new file mode 100644 index 0000000000..5b574a97e6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/magic_trees.json @@ -0,0 +1,29 @@ +{ + "name": "Magical Trees", + "icon": "twilightforest:twilight_sapling:4", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/magic_trees", + "sortnum": 2100, + "pages": [ + { + "type": "text", + "text": "Magic Trees can be found in dungeons on top of big trees inside the lootchest" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/tree_of_time", + "text": "Tree of Time" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/tree_of_transformation", + "text": "Tree of Transformation" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/tree_of_mining", + "text": "Miner's Tree" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/tree_of_sorting", + "text": "Sorting Tree" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/maps.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/maps.json new file mode 100644 index 0000000000..246f7753e5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/maps.json @@ -0,0 +1,31 @@ +{ + "name": "Maps", + "icon": "twilightforest:magic_map", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/maps", + "sortnum": 1100, + "pages": [ + { + "type": "text", + "text": "Map information" + }, { + "type": "spotlight", + "title": "Magic Map", + "item": "twilightforest:magic_map", + "advancement": "twilightforest:alt/treasures/treasures/magic_map", + "text": "Magic Map helps you find biomes and structures" + }, { + "type": "spotlight", + "title": "Maze Map", + "item": "twilightforest:maze_map", + "advancement": "twilightforest:alt/treasures/treasures/maze_map", + "text": "Maze Map helps you see maze layouts" + }, { + "type": "spotlight", + "title": "Ore Map", + "item": "twilightforest:ore_map", + "advancement": "twilightforest:alt/treasures/treasures/ore_map", + "text": "Ore Map helps you see what's underground, especially those ores" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/mazebreaker_pickaxe.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/mazebreaker_pickaxe.json new file mode 100644 index 0000000000..a6ea01946e --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/mazebreaker_pickaxe.json @@ -0,0 +1,15 @@ +{ + "name": "Mazebreaker", + "icon": "twilightforest:mazebreaker_pickaxe", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/mazebreaker_pickaxe", + "sortnum": 5030, + "pages": [ + { + "type": "spotlight", + "title": "Mazebreaker", + "item": "twilightforest:mazebreaker_pickaxe:0{ench:[{lvl:4s,id:32s},{lvl:3s,id:34s},{lvl:2s,id:35s}]}", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/minotaur_axes.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/minotaur_axes.json new file mode 100644 index 0000000000..fbf2f13ff3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/minotaur_axes.json @@ -0,0 +1,25 @@ +{ + "name": "Minotaur Axes", + "icon": "twilightforest:minotaur_axe", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/minotaur_axes", + "sortnum": 5030, + "pages": [ + { + "type": "text", + "text": "Finely forged weapons wielded by Minotaurs and the Minoshroom. They feel like any old axe, but the design of these axes are strange. Though light to hold, these axes feel weighty while running with them." + }, { + "type": "spotlight", + "title": "Golden Minotaur Axe", + "item": "twilightforest:minotaur_axe_gold", + "advancement": "twilightforest:alt/treasures/minotaur_axe_gold", + "text": "Sharp, powerful, but incredibly frail. Only the most worthy of Minotaurs have these weapons." + }, { + "type": "spotlight", + "title": "Diamond Minotaur Axe", + "item": "twilightforest:minotaur_axe", + "advancement": "twilightforest:alt/treasures/minotaur_axe_diamond", + "text": "A finely forged weapon adorned with the strength of Diamond. This powerful weapon is the choice of the Minoshroom, fitting for a great beast." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/moon_dial.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/moon_dial.json new file mode 100644 index 0000000000..ac81b60b64 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/moon_dial.json @@ -0,0 +1,15 @@ +{ + "name": "Moon Dial", + "icon": "twilightforest:moon_dial", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/moon_dial", + "sortnum": 2101, + "pages": [ + { + "type": "spotlight", + "title": "Moon Dial", + "item": "twilightforest:moon_dial", + "text": "It reads the moon." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/phantom_armor.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/phantom_armor.json new file mode 100644 index 0000000000..f25168e23d --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/phantom_armor.json @@ -0,0 +1,20 @@ +{ + "name": "Phantom Armor", + "icon": "twilightforest:phantom_helmet", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/phantom_armor_set", + "sortnum": 6030, + "pages": [ + { + "title": "Phantom Armor", + "type": "twilightforest:headed_spotlight2", + "item0": "twilightforest:phantom_helmet", + "item1": "twilightforest:phantom_chestplate", + "text": "It's strange, but from simply looking at it, it's clear as twilight this is no ordinary helm. The material seems metallic in nature, but feels lukewarm to the touch and it's almost as if it resonates with its surroundings." + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/phantom_armor_worn", + "text": "Quite apparent despite the eerie nature of the piece is that the quality of the helm is superb, no doubt offering great protection from any physical harm. When this gear is worn it gives off a strange sense of familiarity, something that feels like an urge and refusal to let go at all costs. Sometimes, just out of audible reach, you swear on hearing malevolent whispers from what almost sounds like yourself." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/scepters.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/scepters.json new file mode 100644 index 0000000000..9fc567c021 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/scepters.json @@ -0,0 +1,37 @@ +{ + "name": "Scepters", + "icon": "twilightforest:twilight_scepter", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/scepters", + "sortnum": 4030, + "pages": [ + { + "type": "text", + "text": "It seems that Lich I had fought utilized a few different scepters. When I had slain it, one of its scepters dropped. Perhaps if I fought it multiple times I could retrieve all of its different scepters." + }, { + "type": "spotlight", + "title": "Twilight Scepter", + "item": "twilightforest:twilight_scepter", + "advancement": "twilightforest:alt/treasures/twilight_scepter", + "text": "Shoots orbs." + }, { + "type": "spotlight", + "title": "Twilight Scepter", + "item": "twilightforest:lifedrain_scepter", + "advancement": "twilightforest:alt/treasures/lifedrain_scepter", + "text": "Drains health." + }, { + "type": "spotlight", + "title": "Twilight Scepter", + "item": "twilightforest:zombie_scepter", + "advancement": "twilightforest:alt/treasures/zombie_scepter", + "text": "Summons monsters from beyond the grave to aid you in combat." + }, { + "type": "spotlight", + "title": "Twilight Scepter", + "item": "twilightforest:shield_scepter", + "advancement": "twilightforest:alt/treasures/shield_scepter", + "text": "Generates a temporary warding aura." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tc_aspects.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tc_aspects.json new file mode 100644 index 0000000000..218431bc19 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tc_aspects.json @@ -0,0 +1,14 @@ +{ + "name": "[TC6] Aspects", + "icon": "thaumcraft:jar_normal:0{Aspects:[{amount:250,key:\"praecantatio\"}]}", + "category": "treasures", + "flag": "mod:thaumcraft", + "advancement": "twilightforest:alt/compat/tc_aspects", + "sortnum": 1200, + "pages": [ + { + "type": "text", + "text": "Thaumcraft Info about TF stuffs having aspects" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tconstruct.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tconstruct.json new file mode 100644 index 0000000000..ec12a466de --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tconstruct.json @@ -0,0 +1,14 @@ +{ + "name": "[TCon] Tools", + "icon": "tconstruct:large_plate{Material:\"fierymetal\"}", + "category": "treasures", + "flag": "mod:tconstruct", + "advancement": "twilightforest:alt/compat/tconstruct", + "sortnum": 1200, + "pages": [ + { + "type": "text", + "text": "Tinker's Construct info about TF Tools" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tools.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tools.json new file mode 100644 index 0000000000..9276f2cc90 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/tools.json @@ -0,0 +1,41 @@ +{ + "name": "Tools", + "icon": "twilightforest:ironwood_pickaxe", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/tools", + "sortnum": 1100, + "pages": [ + { + "type": "text", + "text": "This world is magical, I infer that using materials from this world in crafting may potentially result in tools with inherent magical abilities that enchanting would normally offer." + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/ironwood_tool_set", + "text": "Ironwood Tools" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/steeleaf_tool_set", + "text": "Steeleaf Tools" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/fiery_tool_set", + "text": "Fiery Tools" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/fiery_tool_set", + "text": "Fiery Tools" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/knightmetal_tool_set", + "text": "Knightly Tools" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/ice_sword", + "text": "Ice Sword" + }, { + "type": "text", + "advancement": "twilightforest:alt/treasures/giant_tool_set", + "text": "Giant Tools" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/trophies.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/trophies.json new file mode 100644 index 0000000000..b37e2620fb --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/trophies.json @@ -0,0 +1,57 @@ +{ + "name": "Trophies", + "icon": "twilightforest:trophy_pedestal", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/trophies", + "sortnum": 2310, + "pages": [ + { + "type": "text", + "text": "Trophy Info" + }, { + "type": "text", + "advancement": "twilightforest:progress_trophy_pedestal", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:quest_ram", + "text": "The ram — grateful for the feast — has bestowed the gift of a... replica of its head. Sometimes, it's better to not look into these kind of things. The trophy can be placed to showcase your appreciation of fine dining wool and even worn as a helm, truly a satisfying reward for a job well done... Probably." + }, { + "type": "text", + "advancement": "twilightforest:progress_naga", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:progress_lich", + "text": "things and stuff" + }, { + "type": "spotlight", + "title": "Minoshroom Trophy", + "item": "twilightforest:trophy:6", + "advancement": "twilightforest:progress_labyrinth", + "text": "The trophy of the Minoshroom, bestowed to those who have bested the beast of the Labyrinth. Though iron-plated, it is still worth the well-fought battle of the brawn, or brain versus brawn, however the Minoshroom was slain." + }, { + "type": "spotlight", + "title": "Hydra Trophy", + "item": "twilightforest:trophy:2", + "advancement": "twilightforest:progress_hydra", + "text": "A trophy depicting one of the many heads of the Hydra. Though slaying a head only creates more, this reward from a heated battle is proof that a beast with regenerating heads can be slain. Seems like the mouth opens when there's no solid surface beneath the Trophy." + }, { + "type": "text", + "advancement": "twilightforest:progress_knights", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:progress_ur_ghast", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:progress_yeti", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:progress_glacier", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/uncrafting_table.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/uncrafting_table.json new file mode 100644 index 0000000000..fc390a58b6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/treasures/uncrafting_table.json @@ -0,0 +1,15 @@ +{ + "name": "Uncrafting Table", + "icon": "twilightforest:uncrafting_table", + "category": "treasures", + "advancement": "twilightforest:alt/treasures/uncrafting_table", + "sortnum": 2100, + "pages": [ + { + "type": "spotlight", + "title": "Uncrafting Table", + "item": "twilightforest:uncrafting_table", + "text": "Uncrafty" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/dark_forest.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/dark_forest.json new file mode 100644 index 0000000000..4748ea85a5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/dark_forest.json @@ -0,0 +1,17 @@ +{ + "name": "Dark Forest", + "icon": "twilightforest:twilight_sapling:3", + "category": "biomes", + "advancement": "twilightforest:alt/biomes/dark_forest", + "sortnum": 6000, + "pages": [ + { + "type": "text", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/dark_forest_center", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/enchanted_forest.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/enchanted_forest.json new file mode 100644 index 0000000000..018cb9db3b --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/enchanted_forest.json @@ -0,0 +1,13 @@ +{ + "name": "Enchanted Forest", + "icon": "twilightforest:twilight_sapling:9", + "category": "biomes", + "advancement": "twilightforest:alt/biomes/enchanted_forest", + "sortnum": 2200, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/general_biomes.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/general_biomes.json new file mode 100644 index 0000000000..bc69f2084a --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/general_biomes.json @@ -0,0 +1,45 @@ +{ + "name": "General Biomes", + "icon": "twilightforest:magic_map_empty", + "category": "biomes", + "advancement": "twilightforest:alt/biomes/general_biomes", + "sortnum": 1000, + "pages": [ + { + "type": "text", + "text": "General Biome Info. These biomes aren't really special." + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/twilight_forest", + "text": "Twilight Forest" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/firefly_forest", + "text": "Firefly Forest" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/twilight_clearing", + "text": "Twilight Clearing" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/oak_savannah", + "text": "Oak Savannah" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/dense_twilight_forest", + "text": "Dense Twilight Forest" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/mushroom_forest", + "text": "Mushroom Forest" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/deep_mushroom_forest", + "text": "Dense Mushroom Forest" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/twilight_lake", + "text": "It is a mystery what these Lakes contain. There seems to be nothing special about these lakes, apart from its abundance of water. It is rumored that one day an island might appear in the lakes. Who knows what it will hold?" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/glacier.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/glacier.json new file mode 100644 index 0000000000..c1d1a446c2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/glacier.json @@ -0,0 +1,13 @@ +{ + "name": "Glacier", + "icon": "minecraft:packed_ice", + "category": "biomes", + "advancement": "twilightforest:alt/biomes/twilight_glacier", + "sortnum": 7100, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/snow_forest.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/snow_forest.json new file mode 100644 index 0000000000..3ff65abeec --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/snow_forest.json @@ -0,0 +1,13 @@ +{ + "name": "Snow Forest", + "icon": "minecraft:snow", + "category": "biomes", + "advancement": "twilightforest:alt/biomes/snowy_forest", + "sortnum": 7000, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/twilight_swamp.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/twilight_swamp.json new file mode 100644 index 0000000000..3b056ecc00 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/biomes/twilight_swamp.json @@ -0,0 +1,17 @@ +{ + "name": "Swamp", + "icon": "twilightforest:twilight_sapling:2", + "category": "biomes", + "advancement": "twilightforest:alt/biomes/twilight_swamp", + "sortnum": 5000, + "pages": [ + { + "type": "text", + "text": "A large, damp expanse of the Twilight Forest resembling a Swamp. This place is swarming with Mosquitoes, and trespassing will sicken any adventurer with an illness. Clearing this place requires one of the Twilight Lich's magical Scepters in order to repel the Mosquitoes. There are mounds in this biome, perhaps indicating a presence of landmarks?" + }, { + "type": "text", + "advancement": "twilightforest:alt/biomes/fire_swamp", + "text": "In the center of the Twilight Swamp is the Fire Swamp. This rather temperate biome has high abundance of Lava, and jets that erupt smoke and flames, all spread across a rusty red landscape. Because of the heat, adventurers need good nutrition in order to pass into the biome. It is said that a terrific monster resides in the remains of a Large Hollow Hill." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/magic_map.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/magic_map.json new file mode 100644 index 0000000000..6404233383 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/magic_map.json @@ -0,0 +1,13 @@ +{ + "name": "Magic Map", + "icon": "twilightforest:magic_map", + "category": "world", + "advancement": "twilightforest:root", + "sortnum": -1000, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/aurora_palace.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/aurora_palace.json new file mode 100644 index 0000000000..d49c10e91f --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/aurora_palace.json @@ -0,0 +1,13 @@ +{ + "name": "Aurora Palace", + "icon": "twilightforest:miniature_structure:12", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/ice_tower", + "sortnum": 7110, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/dark_tower.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/dark_tower.json new file mode 100644 index 0000000000..988d032441 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/dark_tower.json @@ -0,0 +1,13 @@ +{ + "name": "Dark Tower", + "icon": "twilightforest:miniature_structure:10", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/dark_tower", + "sortnum": 6100, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/final_castle.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/final_castle.json new file mode 100644 index 0000000000..153ca36426 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/final_castle.json @@ -0,0 +1,13 @@ +{ + "name": "Final Tower", + "icon": "twilightforest:miniature_structure:14", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/final_castle", + "sortnum": 9001, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/giant_house.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/giant_house.json new file mode 100644 index 0000000000..e7e42e1b61 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/giant_house.json @@ -0,0 +1,13 @@ +{ + "name": "Giant House", + "icon": "twilightforest:miniature_structure:13", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/giant_cloud", + "sortnum": 8100, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hedge_maze.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hedge_maze.json new file mode 100644 index 0000000000..3412a6b538 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hedge_maze.json @@ -0,0 +1,13 @@ +{ + "name": "Hedge Maze", + "icon": "twilightforest:miniature_structure:1", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/hedge_maze", + "sortnum": 2000, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hollow_hills.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hollow_hills.json new file mode 100644 index 0000000000..37ec82c2d3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hollow_hills.json @@ -0,0 +1,22 @@ +{ + "name": "Hollow Hills", + "icon": "twilightforest:miniature_structure:2", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/hollow_hills", + "sortnum": 2000, + "pages": [ + { + "type": "text", + "advancement": "twilightforest:alt/major_landmarks/small_hollow_hill", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:alt/major_landmarks/medium_hollow_hill", + "text": "things and stuff" + }, { + "type": "text", + "advancement": "twilightforest:alt/major_landmarks/large_hollow_hill", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hydra_lair.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hydra_lair.json new file mode 100644 index 0000000000..75c6b1e577 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/hydra_lair.json @@ -0,0 +1,13 @@ +{ + "name": "Hydra Lair", + "icon": "twilightforest:miniature_structure:8", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/hydra_lair", + "sortnum": 5100, + "pages": [ + { + "type": "text", + "text": "Deep within the Fire Swamp is the Hydra Lair: a Large Hollow Hill converted into the home of the Hydra. Still decorated with various rare ores, it's the perfect place to collect some treasures, with the exception of a giant mythical reptile standing in the midst of the treasure." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/knight_stronghold.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/knight_stronghold.json new file mode 100644 index 0000000000..7f3ef5993e --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/knight_stronghold.json @@ -0,0 +1,13 @@ +{ + "name": "Knight Stronghold", + "icon": "twilightforest:miniature_structure:9", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/knight_stronghold", + "sortnum": 6010, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/labyrinth.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/labyrinth.json new file mode 100644 index 0000000000..c8b152438f --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/labyrinth.json @@ -0,0 +1,23 @@ +{ + "name": "Labyrinth", + "icon": "twilightforest:miniature_structure:7", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/labyrinth", + "sortnum": 5010, + "pages": [ + { + "type": "text", + "text": "Large, sprawling mazes that can be found beneath the Twilight Swamp biome. Locating one of these landmarks requires a good eye for terrain, as the entrance is hidden inside a hill the size of a Small Hollow Hill." + }, + { + "type": "text", + "advancement": "twilightforest:alt/entities/minoshroom", + "text": "With some dedication and some navigation, an adventurer may come across the lair of the Minoshroom. Locked behind wooden fences and surrounded in fungus appears to be some chests with some loot, guarded by the beast of the Labyrinth." + }, + { + "type": "text", + "advancement": "twilightforest:alt/treasures/mazebreaker_pickaxe", + "text": "Hidden deep within the walls of the Labyrinth appears to be a small, rigged vault. Careful adventurers can gather some rare, valuable materials, and a coveted Mazebreaker. Such find is quite the reward, but care must be exercised." + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/lich_tower.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/lich_tower.json new file mode 100644 index 0000000000..0360f307c2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/lich_tower.json @@ -0,0 +1,13 @@ +{ + "name": "Lich Tower", + "icon": "twilightforest:miniature_structure:6", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/lich_tower", + "sortnum": 4000, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/naga_courtyard.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/naga_courtyard.json new file mode 100644 index 0000000000..7965c1543a --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/naga_courtyard.json @@ -0,0 +1,13 @@ +{ + "name": "Naga Courtyard", + "icon": "twilightforest:miniature_structure:5", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/naga_courtyard", + "sortnum": 3000, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/troll_caves.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/troll_caves.json new file mode 100644 index 0000000000..dca519ba5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/troll_caves.json @@ -0,0 +1,13 @@ +{ + "name": "Troll Caves", + "icon": "twilightforest:miniature_structure:13", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/troll_lairs", + "sortnum": 8000, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/yeti_caves.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/yeti_caves.json new file mode 100644 index 0000000000..97d4c16dbb --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/major_landmarks/yeti_caves.json @@ -0,0 +1,13 @@ +{ + "name": "Yeti Caves", + "icon": "twilightforest:miniature_structure:11", + "category": "major_landmarks", + "advancement": "twilightforest:alt/major_landmarks/yeti_lairs", + "sortnum": 7010, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/minor_landmarks/druid_hut.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/minor_landmarks/druid_hut.json new file mode 100644 index 0000000000..28123c885d --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/minor_landmarks/druid_hut.json @@ -0,0 +1,12 @@ +{ + "name": "Druid Hut", + "icon": "minecraft:golden_hoe", + "category": "minor_landmark", + "sortnum": 2100, + "pages": [ + { + "type": "text", + "text": "things and stuff" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/portal.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/portal.json new file mode 100644 index 0000000000..f6acc50aae --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/entries/world/portal.json @@ -0,0 +1,62 @@ +{ + "name": "Building a Portal", + "icon": "twilightforest:miniature_structure:0", + "category": "world", + "sortnum": -1010, + "pages": [ + { + "type": "multiblock", + "name": "Twilight Portal", + "text": "Once you finish digging and planting the formation, fill it with water!", + "multiblock": { + "pattern": [ + [ " FF ", "FAAF", "FAAF", " FF " ], + [ " GG ", "G0WG", "GWWG", " GG " ], + [ " ", " DD ", " DD ", " " ] + ], + "mapping": { + " ": "ANY", + "A": "AIR", + "0": "minecraft:water", + "W": "minecraft:water", + "F": "minecraft:red_flower", + "G": "minecraft:grass", + "D": "minecraft:dirt" + }, + "symmetrical": true, + "offset" : [0, 1, 0], + "view_offset": [0, 0, 0] + } + }, { + "type": "spotlight", + "title": "Activation Item", + "item": "minecraft:diamond", + "text": "Drop a diamond into the water!" + }, { + "type": "multiblock", + "name": "Completed Twilight Portal", + "text": "If you see the purple swirls, hop right in!", + "enable_visualize": false, + "advancement": "twilightforest:root", + "multiblock": { + "pattern": [ + [ " FF ", "F0AF", "FAAF", " FF " ], + [ " GG ", "GWWG", "GWWG", " GG " ], + [ " ", " DD ", " DD ", " " ] + ], + "mapping": { + " ": "ANY", + "A": "AIR", + "0": "AIR", + "W": "twilightforest:twilight_portal", + "F": "minecraft:red_flower", + "G": "minecraft:grass", + "D": "minecraft:dirt" + }, + "symmetrical": true, + "offset" : [0, 1, 0], + "view_offset": [0, 0, 0] + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/editable.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/editable.json new file mode 100644 index 0000000000..82bf69101b --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/editable.json @@ -0,0 +1,11 @@ +{ + "components": [ + { + "type": "custom", + "class": "twilightforest.compat.patchouli.RevisableComponent", + "advancement_key": "#advancement_key", + "locked_text": "#locked", + "unlocked_text": "#unlocked" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/gallery.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/gallery.json new file mode 100644 index 0000000000..3f94b722d5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/gallery.json @@ -0,0 +1,14 @@ +{ + "components": [ + { + "type": "custom", + "class": "twilightforest.compat.patchouli.GalleryComponent", + "table_x": 6, + "items": "#item_list" + }, { + "type": "text", + "text": "#text", + "y": 18 + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_gallery.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_gallery.json new file mode 100644 index 0000000000..13550b70ab --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_gallery.json @@ -0,0 +1,24 @@ +{ + "components": [ + { + "type": "header", + "text": "#title", + "x": -1, + "y": -1 + }, { + "type": "separator", + "x": -1, + "y": -1 + }, { + "type": "custom", + "class": "twilightforest.compat.patchouli.GalleryComponent", + "table_x": 6, + "items": "#item_list", + "y": 18 + }, { + "type": "text", + "text": "#text", + "y": 36 + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_spotlight.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_spotlight.json new file mode 100644 index 0000000000..0149da1d36 --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_spotlight.json @@ -0,0 +1,24 @@ +{ + "components": [ + { + "type": "header", + "text": "#title", + "x": -1, + "y": -1 + }, { + "type": "separator", + "x": -1, + "y": -1 + }, { + "type": "item", + "item": "#item", + "framed": "true", + "x": 50, + "y": 20 + }, { + "type": "text", + "text": "#text", + "y": 40 + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_spotlight2.json b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_spotlight2.json new file mode 100644 index 0000000000..dde61eb4da --- /dev/null +++ b/src/main/resources/assets/twilightforest/patchouli_books/guide/en_us/templates/headed_spotlight2.json @@ -0,0 +1,30 @@ +{ + "components": [ + { + "type": "header", + "text": "#title", + "x": -1, + "y": -1 + }, { + "type": "separator", + "x": -1, + "y": -1 + }, { + "type": "item", + "item": "#item0", + "framed": "true", + "x": 38, + "y": 20 + }, { + "type": "item", + "item": "#item1", + "framed": "true", + "x": 62, + "y": 20 + }, { + "type": "text", + "text": "#text", + "y": 40 + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/_constants.json b/src/main/resources/assets/twilightforest/recipes/_constants.json new file mode 100644 index 0000000000..647e9f3548 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/_constants.json @@ -0,0 +1,156 @@ +[ + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "blockDiamond" + }, + "name": "BLOCKDIAMOND" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "blockGold" + }, + "name": "BLOCKGOLD" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "blockIron" + }, + "name": "BLOCKIRON" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "dustGlowstone" + }, + "name": "DUSTGLOWSTONE" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "dustRedstone" + }, + "name": "DUSTREDSTONE" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "enderpearl" + }, + "name": "ENDERPEARL" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "ingotFiery" + }, + "name": "INGOTFIERY" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "ingotIron" + }, + "name": "INGOTIRON" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "ingotIronwood" + }, + "name": "INGOTIRONWOOD" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "ingotKnightmetal" + }, + "name": "INGOTKNIGHTMETAL" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "ingotSteeleaf" + }, + "name": "INGOTSTEELEAF" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "carminite" + }, + "name": "CARMINITE" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "furArctic" + }, + "name": "FURARCTIC" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "ingotFiery" + }, + "name": "INGOTFIERY" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "nuggetGold" + }, + "name": "NUGGETGOLD" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "nuggetIron" + }, + "name": "NUGGETIRON" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "oreRedstone" + }, + "name": "OREREDSTONE" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "paper" + }, + "name": "PAPER" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "stickWood" + }, + "name": "STICKWOOD" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "workbench" + }, + "name": "WORKBENCH" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "stone" + }, + "name": "STONE" + }, + { + "ingredient": { + "type": "forge:ore_dict", + "ore": "brickStone" + }, + "name": "STONEBRICK" + } +] \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/_factories.json b/src/main/resources/assets/twilightforest/recipes/_factories.json new file mode 100644 index 0000000000..155c68f1c8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/_factories.json @@ -0,0 +1,5 @@ +{ + "conditions": { + "uncrafting_enabled": "twilightforest.item.recipe.ConditionFactories$UncraftingEnabled" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/aurora_pillar.json b/src/main/resources/assets/twilightforest/recipes/aurora_pillar.json new file mode 100644 index 0000000000..5901767e10 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/aurora_pillar.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:aurora_pillar", + "count": 2 + }, + "pattern": [ + "#", + "#" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:aurora_block" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/aurora_slab.json b/src/main/resources/assets/twilightforest/recipes/aurora_slab.json new file mode 100644 index 0000000000..39bd7f9a2b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/aurora_slab.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:aurora_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:aurora_block" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castle_paver.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_paver.json new file mode 100644 index 0000000000..8be56efcb3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_paver.json @@ -0,0 +1,32 @@ +{ + "result": { + "item": "twilightforest:castle_brick", + "data": 5, + "count": 4 + }, + "pattern": [ + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:castle_brick", + "data": 0 + }, + { + "item": "twilightforest:castle_brick", + "data": 1 + }, + { + "item": "twilightforest:castle_brick", + "data": 2 + }, + { + "item": "twilightforest:castle_brick", + "data": 4 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_bold.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_bold.json new file mode 100644 index 0000000000..696d5c1941 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_bold.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:castle_pillar", + "data": 2, + "count": 4 + }, + "pattern": [ + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:castle_brick", + "data": 5 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_bold_none.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_bold_none.json new file mode 100644 index 0000000000..2ae5ae1cd1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_bold_none.json @@ -0,0 +1,24 @@ +{ + "result": { + "item": "twilightforest:castle_pillar", + "data": 3, + "count": 4 + }, + "pattern": [ + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:castle_pillar", + "data": 2 + }, + { + "item": "twilightforest:castle_pillar", + "data": 3 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_encased.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_encased.json new file mode 100644 index 0000000000..fb00c0e529 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_encased.json @@ -0,0 +1,50 @@ +{ + "result": { + "item": "twilightforest:castle_pillar", + "data": 0, + "count": 6 + }, + "pattern": [ + "#H#", + "#H#" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:castle_brick", + "data": 0 + }, + { + "item": "twilightforest:castle_brick", + "data": 1 + }, + { + "item": "twilightforest:castle_brick", + "data": 2 + }, + { + "item": "twilightforest:castle_brick", + "data": 4 + }, + { + "item": "twilightforest:castle_brick", + "data": 5 + } + ], + "H": [ + { + "item": "twilightforest:castle_pillar", + "data": 0 + }, + { + "item": "twilightforest:castle_pillar", + "data": 1 + }, + { + "item": "twilightforest:castle_brick", + "data": 3 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_encased_none.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_encased_none.json new file mode 100644 index 0000000000..ab3b941b5c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castle_pillar_encased_none.json @@ -0,0 +1,24 @@ +{ + "result": { + "item": "twilightforest:castle_pillar", + "data": 1, + "count": 4 + }, + "pattern": [ + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:castle_pillar", + "data": 0 + }, + { + "item": "twilightforest:castle_pillar", + "data": 1 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_bold.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_bold.json new file mode 100644 index 0000000000..0662c3881b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_bold.json @@ -0,0 +1,25 @@ +{ + "result": { + "item": "twilightforest:castle_stairs", + "data": 8, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:castle_pillar", + "data": 2 + }, + { + "item": "twilightforest:castle_pillar", + "data": 3 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_bold_reverse.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_bold_reverse.json new file mode 100644 index 0000000000..ce213b3bf3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_bold_reverse.json @@ -0,0 +1,26 @@ +{ + "result": { + "item": "twilightforest:castle_pillar", + "data": 2, + "count": 3 + }, + "ingredients": [ + { + "item": "twilightforest:castle_stairs", + "data": 8 + }, + { + "item": "twilightforest:castle_stairs", + "data": 8 + }, + { + "item": "twilightforest:castle_stairs", + "data": 8 + }, + { + "item": "twilightforest:castle_stairs", + "data": 8 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_brick.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_brick.json new file mode 100644 index 0000000000..150640f65f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_brick.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:castle_stairs_brick", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [{ + "item": "twilightforest:castle_brick", + "data": 0 + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_brick_reverse.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_brick_reverse.json new file mode 100644 index 0000000000..bb097bd91f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_brick_reverse.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:castle_brick", + "data": 0, + "count": 3 + }, + "ingredients": [ { + "item": "twilightforest:castle_stairs_brick", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_brick", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_brick", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_brick", + "data": 0 + } ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_cracked.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_cracked.json new file mode 100644 index 0000000000..c44ac04c55 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_cracked.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:castle_stairs_cracked", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:castle_brick", + "data": 2 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_cracked_reverse.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_cracked_reverse.json new file mode 100644 index 0000000000..41c65010b1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_cracked_reverse.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:castle_brick", + "data": 2, + "count": 3 + }, + "ingredients": [ { + "item": "twilightforest:castle_stairs_cracked", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_cracked", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_cracked", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_cracked", + "data": 0 + } ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_encased.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_encased.json new file mode 100644 index 0000000000..afde69716e --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_encased.json @@ -0,0 +1,25 @@ +{ + "result": { + "item": "twilightforest:castle_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:castle_pillar", + "data": 0 + }, + { + "item": "twilightforest:castle_pillar", + "data": 1 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_encased_reverse.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_encased_reverse.json new file mode 100644 index 0000000000..b01e120cb4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_encased_reverse.json @@ -0,0 +1,26 @@ +{ + "result": { + "item": "twilightforest:castle_pillar", + "data": 0, + "count": 3 + }, + "ingredients": [ + { + "item": "twilightforest:castle_stairs", + "data": 0 + }, + { + "item": "twilightforest:castle_stairs", + "data": 0 + }, + { + "item": "twilightforest:castle_stairs", + "data": 0 + }, + { + "item": "twilightforest:castle_stairs", + "data": 0 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_mossy.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_mossy.json new file mode 100644 index 0000000000..b56078c930 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_mossy.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:castle_stairs_mossy", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:castle_brick", + "data": 4 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_mossy_reverse.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_mossy_reverse.json new file mode 100644 index 0000000000..98a999ec5a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_mossy_reverse.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:castle_brick", + "data": 4, + "count": 3 + }, + "ingredients": [ { + "item": "twilightforest:castle_stairs_mossy", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_mossy", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_mossy", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_mossy", + "data": 0 + } ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_worn.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_worn.json new file mode 100644 index 0000000000..01326c45f5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_worn.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:castle_stairs_worn", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:castle_brick", + "data": 1 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_worn_reverse.json b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_worn_reverse.json new file mode 100644 index 0000000000..c8f1729f14 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/castleblock/castleblock_stairs_worn_reverse.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:castle_brick", + "data": 1, + "count": 3 + }, + "ingredients": [ { + "item": "twilightforest:castle_stairs_worn", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_worn", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_worn", + "data": 0 + }, { + "item": "twilightforest:castle_stairs_worn", + "data": 0 + } ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/arctic_block.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/arctic_block.json new file mode 100644 index 0000000000..6c97597866 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/arctic_block.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:block_storage", + "data": 3 + }, + "pattern": [ + "###", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#FURARCTIC" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/carminite_block.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/carminite_block.json new file mode 100644 index 0000000000..25bfc77a41 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/carminite_block.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:block_storage", + "data": 4 + }, + "pattern": [ + "###", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#CARMINITE" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/fiery_block.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/fiery_block.json new file mode 100644 index 0000000000..c8d6906c6d --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/fiery_block.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:block_storage", + "data": 1 + }, + "pattern": [ + "###", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTFIERY" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/ironwood_block.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/ironwood_block.json new file mode 100644 index 0000000000..6b2eef2a97 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/ironwood_block.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:block_storage", + "data": 0 + }, + "pattern": [ + "###", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/arctic_block_to_item.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/arctic_block_to_item.json new file mode 100644 index 0000000000..7a80a04af1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/arctic_block_to_item.json @@ -0,0 +1,13 @@ +{ + "result": { + "item": "twilightforest:arctic_fur", + "count": 9 + }, + "ingredients": [ + { + "item": "twilightforest:block_storage", + "data": 3 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/carminite_block_to_item.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/carminite_block_to_item.json new file mode 100644 index 0000000000..e350f3234b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/carminite_block_to_item.json @@ -0,0 +1,13 @@ +{ + "result": { + "item": "twilightforest:carminite", + "count": 9 + }, + "ingredients": [ + { + "item": "twilightforest:block_storage", + "data": 4 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/fiery_block_to_ingot.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/fiery_block_to_ingot.json new file mode 100644 index 0000000000..51bbc466c4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/fiery_block_to_ingot.json @@ -0,0 +1,13 @@ +{ + "result": { + "item": "twilightforest:fiery_ingot", + "count": 9 + }, + "ingredients": [ + { + "item": "twilightforest:block_storage", + "data": 1 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/ironwood_block_to_ingot.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/ironwood_block_to_ingot.json new file mode 100644 index 0000000000..c8434882b3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/ironwood_block_to_ingot.json @@ -0,0 +1,13 @@ +{ + "result": { + "item": "twilightforest:ironwood_ingot", + "count": 9 + }, + "ingredients": [ + { + "item": "twilightforest:block_storage", + "data": 0 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/knightmetal_block_to_ingot.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/knightmetal_block_to_ingot.json new file mode 100644 index 0000000000..cbec7e5409 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/knightmetal_block_to_ingot.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:knightmetal_ingot", + "count": 9 + }, + "ingredients": [ + { + "item": "twilightforest:knightmetal_block" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/steeleaf_block_to_ingot.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/steeleaf_block_to_ingot.json new file mode 100644 index 0000000000..adcab28ecc --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/reversed/steeleaf_block_to_ingot.json @@ -0,0 +1,13 @@ +{ + "result": { + "item": "twilightforest:steeleaf_ingot", + "count": 9 + }, + "ingredients": [ + { + "item": "twilightforest:block_storage", + "data": 2 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/compressed_blocks/steeleaf_block.json b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/steeleaf_block.json new file mode 100644 index 0000000000..6d227a976c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/compressed_blocks/steeleaf_block.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:block_storage", + "data": 2 + }, + "pattern": [ + "###", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/encased_fire_jet.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/encased_fire_jet.json new file mode 100644 index 0000000000..0ba911a9b1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/encased_fire_jet.json @@ -0,0 +1,28 @@ +{ + "result": { + "item": "twilightforest:fire_jet", + "data": 6 + }, + "pattern": [ + "ere", + "rjr", + "lll" + ], + "type": "forge:ore_shaped", + "key": { + "r": { + "item": "#DUSTREDSTONE" + }, + "e": { + "item": "twilightforest:tower_wood", + "data": 1 + }, + "j": { + "item": "twilightforest:fire_jet", + "data": 3 + }, + "l": { + "item": "minecraft:lava_bucket" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/encased_smoker.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/encased_smoker.json new file mode 100644 index 0000000000..9727dfd27a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/encased_smoker.json @@ -0,0 +1,25 @@ +{ + "result": { + "item": "twilightforest:fire_jet", + "data": 1 + }, + "pattern": [ + "ere", + "rsr", + "ere" + ], + "type": "forge:ore_shaped", + "key": { + "r": { + "item": "#DUSTREDSTONE" + }, + "s": { + "item": "twilightforest:fire_jet", + "data": 0 + }, + "e": { + "item": "twilightforest:tower_wood", + "data": 1 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_builder.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_builder.json new file mode 100644 index 0000000000..d32f9b5748 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_builder.json @@ -0,0 +1,24 @@ +{ + "result": { + "item": "twilightforest:tower_device", + "data": 6 + }, + "pattern": [ + "ece", + "cdc", + "ece" + ], + "type": "minecraft:crafting_shaped", + "key": { + "c": { + "item": "twilightforest:carminite" + }, + "d": { + "item": "minecraft:dispenser" + }, + "e": { + "item": "twilightforest:tower_wood", + "data": 1 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_reactor.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_reactor.json new file mode 100644 index 0000000000..2a1696e3d1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_reactor.json @@ -0,0 +1,24 @@ +{ + "result": { + "item": "twilightforest:tower_device", + "data": 12 + }, + "pattern": [ + "ece", + "coc", + "ece" + ], + "type": "forge:ore_shaped", + "key": { + "c": { + "item": "twilightforest:carminite" + }, + "e": { + "item": "twilightforest:tower_wood", + "data": 1 + }, + "o": { + "item": "#OREREDSTONE" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_reappearing.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_reappearing.json new file mode 100644 index 0000000000..24becb4cb3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_reappearing.json @@ -0,0 +1,25 @@ +{ + "result": { + "item": "twilightforest:tower_device", + "data": 0, + "count": 2 + }, + "pattern": [ + "ere", + "rcr", + "ere" + ], + "type": "forge:ore_shaped", + "key": { + "r": { + "item": "#DUSTREDSTONE" + }, + "c": { + "item": "twilightforest:carminite" + }, + "e": { + "item": "twilightforest:tower_wood", + "data": 1 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_vanishing.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_vanishing.json new file mode 100644 index 0000000000..f59aecf440 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_device_vanishing.json @@ -0,0 +1,26 @@ +{ + "result": { + "item": "twilightforest:tower_device", + "data": 2, + "count": 8 + }, + "pattern": [ + "ewe", + "wcw", + "ewe" + ], + "type": "minecraft:crafting_shaped", + "key": { + "c": { + "item": "twilightforest:carminite" + }, + "e": { + "item": "twilightforest:tower_wood", + "data": 1 + }, + "w": { + "item": "twilightforest:tower_wood", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_wood.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_wood.json new file mode 100644 index 0000000000..5db3d39208 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_wood.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:tower_wood", + "data": 0, + "count": 4 + }, + "pattern": [ + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_log", + "data": 3 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_wood_encased.json b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_wood_encased.json new file mode 100644 index 0000000000..d9dc2bf03a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/dark_tower/tower_wood_encased.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:tower_wood", + "data": 1, + "count": 3 + }, + "pattern": [ + "#", + "#", + "#" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:tower_wood", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/arctic_boots.json b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_boots.json new file mode 100644 index 0000000000..7591f5e161 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_boots.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:arctic_boots" + }, + "group": "arctic_armor", + "pattern": [ + "# #", + "# #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:arctic_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/arctic_chestplate.json b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_chestplate.json new file mode 100644 index 0000000000..2f8ae13952 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_chestplate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:arctic_chestplate" + }, + "group": "arctic_armor", + "pattern": [ + "# #", + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:arctic_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/arctic_helmet.json b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_helmet.json new file mode 100644 index 0000000000..67c3f7aa8a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_helmet.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:arctic_helmet" + }, + "group": "arctic_armor", + "pattern": [ + "###", + "# #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:arctic_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/arctic_leggings.json b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_leggings.json new file mode 100644 index 0000000000..47f81626be --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/arctic_leggings.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:arctic_leggings" + }, + "group": "arctic_armor", + "pattern": [ + "###", + "# #", + "# #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:arctic_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/block_and_chain.json b/src/main/resources/assets/twilightforest/recipes/equipment/block_and_chain.json new file mode 100644 index 0000000000..1edfa6dabb --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/block_and_chain.json @@ -0,0 +1,23 @@ +{ + "result": { + "item": "twilightforest:block_and_chain" + }, + "ingredients": [ + { + "item": "twilightforest:knightmetal_ring" + }, + { + "item": "#INGOTKNIGHTMETAL" + }, + { + "item": "#INGOTKNIGHTMETAL" + }, + { + "item": "#INGOTKNIGHTMETAL" + }, + { + "item": "twilightforest:knightmetal_block" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_keeping_2.json b/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_keeping_2.json new file mode 100644 index 0000000000..23d77e80c7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_keeping_2.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:charm_of_keeping_2" + }, + "ingredients": [ + { + "item": "twilightforest:charm_of_keeping_1" + }, + { + "item": "twilightforest:charm_of_keeping_1" + }, + { + "item": "twilightforest:charm_of_keeping_1" + }, + { + "item": "twilightforest:charm_of_keeping_1" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_keeping_3.json b/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_keeping_3.json new file mode 100644 index 0000000000..6c79232932 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_keeping_3.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:charm_of_keeping_3" + }, + "ingredients": [ + { + "item": "twilightforest:charm_of_keeping_2" + }, + { + "item": "twilightforest:charm_of_keeping_2" + }, + { + "item": "twilightforest:charm_of_keeping_2" + }, + { + "item": "twilightforest:charm_of_keeping_2" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_life_2.json b/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_life_2.json new file mode 100644 index 0000000000..362d80b774 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/charm_of_life_2.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:charm_of_life_2" + }, + "ingredients": [ + { + "item": "twilightforest:charm_of_life_1" + }, + { + "item": "twilightforest:charm_of_life_1" + }, + { + "item": "twilightforest:charm_of_life_1" + }, + { + "item": "twilightforest:charm_of_life_1" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/fiery_boots.json b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_boots.json new file mode 100644 index 0000000000..d6a7b1de15 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_boots.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:fiery_boots" + }, + "group": "fiery_armor", + "pattern": [ + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTFIERY" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/fiery_chestplate.json b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_chestplate.json new file mode 100644 index 0000000000..be584aabde --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_chestplate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:fiery_chestplate" + }, + "group": "fiery_armor", + "pattern": [ + "# #", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTFIERY" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/fiery_helmet.json b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_helmet.json new file mode 100644 index 0000000000..dc466e6dd0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_helmet.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:fiery_helmet" + }, + "group": "fiery_armor", + "pattern": [ + "###", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTFIERY" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/fiery_leggings.json b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_leggings.json new file mode 100644 index 0000000000..303d13a612 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_leggings.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:fiery_leggings" + }, + "group": "fiery_armor", + "pattern": [ + "###", + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTFIERY" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/fiery_pickaxe.json b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_pickaxe.json new file mode 100644 index 0000000000..63fa03dc1e --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_pickaxe.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:fiery_pickaxe" + }, + "pattern": [ + "###", + " X ", + " X " + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTFIERY" + }, + "X": { + "item": "minecraft:blaze_rod" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/fiery_sword.json b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_sword.json new file mode 100644 index 0000000000..25512d2952 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/fiery_sword.json @@ -0,0 +1,21 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:20s}]}", + "item": "twilightforest:fiery_sword", + "type": "minecraft:item_nbt" + }, + "pattern": [ + "#", + "#", + "X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTFIERY" + }, + "X": { + "item": "minecraft:blaze_rod" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/giant_pickaxe.json b/src/main/resources/assets/twilightforest/recipes/equipment/giant_pickaxe.json new file mode 100644 index 0000000000..64de300326 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/giant_pickaxe.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:giant_pickaxe" + }, + "group": "giant_tool", + "pattern": [ + "###", + " X ", + " X " + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:giant_cobblestone" + }, + "X": { + "item": "twilightforest:giant_log" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/giant_sword.json b/src/main/resources/assets/twilightforest/recipes/equipment/giant_sword.json new file mode 100644 index 0000000000..93e86847cb --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/giant_sword.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:giant_sword" + }, + "group": "giant_tool", + "pattern": [ + "#", + "#", + "X" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:giant_cobblestone" + }, + "X": { + "item": "twilightforest:giant_log" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_axe.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_axe.json new file mode 100644 index 0000000000..f5b965d4ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_axe.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:35s}]}", + "item": "twilightforest:ironwood_axe", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_tool", + "pattern": [ + "##", + "#X", + " X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_boots.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_boots.json new file mode 100644 index 0000000000..e168e1355c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_boots.json @@ -0,0 +1,18 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:2s}]}", + "item": "twilightforest:ironwood_boots", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_armor", + "pattern": [ + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_chestplate.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_chestplate.json new file mode 100644 index 0000000000..d26a455313 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_chestplate.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:0s}]}", + "item": "twilightforest:ironwood_chestplate", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_armor", + "pattern": [ + "# #", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_helmet.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_helmet.json new file mode 100644 index 0000000000..2c95d842a4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_helmet.json @@ -0,0 +1,18 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:6s}]}", + "item": "twilightforest:ironwood_helmet", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_armor", + "pattern": [ + "###", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_hoe.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_hoe.json new file mode 100644 index 0000000000..def82d9ea3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_hoe.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:ironwood_hoe" + }, + "group": "ironwood_tool", + "pattern": [ + "##", + " X", + " X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_leggings.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_leggings.json new file mode 100644 index 0000000000..7623350b55 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_leggings.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:0s}]}", + "item": "twilightforest:ironwood_leggings", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_armor", + "pattern": [ + "###", + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_pickaxe.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_pickaxe.json new file mode 100644 index 0000000000..531c854cfc --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_pickaxe.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:32s}]}", + "item": "twilightforest:ironwood_pickaxe", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_tool", + "pattern": [ + "###", + " X ", + " X " + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_shovel.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_shovel.json new file mode 100644 index 0000000000..0bab1f0226 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_shovel.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:34s}]}", + "item": "twilightforest:ironwood_shovel", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_tool", + "pattern": [ + "#", + "X", + "X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_sword.json b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_sword.json new file mode 100644 index 0000000000..79e0b007ce --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/ironwood_sword.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:1s,id:19s}]}", + "item": "twilightforest:ironwood_sword", + "type": "minecraft:item_nbt" + }, + "group": "ironwood_tool", + "pattern": [ + "#", + "#", + "X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTIRONWOOD" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_axe.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_axe.json new file mode 100644 index 0000000000..200eff4ef7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_axe.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:knightmetal_axe" + }, + "group": "knightmetal_tool", + "pattern": [ + "##", + "#X", + " X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_block.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_block.json new file mode 100644 index 0000000000..fcae630d80 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_block.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:knightmetal_block" + }, + "pattern": [ + "###", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_boots.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_boots.json new file mode 100644 index 0000000000..2808658b57 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_boots.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:knightmetal_boots" + }, + "group": "knightmetal_armor", + "pattern": [ + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_chestplate.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_chestplate.json new file mode 100644 index 0000000000..c15a0e5eb9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_chestplate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:knightmetal_chestplate" + }, + "group": "knightmetal_armor", + "pattern": [ + "# #", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_helmet.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_helmet.json new file mode 100644 index 0000000000..bad8e80be0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_helmet.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:knightmetal_helmet" + }, + "group": "knightmetal_armor", + "pattern": [ + "###", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_leggings.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_leggings.json new file mode 100644 index 0000000000..cc860649fd --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_leggings.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:knightmetal_leggings" + }, + "group": "knightmetal_armor", + "pattern": [ + "###", + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_pickaxe.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_pickaxe.json new file mode 100644 index 0000000000..79b41bec20 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_pickaxe.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:knightmetal_pickaxe" + }, + "group": "knightmetal_tool", + "pattern": [ + "###", + " X ", + " X " + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_ring.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_ring.json new file mode 100644 index 0000000000..8f1afd71a2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_ring.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:knightmetal_ring" + }, + "pattern": [ + " # ", + "# #", + " # " + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_shield.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_shield.json new file mode 100644 index 0000000000..25e0b8640f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_shield.json @@ -0,0 +1,29 @@ +{ + "result": { + "item": "twilightforest:knightmetal_shield" + }, + "pattern": [ + "#W", + "#R", + "#W" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + }, + "R": { + "item": "twilightforest:knightmetal_ring" + }, + "W": [{ + "item": "twilightforest:tower_wood", + "data": 0 + }, { + "item": "twilightforest:tower_wood", + "data": 2 + }, { + "item": "twilightforest:tower_wood", + "data": 3 + }] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_sword.json b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_sword.json new file mode 100644 index 0000000000..821c599f12 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/knightmetal_sword.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:knightmetal_sword" + }, + "group": "knightmetal_tool", + "pattern": [ + "#", + "#", + "X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTKNIGHTMETAL" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/moonworm_queen.json b/src/main/resources/assets/twilightforest/recipes/equipment/moonworm_queen.json new file mode 100644 index 0000000000..6b4b36308c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/moonworm_queen.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:moonworm_queen" + }, + "ingredients": [ + { + "item": "twilightforest:moonworm_queen", + "data": 32767 + }, + { + "item": "twilightforest:torchberries" + }, + { + "item": "twilightforest:torchberries" + }, + { + "item": "twilightforest:torchberries" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/naga_chestplate.json b/src/main/resources/assets/twilightforest/recipes/equipment/naga_chestplate.json new file mode 100644 index 0000000000..4a37cf8323 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/naga_chestplate.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:3s,id:1s}]}", + "item": "twilightforest:naga_chestplate", + "type": "minecraft:item_nbt" + }, + "group": "naga_armor", + "pattern": [ + "# #", + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:naga_scale" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/naga_leggings.json b/src/main/resources/assets/twilightforest/recipes/equipment/naga_leggings.json new file mode 100644 index 0000000000..074d807728 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/naga_leggings.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:3s,id:0s}]}", + "item": "twilightforest:naga_leggings", + "type": "minecraft:item_nbt" + }, + "group": "naga_armor", + "pattern": [ + "###", + "# #", + "# #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:naga_scale" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/scepters/lifedrain_scepter.json b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/lifedrain_scepter.json new file mode 100644 index 0000000000..f415954a8d --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/lifedrain_scepter.json @@ -0,0 +1,15 @@ +{ + "result": { + "item": "twilightforest:lifedrain_scepter" + }, + "ingredients": [ + { + "item": "twilightforest:lifedrain_scepter", + "data": 32767 + }, + { + "item": "minecraft:fermented_spider_eye" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/scepters/shield_scepter.json b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/shield_scepter.json new file mode 100644 index 0000000000..8f3775c808 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/shield_scepter.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:shield_scepter" + }, + "ingredients": [ + { + "item": "twilightforest:shield_scepter", + "data": 32767 + }, + { + "item": "minecraft:golden_apple", + "data": 0 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/scepters/twilight_scepter.json b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/twilight_scepter.json new file mode 100644 index 0000000000..35c4bf785a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/twilight_scepter.json @@ -0,0 +1,15 @@ +{ + "result": { + "item": "twilightforest:twilight_scepter" + }, + "ingredients": [ + { + "item": "twilightforest:twilight_scepter", + "data": 32767 + }, + { + "item": "#ENDERPEARL" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/scepters/zombie_scepter.json b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/zombie_scepter.json new file mode 100644 index 0000000000..07f88bbd56 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/scepters/zombie_scepter.json @@ -0,0 +1,63 @@ +{ + "result": { + "item": "twilightforest:zombie_scepter" + }, + "group": "twilightforest:zombie_scepter", + "ingredients": [ + { + "item": "twilightforest:zombie_scepter", + "data": 32767 + }, + { + "item": "minecraft:rotten_flesh" + }, + [ + { + "nbt": "{Potion:\"minecraft:long_strength\"}", + "item": "minecraft:potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:long_strength\"}", + "item": "minecraft:lingering_potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:long_strength\"}", + "item": "minecraft:splash_potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:strength\"}", + "item": "minecraft:potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:strength\"}", + "item": "minecraft:lingering_potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:strength\"}", + "item": "minecraft:splash_potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:strong_strength\"}", + "item": "minecraft:potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:strong_strength\"}", + "item": "minecraft:lingering_potion", + "type": "minecraft:item_nbt" + }, + { + "nbt": "{Potion:\"minecraft:strong_strength\"}", + "item": "minecraft:splash_potion", + "type": "minecraft:item_nbt" + } + ] + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_axe.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_axe.json new file mode 100644 index 0000000000..513f86b7bd --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_axe.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:32s}]}", + "item": "twilightforest:steeleaf_axe", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_tool", + "pattern": [ + "##", + "#X", + " X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_boots.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_boots.json new file mode 100644 index 0000000000..33455aa1dc --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_boots.json @@ -0,0 +1,18 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:2s}]}", + "item": "twilightforest:steeleaf_boots", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_armor", + "pattern": [ + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_chestplate.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_chestplate.json new file mode 100644 index 0000000000..f8ce92eb17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_chestplate.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:3s}]}", + "item": "twilightforest:steeleaf_chestplate", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_armor", + "pattern": [ + "# #", + "###", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_helmet.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_helmet.json new file mode 100644 index 0000000000..0cb2debcb8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_helmet.json @@ -0,0 +1,18 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:4s}]}", + "item": "twilightforest:steeleaf_helmet", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_armor", + "pattern": [ + "###", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_hoe.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_hoe.json new file mode 100644 index 0000000000..9d9b7fed93 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_hoe.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:steeleaf_hoe" + }, + "group": "steeleaf_tool", + "pattern": [ + "##", + " X", + " X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_leggings.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_leggings.json new file mode 100644 index 0000000000..e331abdb49 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_leggings.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:1s}]}", + "item": "twilightforest:steeleaf_leggings", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_armor", + "pattern": [ + "###", + "# #", + "# #" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_pickaxe.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_pickaxe.json new file mode 100644 index 0000000000..eb4bee6bbf --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_pickaxe.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:35s}]}", + "item": "twilightforest:steeleaf_pickaxe", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_tool", + "pattern": [ + "###", + " X ", + " X " + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_shovel.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_shovel.json new file mode 100644 index 0000000000..432ba046b1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_shovel.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:32s}]}", + "item": "twilightforest:steeleaf_shovel", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_tool", + "pattern": [ + "#", + "X", + "X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_sword.json b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_sword.json new file mode 100644 index 0000000000..ffb1ca85bb --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/steeleaf_sword.json @@ -0,0 +1,22 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:21s}]}", + "item": "twilightforest:steeleaf_sword", + "type": "minecraft:item_nbt" + }, + "group": "steeleaf_tool", + "pattern": [ + "#", + "#", + "X" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#INGOTSTEELEAF" + }, + "X": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/yeti_boots.json b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_boots.json new file mode 100644 index 0000000000..23ab5a83e8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_boots.json @@ -0,0 +1,18 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:0s},{lvl:4s,id:2s}]}", + "item": "twilightforest:yeti_boots", + "type": "minecraft:item_nbt" + }, + "group": "yeti_armor", + "pattern": [ + "# #", + "# #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:alpha_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/yeti_chestplate.json b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_chestplate.json new file mode 100644 index 0000000000..29b5e7dd47 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_chestplate.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:0s}]}", + "item": "twilightforest:yeti_chestplate", + "type": "minecraft:item_nbt" + }, + "group": "yeti_armor", + "pattern": [ + "# #", + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:alpha_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/yeti_helmet.json b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_helmet.json new file mode 100644 index 0000000000..a0b8fca931 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_helmet.json @@ -0,0 +1,18 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:0s}]}", + "item": "twilightforest:yeti_helmet", + "type": "minecraft:item_nbt" + }, + "group": "yeti_armor", + "pattern": [ + "###", + "# #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:alpha_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/equipment/yeti_leggings.json b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_leggings.json new file mode 100644 index 0000000000..baa9a8fcfd --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/equipment/yeti_leggings.json @@ -0,0 +1,19 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:0s}]}", + "item": "twilightforest:yeti_leggings", + "type": "minecraft:item_nbt" + }, + "group": "yeti_armor", + "pattern": [ + "###", + "# #", + "# #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:alpha_fur" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/firefly_jar.json b/src/main/resources/assets/twilightforest/recipes/firefly_jar.json new file mode 100644 index 0000000000..f237036e87 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/firefly_jar.json @@ -0,0 +1,14 @@ +{ + "result": { + "item": "twilightforest:firefly_jar" + }, + "ingredients": [ + { + "item": "twilightforest:firefly" + }, + { + "item": "minecraft:glass_bottle" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_cobblestone.json b/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_cobblestone.json new file mode 100644 index 0000000000..369f11a9fa --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_cobblestone.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "minecraft:cobblestone", + "count": 64 + }, + "ingredients": [ + { + "item": "twilightforest:giant_cobblestone" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_leaves.json b/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_leaves.json new file mode 100644 index 0000000000..5000b46111 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_leaves.json @@ -0,0 +1,13 @@ +{ + "result": { + "item": "minecraft:leaves", + "data": 0, + "count": 64 + }, + "ingredients": [ + { + "item": "twilightforest:giant_leaves" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_log.json b/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_log.json new file mode 100644 index 0000000000..8d5930d69a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/giant_blocks/giant_log.json @@ -0,0 +1,13 @@ +{ + "result": { + "item": "minecraft:planks", + "data": 0, + "count": 64 + }, + "ingredients": [ + { + "item": "twilightforest:giant_log" + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/iron_ladder.json b/src/main/resources/assets/twilightforest/recipes/iron_ladder.json new file mode 100644 index 0000000000..a49b46ea0e --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/iron_ladder.json @@ -0,0 +1,15 @@ +{ + "result": { + "item": "twilightforest:iron_ladder", + "count": 3 + }, + "pattern": [ + "•#•", + "•#•" + ], + "type": "forge:ore_shaped", + "key": { + "•": { "item": "#NUGGETIRON" }, + "#": { "item": "minecraft:iron_bars" } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/magic_map_empty.json b/src/main/resources/assets/twilightforest/recipes/magic_map_empty.json new file mode 100644 index 0000000000..19fcf3381b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/magic_map_empty.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:magic_map_empty" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#PAPER" + }, + "X": { + "item": "twilightforest:magic_map_focus" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/magic_map_focus.json b/src/main/resources/assets/twilightforest/recipes/magic_map_focus.json new file mode 100644 index 0000000000..dba0367e06 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/magic_map_focus.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:magic_map_focus" + }, + "ingredients": [ + { + "item": "twilightforest:raven_feather" + }, + { + "item": "twilightforest:torchberries" + }, + { + "item": "#DUSTGLOWSTONE" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/armor_shard_cluster.json b/src/main/resources/assets/twilightforest/recipes/materials/armor_shard_cluster.json new file mode 100644 index 0000000000..f27b2032f9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/armor_shard_cluster.json @@ -0,0 +1,16 @@ +{ + "result": { + "item": "twilightforest:armor_shard_cluster" + }, + "pattern": [ + "###", + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:armor_shard" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/carminite.json b/src/main/resources/assets/twilightforest/recipes/materials/carminite.json new file mode 100644 index 0000000000..08a4022d84 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/carminite.json @@ -0,0 +1,23 @@ +{ + "result": { + "item": "twilightforest:carminite" + }, + "group": "twilightforest:carminite", + "pattern": [ + "brb", + "rgr", + "brb" + ], + "type": "forge:ore_shaped", + "key": { + "b": { + "item": "twilightforest:borer_essence" + }, + "r": { + "item": "#DUSTREDSTONE" + }, + "g": { + "item": "minecraft:ghast_tear" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/carminite_alt.json b/src/main/resources/assets/twilightforest/recipes/materials/carminite_alt.json new file mode 100644 index 0000000000..f24f510a4b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/carminite_alt.json @@ -0,0 +1,23 @@ +{ + "result": { + "item": "twilightforest:carminite" + }, + "group": "twilightforest:carminite", + "pattern": [ + "rbr", + "bgb", + "rbr" + ], + "type": "forge:ore_shaped", + "key": { + "b": { + "item": "twilightforest:borer_essence" + }, + "r": { + "item": "#DUSTREDSTONE" + }, + "g": { + "item": "minecraft:ghast_tear" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_ingot.json b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_ingot.json new file mode 100644 index 0000000000..a2b0da2861 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_ingot.json @@ -0,0 +1,15 @@ +{ + "result": { + "item": "twilightforest:fiery_ingot" + }, + "ingredients": [ + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + { + "item": "#INGOTIRON" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_boots.json b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_boots.json new file mode 100644 index 0000000000..8d1bb2f33c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_boots.json @@ -0,0 +1,28 @@ +{ + "result": { + "item": "twilightforest:fiery_boots" + }, + "group": "fiery_convert_armor", + "ingredients": [ + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + { + "item": "minecraft:iron_boots" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_chestplate.json b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_chestplate.json new file mode 100644 index 0000000000..c8f74b8a9f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_chestplate.json @@ -0,0 +1,44 @@ +{ + "result": { + "item": "twilightforest:fiery_chestplate" + }, + "group": "fiery_convert_armor", + "ingredients": [ + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + { + "item": "minecraft:iron_chestplate" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_helmet.json b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_helmet.json new file mode 100644 index 0000000000..bb3fb99d43 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_helmet.json @@ -0,0 +1,32 @@ +{ + "result": { + "item": "twilightforest:fiery_helmet" + }, + "group": "fiery_convert_armor", + "ingredients": [ + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + { + "item": "minecraft:iron_helmet" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_leggings.json b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_leggings.json new file mode 100644 index 0000000000..b1f4c582c7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_leggings.json @@ -0,0 +1,40 @@ +{ + "result": { + "item": "twilightforest:fiery_leggings" + }, + "group": "fiery_convert_armor", + "ingredients": [ + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + { + "item": "minecraft:iron_leggings" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_pickaxe.json b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_pickaxe.json new file mode 100644 index 0000000000..6b2e561fca --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_pickaxe.json @@ -0,0 +1,30 @@ +{ + "result": { + "item": "twilightforest:fiery_pickaxe" + }, + "group": "fiery_convert_tool", + "ingredients": [ + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + { + "item": "minecraft:iron_pickaxe" + }, + { + "item": "minecraft:blaze_rod" + }, + { + "item": "minecraft:blaze_rod" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_sword.json b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_sword.json new file mode 100644 index 0000000000..e03683e47f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/fiery_conversion/fiery_iron_sword.json @@ -0,0 +1,25 @@ +{ + "result": { + "nbt": "{ench:[{lvl:2s,id:20s}]}", + "item": "twilightforest:fiery_sword", + "type": "minecraft:item_nbt" + }, + "group": "fiery_convert_tool", + "ingredients": [ + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + [ + { "item": "twilightforest:fiery_blood" }, + { "item": "twilightforest:fiery_tears" } + ], + { + "item": "minecraft:iron_sword" + }, + { + "item": "minecraft:blaze_rod" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/materials/ironwood_raw.json b/src/main/resources/assets/twilightforest/recipes/materials/ironwood_raw.json new file mode 100644 index 0000000000..d6e3c4c2b8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/materials/ironwood_raw.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:ironwood_raw" + }, + "ingredients": [ + { + "item": "twilightforest:liveroot" + }, + { + "item": "#INGOTIRON" + }, + { + "item": "#NUGGETGOLD" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/maze_map_empty.json b/src/main/resources/assets/twilightforest/recipes/maze_map_empty.json new file mode 100644 index 0000000000..30ce2bef16 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/maze_map_empty.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:maze_map_empty" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#PAPER" + }, + "X": { + "item": "twilightforest:maze_map_focus" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_spiral.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_spiral.json new file mode 100644 index 0000000000..0f4ecdd782 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_spiral.json @@ -0,0 +1,49 @@ +{ + "result": { + "item": "twilightforest:spiral_bricks", + "data": 0, + "count": 8 + }, + "pattern": [ + "BSS", + "BSS", + "BBB" + ], + "type": "forge:ore_shaped", + "key": { + "B": [ + { + "item": "minecraft:stonebrick", + "data": 0 + }, + { + "item": "minecraft:stonebrick", + "data": 1 + }, + { + "item": "minecraft:stonebrick", + "data": 2 + }, + { + "item": "minecraft:stonebrick", + "data": 3 + }, + { + "item": "#STONE" + }, + { + "item": "#STONEBRICK" + } + ], + "S": [ + { + "item": "minecraft:stone_slab", + "data": 0 + }, + { + "item": "minecraft:stone_slab", + "data": 5 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left.json new file mode 100644 index 0000000000..a0eaf60e4b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:nagastone_stairs", + "data": 0, + "count": 8 + }, + "group": "nagastone_stairs_left", + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:etched_nagastone" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left_mossy.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left_mossy.json new file mode 100644 index 0000000000..11bbd1d02b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left_mossy.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 0, + "count": 8 + }, + "group": "nagastone_stairs_left", + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:etched_nagastone_mossy" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left_weathered.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left_weathered.json new file mode 100644 index 0000000000..7e7759999f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_left_weathered.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 0, + "count": 8 + }, + "group": "nagastone_stairs_left", + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:etched_nagastone_weathered" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_mossy_reverse.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_mossy_reverse.json new file mode 100644 index 0000000000..a465d71619 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_mossy_reverse.json @@ -0,0 +1,50 @@ +{ + "result": { + "item": "twilightforest:etched_nagastone", + "count": 3 + }, + "group": "nagastone_stairs_reverse", + "ingredients": [ + [ + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 8 + } + ] + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_reverse.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_reverse.json new file mode 100644 index 0000000000..d36d441ddc --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_reverse.json @@ -0,0 +1,50 @@ +{ + "result": { + "item": "twilightforest:etched_nagastone", + "count": 3 + }, + "group": "nagastone_stairs_reverse", + "ingredients": [ + [ + { + "item": "twilightforest:nagastone_stairs", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs", + "data": 8 + } + ] + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right.json new file mode 100644 index 0000000000..a95837eac6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:nagastone_stairs", + "data": 8, + "count": 8 + }, + "group": "nagastone_stairs_right", + "pattern": [ + "###", + " ##", + " #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:etched_nagastone" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right_mossy.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right_mossy.json new file mode 100644 index 0000000000..3345b29409 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right_mossy.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:nagastone_stairs_mossy", + "data": 8, + "count": 8 + }, + "group": "nagastone_stairs_right", + "pattern": [ + "###", + " ##", + " #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:etched_nagastone_mossy" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right_weathered.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right_weathered.json new file mode 100644 index 0000000000..8c00dfbe4b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_right_weathered.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 8, + "count": 8 + }, + "group": "nagastone_stairs_right", + "pattern": [ + "###", + " ##", + " #" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": [ + { + "item": "twilightforest:etched_nagastone_weathered" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_weathered_reverse.json b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_weathered_reverse.json new file mode 100644 index 0000000000..5ce2022745 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/nagastone/nagastone_stairs_weathered_reverse.json @@ -0,0 +1,50 @@ +{ + "result": { + "item": "twilightforest:etched_nagastone", + "count": 3 + }, + "group": "nagastone_stairs_reverse", + "ingredients": [ + [ + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 8 + } + ], + [ + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 0 + }, + { + "item": "twilightforest:nagastone_stairs_weathered", + "data": 8 + } + ] + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/ore_map_empty_from_maze_map_empty.json b/src/main/resources/assets/twilightforest/recipes/ore_map_empty_from_maze_map_empty.json new file mode 100644 index 0000000000..346b45c858 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/ore_map_empty_from_maze_map_empty.json @@ -0,0 +1,20 @@ +{ + "result": { + "item": "twilightforest:ore_map_empty" + }, + "ingredients": [ + { + "item": "twilightforest:maze_map_empty" + }, + { + "item": "#BLOCKGOLD" + }, + { + "item": "#BLOCKDIAMOND" + }, + { + "item": "#BLOCKIRON" + } + ], + "type": "forge:ore_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/patchouli_logbook.json b/src/main/resources/assets/twilightforest/recipes/patchouli_logbook.json new file mode 100644 index 0000000000..909ab50215 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/patchouli_logbook.json @@ -0,0 +1,26 @@ +{ + "conditions": [{ + "type": "forge:mod_loaded", + "modid": "patchouli" + }], + "result": { + "item": "patchouli:guide_book", + "nbt": "{\"patchouli:book\":\"twilightforest:guide\"}" + }, + "ingredients": [ + [{ + "item": "twilightforest:twilight_sapling", + "data": 0 + }, { + "item": "twilightforest:twilight_sapling", + "data": 1 + }, { + "item": "twilightforest:twilight_sapling", + "data": 2 + }], + { "item": "minecraft:book" }, + { "item": "minecraft:feather" }, + { "item": "minecraft:dye", "data": 0 } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/patchouli_logbook_alt.json b/src/main/resources/assets/twilightforest/recipes/patchouli_logbook_alt.json new file mode 100644 index 0000000000..38f46e4873 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/patchouli_logbook_alt.json @@ -0,0 +1,24 @@ +{ + "conditions": [{ + "type": "forge:mod_loaded", + "modid": "patchouli" + }], + "result": { + "item": "patchouli:guide_book", + "nbt": "{\"patchouli:book\":\"twilightforest:guide\"}" + }, + "ingredients": [ + [{ + "item": "twilightforest:twilight_sapling", + "data": 0 + }, { + "item": "twilightforest:twilight_sapling", + "data": 1 + }, { + "item": "twilightforest:twilight_sapling", + "data": 2 + }], + { "item": "minecraft:writable_book" } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/stick.json b/src/main/resources/assets/twilightforest/recipes/stick.json new file mode 100644 index 0000000000..0a24dd35dd --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/stick.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "minecraft:stick" + }, + "ingredients": [ + { + "item": "twilightforest:twilight_plant", + "data": 8 + } + ], + "type": "minecraft:crafting_shapeless" +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/torch.json b/src/main/resources/assets/twilightforest/recipes/torch.json new file mode 100644 index 0000000000..d8196e21eb --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/torch.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "minecraft:torch", + "count": 5 + }, + "pattern": [ + "B", + "S" + ], + "type": "forge:ore_shaped", + "key": { + "B": { + "item": "twilightforest:torchberries" + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/uncrafting_table.json b/src/main/resources/assets/twilightforest/recipes/uncrafting_table.json new file mode 100644 index 0000000000..ce4972d03a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/uncrafting_table.json @@ -0,0 +1,22 @@ +{ + "conditions": [{ + "type": "twilightforest:uncrafting_enabled" + }], + "result": { + "item": "twilightforest:uncrafting_table" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "#WORKBENCH" + }, + "X": { + "item": "twilightforest:maze_map_focus" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_button.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_button.json new file mode 100644 index 0000000000..cd2a511012 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:canopy_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:canopy_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_door.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_door.json new file mode 100644 index 0000000000..870dfe9b03 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:canopy_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:canopy_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_fence.json new file mode 100644 index 0000000000..1c1d57a077 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:canopy_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:canopy_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_gate.json new file mode 100644 index 0000000000..3d79934a8c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:canopy_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:canopy_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_planks.json new file mode 100644 index 0000000000..f4b91eb1a6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:canopy_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:twilight_log", + "data": 1 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_plate.json new file mode 100644 index 0000000000..c21648435a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:canopy_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:canopy_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_slab.json new file mode 100644 index 0000000000..3167245691 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:canopy_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:canopy_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_stairs.json new file mode 100644 index 0000000000..8fad3da2f7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:canopy_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:canopy_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/canopy_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/canopy_trapdoor.json new file mode 100644 index 0000000000..3de1b5af0f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/canopy_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:canopy_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:canopy_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_button.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_button.json new file mode 100644 index 0000000000..315adf605d --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:dark_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:dark_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_door.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_door.json new file mode 100644 index 0000000000..ac91a7f529 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:dark_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:dark_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_fence.json new file mode 100644 index 0000000000..b4e5f772d9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:dark_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:dark_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_gate.json new file mode 100644 index 0000000000..1ef97a8a88 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:dark_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:dark_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_planks.json new file mode 100644 index 0000000000..5a2bfeaaa2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:dark_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:twilight_log", + "data": 3 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_plate.json new file mode 100644 index 0000000000..668b488a64 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:dark_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:dark_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_slab.json new file mode 100644 index 0000000000..29d33f6711 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:dark_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:dark_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_stairs.json new file mode 100644 index 0000000000..14f83ec3c8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:dark_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:dark_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/darkwood_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_trapdoor.json new file mode 100644 index 0000000000..a313aaf23b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/darkwood_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:dark_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:dark_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_button.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_button.json new file mode 100644 index 0000000000..f5a39be982 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:mangrove_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:mangrove_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_door.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_door.json new file mode 100644 index 0000000000..486bf3a133 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:mangrove_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mangrove_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_fence.json new file mode 100644 index 0000000000..cbef615797 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:mangrove_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:mangrove_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_gate.json new file mode 100644 index 0000000000..e50f066610 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:mangrove_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:mangrove_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_planks.json new file mode 100644 index 0000000000..2ebe9ba638 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:mangrove_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:twilight_log", + "data": 2 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_plate.json new file mode 100644 index 0000000000..b2681a21b9 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:mangrove_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mangrove_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_slab.json new file mode 100644 index 0000000000..220afced04 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:mangrove_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mangrove_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_stairs.json new file mode 100644 index 0000000000..0225e9e97e --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:mangrove_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mangrove_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mangrove_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_trapdoor.json new file mode 100644 index 0000000000..be86231282 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mangrove_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:mangrove_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mangrove_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_button.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_button.json new file mode 100644 index 0000000000..d7531740f7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:mine_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:mine_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_door.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_door.json new file mode 100644 index 0000000000..def6b8ee70 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:mine_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mine_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_fence.json new file mode 100644 index 0000000000..2ebf2f10b8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:mine_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:mine_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_gate.json new file mode 100644 index 0000000000..5eaa81bacd --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:mine_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:mine_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_planks.json new file mode 100644 index 0000000000..2d484036fa --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:mine_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:magic_log", + "data": 2 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_plate.json new file mode 100644 index 0000000000..df103783dc --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:mine_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mine_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_slab.json new file mode 100644 index 0000000000..9d9810c3e2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:mine_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mine_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_stairs.json new file mode 100644 index 0000000000..fe590b9c1d --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:mine_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mine_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/mine_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/mine_trapdoor.json new file mode 100644 index 0000000000..a3c59ebf38 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/mine_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:mine_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:mine_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_button.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_button.json new file mode 100644 index 0000000000..7e7b3ba916 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:sort_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:sort_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_door.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_door.json new file mode 100644 index 0000000000..e647a90c95 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:sort_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:sort_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_fence.json new file mode 100644 index 0000000000..7aa57d5523 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:sort_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:sort_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_gate.json new file mode 100644 index 0000000000..ccc879f916 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:sort_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:sort_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_planks.json new file mode 100644 index 0000000000..668f5ef830 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:sort_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:magic_log", + "data": 3 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_plate.json new file mode 100644 index 0000000000..61b2d48b5b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:sort_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:sort_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_slab.json new file mode 100644 index 0000000000..b7adbe918c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:sort_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:sort_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_stairs.json new file mode 100644 index 0000000000..e7b33a8cf1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:sort_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:sort_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/sort_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/sort_trapdoor.json new file mode 100644 index 0000000000..029a45c9bb --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/sort_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:sort_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:sort_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_button.json b/src/main/resources/assets/twilightforest/recipes/wood/time_button.json new file mode 100644 index 0000000000..2b20a3d603 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:time_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:time_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_door.json b/src/main/resources/assets/twilightforest/recipes/wood/time_door.json new file mode 100644 index 0000000000..7ff243e18f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:time_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:time_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/time_fence.json new file mode 100644 index 0000000000..170ac29d50 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:time_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:time_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/time_gate.json new file mode 100644 index 0000000000..1f4835a174 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:time_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:time_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/time_planks.json new file mode 100644 index 0000000000..3aa729eb94 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:time_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:magic_log", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/time_plate.json new file mode 100644 index 0000000000..72a2e6af2a --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:time_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:time_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/time_slab.json new file mode 100644 index 0000000000..1f2ce7e3b0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:time_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:time_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/time_stairs.json new file mode 100644 index 0000000000..6770919fd7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:time_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:time_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/time_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/time_trapdoor.json new file mode 100644 index 0000000000..9fbc724737 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/time_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:time_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:time_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_button.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_button.json new file mode 100644 index 0000000000..ff6a7c0d03 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:trans_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:trans_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_door.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_door.json new file mode 100644 index 0000000000..08b275ca6f --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:trans_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:trans_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_fence.json new file mode 100644 index 0000000000..597de7d034 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:trans_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:trans_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_gate.json new file mode 100644 index 0000000000..af57b2c1a5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:trans_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:trans_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_planks.json new file mode 100644 index 0000000000..f22d331e63 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:trans_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:magic_log", + "data": 1 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_plate.json new file mode 100644 index 0000000000..529550e57b --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:trans_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:trans_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_slab.json new file mode 100644 index 0000000000..ed3ea3f403 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:trans_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:trans_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_stairs.json new file mode 100644 index 0000000000..fe12696f4e --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:trans_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:trans_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/trans_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/trans_trapdoor.json new file mode 100644 index 0000000000..c999b4b11e --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/trans_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:trans_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:trans_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_button.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_button.json new file mode 100644 index 0000000000..91bd3ef962 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_button.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_button", + "data": 0, + "count": 1 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:twilight_oak_planks", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_door.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_door.json new file mode 100644 index 0000000000..93f32bbaf3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_door.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_door", + "data": 0, + "count": 3 + }, + "pattern": [ + "##", + "##", + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_oak_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_fence.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_fence.json new file mode 100644 index 0000000000..e7f22252ad --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_fence.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_fence", + "data": 0, + "count": 3 + }, + "pattern": [ + "#S#", + "#S#" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_oak_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_gate.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_gate.json new file mode 100644 index 0000000000..61c133b386 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_gate.json @@ -0,0 +1,21 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_gate", + "data": 0, + "count": 1 + }, + "pattern": [ + "S#S", + "S#S" + ], + "type": "forge:ore_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_oak_planks", + "data": 0 + }, + "S": { + "item": "#STICKWOOD" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_planks.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_planks.json new file mode 100644 index 0000000000..b5bd1d2ebe --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_planks.json @@ -0,0 +1,12 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_planks", + "data": 0, + "count": 4 + }, + "type": "minecraft:crafting_shapeless", + "ingredients": [{ + "item": "twilightforest:twilight_log", + "data": 0 + }] +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_plate.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_plate.json new file mode 100644 index 0000000000..c1071f542d --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_plate.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_plate", + "data": 0, + "count": 1 + }, + "pattern": [ + "##" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_oak_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_slab.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_slab.json new file mode 100644 index 0000000000..7c5a9fa25c --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_slab.json @@ -0,0 +1,17 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_slab", + "data": 0, + "count": 6 + }, + "pattern": [ + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_oak_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_stairs.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_stairs.json new file mode 100644 index 0000000000..b254268eb3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_stairs.json @@ -0,0 +1,19 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_stairs", + "data": 0, + "count": 8 + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_oak_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_trapdoor.json b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_trapdoor.json new file mode 100644 index 0000000000..36332edd9d --- /dev/null +++ b/src/main/resources/assets/twilightforest/recipes/wood/twilight_oak_trapdoor.json @@ -0,0 +1,18 @@ +{ + "result": { + "item": "twilightforest:twilight_oak_trapdoor", + "data": 0, + "count": 6 + }, + "pattern": [ + "###", + "###" + ], + "type": "minecraft:crafting_shaped", + "key": { + "#": { + "item": "twilightforest:twilight_oak_planks", + "data": 0 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/aurora.frag b/src/main/resources/assets/twilightforest/shaders/aurora.frag new file mode 100644 index 0000000000..78b38d704d --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/aurora.frag @@ -0,0 +1,146 @@ +#version 120 + +uniform sampler2D zero; +uniform vec2 texSize; + +uniform float time; + +varying vec3 position; +varying vec3 worldPos; +varying vec2 texCoord0; + +uniform float offset[5] = float[](0.0, 1.0, 2.0, 3.0, 4.0); +uniform float weight[5] = float[](0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162); + +float getPerceptualBrightness(vec3 c) { + return sqrt(0.241 * c.r * c.r + 0.691 * c.g * c.g + 0.068 * c.b * c.b); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +float mod289(float x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);} + +// Simplex 4D Noise +// by Ian McEwan, Ashima Arts +// +vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} +float permute(float x){return floor(mod(((x*34.0)+1.0)*x, 289.0));} +vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} +float taylorInvSqrt(float r){return 1.79284291400159 - 0.85373472095314 * r;} + +vec4 grad4(float j, vec4 ip){ + const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); + vec4 p,s; + + p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; + p.w = 1.5 - dot(abs(p.xyz), ones.xyz); + s = vec4(lessThan(p, vec4(0.0))); + p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; + + return p; +} + +float snoise(vec4 v){ + const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4 + 0.309016994374947451); // (sqrt(5) - 1)/4 F4 +// First corner + vec4 i = floor(v + dot(v, C.yyyy) ); + vec4 x0 = v - i + dot(i, C.xxxx); + +// Other corners + +// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + vec4 i0; + + vec3 isX = step( x0.yzw, x0.xxx ); + vec3 isYZ = step( x0.zww, x0.yyz ); +// i0.x = dot( isX, vec3( 1.0 ) ); + i0.x = isX.x + isX.y + isX.z; + i0.yzw = 1.0 - isX; + +// i0.y += dot( isYZ.xy, vec2( 1.0 ) ); + i0.y += isYZ.x + isYZ.y; + i0.zw += 1.0 - isYZ.xy; + + i0.z += isYZ.z; + i0.w += 1.0 - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + vec4 i3 = clamp( i0, 0.0, 1.0 ); + vec4 i2 = clamp( i0-1.0, 0.0, 1.0 ); + vec4 i1 = clamp( i0-2.0, 0.0, 1.0 ); + + // x0 = x0 - 0.0 + 0.0 * C + vec4 x1 = x0 - i1 + 1.0 * C.xxxx; + vec4 x2 = x0 - i2 + 2.0 * C.xxxx; + vec4 x3 = x0 - i3 + 3.0 * C.xxxx; + vec4 x4 = x0 - 1.0 + 4.0 * C.xxxx; + +// Permutations + i = mod(i, 289.0); + float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x); + vec4 j1 = permute( permute( permute( permute ( + i.w + vec4(i1.w, i2.w, i3.w, 1.0 )) + + i.z + vec4(i1.z, i2.z, i3.z, 1.0 )) + + i.y + vec4(i1.y, i2.y, i3.y, 1.0 )) + + i.x + vec4(i1.x, i2.x, i3.x, 1.0 )); +// Gradients +// ( 7*7*6 points uniformly over a cube, mapped onto a 4-octahedron.) +// 7*7*6 = 294, which is close to the ring size 17*17 = 289. + + vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ; + + vec4 p0 = grad4(j0, ip); + vec4 p1 = grad4(j1.x, ip); + vec4 p2 = grad4(j1.y, ip); + vec4 p3 = grad4(j1.z, ip); + vec4 p4 = grad4(j1.w, ip); + +// Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= taylorInvSqrt(dot(p4,p4)); + +// Mix contributions from the five corners + vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); + vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0); + m0 = m0 * m0; + m1 = m1 * m1; + return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) + + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; +} + +float noiseTwoPass(vec4 v) { + return snoise(v) + snoise(v/2.0); +} + +void main() { + vec4 color = texture2D(zero, vec2(texCoord0)); + //vec4 light = texture2D(one , vec2(texCoord1)); + + vec4 blurred = vec4(0); + vec2 texcoord = vec2(texCoord0); + + blurred = texture2D(zero, texCoord0) * weight[0]; + + for (int i=1; i<5; i++) { + blurred += texture2D(zero, texCoord0 + offset[i]/texSize.y) * weight[i]; + blurred += texture2D(zero, texCoord0 + offset[i]/texSize.y) * weight[i]; + } + + float posZ = sqrt(max(0.0, -position.z))/10.0; + float val = posZ + getPerceptualBrightness(color.rgb) + time/100.0; + // 0.67 - 0.37 = 0.3 + //gl_FragColor = vec4(hsv2rgb(vec3(((sin(posZ + getPerceptualBrightness(color.rgb) * 10.0)+1.0)/2.0) * 0.3 + 0.37, 1.0, 1.0)), color.a); + + gl_FragColor = vec4(hsv2rgb(vec3(abs(mod(val, 0.68)-0.34) + 0.33, 1.0, 1.0)), max(0.0, color.a*2.0 - 1.0) * sin(noiseTwoPass(vec4(worldPos.xyz / 2, time / 128.0)) * 10) * 2.0); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/bloom.frag b/src/main/resources/assets/twilightforest/shaders/bloom.frag new file mode 100644 index 0000000000..258ee35db8 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/bloom.frag @@ -0,0 +1,17 @@ +#version 120 +//#version 330 core +//layout (location = 0) out vec4 fragOut; +//layout (location = 1) out vec4 brightOut; + +uniform sampler2D texture; +uniform int time; + +uniform float yaw; +uniform float pitch; +uniform ivec2 resolution; + +varying vec3 position; +void main() { + //fragColorOut = vec4(1, 0.5, 0, 1); + //brightColorOut = vec4(0, 0.5, 1, 1); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/camera_fixed.vert b/src/main/resources/assets/twilightforest/shaders/camera_fixed.vert new file mode 100644 index 0000000000..4e1e41fbe3 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/camera_fixed.vert @@ -0,0 +1,22 @@ +#version 120 + +varying float scale; +varying vec2 texCoord0; +varying vec4 worldPos; +varying vec4 center; +varying vec4 position; + +void main() { + // gl_ModelViewMatrix * gl_ProjectionMatrix != gl_ModelViewProjectionMatrix + // gl_ProjectionMatrix * gl_ModelViewMatrix == gl_ModelViewProjectionMatrix + // P * MV = MVP + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + + worldPos = gl_Vertex; + scale = gl_NormalScale; + + center = (gl_ModelViewProjectionMatrix * vec4(vec3(0), 1)); + position = gl_ModelViewProjectionMatrix * gl_Vertex; + + texCoord0 = vec2(gl_MultiTexCoord0); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/ender.frag b/src/main/resources/assets/twilightforest/shaders/ender.frag new file mode 100644 index 0000000000..687f915101 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/ender.frag @@ -0,0 +1,87 @@ +#version 120 + +#define M_PI 3.1415926535897932384626433832795 + +// From TTFTCUTS, thanks TTFTCUTS! + +uniform sampler2D texture; +uniform int time; + +uniform float yaw; +uniform float pitch; + +varying vec3 position; + +mat4 rotationMatrix(vec3 axis, float angle) { + + axis = normalize(axis); + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; + + return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, + 0.0, 0.0, 0.0, 1.0); +} + +void main() { + // background colour + vec4 col = vec4(0.044,0.036,0.063,1); + + // get ray from camera to fragment + vec4 dir = normalize(vec4( -position, 0)); + + // rotate the ray to show the right bit of the sphere for the angle + float sb = sin(pitch); + float cb = cos(pitch); + dir = normalize(vec4(dir.x, dir.y * cb - dir.z * sb, dir.y * sb + dir.z * cb, 0)); + + float sa = sin(-yaw); + float ca = cos(-yaw); + dir = normalize(vec4(dir.z * sa + dir.x * ca, dir.y, dir.z * ca - dir.x * sa, 0)); + + vec4 ray; + + // draw the layers + for (int i=0; i<16; i++) { + int mult = 16-i; + + // get semi-random stuff + int j = i + 7; + float rand1 = (j * j * 4321 + j * 8) * 2.0F; + int k = j + 1; + float rand2 = (k * k * k * 239 + k * 37) * 3.6F; + float rand3 = rand1 * 347.4 + rand2 * 63.4; + + // random rotation matrix by random rotation around random axis + vec3 axis = normalize(vec3(sin(rand1), sin(rand2) , cos(rand3))); + + // apply + ray = dir * rotationMatrix(axis, mod(rand3, 2*M_PI)); + + // calcuate the UVs from the final ray + float u = 0.5 + (atan(ray.z,ray.x)/(2*M_PI)); + float v = 0.5 + (asin(ray.y)/M_PI); + + // get UV scaled for layers and offset by time; + float scale = mult*0.5 + 2.75; + vec2 tex = vec2( u * scale, (v + time * 0.00006) * scale * 0.6 ); + + // sample the texture + vec4 tcol = texture2D(texture, tex); + + // set the alpha, blending out at the bunched ends + float a = tcol.r * (0.05 + (1.0/mult) * 0.65) * (1-smoothstep(0.15, 0.48, abs(v-0.5))); + + // get end-portal-y colours + float r = (mod(rand1, 29.0)/29.0) * 0.5 + 0.1; + float g = (mod(rand2, 35.0)/35.0) * 0.5 + 0.4; + float b = (mod(rand1, 17.0)/17.0) * 0.5 + 0.5; + + // mix the colours + col = col*(1-a) + vec4(r,g,b,1)*a; + } + + gl_FragColor = col; +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/firefly.frag b/src/main/resources/assets/twilightforest/shaders/firefly.frag new file mode 100644 index 0000000000..ac2f14a706 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/firefly.frag @@ -0,0 +1,113 @@ +#version 120 + +uniform sampler2D zero; +uniform vec2 texSize; + +uniform float time; + +varying vec3 position; +varying vec3 worldPos; +varying vec2 texCoord0; + +float mod289(float x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);} + +// Simplex 4D Noise +// by Ian McEwan, Ashima Arts +// +vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} +float permute(float x){return floor(mod(((x*34.0)+1.0)*x, 289.0));} +vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} +float taylorInvSqrt(float r){return 1.79284291400159 - 0.85373472095314 * r;} + +vec4 grad4(float j, vec4 ip){ + const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); + vec4 p,s; + + p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; + p.w = 1.5 - dot(abs(p.xyz), ones.xyz); + s = vec4(lessThan(p, vec4(0.0))); + p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; + + return p; +} + +float snoise(vec4 v){ + const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4 + 0.309016994374947451); // (sqrt(5) - 1)/4 F4 +// First corner + vec4 i = floor(v + dot(v, C.yyyy) ); + vec4 x0 = v - i + dot(i, C.xxxx); + +// Other corners + +// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + vec4 i0; + + vec3 isX = step( x0.yzw, x0.xxx ); + vec3 isYZ = step( x0.zww, x0.yyz ); +// i0.x = dot( isX, vec3( 1.0 ) ); + i0.x = isX.x + isX.y + isX.z; + i0.yzw = 1.0 - isX; + +// i0.y += dot( isYZ.xy, vec2( 1.0 ) ); + i0.y += isYZ.x + isYZ.y; + i0.zw += 1.0 - isYZ.xy; + + i0.z += isYZ.z; + i0.w += 1.0 - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + vec4 i3 = clamp( i0, 0.0, 1.0 ); + vec4 i2 = clamp( i0-1.0, 0.0, 1.0 ); + vec4 i1 = clamp( i0-2.0, 0.0, 1.0 ); + + // x0 = x0 - 0.0 + 0.0 * C + vec4 x1 = x0 - i1 + 1.0 * C.xxxx; + vec4 x2 = x0 - i2 + 2.0 * C.xxxx; + vec4 x3 = x0 - i3 + 3.0 * C.xxxx; + vec4 x4 = x0 - 1.0 + 4.0 * C.xxxx; + +// Permutations + i = mod(i, 289.0); + float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x); + vec4 j1 = permute( permute( permute( permute ( + i.w + vec4(i1.w, i2.w, i3.w, 1.0 )) + + i.z + vec4(i1.z, i2.z, i3.z, 1.0 )) + + i.y + vec4(i1.y, i2.y, i3.y, 1.0 )) + + i.x + vec4(i1.x, i2.x, i3.x, 1.0 )); +// Gradients +// ( 7*7*6 points uniformly over a cube, mapped onto a 4-octahedron.) +// 7*7*6 = 294, which is close to the ring size 17*17 = 289. + + vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ; + + vec4 p0 = grad4(j0, ip); + vec4 p1 = grad4(j1.x, ip); + vec4 p2 = grad4(j1.y, ip); + vec4 p3 = grad4(j1.z, ip); + vec4 p4 = grad4(j1.w, ip); + +// Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= taylorInvSqrt(dot(p4,p4)); + +// Mix contributions from the five corners + vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); + vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0); + m0 = m0 * m0; + m1 = m1 * m1; + return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) + + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; +} + +void main() { + vec4 color = texture2D(zero, vec2(texCoord0)); + + gl_FragColor = vec4( (color.xyz * 0.5 + 0.5) * vec3( 0.7529411765, 1.0, 0.0 ), color.a * sin(snoise(vec4(worldPos.xyz, time / 128.0))) * 2.0 - 0.75); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/grid_lock.frag b/src/main/resources/assets/twilightforest/shaders/grid_lock.frag new file mode 100644 index 0000000000..280dee8833 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/grid_lock.frag @@ -0,0 +1,70 @@ +#version 120 + +uniform sampler2D zero; +uniform float time; + +uniform float yaw; +uniform float pitch; +uniform ivec2 resolution; + +varying vec2 texCoord0; +varying vec4 worldPos; +varying vec4 position; +varying vec4 center; +varying vec4 centerCoord; +varying float scale; + +// Thanks Amadornes! :3 + +// Utils +vec2 convolve(vec2 pos, float off, float strength) { + float amt = length(pos) * strength + off; + float arc = atan(pos.x, pos.y); + return vec2(cos(arc + amt), sin(arc + amt)) * length(pos); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +void main() { + // Do NOT move these to the vertex shader! The interpolation of vert->Frag will cause visual shearing + vec4 center_frag = center / center.w; + vec4 position_frag = position / position.w; + vec4 centerCoord_frag = center_frag - position_frag; + + vec4 tex = texture2D(zero, vec2(texCoord0)); + + ////tex.a = 1; + + ////float posZ = sqrt(abs((center - position).z)) * 10; + + //vec2 pos = (position - center).xy / 2; + //vec2 realPos = convolve(pos, -time/10.0, 75.0); + + //if(abs(realPos.x) < abs(realPos.y) && realPos.y <= 0.0 && realPos.y >= -0.2) { + // gl_FragColor = vec4(vec3(1.0), 1.0); + //} else { + // gl_FragColor = tex; + //} + + // fixme debug + //gl_FragColor = tex; + + float posZ = 1;//sqrt(abs(center.z)); + + //float len = length(vec2(position.y, 1)); + float len = length(centerCoord_frag.w); + + gl_FragColor = vec4(0);//vec4(vec3(len), 1.0); + if ( mod(len, 0.05) < 0.01 && mod(len, 0.05) > 0 ) { gl_FragColor = vec4(hsv2rgb(vec3(len * 4, 1, 1)), 1.0); } + + if ( mod(centerCoord_frag.x, 0.05) < 0.005 && mod(centerCoord_frag.x, 0.05) > 0 ) { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } + if ( mod(centerCoord_frag.y, 0.05) < 0.005 && mod(centerCoord_frag.y, 0.05) > 0 ) { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } + + //gl_FragColor = vec4(vec3(position.xyz), 1.0); + + //gl_FragColor = vec4(hsv2rgb(vec3(position.w - mod(position.w, 0.05), 1, 1)), 1.0); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/normals.frag b/src/main/resources/assets/twilightforest/shaders/normals.frag new file mode 100644 index 0000000000..561a30339e --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/normals.frag @@ -0,0 +1,26 @@ +#version 120 + +uniform sampler2D zero; +//uniform sampler2D one; +uniform int time; + +uniform float yaw; +uniform float pitch; + +varying vec2 texCoord0; +//varying vec2 texCoord1; +varying vec3 position; + +varying vec3 normals; +varying vec3 camNorms; + +// https://gist.github.com/antoineMoPa/dea8e2f8495f6e5edcf724569ba5feae + +void main() { + vec4 tex = texture2D(zero, vec2(texCoord0)); + //vec4 light = texture2D(one, vec2(texCoord1)); + + //gl_FragColor = vec4(abs(normal) * 2 - 1, tex.a); + + gl_FragColor = vec4(abs(camNorms), 1) * tex; +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/outline.frag b/src/main/resources/assets/twilightforest/shaders/outline.frag new file mode 100644 index 0000000000..3de3c7818e --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/outline.frag @@ -0,0 +1,10 @@ +#version 120 + +uniform sampler2D zero; + +varying vec2 texCoord0; +varying vec4 colorIn; + +void main() { + gl_FragColor = vec4(1);//colorIn; +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/outline.vert b/src/main/resources/assets/twilightforest/shaders/outline.vert new file mode 100644 index 0000000000..10183ba0c2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/outline.vert @@ -0,0 +1,14 @@ +#version 120 + + varying vec3 position; + varying vec2 texCoord0; + varying vec4 colorIn; + + void main() { + gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex + vec4((gl_Normal * 0.1), 0)); + position = (gl_ModelViewMatrix * gl_Vertex).xyz; + + texCoord0 = vec2(gl_MultiTexCoord0); + + colorIn = gl_Color; + } \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/projection.frag b/src/main/resources/assets/twilightforest/shaders/projection.frag new file mode 100644 index 0000000000..99761c734d --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/projection.frag @@ -0,0 +1,27 @@ +#version 120 + +// TODO Code needs integrating. Originally written in shadertoy. + +// Rounds the value to either 0 or 1. 0.5 is the threshold. +vec4 roundEither(vec4 valueIn) { + vec4 valueOut = valueIn + 0.5; + + return valueOut - mod(valueOut, 1.0); +} + +void main( in vec2 fragCoord ) { + // Ticker used for progression. + // TODO Change to a uniform for time progression + float tick = mod(iTime, 2.0) / 2.0; + + // Transform screen position into percent + vec2 uv = fragCoord.xy / iResolution.xy; + + // Sampler, Texture in + vec4 texVal = texture( iChannel0, uv ); + + // tests the distance from a source + float distanceFrom = distance(uv*vec2(2,1), vec2(1,0)); + + gl_FragColor = roundEither(texVal - (distanceFrom - (tick * 2.0))); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/pulsing.frag b/src/main/resources/assets/twilightforest/shaders/pulsing.frag new file mode 100644 index 0000000000..be42787219 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/pulsing.frag @@ -0,0 +1,36 @@ +#version 120 + +#define M_PI 3.1415926535897932384626433832795 + +uniform sampler2D zero; +uniform float time; +uniform ivec2 resolution; + +uniform float ringCount = 3; +uniform float ringThickness = 0.3679; + +varying float scale; +varying vec2 texCoord0; +varying vec4 worldPos; + +varying vec4 center; +varying vec4 position; + +void main() { + // Do NOT move these to the vertex shader! The interpolation of vertex->fragment will cause visual shearing + vec4 centerCoord_frag = (center / center.w) - (position / position.w); + float posZ = (0.55 + center.w * 0.45);//sqrt(abs(center_z_frag.z - position_frag.z)) * 5; + vec2 pos = vec2(centerCoord_frag.x * (float(resolution.x)/float(resolution.y)), centerCoord_frag.y) * posZ * posZ * 0.9; + // Begin actual shader code + + vec4 tex = texture2D(zero, vec2(texCoord0)); + + // 3D effect variation + //float dist = length(worldPos.xyz * scale) * 2; + // 2D effect variation + float dist = length(pos) * 2; + + float wave = floor(fract(ringCount * dist * dist - time / 30) + ringThickness); + + gl_FragColor = vec4( max(wave - dist, 0) * 0.592 + 0.339 * tex.r, 0, 0, tex.a ); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/pulsing_yellow.frag b/src/main/resources/assets/twilightforest/shaders/pulsing_yellow.frag new file mode 100644 index 0000000000..d60db283a5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/pulsing_yellow.frag @@ -0,0 +1,132 @@ +#version 120 + +uniform sampler2D zero; +uniform float time; + +uniform float yaw; +uniform float pitch; + +varying float scale; +varying vec2 texCoord0; +varying vec3 worldPos; + +float mod289(float x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);} + +// Simplex 4D Noise +// by Ian McEwan, Ashima Arts +// +vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} +float permute(float x){return floor(mod(((x*34.0)+1.0)*x, 289.0));} +vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} +float taylorInvSqrt(float r){return 1.79284291400159 - 0.85373472095314 * r;} + +vec4 grad4(float j, vec4 ip){ + const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); + vec4 p,s; + + p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; + p.w = 1.5 - dot(abs(p.xyz), ones.xyz); + s = vec4(lessThan(p, vec4(0.0))); + p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; + + return p; +} + +float snoise(vec4 v){ + const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4 + 0.309016994374947451); // (sqrt(5) - 1)/4 F4 +// First corner + vec4 i = floor(v + dot(v, C.yyyy) ); + vec4 x0 = v - i + dot(i, C.xxxx); + +// Other corners + +// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + vec4 i0; + + vec3 isX = step( x0.yzw, x0.xxx ); + vec3 isYZ = step( x0.zww, x0.yyz ); +// i0.x = dot( isX, vec3( 1.0 ) ); + i0.x = isX.x + isX.y + isX.z; + i0.yzw = 1.0 - isX; + +// i0.y += dot( isYZ.xy, vec2( 1.0 ) ); + i0.y += isYZ.x + isYZ.y; + i0.zw += 1.0 - isYZ.xy; + + i0.z += isYZ.z; + i0.w += 1.0 - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + vec4 i3 = clamp( i0, 0.0, 1.0 ); + vec4 i2 = clamp( i0-1.0, 0.0, 1.0 ); + vec4 i1 = clamp( i0-2.0, 0.0, 1.0 ); + + // x0 = x0 - 0.0 + 0.0 * C + vec4 x1 = x0 - i1 + 1.0 * C.xxxx; + vec4 x2 = x0 - i2 + 2.0 * C.xxxx; + vec4 x3 = x0 - i3 + 3.0 * C.xxxx; + vec4 x4 = x0 - 1.0 + 4.0 * C.xxxx; + +// Permutations + i = mod(i, 289.0); + float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x); + vec4 j1 = permute( permute( permute( permute ( + i.w + vec4(i1.w, i2.w, i3.w, 1.0 )) + + i.z + vec4(i1.z, i2.z, i3.z, 1.0 )) + + i.y + vec4(i1.y, i2.y, i3.y, 1.0 )) + + i.x + vec4(i1.x, i2.x, i3.x, 1.0 )); +// Gradients +// ( 7*7*6 points uniformly over a cube, mapped onto a 4-octahedron.) +// 7*7*6 = 294, which is close to the ring size 17*17 = 289. + + vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ; + + vec4 p0 = grad4(j0, ip); + vec4 p1 = grad4(j1.x, ip); + vec4 p2 = grad4(j1.y, ip); + vec4 p3 = grad4(j1.z, ip); + vec4 p4 = grad4(j1.w, ip); + +// Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= taylorInvSqrt(dot(p4,p4)); + +// Mix contributions from the five corners + vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); + vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0); + m0 = m0 * m0; + m1 = m1 * m1; + return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) + + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; +} + +float fracNoise(vec4 n) { + return (snoise(n) + snoise(vec4(n.xyz/2, n.w)) + snoise(vec4(n.xyz/4, n.w)))/2.5; +} + +float round(float n) { + float y = n + 0.5; + + return y - mod(y, 1.0); +} + +void main() { + vec4 tex = texture2D(zero, vec2(texCoord0)); + float timing = fracNoise(vec4(worldPos.xyz * 4, time / 25)); + + timing = clamp(timing / 2 + 0.5, 0, 1); + //tex.a = clamp(tex.a * 1.5 - 0.375, 0, 1); + //tex.a = clamp((tex.a * 1.5 - 0.375 + round(tex.a)) / 2, 0, 1); + //float oldA = tex.a; + tex.a = clamp(tex.a * 2 - 0.5, 0, 1); + + gl_FragColor = vec4( 0.729 * tex.a, 0.933 * tex.a, 0.0078 * tex.a, tex.a + tex.a * 0.5 ) * timing; + //gl_FragColor = vec4(vec3(timing), 1); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/shield.frag b/src/main/resources/assets/twilightforest/shaders/shield.frag new file mode 100644 index 0000000000..71950111fd --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/shield.frag @@ -0,0 +1,145 @@ +#version 120 + +#define M_PI 3.1415926535897932384626433832795 + +uniform sampler2D texture; +uniform float time; +uniform vec3 position; + +uniform vec2 secondPass = vec2(2.0, 1.0); +uniform vec2 thirdPass = vec2(3.0, 1.0); +uniform vec2 fourthPass = vec2(4.0, 1.0); +uniform vec2 fifthPass = vec2(5.0, 1.0); +uniform vec2 sixthPass = vec2(6.0, 1.0); +uniform vec2 seventhPass = vec2(7.0, 1.0); +uniform vec2 eighthPass = vec2(8.0, 1.0); + +varying vec2 texCoord0; + +varying vec3 worldPos; + +varying vec4 colorIn; + +float mod289(float x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;} +vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);} + +// Simplex 4D Noise +// by Ian McEwan, Ashima Arts +// +vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} +float permute(float x){return floor(mod(((x*34.0)+1.0)*x, 289.0));} +vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} +float taylorInvSqrt(float r){return 1.79284291400159 - 0.85373472095314 * r;} + +vec4 grad4(float j, vec4 ip){ + const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0); + vec4 p,s; + + p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0; + p.w = 1.5 - dot(abs(p.xyz), ones.xyz); + s = vec4(lessThan(p, vec4(0.0))); + p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; + + return p; +} + +float snoise(vec4 v){ + const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4 + 0.309016994374947451); // (sqrt(5) - 1)/4 F4 +// First corner + vec4 i = floor(v + dot(v, C.yyyy) ); + vec4 x0 = v - i + dot(i, C.xxxx); + +// Other corners + +// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) + vec4 i0; + + vec3 isX = step( x0.yzw, x0.xxx ); + vec3 isYZ = step( x0.zww, x0.yyz ); +// i0.x = dot( isX, vec3( 1.0 ) ); + i0.x = isX.x + isX.y + isX.z; + i0.yzw = 1.0 - isX; + +// i0.y += dot( isYZ.xy, vec2( 1.0 ) ); + i0.y += isYZ.x + isYZ.y; + i0.zw += 1.0 - isYZ.xy; + + i0.z += isYZ.z; + i0.w += 1.0 - isYZ.z; + + // i0 now contains the unique values 0,1,2,3 in each channel + vec4 i3 = clamp( i0, 0.0, 1.0 ); + vec4 i2 = clamp( i0-1.0, 0.0, 1.0 ); + vec4 i1 = clamp( i0-2.0, 0.0, 1.0 ); + + // x0 = x0 - 0.0 + 0.0 * C + vec4 x1 = x0 - i1 + 1.0 * C.xxxx; + vec4 x2 = x0 - i2 + 2.0 * C.xxxx; + vec4 x3 = x0 - i3 + 3.0 * C.xxxx; + vec4 x4 = x0 - 1.0 + 4.0 * C.xxxx; + +// Permutations + i = mod(i, 289.0); + float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x); + vec4 j1 = permute( permute( permute( permute ( + i.w + vec4(i1.w, i2.w, i3.w, 1.0 )) + + i.z + vec4(i1.z, i2.z, i3.z, 1.0 )) + + i.y + vec4(i1.y, i2.y, i3.y, 1.0 )) + + i.x + vec4(i1.x, i2.x, i3.x, 1.0 )); +// Gradients +// ( 7*7*6 points uniformly over a cube, mapped onto a 4-octahedron.) +// 7*7*6 = 294, which is close to the ring size 17*17 = 289. + + vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ; + + vec4 p0 = grad4(j0, ip); + vec4 p1 = grad4(j1.x, ip); + vec4 p2 = grad4(j1.y, ip); + vec4 p3 = grad4(j1.z, ip); + vec4 p4 = grad4(j1.w, ip); + +// Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + p4 *= taylorInvSqrt(dot(p4,p4)); + +// Mix contributions from the five corners + vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); + vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0); + m0 = m0 * m0; + m1 = m1 * m1; + return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) + + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; +} + +float noiseMultiPass(vec4 v) { + return snoise(v) + + snoise(v/secondPass .xxxx) + + snoise(v/thirdPass .xxxx) + + snoise(v/fourthPass .xxxx) + + snoise(v/fifthPass .xxxx) + + snoise(v/sixthPass .xxxx) + + snoise(v/seventhPass.xxxx) + + snoise(v/eighthPass .xxxx) + ; +} + +void main( void ) { + vec4 tex = texture2D(texture, vec2(texCoord0)); + + float noise = noiseMultiPass(vec4(worldPos * 2.5, time/100)) * 0.25 + 0.5; + //float noise2 = noiseTwoPass(vec4(worldPos * 2, time/50)) * 0.25 + 0.5; + + //float effect = sin(time/10 + noise * 10 + worldPos.y * 10) * 2 - 1; + float effect = sin(time/10 + noise * 20) * 1.5 - 0.5; + float effect2 = sin(time/5 + noise * 10) * 100 - 99; + + //gl_FragColor = vec4(vec3(1, 1, 0.5), tex.a * effect); + gl_FragColor = vec4(vec3(max(effect, effect2)), 1); + //gl_FragColor = vec4(vec3(noise), 1); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/spiral.frag b/src/main/resources/assets/twilightforest/shaders/spiral.frag new file mode 100644 index 0000000000..e081ad2725 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/spiral.frag @@ -0,0 +1,54 @@ +#version 120 + +uniform sampler2D zero; +uniform float time; + +uniform float yaw; +uniform float pitch; +uniform ivec2 resolution; + +varying float scale; +varying vec2 texCoord0; +varying vec4 worldPos; +varying vec4 center; +varying vec4 position; + +// Thanks Amadornes! :3 + +// Utils +vec2 convolve(vec2 pos, float off, float strength) { + float amt = length(pos) * strength + off; + float arc = atan(pos.x, pos.y); + return vec2(cos(arc + amt), sin(arc + amt)) * length(pos); +} + +float getPerceptualBrightness(vec3 c) { + return sqrt(0.241 * c.r * c.r + 0.691 * c.g * c.g + 0.068 * c.b * c.b); +} + +void main() { + // Do NOT move these to the vertex shader! The interpolation of vertex->fragment will cause visual shearing + float dist = center.w; + vec4 center_frag = center / center.w; + //vec4 center_z_frag = center_z / center_z.w; + vec4 position_frag = position / position.w; + vec4 centerCoord_frag = center_frag - position_frag; + + vec4 tex = texture2D(zero, vec2(texCoord0)); + float gray = getPerceptualBrightness(tex.xyz); + float posZ = (0.55 + dist * 0.45);//sqrt(abs(center_z_frag.z - position_frag.z)) * 5; + + vec2 pos = vec2(centerCoord_frag.x * (float(resolution.x)/float(resolution.y)), centerCoord_frag.y) * posZ * posZ * 0.9; + vec2 realPos = convolve(pos, -time/10.0, 65.0 / posZ); + + if(tex.a != 0.0 && abs(realPos.x) < abs(realPos.y) && realPos.y <= 0.0) { + float col = max(0.0, 1.5 + 6 * realPos.y); + float col2 = max(0.0, 1.5 + 8 * realPos.y) - 0.5; + + gl_FragColor = vec4(max(col, 0.2862), col2, col2, /*max(0.0, 1.5 + 8 * realPos.y) * */tex.a * gray); + } else { + gl_FragColor = vec4(0.2862, 0, 0, tex.a * gray); + } + + //gl_FragColor = vec4(realPos * 0.5 + 0.5, 0, 1); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/spiral_2.frag b/src/main/resources/assets/twilightforest/shaders/spiral_2.frag new file mode 100644 index 0000000000..c2ac808e50 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/spiral_2.frag @@ -0,0 +1,54 @@ +//precision highp float; + +#version 120 + +uniform sampler2D zero; +uniform float time; + +uniform float yaw; +uniform float pitch; +uniform ivec2 resolution; + +varying vec4 center; +varying vec2 texCoord0; +varying vec3 worldPos; +varying vec4 position; + +varying vec3 centerCoord; + +// Thanks Amadornes! :3 + +// Utils +vec2 convolve(vec2 pos, float off, float strength) { + float amt = -length(pos) * strength + off; + float arc = atan(pos.x, pos.y); + return vec2(cos(arc + amt), sin(arc + amt)) * length(pos); +} + +void main() { + vec4 tex = texture2D(zero, vec2(texCoord0)); + + //tex.a = 1; + + //float posZ = sqrt(abs(centerCoord.z)) * 10; + + //vec2 pos = centerCoord.xy; + //vec2 realPos = convolve(pos * posZ, -time/10.0, 50.0); + + //if(abs(realPos.x) < abs(realPos.y) && realPos.y <= 0.0 && realPos.y >= -0.2) { + // gl_FragColor = vec4(vec3(1.0), tex.a); + //} else { + // gl_FragColor = vec4(vec3(0.0), tex.a); + //} + + // fixme debug + gl_FragColor.xyz = centerCoord; + gl_FragColor.a = 1.0; + + float posZ = 1;//sqrt(abs(center.z)); + + if (length(centerCoord.xy) < 0.1 * posZ) { gl_FragColor = vec4(vec3(0.5), 1.0); } + if (length(centerCoord.xy) < 0.05 * posZ) { gl_FragColor = vec4(1.0); } + + gl_FragColor = vec4(position.xy, 1, 1); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/spiral_fixed.frag b/src/main/resources/assets/twilightforest/shaders/spiral_fixed.frag new file mode 100644 index 0000000000..cbee013682 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/spiral_fixed.frag @@ -0,0 +1,36 @@ +//precision highp float; + +#version 120 + +uniform sampler2D zero; +uniform float time; + +uniform float yaw; +uniform float pitch; +uniform ivec2 resolution; + +varying vec2 texCoord0; + +// Thanks Amadornes! :3 + +// Utils +vec2 convolve(vec2 pos, float off, float strength) { + float amt = length(pos) * strength + off; + float arc = atan(pos.x, pos.y); + return vec2(cos(arc + amt), sin(arc + amt)) * length(pos); +} + +void main() { + vec4 tex = texture2D(zero, vec2(texCoord0)); + + tex.a = 1; + + vec2 pos = (gl_FragCoord.xy/resolution) * 2.0 - 1.0; + vec2 realPos = convolve(pos, -time/10.0, 50.0); + + if(abs(realPos.x) < abs(realPos.y) && realPos.y <= 0.0 && realPos.y >= -0.2) { + gl_FragColor = vec4(vec3(1.0), tex.a); + } else { + gl_FragColor = vec4(vec3(0.0), tex.a); + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/standard.vert b/src/main/resources/assets/twilightforest/shaders/standard.vert new file mode 100644 index 0000000000..e71d1de9e1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/standard.vert @@ -0,0 +1,11 @@ +#version 120 + +// From TTFTCUTS, thanks TTFTCUTS! + +varying vec3 position; + +void main() +{ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + position = (gl_ModelViewMatrix * gl_Vertex).xyz; +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/standard_texcoord.vert b/src/main/resources/assets/twilightforest/shaders/standard_texcoord.vert new file mode 100644 index 0000000000..ed2d324bd1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/standard_texcoord.vert @@ -0,0 +1,13 @@ +#version 120 + +// From TTFTCUTS, thanks TTFTCUTS! + +varying vec3 position; +varying vec2 texCoord0; + +void main() { + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + position = (gl_ModelViewMatrix * gl_Vertex).xyz; + + texCoord0 = vec2(gl_MultiTexCoord0); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/standard_texcoord2.vert b/src/main/resources/assets/twilightforest/shaders/standard_texcoord2.vert new file mode 100644 index 0000000000..828bdc9de4 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/standard_texcoord2.vert @@ -0,0 +1,19 @@ +#version 120 + +varying vec3 position; +varying vec3 worldPos; +varying vec2 texCoord0; +varying float scale; +varying vec4 colorIn; + +void main() { + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + position = (gl_ModelViewMatrix * gl_Vertex).xyz; + + worldPos = gl_Vertex.xyz; + scale = gl_NormalScale; + + texCoord0 = vec2(gl_MultiTexCoord0); + + colorIn = gl_Color; +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/standard_texcoord_normals.vert b/src/main/resources/assets/twilightforest/shaders/standard_texcoord_normals.vert new file mode 100644 index 0000000000..1d7ef05041 --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/standard_texcoord_normals.vert @@ -0,0 +1,24 @@ +#version 120 + +// From TTFTCUTS, thanks TTFTCUTS! + +varying vec3 position; +varying vec2 texCoord0; +varying vec2 texCoord1; + +varying vec3 normals; +varying vec3 camNorms; + +void main() { + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + position = (gl_ModelViewMatrix * gl_Vertex).xyz; + + texCoord0 = vec2(gl_MultiTexCoord0); + texCoord1 = vec2(gl_MultiTexCoord1); + + normals = gl_Normal; + camNorms = gl_NormalMatrix * gl_Normal; + + // to make a color from the normals do: + // gl_FragColor = vec4(abs(normal), 1) * tex; +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/starburst.frag b/src/main/resources/assets/twilightforest/shaders/starburst.frag new file mode 100644 index 0000000000..3fde91d57b --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/starburst.frag @@ -0,0 +1,29 @@ +#version 120 + +#define M_PI 3.1415926535897932384626433832795 + +uniform sampler2D texture; +uniform float time; +uniform vec3 position; + +varying vec2 texCoord0; + +varying vec3 worldPos; + +varying vec4 colorIn; + +float roundEither(float valueIn) { + float valueOut = valueIn + 0.5; + + return valueOut - mod(valueOut, 1.0); +} + +void main( void ) { + vec4 tex = texture2D(texture, vec2(texCoord0)); + + float ray = atan( (worldPos.y)/(worldPos.x) ) / M_PI * 2.0; + + float burst = roundEither(mod(ray + time/100.0, 0.5)*2.0); + + gl_FragColor = vec4(colorIn.xyz * 0.6666 + 0.3333, burst*tex.r); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/shaders/twilight_sky.frag b/src/main/resources/assets/twilightforest/shaders/twilight_sky.frag new file mode 100644 index 0000000000..281366d1dd --- /dev/null +++ b/src/main/resources/assets/twilightforest/shaders/twilight_sky.frag @@ -0,0 +1,101 @@ +#version 120 + +#define M_PI 3.1415926535897932384626433832795 + +// Modifed version of ender.frag + +uniform sampler2D zero; // Main minecraft atlas +uniform sampler2D two; // Stars + +uniform float time; + +uniform float yaw; +uniform float pitch; +uniform ivec2 resolution; + +varying vec3 position; +varying vec3 worldPos; + +varying vec2 texCoord0; + +vec4 interpolate(vec4 v1, vec4 v2, float placement) { + placement = clamp(placement, 0.0, 1.0); + return sqrt(((v1 * v1) * (1.0 - placement)) + ((v2 * v2) * placement)); +} + +mat4 rotationMatrix(vec3 axis, float angle){ + axis = normalize(axis); + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; + + return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, + 0.0, 0.0, 0.0, 1.0); +} + +void main() { + float fixedPitch = (pitch/3.2) + 0.5; + float fixedY = gl_FragCoord.y / (resolution.y / 2.0); + + // background colour + vec4 sky = vec4( 40.0 / 255.0, 37.0 / 255.0, 63.0 / 255.0, 1.0 ); + // fog color + vec4 fog = vec4( 0.39905882, 0.53, 0.46164703, 1.0 ); + + float fogHeight = ((fixedPitch - 0.5) * 18) + ((fixedY - 0.9) * 4); + + vec4 col = interpolate(fog, sky, fogHeight); + + // get ray from camera to fragment + vec4 dir = normalize(vec4( -position, 0)); + + // rotate the ray to show the right bit of the sphere for the angle + float sb = sin(pitch); + float cb = cos(pitch); + dir = normalize(vec4(dir.x, dir.y * cb - dir.z * sb, dir.y * sb + dir.z * cb, 0)); + + float sa = sin(-yaw); + float ca = cos(-yaw); + dir = normalize(vec4(dir.z * sa + dir.x * ca, dir.y, dir.z * ca - dir.x * sa, 0)); + + vec4 ray; + + // draw the layers + for (int i=0; i<4; i++) { + int mult = 4-i; + + // get semi-random stuff + int j = i + 7; + float rand1 = (j * j * 4321 + j * 8) * 2.0F; + int k = j + 1; + float rand2 = (k * k * k * 239 + k * 37) * 3.6F; + float rand3 = rand1 * 347.4 + rand2 * 63.4; + + // random rotation matrix by random rotation around random axis + vec3 axis = normalize(vec3(sin(rand1), sin(rand2) , cos(rand3))); + + // apply + ray = dir * rotationMatrix(axis, mod(rand3, 2*M_PI)); + + // calcuate the UVs from the final ray + float u = 0.5 + (atan(ray.z,ray.x)/(2*M_PI)); + float v = 0.5 + (asin(ray.y)/M_PI); + + // get UV scaled for layers and offset by time; + float scale = mult*0.5 + 2.75; + vec2 tex = vec2( u * scale, (v + time * 0.00006) * scale * 0.6 ); + + // sample the texture + vec4 tcol = texture2D(two, tex); + + // set the alpha, blending out at the bunched ends + float a = tcol.r == 1 ? 1 : 0; // * (0.05 + (1.0/mult) * 0.65) * (1-smoothstep(0.15, 0.48, abs(v-0.5))); + + // mix the colours + col = col*(1-a) + vec4(1)*a; + } + + gl_FragColor = vec4(col.xyz, texture2D(zero, vec2(texCoord0)).a);//roundEither(texture2D(zero, vec2(texCoord0)).a * 2.0-1)); +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/sounds.json b/src/main/resources/assets/twilightforest/sounds.json index 99e3187038..ad3da4392b 100644 --- a/src/main/resources/assets/twilightforest/sounds.json +++ b/src/main/resources/assets/twilightforest/sounds.json @@ -1,229 +1,71 @@ { - "mob.kobold.die": { - "category": "hostile", - "sounds": [ - "mob/kobold/die0", - "mob/kobold/die1", - "mob/kobold/die2" - ] - }, - "mob.kobold.kobold": { - "category": "hostile", - "sounds": [ - "mob/kobold/kobold0", - "mob/kobold/kobold1", - "mob/kobold/kobold2", - "mob/kobold/kobold3", - "mob/kobold/kobold4", - "mob/kobold/kobold5" - ] - }, - "mob.kobold.hurt": { - "category": "hostile", - "sounds": [ - "mob/kobold/hurt0", - "mob/kobold/hurt1", - "mob/kobold/hurt2" - ] - }, - "mob.cicada": { - "category": "ambient", - "sounds": [ - "mob/cicada0", - "mob/cicada1" - ] - }, - "mob.naga.hiss": { - "category": "hostile", - "sounds": [ - "mob/naga/hiss0", - "mob/naga/hiss1", - "mob/naga/hiss2" - ] - }, - "mob.naga.hurt": { - "category": "hostile", - "sounds": [ - "mob/naga/hurt0", - "mob/naga/hurt1", - "mob/naga/hurt2" - ] - }, - "mob.naga.rattle": { - "category": "hostile", - "sounds": [ - "mob/naga/rattle0", - "mob/naga/rattle1" - ] - }, - "mob.raven.caw": { - "category": "neutral", - "sounds": [ - "mob/raven/caw0", - "mob/raven/caw1" - ] - }, - "mob.raven.squawk": { - "category": "neutral", - "sounds": [ - "mob/raven/squawk0", - "mob/raven/squawk1" - ] - }, - "mob.redcap.die": { - "category": "hostile", - "sounds": [ - "mob/redcap/die0", - "mob/redcap/die1", - "mob/redcap/die2" - ] - }, - "mob.redcap.redcap": { - "category": "hostile", - "sounds": [ - "mob/redcap/redcap0", - "mob/redcap/redcap1", - "mob/redcap/redcap2", - "mob/redcap/redcap3", - "mob/redcap/redcap4", - "mob/redcap/redcap5" - ] - }, - "mob.redcap.hurt": { - "category": "hostile", - "sounds": [ - "mob/redcap/hurt0", - "mob/redcap/hurt1", - "mob/redcap/hurt2", - "mob/redcap/hurt3" - ] - }, - "mob.tinybird.chirp": { - "category": "neutral", - "sounds": [ - "mob/tinybird/chirp0", - "mob/tinybird/chirp1", - "mob/tinybird/chirp2" - ] - }, - "mob.tinybird.hurt": { - "category": "neutral", - "sounds": [ - "mob/tinybird/hurt0", - "mob/tinybird/hurt1" - ] - }, - "mob.tinybird.song": { - "category": "neutral", - "sounds": [ - "mob/tinybird/song0", - "mob/tinybird/song1" - ] - }, - "mob.urghast.trapactive": { - "category": "block", - "sounds": [ - "mob/urghast/trapactive" - ] - }, - "mob.urghast.trapon": { - "category": "block", - "sounds": [ - "mob/urghast/trapon0", - "mob/urghast/trapon1", - "mob/urghast/trapon2", - "mob/urghast/trapon3", - "mob/urghast/trapon4" - ] - }, - "mob.urghast.trapspindown": { - "category": "block", - "sounds": [ - "mob/urghast/trapspindown" - ] - }, - "mob.urghast.trapwarmup": { - "category": "block", - "sounds": [ - "mob/urghast/trapwarmup" - ] - }, - "mob.wraith.wraith": { - "category": "block", - "sounds": [ - "mob/wraith/wraith0", - "mob/wraith/wraith1", - "mob/wraith/wraith2", - "mob/wraith/wraith3" - ] - }, - "mob.hydra.hurt": { - "category": "hostile", - "sounds": [ - "mob/hydra/hurt0", - "mob/hydra/hurt1", - "mob/hydra/hurt2", - "mob/hydra/hurt3" - ] - }, - "mob.hydra.death": { - "category": "hostile", - "sounds": [ - "mob/hydra/death0" - ] - }, - "mob.hydra.growl": { - "category": "hostile", - "sounds": [ - "mob/hydra/growl0", - "mob/hydra/growl1", - "mob/hydra/growl2" - ] - }, - "mob.hydra.roar": { - "category": "hostile", - "sounds": [ - "mob/hydra/roar0", - "mob/hydra/roar1" - ] - }, - "mob.hydra.warn": { - "category": "hostile", - "sounds": [ - "mob/hydra/warn0" - ] - }, - "mob.mosquito.mosquito": { - "category": "hostile", - "sounds": [ - "mob/mosquito/animals132" - ] - }, - "mob.ice.noise": { - "category": "hostile", - "sounds": [ - "mob/ice/noise0", - "mob/ice/noise1" - ] - }, - "mob.ice.hurt": { - "category": "hostile", - "sounds": [ - "mob/ice/hurt0", - "mob/ice/hurt1" - ] - }, - "mob.ice.death": { - "category": "hostile", - "sounds": [ - "mob/ice/death0", - "mob/ice/death1" - ] - }, - "random.slider": { - "category": "block", - "sounds": [ - "random/creakgo2" - ] - } + "mob.kobold.die": { "sounds": [ "twilightforest:mob/kobold/die0", "twilightforest:mob/kobold/die1", "twilightforest:mob/kobold/die2" ] }, + "mob.kobold.kobold": { "sounds": [ "twilightforest:mob/kobold/kobold0", "twilightforest:mob/kobold/kobold1", "twilightforest:mob/kobold/kobold2", "twilightforest:mob/kobold/kobold3", "twilightforest:mob/kobold/kobold4", "twilightforest:mob/kobold/kobold5" ] }, + "mob.kobold.hurt": { "sounds": [ "twilightforest:mob/kobold/hurt0", "twilightforest:mob/kobold/hurt1", "twilightforest:mob/kobold/hurt2" ] }, + "mob.kobold.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.kobold.kobold", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.cicada": { "sounds": [ "twilightforest:mob/cicada0", "twilightforest:mob/cicada1" ] }, + "mob.naga.hiss": { "sounds": [ "twilightforest:mob/naga/hiss0", "twilightforest:mob/naga/hiss1", "twilightforest:mob/naga/hiss2" ] }, + "mob.naga.hurt": { "sounds": [ "twilightforest:mob/naga/hurt0", "twilightforest:mob/naga/hurt1", "twilightforest:mob/naga/hurt2" ] }, + "mob.naga.rattle": { "sounds": [ "twilightforest:mob/naga/rattle0", "twilightforest:mob/naga/rattle1" ] }, + "mob.naga.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.naga.rattle", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.raven.caw": { "sounds": [ "twilightforest:mob/raven/caw0", "twilightforest:mob/raven/caw1" ] }, + "mob.raven.squawk": { "sounds": [ "twilightforest:mob/raven/squawk0", "twilightforest:mob/raven/squawk1" ] }, + "mob.redcap.die": { "sounds": [ "twilightforest:mob/redcap/die0", "twilightforest:mob/redcap/die1", "twilightforest:mob/redcap/die2" ] }, + "mob.redcap.redcap": { "sounds": [ "twilightforest:mob/redcap/redcap0", "twilightforest:mob/redcap/redcap1", "twilightforest:mob/redcap/redcap2", "twilightforest:mob/redcap/redcap3", "twilightforest:mob/redcap/redcap4", "twilightforest:mob/redcap/redcap5" ] }, + "mob.redcap.hurt": { "sounds": [ "twilightforest:mob/redcap/hurt0", "twilightforest:mob/redcap/hurt1", "twilightforest:mob/redcap/hurt2", "twilightforest:mob/redcap/hurt3" ] }, + "mob.redcap.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.redcap.redcap", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.tinybird.chirp": { "sounds": [ "twilightforest:mob/tinybird/chirp0", "twilightforest:mob/tinybird/chirp1", "twilightforest:mob/tinybird/chirp2" ] }, + "mob.tinybird.hurt": { "sounds": [ "twilightforest:mob/tinybird/hurt0", "twilightforest:mob/tinybird/hurt1" ] }, + "mob.tinybird.song": { "sounds": [ "twilightforest:mob/tinybird/song0", "twilightforest:mob/tinybird/song1" ] }, + "mob.urghast.trapactive": { "sounds": [ "twilightforest:mob/urghast/trapactive" ] }, + "mob.urghast.trapon": { "sounds": [ "twilightforest:mob/urghast/trapon0", "twilightforest:mob/urghast/trapon1", "twilightforest:mob/urghast/trapon2", "twilightforest:mob/urghast/trapon3", "twilightforest:mob/urghast/trapon4" ] }, + "mob.urghast.trapspindown": { "sounds": [ "twilightforest:mob/urghast/trapspindown" ] }, + "mob.urghast.trapwarmup": { "sounds": [ "twilightforest:mob/urghast/trapwarmup" ] }, + "mob.wraith.wraith": { "sounds": [ "twilightforest:mob/wraith/wraith0", "twilightforest:mob/wraith/wraith1", "twilightforest:mob/wraith/wraith2", "twilightforest:mob/wraith/wraith3" ] }, + "mob.wraith.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.wraith.wraith", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.hydra.hurt": { "sounds": [ "twilightforest:mob/hydra/hurt0", "twilightforest:mob/hydra/hurt1", "twilightforest:mob/hydra/hurt2", "twilightforest:mob/hydra/hurt3" ] }, + "mob.hydra.death": { "sounds": [ "twilightforest:mob/hydra/death0" ] }, + "mob.hydra.growl": { "sounds": [ "twilightforest:mob/hydra/growl0", "twilightforest:mob/hydra/growl1", "twilightforest:mob/hydra/growl2" ] }, + "mob.hydra.roar": { "sounds": [ "twilightforest:mob/hydra/roar0", "twilightforest:mob/hydra/roar1" ] }, + "mob.hydra.warn": { "sounds": [ "twilightforest:mob/hydra/warn0" ] }, + "mob.hydra.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.hydra.growl", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.mosquito.mosquito": { "sounds": [ "twilightforest:mob/mosquito/animals132" ] }, + "mob.mosquito.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.mosquito.mosquito", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.ice.noise": { "sounds": [ "twilightforest:mob/ice/noise0", "twilightforest:mob/ice/noise1" ] }, + "mob.ice.hurt": { "sounds": [ "twilightforest:mob/ice/hurt0", "twilightforest:mob/ice/hurt1" ] }, + "mob.ice.death": { "sounds": [ "twilightforest:mob/ice/death0", "twilightforest:mob/ice/death1" ] }, + "mob.ice.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.ice.noise", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.minotaur.parrot": { "sounds": [ { "type": "event", "name": "entity.cow.ambient", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.alphayeti.alert": { "sounds": [ "twilightforest:mob/alphayeti/alert" ] }, + "mob.alphayeti.die": { "sounds": [ "twilightforest:mob/alphayeti/die" ] }, + "mob.alphayeti.grab": { "sounds": [ "twilightforest:mob/alphayeti/grab" ] }, + "mob.alphayeti.growl": { "sounds": [ "twilightforest:mob/alphayeti/growl1", "twilightforest:mob/alphayeti/growl2", "twilightforest:mob/alphayeti/growl3" ] }, + "mob.alphayeti.hurt": { "sounds": [ "twilightforest:mob/alphayeti/hurt1", "twilightforest:mob/alphayeti/hurt2", "twilightforest:mob/alphayeti/hurt3" ] }, + "mob.alphayeti.pant": { "sounds": [ "twilightforest:mob/alphayeti/pant1", "twilightforest:mob/alphayeti/pant2", "twilightforest:mob/alphayeti/pant3" ] }, + "mob.alphayeti.roar": { "sounds": [ "twilightforest:mob/alphayeti/roar" ] }, + "mob.alphayeti.throw": { "sounds": [ "twilightforest:mob/alphayeti/throw" ] }, + "mob.alphayeti.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.alphayeti.growl", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.deer.death": { "sounds": [ "twilightforest:mob/deer/death" ] }, + "mob.deer.hurt": { "sounds": [ "twilightforest:mob/deer/hurt1", "twilightforest:mob/deer/hurt2" ] }, + "mob.deer.idle": { "sounds": [ "twilightforest:mob/deer/idle1", "twilightforest:mob/deer/idle2", "twilightforest:mob/deer/idle3" ] }, + "mob.mistwolf.target": { "sounds": [ "twilightforest:mob/mistwolf/target" ] }, + "mob.mistwolf.hurt": { "sounds": [ "twilightforest:mob/mistwolf/hurt1", "twilightforest:mob/mistwolf/hurt2" ] }, + "mob.mistwolf.idle": { "sounds": [ "twilightforest:mob/mistwolf/idle1", "twilightforest:mob/mistwolf/idle2", "twilightforest:mob/mistwolf/idle3" ] }, + "mob.mistwolf.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.mistwolf.idle", "volume": 0.6, "pitch": 1.8 } ] }, + "mob.tome.death": { "sounds": [ "twilightforest:mob/tome/death" ] }, + "mob.tome.hurt": { "sounds": [ "twilightforest:mob/tome/hurt1", "twilightforest:mob/tome/hurt2", "twilightforest:mob/tome/hurt3" ] }, + "mob.tome.idle": { "sounds": [ "twilightforest:mob/tome/idle1", "twilightforest:mob/tome/idle2" ] }, + "mob.tome.parrot": { "sounds": [ { "type": "event", "name": "twilightforest:mob.tome.idle", "volume": 0.6, "pitch": 1.8 } ] }, + "random.slider": { "sounds": [ "twilightforest:random/creakgo2" ] }, + "music.bg": { "sounds": [ + { "name": "twilightforest:music/superstitious", "stream": true, "volume": 0.25 }, + { "name": "twilightforest:music/steps", "stream": true, "volume": 0.25 }, + { "name": "twilightforest:music/radiance", "stream": true, "volume": 0.25 }, + { "name": "twilightforest:music/ambient1", "stream": true }, + { "name": "twilightforest:music/ambient2", "stream": true }, + { "name": "twilightforest:music/ambient3", "stream": true }, + { "name": "twilightforest:music/ambient4", "stream": true }, + { "name": "twilightforest:music/ambient5", "stream": true }, + { "name": "twilightforest:music/ambient6", "stream": true } + ] } } diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/alert.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/alert.ogg new file mode 100644 index 0000000000..73b0410cf2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/alert.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/die.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/die.ogg new file mode 100644 index 0000000000..31909af08c Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/die.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/grab.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/grab.ogg new file mode 100644 index 0000000000..9985479e40 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/grab.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl1.ogg new file mode 100644 index 0000000000..20c5d4e6d8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl2.ogg new file mode 100644 index 0000000000..c1520c1aa9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl3.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl3.ogg new file mode 100644 index 0000000000..d8e7c2a8c0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/growl3.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt1.ogg new file mode 100644 index 0000000000..4e80d4d7ff Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt2.ogg new file mode 100644 index 0000000000..98722421aa Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt3.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt3.ogg new file mode 100644 index 0000000000..172daaa76e Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/hurt3.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant1.ogg new file mode 100644 index 0000000000..b237634c52 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant2.ogg new file mode 100644 index 0000000000..35a33ef314 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant3.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant3.ogg new file mode 100644 index 0000000000..a3724a0a4f Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/pant3.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/roar.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/roar.ogg new file mode 100644 index 0000000000..8dc94ffeaf Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/roar.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/throw.ogg b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/throw.ogg new file mode 100644 index 0000000000..50f6e96409 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/alphayeti/throw.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/deer/death.ogg b/src/main/resources/assets/twilightforest/sounds/mob/deer/death.ogg new file mode 100644 index 0000000000..764145a09e Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/deer/death.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/deer/hurt1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/deer/hurt1.ogg new file mode 100644 index 0000000000..b55730b40a Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/deer/hurt1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/deer/hurt2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/deer/hurt2.ogg new file mode 100644 index 0000000000..b9c2f2f0ff Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/deer/hurt2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/deer/idle1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/deer/idle1.ogg new file mode 100644 index 0000000000..b9d7a2eaac Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/deer/idle1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/deer/idle2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/deer/idle2.ogg new file mode 100644 index 0000000000..a0dc4fde97 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/deer/idle2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/deer/idle3.ogg b/src/main/resources/assets/twilightforest/sounds/mob/deer/idle3.ogg new file mode 100644 index 0000000000..63a74316d1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/deer/idle3.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/hurt1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/hurt1.ogg new file mode 100644 index 0000000000..8757667678 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/hurt1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/hurt2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/hurt2.ogg new file mode 100644 index 0000000000..c2e83add5e Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/hurt2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle1.ogg new file mode 100644 index 0000000000..28fbf72571 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle2.ogg new file mode 100644 index 0000000000..ea0c4af4a4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle3.ogg b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle3.ogg new file mode 100644 index 0000000000..24880681d2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/idle3.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/target.ogg b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/target.ogg new file mode 100644 index 0000000000..55bf377214 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/mistwolf/target.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/tome/death.ogg b/src/main/resources/assets/twilightforest/sounds/mob/tome/death.ogg new file mode 100644 index 0000000000..e0c53533fe Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/tome/death.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt1.ogg new file mode 100644 index 0000000000..8745e50763 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt2.ogg new file mode 100644 index 0000000000..109993935d Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt3.ogg b/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt3.ogg new file mode 100644 index 0000000000..cb0d46fd9b Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/tome/hurt3.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/tome/idle1.ogg b/src/main/resources/assets/twilightforest/sounds/mob/tome/idle1.ogg new file mode 100644 index 0000000000..c040bc79f9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/tome/idle1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/mob/tome/idle2.ogg b/src/main/resources/assets/twilightforest/sounds/mob/tome/idle2.ogg new file mode 100644 index 0000000000..511da15239 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/mob/tome/idle2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/ambient1.ogg b/src/main/resources/assets/twilightforest/sounds/music/ambient1.ogg new file mode 100644 index 0000000000..da591dc46e Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/ambient1.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/ambient2.ogg b/src/main/resources/assets/twilightforest/sounds/music/ambient2.ogg new file mode 100644 index 0000000000..a06d4efe0e Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/ambient2.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/ambient3.ogg b/src/main/resources/assets/twilightforest/sounds/music/ambient3.ogg new file mode 100644 index 0000000000..14b82c38e1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/ambient3.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/ambient4.ogg b/src/main/resources/assets/twilightforest/sounds/music/ambient4.ogg new file mode 100644 index 0000000000..e97d8986c2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/ambient4.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/ambient5.ogg b/src/main/resources/assets/twilightforest/sounds/music/ambient5.ogg new file mode 100644 index 0000000000..6d5ac8e314 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/ambient5.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/ambient6.ogg b/src/main/resources/assets/twilightforest/sounds/music/ambient6.ogg new file mode 100644 index 0000000000..fb8d9d38d6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/ambient6.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/radiance.ogg b/src/main/resources/assets/twilightforest/sounds/music/radiance.ogg new file mode 100644 index 0000000000..e755a13844 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/radiance.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/steps.ogg b/src/main/resources/assets/twilightforest/sounds/music/steps.ogg new file mode 100644 index 0000000000..e9b926bb9c Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/steps.ogg differ diff --git a/src/main/resources/assets/twilightforest/sounds/music/superstitious.ogg b/src/main/resources/assets/twilightforest/sounds/music/superstitious.ogg new file mode 100644 index 0000000000..82f8ca5fa3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/sounds/music/superstitious.ogg differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall.nbt new file mode 100644 index 0000000000..4ae92d9c4f Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner.nbt new file mode 100644 index 0000000000..d0ef54d1ef Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_decayed.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_decayed.nbt new file mode 100644 index 0000000000..7e8256a5fd Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_decayed.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_inner.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_inner.nbt new file mode 100644 index 0000000000..13c032232f Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_inner.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_inner_decayed.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_inner_decayed.nbt new file mode 100644 index 0000000000..3d5b906d6a Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_corner_inner_decayed.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_decayed.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_decayed.nbt new file mode 100644 index 0000000000..a9b7ca956a Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_decayed.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_padding.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_padding.nbt new file mode 100644 index 0000000000..52e836a35d Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_padding.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_padding_decayed.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_padding_decayed.nbt new file mode 100644 index 0000000000..7ef84f3066 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/courtyard_wall_padding_decayed.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_between.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_between.nbt new file mode 100644 index 0000000000..a7ba0771ef Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_between.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_between_big.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_between_big.nbt new file mode 100644 index 0000000000..3760f70d84 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_between_big.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_corner.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_corner.nbt new file mode 100644 index 0000000000..e2d65cd850 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_corner.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_corner_big.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_corner_big.nbt new file mode 100644 index 0000000000..3d26223725 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_corner_big.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end.nbt new file mode 100644 index 0000000000..622150f3c5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_big.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_big.nbt new file mode 100644 index 0000000000..175aa779e0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_big.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_pillar.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_pillar.nbt new file mode 100644 index 0000000000..a71faadc8d Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_pillar.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_pillar_big.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_pillar_big.nbt new file mode 100644 index 0000000000..847616ba37 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_end_pillar_big.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_intersection.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_intersection.nbt new file mode 100644 index 0000000000..ad9ffbb49a Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_intersection.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_intersection_big.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_intersection_big.nbt new file mode 100644 index 0000000000..f83fe05c0f Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_intersection_big.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_line.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_line.nbt new file mode 100644 index 0000000000..10b9393660 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_line.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_line_big.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_line_big.nbt new file mode 100644 index 0000000000..bf87b65abc Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_line_big.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_t.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_t.nbt new file mode 100644 index 0000000000..3d7446498c Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_t.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hedge_t_big.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_t_big.nbt new file mode 100644 index 0000000000..7cf31ac640 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hedge_t_big.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/hydra_statue.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/hydra_statue.nbt new file mode 100644 index 0000000000..1a335ea611 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/hydra_statue.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/pathway.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/pathway.nbt new file mode 100644 index 0000000000..21719a84fe Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/pathway.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/terrace_duct.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/terrace_duct.nbt new file mode 100644 index 0000000000..a292897776 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/terrace_duct.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/terrace_fire.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/terrace_fire.nbt new file mode 100644 index 0000000000..01e5b06310 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/terrace_fire.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/courtyard/terrace_statue.nbt b/src/main/resources/assets/twilightforest/structures/courtyard/terrace_statue.nbt new file mode 100644 index 0000000000..876371e5d6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/courtyard/terrace_statue.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_gallery.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_gallery.nbt new file mode 100644 index 0000000000..1888f0c9d9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_gallery.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_gallery_trap.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_gallery_trap.nbt new file mode 100644 index 0000000000..867b7f446c Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_gallery_trap.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_shelves.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_shelves.nbt new file mode 100644 index 0000000000..67b899cf76 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_shelves.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_shelves_trap.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_shelves_trap.nbt new file mode 100644 index 0000000000..a7074dba94 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_shelves_trap.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_study.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_study.nbt new file mode 100644 index 0000000000..cf13f0451d Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_study.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_study_trap.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_study_trap.nbt new file mode 100644 index 0000000000..d6fe31b47a Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/basement_study_trap.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_doubledeck.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_doubledeck.nbt new file mode 100644 index 0000000000..284b327503 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_doubledeck.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_hut.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_hut.nbt new file mode 100644 index 0000000000..e300d61832 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_hut.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_sideways.nbt b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_sideways.nbt new file mode 100644 index 0000000000..67edd75830 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/druid_hut/druid_sideways.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_full.nbt b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_full.nbt new file mode 100644 index 0000000000..bcfc7144d5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_full.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_lower.nbt b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_lower.nbt new file mode 100644 index 0000000000..0139a05418 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_lower.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_trap.nbt b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_trap.nbt new file mode 100644 index 0000000000..3fbf9125bf Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_trap.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_upper.nbt b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_upper.nbt new file mode 100644 index 0000000000..146a3c2fd0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/grave_upper.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/graveyard/graveyard.nbt b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/graveyard.nbt new file mode 100644 index 0000000000..abd810b1b0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/graveyard/graveyard.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/well/well_bottom.nbt b/src/main/resources/assets/twilightforest/structures/landscape/well/well_bottom.nbt new file mode 100644 index 0000000000..de85c3f41f Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/well/well_bottom.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/landscape/well/well_top.nbt b/src/main/resources/assets/twilightforest/structures/landscape/well/well_top.nbt new file mode 100644 index 0000000000..814e9f17d0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/landscape/well/well_top.nbt differ diff --git a/src/main/resources/assets/twilightforest/structures/testing/spiral_rotations.nbt b/src/main/resources/assets/twilightforest/structures/testing/spiral_rotations.nbt new file mode 100644 index 0000000000..539fe46341 Binary files /dev/null and b/src/main/resources/assets/twilightforest/structures/testing/spiral_rotations.nbt differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1.png b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1.png index 434c58e6d0..cd3d189a2e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1.png and b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1_dyed.png b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1_dyed.png new file mode 100644 index 0000000000..cdf857b490 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1_dyed.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1_overlay.png b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1_overlay.png new file mode 100644 index 0000000000..aa8c123adc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_1_overlay.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2.png b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2.png index 99f8898e74..131566c1cd 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2.png and b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2_dyed.png b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2_dyed.png new file mode 100644 index 0000000000..754901651c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2_dyed.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2_overlay.png b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2_overlay.png new file mode 100644 index 0000000000..83f29cd24e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/armor/arcticarmor_2_overlay.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/fiery_1.png b/src/main/resources/assets/twilightforest/textures/armor/fiery_1.png index 8ea1b0a511..bb78776106 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/fiery_1.png and b/src/main/resources/assets/twilightforest/textures/armor/fiery_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/fiery_2.png b/src/main/resources/assets/twilightforest/textures/armor/fiery_2.png index a467ab8ac2..c15a749564 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/fiery_2.png and b/src/main/resources/assets/twilightforest/textures/armor/fiery_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/ironwood_1.png b/src/main/resources/assets/twilightforest/textures/armor/ironwood_1.png index 5957cb7d79..6e665c4a29 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/ironwood_1.png and b/src/main/resources/assets/twilightforest/textures/armor/ironwood_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/ironwood_2.png b/src/main/resources/assets/twilightforest/textures/armor/ironwood_2.png index 70a6d98271..51637a9d11 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/ironwood_2.png and b/src/main/resources/assets/twilightforest/textures/armor/ironwood_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/knightly_1.png b/src/main/resources/assets/twilightforest/textures/armor/knightly_1.png index 87436509a4..d797fb1c54 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/knightly_1.png and b/src/main/resources/assets/twilightforest/textures/armor/knightly_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/knightly_2.png b/src/main/resources/assets/twilightforest/textures/armor/knightly_2.png index 10c37d4800..64b86fb2b5 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/knightly_2.png and b/src/main/resources/assets/twilightforest/textures/armor/knightly_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/naga_scale_1.png b/src/main/resources/assets/twilightforest/textures/armor/naga_scale_1.png index 7a13f2503a..fcc668fe58 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/naga_scale_1.png and b/src/main/resources/assets/twilightforest/textures/armor/naga_scale_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/naga_scale_2.png b/src/main/resources/assets/twilightforest/textures/armor/naga_scale_2.png index be315c0ebf..3e27ffca26 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/naga_scale_2.png and b/src/main/resources/assets/twilightforest/textures/armor/naga_scale_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/phantom_1.png b/src/main/resources/assets/twilightforest/textures/armor/phantom_1.png index 7edbe0b249..3058458901 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/phantom_1.png and b/src/main/resources/assets/twilightforest/textures/armor/phantom_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/steeleaf_1.png b/src/main/resources/assets/twilightforest/textures/armor/steeleaf_1.png index 760d82a70a..5e43f6f870 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/steeleaf_1.png and b/src/main/resources/assets/twilightforest/textures/armor/steeleaf_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/steeleaf_2.png b/src/main/resources/assets/twilightforest/textures/armor/steeleaf_2.png index 84112c290c..9a795241c5 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/steeleaf_2.png and b/src/main/resources/assets/twilightforest/textures/armor/steeleaf_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_1.png b/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_1.png index a302f9d5ce..5ff8e3e034 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_1.png and b/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_2.png b/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_2.png index ad6dfd5d44..bea4f7d1fa 100644 Binary files a/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_2.png and b/src/main/resources/assets/twilightforest/textures/armor/yetiarmor_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/Untitled.png b/src/main/resources/assets/twilightforest/textures/blocks/Untitled.png index 5c86499404..19c557585f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/Untitled.png and b/src/main/resources/assets/twilightforest/textures/blocks/Untitled.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block.png b/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block.png new file mode 100644 index 0000000000..7aa2ab11f9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block.png.mcmeta new file mode 100644 index 0000000000..a96d4206ef --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block.png.mcmeta @@ -0,0 +1,7 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/arctic_fur_block_ctm" ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block_ctm.png new file mode 100644 index 0000000000..9fb3bd37fa Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/arctic_fur_block_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_side.png b/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_side.png index 108aaadaf8..f76615b0f8 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_top.png b/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_top.png index 96c8d7b65e..2bb7368543 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurora_pillar_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurora_slab_side.png b/src/main/resources/assets/twilightforest/textures/blocks/aurora_slab_side.png index c535914493..7fca163040 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurora_slab_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurora_slab_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png.mcmeta index ebc2202835..62c3ce53c5 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick0.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 0, 1, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png.mcmeta index 045eda5939..6698db17a2 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick1.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 2, 3, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick10.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick10.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick10.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick10.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick10.png.mcmeta new file mode 100644 index 0000000000..89a7b346ed --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick10.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 13, + 12, + 11 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick11.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick11.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick11.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick11.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick11.png.mcmeta new file mode 100644 index 0000000000..f049f9a635 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick11.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 13, + 12, + 11, + 10, + 9 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick12.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick12.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick12.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick12.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick12.png.mcmeta new file mode 100644 index 0000000000..b11e22cfa2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick12.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 6, + 5, + 4, + 3, + 2, + 1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick13.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick13.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick13.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick13.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick13.png.mcmeta new file mode 100644 index 0000000000..655f3eda86 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick13.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 4, + 3, + 2, + 1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick14.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick14.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick14.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick14.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick14.png.mcmeta new file mode 100644 index 0000000000..99f9e7ee23 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick14.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 2, + 1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick15.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick15.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick15.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick15.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick15.png.mcmeta new file mode 100644 index 0000000000..62c3ce53c5 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick15.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png.mcmeta index db1c7873f4..d779139fcb 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick2.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 4, 5, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png.mcmeta index 8c73439e64..05c40d3d4a 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick3.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 6, 7, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png.mcmeta index e566da5c76..922d27547b 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick4.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 8, 9, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png.mcmeta index 8f82a5a9c4..5738e9ae0b 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick5.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 10, 11, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png.mcmeta index 0351a00084..b5c395d4b2 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick6.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 12, 13, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png index eb3c164645..bc93edfd27 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png.mcmeta index f2725da423..a7072035a4 100644 --- a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png.mcmeta +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick7.png.mcmeta @@ -1,6 +1,7 @@ { "animation": { "frametime": 4, + "interpolate": true, "frames": [ 14, 15, diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick8.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick8.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick8.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick8.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick8.png.mcmeta new file mode 100644 index 0000000000..6e31ab8e5b --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick8.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick9.png b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick9.png new file mode 100644 index 0000000000..bc93edfd27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick9.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick9.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick9.png.mcmeta new file mode 100644 index 0000000000..42d4716cad --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/aurorabrick9.png.mcmeta @@ -0,0 +1,38 @@ +{ + "animation": { + "frametime": 4, + "interpolate": true, + "frames": [ + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 14, + 13 + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass.png b/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass.png new file mode 100644 index 0000000000..fbc11a19c3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass.png.mcmeta new file mode 100644 index 0000000000..a7e4d42cf6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "layer": "TRANSLUCENT", + "textures": [ "twilightforest:blocks/auroralized_glass_ct" ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass_ct.png b/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass_ct.png new file mode 100644 index 0000000000..4c3004df0e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/auroralized_glass_ct.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/blank.png b/src/main/resources/assets/twilightforest/textures/blocks/blank.png index a8ffaba12d..aeaf6d4b67 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/blank.png and b/src/main/resources/assets/twilightforest/textures/blocks/blank.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/blank.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/blank.png.mcmeta new file mode 100644 index 0000000000..f2f6a49153 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/blank.png.mcmeta @@ -0,0 +1,6 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_side.png b/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_side.png index 785c5292e8..1e1393ea55 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_top.png b/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_top.png index 14d816d75d..586b3c5bc7 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/brown_thorns_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_side.png b/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_side.png index 13c89f0b68..e602642d90 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_top.png b/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_top.png index 9f6198d2ae..f92be88d2c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/burnt_thorns_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/canopy_top.png b/src/main/resources/assets/twilightforest/textures/blocks/canopy_top.png index 66526061a5..8b5aec047f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/canopy_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/canopy_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/carminite_block.png b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block.png new file mode 100644 index 0000000000..a588507690 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/carminite_block.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block.png.mcmeta new file mode 100644 index 0000000000..8121d7696d --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 4 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/carminite_block_overlay.png b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block_overlay.png new file mode 100644 index 0000000000..391b227d00 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block_overlay.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/carminite_block_overlay.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block_overlay.png.mcmeta new file mode 100644 index 0000000000..9cfe353222 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/carminite_block_overlay.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_door.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_door.png index 7a39209662..90157a91a3 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castle_door.png and b/src/main/resources/assets/twilightforest/textures/blocks/castle_door.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_active.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_active.png index 9cee3adebb..90157a91a3 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_active.png and b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_active.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_corners.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_corners.png new file mode 100644 index 0000000000..125241085e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_corners.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_corners.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_corners.png.mcmeta new file mode 100644 index 0000000000..954402f5ba --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_corners.png.mcmeta @@ -0,0 +1,19 @@ +{ + "ctm": { + "ctm_version": 1, + "type":"CTM", + "layer":"CUTOUT", + "textures":[ + "twilightforest:blocks/castle_door_rune_ctm" + ], + "extra": { + "ignore_states": true, + "connect_inside": true, + "light": 15, + "connect_to": [ + { "block": "twilightforest:castle_door" }, + { "block": "twilightforest:castle_door_vanished" } + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_ctm.png new file mode 100644 index 0000000000..f494bda90d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_rune_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished.png index ee9a9bb3c1..5098bcf7a2 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished.png and b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished_active.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished_active.png index c69f0d05e4..ec28f5ee58 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished_active.png and b/src/main/resources/assets/twilightforest/textures/blocks/castle_door_vanished_active.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_end.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_end.png new file mode 100644 index 0000000000..fa90a64927 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_end.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_side.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_side.png new file mode 100644 index 0000000000..3e2f7d1036 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_tiles.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_tiles.png new file mode 100644 index 0000000000..73149209df Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_bold_tiles.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_end.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_end.png new file mode 100644 index 0000000000..094af27c8a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_end.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_h.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_h.png new file mode 100644 index 0000000000..371d62b20b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_h.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_side.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_side.png new file mode 100644 index 0000000000..1a930f9d44 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_pillar_encased_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_stair.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair.png new file mode 100644 index 0000000000..c1ae7177a1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_cracked.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_cracked.png new file mode 100644 index 0000000000..d3f9a1b525 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_cracked.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_faded.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_faded.png new file mode 100644 index 0000000000..0d591c6109 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_faded.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_mossy.png new file mode 100644 index 0000000000..b5c08d6a94 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castle_stair_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_brick.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_brick.png index 91f70f8cfb..ae420b234c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_brick.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_brick.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_cracked.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_cracked.png index 77d6eb9abf..b1278f9596 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_cracked.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_cracked.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_faded.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_faded.png index dfddc80c1f..0d69fd5731 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_faded.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_faded.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame.png new file mode 100644 index 0000000000..036ce15c8c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_ct.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_ct.png new file mode 100644 index 0000000000..56003632c1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_ct.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_edge2.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_edge2.png new file mode 100644 index 0000000000..99d1c70353 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_edge2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_edge_v2.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_edge_v2.png new file mode 100644 index 0000000000..065d07be0f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_frame_edge_v2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_0.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_0.png index c01c96db82..c29128824d 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_0.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_0.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_0.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_0.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_1.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_1.png index 757ca5c6ca..2a4af05bce 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_1.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_2.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_2.png index 23d7fe0d04..f68e42e5c9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_2.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_2.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_3.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_3.png index 49596dbb1e..e4121a603c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_3.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_3.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_3.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_3.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_4.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_4.png index 1750b3b0a5..a2a9d46018 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_4.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_4.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_4.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_4.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_4.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_5.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_5.png index c561c7d0f2..13aa051d11 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_5.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_5.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_5.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_5.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_5.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_6.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_6.png index d6ff0a11a8..a6db780d74 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_6.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_6.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_6.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_6.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_6.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_7.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_7.png index b229b12e5b..9f7b0c6644 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_7.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_7.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_7.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_7.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_magic_7.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_mossy.png index c193e33509..4efb21eaa2 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_mossy.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_roof.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_roof.png index 6ffbfd3cc9..a3140bf07c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_roof.png and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_roof.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castleblock_tile.png b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_tile.png new file mode 100644 index 0000000000..ad44ecb539 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castleblock_tile.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castlestair_brick.png b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_brick.png new file mode 100644 index 0000000000..1da9693c77 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_brick.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castlestair_cracked.png b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_cracked.png new file mode 100644 index 0000000000..9d390d4632 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_cracked.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castlestair_faded.png b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_faded.png new file mode 100644 index 0000000000..62ff976350 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_faded.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/castlestair_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_mossy.png new file mode 100644 index 0000000000..0585a262c7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/castlestair_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/TFCicada.png b/src/main/resources/assets/twilightforest/textures/blocks/cicada.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/blocks/TFCicada.png rename to src/main/resources/assets/twilightforest/textures/blocks/cicada.png diff --git a/src/main/resources/assets/twilightforest/textures/blocks/cinder_corner.png b/src/main/resources/assets/twilightforest/textures/blocks/cinder_corner.png index 3baf5f3773..6fd8546c91 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/cinder_corner.png and b/src/main/resources/assets/twilightforest/textures/blocks/cinder_corner.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/cinder_log_end.png b/src/main/resources/assets/twilightforest/textures/blocks/cinder_log_end.png new file mode 100644 index 0000000000..14b9c8f8c0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/cinder_log_end.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/cinder_log_side.png b/src/main/resources/assets/twilightforest/textures/blocks/cinder_log_side.png new file mode 100644 index 0000000000..2131806b85 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/cinder_log_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/cinder_side.png b/src/main/resources/assets/twilightforest/textures/blocks/cinder_side.png index b1cab2f3c4..058f15ca65 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/cinder_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/cinder_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/cinder_top.png b/src/main/resources/assets/twilightforest/textures/blocks/cinder_top.png index 7e634b5a3a..afb5abdd05 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/cinder_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/cinder_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/cloverpatch.png b/src/main/resources/assets/twilightforest/textures/blocks/cloverpatch.png index 5a1beb813f..6d0f947748 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/cloverpatch.png and b/src/main/resources/assets/twilightforest/textures/blocks/cloverpatch.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves.png b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves.png index 3863010d78..1eac3e896c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves.png and b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves2.png b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves2.png index 8fa0f9be7b..5b41d4a786 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves2.png and b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_leaves2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_side.png b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_side.png index 95fa3c31a3..174c42f0c2 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_top.png b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_top.png index e84ca989ed..e620acf7a0 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/darkwood_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/darkwood_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/deadrock_cracked.png b/src/main/resources/assets/twilightforest/textures/blocks/deadrock_cracked.png index 6c5fbe8c9c..0a433cbffd 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/deadrock_cracked.png and b/src/main/resources/assets/twilightforest/textures/blocks/deadrock_cracked.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/deadrock_solid.png b/src/main/resources/assets/twilightforest/textures/blocks/deadrock_solid.png index a43d06a723..b5e888f427 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/deadrock_solid.png and b/src/main/resources/assets/twilightforest/textures/blocks/deadrock_solid.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/deadrock_surface.png b/src/main/resources/assets/twilightforest/textures/blocks/deadrock_surface.png index 3801c72cf7..cadd9f39a1 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/deadrock_surface.png and b/src/main/resources/assets/twilightforest/textures/blocks/deadrock_surface.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down.png new file mode 100644 index 0000000000..30629d30f2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down_mossy.png new file mode 100644 index 0000000000..26f2d7f6e4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down_weathered.png new file mode 100644 index 0000000000..e2ecd68ad2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_down_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left.png new file mode 100644 index 0000000000..3b5db54568 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left_mossy.png new file mode 100644 index 0000000000..d1ea49739d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left_weathered.png new file mode 100644 index 0000000000..1bab0a5646 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_left_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right.png new file mode 100644 index 0000000000..04004b0944 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right_mossy.png new file mode 100644 index 0000000000..bf6645fda4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right_weathered.png new file mode 100644 index 0000000000..cf38f1d3ee Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_right_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up.png new file mode 100644 index 0000000000..4b2c9bd052 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up_mossy.png new file mode 100644 index 0000000000..e42e27fb5c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up_weathered.png new file mode 100644 index 0000000000..2b48bd5d07 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/etched_nagastone_up_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_bottom.png b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_bottom.png new file mode 100644 index 0000000000..428f0b7644 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_bottom.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_inner.png b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_inner.png new file mode 100644 index 0000000000..2ad77b6fdb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_inner.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_side.png b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_side.png new file mode 100644 index 0000000000..99fb947693 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_sprinkle.png b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_sprinkle.png new file mode 100644 index 0000000000..b5720abeb4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_sprinkle.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_sprinkle.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_sprinkle.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_sprinkle.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_top.png b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_top.png new file mode 100644 index 0000000000..a6fc968aeb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/experiment115/experiment115_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fiery_block.png b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block.png new file mode 100644 index 0000000000..96a656a95e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fiery_block.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block.png.mcmeta new file mode 100644 index 0000000000..f34eb7ba48 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner.png b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner.png new file mode 100644 index 0000000000..fd22143c27 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner.png.mcmeta new file mode 100644 index 0000000000..c48bdf6f98 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner.png.mcmeta @@ -0,0 +1,12 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "layer": "CUTOUT", + "textures": [ "twilightforest:blocks/fiery_block_inner_ctm" ], + "extra": { + "light": 15, + "connect_inside": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner_ctm.png new file mode 100644 index 0000000000..ec403d9cc5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/fiery_block_inner_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fiery_pattern.png b/src/main/resources/assets/twilightforest/textures/blocks/fiery_pattern.png new file mode 100644 index 0000000000..dedc0257a3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/fiery_pattern.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fiery_pattern.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/fiery_pattern.png.mcmeta new file mode 100755 index 0000000000..aaf1204dba --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/fiery_pattern.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "pattern", + "extra": { + "light": 15, + "size": 2 + } + } +} diff --git a/src/main/resources/assets/twilightforest/textures/blocks/TFFirefly.png b/src/main/resources/assets/twilightforest/textures/blocks/firefly.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/blocks/TFFirefly.png rename to src/main/resources/assets/twilightforest/textures/blocks/firefly.png diff --git a/src/main/resources/assets/twilightforest/textures/blocks/fluffy_cloud.png b/src/main/resources/assets/twilightforest/textures/blocks/fluffy_cloud.png index adbff52698..528e6cb359 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/fluffy_cloud.png and b/src/main/resources/assets/twilightforest/textures/blocks/fluffy_cloud.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_blue.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_blue.png index c07d8540f7..6eb4fbafa8 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_blue.png and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_blue.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_blue.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_blue.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_blue.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_green.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_green.png index fad44727f4..f6cade8f71 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_green.png and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_green.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_green.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_green.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_green.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_orange.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_orange.png index 656f1c253c..1e2605a915 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_orange.png and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_orange.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_orange.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_orange.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_orange.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_pink.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_pink.png index fd91fe1649..6c00e0dbc7 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_pink.png and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_pink.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_pink.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_pink.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_pink.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_purple.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_purple.png index 7396bc9ca2..4224459e6c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_purple.png and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_purple.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_purple.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_purple.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_purple.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint.png new file mode 100644 index 0000000000..c4fcd76151 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint.png.mcmeta new file mode 100644 index 0000000000..ee7bd24674 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint.png.mcmeta @@ -0,0 +1,15 @@ +{ + "ctm": { + "ctm_version": 1, + "type":"ctm", + "layer":"TRANSLUCENT", + "textures":[ + "twilightforest:blocks/forcefield_tint_ct" + ], + "extra": { + "light": 15, + "connect_inside": true, + "ignore_states": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint_ct.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint_ct.png new file mode 100644 index 0000000000..83d3280a57 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_tint_ct.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_top.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_top.png index e73662b789..dc3559c918 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_white.png b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_white.png new file mode 100644 index 0000000000..42b7311113 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_white.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/forcefield_white.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_white.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/forcefield_white.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/cobblestone.png b/src/main/resources/assets/twilightforest/textures/blocks/giant/cobblestone.png new file mode 100755 index 0000000000..da3498c5c8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/giant/cobblestone.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/cobblestone.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/giant/cobblestone.png.mcmeta new file mode 100755 index 0000000000..845ec015c6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/giant/cobblestone.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm":{ + "ctm_version": 1, + "type":"V", + "layer":"CUTOUT", + "extra":{ + "size":4 + } + } +} diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/leaves_oak.png b/src/main/resources/assets/twilightforest/textures/blocks/giant/leaves_oak.png new file mode 100755 index 0000000000..a6773aff74 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/giant/leaves_oak.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/leaves_oak.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/giant/leaves_oak.png.mcmeta new file mode 100755 index 0000000000..845ec015c6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/giant/leaves_oak.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm":{ + "ctm_version": 1, + "type":"V", + "layer":"CUTOUT", + "extra":{ + "size":4 + } + } +} diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak.png b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak.png new file mode 100755 index 0000000000..914cb5fbc1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak.png.mcmeta new file mode 100755 index 0000000000..845ec015c6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm":{ + "ctm_version": 1, + "type":"V", + "layer":"CUTOUT", + "extra":{ + "size":4 + } + } +} diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak_top.png b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak_top.png new file mode 100755 index 0000000000..97eebd1f65 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak_top.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak_top.png.mcmeta new file mode 100755 index 0000000000..845ec015c6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/giant/log_oak_top.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm":{ + "ctm_version": 1, + "type":"V", + "layer":"CUTOUT", + "extra":{ + "size":4 + } + } +} diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/obsidian.png b/src/main/resources/assets/twilightforest/textures/blocks/giant/obsidian.png new file mode 100755 index 0000000000..ff0a68363e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/giant/obsidian.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/giant/obsidian.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/giant/obsidian.png.mcmeta new file mode 100755 index 0000000000..845ec015c6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/giant/obsidian.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm":{ + "ctm_version": 1, + "type":"V", + "layer":"CUTOUT", + "extra":{ + "size":4 + } + } +} diff --git a/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_side.png b/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_side.png index 5fd63bb68f..ae9b3a8e8f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_top.png b/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_top.png index 583db57532..26ce9c391e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/green_thorns_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/hedge_rose.png b/src/main/resources/assets/twilightforest/textures/blocks/hedge_rose.png new file mode 100644 index 0000000000..cf42edd7f8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/hedge_rose.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_cap.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_cap.png index f9d7fabce5..d012e6cc32 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_cap.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_cap.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_cap.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_cap.png.mcmeta new file mode 100644 index 0000000000..36845e4915 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_cap.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_inside.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_inside.png index 32ed881a9c..bcc12ee370 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_inside.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_inside.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_inside.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_inside.png.mcmeta new file mode 100644 index 0000000000..36845e4915 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_inside.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_stem.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_stem.png index 04a3a7f5fb..59c118009e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_stem.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_stem.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_stem.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_stem.png.mcmeta new file mode 100644 index 0000000000..36845e4915 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/huge_gloom_stem.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad.png new file mode 100644 index 0000000000..5bb645c9b2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_0.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_0.png index 47f9fde13e..267bd9c1f9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_0.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_1.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_1.png index c77d0df305..baa9c0e460 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_1.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_2.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_2.png index b8329c91f0..66ebfac94b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_2.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_3.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_3.png index 81da5bb818..51b9d8a8d4 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_3.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_lilypad_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk.png index 013f2ea83a..321412c500 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk_top.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk_top.png index 0b7803bab7..d4c7351acb 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_stalk_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/huge_waterlily.png b/src/main/resources/assets/twilightforest/textures/blocks/huge_waterlily.png index 1e27f368ce..3e51c8ce59 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/huge_waterlily.png and b/src/main/resources/assets/twilightforest/textures/blocks/huge_waterlily.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_carminite.png b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_carminite.png new file mode 100644 index 0000000000..78017f9765 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_energy.png b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_energy.png new file mode 100644 index 0000000000..931fdcde8b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_energy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_scales.png b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_scales.png new file mode 100644 index 0000000000..8cd0198d50 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_scales.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_streaks.png b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_streaks.png new file mode 100644 index 0000000000..6fe9b0c49c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/immersiveengineering/balloon_streaks.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ironwood_block.png b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_block.png new file mode 100644 index 0000000000..dc1f587a43 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_block.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ironwood_block.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_block.png.mcmeta new file mode 100644 index 0000000000..aafe6db154 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_block.png.mcmeta @@ -0,0 +1,6 @@ +{ + "ctm": { + "ctm_version": 1, + "proxy": "twilightforest:blocks/ironwood_frame" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame.png b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame.png new file mode 100644 index 0000000000..4ca84ea329 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame.png.mcmeta new file mode 100644 index 0000000000..932728b2a7 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "layer": "CUTOUT", + "textures": [ "twilightforest:blocks/ironwood_frame_ctm" ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame_ctm.png new file mode 100644 index 0000000000..302ac93aff Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_frame_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ironwood_pattern.png b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_pattern.png new file mode 100644 index 0000000000..11106c0361 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_pattern.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ironwood_pattern.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_pattern.png.mcmeta new file mode 100755 index 0000000000..87f230c7e2 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/ironwood_pattern.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm":{ + "ctm_version": 1, + "type":"pattern", + "extra":{ + "size":3 + } + } +} diff --git a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick.png b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick.png index a29d95076a..7b1420ef03 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick.png and b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_cracked.png b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_cracked.png index ffd07db4ac..117d884923 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_cracked.png and b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_cracked.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_floor.png b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_floor.png index 5316014ddf..256bb3eea4 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_floor.png and b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_floor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_mossy.png index a31bfb6979..6a135f915c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_mossy.png and b/src/main/resources/assets/twilightforest/textures/blocks/knightbrick_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/knightmetal_block.png b/src/main/resources/assets/twilightforest/textures/blocks/knightmetal_block.png index fe23eb3227..2bc3ebf480 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/knightmetal_block.png and b/src/main/resources/assets/twilightforest/textures/blocks/knightmetal_block.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ladder_iron.png b/src/main/resources/assets/twilightforest/textures/blocks/ladder_iron.png new file mode 100644 index 0000000000..8a24130d07 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/ladder_iron.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_0.png b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_0.png new file mode 100644 index 0000000000..2f30fb6694 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_1.png b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_1.png new file mode 100644 index 0000000000..f02f2b739f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_2.png b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_2.png new file mode 100644 index 0000000000..fe39f2f323 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_3.png b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_3.png new file mode 100644 index 0000000000..cf1af982a7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/lapis_shale_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/lunchbox_face.png b/src/main/resources/assets/twilightforest/textures/blocks/lunchbox_face.png new file mode 100644 index 0000000000..91032ae681 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/lunchbox_face.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/lunchbox_side.png b/src/main/resources/assets/twilightforest/textures/blocks/lunchbox_side.png new file mode 100644 index 0000000000..247107bfa5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/lunchbox_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mangrove_side.png b/src/main/resources/assets/twilightforest/textures/blocks/mangrove_side.png index a2888742ee..75912ed4f0 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mangrove_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/mangrove_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mangrove_top.png b/src/main/resources/assets/twilightforest/textures/blocks/mangrove_top.png index feb1470751..abb59082f0 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mangrove_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/mangrove_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mayapple.png b/src/main/resources/assets/twilightforest/textures/blocks/mayapple.png index 7753dc0ce4..405cb71184 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mayapple.png and b/src/main/resources/assets/twilightforest/textures/blocks/mayapple.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mayapple_side.png b/src/main/resources/assets/twilightforest/textures/blocks/mayapple_side.png index 60ba6300a2..f421b5bf0b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mayapple_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/mayapple_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_decorative.png b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_decorative.png index 56336e210d..18ae966306 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_decorative.png and b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_decorative.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_large_brick.png b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_large_brick.png new file mode 100644 index 0000000000..d378ecf601 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_large_brick.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_mossy.png index 6e3b132cc6..6d8400635c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_mossy.png and b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_pillar.png b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_pillar.png index 5af7ab9159..3eec5e5c8a 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_pillar.png and b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_pillar.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_plain.png b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_plain.png index 9db291ece0..32834f0fa6 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mazestone_plain.png and b/src/main/resources/assets/twilightforest/textures/blocks/mazestone_plain.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mine_gem.png b/src/main/resources/assets/twilightforest/textures/blocks/mine_gem.png index 085dfef53e..1d68c51284 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mine_gem.png and b/src/main/resources/assets/twilightforest/textures/blocks/mine_gem.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mine_gem_off.png b/src/main/resources/assets/twilightforest/textures/blocks/mine_gem_off.png index 540ca2985c..ddb547214d 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mine_gem_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/mine_gem_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mine_side.png b/src/main/resources/assets/twilightforest/textures/blocks/mine_side.png index 479057a7a8..38170fb056 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mine_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/mine_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/TFMoonworm.png b/src/main/resources/assets/twilightforest/textures/blocks/moonworm.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/blocks/TFMoonworm.png rename to src/main/resources/assets/twilightforest/textures/blocks/moonworm.png diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mosspatch.png b/src/main/resources/assets/twilightforest/textures/blocks/mosspatch.png index f0dce5f978..1bef844b66 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mosspatch.png and b/src/main/resources/assets/twilightforest/textures/blocks/mosspatch.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mushgloom.png b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom.png index bb33efc697..140cf14514 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/mushgloom.png and b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mushgloom.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom.png.mcmeta new file mode 100644 index 0000000000..f5fa68e260 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 6 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mushgloom_head.png b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom_head.png new file mode 100644 index 0000000000..10d9ce21bd Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom_head.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/mushgloom_head.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom_head.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/mushgloom_head.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare.png new file mode 100644 index 0000000000..c6eb261293 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare_mossy.png new file mode 100644 index 0000000000..41a74db6f0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare_weathered.png new file mode 100644 index 0000000000..cad6e37bf3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_bare_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_long_vertical.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_long_vertical.png new file mode 100644 index 0000000000..5869970b4e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_long_vertical.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end.png new file mode 100644 index 0000000000..764af39030 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end_mossy.png new file mode 100644 index 0000000000..0d4c735068 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end_weathered.png new file mode 100644 index 0000000000..9e6c5d020f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_end_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side.png new file mode 100644 index 0000000000..05fb13eb24 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_alt.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_alt.png new file mode 100644 index 0000000000..5d33b156e6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_alt.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_mossy.png new file mode 100644 index 0000000000..15928e1807 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_mossy_alt.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_mossy_alt.png new file mode 100644 index 0000000000..7550dd6091 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_mossy_alt.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_weathered.png new file mode 100644 index 0000000000..d7a6a47d0f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_weathered_alt.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_weathered_alt.png new file mode 100644 index 0000000000..b47013dad1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_pillar_side_weathered_alt.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_tip_down.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_tip_down.png new file mode 100644 index 0000000000..e2e37cd963 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_tip_down.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/nagastone_tip_up.png b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_tip_up.png new file mode 100644 index 0000000000..6b610cff1b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/nagastone_tip_up.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/oak_side.png b/src/main/resources/assets/twilightforest/textures/blocks/oak_side.png index 3687cda429..1ab5557368 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/oak_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/oak_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/oak_top.png b/src/main/resources/assets/twilightforest/textures/blocks/oak_top.png index 33d3e46055..76502c9604 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/oak_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/oak_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/oreroots.png b/src/main/resources/assets/twilightforest/textures/blocks/oreroots.png index 1858fd558d..b7b309265c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/oreroots.png and b/src/main/resources/assets/twilightforest/textures/blocks/oreroots.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover.png new file mode 100644 index 0000000000..006149e645 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_0.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_0.png new file mode 100644 index 0000000000..006149e645 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_0_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_0_ctm.png new file mode 100644 index 0000000000..6bbc2871fc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_0_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_1.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_1.png new file mode 100644 index 0000000000..71f3cbee51 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_1_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_1_ctm.png new file mode 100644 index 0000000000..e9484893a8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_1_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_2.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_2.png new file mode 100644 index 0000000000..b3a8ee79a7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_2_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_2_ctm.png new file mode 100644 index 0000000000..dce74e3ccf Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_2_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_3.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_3.png new file mode 100644 index 0000000000..53cef1c7bf Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_3_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_3_ctm.png new file mode 100644 index 0000000000..2a74dde2c7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/clover_3_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss.png new file mode 100644 index 0000000000..86b75d70a2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_0.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_0.png new file mode 100644 index 0000000000..86b75d70a2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_0_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_0_ctm.png new file mode 100644 index 0000000000..07a414bf95 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_0_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_1.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_1.png new file mode 100644 index 0000000000..4b792d2b0d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_1_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_1_ctm.png new file mode 100644 index 0000000000..51c68048d3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_1_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_2.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_2.png new file mode 100644 index 0000000000..8b5bee5f7b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_2_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_2_ctm.png new file mode 100644 index 0000000000..62a75ea0d7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_2_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_3.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_3.png new file mode 100644 index 0000000000..cb008ce6ae Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_3_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_3_ctm.png new file mode 100644 index 0000000000..cf8c8ec9bc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/patch/moss_3_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra.png new file mode 100644 index 0000000000..5f966400fa Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_flat.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_flat.png new file mode 100644 index 0000000000..6e1370929b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_flat.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_flat.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_flat.png.mcmeta new file mode 100644 index 0000000000..be7f8a1c5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_flat.png.mcmeta @@ -0,0 +1,8 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_glow.png new file mode 100644 index 0000000000..b517e2a5c3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_glow.png.mcmeta new file mode 100644 index 0000000000..9670314c6c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_glow.png.mcmeta @@ -0,0 +1,15 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + }, + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_latent.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_latent.png new file mode 100644 index 0000000000..e70ba823c9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/hydra_latent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich.png new file mode 100644 index 0000000000..211995e851 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_flat.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_flat.png new file mode 100644 index 0000000000..726b9aab6c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_flat.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_flat.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_flat.png.mcmeta new file mode 100644 index 0000000000..be7f8a1c5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_flat.png.mcmeta @@ -0,0 +1,8 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_glow.png new file mode 100644 index 0000000000..a43e1fb0f7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_glow.png.mcmeta new file mode 100644 index 0000000000..9670314c6c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_glow.png.mcmeta @@ -0,0 +1,15 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + }, + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_latent.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_latent.png new file mode 100644 index 0000000000..7ba03ae713 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/lich_latent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga.png new file mode 100644 index 0000000000..db9cf511da Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_flat.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_flat.png new file mode 100644 index 0000000000..d3dbce9543 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_flat.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_flat.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_flat.png.mcmeta new file mode 100644 index 0000000000..be7f8a1c5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_flat.png.mcmeta @@ -0,0 +1,8 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_glow.png new file mode 100644 index 0000000000..840fd93764 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_glow.png.mcmeta new file mode 100644 index 0000000000..9670314c6c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_glow.png.mcmeta @@ -0,0 +1,15 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + }, + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_latent.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_latent.png new file mode 100644 index 0000000000..77f5445b6d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/naga_latent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen.png new file mode 100644 index 0000000000..199909192e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_flat.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_flat.png new file mode 100644 index 0000000000..0968c1bc15 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_flat.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_flat.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_flat.png.mcmeta new file mode 100644 index 0000000000..be7f8a1c5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_flat.png.mcmeta @@ -0,0 +1,8 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_glow.png new file mode 100644 index 0000000000..7ae2a03d03 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_glow.png.mcmeta new file mode 100644 index 0000000000..9670314c6c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_glow.png.mcmeta @@ -0,0 +1,15 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + }, + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_latent.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_latent.png new file mode 100644 index 0000000000..6eeb678e7c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/snow_queen_latent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top.png new file mode 100644 index 0000000000..7b2c947fbc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_flat.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_flat.png new file mode 100644 index 0000000000..970d796662 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_flat.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_flat.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_flat.png.mcmeta new file mode 100644 index 0000000000..be7f8a1c5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_flat.png.mcmeta @@ -0,0 +1,8 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_glow.png new file mode 100644 index 0000000000..d6107fcfdc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_glow.png.mcmeta new file mode 100644 index 0000000000..9670314c6c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/top_glow.png.mcmeta @@ -0,0 +1,15 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + }, + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast.png new file mode 100644 index 0000000000..335e1dc6ca Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_flat.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_flat.png new file mode 100644 index 0000000000..281b023a24 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_flat.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_flat.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_flat.png.mcmeta new file mode 100644 index 0000000000..be7f8a1c5e --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_flat.png.mcmeta @@ -0,0 +1,8 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_glow.png new file mode 100644 index 0000000000..3edc331d08 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_glow.png.mcmeta new file mode 100644 index 0000000000..9670314c6c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_glow.png.mcmeta @@ -0,0 +1,15 @@ +{ + "animation": { + "width": 1, + "height": 16, + "frametime": 4, + "interpolate": true + }, + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_latent.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_latent.png new file mode 100644 index 0000000000..fd8164d6f6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/pedestal/ur-ghast_latent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_hydra.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_hydra.png deleted file mode 100644 index f2ac3aa213..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_hydra.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_hydra_active.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_hydra_active.png deleted file mode 100644 index c1c5d1a8a7..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_hydra_active.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_lich.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_lich.png deleted file mode 100644 index 15da25ffa5..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_lich.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_lich_active.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_lich_active.png deleted file mode 100644 index 3c7be2b445..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_lich_active.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_naga.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_naga.png deleted file mode 100644 index 717654d309..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_naga.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_naga_active.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_naga_active.png deleted file mode 100644 index 45ed3ab989..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_naga_active.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_top.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_top.png deleted file mode 100644 index a9f556ca7d..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_top.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_top_active.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_top_active.png deleted file mode 100644 index 8be0730175..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_top_active.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_urghast.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_urghast.png deleted file mode 100644 index c4ebf486fe..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_urghast.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_urghast_active.png b/src/main/resources/assets/twilightforest/textures/blocks/pedestal_urghast_active.png deleted file mode 100644 index 6611271139..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/pedestal_urghast_active.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/portal_barrier.png b/src/main/resources/assets/twilightforest/textures/blocks/portal_barrier.png new file mode 100644 index 0000000000..eecbb53686 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/portal_barrier.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/portal_barrier.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/portal_barrier.png.mcmeta new file mode 100644 index 0000000000..a8f1f63a81 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/portal_barrier.png.mcmeta @@ -0,0 +1,8 @@ +{ + "animation": { + "width": 1, + "height": 32, + "frametime": 2, + "interpolate": true + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/portal_gradient.png b/src/main/resources/assets/twilightforest/textures/blocks/portal_gradient.png new file mode 100644 index 0000000000..5465c114dc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/portal_gradient.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster.png b/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster.png index b6e16023e8..715e62a3de 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster.png and b/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster_glow.png new file mode 100644 index 0000000000..122d970284 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster_glow.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/ripe_torch_cluster_glow.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/rootblock.png b/src/main/resources/assets/twilightforest/textures/blocks/rootblock.png index bfed4d7163..9b312d2e8b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/rootblock.png and b/src/main/resources/assets/twilightforest/textures/blocks/rootblock.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sapling_canopy.png b/src/main/resources/assets/twilightforest/textures/blocks/sapling_canopy.png index 3789390406..f3191d0785 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sapling_canopy.png and b/src/main/resources/assets/twilightforest/textures/blocks/sapling_canopy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sapling_darkwood.png b/src/main/resources/assets/twilightforest/textures/blocks/sapling_darkwood.png index dc84363c9c..f2ab898ccf 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sapling_darkwood.png and b/src/main/resources/assets/twilightforest/textures/blocks/sapling_darkwood.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sapling_mangrove.png b/src/main/resources/assets/twilightforest/textures/blocks/sapling_mangrove.png index a569d30e15..dc567b6b1b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sapling_mangrove.png and b/src/main/resources/assets/twilightforest/textures/blocks/sapling_mangrove.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sapling_mining.png b/src/main/resources/assets/twilightforest/textures/blocks/sapling_mining.png index ab4198d10b..44ea6e696e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sapling_mining.png and b/src/main/resources/assets/twilightforest/textures/blocks/sapling_mining.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sapling_sorting.png b/src/main/resources/assets/twilightforest/textures/blocks/sapling_sorting.png index 1d5550fde1..704465086d 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sapling_sorting.png and b/src/main/resources/assets/twilightforest/textures/blocks/sapling_sorting.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sapling_time.png b/src/main/resources/assets/twilightforest/textures/blocks/sapling_time.png index a42b887006..0736e0c2be 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sapling_time.png and b/src/main/resources/assets/twilightforest/textures/blocks/sapling_time.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sapling_transformation.png b/src/main/resources/assets/twilightforest/textures/blocks/sapling_transformation.png index 1d448f0625..b6ab430b37 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sapling_transformation.png and b/src/main/resources/assets/twilightforest/textures/blocks/sapling_transformation.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/shield_inside.png b/src/main/resources/assets/twilightforest/textures/blocks/shield_inside.png index 96e88acc25..6e094773b8 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/shield_inside.png and b/src/main/resources/assets/twilightforest/textures/blocks/shield_inside.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/shield_outside.png b/src/main/resources/assets/twilightforest/textures/blocks/shield_outside.png index 2c2df0ca77..0df790bd3e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/shield_outside.png and b/src/main/resources/assets/twilightforest/textures/blocks/shield_outside.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/slider_h.png b/src/main/resources/assets/twilightforest/textures/blocks/slider_h.png index acd583c63e..3720be8de2 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/slider_h.png and b/src/main/resources/assets/twilightforest/textures/blocks/slider_h.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/slider_h_90.png b/src/main/resources/assets/twilightforest/textures/blocks/slider_h_90.png new file mode 100644 index 0000000000..0e2ea5a075 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/slider_h_90.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/slider_top.png b/src/main/resources/assets/twilightforest/textures/blocks/slider_top.png index b82db561a5..feee157204 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/slider_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/slider_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/slider_v.png b/src/main/resources/assets/twilightforest/textures/blocks/slider_v.png index 1a0f3c17df..9b9ef8d808 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/slider_v.png and b/src/main/resources/assets/twilightforest/textures/blocks/slider_v.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sort_eye.png b/src/main/resources/assets/twilightforest/textures/blocks/sort_eye.png index 89ee11e5c1..1f97ae8078 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sort_eye.png and b/src/main/resources/assets/twilightforest/textures/blocks/sort_eye.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sort_eye_off.png b/src/main/resources/assets/twilightforest/textures/blocks/sort_eye_off.png index 2613198e08..f67f0cec99 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sort_eye_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/sort_eye_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sort_leaves.png b/src/main/resources/assets/twilightforest/textures/blocks/sort_leaves.png index 6acebd5be6..17a4a9770c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sort_leaves.png and b/src/main/resources/assets/twilightforest/textures/blocks/sort_leaves.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/sort_section.png b/src/main/resources/assets/twilightforest/textures/blocks/sort_section.png index abca9140a5..fa1562f875 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/sort_section.png and b/src/main/resources/assets/twilightforest/textures/blocks/sort_section.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_down.png b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_down.png new file mode 100644 index 0000000000..7e896feb3b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_down.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_left.png b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_left.png new file mode 100644 index 0000000000..4c73697358 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_left.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_right.png b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_right.png new file mode 100644 index 0000000000..dcf62c5a85 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_right.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_up.png b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_up.png new file mode 100644 index 0000000000..7b77ed528d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/spiral_inner_up.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/spiral_shadow_x.png b/src/main/resources/assets/twilightforest/textures/blocks/spiral_shadow_x.png new file mode 100644 index 0000000000..a4197dc7c4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/spiral_shadow_x.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/spiral_shadow_z.png b/src/main/resources/assets/twilightforest/textures/blocks/spiral_shadow_z.png new file mode 100644 index 0000000000..23ea4cd5e7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/spiral_shadow_z.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/steelleaf_block.png b/src/main/resources/assets/twilightforest/textures/blocks/steelleaf_block.png new file mode 100644 index 0000000000..84cd151143 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/steelleaf_block.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_spiral_large.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_spiral_large.png new file mode 100644 index 0000000000..5a5bad4d19 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_spiral_large.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles.png new file mode 100644 index 0000000000..66aeb54dae Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles_mossy.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles_mossy.png new file mode 100644 index 0000000000..20ae2a1bd3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles_mossy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles_weathered.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles_weathered.png new file mode 100644 index 0000000000..8aed310340 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_tiles_weathered.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end.png new file mode 100644 index 0000000000..006ea45d81 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end.png.mcmeta new file mode 100644 index 0000000000..312620e108 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/end_ctm" ], + "extra": { + "connect_inside": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_x.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_x.png new file mode 100644 index 0000000000..006ea45d81 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_x.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_x.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_x.png.mcmeta new file mode 100644 index 0000000000..35a09db929 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_x.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/end_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "x" }, + { "down": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_y.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_y.png new file mode 100644 index 0000000000..006ea45d81 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_y.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_y.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_y.png.mcmeta new file mode 100644 index 0000000000..0526ac3a86 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_y.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/end_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "y" }, + { "down": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_z.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_z.png new file mode 100644 index 0000000000..006ea45d81 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_z.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_z.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_z.png.mcmeta new file mode 100644 index 0000000000..c017d7f051 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_bottom_z.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/end_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "z" }, + { "down": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_ctm.png new file mode 100644 index 0000000000..385a52ab37 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_x.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_x.png new file mode 100644 index 0000000000..006ea45d81 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_x.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_x.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_x.png.mcmeta new file mode 100644 index 0000000000..2267c1dd99 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_x.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/end_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "x" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_y.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_y.png new file mode 100644 index 0000000000..006ea45d81 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_y.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_y.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_y.png.mcmeta new file mode 100644 index 0000000000..4ff1806780 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_y.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/end_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "y" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_z.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_z.png new file mode 100644 index 0000000000..006ea45d81 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_z.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_z.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_z.png.mcmeta new file mode 100644 index 0000000000..d05fb4d43e --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/end_top_z.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/end_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "z" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x.png new file mode 100644 index 0000000000..346a374559 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x.png.mcmeta new file mode 100644 index 0000000000..7a0a787d8f --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/x_ctm" ], + "extra": { + "connect_inside": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_ctm.png new file mode 100644 index 0000000000..e66203035c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_bottom.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_bottom.png new file mode 100644 index 0000000000..346a374559 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_bottom.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_bottom.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_bottom.png.mcmeta new file mode 100644 index 0000000000..dd115b2d2c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_bottom.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/x_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "x" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_top.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_top.png new file mode 100644 index 0000000000..346a374559 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_top.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_top.png.mcmeta new file mode 100644 index 0000000000..dd115b2d2c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_x_top.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/x_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "x" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_bottom.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_bottom.png new file mode 100644 index 0000000000..346a374559 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_bottom.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_bottom.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_bottom.png.mcmeta new file mode 100644 index 0000000000..7cc76bf2ec --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_bottom.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/x_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "z" }, + { "down": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_top.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_top.png new file mode 100644 index 0000000000..346a374559 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_top.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_top.png.mcmeta new file mode 100644 index 0000000000..0f82209049 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/x_z_top.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/x_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "z" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y.png new file mode 100644 index 0000000000..e5a10fda49 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y.png.mcmeta new file mode 100644 index 0000000000..509cccd643 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y.png.mcmeta @@ -0,0 +1,10 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/y_ctm" ], + "extra": { + "connect_inside": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_ctm.png new file mode 100644 index 0000000000..4258fdb0a3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_bottom.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_bottom.png new file mode 100644 index 0000000000..e5a10fda49 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_bottom.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_bottom.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_bottom.png.mcmeta new file mode 100644 index 0000000000..140c7b0695 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_bottom.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/y_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "y" }, + { "down": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_top.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_top.png new file mode 100644 index 0000000000..e5a10fda49 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_top.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_top.png.mcmeta new file mode 100644 index 0000000000..fcc35dbc3d --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_y_top.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/y_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "y" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_bottom.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_bottom.png new file mode 100644 index 0000000000..e5a10fda49 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_bottom.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_bottom.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_bottom.png.mcmeta new file mode 100644 index 0000000000..9269d25ffa --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_bottom.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/y_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "z" }, + { "down": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_top.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_top.png new file mode 100644 index 0000000000..e5a10fda49 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_top.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_top.png.mcmeta new file mode 100644 index 0000000000..d600a7949b --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/cap/y_z_top.png.mcmeta @@ -0,0 +1,17 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "textures": [ "twilightforest:blocks/stone_twist/cap/y_ctm" ], + "extra": { + "connect_inside": true, + "connect_to": [{ + "block": "twilightforest:stone_twist_thin", + "predicate": [ + { "axis": "z" }, + { "up": false } + ] + }] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/pillar_side.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/pillar_side.png new file mode 100644 index 0000000000..6263484600 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/pillar_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_blank.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_blank.png new file mode 100644 index 0000000000..aeaf6d4b67 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_blank.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_blank.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_blank.png.mcmeta new file mode 100644 index 0000000000..6e4adff6e6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_blank.png.mcmeta @@ -0,0 +1,11 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "layer": "CUTOUT", + "textures": [ "twilightforest:blocks/stone_twist/twist_crown" ], + "extra": { + "connect_inside": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_crown.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_crown.png new file mode 100644 index 0000000000..bcd64b49c0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_crown.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_end.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_end.png new file mode 100644 index 0000000000..9ac46abb19 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_end.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_side.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_side.png new file mode 100644 index 0000000000..29d50c185f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_small.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_small.png new file mode 100644 index 0000000000..c201c1e5d8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_small.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x.png new file mode 100644 index 0000000000..a460ae80d4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x.png.mcmeta new file mode 100644 index 0000000000..8fbeb7f3d1 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x.png.mcmeta @@ -0,0 +1,11 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "layer": "CUTOUT", + "textures": [ "twilightforest:blocks/stone_twist/twist_x_ctm" ], + "extra": { + "connect_inside": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x_ctm.png new file mode 100644 index 0000000000..be45cbe475 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_x_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y.png new file mode 100644 index 0000000000..3dcbe806e8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y.png.mcmeta new file mode 100644 index 0000000000..0e202bbf02 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y.png.mcmeta @@ -0,0 +1,11 @@ +{ + "ctm": { + "ctm_version": 1, + "type": "ctm", + "layer": "CUTOUT", + "textures": [ "twilightforest:blocks/stone_twist/twist_y_ctm" ], + "extra": { + "connect_inside": true + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y_ctm.png b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y_ctm.png new file mode 100644 index 0000000000..7d25e1fea0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/stone_twist/twist_y_ctm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_0.png b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_0.png new file mode 100644 index 0000000000..a7b4ee4153 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_1.png b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_1.png new file mode 100644 index 0000000000..3e610fc3c7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_a.png b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_a.png new file mode 100644 index 0000000000..b0f530d195 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_a.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_b.png b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_b.png new file mode 100644 index 0000000000..885ff3721b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_b.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_c.png b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_c.png new file mode 100644 index 0000000000..b81ee693f0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_c.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_d.png b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_d.png new file mode 100644 index 0000000000..b6d9d0702a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/terrorcotta_d.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/thornRose.png b/src/main/resources/assets/twilightforest/textures/blocks/thornRose.png deleted file mode 100644 index 7db390eeee..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/thornRose.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/thorn_rose.png b/src/main/resources/assets/twilightforest/textures/blocks/thorn_rose.png new file mode 100644 index 0000000000..86142bd3ca Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/thorn_rose.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/time_clock.png b/src/main/resources/assets/twilightforest/textures/blocks/time_clock.png index 610840fd5e..160fe4827b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/time_clock.png and b/src/main/resources/assets/twilightforest/textures/blocks/time_clock.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/time_clock_off.png b/src/main/resources/assets/twilightforest/textures/blocks/time_clock_off.png index 0559c97441..23a0bfa10e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/time_clock_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/time_clock_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/time_leaves.png b/src/main/resources/assets/twilightforest/textures/blocks/time_leaves.png index cc92011a85..08a3749256 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/time_leaves.png and b/src/main/resources/assets/twilightforest/textures/blocks/time_leaves.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/time_section.png b/src/main/resources/assets/twilightforest/textures/blocks/time_section.png index d15e09d5a6..17d20227de 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/time_section.png and b/src/main/resources/assets/twilightforest/textures/blocks/time_section.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/time_side.png b/src/main/resources/assets/twilightforest/textures/blocks/time_side.png index 161b9c9fcc..2a3aea9450 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/time_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/time_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/torchberry.png b/src/main/resources/assets/twilightforest/textures/blocks/torchberry.png index 4f1937482d..25c525d79c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/torchberry.png and b/src/main/resources/assets/twilightforest/textures/blocks/torchberry.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/torchberry_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/torchberry_glow.png new file mode 100644 index 0000000000..b14a89f571 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/torchberry_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/torchberry_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/torchberry_glow.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/torchberry_glow.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_antibuilder_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_antibuilder_1.png new file mode 100644 index 0000000000..3788d10782 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_antibuilder_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_antibuilder_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_antibuilder_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_antibuilder_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_off_1.png new file mode 100644 index 0000000000..1b282b6c1d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_off_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_on_1.png new file mode 100644 index 0000000000..0df54daccc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_on_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_builder_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_firejet_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_firejet_1.png new file mode 100644 index 0000000000..302b44b0a8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_firejet_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_firejet_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_firejet_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_firejet_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_off_1.png new file mode 100644 index 0000000000..1310e1731b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_off_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_on_1.png new file mode 100644 index 0000000000..0b9962cfb5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_on_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_ghasttrap_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_off_1.png new file mode 100644 index 0000000000..831b7de5fb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_off_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_on_1.png new file mode 100644 index 0000000000..726130e1d3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_on_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_lock_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_off_1.png new file mode 100644 index 0000000000..c4ab4227f3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_off_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_on_1.png new file mode 100644 index 0000000000..1c26a1179f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_on_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reactor_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_off_1.png new file mode 100644 index 0000000000..3c95f7fa4a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_off_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_on_1.png new file mode 100644 index 0000000000..d8bcea1cd6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_on_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_reappearing_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_smoker_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_smoker_1.png new file mode 100644 index 0000000000..6f67731d04 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_smoker_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_smoker_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_smoker_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_smoker_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_off_1.png new file mode 100644 index 0000000000..b088077055 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_off_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_on_1.png new file mode 100644 index 0000000000..57edfa7721 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_on_1.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_1/towerdev_vanish_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilder_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilder_2.png new file mode 100644 index 0000000000..6014814d62 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilder_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilder_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilder_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilder_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilt_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilt_1.png new file mode 100644 index 0000000000..15bff36954 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilt_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilt_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilt_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_antibuilt_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_off_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_off_2.png new file mode 100644 index 0000000000..ba0fa2bc03 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_off_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_off_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_off_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_off_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_on_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_on_2.png new file mode 100644 index 0000000000..b46b135212 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_on_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_on_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_on_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_on_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_timeout_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_timeout_1.png new file mode 100644 index 0000000000..68719bad77 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_timeout_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_timeout_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_timeout_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_builder_timeout_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_off_1.png new file mode 100644 index 0000000000..1fa6b49f08 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_off_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_on_1.png new file mode 100644 index 0000000000..e1e527016a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_on_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_firejet_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_off_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_off_2.png new file mode 100644 index 0000000000..70c4661acb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_off_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_off_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_off_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_off_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_on_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_on_2.png new file mode 100644 index 0000000000..8f4b3da611 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_on_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_on_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_on_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttrap_on_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_off_1.png new file mode 100644 index 0000000000..cf84d76d73 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_off_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_on_1.png new file mode 100644 index 0000000000..57593e04d8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_on_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_ghasttraplid_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_off_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_off_2.png new file mode 100644 index 0000000000..8fd54c1bf9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_off_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_off_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_off_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_off_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_on_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_on_2.png new file mode 100644 index 0000000000..b08660df48 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_on_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_on_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_on_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_lock_on_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_off_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_off_2.png new file mode 100644 index 0000000000..aefbd5b34a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_off_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_off_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_off_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_off_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_on_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_on_2.png new file mode 100644 index 0000000000..646d36a635 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_on_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_on_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_on_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reactor_on_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_off_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_off_2.png new file mode 100644 index 0000000000..f56aa6cb55 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_off_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_off_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_off_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_off_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_on_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_on_2.png new file mode 100644 index 0000000000..7082c97968 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_on_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_on_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_on_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_reappearing_on_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_off_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_off_1.png new file mode 100644 index 0000000000..8b6a053077 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_off_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_off_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_off_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_off_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_on_1.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_on_1.png new file mode 100644 index 0000000000..89a3095e3d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_on_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_on_1.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_on_1.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_smoker_on_1.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_off_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_off_2.png new file mode 100644 index 0000000000..b6e6f021ac Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_off_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_off_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_off_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_off_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_on_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_on_2.png new file mode 100644 index 0000000000..30b7d28cab Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_on_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_on_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_on_2.png.mcmeta new file mode 100644 index 0000000000..ea101a51a0 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_2/towerdev_vanish_on_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 10 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_builder_timeout_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_builder_timeout_2.png new file mode 100644 index 0000000000..ec19476160 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_builder_timeout_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_builder_timeout_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_builder_timeout_2.png.mcmeta new file mode 100644 index 0000000000..7dec6518e6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_builder_timeout_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_ghasttraplid_on_2.png b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_ghasttraplid_on_2.png new file mode 100644 index 0000000000..a2e59e959e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_ghasttraplid_on_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_ghasttraplid_on_2.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_ghasttraplid_on_2.png.mcmeta new file mode 100644 index 0000000000..7dec6518e6 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/tower_device_level_3/towerdev_ghasttraplid_on_2.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_built_off.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_built_off.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_built_off.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_built_on.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_built_on.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_built_on.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_off.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_off.png index ea7760fe45..0b406a323e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_on.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_on.png index 86801c95f8..99c0ff4c8c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_on.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_firejet_on.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_off.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_off.png index 0bb27a3446..d5da86f0fa 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_on.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_on.png index d8a4665c7a..0e336075c1 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_on.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttrap_on.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_off.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_off.png index 3c29f581eb..e25e846231 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_on.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_on.png index caad218629..2546697740 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_on.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_ghasttraplid_on.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_off.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_off.png index 1b1e9a7101..36241ea305 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_on.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_on.png index 8a796620a5..4fc49d4849 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_on.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reactor_on.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reappearing_trace_off.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reappearing_trace_off.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reappearing_trace_off.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reappearing_trace_on.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reappearing_trace_on.png.mcmeta new file mode 100644 index 0000000000..eea6c1fe17 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_reappearing_trace_on.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "CUTOUT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_off.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_off.png index 60deb8941e..a3014c1321 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_on.png b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_on.png index 5907ec47d3..4b22cd2c2d 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_on.png and b/src/main/resources/assets/twilightforest/textures/blocks/towerdev_smoker_on.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/trans_heart.png b/src/main/resources/assets/twilightforest/textures/blocks/trans_heart.png index 2ef5663315..50d9059205 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/trans_heart.png and b/src/main/resources/assets/twilightforest/textures/blocks/trans_heart.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/trans_heart_off.png b/src/main/resources/assets/twilightforest/textures/blocks/trans_heart_off.png index 927442d60d..d58673574b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/trans_heart_off.png and b/src/main/resources/assets/twilightforest/textures/blocks/trans_heart_off.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/trans_leaves.png b/src/main/resources/assets/twilightforest/textures/blocks/trans_leaves.png index 5dd044e1c0..b23d3ade4f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/trans_leaves.png and b/src/main/resources/assets/twilightforest/textures/blocks/trans_leaves.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/trans_side.png b/src/main/resources/assets/twilightforest/textures/blocks/trans_side.png index bc2ca895a5..eb621118c1 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/trans_side.png and b/src/main/resources/assets/twilightforest/textures/blocks/trans_side.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/troll_root.png b/src/main/resources/assets/twilightforest/textures/blocks/troll_root.png index 37e7925b55..15f56e4ea9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/troll_root.png and b/src/main/resources/assets/twilightforest/textures/blocks/troll_root.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn.png b/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn.png index 6d0321ea29..50cc7bc4f4 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn.png and b/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn_light.png b/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn_light.png index 0154d6bda5..dc83fb0c15 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn_light.png and b/src/main/resources/assets/twilightforest/textures/blocks/trollsteinn_light.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil.png b/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil.png index ebd2d6d5f6..c043861c45 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil.png and b/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil_glow.png new file mode 100644 index 0000000000..26b7b0d4b5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil_glow.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/uberous_soil_glow.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_glow.png b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_glow.png new file mode 100644 index 0000000000..a6756ae057 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_glow.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_glow.png.mcmeta b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_glow.png.mcmeta new file mode 100644 index 0000000000..95fc346a21 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_glow.png.mcmeta @@ -0,0 +1,9 @@ +{ + "ctm": { + "ctm_version": 1, + "layer": "TRANSLUCENT", + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_particle.png b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_particle.png new file mode 100644 index 0000000000..724f54d4f6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_particle.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_top.png b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_top.png index ba686bf9c8..8e5c2b7d4e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_top.png and b/src/main/resources/assets/twilightforest/textures/blocks/uncrafting_top.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/unripe_torch_cluster.png b/src/main/resources/assets/twilightforest/textures/blocks/unripe_torch_cluster.png index 863696d638..b6d7f4d317 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/unripe_torch_cluster.png and b/src/main/resources/assets/twilightforest/textures/blocks/unripe_torch_cluster.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wispy_cloud.png b/src/main/resources/assets/twilightforest/textures/blocks/wispy_cloud.png index bf761e6479..dd9802920e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/blocks/wispy_cloud.png and b/src/main/resources/assets/twilightforest/textures/blocks/wispy_cloud.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/canopy_lower.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/canopy_lower.png new file mode 100644 index 0000000000..904fc97215 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/canopy_lower.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/canopy_upper.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/canopy_upper.png new file mode 100644 index 0000000000..0f0c3ee8c1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/canopy_upper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/dark_lower.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/dark_lower.png new file mode 100644 index 0000000000..944d10b929 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/dark_lower.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/dark_upper.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/dark_upper.png new file mode 100644 index 0000000000..8b23abcfc1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/dark_upper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mangrove_lower.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mangrove_lower.png new file mode 100644 index 0000000000..9ee7f479b2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mangrove_lower.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mangrove_upper.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mangrove_upper.png new file mode 100644 index 0000000000..1bfb244a4b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mangrove_upper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mine_lower.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mine_lower.png new file mode 100644 index 0000000000..5ab82508c7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mine_lower.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mine_upper.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mine_upper.png new file mode 100644 index 0000000000..0496c92f25 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/mine_upper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/sort_lower.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/sort_lower.png new file mode 100644 index 0000000000..7d19f41b7d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/sort_lower.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/sort_upper.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/sort_upper.png new file mode 100644 index 0000000000..8a005acba0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/sort_upper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/time_lower.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/time_lower.png new file mode 100644 index 0000000000..f30f2b29fb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/time_lower.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/time_upper.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/time_upper.png new file mode 100644 index 0000000000..7f103d6e51 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/time_upper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/twilight_oak_lower.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/twilight_oak_lower.png new file mode 100644 index 0000000000..91a4442f72 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/twilight_oak_lower.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/door/twilight_oak_upper.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/twilight_oak_upper.png new file mode 100644 index 0000000000..4e30ba5d8e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/door/twilight_oak_upper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_0.png new file mode 100644 index 0000000000..5f7b35054c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_1.png new file mode 100644 index 0000000000..da576e3bfe Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_2.png new file mode 100644 index 0000000000..5597f5e10f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_3.png new file mode 100644 index 0000000000..60bfea14eb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_canopy_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_0.png new file mode 100644 index 0000000000..0de685a06b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_1.png new file mode 100644 index 0000000000..868aa5f699 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_2.png new file mode 100644 index 0000000000..2a33c64a8d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_3.png new file mode 100644 index 0000000000..77dcfc67c4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_darkwood_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_0.png new file mode 100644 index 0000000000..8bd5b7551c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_1.png new file mode 100644 index 0000000000..005c518cee Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_2.png new file mode 100644 index 0000000000..34ec05b2cd Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_3.png new file mode 100644 index 0000000000..6af9ed63b7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mangrove_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_0.png new file mode 100644 index 0000000000..079ee0416c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_1.png new file mode 100644 index 0000000000..468743ee40 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_2.png new file mode 100644 index 0000000000..a64031582c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_3.png new file mode 100644 index 0000000000..276d24a2cf Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_mine_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_0.png new file mode 100644 index 0000000000..8c9d02c9ba Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_1.png new file mode 100644 index 0000000000..7ca2ecdf5b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_2.png new file mode 100644 index 0000000000..03a4298d97 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_3.png new file mode 100644 index 0000000000..560c5a9652 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_sort_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_0.png new file mode 100644 index 0000000000..b59f81fe3f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_1.png new file mode 100644 index 0000000000..8d3c0b99cd Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_2.png new file mode 100644 index 0000000000..70282d8c7d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_3.png new file mode 100644 index 0000000000..4d58103ed4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_time_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_0.png new file mode 100644 index 0000000000..d5da8c8e23 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_1.png new file mode 100644 index 0000000000..02a898140a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_2.png new file mode 100644 index 0000000000..cf5fa94baa Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_3.png new file mode 100644 index 0000000000..e31b1747e0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_trans_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_0.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_0.png new file mode 100644 index 0000000000..ce12a110c8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_1.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_1.png new file mode 100644 index 0000000000..12d8a91ae0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_2.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_2.png new file mode 100644 index 0000000000..f44d6f3dc3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_3.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_3.png new file mode 100644 index 0000000000..358766a5b1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/planks_twilight_oak_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/canopy_trapdoor.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/canopy_trapdoor.png new file mode 100644 index 0000000000..ec9c4e9ffd Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/canopy_trapdoor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/dark_trapdoor.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/dark_trapdoor.png new file mode 100644 index 0000000000..254967f9c7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/dark_trapdoor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/mangrove_trapdoor.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/mangrove_trapdoor.png new file mode 100644 index 0000000000..5ca11115e5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/mangrove_trapdoor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/mine_trapdoor.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/mine_trapdoor.png new file mode 100644 index 0000000000..de43d778cb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/mine_trapdoor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/sort_trapdoor.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/sort_trapdoor.png new file mode 100644 index 0000000000..78a05da39c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/sort_trapdoor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/time_trapdoor.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/time_trapdoor.png new file mode 100644 index 0000000000..4e64becb25 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/time_trapdoor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/twilight_oak_trapdoor.png b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/twilight_oak_trapdoor.png new file mode 100644 index 0000000000..45eb334dc8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/blocks/wood/trapdoor/twilight_oak_trapdoor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/environment/ashes.png b/src/main/resources/assets/twilightforest/textures/environment/ashes.png index fd67142119..c566a3baad 100644 Binary files a/src/main/resources/assets/twilightforest/textures/environment/ashes.png and b/src/main/resources/assets/twilightforest/textures/environment/ashes.png differ diff --git a/src/main/resources/assets/twilightforest/textures/environment/bigrain.png b/src/main/resources/assets/twilightforest/textures/environment/bigrain.png index ba0c9e2884..b5833168d9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/environment/bigrain.png and b/src/main/resources/assets/twilightforest/textures/environment/bigrain.png differ diff --git a/src/main/resources/assets/twilightforest/textures/environment/blizzard.png b/src/main/resources/assets/twilightforest/textures/environment/blizzard.png index 7de8417be6..8003f3c212 100644 Binary files a/src/main/resources/assets/twilightforest/textures/environment/blizzard.png and b/src/main/resources/assets/twilightforest/textures/environment/blizzard.png differ diff --git a/src/main/resources/assets/twilightforest/textures/environment/darkstream.png b/src/main/resources/assets/twilightforest/textures/environment/darkstream.png index eee7fa8b9c..7bea79266b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/environment/darkstream.png and b/src/main/resources/assets/twilightforest/textures/environment/darkstream.png differ diff --git a/src/main/resources/assets/twilightforest/textures/environment/mosquitoes.png b/src/main/resources/assets/twilightforest/textures/environment/mosquitoes.png index c7a5756029..8abe175c97 100644 Binary files a/src/main/resources/assets/twilightforest/textures/environment/mosquitoes.png and b/src/main/resources/assets/twilightforest/textures/environment/mosquitoes.png differ diff --git a/src/main/resources/assets/twilightforest/textures/environment/sparkles.png b/src/main/resources/assets/twilightforest/textures/environment/sparkles.png index a658a3c28e..418112c7f2 100644 Binary files a/src/main/resources/assets/twilightforest/textures/environment/sparkles.png and b/src/main/resources/assets/twilightforest/textures/environment/sparkles.png differ diff --git a/src/main/resources/assets/twilightforest/textures/gui/frosty.png b/src/main/resources/assets/twilightforest/textures/gui/frosty.png new file mode 100644 index 0000000000..bc7bfc2f10 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/gui/frosty.png differ diff --git a/src/main/resources/assets/twilightforest/textures/gui/glow_overlay.png b/src/main/resources/assets/twilightforest/textures/gui/glow_overlay.png index eff05777d9..50644d7156 100644 Binary files a/src/main/resources/assets/twilightforest/textures/gui/glow_overlay.png and b/src/main/resources/assets/twilightforest/textures/gui/glow_overlay.png differ diff --git a/src/main/resources/assets/twilightforest/textures/gui/guigoblintinkering.png b/src/main/resources/assets/twilightforest/textures/gui/guigoblintinkering.png index 2407651757..25da384be9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/gui/guigoblintinkering.png and b/src/main/resources/assets/twilightforest/textures/gui/guigoblintinkering.png differ diff --git a/src/main/resources/assets/twilightforest/textures/gui/mapicons.png b/src/main/resources/assets/twilightforest/textures/gui/mapicons.png index 8cffc74e7f..9e003cd552 100644 Binary files a/src/main/resources/assets/twilightforest/textures/gui/mapicons.png and b/src/main/resources/assets/twilightforest/textures/gui/mapicons.png differ diff --git a/src/main/resources/assets/twilightforest/textures/gui/page_filler.png b/src/main/resources/assets/twilightforest/textures/gui/page_filler.png new file mode 100644 index 0000000000..a1a4ab3eab Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/gui/page_filler.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/alphaFur.png b/src/main/resources/assets/twilightforest/textures/items/alphaFur.png deleted file mode 100644 index 5911c57e90..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/alphaFur.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/alpha_fur.png b/src/main/resources/assets/twilightforest/textures/items/alpha_fur.png new file mode 100644 index 0000000000..f5a1e6e13d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/alpha_fur.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/annihilate_particle.png b/src/main/resources/assets/twilightforest/textures/items/annihilate_particle.png deleted file mode 100644 index cd279b8c8e..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/annihilate_particle.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arcticBoots.png b/src/main/resources/assets/twilightforest/textures/items/arcticBoots.png deleted file mode 100644 index ff59bbfcad..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/arcticBoots.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arcticFur.png b/src/main/resources/assets/twilightforest/textures/items/arcticFur.png deleted file mode 100644 index a250a88e11..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/arcticFur.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arcticHelm.png b/src/main/resources/assets/twilightforest/textures/items/arcticHelm.png deleted file mode 100644 index b9a3921f9c..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/arcticHelm.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arcticLegs.png b/src/main/resources/assets/twilightforest/textures/items/arcticLegs.png deleted file mode 100644 index 793870dd25..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/arcticLegs.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arcticPlate.png b/src/main/resources/assets/twilightforest/textures/items/arcticPlate.png deleted file mode 100644 index 8c848e1595..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/arcticPlate.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_boots.png b/src/main/resources/assets/twilightforest/textures/items/arctic_boots.png new file mode 100644 index 0000000000..37c585e043 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_boots.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_boots_0.png b/src/main/resources/assets/twilightforest/textures/items/arctic_boots_0.png new file mode 100644 index 0000000000..08ea0cba40 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_boots_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_boots_1.png b/src/main/resources/assets/twilightforest/textures/items/arctic_boots_1.png new file mode 100644 index 0000000000..96129bd640 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_boots_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_fur.png b/src/main/resources/assets/twilightforest/textures/items/arctic_fur.png new file mode 100644 index 0000000000..9d8a75a75b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_fur.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_helm.png b/src/main/resources/assets/twilightforest/textures/items/arctic_helm.png new file mode 100644 index 0000000000..79ecd36231 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_helm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_helm_0.png b/src/main/resources/assets/twilightforest/textures/items/arctic_helm_0.png new file mode 100644 index 0000000000..f3894df227 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_helm_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_helm_1.png b/src/main/resources/assets/twilightforest/textures/items/arctic_helm_1.png new file mode 100644 index 0000000000..9a94d0979a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_helm_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_legs.png b/src/main/resources/assets/twilightforest/textures/items/arctic_legs.png new file mode 100644 index 0000000000..377ee2d6a5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_legs.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_legs_0.png b/src/main/resources/assets/twilightforest/textures/items/arctic_legs_0.png new file mode 100644 index 0000000000..8ad1b6bd37 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_legs_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_legs_1.png b/src/main/resources/assets/twilightforest/textures/items/arctic_legs_1.png new file mode 100644 index 0000000000..4251a07d73 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_legs_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_plate.png b/src/main/resources/assets/twilightforest/textures/items/arctic_plate.png new file mode 100644 index 0000000000..23b21eeddc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_plate_0.png b/src/main/resources/assets/twilightforest/textures/items/arctic_plate_0.png new file mode 100644 index 0000000000..f2ed29073e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_plate_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/arctic_plate_1.png b/src/main/resources/assets/twilightforest/textures/items/arctic_plate_1.png new file mode 100644 index 0000000000..107bcbc6fd Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/arctic_plate_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/armorShards.png b/src/main/resources/assets/twilightforest/textures/items/armorShards.png deleted file mode 100644 index eaa37fe3a7..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/armorShards.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/armor_shards.png b/src/main/resources/assets/twilightforest/textures/items/armor_shards.png new file mode 100644 index 0000000000..aacac1b294 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/armor_shards.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/bee/body.png b/src/main/resources/assets/twilightforest/textures/items/bee/body.png new file mode 100644 index 0000000000..3a5c089e14 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/bee/body.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/bee/crown_princess.png b/src/main/resources/assets/twilightforest/textures/items/bee/crown_princess.png new file mode 100644 index 0000000000..09081c913f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/bee/crown_princess.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/bee/crown_queen.png b/src/main/resources/assets/twilightforest/textures/items/bee/crown_queen.png new file mode 100644 index 0000000000..180355be59 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/bee/crown_queen.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/bee/outline_body.png b/src/main/resources/assets/twilightforest/textures/items/bee/outline_body.png new file mode 100644 index 0000000000..485ebe2f46 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/bee/outline_body.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/bee/outline_wings.png b/src/main/resources/assets/twilightforest/textures/items/bee/outline_wings.png new file mode 100644 index 0000000000..f66783ecf0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/bee/outline_wings.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/bee/tint.png b/src/main/resources/assets/twilightforest/textures/items/bee/tint.png new file mode 100644 index 0000000000..b1f5c1b96e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/bee/tint.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/bee/wings.png b/src/main/resources/assets/twilightforest/textures/items/bee/wings.png new file mode 100644 index 0000000000..074d6b2dbb Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/bee/wings.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/borerEssence.png b/src/main/resources/assets/twilightforest/textures/items/borerEssence.png deleted file mode 100644 index c863190efc..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/borerEssence.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/borer_essence.png b/src/main/resources/assets/twilightforest/textures/items/borer_essence.png new file mode 100644 index 0000000000..88d61612d1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/borer_essence.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/borer_essence.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/borer_essence.png.mcmeta new file mode 100644 index 0000000000..36845e4915 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/borer_essence.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/borer_essence_particles.png b/src/main/resources/assets/twilightforest/textures/items/borer_essence_particles.png new file mode 100644 index 0000000000..6a87db2c68 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/borer_essence_particles.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/borer_essence_particles.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/borer_essence_particles.png.mcmeta new file mode 100644 index 0000000000..f34eb7ba48 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/borer_essence_particles.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/carminite.png b/src/main/resources/assets/twilightforest/textures/items/carminite.png index aae1ad894d..534d18bdef 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/carminite.png and b/src/main/resources/assets/twilightforest/textures/items/carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/carminite.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/carminite.png.mcmeta new file mode 100644 index 0000000000..36845e4915 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/carminite.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 7 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/chainBlock.png b/src/main/resources/assets/twilightforest/textures/items/chainBlock.png deleted file mode 100644 index bfbc0bba7a..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/chainBlock.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/chain_block.png b/src/main/resources/assets/twilightforest/textures/items/chain_block.png new file mode 100644 index 0000000000..127cb22933 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/chain_block.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/chain_block_thrown.png b/src/main/resources/assets/twilightforest/textures/items/chain_block_thrown.png new file mode 100644 index 0000000000..fbaeedcb1b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/chain_block_thrown.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/charmOfKeeping1.png b/src/main/resources/assets/twilightforest/textures/items/charm_of_keeping_1.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/charmOfKeeping1.png rename to src/main/resources/assets/twilightforest/textures/items/charm_of_keeping_1.png diff --git a/src/main/resources/assets/twilightforest/textures/items/charmOfKeeping2.png b/src/main/resources/assets/twilightforest/textures/items/charm_of_keeping_2.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/charmOfKeeping2.png rename to src/main/resources/assets/twilightforest/textures/items/charm_of_keeping_2.png diff --git a/src/main/resources/assets/twilightforest/textures/items/charmOfKeeping3.png b/src/main/resources/assets/twilightforest/textures/items/charm_of_keeping_3.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/charmOfKeeping3.png rename to src/main/resources/assets/twilightforest/textures/items/charm_of_keeping_3.png diff --git a/src/main/resources/assets/twilightforest/textures/items/charmOfLife1.png b/src/main/resources/assets/twilightforest/textures/items/charm_of_life_1.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/charmOfLife1.png rename to src/main/resources/assets/twilightforest/textures/items/charm_of_life_1.png diff --git a/src/main/resources/assets/twilightforest/textures/items/charmOfLife2.png b/src/main/resources/assets/twilightforest/textures/items/charm_of_life_2.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/charmOfLife2.png rename to src/main/resources/assets/twilightforest/textures/items/charm_of_life_2.png diff --git a/src/main/resources/assets/twilightforest/textures/items/crumbleHorn.png b/src/main/resources/assets/twilightforest/textures/items/crumbleHorn.png deleted file mode 100644 index 2e2a03871d..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/crumbleHorn.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/crumble_horn.png b/src/main/resources/assets/twilightforest/textures/items/crumble_horn.png new file mode 100644 index 0000000000..274381a1bc Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/crumble_horn.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/cubeOfAnnihilation.png b/src/main/resources/assets/twilightforest/textures/items/cubeOfAnnihilation.png deleted file mode 100644 index f2333fc9a9..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/cubeOfAnnihilation.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/cubeTalisman.png b/src/main/resources/assets/twilightforest/textures/items/cubeTalisman.png deleted file mode 100644 index 38fb142f44..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/cubeTalisman.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/cube_of_annihilation.png b/src/main/resources/assets/twilightforest/textures/items/cube_of_annihilation.png new file mode 100644 index 0000000000..dbc710630b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/cube_of_annihilation.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/cube_of_annihilation_thrown.png b/src/main/resources/assets/twilightforest/textures/items/cube_of_annihilation_thrown.png new file mode 100644 index 0000000000..9945bc2662 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/cube_of_annihilation_thrown.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/cube_talisman.png b/src/main/resources/assets/twilightforest/textures/items/cube_talisman.png new file mode 100644 index 0000000000..8310cba210 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/cube_talisman.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/emptyEnchantedMap.png b/src/main/resources/assets/twilightforest/textures/items/emptyEnchantedMap.png deleted file mode 100644 index f25daab65d..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/emptyEnchantedMap.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/emptyOreMap.png b/src/main/resources/assets/twilightforest/textures/items/emptyOreMap.png deleted file mode 100644 index 8a0f03de49..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/emptyOreMap.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/empty_enchanted_map.png b/src/main/resources/assets/twilightforest/textures/items/empty_enchanted_map.png new file mode 100644 index 0000000000..23bfcf5555 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/empty_enchanted_map.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/emptyMagicMap.png b/src/main/resources/assets/twilightforest/textures/items/empty_magic_map.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/emptyMagicMap.png rename to src/main/resources/assets/twilightforest/textures/items/empty_magic_map.png diff --git a/src/main/resources/assets/twilightforest/textures/items/emptyMazeMap.png b/src/main/resources/assets/twilightforest/textures/items/empty_maze_map.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/emptyMazeMap.png rename to src/main/resources/assets/twilightforest/textures/items/empty_maze_map.png diff --git a/src/main/resources/assets/twilightforest/textures/items/empty_ore_map.png b/src/main/resources/assets/twilightforest/textures/items/empty_ore_map.png new file mode 100644 index 0000000000..49cda74164 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/empty_ore_map.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/enchantedMap.png b/src/main/resources/assets/twilightforest/textures/items/enchantedMap.png deleted file mode 100644 index ada7785093..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/enchantedMap.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/enchanted_map.png b/src/main/resources/assets/twilightforest/textures/items/enchanted_map.png new file mode 100644 index 0000000000..4189503d8e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/enchanted_map.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_0.png b/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_0.png index 5f22e64bcd..09823a3193 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_0.png and b/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_1.png b/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_1.png index c57079fe65..066194f996 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_1.png and b/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_2.png b/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_2.png index be73af4bdd..67ce09b405 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_2.png and b/src/main/resources/assets/twilightforest/textures/items/enderbow_pulling_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/enderbow_standby.png b/src/main/resources/assets/twilightforest/textures/items/enderbow_standby.png index e1a2f0a22e..809726cc28 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/enderbow_standby.png and b/src/main/resources/assets/twilightforest/textures/items/enderbow_standby.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/experiment115.png b/src/main/resources/assets/twilightforest/textures/items/experiment115.png deleted file mode 100644 index 177a557ee7..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/experiment115.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/experiment_115.png b/src/main/resources/assets/twilightforest/textures/items/experiment_115.png new file mode 100644 index 0000000000..b3433be93c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/experiment_115.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/tfFeather.png b/src/main/resources/assets/twilightforest/textures/items/feather.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/tfFeather.png rename to src/main/resources/assets/twilightforest/textures/items/feather.png diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryAxe.png b/src/main/resources/assets/twilightforest/textures/items/fieryAxe.png deleted file mode 100644 index 96729e159b..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryAxe.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryBlood.png b/src/main/resources/assets/twilightforest/textures/items/fieryBlood.png deleted file mode 100644 index f6f0344668..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryBlood.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryBoots.png b/src/main/resources/assets/twilightforest/textures/items/fieryBoots.png deleted file mode 100644 index 3e1d779d49..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryBoots.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryHelm.png b/src/main/resources/assets/twilightforest/textures/items/fieryHelm.png deleted file mode 100644 index 80f1d9478e..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryHelm.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryIngot.png b/src/main/resources/assets/twilightforest/textures/items/fieryIngot.png deleted file mode 100644 index 985ae3b991..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryIngot.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryLegs.png b/src/main/resources/assets/twilightforest/textures/items/fieryLegs.png deleted file mode 100644 index 50a125439b..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryLegs.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryPick.png b/src/main/resources/assets/twilightforest/textures/items/fieryPick.png deleted file mode 100644 index 2f10445263..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryPick.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryPlate.png b/src/main/resources/assets/twilightforest/textures/items/fieryPlate.png deleted file mode 100644 index 7b75a1b6b5..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryPlate.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fierySword.png b/src/main/resources/assets/twilightforest/textures/items/fierySword.png deleted file mode 100644 index 8e89af376e..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fierySword.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fieryTears.png b/src/main/resources/assets/twilightforest/textures/items/fieryTears.png deleted file mode 100644 index 6d1deeef5e..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/fieryTears.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_blood.png b/src/main/resources/assets/twilightforest/textures/items/fiery_blood.png new file mode 100644 index 0000000000..f80ac67e48 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_blood.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_boots.png b/src/main/resources/assets/twilightforest/textures/items/fiery_boots.png new file mode 100644 index 0000000000..7e3afbb318 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_boots.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_boots.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/fiery_boots.png.mcmeta new file mode 100644 index 0000000000..630e35d54c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/fiery_boots.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 18 + }, + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_helm.png b/src/main/resources/assets/twilightforest/textures/items/fiery_helm.png new file mode 100644 index 0000000000..57ecdf8647 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_helm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_helm.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/fiery_helm.png.mcmeta new file mode 100644 index 0000000000..630e35d54c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/fiery_helm.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 18 + }, + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_ingot.png b/src/main/resources/assets/twilightforest/textures/items/fiery_ingot.png new file mode 100644 index 0000000000..2f50f4a6c6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_ingot.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_ingot.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/fiery_ingot.png.mcmeta new file mode 100644 index 0000000000..630e35d54c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/fiery_ingot.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 18 + }, + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_legs.png b/src/main/resources/assets/twilightforest/textures/items/fiery_legs.png new file mode 100644 index 0000000000..450ef9eed6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_legs.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_legs.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/fiery_legs.png.mcmeta new file mode 100644 index 0000000000..630e35d54c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/fiery_legs.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 18 + }, + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_pick.png b/src/main/resources/assets/twilightforest/textures/items/fiery_pick.png new file mode 100644 index 0000000000..fd0f8fadba Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_pick.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_pick.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/fiery_pick.png.mcmeta new file mode 100644 index 0000000000..630e35d54c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/fiery_pick.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 18 + }, + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_plate.png b/src/main/resources/assets/twilightforest/textures/items/fiery_plate.png new file mode 100644 index 0000000000..9cbc77fa90 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_plate.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/fiery_plate.png.mcmeta new file mode 100644 index 0000000000..630e35d54c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/fiery_plate.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 18 + }, + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_sword.png b/src/main/resources/assets/twilightforest/textures/items/fiery_sword.png new file mode 100644 index 0000000000..b987a035fe Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_sword.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_sword.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/fiery_sword.png.mcmeta new file mode 100644 index 0000000000..630e35d54c --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/fiery_sword.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + "interpolate": true, + "frametime": 18 + }, + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/fiery_tears.png b/src/main/resources/assets/twilightforest/textures/items/fiery_tears.png new file mode 100644 index 0000000000..f5dc8b4689 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/fiery_tears.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/glassSword.png b/src/main/resources/assets/twilightforest/textures/items/glassSword.png deleted file mode 100644 index 4d856ed01a..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/glassSword.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/glass_sword_clear.png b/src/main/resources/assets/twilightforest/textures/items/glass_sword_clear.png new file mode 100644 index 0000000000..23812dbae3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/glass_sword_clear.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/glass_sword_solid.png b/src/main/resources/assets/twilightforest/textures/items/glass_sword_solid.png new file mode 100644 index 0000000000..745dbfb203 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/glass_sword_solid.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/hydraChop.png b/src/main/resources/assets/twilightforest/textures/items/hydraChop.png deleted file mode 100644 index 44abe2a57b..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/hydraChop.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/hydraTrophy.png b/src/main/resources/assets/twilightforest/textures/items/hydraTrophy.png deleted file mode 100644 index 32bc0232ca..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/hydraTrophy.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/hydra_chop.png b/src/main/resources/assets/twilightforest/textures/items/hydra_chop.png new file mode 100644 index 0000000000..af59370dce Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/hydra_chop.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/hydra_trophy.png b/src/main/resources/assets/twilightforest/textures/items/hydra_trophy.png new file mode 100644 index 0000000000..984a46dc09 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/hydra_trophy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/iceBomb.png b/src/main/resources/assets/twilightforest/textures/items/iceBomb.png deleted file mode 100644 index d5156277d3..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/iceBomb.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/iceSword.png b/src/main/resources/assets/twilightforest/textures/items/iceSword.png deleted file mode 100644 index 296f966062..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/iceSword.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bomb.png b/src/main/resources/assets/twilightforest/textures/items/ice_bomb.png new file mode 100644 index 0000000000..6a43971878 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bomb.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_0.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_0.png new file mode 100644 index 0000000000..359bd4eba8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_1.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_1.png new file mode 100644 index 0000000000..43881c335f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_2.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_2.png new file mode 100644 index 0000000000..943d8e6c24 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_pulling_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_standby.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_standby.png new file mode 100644 index 0000000000..f0deb6eca3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_clear_standby.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_0.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_0.png new file mode 100644 index 0000000000..4aa42ec058 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_1.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_1.png new file mode 100644 index 0000000000..1cc0518348 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_2.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_2.png new file mode 100644 index 0000000000..cb78aa0ece Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_pulling_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_standby.png b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_standby.png new file mode 100644 index 0000000000..83085f10b2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_bow_solid_standby.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_sword_clear.png b/src/main/resources/assets/twilightforest/textures/items/ice_sword_clear.png new file mode 100644 index 0000000000..df12c113e3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_sword_clear.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ice_sword_solid.png b/src/main/resources/assets/twilightforest/textures/items/ice_sword_solid.png new file mode 100644 index 0000000000..19a791dea6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ice_sword_solid.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_0.png b/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_0.png deleted file mode 100644 index 54c27c7982..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_0.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_1.png b/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_1.png deleted file mode 100644 index ce0b0ce142..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_1.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_2.png b/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_2.png deleted file mode 100644 index 29d601d70c..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/icebow_pulling_2.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/icebow_standby.png b/src/main/resources/assets/twilightforest/textures/items/icebow_standby.png deleted file mode 100644 index c14a4d4e6b..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/icebow_standby.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_carminite.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_carminite.png new file mode 100644 index 0000000000..3388b24134 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_energy.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_energy.png new file mode 100644 index 0000000000..d7fb83f699 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_energy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_scales.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_scales.png new file mode 100644 index 0000000000..831f28cd35 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_scales.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_streaks.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_streaks.png new file mode 100644 index 0000000000..05bb1c2165 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/chemthrower_streaks.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_carminite.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_carminite.png new file mode 100644 index 0000000000..6b5a1e8692 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_energy.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_energy.png new file mode 100644 index 0000000000..d133b98fdd Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_energy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_scales.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_scales.png new file mode 100644 index 0000000000..1516d1cae7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_scales.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_streaks.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_streaks.png new file mode 100644 index 0000000000..78f1dc5419 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/drill_streaks.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_carminite.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_carminite.png new file mode 100644 index 0000000000..adf33449ee Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_energy.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_energy.png new file mode 100644 index 0000000000..067dc05e25 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_energy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_scales.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_scales.png new file mode 100644 index 0000000000..a37fcb16c3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_scales.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_streaks.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_streaks.png new file mode 100644 index 0000000000..2403fe6088 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/railgun_streaks.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_carminite.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_carminite.png new file mode 100644 index 0000000000..3ecb86cf02 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_energy.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_energy.png new file mode 100644 index 0000000000..a5a28dbb65 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_energy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_scales.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_scales.png new file mode 100644 index 0000000000..fda35926a0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_scales.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_streaks.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_streaks.png new file mode 100644 index 0000000000..b89caacea7 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/revolver_streaks.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_carminite.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_carminite.png new file mode 100644 index 0000000000..799f98cf1f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_energy.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_energy.png new file mode 100644 index 0000000000..b921db146b Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_energy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_scales.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_scales.png new file mode 100644 index 0000000000..1b53bc9139 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_scales.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_streaks.png b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_streaks.png new file mode 100644 index 0000000000..193b6d1db2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/immersiveengineering/shield_streaks.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodLegs.png b/src/main/resources/assets/twilightforest/textures/items/ironwoodLegs.png deleted file mode 100644 index 97bc1e844d..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/ironwoodLegs.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodPlate.png b/src/main/resources/assets/twilightforest/textures/items/ironwoodPlate.png deleted file mode 100644 index 864a68f3bd..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/ironwoodPlate.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodAxe.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_axe.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodAxe.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_axe.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodBoots.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_boots.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodBoots.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_boots.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodHelm.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_helm.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodHelm.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_helm.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodHoe.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_hoe.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodHoe.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_hoe.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodIngot.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_ingot.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodIngot.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_ingot.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwood_legs.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_legs.png new file mode 100644 index 0000000000..af20d98bd0 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ironwood_legs.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodPick.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_pick.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodPick.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_pick.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwood_plate.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_plate.png new file mode 100644 index 0000000000..472717392f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ironwood_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodRaw.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_raw.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodRaw.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_raw.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodShovel.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_shovel.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodShovel.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_shovel.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ironwoodSword.png b/src/main/resources/assets/twilightforest/textures/items/ironwood_sword.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/ironwoodSword.png rename to src/main/resources/assets/twilightforest/textures/items/ironwood_sword.png diff --git a/src/main/resources/assets/twilightforest/textures/items/knightMetal.png b/src/main/resources/assets/twilightforest/textures/items/knightMetal.png deleted file mode 100644 index c4c4ba75d4..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightMetal.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knight_metal.png b/src/main/resources/assets/twilightforest/textures/items/knight_metal.png new file mode 100644 index 0000000000..3c4daba00d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knight_metal.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightlyAxe.png b/src/main/resources/assets/twilightforest/textures/items/knightlyAxe.png deleted file mode 100644 index f417f817c8..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightlyAxe.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightlyBoots.png b/src/main/resources/assets/twilightforest/textures/items/knightlyBoots.png deleted file mode 100644 index ed0dcda5d2..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightlyBoots.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightlyHelm.png b/src/main/resources/assets/twilightforest/textures/items/knightlyHelm.png deleted file mode 100644 index 183058a9b6..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightlyHelm.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightlyLegs.png b/src/main/resources/assets/twilightforest/textures/items/knightlyLegs.png deleted file mode 100644 index 1cb996a296..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightlyLegs.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightlyPick.png b/src/main/resources/assets/twilightforest/textures/items/knightlyPick.png deleted file mode 100644 index f98ee60ae6..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightlyPick.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightlyPlate.png b/src/main/resources/assets/twilightforest/textures/items/knightlyPlate.png deleted file mode 100644 index 6b94224cb2..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightlyPlate.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightlySword.png b/src/main/resources/assets/twilightforest/textures/items/knightlySword.png deleted file mode 100644 index f11c8a2848..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightlySword.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_axe.png b/src/main/resources/assets/twilightforest/textures/items/knightly_axe.png new file mode 100644 index 0000000000..0b3ed96976 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_axe.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_boots.png b/src/main/resources/assets/twilightforest/textures/items/knightly_boots.png new file mode 100644 index 0000000000..2c423a13e2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_boots.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_helm.png b/src/main/resources/assets/twilightforest/textures/items/knightly_helm.png new file mode 100644 index 0000000000..234c7066cf Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_helm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_legs.png b/src/main/resources/assets/twilightforest/textures/items/knightly_legs.png new file mode 100644 index 0000000000..62a5dd308f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_legs.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_pick.png b/src/main/resources/assets/twilightforest/textures/items/knightly_pick.png new file mode 100644 index 0000000000..0e5a43fd30 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_pick.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_plate.png b/src/main/resources/assets/twilightforest/textures/items/knightly_plate.png new file mode 100644 index 0000000000..3490263c32 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_shield.png b/src/main/resources/assets/twilightforest/textures/items/knightly_shield.png new file mode 100644 index 0000000000..7cfdb03bc3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_shield.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightly_sword.png b/src/main/resources/assets/twilightforest/textures/items/knightly_sword.png new file mode 100644 index 0000000000..8e72bf6b3a Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightly_sword.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightmetalRing.png b/src/main/resources/assets/twilightforest/textures/items/knightmetalRing.png deleted file mode 100644 index 24f4c64ed1..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/knightmetalRing.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/knightmetal_ring.png b/src/main/resources/assets/twilightforest/textures/items/knightmetal_ring.png new file mode 100644 index 0000000000..a564a8ffae Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/knightmetal_ring.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/lampOfCinders.png b/src/main/resources/assets/twilightforest/textures/items/lampOfCinders.png deleted file mode 100644 index a57242584f..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/lampOfCinders.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/lamp_of_cinders.png b/src/main/resources/assets/twilightforest/textures/items/lamp_of_cinders.png new file mode 100644 index 0000000000..d50a92dd54 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/lamp_of_cinders.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/legsNaga.png b/src/main/resources/assets/twilightforest/textures/items/legsNaga.png deleted file mode 100644 index 361c9a1a84..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/legsNaga.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/lichTrophy.png b/src/main/resources/assets/twilightforest/textures/items/lichTrophy.png deleted file mode 100644 index afc831e9e6..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/lichTrophy.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/lich_shield_fill.png b/src/main/resources/assets/twilightforest/textures/items/lich_shield_fill.png new file mode 100644 index 0000000000..9a54dfd870 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/lich_shield_fill.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/lich_shield_frame.png b/src/main/resources/assets/twilightforest/textures/items/lich_shield_frame.png new file mode 100644 index 0000000000..ccd61f3fcf Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/lich_shield_frame.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/lich_trophy.png b/src/main/resources/assets/twilightforest/textures/items/lich_trophy.png new file mode 100644 index 0000000000..e71ba119f9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/lich_trophy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/liveRoot.png b/src/main/resources/assets/twilightforest/textures/items/liveRoot.png deleted file mode 100644 index 745eaefb55..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/liveRoot.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/liveroot.png b/src/main/resources/assets/twilightforest/textures/items/liveroot.png new file mode 100644 index 0000000000..5c4ea60cb9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/liveroot.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/logbook/fresh.png b/src/main/resources/assets/twilightforest/textures/items/logbook/fresh.png new file mode 100644 index 0000000000..f5a9238a17 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/logbook/fresh.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/logbook/knowledgable.png b/src/main/resources/assets/twilightforest/textures/items/logbook/knowledgable.png new file mode 100644 index 0000000000..47d38bd8fa Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/logbook/knowledgable.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/logbook/supreme.png b/src/main/resources/assets/twilightforest/textures/items/logbook/supreme.png new file mode 100644 index 0000000000..58befb11ec Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/logbook/supreme.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/logbook/used.png b/src/main/resources/assets/twilightforest/textures/items/logbook/used.png new file mode 100644 index 0000000000..773e538851 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/logbook/used.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/magicBeans.png b/src/main/resources/assets/twilightforest/textures/items/magicBeans.png deleted file mode 100644 index 7fc9c64f1b..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/magicBeans.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/magicMap.png b/src/main/resources/assets/twilightforest/textures/items/magicMap.png deleted file mode 100644 index 05630b1fab..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/magicMap.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/magic_beans.png b/src/main/resources/assets/twilightforest/textures/items/magic_beans.png new file mode 100644 index 0000000000..62602fb7f5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/magic_beans.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/magic_map.png b/src/main/resources/assets/twilightforest/textures/items/magic_map.png new file mode 100644 index 0000000000..ba9dcdf8e3 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/magic_map.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/magicMapFocus.png b/src/main/resources/assets/twilightforest/textures/items/magic_map_focus.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/magicMapFocus.png rename to src/main/resources/assets/twilightforest/textures/items/magic_map_focus.png diff --git a/src/main/resources/assets/twilightforest/textures/items/mazeWafer.png b/src/main/resources/assets/twilightforest/textures/items/mazeWafer.png deleted file mode 100644 index ed8cad8ca6..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/mazeWafer.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/mazeMap.png b/src/main/resources/assets/twilightforest/textures/items/maze_map.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/mazeMap.png rename to src/main/resources/assets/twilightforest/textures/items/maze_map.png diff --git a/src/main/resources/assets/twilightforest/textures/items/mazeMapFocus.png b/src/main/resources/assets/twilightforest/textures/items/maze_map_focus.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/mazeMapFocus.png rename to src/main/resources/assets/twilightforest/textures/items/maze_map_focus.png diff --git a/src/main/resources/assets/twilightforest/textures/items/maze_wafer.png b/src/main/resources/assets/twilightforest/textures/items/maze_wafer.png new file mode 100644 index 0000000000..3b6990e732 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/maze_wafer.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/mazebreakerPick.png b/src/main/resources/assets/twilightforest/textures/items/mazebreaker_pick.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/mazebreakerPick.png rename to src/main/resources/assets/twilightforest/textures/items/mazebreaker_pick.png diff --git a/src/main/resources/assets/twilightforest/textures/items/meefRaw.png b/src/main/resources/assets/twilightforest/textures/items/meefRaw.png deleted file mode 100644 index 14db993e0b..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/meefRaw.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/meefSteak.png b/src/main/resources/assets/twilightforest/textures/items/meefSteak.png deleted file mode 100644 index 5253c791fa..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/meefSteak.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/meefStroganoff.png b/src/main/resources/assets/twilightforest/textures/items/meefStroganoff.png deleted file mode 100644 index 893aec2498..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/meefStroganoff.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/meef_raw.png b/src/main/resources/assets/twilightforest/textures/items/meef_raw.png new file mode 100644 index 0000000000..6de00b6d60 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/meef_raw.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/meef_steak.png b/src/main/resources/assets/twilightforest/textures/items/meef_steak.png new file mode 100644 index 0000000000..3c881df3c5 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/meef_steak.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/meef_stroganoff.png b/src/main/resources/assets/twilightforest/textures/items/meef_stroganoff.png new file mode 100644 index 0000000000..971845f634 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/meef_stroganoff.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/minotaurAxe.png b/src/main/resources/assets/twilightforest/textures/items/minotaur_axe.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/minotaurAxe.png rename to src/main/resources/assets/twilightforest/textures/items/minotaur_axe.png diff --git a/src/main/resources/assets/twilightforest/textures/items/minotaur_axe_gold.png b/src/main/resources/assets/twilightforest/textures/items/minotaur_axe_gold.png new file mode 100644 index 0000000000..84eb54cc96 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/minotaur_axe_gold.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/first_quarter.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/first_quarter.png new file mode 100644 index 0000000000..d6755ce5f1 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/first_quarter.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/full.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/full.png new file mode 100644 index 0000000000..2431d35e53 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/full.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/new.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/new.png new file mode 100644 index 0000000000..cf163e8b73 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/new.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/third_quarter.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/third_quarter.png new file mode 100644 index 0000000000..35a2cf9f7e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/third_quarter.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/waning_cresent.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waning_cresent.png new file mode 100644 index 0000000000..93f6b8cb44 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waning_cresent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/waning_gibbous.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waning_gibbous.png new file mode 100644 index 0000000000..f8d1537106 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waning_gibbous.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/waxing_cresent.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waxing_cresent.png new file mode 100644 index 0000000000..b32146f611 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waxing_cresent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moon_dial/waxing_gibbous.png b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waxing_gibbous.png new file mode 100644 index 0000000000..17dac567ca Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/moon_dial/waxing_gibbous.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/moonwormQueen.png b/src/main/resources/assets/twilightforest/textures/items/moonworm_queen.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/moonwormQueen.png rename to src/main/resources/assets/twilightforest/textures/items/moonworm_queen.png diff --git a/src/main/resources/assets/twilightforest/textures/items/moonworm_queen.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/moonworm_queen.png.mcmeta new file mode 100644 index 0000000000..d91d489b08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/moonworm_queen.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/moonwormQueenAlt.png b/src/main/resources/assets/twilightforest/textures/items/moonworm_queen_alt.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/moonwormQueenAlt.png rename to src/main/resources/assets/twilightforest/textures/items/moonworm_queen_alt.png diff --git a/src/main/resources/assets/twilightforest/textures/items/moonworm_queen_alt.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/moonworm_queen_alt.png.mcmeta new file mode 100644 index 0000000000..d91d489b08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/moonworm_queen_alt.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/nagaTrophy.png b/src/main/resources/assets/twilightforest/textures/items/nagaTrophy.png deleted file mode 100644 index 61aaa7bed4..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/nagaTrophy.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/naga_legs.png b/src/main/resources/assets/twilightforest/textures/items/naga_legs.png new file mode 100644 index 0000000000..6172287d49 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/naga_legs.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/naga_plate.png b/src/main/resources/assets/twilightforest/textures/items/naga_plate.png new file mode 100644 index 0000000000..ed16c81782 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/naga_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/nagaScale.png b/src/main/resources/assets/twilightforest/textures/items/naga_scale.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/nagaScale.png rename to src/main/resources/assets/twilightforest/textures/items/naga_scale.png diff --git a/src/main/resources/assets/twilightforest/textures/items/naga_trophy.png b/src/main/resources/assets/twilightforest/textures/items/naga_trophy.png new file mode 100644 index 0000000000..4e37d8065f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/naga_trophy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/oreMap.png b/src/main/resources/assets/twilightforest/textures/items/oreMap.png deleted file mode 100644 index 24a4e57cff..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/oreMap.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/oreMagnet.png b/src/main/resources/assets/twilightforest/textures/items/ore_magnet.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/oreMagnet.png rename to src/main/resources/assets/twilightforest/textures/items/ore_magnet.png diff --git a/src/main/resources/assets/twilightforest/textures/items/oreMagnet1.png b/src/main/resources/assets/twilightforest/textures/items/ore_magnet_pulling_1.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/oreMagnet1.png rename to src/main/resources/assets/twilightforest/textures/items/ore_magnet_pulling_1.png diff --git a/src/main/resources/assets/twilightforest/textures/items/oreMagnet2.png b/src/main/resources/assets/twilightforest/textures/items/ore_magnet_pulling_2.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/oreMagnet2.png rename to src/main/resources/assets/twilightforest/textures/items/ore_magnet_pulling_2.png diff --git a/src/main/resources/assets/twilightforest/textures/items/ore_map.png b/src/main/resources/assets/twilightforest/textures/items/ore_map.png new file mode 100644 index 0000000000..817a1e6329 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ore_map.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/oreMeter.png b/src/main/resources/assets/twilightforest/textures/items/ore_meter.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/oreMeter.png rename to src/main/resources/assets/twilightforest/textures/items/ore_meter.png diff --git a/src/main/resources/assets/twilightforest/textures/items/peacockFan.png b/src/main/resources/assets/twilightforest/textures/items/peacock_fan.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/peacockFan.png rename to src/main/resources/assets/twilightforest/textures/items/peacock_fan.png diff --git a/src/main/resources/assets/twilightforest/textures/items/phantomHelm.png b/src/main/resources/assets/twilightforest/textures/items/phantomHelm.png deleted file mode 100644 index 9047c4a041..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/phantomHelm.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/phantomPlate.png b/src/main/resources/assets/twilightforest/textures/items/phantomPlate.png deleted file mode 100644 index 9826784324..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/phantomPlate.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/phantom_helm.png b/src/main/resources/assets/twilightforest/textures/items/phantom_helm.png new file mode 100644 index 0000000000..2ebb9f8e35 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/phantom_helm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/phantom_plate.png b/src/main/resources/assets/twilightforest/textures/items/phantom_plate.png new file mode 100644 index 0000000000..5b98979855 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/phantom_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/plateNaga.png b/src/main/resources/assets/twilightforest/textures/items/plateNaga.png deleted file mode 100644 index d5c4c6efed..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/plateNaga.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/scepterLifeDrain.png b/src/main/resources/assets/twilightforest/textures/items/scepterLifeDrain.png deleted file mode 100644 index 1ef2ec3b3b..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/scepterLifeDrain.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/scepterTwilight.png b/src/main/resources/assets/twilightforest/textures/items/scepterTwilight.png deleted file mode 100644 index 83c009b6ce..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/scepterTwilight.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/scepter_lifedrain.png b/src/main/resources/assets/twilightforest/textures/items/scepter_lifedrain.png new file mode 100644 index 0000000000..ab0692d097 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/scepter_lifedrain.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/scepter_shielding.png b/src/main/resources/assets/twilightforest/textures/items/scepter_shielding.png new file mode 100644 index 0000000000..7d7561e578 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/scepter_shielding.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/scepter_twilight.png b/src/main/resources/assets/twilightforest/textures/items/scepter_twilight.png new file mode 100644 index 0000000000..85529970f8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/scepter_twilight.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/scepterZombie.png b/src/main/resources/assets/twilightforest/textures/items/scepter_zombie.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/scepterZombie.png rename to src/main/resources/assets/twilightforest/textures/items/scepter_zombie.png diff --git a/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_0.png b/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_0.png index fff2b5617b..66df5cf992 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_0.png and b/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_1.png b/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_1.png index 0bed2ab95e..258b362699 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_1.png and b/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_2.png b/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_2.png index aa172a68d8..39db349b47 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_2.png and b/src/main/resources/assets/twilightforest/textures/items/seekerbow_pulling_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/seekerbow_standby.png b/src/main/resources/assets/twilightforest/textures/items/seekerbow_standby.png index ad3596f4a8..4848746400 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/seekerbow_standby.png and b/src/main/resources/assets/twilightforest/textures/items/seekerbow_standby.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/shardCluster.png b/src/main/resources/assets/twilightforest/textures/items/shardCluster.png deleted file mode 100644 index 18a2d4efe2..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/shardCluster.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/shard_cluster.png b/src/main/resources/assets/twilightforest/textures/items/shard_cluster.png new file mode 100644 index 0000000000..e5f093f11f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/shard_cluster.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/snowQueenTrophy.png b/src/main/resources/assets/twilightforest/textures/items/snowQueenTrophy.png deleted file mode 100644 index 7e41a1cfa3..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/snowQueenTrophy.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/snow_0.png b/src/main/resources/assets/twilightforest/textures/items/snow_0.png deleted file mode 100644 index 8fb5c49c45..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/snow_0.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/snow_1.png b/src/main/resources/assets/twilightforest/textures/items/snow_1.png deleted file mode 100644 index 6031db794f..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/snow_1.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/snow_2.png b/src/main/resources/assets/twilightforest/textures/items/snow_2.png deleted file mode 100644 index 0e354f7686..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/snow_2.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/snow_3.png b/src/main/resources/assets/twilightforest/textures/items/snow_3.png deleted file mode 100644 index d5e6875bd2..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/snow_3.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/snow_queen_trophy.png b/src/main/resources/assets/twilightforest/textures/items/snow_queen_trophy.png new file mode 100644 index 0000000000..eb6f8423e4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/snow_queen_trophy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/star_burst_mask.png b/src/main/resources/assets/twilightforest/textures/items/star_burst_mask.png new file mode 100644 index 0000000000..52e56fe9f4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/star_burst_mask.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafPlate.png b/src/main/resources/assets/twilightforest/textures/items/steeleafPlate.png deleted file mode 100644 index fbc7d4d9c2..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/steeleafPlate.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafAxe.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_axe.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafAxe.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_axe.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafBoots.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_boots.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafBoots.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_boots.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafHelm.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_helm.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafHelm.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_helm.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafHoe.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_hoe.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafHoe.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_hoe.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafIngot.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_ingot.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafIngot.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_ingot.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafLegs.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_legs.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafLegs.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_legs.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafPick.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_pick.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafPick.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_pick.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleaf_plate.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_plate.png new file mode 100644 index 0000000000..b9764a9159 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/steeleaf_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafShovel.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_shovel.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafShovel.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_shovel.png diff --git a/src/main/resources/assets/twilightforest/textures/items/steeleafSword.png b/src/main/resources/assets/twilightforest/textures/items/steeleaf_sword.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/steeleafSword.png rename to src/main/resources/assets/twilightforest/textures/items/steeleaf_sword.png diff --git a/src/main/resources/assets/twilightforest/textures/items/think115.png b/src/main/resources/assets/twilightforest/textures/items/think115.png new file mode 100644 index 0000000000..46fd273ebd Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/think115.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/torchberries.png b/src/main/resources/assets/twilightforest/textures/items/torchberries.png index a049e23fbe..6eed87cafb 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/torchberries.png and b/src/main/resources/assets/twilightforest/textures/items/torchberries.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/torchberries.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/torchberries.png.mcmeta new file mode 100644 index 0000000000..d91d489b08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/torchberries.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/towerKey.png b/src/main/resources/assets/twilightforest/textures/items/tower_key.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/towerKey.png rename to src/main/resources/assets/twilightforest/textures/items/tower_key.png diff --git a/src/main/resources/assets/twilightforest/textures/items/tower_key.png.mcmeta b/src/main/resources/assets/twilightforest/textures/items/tower_key.png.mcmeta new file mode 100644 index 0000000000..d91d489b08 --- /dev/null +++ b/src/main/resources/assets/twilightforest/textures/items/tower_key.png.mcmeta @@ -0,0 +1,8 @@ +{ + "ctm": { + "ctm_version": 1, + "extra": { + "light": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/twilightforest/textures/items/transformPowder.png b/src/main/resources/assets/twilightforest/textures/items/transform_powder.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/transformPowder.png rename to src/main/resources/assets/twilightforest/textures/items/transform_powder.png diff --git a/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_0.png b/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_0.png index 1d4a0d3a03..09e83ab8d3 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_0.png and b/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_1.png b/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_1.png index c4777227a5..7cae314c5d 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_1.png and b/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_2.png b/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_2.png index 018d642898..0cace13de4 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_2.png and b/src/main/resources/assets/twilightforest/textures/items/triplebow_pulling_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/triplebow_standby.png b/src/main/resources/assets/twilightforest/textures/items/triplebow_standby.png index 2da99894e9..9b59c3cf5f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/items/triplebow_standby.png and b/src/main/resources/assets/twilightforest/textures/items/triplebow_standby.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/trophy.png b/src/main/resources/assets/twilightforest/textures/items/trophy.png new file mode 100644 index 0000000000..f108786e43 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/trophy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/trophy_minor.png b/src/main/resources/assets/twilightforest/textures/items/trophy_minor.png new file mode 100644 index 0000000000..4d8197d5c6 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/trophy_minor.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/trophy_quest.png b/src/main/resources/assets/twilightforest/textures/items/trophy_quest.png new file mode 100644 index 0000000000..b737be64f4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/trophy_quest.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/twilightOrb.png b/src/main/resources/assets/twilightforest/textures/items/twilight_orb.png similarity index 100% rename from src/main/resources/assets/twilightforest/textures/items/twilightOrb.png rename to src/main/resources/assets/twilightforest/textures/items/twilight_orb.png diff --git a/src/main/resources/assets/twilightforest/textures/items/urGhastTrophy.png b/src/main/resources/assets/twilightforest/textures/items/urGhastTrophy.png deleted file mode 100644 index 3aceda9812..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/urGhastTrophy.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/ur_ghast_trophy.png b/src/main/resources/assets/twilightforest/textures/items/ur_ghast_trophy.png new file mode 100644 index 0000000000..cde00590ac Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/ur_ghast_trophy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/venisonCooked.png b/src/main/resources/assets/twilightforest/textures/items/venisonCooked.png deleted file mode 100644 index dc6fd55ce3..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/venisonCooked.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/venisonRaw.png b/src/main/resources/assets/twilightforest/textures/items/venisonRaw.png deleted file mode 100644 index c83be0a434..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/venisonRaw.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/venison_cooked.png b/src/main/resources/assets/twilightforest/textures/items/venison_cooked.png new file mode 100644 index 0000000000..d53131fe1d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/venison_cooked.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/venison_raw.png b/src/main/resources/assets/twilightforest/textures/items/venison_raw.png new file mode 100644 index 0000000000..1d6a96d4ae Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/venison_raw.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yetiBoots.png b/src/main/resources/assets/twilightforest/textures/items/yetiBoots.png deleted file mode 100644 index 5cf685d3cb..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/yetiBoots.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yetiHelm.png b/src/main/resources/assets/twilightforest/textures/items/yetiHelm.png deleted file mode 100644 index fae59490dd..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/yetiHelm.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yetiLegs.png b/src/main/resources/assets/twilightforest/textures/items/yetiLegs.png deleted file mode 100644 index 286d7684d9..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/yetiLegs.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yetiPlate.png b/src/main/resources/assets/twilightforest/textures/items/yetiPlate.png deleted file mode 100644 index cc54a07ffd..0000000000 Binary files a/src/main/resources/assets/twilightforest/textures/items/yetiPlate.png and /dev/null differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yeti_boots.png b/src/main/resources/assets/twilightforest/textures/items/yeti_boots.png new file mode 100644 index 0000000000..a5bad23cb9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/yeti_boots.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yeti_helm.png b/src/main/resources/assets/twilightforest/textures/items/yeti_helm.png new file mode 100644 index 0000000000..6331ade4b8 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/yeti_helm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yeti_legs.png b/src/main/resources/assets/twilightforest/textures/items/yeti_legs.png new file mode 100644 index 0000000000..d9efb43714 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/yeti_legs.png differ diff --git a/src/main/resources/assets/twilightforest/textures/items/yeti_plate.png b/src/main/resources/assets/twilightforest/textures/items/yeti_plate.png new file mode 100644 index 0000000000..62d094e453 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/items/yeti_plate.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/adherent.png b/src/main/resources/assets/twilightforest/textures/model/adherent.png index e65facb98e..925368e3bc 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/adherent.png and b/src/main/resources/assets/twilightforest/textures/model/adherent.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/apocalypse2.png b/src/main/resources/assets/twilightforest/textures/model/apocalypse2.png index 0c4640ab3d..924b52e143 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/apocalypse2.png and b/src/main/resources/assets/twilightforest/textures/model/apocalypse2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/bighorn.png b/src/main/resources/assets/twilightforest/textures/model/bighorn.png index 7d4b4ac59b..592cab7f37 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/bighorn.png and b/src/main/resources/assets/twilightforest/textures/model/bighorn.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/blockgoblin.png b/src/main/resources/assets/twilightforest/textures/model/blockgoblin.png index 5ccd1bc34b..590c0a2778 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/blockgoblin.png and b/src/main/resources/assets/twilightforest/textures/model/blockgoblin.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/bunnybrown.png b/src/main/resources/assets/twilightforest/textures/model/bunnybrown.png index 5ee02968b0..5ae288446e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/bunnybrown.png and b/src/main/resources/assets/twilightforest/textures/model/bunnybrown.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/bunnydutch.png b/src/main/resources/assets/twilightforest/textures/model/bunnydutch.png index 8e0d2cadd1..ca73a7c724 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/bunnydutch.png and b/src/main/resources/assets/twilightforest/textures/model/bunnydutch.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/bunnywhite.png b/src/main/resources/assets/twilightforest/textures/model/bunnywhite.png index 0af800f02a..1c1aed00e0 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/bunnywhite.png and b/src/main/resources/assets/twilightforest/textures/model/bunnywhite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/carminitegolem.png b/src/main/resources/assets/twilightforest/textures/model/carminitegolem.png index a5e7fdcc25..9adad943be 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/carminitegolem.png and b/src/main/resources/assets/twilightforest/textures/model/carminitegolem.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/cicada-model.png b/src/main/resources/assets/twilightforest/textures/model/cicada-model.png index e8583026f2..d57aff4e5e 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/cicada-model.png and b/src/main/resources/assets/twilightforest/textures/model/cicada-model.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/cubeofannihilation.png b/src/main/resources/assets/twilightforest/textures/model/cubeofannihilation.png index 579486ae5c..eb2030609b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/cubeofannihilation.png and b/src/main/resources/assets/twilightforest/textures/model/cubeofannihilation.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/doublegoblin.png b/src/main/resources/assets/twilightforest/textures/model/doublegoblin.png index ff6da80c14..b690ccd91d 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/doublegoblin.png and b/src/main/resources/assets/twilightforest/textures/model/doublegoblin.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/finalcastle/castle_guardian.png b/src/main/resources/assets/twilightforest/textures/model/finalcastle/castle_guardian.png new file mode 100644 index 0000000000..d5ddb43788 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/model/finalcastle/castle_guardian.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/firebeetle.png b/src/main/resources/assets/twilightforest/textures/model/firebeetle.png index 30a24470c1..a66c300875 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/firebeetle.png and b/src/main/resources/assets/twilightforest/textures/model/firebeetle.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/firefly-tiny.png b/src/main/resources/assets/twilightforest/textures/model/firefly-tiny.png index 2a19b5ab8d..ac4be69fcd 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/firefly-tiny.png and b/src/main/resources/assets/twilightforest/textures/model/firefly-tiny.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/ghost-crown.png b/src/main/resources/assets/twilightforest/textures/model/ghost-crown.png index 9ec82cbf4e..127842dba3 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/ghost-crown.png and b/src/main/resources/assets/twilightforest/textures/model/ghost-crown.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/ghost.png b/src/main/resources/assets/twilightforest/textures/model/ghost.png index d3c124cef7..4c6b260084 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/ghost.png and b/src/main/resources/assets/twilightforest/textures/model/ghost.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/hedgespider.png b/src/main/resources/assets/twilightforest/textures/model/hedgespider.png index 6fb6003dcb..f2a3bf4cd9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/hedgespider.png and b/src/main/resources/assets/twilightforest/textures/model/hedgespider.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/helmetcrab.png b/src/main/resources/assets/twilightforest/textures/model/helmetcrab.png index c26c12abc5..8f298df1f8 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/helmetcrab.png and b/src/main/resources/assets/twilightforest/textures/model/helmetcrab.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/hydra4.png b/src/main/resources/assets/twilightforest/textures/model/hydra4.png index fd38ef0777..45d8ab83dd 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/hydra4.png and b/src/main/resources/assets/twilightforest/textures/model/hydra4.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/hydramortar.png b/src/main/resources/assets/twilightforest/textures/model/hydramortar.png index 8e977cfa5d..64aa44b23b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/hydramortar.png and b/src/main/resources/assets/twilightforest/textures/model/hydramortar.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/icecrystal.png b/src/main/resources/assets/twilightforest/textures/model/icecrystal.png index aff597604a..b6c4b856dc 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/icecrystal.png and b/src/main/resources/assets/twilightforest/textures/model/icecrystal.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/iceexploder.png b/src/main/resources/assets/twilightforest/textures/model/iceexploder.png index 26d24f9688..0600d4bef2 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/iceexploder.png and b/src/main/resources/assets/twilightforest/textures/model/iceexploder.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/iceshooter.png b/src/main/resources/assets/twilightforest/textures/model/iceshooter.png index 70fa2b4a93..b089a69a7a 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/iceshooter.png and b/src/main/resources/assets/twilightforest/textures/model/iceshooter.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_carminite.png b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_carminite.png new file mode 100644 index 0000000000..216d20efa2 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_carminite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_energy.png b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_energy.png new file mode 100644 index 0000000000..93f08a3ebe Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_energy.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_scales.png b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_scales.png new file mode 100644 index 0000000000..0dc95a926f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_scales.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_streaks.png b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_streaks.png new file mode 100644 index 0000000000..0489772e0e Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/model/immersiveengineering/minecart_streaks.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/kingspider.png b/src/main/resources/assets/twilightforest/textures/model/kingspider.png index e31f1fafe3..43101e76c1 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/kingspider.png and b/src/main/resources/assets/twilightforest/textures/model/kingspider.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/knightphantom.png b/src/main/resources/assets/twilightforest/textures/model/knightphantom.png index d416ee2d6d..fe347f87d6 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/knightphantom.png and b/src/main/resources/assets/twilightforest/textures/model/knightphantom.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/kobold.png b/src/main/resources/assets/twilightforest/textures/model/kobold.png index 5fdfbc810e..d2f9ff95fd 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/kobold.png and b/src/main/resources/assets/twilightforest/textures/model/kobold.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/mazeslime.png b/src/main/resources/assets/twilightforest/textures/model/mazeslime.png index df185b3d6a..3a60fe8d88 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/mazeslime.png and b/src/main/resources/assets/twilightforest/textures/model/mazeslime.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/minoshroomtaur.png b/src/main/resources/assets/twilightforest/textures/model/minoshroomtaur.png index cc2bc60f60..733890d057 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/minoshroomtaur.png and b/src/main/resources/assets/twilightforest/textures/model/minoshroomtaur.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/minotaur.png b/src/main/resources/assets/twilightforest/textures/model/minotaur.png index f11d5db96c..20a719e1df 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/minotaur.png and b/src/main/resources/assets/twilightforest/textures/model/minotaur.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/mistwolf.png b/src/main/resources/assets/twilightforest/textures/model/mistwolf.png index a2eb850004..d70b95ff79 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/mistwolf.png and b/src/main/resources/assets/twilightforest/textures/model/mistwolf.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/moonworm.png b/src/main/resources/assets/twilightforest/textures/model/moonworm.png index 5814ba9b2d..4b421ab73b 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/moonworm.png and b/src/main/resources/assets/twilightforest/textures/model/moonworm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/mosquitoswarm.png b/src/main/resources/assets/twilightforest/textures/model/mosquitoswarm.png index 95780e7143..c5d1a21ac9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/mosquitoswarm.png and b/src/main/resources/assets/twilightforest/textures/model/mosquitoswarm.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/nagahead.png b/src/main/resources/assets/twilightforest/textures/model/nagahead.png index 06ccd3badc..f0942f25fa 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/nagahead.png and b/src/main/resources/assets/twilightforest/textures/model/nagahead.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/nagahead_dazed.png b/src/main/resources/assets/twilightforest/textures/model/nagahead_dazed.png new file mode 100644 index 0000000000..b1c00de3ce Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/model/nagahead_dazed.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/nagasegment.png b/src/main/resources/assets/twilightforest/textures/model/nagasegment.png index cad221f013..523c0f891f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/nagasegment.png and b/src/main/resources/assets/twilightforest/textures/model/nagasegment.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/penguin.png b/src/main/resources/assets/twilightforest/textures/model/penguin.png index 428600fadc..8a2d900fc9 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/penguin.png and b/src/main/resources/assets/twilightforest/textures/model/penguin.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/phantomskeleton.png b/src/main/resources/assets/twilightforest/textures/model/phantomskeleton.png index bb452a9a55..57bb7cdade 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/phantomskeleton.png and b/src/main/resources/assets/twilightforest/textures/model/phantomskeleton.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/pinchbeetle.png b/src/main/resources/assets/twilightforest/textures/model/pinchbeetle.png index f496d6eb16..0a41b20a40 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/pinchbeetle.png and b/src/main/resources/assets/twilightforest/textures/model/pinchbeetle.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/protectionbox.png b/src/main/resources/assets/twilightforest/textures/model/protectionbox.png index cbf447ace2..38f876c1dd 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/protectionbox.png and b/src/main/resources/assets/twilightforest/textures/model/protectionbox.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/questram.png b/src/main/resources/assets/twilightforest/textures/model/questram.png index a1e2cf7c5f..15fb3e1703 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/questram.png and b/src/main/resources/assets/twilightforest/textures/model/questram.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/questram_lines.png b/src/main/resources/assets/twilightforest/textures/model/questram_lines.png index e5ba354c07..3165248401 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/questram_lines.png and b/src/main/resources/assets/twilightforest/textures/model/questram_lines.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/raven.png b/src/main/resources/assets/twilightforest/textures/model/raven.png index edacaa3af0..a5f2bcb120 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/raven.png and b/src/main/resources/assets/twilightforest/textures/model/raven.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/redcap.png b/src/main/resources/assets/twilightforest/textures/model/redcap.png index 5d03507ce8..6f867e7505 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/redcap.png and b/src/main/resources/assets/twilightforest/textures/model/redcap.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/redcapsapper.png b/src/main/resources/assets/twilightforest/textures/model/redcapsapper.png index 48356d47be..532cac0825 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/redcapsapper.png and b/src/main/resources/assets/twilightforest/textures/model/redcapsapper.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/skeletondruid.png b/src/main/resources/assets/twilightforest/textures/model/skeletondruid.png index 7d34f9a5e5..1d74471ff0 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/skeletondruid.png and b/src/main/resources/assets/twilightforest/textures/model/skeletondruid.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/slimebeetle.png b/src/main/resources/assets/twilightforest/textures/model/slimebeetle.png index 3a40fbebd0..c3c8cc526f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/slimebeetle.png and b/src/main/resources/assets/twilightforest/textures/model/slimebeetle.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/snowqueen.png b/src/main/resources/assets/twilightforest/textures/model/snowqueen.png index 8b2b119df3..8e904b4bee 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/snowqueen.png and b/src/main/resources/assets/twilightforest/textures/model/snowqueen.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/squirrel2.png b/src/main/resources/assets/twilightforest/textures/model/squirrel2.png index 3e0acc20b1..586db50222 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/squirrel2.png and b/src/main/resources/assets/twilightforest/textures/model/squirrel2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/swarmspider.png b/src/main/resources/assets/twilightforest/textures/model/swarmspider.png index 09006f924e..c19ea8f545 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/swarmspider.png and b/src/main/resources/assets/twilightforest/textures/model/swarmspider.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/tinybirdblue.png b/src/main/resources/assets/twilightforest/textures/model/tinybirdblue.png index 41836188fb..d129e9a7c4 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/tinybirdblue.png and b/src/main/resources/assets/twilightforest/textures/model/tinybirdblue.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/tinybirdbrown.png b/src/main/resources/assets/twilightforest/textures/model/tinybirdbrown.png index 8f6c54d092..6167060903 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/tinybirdbrown.png and b/src/main/resources/assets/twilightforest/textures/model/tinybirdbrown.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/tinybirdgold.png b/src/main/resources/assets/twilightforest/textures/model/tinybirdgold.png index f5830ceabf..98c6205e7a 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/tinybirdgold.png and b/src/main/resources/assets/twilightforest/textures/model/tinybirdgold.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/tinybirdred.png b/src/main/resources/assets/twilightforest/textures/model/tinybirdred.png index 3ffb97b919..b68f90e733 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/tinybirdred.png and b/src/main/resources/assets/twilightforest/textures/model/tinybirdred.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towerboss.png b/src/main/resources/assets/twilightforest/textures/model/towerboss.png index 8aa7731316..77b1733557 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towerboss.png and b/src/main/resources/assets/twilightforest/textures/model/towerboss.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towerboss_fire.png b/src/main/resources/assets/twilightforest/textures/model/towerboss_fire.png index d413aa4f19..f255230446 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towerboss_fire.png and b/src/main/resources/assets/twilightforest/textures/model/towerboss_fire.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towerboss_openeyes.png b/src/main/resources/assets/twilightforest/textures/model/towerboss_openeyes.png index 2315333070..20490e617f 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towerboss_openeyes.png and b/src/main/resources/assets/twilightforest/textures/model/towerboss_openeyes.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towerbroodling.png b/src/main/resources/assets/twilightforest/textures/model/towerbroodling.png index 877296c4d1..69f48cdd17 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towerbroodling.png and b/src/main/resources/assets/twilightforest/textures/model/towerbroodling.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towerghast.png b/src/main/resources/assets/twilightforest/textures/model/towerghast.png index e6a1c0ea38..d8069b4ec1 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towerghast.png and b/src/main/resources/assets/twilightforest/textures/model/towerghast.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towerghast_fire.png b/src/main/resources/assets/twilightforest/textures/model/towerghast_fire.png index d34be9c67d..8f8916a6aa 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towerghast_fire.png and b/src/main/resources/assets/twilightforest/textures/model/towerghast_fire.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towerghast_openeyes.png b/src/main/resources/assets/twilightforest/textures/model/towerghast_openeyes.png index 71cabed17e..f9ed4be272 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towerghast_openeyes.png and b/src/main/resources/assets/twilightforest/textures/model/towerghast_openeyes.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/towertermite.png b/src/main/resources/assets/twilightforest/textures/model/towertermite.png index 2528eec7db..170aa1af65 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/towertermite.png and b/src/main/resources/assets/twilightforest/textures/model/towertermite.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/troll.png b/src/main/resources/assets/twilightforest/textures/model/troll.png index 75057ba4e5..808dc0cd6a 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/troll.png and b/src/main/resources/assets/twilightforest/textures/model/troll.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/twilightlich64.png b/src/main/resources/assets/twilightforest/textures/model/twilightlich64.png index efd91056ca..b86ddf884a 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/twilightlich64.png and b/src/main/resources/assets/twilightforest/textures/model/twilightlich64.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/wildboar.png b/src/main/resources/assets/twilightforest/textures/model/wildboar.png index dfff96dafc..8c89b34e31 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/wildboar.png and b/src/main/resources/assets/twilightforest/textures/model/wildboar.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/wilddeer.png b/src/main/resources/assets/twilightforest/textures/model/wilddeer.png index 7d5c28959e..1c18fd2b69 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/wilddeer.png and b/src/main/resources/assets/twilightforest/textures/model/wilddeer.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/winterwolf.png b/src/main/resources/assets/twilightforest/textures/model/winterwolf.png index b917b3c17d..94b30c7e8c 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/winterwolf.png and b/src/main/resources/assets/twilightforest/textures/model/winterwolf.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/wraith.png b/src/main/resources/assets/twilightforest/textures/model/wraith.png index 21eb57e0af..0f876c7072 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/wraith.png and b/src/main/resources/assets/twilightforest/textures/model/wraith.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/yeti2.png b/src/main/resources/assets/twilightforest/textures/model/yeti2.png index 0147111eb1..7e696ecd30 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/yeti2.png and b/src/main/resources/assets/twilightforest/textures/model/yeti2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/model/yetialpha.png b/src/main/resources/assets/twilightforest/textures/model/yetialpha.png index 84b533c924..5b4b0baf74 100644 Binary files a/src/main/resources/assets/twilightforest/textures/model/yetialpha.png and b/src/main/resources/assets/twilightforest/textures/model/yetialpha.png differ diff --git a/src/main/resources/assets/twilightforest/textures/particles/annihilate_particle.png b/src/main/resources/assets/twilightforest/textures/particles/annihilate_particle.png new file mode 100644 index 0000000000..b079f80557 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/particles/annihilate_particle.png differ diff --git a/src/main/resources/assets/twilightforest/textures/particles/fallen_leaf.png b/src/main/resources/assets/twilightforest/textures/particles/fallen_leaf.png new file mode 100644 index 0000000000..b9dc83815f Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/particles/fallen_leaf.png differ diff --git a/src/main/resources/assets/twilightforest/textures/particles/firefly.png b/src/main/resources/assets/twilightforest/textures/particles/firefly.png new file mode 100644 index 0000000000..f531a133f4 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/particles/firefly.png differ diff --git a/src/main/resources/assets/twilightforest/textures/particles/snow_0.png b/src/main/resources/assets/twilightforest/textures/particles/snow_0.png new file mode 100644 index 0000000000..6cce89143c Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/particles/snow_0.png differ diff --git a/src/main/resources/assets/twilightforest/textures/particles/snow_1.png b/src/main/resources/assets/twilightforest/textures/particles/snow_1.png new file mode 100644 index 0000000000..d9669dc3e9 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/particles/snow_1.png differ diff --git a/src/main/resources/assets/twilightforest/textures/particles/snow_2.png b/src/main/resources/assets/twilightforest/textures/particles/snow_2.png new file mode 100644 index 0000000000..da5888478d Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/particles/snow_2.png differ diff --git a/src/main/resources/assets/twilightforest/textures/particles/snow_3.png b/src/main/resources/assets/twilightforest/textures/particles/snow_3.png new file mode 100644 index 0000000000..0a9aff3460 Binary files /dev/null and b/src/main/resources/assets/twilightforest/textures/particles/snow_3.png differ diff --git a/src/main/resources/assets/twilightforest/textures/twilightforest_logo.png b/src/main/resources/assets/twilightforest/textures/twilightforest_logo.png index 51722b3535..a198a8e8f3 100644 Binary files a/src/main/resources/assets/twilightforest/textures/twilightforest_logo.png and b/src/main/resources/assets/twilightforest/textures/twilightforest_logo.png differ diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 3e181edb09..8fe7dccdf4 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,16 +1,22 @@ [ { - "modid": "TwilightForest", + "modid": "twilightforest", "name": "The Twilight Forest", "description": "An enchanted forest dimension.", "version": "${version}", "mcversion": "${mcversion}", - "url": "http://www.minecraftforum.net/topic/561673-", + "url": "https://minecraft.curseforge.com/projects/the-twilight-forest", "updateUrl": "", - "authors": [ - "Benimatic (Ben Mazur)" + "authorList": [ + "Benimatic", + "AtomicBlom", + "Drullkus", + "Killer_Demon", + "quadraxis", + "Tamaized", + "williewillus" ], - "credits": "By Benimatic", + "credits": "By Benimatic (Ben Mazur)", "logoFile": "assets/twilightforest/textures/twilightforest_logo.png", "screenshots": [], "dependencies": [] diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 0000000000..e7988f6e3a --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "pack_format": 3, + "description": "Resources used for TwilightForest" + } +} \ No newline at end of file diff --git a/update.json b/update.json new file mode 100644 index 0000000000..b141e10dc8 --- /dev/null +++ b/update.json @@ -0,0 +1,22 @@ +{ + "homepage": "https://minecraft.curseforge.com/projects/the-twilight-forest", + "1.12.2": { + "3.8.689": "ADDED:\n • Extra Mob transformations for Powder of Transformation!\n\nCHANGED:\n • Improved textures for Uncrafting Table, Trophy Pedestal, Block-Chain Goblins, and Hermit Crabs.\n • Shield Scepter's magic shields render fully lit now, unaffected by darkness.\n • The magic shields also render in first-person.\n\nFIXED:\n • Fix crash when parrying Naga.\n • Fix crash with Trophy Pedestals upon unexpected Moonworm.\n • Small-time optimizations and code tidying here and there!", + "3.8.654": "FIXES:\n • Hotfix: Fixed a crash that happened on dedicated servers due to the new IE shaders.", + "3.8.652": "ADDED:\n • Added a Quadraxis to the team, A great addition to the mod.\n • Added Auroralized Glass.\n • Added actual Castle Brick Stairs, literally the sequel to Jesus.\n • Cicadas can now be shot from an Immersive Engineering Railgun. You monster.\n • Added the Skylight Forest.\n • Skylight Forest is a skyblock variant of Twilight Forest with only structures generating on their own little islands and everything else as void.\n • Parrots can now mimic any and all mobs in the mod. :parrot_party:\n • Added the Scepter of Fortification\n • A new scepter dropped by the Lich that summons five (5) shields around you that each block a hit.\n • Progression advancements each grant three (3) shields that don't decay over time.\n • The Naga Can now be dazed if it rams a blocking shield with its charge attack, knocking you both backwards in the process.\n • Giant Tools now have a longer reach.\n • The uncrafting Table is now compatible with shapeless recipes. It totally didn't become twice as broken in potential!\n • It can now also cycle through multiple recipes in case of conflict.\n • Added tool shaders for Immersive Engineering with their own rarity, these include:\nTwilight, Firefly, Pinch Beetle, Snakestone, Mazestone, Underbrick, Towerwood, Carminite, Auroralized, Ironwood, Steeleaf, Knightly, Fiery, Final Castle, Cube of Annihilation, Questing Ram, Naga, Lich, Minoshroom, Hydra, Knight Phantom, Ur-Ghast, Alpha Yeti, Snow Queen.\n\nCHANGED:\n • Reworked the Druid Huts completely.\n • Druid Huts are no longer the number one fire hazard in the forest. \n • /tffeature now can locate structures and can use tab-completion for so.\n • Phantom Armor when worn is now kept on death.\n • It also cannot be enchanted with Curse of Binding and Curse of Vanishing anymore.\n • Improved handling of items displaced by a Charm of Keeping, should be more reliable now.\n • Tweaked Axe damage and speed values to better match vanilla.\n • Blacklisted surface lakes from some of the biomes.\n • Mobs like Deer, Boars, etc. are now unable to spawn on the Glacier.\n • The Minoshroom's charge attack now breaks through blocks.\n • Spiral Bricks are now in the creative menu.\n • Maze ceilings now always generated if there is no terrain.\n • Strongholds are now marked as clear on the last Knight's death.\n • Tweaked the Synergy tool trait.\n • There can now be multiple portal activations items specified in the config.\n • Twilight Saplings can now be used as Furnace fuel.\n • The Encased Firejet and Smoker now count as a wood material instead of stone.\n • Arctic Fur Blocks now break faster with shears.\n • Fiddleheads now require Shears to harvest.\n • The Lich's shields are now proper 3D models instead of two textures loosely glued together.\n • TF now registers its TEs under our own namespace, not the default. We have a datafixer that handles the transition, but once updated to this version the datafix is irreversible.\n\nFIXED:\n • Players can no longer spawn on top of the portal which would teleport them back into the overworld right away. Good lord that was annoying.\n • Improved a lot of the logic relating to the Twilight Forest portal.\n • Fixed an issue with Trophy Pedestal progression where it didn't unlock after the Lich.\n • Remeasured the sizes of goblin's feet. Their boots should render on and fit them again.\n • The Seeker Bow now actually, you know, seeks again.\n • Fixed crash related to getting localized names of saplings on servers.\n • Removed a redundant language key in the Forgotten Explorer book for Yeti Caves.\n • Fixed Minotaurs dropping Magic Map foci instead of Maze Map.\n • Fiery tool heads now correctly have the missing Twilit and Flammable traits.\n • Changed the grip on the Moonworm Queen to be more comfortable, now correctly holding it as a tool in third person view.\n • Fixed a portal generation issue where it would generate underwater.\n • Added a null-check to tile entity access, fixing a crash with Mystcraft.\n • Cleaned up Bauble handling code, fixing console spam.\n • Fixed the blockstate rotations for Castle Brick Stair variants.\n • Fixed the lighting on some of the stair blocks.\n • Fixed incorrect level cost being shown for some recrafting recipes.\n • Giant blocks now correctly tile their texture.\n • Fixed a lighting issue on Fiery Blocks.\n • Portals are now prevented from generating inside of structures.\n • Refactored Naga Courtyard code, hopefully fixes generation issues.\n • Alternate Naga Courtyard Terrace pieces now generate again. #BlameDrullkus\n • Fixed a crash with the Uncrafting Table by adding some more checks.\n • The Fiery Pickaxe now correctly smelts every item a block drops if it drops multiple.\n • Fixed a Repeater in the Dark Tower not repeating what should be repeated, with delay.\n • Giant Leaves are now correctly tinted in inventories.\n • Fixed Uberous Soil not generating at the correct height.\n • Fixed the Snow Queen marking the wrong structure conquered on death.\n • Fixed the Charm of Keeping effects.\n • Setting the game to peaceful now correctly has the Snow waifu Queen put her spawner back.\n • Snow Queen minions now correctly spawn inside of the boss room during the fight.\n • Giant Tools are now held in a more human like fashion.\n • Firefly, Moonworm, and Cicada no longer use Soul Sand as their breaking particles.\n • Fixed the texture auto generator only processing first texture in array.\n • Lampposts can now generate again after several years. Neat.\n • Large mushrooms should no longer piggyback on top of each other.\n • Seeds even with only numbers were being used as seeds to make a random number seed instead of directing being used as a random number seed. Confusing, we know!", + "3.7.424": "ADDED:\n • We split the progression into three separate lines, meaning that instead of clearing one dungeon and moving to the next in line, you now have the choice after defeating the Lich to go to the Hydra, Ur-Ghast, or Aurora Palace first.\nDefeating all three is still necessary to gain access to the Highlands.\n • Tinkers' Construct integration!\n • Added Tinker's Construct Integration with Naga Scales, Steeleaves, Fiery Ingots, Knightmetal Ingots, and Raven's Feathers to make materials & tools out of.\n • Added unique traits for each material:\n • Twilit appears on all Twilight Forest materials, meaning your tool gains +2 speed in the Twilight Forest and deals +2 damage in any other dimension.\n • Precipitate appears on Naga Scale materials, it lets you use the tool quicker with the lesser health on your Player.\n • Synergy appears on Steeleaf materials, it will passively repair the tool if you have Steeleaf in your hotbar. The more Steeleaves you have in the hotbar, the faster it repairs.\n • Stalwart appears on Knightmetal materials, it will make you more resilient in combat.\n • Veiled appears on Raven's Feather materials, it will render arrows invisible.\n • Baubles integration!\n • All charms can now be used in the off-hand and also equipped in the Baubles inventory.\n • All tiers of the Charm of Keeping will keep the Baubles Inventory.\n • Thaumcraft Compat: Live & Reloaded! All items and blocks (aside from unobtainable and some WIP items) now have aspects.\n • Added a config option to make the Portal creation lightning not cause fires, disable it if you're against pyromania derrived fun.\n • Made a new potion effect for the ice render effect from Ice Bombs, Ice Bow, etc. instead of putting it on the Slowness effect.\n • This also stops ice getting applied getting the slowness effect under certain conditions.\n • The Block and Chain now disables shields like an axe.\n • Added config option for players spawning for the first time to spawn in the Twilight Forest. Off by default.\n • Added config option to make Twilight Portals create a blocked-off portal at their destination. Toss in the activation item to unblock the portal. Off by default.\n • Added recipes where Iron armor and tools can be crafted directly into their Fiery counterparts.\n • Added Shield-Parrying for all Twilight Forest Projectiles. Installing https://minecraft.curseforge.com/projects/parry Shield Parry mod causes Twilight Forest to skip its parrying methods.\n • Updated the Japanese language file.\n • Updated the Chinese language file.\n • The Russian language file now covers everything in the mod.\nCHANGED:\n • Changed the Creative menu icon to the Miniature Portal item.\n • The advancements Past the Thorns and So Castle Very Wow now have a [NYI] tag in their names to signify they are not functional yet.\n • All tiers of the Charm of Keeping now preserve items in the off-hand slot.\n • Charm of Keeping usage now drops any items that would be overwritten by an item saved to prevent item loss if something is put in the player's inventory.\n • Code Improvements for Naga Courtyard.\nFIXED:\n • Magic Maps now properly update after switching Dimensions\n • The Zombie Scepter no longer joins its zombie kind by destroying itself at 0 durability.\n • Special leaves in Twilight Forest are now using the ore dictionary properly. (This totally wasn’t solved previously and went undocumented we swear.)\n • Ore magnet no longer checks ModID in the registry string.\n • Mazestone and its variants once again consume 16 durability from your mining tools when mined.\n • Castle Doors no longer have their texture broken.\n • Charm of Life effect upon death now uses the correct sprite.\n • Improved algorithm for the Miner's Tree, it should be less confused and stuck when trying to pull ores from the ground.\n • Fixed some blocks missing getBlockFaceShape overrides, causing glass panes, fences, walls, etc. to connect to blocks when they shouldn't.\n • Fixed the placement problems with Spiral Bricks and took off the [WIP] tag.\n • Finally fixed texture and UV problems with Knightly Armor and Phantom Armor; rejoice!\n • Ur-Ghast's tears should be visible again in Multiplayer when it's throwing a tantrum.", + "3.6.345": "FIXES:\n • Hotfix: Fixed players getting kicked from servers when near locked structures.", + "3.6.343": "FIXES:\n • Hotfix: Fixed Sponge server crashing related to packet fix last release.", + "3.6.342": "ADDED:\n • Not yet fully implemented Tinkers' Construct compatibility for some of our materials to make tools out of.\n\nFIXES:\n • Fixed our Forge minimum version dependency string being behind.\n • Fixed potential console spam related to weather rendering when the mod 'Fancy Block Particles' is present.\n • Added a message that if Sponge is installed the max bounding-box-size should be adjusted for Hydras to show up properly.\n • Removed the structure layout print debug that appears in the console, made it into the release on accident.\n • Fixed a config-related crash.\n • Fixed a generation problem with terraces being mashed together despite us telling them not do.", + "3.6.324": "ADDED:\n • The Naga Courtyard has received a complete revamp while maintaining the old style of it.\n • More things are planned at a later date for a second batch.\n • Many new blocks styled for and after the Naga including but not limited to:\n • Etched Nagastone\n • Block is available in 6 rotations. It's a block that kind of is placed like a pillar except the swirls on the block are placed dependent on the direction you placed.\n • Has 2x2 stone tiles on the end.\n • Comes in normal, mossy, and cracked variants.\n • Nagastone Pillar\n • Block is available in 3 axal rotations.\n • Works like vanilla Quartz Pillar Block.\n • Comes in normal, mossy, and cracked variants.\n • Nagastone Stairs\n • Textures like Etched Nagastone.\n • Has Left and Right facing variants dictating which way the swirls go.\n • Both Left and Right come in normal, mossy, and cracked variants.\n • Spiral Stone Bricks\n • Can be used in a 2x2 patterns to make a complete spiral.\n • The block itself is in 3D and has depth not only through shading.\n • The Uncrafting Table was added to the list of Crafting Tables for the Crafting Category in JEI.\n • Two original music tracks by MrOwltkins were added.\n • Updated our Chinese language file thanks to 3TUSK.\nCHANGED:\n • Block And Chain now appears from your left hand if used in the off-hand slot.\n • Also cleaned up the code around there.\n • shifted the Knightmetal Loop texture to the middle.\n • Block and Chain + Cube of Annihilation leave their x16 boundary to accommodate their texture.\n • Made the Block and Chain thicker when held.\n • The Block and Chain recieved a model override, the texture will change to only the loop when it is thrown.\n • Cube of Annihilation recieved a new texture for this too.\n • Optimized Cicadas, Fireflies, and Moonworms for the server side.\n • Made TF Critters not tick at all on the server side.\n • Wispy Clouds are now dropped when broken.\n • Removed unused EntityTFTinyFirefly (old version of ParticleFirefly).\n • Made Castle Doors breakable again so people can use them until the Final Castle is implemented fully, afterwards we'll prevent them from breaking until the structure is cleared.\n • Broke the fourth wall, wont fix.\nFIXES:\n • Made the player invulnerable when teleporting across dimensions, this was the issue causing players to wrongly teleport.\n • Fixed the issue when going through a portal would displace you up in the air.\n • Moved the language key for \"Underbrick Floor\" from meta 2 to meta 3 to fix lang entry collision for Underbrick.\n • Fixed a crash that happened due to the mod OpenTerrainGenerator.\n • Magic Beans once again properly grow into beanstalks on dedicated servers.\n • The vignette that appears in low light no longer randomly flickers in the Twilight Forest.\n • Fixed Root Strands being offset downwards for the second time, hopefully preventing them to sag with age.\n • Placing a giant block where it would replace a snow layer no longer crashes the client.\n • Moonworm Queen no longer breaks like a tool when it hits 0 durability.\n • Only the Moonworm Queen you're using should wiggle now instead of all of them when you have multiple.\n • Scepter of Twilight/Life Draining once again can be recharged.\n • Fixed the broken fourth wall.", + "3.5.263": "ADDED:\n • Added compatibility for many of our blocks with Chisel.\n • Crafting recipes added for Final Castle related blocks.\n • Vanilla's block to stairs ratio in crafting makes no sense, we opted for the stair recipes to give you 8 instead of the usual 4.\n\nCHANGED:\n • \"And Drullkus said; \"let portals be shapeless!\" And it was so.\"\n • Portals can now be made into any horizontal shape.\n • They still have the same requirements (water pool, plants surrounding it, etc.)\n\nFIXES:\n • Fixed a serious crash involving the Anti-Builder.\n • Fixed an issue with the Trophies interacting with other mods such as Skillable.\n • Also caught an Item Stack null.\n • All magic tree log variants now drop their respective wood properly.\n • Made sure bosses are recognised as such by the game.\n • Collected all of the Fireflies that escaped the Firefly Jar and put them back in.\n • The Firefly \"block\" also gives off its little firefly lights again.\n • Resolved some Hydra rotation issues; it should no longer track you by spinning around at the speed of sound.", + "3.4.239": "ADDED:\n • We now have loading screens when going to the Twilight Forest! \n • The Naga and Lich now have fancy incremental boss bars for the body segments and phases respectively.\n • The Block of Fiery Metal now has a fancy model.\n • Arctic armour now has lore text that makes it clear it can be dyed.\n • Also added a advancement related to dying Arctic armour.\n • Armour made from boss drops now have damage resistance, balanced relative to the progression.\n • Death Tome has a chance to drop enchanted books.\n\nCHANGED:\n • Quest Ram now pulls rewards from a loot table.\n • Uncrafting Table now returns materials directly to inventory like 1.12 vanilla Crafting Table.\n • Changing dimension ID of the TF now requires a relaunch.\n • Changing seed of your world now needs the world reloaded.\n • The 'shedding' from Death Tomes now draws from a loot table.\n • Block of Fiery Metal now stays lit when set on fire.\n • Made the boss spawner unbreakable, no more pacifist route unless on peaceful.\n • The Ore Magnet no longer moves ores if it is a tile entity.\n • Ghast Trap advancement is more specific in its wording.\n • Updated our JEI dependency to a newer version.\n\nFIXES:\n • Fixed Ironwood model.\n • Set particle Firefly size to 0 so they don't keep blinking in and out in F3+B mode.\n • Fixed a bug where all storage blocks worked as fuel.\n • Fixed Block of Fiery Metal and Block of Ironwood having parts render solid black without CTM.\n • Spruce trees in the snow biomes are no longer partially oak logs.\n • Giant blocks no longer destroy other blocks upon placement, including bedrock and the laws of physics.\n • Charm of Keeping and Charm of Life no longer conflict resulting in item loss, they now properly take turns and play nice.\n • Fiery Tears and Blood now show as interchangeable in JEI.\n • Roots no longer replace important blocks in generation.\n • Cleaned up the chunk generator some more.", + "3.3.202": "ADDED:\n • Block of Fiery Metal now deals damage when walked on.\n • Block of Arctic Fur reduces fall damage by 90%.\n • Block of Steeleaf reduces fall damage by 25%.\n • Advancement called \"Something Strange in The Towerwood\" was added.\n • Questing Ram has its own spawn egg now.\n • Questing Ram Trophy makes adorable noises now.\n • When a worn bug dies it now makes a *squish* sound.\n • The Anti-Builder now has a blacklist feature for people to prevent blocks being destroyed, a must have for mods that add graves.\n • Added proper breaking particles to Device Translucent and the Castle Doors.\n • Added names to multiple unlocalised blocks.\n\nCHANGES:\n • Made axes not terrible damage wise.\n • Buffed the Giant Sword.\n • Added proper sounds and material to the new storage blocks.\n • Tri-Bow no longer creates free arrows, only one can be picked up again when shot.\n • New storage blocks can now be used as base blocks for a beacon.\n • Magic tree cores no longer drop with Silk Touch.\n • Final Castle doors are now in the creative menu and can be pick-blocked.\n • Some advancement names and descriptions had changes.\n\nFIXES:\n • Fixed the Magic Map grinding your FPS to a halt over time, thousands of duplicate icons were hogging up all the precious memory over time.\n • The new storage blocks now show up in the creative menu.\n • Fixed the shadows of several mobs, no longer does the Alpha Yeti feel like a Beta Yeti.\n • Knightly Axe now properly deals extra damage to unarmoured targets.\n • Temporary workaround to not display the dismount message when a Pinch Beetle grabs you.\n • Fixed Magic Beans not getting consumed upon use.\n • Hydra can now rotate its body again.\n • Hydra will no longer harm itself, it enjoys life once again.\n • Unstable Ice Cores will no longer be griefing jerks with the MobGriefing gamerule being false.\n • The Hydra's mortar attack now also respects MobGriefing.\n • All mobs with a breath like attacks now have it functioning properly again.\n • Also fixed the particle rendering of the Snow Queen's icy breath.\n • Charm of Keeping should now activate before a gravestone mod can take hold of your items.\n • Fixed a transparency issue when wearing the Quest Ram Trophy.\n • The mushroom growing on the Minoshroom's head is back where it belongs.\n • Roots are no longer offset by one pixel down.\n • Swarm Spiders and Carminite Broodlings are no longer intimate with ceilings to the point of death." + }, + "promos": { + "1.12.2-latest": "3.8.689", + "1.12.2-recommended": "3.8.689", + "1.7.10-latest": "2.3.7", + "1.7.10-recommended": "2.3.7" + } +} \ No newline at end of file